diff --git a/build_toc.py b/build_toc.py new file mode 100644 index 0000000..700d91c --- /dev/null +++ b/build_toc.py @@ -0,0 +1,64 @@ +"""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): + f.write(item + '\n') + f.write(_NEWLINES + md[j:]) + + +if __name__ == '__main__': + filename = 'README.md' + gen_toc(filename)