#!/usr/bin/env python3 # -*- python -*- import sys import subprocess import re import os import sqlite3 from preserves import preserve, parse, stringify from preserves.schema import load_schema_file, extend cache = sqlite3.connect('.mdbook-ditaa.sqlite') try: cache.cursor().execute('CREATE TABLE diagrams(source text, svg text)') except: pass try: schema = load_schema_file('./book.prb').book except FileNotFoundError: subprocess.check_output(['sh', '-c', 'preserves-schemac --no-bundle .:book.prs > book.prb']) schema = load_schema_file('./book.prb').book @extend(schema.Book) def expand(self, context): for i in self.sections: i.expand(context) @extend(schema.BookItem.chapter) def expand(self, context): self.value.expand(context) @extend(schema.BookItem._ALL) def expand(self, context): pass @extend(schema.Chapter) def expand(self, context): if self.source_path.VARIANT.name == 'present': directory = os.path.dirname(self.source_path.value) self.content = expand_codeblock(DITAA_TAG, expand_ditaa, self.content, context, directory) for i in self.sub_items: i.expand(context) def expand_codeblock(language_re, expander, s, *args): return re.sub('^```' + language_re + '\n(.*?)\n```\n', lambda m: expander(m, *args), s, 0, re.M | re.S) figure_count = 0 def next_filename(): global figure_count figure_count = figure_count + 1 return f'figure_{figure_count}' DITAA_TAG = r'ditaa(?: ((?:\w|-)+))?' def expand_ditaa(m, context, directory): sourcedir = context['config']['book']['src'] baseurl = context['config']['output']['html']['site-url'] filename = os.path.join(directory, (m.group(1) or next_filename()) + '.svg') sys.stderr.write(f'ditaa {filename} ...') ditaa_source = m.group(2) cached = list(cache.cursor().execute('SELECT svg FROM diagrams WHERE source = ?', (ditaa_source,))) if cached: svg = cached[0][0] else: svg = subprocess.check_output(['ditaa', '--svg', '-'], input=ditaa_source.encode('utf-8')) svg = svg.decode('utf-8') cache.cursor().execute('INSERT INTO diagrams VALUES (?, ?)', (ditaa_source, svg)) cache.cursor().execute('COMMIT') svgfilename = os.path.join(sourcedir, output_prefix, filename) os.makedirs(os.path.dirname(svgfilename), exist_ok=True) need_write = True if os.path.exists(svgfilename): with open(svgfilename, 'rt') as f: existing = f.read() if existing == svg: need_write = False if need_write: sys.stderr.write('updated\n') with open(svgfilename, 'wt') as f: f.write(svg) else: sys.stderr.write('unchanged\n') return f'

{filename}

\n' def structure(items): answer = [] for i in items: if i.VARIANT.name == 'chapter': a = structure(i.value.sub_items) answer.append({ i.value.name: a }) return answer if __name__ == '__main__': if sys.argv[-2:-1] == ['supports']: sys.exit(0 if sys.argv[-1] == 'html' else 1) output_prefix = sys.argv[1] if len(sys.argv) > 1 else 'figures' raw = parse(sys.stdin.read()) # sys.stderr.write(stringify(raw, indent=2) + '\n') i = schema.PreprocessorInput.decode(raw) # sys.stderr.write(stringify(preserve(i.context), indent=2) + '\n') i.book.expand(i.context) print(stringify(preserve(i.book), with_commas=True))