Skip to content
Snippets Groups Projects
Commit c1ae0e05 authored by James Vasile's avatar James Vasile
Browse files

Allow post-processing pipeline plugins

parent 5d09275b
No related branches found
No related tags found
No related merge requests found
......@@ -88,6 +88,8 @@ all-redacted:
@cp $< $(<:.ltx=.knowngood) # for diffing broken builds to find bugs
@${PIPELINE} $< -o stage post
# This builds a draft. This only works if you're using the jinja
# template that extends down to base.ltx. Without that, draft
# versions are unsupported and this should have no effect.
......
......@@ -7,7 +7,23 @@ import os
import pkgutil
import sys
"""
The 'stage' option is for running this pipeline either pre- or post- latex.
Ex: pipeline.py target.ltx -o stage post
Ex: pipeline.py target.ltx -o stage pre
"""
def err(msg):
"""Yeah, this is an obnoxious error message, but the user will have to
pick it out of a long scroll of LaTeX and make output.
"""
sys.stderr.write("BEGIN PIPELINE ERROR MSG\n")
sys.stderr.write(msg)
sys.stderr.write("\n")
sys.stderr.write("END PIPELINE ERROR MSG\n")
sys.exit(-1)
def get_plugins(plugin_dir=None):
"""Load plugins from PLUGIN_DIR and return a dict with the plugin name
hashed to the imported plugin.
......@@ -19,10 +35,15 @@ def get_plugins(plugin_dir=None):
PLUGIN API:
run_p(text, meta): (required) predicate returns True if this
run_p(text, meta, opt): predicate returns True if this
plugin thinks it should run in the pipeline.
run(text, meta): (required) runs the plugin, returns text, meta
run(text, meta, opt): runs the plugin, returns text, meta
after_p(pdf_fname, meta, opt): predicate returns True if this plugin
thinks it should run after the pdf is produced.
after(pdf_fname, meta, opt): runs the plugin, returns meta. May change the pdf
"""
if not plugin_dir:
......@@ -43,12 +64,23 @@ def get_plugins(plugin_dir=None):
spec.loader.exec_module(plugins[fname])
return plugins
def tuple2dict(tup):
"""TUP is a tuple of 2-tuples. Return a dict where the first element
of each tuple hashes to the second.
"""
ret = {}
for t in tup:
ret[t[0]] = t[1]
return ret
@click.command()
@click.argument('filename')
@click.option('--output', help="output filename")
@click.option('--plugin', help="specify just one plugin to run (not implemented)")
@click.option('--option', '-o', nargs=2, multiple=True, default='', help='Variables and their values.')
def cli(filename, output, option, plugin):
pdf_fname = os.path.splitext(filename)[0]+'.pdf'
doc = frontmatter.load(filename)
text = doc.content
meta = doc.metadata
......@@ -64,17 +96,30 @@ def cli(filename, output, option, plugin):
for o in option:
meta[o[0]] = o[1]
# Dict is easier to work with
option = tuple2dict(option)
option['stage'] = option.get('stage', 'pre')
plugins = get_plugins()
for p,m in plugins.items():
if hasattr(m, "run_p"):
if m.run_p(text, meta):
text, meta = m.run(text, meta)
if output:
with open(output, 'w') as fh:
fh.write(text)
else:
print(text)
if option['stage'] == 'pre':
if hasattr(m, "run_p"):
if m.run_p(text, meta):
text, meta = m.run(text, meta)
elif option['stage'] == 'post':
if hasattr(m, "after_p"):
if m.after_p(pdf_fname, meta):
meta = m.after(pdf_fname, meta)
else:
err("Unknown stage: %s" % option['stage'])
## Print the output or write it to a file if we're pre-latex
if option['stage'] == 'pre':
if output:
with open(output, 'w') as fh:
fh.write(text)
else:
print(text)
if __name__ == '__main__':
cli()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment