#!/usr/bin/env python3 import argparse import glob import itertools from jinja2 import Environment, FileSystemLoader, select_autoescape, pass_context from markdown import markdown from markupsafe import Markup import os import os.path import re import shutil import yaml parser = argparse.ArgumentParser() parser.add_argument('--root', default='/jq') args = parser.parse_args() env = Environment( loader=FileSystemLoader('templates'), autoescape=select_autoescape(['html.j2']), ) def load_yml_file(fn): with open(fn) as f: return yaml.safe_load(f) env.globals['url'] = 'https://jqlang.github.io/jq' env.globals['root'] = args.root env.filters['search_id'] = lambda input: input.replace(r'`', '') env.filters['section_id'] = lambda input: re.sub( r'[^-a-zA-Z0-9_]', '', input.replace(' ', '-')).lower() env.filters['entry_id'] = lambda input: re.sub( r'^(split|first-last-nth)$', r'\1' + ('-1' if ';' not in input else '-2'), # avoid id conflict re.sub( r'\b([^-]+)(?:-\1)+\b', r'\1', # e.g. range-range-range -> range re.sub(r' ?/ ?|,? ', '-', re.sub(r'[`;]|: .*|\(.*?\)| \[.+\]', '', input)))).lower() env.filters['markdownify'] = lambda input: Markup(markdown(input)) env.filters['no_paragraph'] = lambda input: Markup(re.sub(r'', '', input)) env.globals['unique_id'] = pass_context( lambda ctx: str(next(ctx['unique_ctr']))) def raise_handler(message): raise Exception(message) env.globals['raise'] = raise_handler def generate_file(env, fname): path, base = os.path.split(fname) path = os.path.relpath(path, 'content') if path == '.': path = '' permalink = '' else: permalink = path + '/' output_dir = os.path.join('output', path) output_path = os.path.join(output_dir, 'index.html') template_name = re.sub(r'.yml$', '.html.j2', base) ctx = load_yml_file(fname) ctx.update(unique_ctr=itertools.count(1), permalink=permalink, navitem=path) os.makedirs(output_dir, exist_ok=True) env.get_template(template_name).stream(ctx).dump(output_path, encoding='utf-8') def copy_public_files(root=''): for f in os.scandir(os.path.join('public', root)): src = os.path.join(root, f.name) dst = os.path.join('output', src) if f.is_dir(): os.makedirs(dst, exist_ok=True) copy_public_files(src) else: shutil.copyfile(f.path, dst) os.makedirs('output', exist_ok=True) copy_public_files() for fn in glob.glob('content/**/*.yml', recursive=True): generate_file(env, fn)