11# stdlib
2- from typing import Any , Dict , List , Tuple
2+ from typing import Any , Dict , List
33
44# 3rd party
55import sphinx .directives .other
6+ import sphinx .writers .latex
67from docutils import nodes
78from sphinx .application import Sphinx
8- from sphinx .domains import IndexEntry
9- from sphinx .writers .latex import LaTeXTranslator
109
1110__all__ = ["TocTreePlusDirective" , "setup" ]
1211
1312
14- def generate_indices (translator ) -> str :
15- def generate (content : List [Tuple [str , List [IndexEntry ]]], collapsed : bool ) -> None :
16- ret .append ("\\ bookmarksetupnext{{level=part}}\n " )
17- ret .append ('\\ begin{sphinxtheindex}\n ' )
18- ret .append ('\\ let\\ bigletter\\ sphinxstyleindexlettergroup\n ' )
19- for i , (letter , entries ) in enumerate (content ):
20- if i > 0 :
21- ret .append ('\\ indexspace\n ' )
22- ret .append ('\\ bigletter{%s}\n ' % translator .escape (letter ))
23- for entry in entries :
24- if not entry [3 ]:
25- continue
26- ret .append ('\\ item\\ relax\\ sphinxstyleindexentry{%s}' %
27- translator .encode (entry [0 ]))
28- if entry [4 ]:
29- # add "extra" info
30- ret .append ('\\ sphinxstyleindexextra{%s}' % translator .encode (entry [4 ]))
31- ret .append ('\\ sphinxstyleindexpageref{%s:%s}\n ' %
32- (entry [2 ], translator .idescape (entry [3 ])))
33- ret .append ('\\ end{sphinxtheindex}\n ' )
34-
35- ret = []
36- # latex_domain_indices can be False/True or a list of index names
37- indices_config = translator .builder .config .latex_domain_indices
38- if indices_config :
39- for domain in translator .builder .env .domains .values ():
40- for indexcls in domain .indices :
41- indexname = '%s-%s' % (domain .name , indexcls .name )
42- if isinstance (indices_config , list ):
43- if indexname not in indices_config :
44- continue
45- content , collapsed = indexcls (domain ).generate (
46- translator .builder .docnames )
47- if not content :
48- continue
49- ret .append ('\\ renewcommand{\\ indexname}{%s}\n ' %
50- indexcls .localname )
51- generate (content , collapsed )
52-
53- return '' .join (ret )
13+ class LaTeXTranslator (sphinx .writers .latex .LaTeXTranslator ):
14+
15+ def generate_indices (self ) -> str :
16+
17+ lines = super ().generate_indices ().splitlines ()
18+
19+ return "\n " .join ([
20+ "\\ bookmarksetupnext{{level=part}}\n " ,
21+ * lines ,
22+ '' ,
23+ "\\ bookmarksetupnext{{level=part}}\n " ,
24+ ])
5425
5526# TODO: The first section in a part has all sub sections nested under it in the sidebar,
5627# The numbering is correct, and its correct in the contents
5728
29+
5830class TocTreePlusDirective (sphinx .directives .other .TocTree ):
5931
6032 def run (self ) -> List [nodes .Node ]:
@@ -69,7 +41,11 @@ def run(self) -> List[nodes.Node]:
6941
7042 # TODO: \setcounter{section}{0}
7143 # https://tex.stackexchange.com/questions/271075/reset-counter-section-in-part
72- latex_part_node = nodes .raw (text = f"\\ setcounter{{section}}{{0}}\n \\ bookmarksetupnext{{level=part}}\n \\ part{{{ caption } }}\n \\ setcounter{{chapter}}{{1}}" , format = "latex" )
44+ latex_part_node = nodes .raw (
45+ text =
46+ f"\\ setcounter{{section}}{{0}}\n \\ bookmarksetupnext{{level=part}}\n \\ part{{{ caption } }}\n \\ setcounter{{chapter}}{{1}}" ,
47+ format = "latex"
48+ )
7349 output .append (latex_part_node )
7450 # self.state.nested_parse(StringList(), self.content_offset, latex_part_node)
7551
@@ -85,7 +61,7 @@ def setup(app: Sphinx) -> Dict[str, Any]:
8561 """
8662
8763 app .add_directive ("toctree" , TocTreePlusDirective , override = True )
88- LaTeXTranslator . generate_indices = generate_indices
64+ app . set_translator ( "latex" , LaTeXTranslator , override = True )
8965
9066 return {
9167 "parallel_read_safe" : True ,
0 commit comments