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-
4721def 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