forked from rossant/awesome-math
-
Notifications
You must be signed in to change notification settings - Fork 0
/
build_toc.py
66 lines (46 loc) · 1.48 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
"""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})'
_NEWLINES = '\n\n\n'
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(_NEWLINES)
j = md.index('# General Resources', i)
with open(filename, 'w') as f:
f.write(md[:i] + _NEWLINES)
for item in _gen_items(md):
if 'Awesome Math' in item:
continue
f.write(item + '\n')
f.write(_NEWLINES + md[j:])
if __name__ == '__main__':
filename = 'README.md'
gen_toc(filename)