Skip to content

Commit

Permalink
Closes #13022: fix _toctree_copy with multi level 'only' nodes.
Browse files Browse the repository at this point in the history
When copying toc tree, 'only' nodes should not be copied, but previous
implementation always considered 'only' node children as duplicable nodes which
is wrong when 'only' nodes is parent of other 'only' nodes.
  • Loading branch information
Arnaud Desmier committed Nov 14, 2024
1 parent c93723b commit b1a10a0
Showing 1 changed file with 16 additions and 17 deletions.
33 changes: 16 additions & 17 deletions sphinx/environment/adapters/toctree.py
Original file line number Diff line number Diff line change
Expand Up @@ -464,16 +464,13 @@ def _toctree_add_classes(node: Element, depth: int, docname: str) -> None:

ET = TypeVar('ET', bound=Element)


def _toctree_copy(
node: ET, depth: int, maxdepth: int, collapse: bool, tags: Tags
) -> ET:
def _toctree_copy_children(

Check failure on line 467 in sphinx/environment/adapters/toctree.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (E302)

sphinx/environment/adapters/toctree.py:467:1: E302 Expected 2 blank lines, found 1
copy: ET, node: ET, depth: int, maxdepth: int, collapse: bool, tags: Tags
) -> None:
"""Utility: Cut and deep-copy a TOC at a specified depth."""
keep_bullet_list_sub_nodes = depth <= 1 or (
(depth <= maxdepth or maxdepth <= 0) and (not collapse or 'iscurrent' in node)
)

copy = node.copy()
for subnode in node.children:
if isinstance(subnode, addnodes.compact_paragraph | nodes.list_item):
# for <p> and <li>, just recurse
Expand All @@ -489,18 +486,11 @@ def _toctree_copy(
# copy sub toctree nodes for later processing
copy.append(subnode.copy())
elif isinstance(subnode, addnodes.only):
# only keep children if the only node matches the tags
# Only keep its children if the 'only' node matches the tags. When
# matching, call recursively the current function without
# incrementing the depth as 'only' nodes are not toctree nodes.
if _only_node_keep_children(subnode, tags):
for child in subnode.children:
copy.append(
_toctree_copy(
child,
depth,
maxdepth,
collapse,
tags, # type: ignore[type-var]
)
)
_toctree_copy_children(copy, subnode, depth, maxdepth, collapse, tags)
elif isinstance(subnode, nodes.reference | nodes.title):
# deep copy references and captions
sub_node_copy = subnode.copy()
Expand All @@ -511,6 +501,15 @@ def _toctree_copy(
else:
msg = f'Unexpected node type {subnode.__class__.__name__!r}!'
raise ValueError(msg)

return copy


def _toctree_copy(
node: ET, depth: int, maxdepth: int, collapse: bool, tags: Tags
) -> ET:
copy = node.copy()
_toctree_copy_children(copy, node, depth, maxdepth, collapse, tags)
return copy


Expand Down

0 comments on commit b1a10a0

Please sign in to comment.