|
20 | 20 |
|
21 | 21 | class MyTocTree(TocTree):
|
22 | 22 | def get_toctree_for_subpage(
|
23 |
| - self, pagename, builder, collapse=True, maxdepth=-1, **kwargs |
| 23 | + self, toctree_page, current_page, builder, collapse=True, maxdepth=-1, **kwargs |
24 | 24 | ):
|
25 | 25 | """Return the global TOC nodetree."""
|
26 |
| - if pagename in ["genindex", "search"]: |
| 26 | + if current_page in ["genindex", "search"]: |
27 | 27 | return
|
28 |
| - doctree = self.env.get_doctree(pagename) |
29 |
| - toctrees = [] # type: List[Element] |
30 |
| - if "includehidden" not in kwargs: |
31 |
| - kwargs["includehidden"] = True |
32 |
| - if "maxdepth" not in kwargs: |
33 |
| - kwargs["maxdepth"] = 0 |
34 |
| - kwargs["collapse"] = collapse |
| 28 | + doctree = self.env.get_doctree( |
| 29 | + toctree_page |
| 30 | + ) # current_page should be the "first active page" |
| 31 | + toctrees = [] |
35 | 32 | for toctreenode in doctree.traverse(addnodes.toctree):
|
36 |
| - toctree = self.resolve(pagename, builder, toctreenode, prune=True, **kwargs) |
| 33 | + toctree = self.resolve( |
| 34 | + current_page, builder, toctreenode, prune=True, **kwargs |
| 35 | + ) |
37 | 36 | if toctree:
|
38 | 37 | toctrees.append(toctree)
|
39 | 38 | if not toctrees:
|
40 | 39 | return None
|
41 |
| - result = toctrees[0] |
| 40 | + toctree_subpage = toctrees[0] |
42 | 41 | for toctree in toctrees[1:]:
|
43 |
| - result.extend(toctree.children) |
44 |
| - return result |
| 42 | + toctree_subpage.extend(toctree.children) |
| 43 | + return toctree_subpage |
45 | 44 |
|
46 | 45 |
|
47 | 46 | def add_toctree_functions(app, pagename, templatename, context, doctree):
|
@@ -77,31 +76,48 @@ def get_nav_object(maxdepth=None, collapse=True, subpage_caption=False, **kwargs
|
77 | 76 | return []
|
78 | 77 |
|
79 | 78 | if subpage_caption:
|
80 |
| - if pagename not in [app.env.config.master_doc, "genindex", "search"]: |
81 |
| - def is_first_active_page(node): |
82 |
| - return isinstance(node, nodes.bullet_list) and node.attributes.get("iscurrent") |
83 |
| - |
84 |
| - active_first_page = list(toctree.traverse(is_first_active_page))[0] |
85 |
| - # A path to the active TOC item's first page, relative to the current page |
86 |
| - first_page_path = list(active_first_page.traverse(nodes.reference))[0].attributes.get("refuri") |
87 |
| - if first_page_path == "": |
88 |
| - # First TOC item's first page *is* the active page |
89 |
| - first_page_path = Path(pagename).name |
90 |
| - else: |
91 |
| - first_page_path = Path(first_page_path).with_suffix("") |
92 |
| - rel_first_page_path = str(Path(pagename).parent.joinpath(first_page_path)) |
93 |
| - |
94 |
| - # We only wish to show a single page's descendants, so we'll keep their captions |
95 |
| - subpage_toctree = toc.get_toctree_for_subpage( |
96 |
| - rel_first_page_path, app.builder, collapse=collapse, maxdepth=maxdepth, **kwargs |
| 79 | + |
| 80 | + def is_level1_page(node): |
| 81 | + return isinstance( |
| 82 | + node, nodes.list_item |
| 83 | + ) and "toctree-l1" in node.attributes.get("classes") |
| 84 | + |
| 85 | + # Grab all of the first-level pages from the index toctree |
| 86 | + toctree_root = toc.get_toctree_for( |
| 87 | + app.env.config.master_doc, |
| 88 | + app.builder, |
| 89 | + collapse=collapse, |
| 90 | + maxdepth=maxdepth, |
| 91 | + **kwargs, |
| 92 | + ) |
| 93 | + first_pages = toctree_root.traverse(is_level1_page) |
| 94 | + # For each page in the top toctree, access the page-specific toctree |
| 95 | + for first_page in first_pages: |
| 96 | + # First reference will be for the top page |
| 97 | + first_page_ref = list(first_page.traverse(nodes.reference))[0] |
| 98 | + first_page_path = first_page_ref.attributes.get("refuri").rsplit( |
| 99 | + ".html", 1 |
| 100 | + )[0] |
| 101 | + |
| 102 | + # Grab the toctree for this page, with links relative from current page |
| 103 | + first_page_toctree = toc.get_toctree_for_subpage( |
| 104 | + first_page_path, |
| 105 | + pagename, |
| 106 | + app.builder, |
| 107 | + collapse=collapse, |
| 108 | + maxdepth=maxdepth - 1, |
| 109 | + **kwargs, |
97 | 110 | )
|
98 |
| - if subpage_toctree is not None: |
| 111 | + |
| 112 | + if first_page_toctree is not None: |
99 | 113 | # Find the current page in the top-level children
|
100 |
| - for item in toctree.children: |
101 |
| - if isinstance(item, nodes.bullet_list) and item.attributes.get("iscurrent", []): |
102 |
| - # Append that pages' toctree so we get captions |
103 |
| - subpage_list = item.children[0] |
104 |
| - subpage_list.children = [subpage_list.children[0]] + subpage_toctree.children |
| 114 | + for page in toctree.traverse(is_level1_page): |
| 115 | + toc_page_ref = list(page.traverse(nodes.reference))[0] |
| 116 | + page_uri = toc_page_ref.attributes.get("refuri").rsplit( |
| 117 | + ".html", 1 |
| 118 | + )[0] |
| 119 | + if page_uri == first_page_path: |
| 120 | + page.children = first_page_toctree.children |
105 | 121 |
|
106 | 122 | # toctree has this structure
|
107 | 123 | # <caption>
|
|
0 commit comments