ci(wiki): auto-insert new module pages into the sidebar
generate.py now keeps _Sidebar.md in sync: any Module:-* page from the mapping that is not yet linked is inserted alphabetically into the Modules list. Existing entries (custom labels, nested sub-entries, hand-written non-module links) are left untouched, so adding a module no longer requires editing the sidebar by hand. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -18,6 +18,12 @@ touches `man/**` or this tooling.
|
|||||||
- `extras/<Page>.md` — optional hand-maintained appendix (screenshots, showcase
|
- `extras/<Page>.md` — optional hand-maintained appendix (screenshots, showcase
|
||||||
snippets that have no man equivalent), appended verbatim after the generated body.
|
snippets that have no man equivalent), appended verbatim after the generated body.
|
||||||
|
|
||||||
|
The generator also keeps `_Sidebar.md` in sync: any `Module:-*` page in the mapping
|
||||||
|
that is not yet linked in the sidebar is inserted alphabetically into the `Modules:`
|
||||||
|
list. Existing sidebar entries (custom labels, nested sub-entries, hand-written
|
||||||
|
non-module links) are never modified — so a new module auto-appears in navigation
|
||||||
|
without disturbing the curated structure.
|
||||||
|
|
||||||
## What it touches
|
## What it touches
|
||||||
|
|
||||||
Only the pages listed in `mapping.json` are (re)written. Every other wiki page
|
Only the pages listed in `mapping.json` are (re)written. Every other wiki page
|
||||||
|
|||||||
@@ -90,6 +90,54 @@ def build_page(man_dir, sources, page, extras_dir):
|
|||||||
return "\n".join(parts).rstrip() + "\n"
|
return "\n".join(parts).rstrip() + "\n"
|
||||||
|
|
||||||
|
|
||||||
|
ENTRY_RE = re.compile(r"^ - \[([^\]]+)\]\(\./Module:-")
|
||||||
|
LINK_RE = re.compile(r"\]\(\./(Module:-[^)]+)\)")
|
||||||
|
|
||||||
|
|
||||||
|
def sync_sidebar(out_dir, mapping):
|
||||||
|
"""Non-destructively add any mapped Module page missing from _Sidebar.md.
|
||||||
|
|
||||||
|
Only inserts links for pages absent from the sidebar; existing entries
|
||||||
|
(custom labels, nested sub-entries, hand-written non-module links) are
|
||||||
|
never modified. Insertion is alphabetical within the top-level module list.
|
||||||
|
"""
|
||||||
|
path = os.path.join(out_dir, "_Sidebar.md")
|
||||||
|
if not os.path.exists(path):
|
||||||
|
print(" no _Sidebar.md; skipping sidebar sync")
|
||||||
|
return
|
||||||
|
lines = open(path).read().splitlines()
|
||||||
|
linked = set(LINK_RE.findall("\n".join(lines)))
|
||||||
|
missing = sorted((p for p in mapping
|
||||||
|
if p.startswith("Module:-") and p not in linked),
|
||||||
|
key=str.lower)
|
||||||
|
if not missing:
|
||||||
|
print(" sidebar up to date")
|
||||||
|
return
|
||||||
|
|
||||||
|
def entries():
|
||||||
|
return [i for i, l in enumerate(lines) if ENTRY_RE.match(l)]
|
||||||
|
|
||||||
|
if not entries():
|
||||||
|
print(" could not locate Modules section; skipping sidebar sync")
|
||||||
|
return
|
||||||
|
for page in missing:
|
||||||
|
label = page[len("Module:-"):].replace("-", " ")
|
||||||
|
new_line = f" - [{label}](./{page})"
|
||||||
|
pos = None
|
||||||
|
for i in entries():
|
||||||
|
if ENTRY_RE.match(lines[i]).group(1).lower() > label.lower():
|
||||||
|
pos = i
|
||||||
|
break
|
||||||
|
if pos is None: # after the last module entry and its sub-entries
|
||||||
|
j = entries()[-1] + 1
|
||||||
|
while j < len(lines) and lines[j].startswith(" "):
|
||||||
|
j += 1
|
||||||
|
pos = j
|
||||||
|
lines.insert(pos, new_line)
|
||||||
|
print(f" sidebar += {label}")
|
||||||
|
open(path, "w").write("\n".join(lines) + "\n")
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
ap = argparse.ArgumentParser()
|
ap = argparse.ArgumentParser()
|
||||||
ap.add_argument("--man-dir", default="man")
|
ap.add_argument("--man-dir", default="man")
|
||||||
@@ -130,6 +178,7 @@ def main():
|
|||||||
out = os.path.join(args.out_dir, page + ".md")
|
out = os.path.join(args.out_dir, page + ".md")
|
||||||
open(out, "w").write(build_page(args.man_dir, sources, page, extras_dir))
|
open(out, "w").write(build_page(args.man_dir, sources, page, extras_dir))
|
||||||
print(f" wrote {page}.md ({', '.join(sources)})")
|
print(f" wrote {page}.md ({', '.join(sources)})")
|
||||||
|
sync_sidebar(args.out_dir, mapping)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user