Generates HTML5 from kramdown and metadata sourcefiles
#!/usr/bin/env python | |
# | |
# pagemaker [-xh] sourcefile [destination] | Kyle Barbour | Spring 2013 | |
# Generates XHTML from kramdown and metadata sourcefiles | |
# | |
# The sourcefile should be formatted as follows: | |
# | |
# TITLE: Title | |
# META: Meta content | |
# HEADER: Relative path to the XHTML header | |
# FOOTER: Relative path to the XHTML footer | |
# DEST: Default relative path for the XHTML output | |
# ... other KEY: value pairs as appropriate | |
# | |
# <valid kramdown file> | |
# | |
# Whitespace between the key and value are ignored. The first blank line is | |
# the delimiter between key-value pairs and written content. Providing a | |
# destination on the command line overrides any default destination in the | |
# metadata. Only HEADER and FOOTER are required, although if a default | |
# destination is desired, the key must be named DEST. | |
# | |
# -x Ignore default destination (if it exists) and generate the XHTML | |
# file in the same directory as the sourcefile. | |
# | |
# -h Prints a help file. | |
# | |
# pagemaker by default only replaces KEY: value pairs in the header. To allow | |
# replacement in the source text or the footer as well, add one or both of | |
# these lines in the for loop below the corresponding line for the header. | |
# | |
# markdown = markdown.replace(key, value) | |
# footer = footer.replace(key, value) | |
# | |
# pagemaker calls kr instead of kramdown as my local system passes kramdown | |
# through a shell script which removes some special characters. If you don't | |
# want to do similar postprocessing or your script is called something else, | |
# change 'kr' inside of the Popen parentheses to 'kramdown' or the name of | |
# your script. | |
# | |
# To run pagemaker on every file in a kramdown source directory or on multiple | |
# files, the simplest current solution is to use standard Unix techniques: | |
# | |
# $ find . -name "*.txt" -exec pagemaker {} \; | |
# $ for file in file1 file2 ... fileN; do pagemaker $file; done | |
# | |
# This doesn't allow command-line specification of destinations, but will | |
# otherwise work as expected. I considered adding recursive and multiargument | |
# options, but didn't want to add unnecessary complexity: if you have a simple | |
# solution I'm interested in hearing it. | |
# | |
############################################################################## | |
import os | |
import sys | |
import argparse | |
from subprocess import Popen, PIPE | |
from collections import OrderedDict | |
# argparser definitions, allows for temporary move output option | |
parser = argparse.ArgumentParser(description="Generates XHTML from kramdown " | |
"and metadata sourcefiles.") | |
parser.add_argument('source', type=str, | |
help="Location of kramdown sourcefile.") | |
parser.add_argument('dest', type=str, nargs='?', default='', | |
help="Destination directory of compiled XHTML file.") | |
parser.add_argument('-x', action='store_true', help="Ignore default destination.") | |
args = parser.parse_args() | |
# Move into the correct working directory | |
origdir = os.getcwd() | |
workingdir, sourcename = os.path.split(args.source) | |
if workingdir: | |
os.chdir(workingdir) | |
# Process metadata, then extract kramdown | |
print "Processing %s." % args.source | |
metadata = OrderedDict() | |
markdown = "" | |
with open(sourcename, 'r') as readfile: | |
readlines = iter(readfile) | |
for line in readlines: | |
if line == '\n': | |
break | |
key, value = line.split(":", 1) | |
metadata[key.strip()] = value.strip() | |
for line in readlines: | |
markdown += line | |
print "Metadata is:" | |
for key in metadata.iterkeys(): | |
print " %s: %s" % (key, metadata[key]) | |
# Determine destination and prevent unintentional overwrites | |
xhtmlname = "%s.html" % os.path.splitext(sourcename)[0] | |
xhtmlfile = xhtmlname | |
if args.dest or 'DEST' in metadata and not args.x: | |
xhtmldir = args.dest or metadata['DEST'] | |
xhtmlfile = os.path.join(xhtmldir, xhtmlname) | |
xhtmlfilepath = os.path.relpath(xhtmlfile, origdir) | |
if os.path.exists(xhtmlfile): | |
choice = raw_input("Overwrite " + xhtmlfilepath + "? [y/n]: ").lower() | |
if not choice == 'y': | |
sys.exit("Abandoning.") | |
else: | |
pass | |
# Replace placeholders in header, generate complete XHTML file | |
print "Running kramdown." | |
with open(metadata['HEADER'], 'r') as headerfile, open(metadata['FOOTER'], | |
'r') as footerfile: | |
header = headerfile.read() | |
footer = footerfile.read() | |
for key, value in metadata.iteritems(): | |
header = header.replace(key, value) | |
with open(xhtmlfile, 'w') as writefile: | |
kr = Popen('kr', stdin=PIPE, stdout=PIPE) | |
writefile.write(header + kr.communicate(markdown)[0] + footer) | |
print "Generated %s." % xhtmlfilepath |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment