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 3250427
Showing 1 changed file with 22 additions and 21 deletions.
43 changes: 22 additions & 21 deletions sphinx/environment/adapters/toctree.py
Original file line number Diff line number Diff line change
Expand Up @@ -464,16 +464,11 @@ 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:
"""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()
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: used to copy node children except 'only' nodes which are not
toctree nodes but conditions to include or not their children."""

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

View workflow job for this annotation

GitHub Actions / ruff

Ruff (D209)

sphinx/environment/adapters/toctree.py:470:5: D209 Multi-line docstring closing quotes should be on a separate line
for subnode in node.children:
if isinstance(subnode, addnodes.compact_paragraph | nodes.list_item):
# for <p> and <li>, just recurse
Expand All @@ -489,18 +484,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 +499,19 @@ def _toctree_copy(
else:
msg = f'Unexpected node type {subnode.__class__.__name__!r}!'
raise ValueError(msg)

return copy

def _toctree_copy(

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

View workflow job for this annotation

GitHub Actions / ruff

Ruff (E302)

sphinx/environment/adapters/toctree.py:505:1: E302 Expected 2 blank lines, found 1
node: ET, depth: int, maxdepth: int, collapse: bool, tags: Tags
) -> ET:
"""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()
_toctree_copy_children(copy, node, depth, maxdepth, collapse, tags)
return copy


Expand Down

0 comments on commit 3250427

Please sign in to comment.