Skip to content

Instantly share code, notes, and snippets.

@kylebarbour
Last active December 26, 2016 22:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kylebarbour/5778189 to your computer and use it in GitHub Desktop.
Save kylebarbour/5778189 to your computer and use it in GitHub Desktop.
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