Skip to content

Commit

Permalink
Properly fix duplicated headings for nested docstrings
Browse files Browse the repository at this point in the history
  • Loading branch information
oprypin committed Sep 18, 2023
1 parent e2123a9 commit 592554c
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 16 deletions.
17 changes: 7 additions & 10 deletions src/mkdocstrings/extension.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,24 +233,21 @@ class _PostProcessor(Treeprocessor):
def run(self, root: Element) -> None:
self._remove_duplicated_headings(root)

def _remove_duplicated_headings(self, parent: Element) -> bool:
def _remove_duplicated_headings(self, parent: Element) -> None:
carry_text = ""
found = False
for el in reversed(parent): # Reversed mainly for the ability to mutate during iteration.
if el.tag == "div" and el.get("class") == "mkdocstrings":
# Delete the duplicated headings along with their container, but keep the text (i.e. the actual HTML).
carry_text = (el.text or "") + carry_text
parent.remove(el)
found = True
elif carry_text:
el.tail = (el.tail or "") + carry_text
carry_text = ""
elif self._remove_duplicated_headings(el):
found = True
break
else:
if carry_text:
el.tail = (el.tail or "") + carry_text
carry_text = ""
self._remove_duplicated_headings(el)

if carry_text:
parent.text = (parent.text or "") + carry_text
return found


class MkdocstringsExtension(Extension):
Expand Down
12 changes: 12 additions & 0 deletions tests/fixtures/headings.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,15 @@
###### Baz
"""


def heading_1():
"""## Heading one"""


def heading_2():
"""### Heading two"""


def heading_3():
"""#### Heading three"""
16 changes: 10 additions & 6 deletions tests/test_extension.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,19 +152,23 @@ def test_use_options_yaml_key(ext_markdown: Markdown) -> None:
assert "h1" not in ext_markdown.convert("::: tests.fixtures.headings\n options:\n heading_level: 2")


@pytest.mark.parametrize("ext_markdown", [{"markdown_extensions": [{"pymdownx.tabbed": {"alternate_style": True}}]}], indirect=["ext_markdown"])
@pytest.mark.parametrize("ext_markdown", [{"markdown_extensions": [{"admonition": {}}]}], indirect=["ext_markdown"])
def test_removing_duplicated_headings(ext_markdown: Markdown) -> None:
"""Assert duplicated headings are removed from the output."""
output = ext_markdown.convert(
dedent(
"""
=== "Tab A"
::: tests.fixtures.headings.heading_1
::: tests.fixtures.headings
!!! note
::: tests.fixtures.headings.heading_2
::: tests.fixtures.headings.heading_3
""",
),
)
assert output.count("Foo") == 1
assert output.count("Bar") == 1
assert output.count("Baz") == 1
assert output.count(">Heading one<") == 1
assert output.count(">Heading two<") == 1
assert output.count(">Heading three<") == 1
assert output.count('class="mkdocstrings') == 0

0 comments on commit 592554c

Please sign in to comment.