From 8af9bf1dadfe5212b79c52a05fa7184831514d36 Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+aa-turner@users.noreply.github.com> Date: Sat, 29 Jan 2022 00:04:56 +0000 Subject: [PATCH] Remove automatic table of contents --- .../pep_processor/parsing/pep_parser.py | 4 +- .../pep_processor/transforms/pep_contents.py | 79 ------------------- .../transforms/pep_section_linker.py | 30 +++++++ .../pep_processor/transforms/pep_title.py | 3 + 4 files changed, 35 insertions(+), 81 deletions(-) delete mode 100644 pep_sphinx_extensions/pep_processor/transforms/pep_contents.py create mode 100644 pep_sphinx_extensions/pep_processor/transforms/pep_section_linker.py diff --git a/pep_sphinx_extensions/pep_processor/parsing/pep_parser.py b/pep_sphinx_extensions/pep_processor/parsing/pep_parser.py index 2ccbd6cb857..2994848c287 100644 --- a/pep_sphinx_extensions/pep_processor/parsing/pep_parser.py +++ b/pep_sphinx_extensions/pep_processor/parsing/pep_parser.py @@ -4,7 +4,7 @@ from sphinx import parsers -from pep_sphinx_extensions.pep_processor.transforms import pep_contents +from pep_sphinx_extensions.pep_processor.transforms import pep_section_linker from pep_sphinx_extensions.pep_processor.transforms import pep_footer from pep_sphinx_extensions.pep_processor.transforms import pep_headers from pep_sphinx_extensions.pep_processor.transforms import pep_title @@ -27,6 +27,6 @@ def get_transforms(self) -> list[type[transforms.Transform]]: return [ pep_headers.PEPHeaders, pep_title.PEPTitle, - pep_contents.PEPContents, + pep_section_linker.PEPSectionLinker, pep_footer.PEPFooter, ] diff --git a/pep_sphinx_extensions/pep_processor/transforms/pep_contents.py b/pep_sphinx_extensions/pep_processor/transforms/pep_contents.py deleted file mode 100644 index db975549f7f..00000000000 --- a/pep_sphinx_extensions/pep_processor/transforms/pep_contents.py +++ /dev/null @@ -1,79 +0,0 @@ -from __future__ import annotations - -from pathlib import Path - -from docutils import nodes -from docutils import transforms -from docutils.transforms import parts - - -class PEPContents(transforms.Transform): - """Add TOC placeholder and horizontal rule after PEP title and headers.""" - - # Use same priority as docutils.transforms.Contents - default_priority = 380 - - def apply(self) -> None: - if not Path(self.document["source"]).match("pep-*"): - return # not a PEP file, exit early - # Create the contents placeholder section - title = nodes.title("", "", nodes.Text("Contents")) - contents_section = nodes.section("", title) - if not self.document.has_name("contents"): - contents_section["names"].append("contents") - self.document.note_implicit_target(contents_section) - - # Add a table of contents builder - pending = nodes.pending(Contents) - contents_section += pending - self.document.note_pending(pending) - - # Insert the toc after title and PEP headers - self.document.children[0].insert(2, contents_section) - - # Add a horizontal rule before contents - transition = nodes.transition() - self.document[0].insert(2, transition) - - -class Contents(parts.Contents): - """Build Table of Contents from document.""" - def __init__(self, document: nodes.document, startnode: nodes.Node | None = None): - super().__init__(document, startnode) - - # used in parts.Contents.build_contents - self.toc_id = None - self.backlinks = None - - def apply(self) -> None: - contents = self.build_contents(self.document[0][4:]) # skip PEP title, headers,
, and contents - if contents: - self.startnode.replace_self(contents) - else: - # if no contents, remove the empty placeholder - self.startnode.parent.parent.remove(self.startnode.parent) - - def build_contents(self, node: nodes.Node | list[nodes.Node], _level: None = None): - entries = [] - children = getattr(node, "children", node) - - for section in children: - if not isinstance(section, nodes.section): - continue - - title = section[0] - - # remove all pre-existing hyperlinks in the title (e.g. PEP references) - while (link_node := title.next_node(nodes.reference)) is not None: - link_node.replace_self(link_node[0]) - ref_id = section['ids'][0] - title["refid"] = ref_id # Add a link to self - entry_text = self.copy_and_filter(title) - reference = nodes.reference("", "", refid=ref_id, *entry_text) - item = nodes.list_item("", nodes.paragraph("", "", reference)) - - item += self.build_contents(section) # recurse to add sub-sections - entries.append(item) - if entries: - return nodes.bullet_list('', *entries) - return [] diff --git a/pep_sphinx_extensions/pep_processor/transforms/pep_section_linker.py b/pep_sphinx_extensions/pep_processor/transforms/pep_section_linker.py new file mode 100644 index 00000000000..a52f37771ea --- /dev/null +++ b/pep_sphinx_extensions/pep_processor/transforms/pep_section_linker.py @@ -0,0 +1,30 @@ +from pathlib import Path + +from docutils import nodes +from docutils import transforms + + +class PEPSectionLinker(transforms.Transform): + """Link section headings to themselves.""" + + default_priority = 720 + + def apply(self) -> None: + if not Path(self.document["source"]).match("pep-*"): + return # not a PEP file, exit early + _link_section_headings(self.document[0][3:]) # skip PEP title, headers, and
+ + +def _link_section_headings(children: list[nodes.Node]): + for section in children: + if not isinstance(section, nodes.section): + continue + + # remove all pre-existing hyperlinks in the title (e.g. PEP references) + title = section[0] + while (link_node := title.next_node(nodes.reference)) is not None: + link_node.replace_self(link_node[0]) + + title["refid"] = section["ids"][0] # Add a link to self + + _link_section_headings(section.children) # recurse to sub-sections diff --git a/pep_sphinx_extensions/pep_processor/transforms/pep_title.py b/pep_sphinx_extensions/pep_processor/transforms/pep_title.py index 14e1190aabc..29c6e893e78 100644 --- a/pep_sphinx_extensions/pep_processor/transforms/pep_title.py +++ b/pep_sphinx_extensions/pep_processor/transforms/pep_title.py @@ -46,6 +46,9 @@ def apply(self) -> None: pep_title_node.extend(document_children) self.document.note_implicit_target(pep_title_node, pep_title_node) + # Add a horizontal rule after title and PEP headers + self.document[0].insert(2, nodes.transition()) + def _line_to_nodes(text: str) -> list[nodes.Node]: """Parse RST string to nodes."""