Skip to content

Commit b5a8cc2

Browse files
committed
refactoring caption code
1 parent 7f741f6 commit b5a8cc2

File tree

4 files changed

+52
-56
lines changed

4 files changed

+52
-56
lines changed

docs/demo/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ the left sidebar to see how various elements look on this theme.
1616
lists_tables
1717
markdown
1818
example_pandas
19+
index2
1920

2021
.. toctree::
2122
:maxdepth: 3

docs/demo/index2.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
A second index
2+
==============
3+
4+
An index to show off level nesting.
5+
6+
.. toctree::
7+
8+
page2

docs/demo/page2.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
A second page
2+
=============
3+
4+
A demo page to see how levels nest within each other in the theme.

pydata_sphinx_theme/__init__.py

Lines changed: 39 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -18,32 +18,6 @@
1818
__version__ = "0.1.1"
1919

2020

21-
class MyTocTree(TocTree):
22-
def get_toctree_for_subpage(
23-
self, pagename, builder, collapse=True, maxdepth=-1, **kwargs
24-
):
25-
"""Return the global TOC nodetree."""
26-
if pagename in ["genindex", "search"]:
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
35-
for toctreenode in doctree.traverse(addnodes.toctree):
36-
toctree = self.resolve(pagename, builder, toctreenode, prune=True, **kwargs)
37-
if toctree:
38-
toctrees.append(toctree)
39-
if not toctrees:
40-
return None
41-
result = toctrees[0]
42-
for toctree in toctrees[1:]:
43-
result.extend(toctree.children)
44-
return result
45-
46-
4721
def add_toctree_functions(app, pagename, templatename, context, doctree):
4822
"""Add functions so Jinja templates can add toctree objects.
4923
@@ -67,7 +41,7 @@ def get_nav_object(maxdepth=None, collapse=True, subpage_caption=False, **kwargs
6741
# The TocTree will contain the full site TocTree including sub-pages.
6842
# "collapse=True" collapses sub-pages of non-active TOC pages.
6943
# maxdepth controls how many TOC levels are returned
70-
toc = MyTocTree(app.env)
44+
toc = TocTree(app.env)
7145
toctree = toc.get_toctree_for(
7246
pagename, app.builder, collapse=collapse, maxdepth=maxdepth, **kwargs
7347
)
@@ -76,32 +50,23 @@ def get_nav_object(maxdepth=None, collapse=True, subpage_caption=False, **kwargs
7650
if toctree is None:
7751
return []
7852

79-
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
97-
)
98-
if subpage_toctree is not None:
99-
# 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
53+
# Grab all of the first-level pages from the index toctree
54+
toctrees_root = app.env.tocs[app.env.config['master_doc']]
55+
first_pages = []
56+
for toctree_root in toctrees_root.traverse(addnodes.toctree):
57+
for _, path_first_page in toctree_root.attributes.get("entries", []):
58+
first_pages.append(path_first_page)
59+
60+
# Now find the toctrees for each first page and see if it has a caption
61+
caption_pages = []
62+
for first_page in first_pages:
63+
toctrees_first_page = app.env.tocs[first_page]
64+
for toctree_first_page in toctrees_first_page.traverse(addnodes.toctree):
65+
# If the toctree has a caption, keep track of the first page
66+
caption = toctree_first_page.attributes.get("caption")
67+
if caption:
68+
_, first_entry = toctree_first_page.attributes.get("entries", [])[0]
69+
caption_pages.append((first_entry, caption))
10570

10671
# toctree has this structure
10772
# <caption>
@@ -111,11 +76,29 @@ def is_first_active_page(node):
11176
# `list_item`s are the actual TOC links and are the only thing we want
11277
toc_items = []
11378
for child in toctree.children:
114-
if isinstance(child, docutils.nodes.caption):
115-
toc_items.append(child)
116-
elif isinstance(child, docutils.nodes.bullet_list):
79+
if isinstance(child, docutils.nodes.bullet_list):
11780
for list_entry in child:
11881
if isinstance(list_entry, docutils.nodes.list_item):
82+
# Grab the toc path relative to the current page
83+
list_entry_ref = list(list_entry.traverse(nodes.reference))[0]
84+
ref_uri = list_entry_ref.attributes.get('refuri')
85+
if ref_uri == "":
86+
# Will be "" for the *current* page
87+
ref_uri = pagename
88+
# Parent folder of current page
89+
path_pagename_parent = Path(pagename).parent.resolve()
90+
# Absolute path of the entry
91+
path_entry = path_pagename_parent.joinpath(Path(ref_uri)).resolve()
92+
# Absolute path of docs root
93+
path_root = Path(app.env.config['master_doc']).parent.resolve()
94+
# Path relative to docs root of the entry
95+
path_entry_rel_root = path_entry.relative_to(path_root).with_suffix("")
96+
97+
# Check whether the entry path is one of the pages that should have a caption first
98+
for path_caption_page, icaption in caption_pages:
99+
if path_caption_page == str(path_entry_rel_root):
100+
toc_items.append({'caption': icaption})
101+
119102
toc_items.append(list_entry)
120103

121104
# Now convert our docutils nodes into dicts that Jinja can use

0 commit comments

Comments
 (0)