summaryrefslogtreecommitdiff
path: root/ftt-docgen
diff options
context:
space:
mode:
Diffstat (limited to 'ftt-docgen')
-rwxr-xr-xftt-docgen124
1 files changed, 124 insertions, 0 deletions
diff --git a/ftt-docgen b/ftt-docgen
new file mode 100755
index 0000000..6dd7ee9
--- /dev/null
+++ b/ftt-docgen
@@ -0,0 +1,124 @@
+#!/bin/env python3
+
+import copy
+import re
+import sys
+
+import CommonMark_bkrs as CommonMark
+import yaml
+
+def format_keyword(line):
+ words = line.split(' ')
+ keyword = words[0]
+ return '**{}** '.format(keyword) + line[len(keyword):]
+
+def format_scenario_step(bind, line):
+ for b in bind:
+ m = re.match(b['pattern'], line, re.I)
+ if m and m.end() == len(line):
+ n = len(m.groups())
+ if n > 0:
+ end = 0
+ parts = []
+ for i in range(1, n+1):
+ parts.append(line[end:m.start(i)])
+ thispart = line[m.start(i) : m.end(i)]
+ parts.append('_{}_'.format(thispart))
+ end = m.end(i)
+ line = ''.join(parts) + line[m.end(n):]
+
+ if not line.strip():
+ return line
+ return format_keyword(line)
+
+def format_fable_snippet(bind, lines):
+ return [format_scenario_step(bind, line) for line in lines]
+
+def is_fable_snippet(o):
+ prefix = "```fable\n"
+ return o.t == 'FencedCode' and o.info == 'fable'
+
+def is_heading(o):
+ return o.t =='ATXHeader'
+
+def write_document(bind, f, o):
+ pass
+
+def write_atxheader(bind, f, o):
+ f.write('{} {}\n\n'.format('#' * o.level, ' '.join(o.strings)))
+
+def write_setextheader(bind, f, o):
+ chars = {
+ 1: '=',
+ 2: '-',
+ }
+ c = chars[o.level]
+ f.write('{}\n{}\n\n'.format(' '.join(o.strings), c * 72))
+
+def write_paragraph(bind, f, o):
+ for s in o.strings:
+ f.write('{}\n'.format(s))
+ f.write('\n')
+
+def write_fable_snippet(bind, f, o):
+ for line in format_fable_snippet(bind, o.strings[1:]):
+ f.write('> {} \n'.format(line))
+ f.write('\n')
+
+def write_not_fable_snippet(bind, f, o):
+ fence = o.fence_char * o.fence_length
+ lang = o.strings[0]
+ f.write('{}{}\n'.format(fence, lang))
+ for line in o.strings[1:]:
+ f.write('{}\n'.format(line))
+ f.write('{}\n'.format(fence))
+ f.write('\n')
+
+def write_fencedcode(bind, f, o):
+ if is_fable_snippet(o):
+ write_fable_snippet(bind, f, o)
+ else:
+ write_not_fable_snippet(bind, f, o)
+
+def write_horizontalrule(bind, f, o):
+ f.write('---\n')
+
+writers = {
+ 'Document': write_document,
+ 'ATXHeader': write_atxheader,
+ 'SetextHeader': write_setextheader,
+ 'Paragraph': write_paragraph,
+ 'FencedCode': write_fencedcode,
+ 'HorizontalRule': write_horizontalrule,
+}
+
+def write(bind, f, o):
+ if o.t not in writers:
+ debug('{} not known'.format(repr(o.t)))
+ return
+ writer = writers[o.t]
+ writer(bind, f, o)
+
+def walk(o, func):
+ func(o)
+ for c in o.children:
+ walk(c, func)
+
+def debug(msg):
+ sys.stderr.write('DEBUG: {}\n'.format(msg))
+ sys.stderr.flush()
+
+debug('reading bindings')
+bindings = yaml.safe_load(open(sys.argv[1]))
+
+debug('reading inputs')
+text = ''.join(open(filename).read() for filename in sys.argv[2:])
+
+debug('parse')
+parser = CommonMark.DocParser()
+ast = parser.parse(text)
+
+debug('output')
+walk(ast, lambda o: write(bindings, sys.stdout, o))
+
+debug('ok')