|
1 | 1 | # stdlib
|
2 |
| -from typing import Any, Dict, List |
| 2 | +from typing import Any, Dict, List, Tuple |
3 | 3 |
|
4 | 4 | # 3rd party
|
5 | 5 | import sphinx.directives.other
|
6 | 6 | from docutils import nodes
|
7 | 7 | from sphinx.application import Sphinx
|
| 8 | +from sphinx.domains import IndexEntry |
| 9 | +from sphinx.writers.latex import LaTeXTranslator |
8 | 10 |
|
9 | 11 | __all__ = ["TocTreePlusDirective", "setup"]
|
10 | 12 |
|
11 | 13 |
|
| 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) |
| 54 | + |
12 | 55 | # TODO: The first section in a part has all sub sections nested under it in the sidebar,
|
13 | 56 | # The numbering is correct, and its correct in the contents
|
14 | 57 |
|
@@ -42,6 +85,7 @@ def setup(app: Sphinx) -> Dict[str, Any]:
|
42 | 85 | """
|
43 | 86 |
|
44 | 87 | app.add_directive("toctree", TocTreePlusDirective, override=True)
|
| 88 | + LaTeXTranslator.generate_indices = generate_indices |
45 | 89 |
|
46 | 90 | return {
|
47 | 91 | "parallel_read_safe": True,
|
|
0 commit comments