Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add PEP titles and sections as reference title text #2366

Merged
merged 2 commits into from
Feb 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions pep_sphinx_extensions/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from pep_sphinx_extensions.pep_processor.html import pep_html_translator
from pep_sphinx_extensions.pep_processor.parsing import pep_parser
from pep_sphinx_extensions.pep_processor.parsing import pep_role
from pep_sphinx_extensions.pep_processor.transforms import pep_references
from pep_sphinx_extensions.pep_zero_generator.pep_index_generator import create_pep_zero

if TYPE_CHECKING:
Expand All @@ -28,6 +29,7 @@ def _depart_maths():


def _update_config_for_builder(app: Sphinx):
app.env.document_ids = {} # For PEPReferenceRoleTitleText
if app.builder.name == "dirhtml":
app.env.settings["pep_url"] = "../pep-{:0>4}"

Expand All @@ -49,6 +51,8 @@ def setup(app: Sphinx) -> dict[str, bool]:

app.add_role("pep", pep_role.PEPRole(), override=True) # Transform PEP references to links

app.add_post_transform(pep_references.PEPReferenceRoleTitleText)

# Register event callbacks
app.connect("builder-inited", _update_config_for_builder) # Update configuration values for builder used
app.connect("env-before-read-docs", create_pep_zero) # PEP 0 hook
Expand Down
35 changes: 28 additions & 7 deletions pep_sphinx_extensions/pep_processor/parsing/pep_role.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,35 @@
from docutils import nodes
from sphinx import roles


class PEPRole(roles.PEP):
class PEPRole(roles.ReferenceRole):
"""Override the :pep: role"""
# TODO override the entire thing (internal should be True)

def build_uri(self) -> str:
"""Get PEP URI from role text."""
def run(self) -> tuple[list[nodes.Node], list[nodes.system_message]]:
# Get PEP URI from role text.
pep_str, _, fragment = self.target.partition("#")
pep_base = self.inliner.document.settings.pep_url.format(int(pep_str))
try:
pep_num = int(pep_str)
except ValueError:
msg = self.inliner.reporter.error(f'invalid PEP number {self.target}', line=self.lineno)
prb = self.inliner.problematic(self.rawtext, self.rawtext, msg)
return [prb], [msg]
pep_base = self.inliner.document.settings.pep_url.format(pep_num)
if fragment:
return f"{pep_base}#{fragment}"
return pep_base
ref_uri = f"{pep_base}#{fragment}"
else:
ref_uri = pep_base
if self.has_explicit_title:
title = self.title
else:
title = f"PEP {pep_num}"

return [
nodes.reference(
"", title,
internal=True,
refuri=ref_uri,
classes=["pep"],
_title_tuple=(pep_num, fragment)
)
], []
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from pathlib import Path

from docutils import nodes
from docutils import transforms


class PEPReferenceRoleTitleText(transforms.Transform):
"""Add title text of document titles to reference role references."""

default_priority = 730

def apply(self) -> None:
if not Path(self.document["source"]).match("pep-*"):
return # not a PEP file, exit early
for node in self.document.findall(nodes.reference):
if "_title_tuple" not in node:
continue

# get pep number and section target (fragment)
pep_num, fragment = node.attributes.pop("_title_tuple")
filename = f"pep-{pep_num:0>4}"

# Cache target_ids
env = self.document.settings.env
try:
target_ids = env.document_ids[filename]
except KeyError:
env.document_ids[filename] = target_ids = env.get_doctree(filename).ids

# Create title text string. We hijack the 'reftitle' attribute so
# that we don't have to change things in the HTML translator
node["reftitle"] = env.titles[filename].astext()
try:
node["reftitle"] += f" § {target_ids[fragment][0].astext()}"
except KeyError:
pass