Skip to content

Commit

Permalink
Don't auto-add inline links to ref section & rm if empty, per python#…
Browse files Browse the repository at this point in the history
  • Loading branch information
CAM-Gerlach committed Nov 19, 2021
1 parent c088d64 commit 129ecb2
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 43 deletions.
45 changes: 43 additions & 2 deletions pep2html.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,15 @@
import random
import time
from io import open
from pathlib import Path
try:
from html import escape
except ImportError:
from cgi import escape

from docutils import core, nodes, utils
from docutils.readers import standalone
from docutils.transforms import peps, frontmatter, Transform
from docutils.transforms import frontmatter, misc, peps, Transform
from docutils.parsers import rst

class DataError(Exception):
Expand Down Expand Up @@ -433,6 +434,46 @@ def apply(self):
elif name == 'version' and len(body):
utils.clean_rcs_keywords(para, self.rcs_keyword_substitutions)


class PEPFooter(Transform):
"""Remove the References section if it is empty when rendered."""

# Uses same priority as docutils.transforms.TargetNotes
default_priority = 520

def apply(self):
pep_source_path = Path(self.document["source"])
if not pep_source_path.match("pep-*"):
return # not a PEP file, exit early

doc = self.document
reference_section = None

# Iterate through sections from the end of the document
for i, section in enumerate(reversed(doc)):
if not isinstance(section, nodes.section):
continue
title_words = section[0].astext().lower().split()
if "references" in title_words:
reference_section = section
break

# Remove references section if there are no displayed footnotes
if reference_section:
pending = nodes.pending(
misc.CallBack, details={"callback": _cleanup_callback})
reference_section.append(pending)
self.document.note_pending(pending, priority=1)


def _cleanup_callback(pending):
"""Remove an empty "References" section."""
for footer_node in pending.parent:
if isinstance(footer_node, (nodes.title, nodes.target, nodes.pending)):
return
pending.parent.parent.remove(pending.parent)


class PEPReader(standalone.Reader):

supported = ('pep',)
Expand All @@ -453,7 +494,7 @@ def get_transforms(self):
transforms.remove(frontmatter.DocTitle)
transforms.remove(frontmatter.SectionSubTitle)
transforms.remove(frontmatter.DocInfo)
transforms.extend([PEPHeaders, peps.Contents, peps.TargetNotes])
transforms.extend([PEPHeaders, peps.Contents, PEPFooter])
return transforms

settings_default_overrides = {'pep_references': 1, 'rfc_references': 1}
Expand Down
56 changes: 15 additions & 41 deletions pep_sphinx_extensions/pep_processor/transforms/pep_footer.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,16 @@
from docutils import nodes
from docutils import transforms
from docutils.transforms import misc
from docutils.transforms import references

from pep_sphinx_extensions import config


class PEPFooter(transforms.Transform):
"""Footer transforms for PEPs.
- Appends external links to footnotes.
- Removes the References section if it is empty when rendered.
- Creates a link to the (GitHub) source text.
TargetNotes:
Locate the `References` section, insert a placeholder at the end
for an external target footnote insertion transform, and schedule
the transform to run immediately.
Source Link:
Create the link to the source file from the document source path,
and append the text to the end of the document.
Expand All @@ -36,42 +30,22 @@ def apply(self) -> None:
return # not a PEP file, exit early

doc = self.document[0]
reference_section = copyright_section = None
reference_section = None

# Iterate through sections from the end of the document
num_sections = len(doc)
for i, section in enumerate(reversed(doc)):
if not isinstance(section, nodes.section):
continue
title_words = section[0].astext().lower().split()
if "references" in title_words:
reference_section = section
break
elif "copyright" in title_words:
copyright_section = num_sections - i - 1

# Add a references section if we didn't find one
if not reference_section:
reference_section = nodes.section()
reference_section += nodes.title("", "References")
self.document.set_id(reference_section)
if copyright_section:
# Put the new "References" section before "Copyright":
doc.insert(copyright_section, reference_section)
else:
# Put the new "References" section at end of doc:
doc.append(reference_section)

# Add and schedule execution of the TargetNotes transform
pending = nodes.pending(references.TargetNotes)
reference_section.append(pending)
self.document.note_pending(pending, priority=0)

# If there are no references after TargetNotes has finished, remove the
# references section
pending = nodes.pending(misc.CallBack, details={"callback": _cleanup_callback})
reference_section.append(pending)
self.document.note_pending(pending, priority=1)

# Remove references section if there are no displayed footnotes
if reference_section:
pending = nodes.pending(misc.CallBack, details={"callback": _cleanup_callback})
reference_section.append(pending)
self.document.note_pending(pending, priority=1)

# Add link to source text and last modified date
if pep_source_path.stem != "pep-0000":
Expand All @@ -80,13 +54,13 @@ def apply(self) -> None:


def _cleanup_callback(pending: nodes.pending) -> None:
"""Remove an empty "References" section.
Called after the `references.TargetNotes` transform is complete.
"""
if len(pending.parent) == 2: # <title> and <pending>
pending.parent.parent.remove(pending.parent)
"""Remove an empty "References" section."""
for ref_node in pending.parent:
# Don't remove section if has more than title, link targets and pending
if not isinstance(
ref_node, (nodes.title, nodes.target, nodes.pending)):
return
pending.parent.parent.remove(pending.parent)


def _add_source_link(pep_source_path: Path) -> nodes.paragraph:
Expand Down

0 comments on commit 129ecb2

Please sign in to comment.