Skip to content

Commit

Permalink
DOP-4967: Contextualize headings in method selector for "On This Page…
Browse files Browse the repository at this point in the history
…" list (#620)

* selector id

* tests

* refine scanned pattern

* adding test
  • Loading branch information
mayaraman19 authored Sep 20, 2024
1 parent 45d4a43 commit bdd1428
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 2 deletions.
18 changes: 17 additions & 1 deletion snooty/postprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -470,13 +470,15 @@ class HeadingData(NamedTuple):
depth: int
id: str
title: Sequence[n.InlineNode]
selector_id: Optional[str]

def __init__(self, context: Context) -> None:
super().__init__(context)
self.contents_depth = sys.maxsize
self.current_depth = 0
self.has_contents_directive = False
self.headings: List[ContentsHandler.HeadingData] = []
self.scanned_pattern: List[str] = []

def enter_page(self, fileid_stack: FileIdStack, page: Page) -> None:
self.contents_depth = sys.maxsize
Expand All @@ -494,6 +496,7 @@ def exit_page(self, fileid_stack: FileIdStack, page: Page) -> None:
"depth": h.depth,
"id": h.id,
"title": [node.serialize() for node in h.title],
"selector_id": h.selector_id,
}
for h in self.headings
if h.depth - 1 <= self.contents_depth
Expand All @@ -506,6 +509,9 @@ def enter_node(self, fileid_stack: FileIdStack, node: n.Node) -> None:
self.current_depth += 1
return

if isinstance(node, n.Directive) and node.name == "method-option":
self.scanned_pattern.append(node.options["id"])

if isinstance(node, n.Directive) and node.name == "contents":
if self.has_contents_directive:
self.context.diagnostics[fileid_stack.current].append(
Expand All @@ -520,10 +526,17 @@ def enter_node(self, fileid_stack: FileIdStack, node: n.Node) -> None:
if self.current_depth - 1 > self.contents_depth:
return

selector_id = None
if len(self.scanned_pattern) > 0:
for item in self.scanned_pattern:
selector_id = item

# Omit title headings (depth = 1) from heading list
if isinstance(node, n.Heading) and self.current_depth > 1:
self.headings.append(
ContentsHandler.HeadingData(self.current_depth, node.id, node.children)
ContentsHandler.HeadingData(
self.current_depth, node.id, node.children, selector_id
)
)

if isinstance(node, n.Directive) and node.name == "collapsible":
Expand All @@ -533,10 +546,13 @@ def enter_node(self, fileid_stack: FileIdStack, node: n.Node) -> None:
self.current_depth + 1,
node.options["id"],
[n.Text(node.span, node.options["heading"])],
selector_id,
)
)

def exit_node(self, fileid_stack: FileIdStack, node: n.Node) -> None:
if isinstance(node, n.Directive) and node.name == "method-option":
self.scanned_pattern.pop()
if isinstance(node, n.Section):
self.current_depth -= 1

Expand Down
97 changes: 96 additions & 1 deletion snooty/test_postprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -2347,7 +2347,7 @@ def test_contents_directive() -> None:
check_ast_testing_string(
page.ast,
"""
<root fileid="page.txt" headings="[{'depth': 2, 'id': 'first-heading', 'title': [{'type': 'text', 'position': {'start': {'line': 9}}, 'value': 'First Heading'}]}, {'depth': 3, 'id': 'second-heading', 'title': [{'type': 'text', 'position': {'start': {'line': 12}}, 'value': 'Second Heading'}]}, {'depth': 2, 'id': 'third-heading', 'title': [{'type': 'text', 'position': {'start': {'line': 18}}, 'value': 'Third Heading'}]}]">
<root fileid="page.txt" headings="[{'depth': 2, 'id': 'first-heading', 'title': [{'type': 'text', 'position': {'start': {'line': 9}}, 'value': 'First Heading'}], 'selector_id': None}, {'depth': 3, 'id': 'second-heading', 'title': [{'type': 'text', 'position': {'start': {'line': 12}}, 'value': 'Second Heading'}], 'selector_id': None}, {'depth': 2, 'id': 'third-heading', 'title': [{'type': 'text', 'position': {'start': {'line': 18}}, 'value': 'Third Heading'}], 'selector_id': None}]">
<section>
<heading id="title"><text>Title</text></heading>
<directive name="contents" depth="2" />
Expand Down Expand Up @@ -3512,6 +3512,7 @@ def test_collapsible_headings() -> None:
"value": "Subsection heading",
}
],
"selector_id": None,
},
{
"depth": 3,
Expand All @@ -3523,6 +3524,7 @@ def test_collapsible_headings() -> None:
"value": "Subsubsection heading",
}
],
"selector_id": None,
},
]

Expand Down Expand Up @@ -3574,6 +3576,7 @@ def test_collapsible_headings() -> None:
"value": "Subsection heading",
}
],
"selector_id": None,
}
]

Expand Down Expand Up @@ -3611,6 +3614,7 @@ def test_collapsible_headings() -> None:
"value": "Collapsible heading",
}
],
"selector_id": None,
}
]

Expand Down Expand Up @@ -3959,6 +3963,97 @@ def test_method_selector() -> None:
)


def test_method_selector_headings() -> None:
with make_test(
{
Path(
"source/index.txt"
): """
.. contents::
:depth: 2
===================
Heading of the page
===================
Subsection heading
------------------
.. method-selector::
.. method-option::
:id: driver
WHAT
~~~~
.. method-description::
This is an optional description. Learn more about drivers at `MongoDB Documentation <https://www.mongodb.com/docs/drivers/>`__.
This is content in the Driver method haha.
.. method-option::
:id: cli
This is a heading
~~~~~~~~~~~~~~~~~
.. method-description::
This is a description under the heading for cli.
This is content in the CLI method haha.
.. method-option::
:id: mongosh
Foo
""",
}
) as result:
page = result.pages[FileId("index.txt")]
assert (page.ast.options.get("headings")) == [
{
"depth": 2,
"id": "subsection-heading",
"title": [
{
"type": "text",
"position": {"start": {"line": 9}},
"value": "Subsection heading",
}
],
"selector_id": None,
},
{
"depth": 3,
"id": "what",
"selector_id": "driver",
"title": [
{
"position": {"start": {"line": 17}},
"type": "text",
"value": "WHAT",
}
],
},
{
"depth": 3,
"id": "this-is-a-heading",
"selector_id": "cli",
"title": [
{
"position": {"start": {"line": 29}},
"type": "text",
"value": "This is a heading",
}
],
},
]


def test_multi_page_tutorials() -> None:
test_page_template = """
.. multi-page-tutorial::
Expand Down

0 comments on commit bdd1428

Please sign in to comment.