taler-docs

Documentation for GNU Taler components, APIs and protocols
Log | Files | Refs | README | LICENSE

commit c63763d166ed1af1700c61bce3f9e293d18dcb87
parent dcc6149dd47cabba0686d38c24b173823e8ba1d7
Author: Özgür Kesim <oec-taler@kesim.org>
Date:   Mon, 29 Dec 2025 12:49:52 +0100

added sphinx-multitoc-numbering extension locally

Diffstat:
A_exts/sphinx_multitoc_numbering/__init__.py | 130+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 130 insertions(+), 0 deletions(-)

diff --git a/_exts/sphinx_multitoc_numbering/__init__.py b/_exts/sphinx_multitoc_numbering/__init__.py @@ -0,0 +1,130 @@ +# -*- coding: utf-8 -*- +""" + sphinx_multitoc_numbering + ~~~~~~~~~~~~~~~~~~~~~~~~~~ + A sphinx extension for continuous numbering of sections across toctrees. +""" + +from typing import Dict, List, Set, Tuple +from typing import cast + +from docutils import nodes +from docutils.nodes import Element + +from sphinx import addnodes +from sphinx.environment import BuildEnvironment +from sphinx.locale import __ +from sphinx.util import url_re, logging + +logger = logging.getLogger(__name__) + +__version__ = "0.1.3" +"""sphinx-multitoc-numbering version""" + + +def build_init_handler(app): + from sphinx.util.console import bold + + logger.info(bold("sphinx-multitoc-numbering v%s:") + " Loaded", __version__) + + +def assign_section_numbers(self, env: BuildEnvironment) -> List[str]: + """Assign a section number to each heading under a numbered toctree.""" + # a list of all docnames whose section numbers changed + rewrite_needed = [] + + assigned = set() # type: Set[str] + old_secnumbers = env.toc_secnumbers + env.toc_secnumbers = {} + self.last_chapter_number = 0 + + def _walk_toc( + node: Element, secnums: Dict, depth: int, titlenode: nodes.title = None + ) -> None: + # titlenode is the title of the document, it will get assigned a + # secnumber too, so that it shows up in next/prev/parent rellinks + for subnode in node.children: + if isinstance(subnode, nodes.bullet_list): + numstack.append(0) + _walk_toc(subnode, secnums, depth - 1, titlenode) + numstack.pop() + titlenode = None + elif isinstance(subnode, nodes.list_item): + _walk_toc(subnode, secnums, depth, titlenode) + titlenode = None + elif isinstance(subnode, addnodes.only): + # at this stage we don't know yet which sections are going + # to be included; just include all of them, even if it leads + # to gaps in the numbering + _walk_toc(subnode, secnums, depth, titlenode) + titlenode = None + elif isinstance(subnode, addnodes.compact_paragraph): + numstack[-1] += 1 + reference = cast(nodes.reference, subnode[0]) + + # if a new chapter is encountered increment the chapter number + if len(numstack) == 1: + self.last_chapter_number += 1 + if depth > 0: + number = list(numstack) + secnums[reference["anchorname"]] = tuple(numstack) + else: + number = None + secnums[reference["anchorname"]] = None + reference["secnumber"] = number + if titlenode: + titlenode["secnumber"] = number + titlenode = None + elif isinstance(subnode, addnodes.toctree): + _walk_toctree(subnode, depth) + + def _walk_toctree(toctreenode: addnodes.toctree, depth: int) -> None: + if depth == 0: + return + for (title, ref) in toctreenode["entries"]: + if url_re.match(ref) or ref == "self": + # don't mess with those + continue + elif ref in assigned: + logger.warning( + __( + "%s is already assigned section numbers " + "(nested numbered toctree?)" + ), + ref, + location=toctreenode, + type="toc", + subtype="secnum", + ) + elif ref in env.tocs: + secnums = {} # type: Dict[str, Tuple[int, ...]] + env.toc_secnumbers[ref] = secnums + assigned.add(ref) + _walk_toc(env.tocs[ref], secnums, depth, env.titles.get(ref)) + if secnums != old_secnumbers.get(ref): + rewrite_needed.append(ref) + + # rearrange it to respect ordering in toctree directives + rearranged_numbered_toctrees = [] + for toc in env.tocs: + if toc in env.numbered_toctrees: + rearranged_numbered_toctrees.append(toc) + + for docname in rearranged_numbered_toctrees: + assigned.add(docname) + doctree = env.get_doctree(docname) + for toctreenode in doctree.traverse(addnodes.toctree): + depth = toctreenode.get("numbered", 0) + if depth: + # every numbered toctree continues the numbering + numstack = [self.last_chapter_number] + _walk_toctree(toctreenode, depth) + + return rewrite_needed + + +def setup(app): + from sphinx.environment.collectors.toctree import TocTreeCollector + + app.connect("builder-inited", build_init_handler) + TocTreeCollector.assign_section_numbers = assign_section_numbers