Skip to content

Commit

Permalink
toctree, use document nesting instead of domain nesting
Browse files Browse the repository at this point in the history
  • Loading branch information
jakobandersen committed May 11, 2024
1 parent 98f953e commit 52ea6ce
Showing 1 changed file with 23 additions and 13 deletions.
36 changes: 23 additions & 13 deletions sphinx/environment/collectors/toctree.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,6 @@ def build_toc(
) -> nodes.bullet_list | None:
# list of table of contents entries
entries: list[Element] = []
# cache of parents -> list item
memo_parents: dict[tuple[str, ...], nodes.list_item] = {}
for sectionnode in node:
# find all toctree nodes in this section and add them
# to the toc (just copying the toctree node which is then
Expand Down Expand Up @@ -103,6 +101,8 @@ def build_toc(
entries.append(onlynode)
# check within the section for other node types
elif isinstance(sectionnode, nodes.Element):
# cache of parents -> list item
memo_parents: dict[nodes.Element, nodes.Element] = {}
toctreenode: nodes.Node
for toctreenode in sectionnode.findall():
if isinstance(toctreenode, nodes.section):
Expand All @@ -114,6 +114,10 @@ def build_toc(
note_toctree(app.env, docname, toctreenode)
# add object signatures within a section to the ToC
elif isinstance(toctreenode, addnodes.desc):
# The desc has one or more nested desc_signature,
# and then a desc_content, which again may have desc nodes.
# Thus, desc is the one we can bubble up to through parents.
entry: nodes.list_item | None = None
for sig_node in toctreenode:
if not isinstance(sig_node, addnodes.desc_signature):
continue
Expand All @@ -136,22 +140,28 @@ def build_toc(
para = addnodes.compact_paragraph('', '', reference,
skip_section_number=True)
entry = nodes.list_item('', para)
*parents, _ = sig_node['_toc_parts']
parents = tuple(parents)

# Cache parents tuple
memo_parents[sig_node['_toc_parts']] = entry

# Nest children within parents
if parents and parents in memo_parents:
root_entry = memo_parents[parents]
# Find parent node
parent = sig_node.parent
while parent not in memo_parents and parent != sectionnode:
parent = parent.parent
# Note, it may both be the limit and in memo_parents,
# prefer memo_parents, so we get the nesting.
if parent in memo_parents:
root_entry = memo_parents[parent]
if isinstance(root_entry[-1], nodes.bullet_list):
root_entry[-1].append(entry)
else:
root_entry.append(nodes.bullet_list('', entry))
continue

entries.append(entry)
else:
assert parent == sectionnode
entries.append(entry)

# Save the latest desc_signature as the one we put sub entries in.
# If there are multiple signatures, then the latest is used.
if entry is not None:
# are there any desc nodes without desc_signature nodes?
memo_parents[toctreenode] = entry

if entries:
return nodes.bullet_list('', *entries)
Expand Down

0 comments on commit 52ea6ce

Please sign in to comment.