Skip to content

[TOC] Generate TOCs from Doxygen modules.html and fix leaf detection#177

Open
Scheremo wants to merge 1 commit into
boschglobal:mainfrom
mosaic-soc:pr-modules-toc
Open

[TOC] Generate TOCs from Doxygen modules.html and fix leaf detection#177
Scheremo wants to merge 1 commit into
boschglobal:mainfrom
mosaic-soc:pr-modules-toc

Conversation

@Scheremo

Copy link
Copy Markdown

Extend the Doxygen TOC generator to derive a hierarchical menu from modules.html, enabling proper TOC generation for the API reference and nested Doxygen groups. Fix _MenuEntry.is_leaf to be computed dynamically so tree traversal works correctly with incrementally-built structures.

  • Parse modules.html to reconstruct the Doxygen module hierarchy using table row IDs (row_0_2_4_ -> nested structure)
  • Introduce a synthetic modules root entry representing the API reference page
  • Merge module/group entries into the TOC lookup so:
    • modules.html gets a TOC
    • group pages (group__*) list their subgroups when applicable
  • Replace stored is_leaf state with a computed property based on children to avoid stale tree metadata
  • Add lightweight HTML helpers for tag stripping and row parsing (stdlib-only, no new dependencies)

Doxygen’s menudata.js does not contain module hierarchy information, so TOCs for modules.html and group pages could not be generated. Parsing modules.html provides the missing structure. Making is_leaf a property ensures correct traversal when menu trees are built or modified dynamically.

  • Correct TOCs for API reference and module group pages
  • More robust and semantically correct menu tree handling
  • No changes to public APIs or output format outside TOC generation

This was tested with doxygen 1.9.7; newer versions (e.g. doxygen 1.10 and above) no longer reference "modules.html" but "topics.html", so adjustments might have to be made there.

@Scheremo Scheremo requested a review from twodrops as a code owner January 11, 2026 14:10
Extend the Doxygen TOC generator to derive a hierarchical menu from
`modules.html`, enabling proper TOC generation for the API reference
and nested Doxygen groups. Fix `_MenuEntry.is_leaf` to be computed
dynamically so tree traversal works correctly with incrementally-built
structures.

- Parse `modules.html` to reconstruct the Doxygen module hierarchy
  using table row IDs (`row_0_2_4_` -> nested structure)
- Introduce a synthetic `modules` root entry representing the API
  reference page
- Merge module/group entries into the TOC lookup so:
  - `modules.html` gets a TOC
  - group pages (`group__*`) list their subgroups when applicable
- Replace stored `is_leaf` state with a computed property based on
  `children` to avoid stale tree metadata
- Add lightweight HTML helpers for tag stripping and row parsing
  (stdlib-only, no new dependencies)

Doxygen’s `menudata.js` does not contain module hierarchy information,
so TOCs for `modules.html` and group pages could not be generated.
Parsing `modules.html` provides the missing structure. Making `is_leaf`
a property ensures correct traversal when menu trees are built or
modified dynamically.

- Correct TOCs for API reference and module group pages
- More robust and semantically correct menu tree handling
- No changes to public APIs or output format outside TOC generation

Signed-off-by: Moritz Scherer <moritz@mosaic-soc.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends DoxygenTocGenerator to generate hierarchical TOCs for modules.html and nested Doxygen groups by parsing modules.html table row IDs into a tree, and it fixes menu leaf detection by making _MenuEntry.is_leaf computed from children.

Changes:

  • Add HTML parsing helpers and a modules.html-derived menu tree that’s merged into the TOC lookup.
  • Introduce a synthetic modules root entry representing the API reference page.
  • Replace stored _MenuEntry.is_leaf state with a computed property to avoid stale metadata during incremental tree building.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread doxysphinx/toc.py
Comment on lines +28 to +30
def _strip_tags(s: str) -> str:
# titles are usually plain text, but be safe
return _TAG_STRIP_RE.sub("", s).replace("&amp;", "&").strip()
Comment thread doxysphinx/toc.py
Comment on lines +193 to +195
def _load_modules_tree(self, modules_html_path: Path, title: str = "API Reference") -> _MenuEntry:
html = modules_html_path.read_text(encoding="utf-8", errors="ignore")
matches = list(_ROW_RE.finditer(html))
Comment thread doxysphinx/toc.py
Comment on lines +227 to +229
if len(path) == 1:
parent.children[idx] = node
return
Comment thread doxysphinx/toc.py
Comment on lines +231 to +246
# Intermediate structural node:
child = parent.children[idx]
if child.title == "__placeholder__":
# Use the current node’s identity for the intermediate folder if we don’t have one yet.
# But careful: we only know the final node for full path; intermediates appear as their own rows
# in doxygen, so they should be inserted by their own match eventually.
child = _MenuEntry(
title="__placeholder__",
docname="__placeholder__",
url="__placeholder__",
children=[],
is_structural_dummy=False,
)
parent.children[idx] = child

insert(parent.children[idx], path[1:], node)
Comment thread doxysphinx/toc.py
Comment on lines +265 to +272
def prune(node: _MenuEntry) -> None:
kept: List[_MenuEntry] = []
for c in node.children:
prune(c)
if c.title == "__placeholder__":
continue
kept.append(c)
node.children = kept
Comment thread doxysphinx/toc.py
Comment on lines +176 to +180
# NEW: build modules hierarchy from modules.html (if present)
modules_path = source_dir / "modules.html"
self._modules_entry: Optional[_MenuEntry] = None
if modules_path.exists():
self._modules_entry = self._load_modules_tree(modules_path, title="API Reference")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants