1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
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')
|