pub fn traverse_toctree(
toctree_includes: &BTreeMap<String, Vec<String>>,
root: &str,
) -> Vec<(Option<String>, String)>Expand description
Pre-order depth-first walk of toctree_includes from root, yielding
(parent, docname) once per document — the first visit wins.
Port of _traverse_toctree (environment/__init__.py:914-939) with one
deliberate difference: descent is guarded by the visited set, not just
yielding. Sphinx recurses into every child unconditionally and only
filters the yields, so a mutual A -> B -> A cycle recurses without
bound and raises RecursionError — a real, oracle-verified sphinx 9.1.0
crash (tests/fixtures/env_differential.json records relations: null
for the toctree_circular project because of it). For an acyclic graph
the two are equivalent: re-descending into an already-visited document
can only re-yield documents that were already yielded, and those are
filtered out anyway.
The walk is iterative for the same reason it is guarded: an explicit stack cannot overflow on a deep document tree.
Sphinx logs self referenced toctree found. Ignored. (toc.circular)
when a document’s toctree includes the document itself, and drops that
subtree. The drop is ported; the warning is not, because the branch is
unreachable in this pipeline — resolve_entries removes the current
document from its own candidate set, so a self-entry never reaches
toctree_includes; it is reported at parse time as
toctree contains reference to nonexisting document instead (which is
exactly what the oracle records for the toctree_self_ref project).