-
Notifications
You must be signed in to change notification settings - Fork 963
/
build_toc.py
67 lines (47 loc) · 1.51 KB
/
build_toc.py
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
"""Generate the table of contents and insert it at the top of README.md."""
import re
_HEADER_REGEX = r'([#]+) ([^\n]+)'
_PUNCTUATION_REGEX = r'[^\w\- ]'
_HEADER_TEMPLATE = '{indent}* [{name}](#{anchor})'
_START_TOC = '<!-- START_TOC -->'
_END_TOC = '<!-- END_TOC -->'
def _anchor(name):
anchor = name.lower().replace(' ', '-')
anchor = re.sub(_PUNCTUATION_REGEX, '', anchor)
return anchor
def _parse_header(header):
r = re.match(_HEADER_REGEX, header)
if r:
level = len(r.group(1))
name = r.group(2)
return level, _anchor(name), name
def _iter_headers(md):
headers = (line for line in md.splitlines()
if line.startswith('#'))
for header in headers:
yield header
def _get_header_item(header):
level, anchor, name = _parse_header(header)
indent = ' ' * max(0, level - 1)
return _HEADER_TEMPLATE.format(**locals())
def _gen_items(md):
for header in _iter_headers(md):
item = _get_header_item(header)
yield item
def _read_md(filename):
with open(filename, 'r') as f:
return f.read()
def gen_toc(filename):
md = _read_md(filename)
i = md.index(_START_TOC) + len(_START_TOC) + 2
j = md.index(_END_TOC)
with open(filename, 'w') as f:
f.write(md[:i])
for item in _gen_items(md):
if 'Awesome Math' in item:
continue
f.write(item + '\n')
f.write('\n' + md[j:])
if __name__ == '__main__':
filename = 'README.md'
gen_toc(filename)