2021-04-08 06:37:51 +00:00
|
|
|
"""A tiny template(s) tool.
|
|
|
|
|
|
|
|
Processes Jekyll/Hyde/Hugo/... style 'fontmatter' headers, applying Jinja2/Liquid templating from an
|
|
|
|
optional templates and includes directory.
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
import os
|
|
|
|
import re
|
|
|
|
|
|
|
|
import click
|
|
|
|
import jinja2
|
|
|
|
import yaml
|
|
|
|
|
2021-05-31 18:28:46 +00:00
|
|
|
|
2021-04-08 06:37:51 +00:00
|
|
|
FONTMATTER_PATTERN = re.compile(
|
|
|
|
r"^(---\n\r?(?P<fontmatter>.*?)\n\r?---\n\r?)?(?P<content>.+)$", re.DOTALL
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@click.command()
|
|
|
|
@click.option("-i", "--include", "include_dir", multiple=True)
|
|
|
|
@click.option("-t", "--template", "template_dir", multiple=True)
|
|
|
|
@click.option("-c", "--config", "config_file")
|
|
|
|
@click.argument("infile")
|
|
|
|
@click.argument("outfile")
|
|
|
|
def main(include_dir, template_dir, config_file, infile, outfile):
|
|
|
|
"""Apply templating.
|
|
|
|
|
|
|
|
Consume infile, processing it with templating and write the results to outfile.
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
loaders = []
|
|
|
|
for d in include_dir:
|
|
|
|
loaders.append(jinja2.FileSystemLoader(os.path.realpath(d)))
|
|
|
|
|
|
|
|
for d in template_dir:
|
|
|
|
loaders.append(jinja2.FileSystemLoader(os.path.realpath(d)))
|
|
|
|
|
|
|
|
# Build a j2 environment using the potentially various loaders..
|
|
|
|
environment = jinja2.Environment(loader=jinja2.ChoiceLoader(loaders))
|
|
|
|
|
|
|
|
# Load a site config
|
|
|
|
if config_file:
|
|
|
|
with open(config_file) as f:
|
|
|
|
site = yaml.safe_load(f.read())
|
|
|
|
else:
|
|
|
|
site = {}
|
|
|
|
|
|
|
|
# Figure out doing the fontmatter nonsense...
|
|
|
|
with open(infile, "r") as f:
|
|
|
|
buff = f.read()
|
|
|
|
|
|
|
|
match = re.match(FONTMATTER_PATTERN, buff)
|
|
|
|
if fontmatter := match.group("fontmatter"):
|
|
|
|
fontmatter = yaml.safe_load(fontmatter)
|
|
|
|
else:
|
|
|
|
fontmatter = {}
|
|
|
|
|
|
|
|
# Render the file contents
|
|
|
|
template = environment.from_string(match.group("content"))
|
|
|
|
content = template.render(site=site, page=fontmatter)
|
|
|
|
|
|
|
|
# If there's a configured `layout:` stick the content in the layout.
|
|
|
|
if "layout" in fontmatter:
|
|
|
|
template = environment.get_template(fontmatter.get("layout"))
|
|
|
|
content = template.render(content=content, site=site, page=fontmatter)
|
|
|
|
|
|
|
|
# And dump the results
|
|
|
|
with open(outfile, "w") as f:
|
|
|
|
f.write(content)
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
main()
|