Add script for updating mkdocs toc
This commit is contained in:
parent
3ead88da48
commit
ff924ebe52
1 changed files with 128 additions and 0 deletions
128
scripts/update-toc
Executable file
128
scripts/update-toc
Executable file
|
@ -0,0 +1,128 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import click
|
||||
|
||||
import os
|
||||
import re
|
||||
import pdb
|
||||
import pprint
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
pp = pprint.PrettyPrinter(indent=4).pprint
|
||||
|
||||
class TocBuilder:
|
||||
def __init__(self, root_path):
|
||||
self.root_path = root_path
|
||||
|
||||
# Helper for titles
|
||||
def __get_title(self, fn):
|
||||
if not os.path.exists(fn):
|
||||
return None
|
||||
f1 = open(fn, "r")
|
||||
for line in f1:
|
||||
m = re.match(r"^#\s(.*)$", line)
|
||||
if m:
|
||||
f1.close()
|
||||
return m.groups()[0]
|
||||
f1.close()
|
||||
return None
|
||||
|
||||
def lookup(self):
|
||||
md_files = []
|
||||
for root, dirs, files in os.walk(self.root_path):
|
||||
for fn in files:
|
||||
# compute absolute and relative path
|
||||
abs_path = os.path.join(root, fn)
|
||||
rel_path = os.path.relpath(abs_path, self.root_path)
|
||||
|
||||
# split name into parts
|
||||
bname = os.path.basename(rel_path)
|
||||
bname_split = os.path.splitext(bname)
|
||||
dname = os.path.dirname(rel_path)
|
||||
|
||||
# skip files in docs/ root
|
||||
if dname == "":
|
||||
continue
|
||||
|
||||
# skip index files
|
||||
if bname_split[0] == 'index':
|
||||
continue
|
||||
|
||||
# keep only .md files
|
||||
if bname_split[1] == '.md':
|
||||
md_files.append(rel_path)
|
||||
return md_files
|
||||
|
||||
def format(self, md_files):
|
||||
lines = ["nav:"]
|
||||
lastdir=""
|
||||
for f in sorted(md_files):
|
||||
bname = os.path.basename(f)
|
||||
bname_split = os.path.splitext(bname)
|
||||
dname = os.path.dirname(f)
|
||||
|
||||
if lastdir != dname:
|
||||
lastdir = dname
|
||||
title = self.__get_title(os.path.join(self.root_path, dname, 'index.md'))
|
||||
if title is not None:
|
||||
lines.append(" - \"%s\":" % title)
|
||||
else:
|
||||
lines.append(" - \"%s\":" % dname)
|
||||
|
||||
lines.append(" - %s" % f)
|
||||
return lines
|
||||
|
||||
class FileInjector:
|
||||
def __init__(self, delimiter):
|
||||
self.delimiter = delimiter
|
||||
|
||||
def inject(self, filename, lines):
|
||||
suffix = '~update_toc'
|
||||
src_fh = open(filename, 'r')
|
||||
dst_fh = open(filename + suffix, 'w')
|
||||
|
||||
inject_mode = False
|
||||
end_pattern = r"^#\s+END {0}\s*$".format(self.delimiter)
|
||||
begin_pattern = r"^#\s+BEGIN {0}\s*$".format(self.delimiter)
|
||||
for src_line in src_fh:
|
||||
if (not inject_mode) and re.match(begin_pattern, src_line):
|
||||
# activate inject_mode, write begin pattern and lines
|
||||
inject_mode = True
|
||||
dst_fh.write(src_line)
|
||||
for line in lines:
|
||||
dst_fh.write(line + "\n")
|
||||
|
||||
elif inject_mode and re.match(end_pattern, src_line):
|
||||
# disable inject_mode and write end pattern
|
||||
inject_mode = False
|
||||
dst_fh.write(src_line)
|
||||
elif inject_mode:
|
||||
# skip line if injection mode is active
|
||||
next
|
||||
else:
|
||||
# simple copy if injection mode is NOT active
|
||||
dst_fh.write(src_line)
|
||||
# si la ligne <
|
||||
# FIXME: error if inject_mode is still True
|
||||
src_fh.close()
|
||||
dst_fh.close()
|
||||
os.rename(filename + suffix, filename)
|
||||
|
||||
# build TOC in-memory
|
||||
#
|
||||
# open mkdocs.yml file
|
||||
# save part before
|
||||
|
||||
@click.command()
|
||||
def build():
|
||||
root_path = Path(__file__).parent.parent
|
||||
toc = TocBuilder(str(root_path / 'docs'))
|
||||
md_files = toc.lookup()
|
||||
md_toc = toc.format(md_files)
|
||||
fi = FileInjector('MKDOCS-TOC')
|
||||
fi.inject(str(root_path / 'mkdocs.yml'), md_toc)
|
||||
|
||||
if __name__ == '__main__':
|
||||
build()
|
||||
|
Loading…
Reference in a new issue