An Overview of the PEP Rendering System
This document provides an overview of the PEP rendering system, as a companion to PEP 676.
Configuration is stored in three files:
conf.pycontains the majority of the Sphinx configuration
contents.rstcreates the Sphinx-mandated table of contents directive
pep_sphinx_extensions/pep_theme/theme.confsets the Pygments themes
- registers the custom Sphinx extension
- sets both
.rstsuffixes to be parsed as PEPs
- tells Sphinx which source files to use
- registers the PEP theme, maths renderer, and template
- disables some default settings that are covered in the extension
- sets the default and “dark mode” code formatter styles
build.py manages the rendering process.
Usage is covered in Building PEPs Locally.
The Sphinx extension and theme are contained in the
The following is a brief overview of the stages of the PEP rendering process,
and how the extension functions at each point.
3.1 Extension setup
The extension registers several objects:
DirectoryBuilderrun the build process for file- and directory-based building, respectively.
PEPParserregisters the custom document transforms and parses PEPs to a Docutils document.
PEPTranslatorconverts a Docutils document into HTML.
:pep:roles in the reStructuredText source.
The extension also patches default behaviour:
- updating the default settings
- updating the Docutils inliner
- using HTML maths display over MathJax
3.2 Builder initialised
After the Sphinx builder object is created and initialised, we ensure the configuration is correct for the builder chosen.
Currently this involves updating the relative link template.
3.3 Before documents are read
create_pep_zero hook is called. See 5. PEP 0.
3.4 Read document
Parsing the document is handled by
lightweight wrapper over
PEPParser reads the document with leading RFC 2822 headers and registers
the transforms we want to apply.
Transforms are then applied in priority order.
This overrides the built-in
:pep: role to return the correct URL.
PEPs start with a set of RFC 2822 headers, per PEP 1.
This transform validates that the required headers are present and of the
correct data type, and removes headers not for display.
It must run before the
We generate the title node from the parsed title in the PEP headers, and make all nodes in the document children of the new title node. This transform must also handle parsing reStructuredText markup within PEP titles, such as PEP 604.
The automatic table of contents (TOC) is inserted in this transform in a two-part process.
First, the transform inserts a placeholder for the TOC and a horizontal rule after the document title and PEP headers. A callback transform then recursively walks the document to create the TOC, starting from after the placeholder node. Whilst walking the document, all reference nodes in the titles are removed, and titles are given a self-link.
3.5 Prepare for writing
pep_html_builder.FileBuilder.prepare_writing initialises the bare miniumum
of the Docutils writer and the settings for writing documents.
This provides a significant speed-up over the base Sphinx implementation, as
most of the data automatically initialised was unused.
3.6 Translate Docutils to HTML
PEPTranslator overrides paragraph and reference logic to replicate
processing from the previous
Paragraphs are made compact where possible by omitting
<p> tags, and
footnote references are be enclosed in square brackets.
3.7 Prepare for export to Jinja
pep_html_builder, we gather all the parts to be passed to the
This is also where we create the sidebar table of contents.
The HTML files are then written out to the build directory.
The theme is comprised of the HTML template in
pep_sphinx_extensions/pep_theme/templates/page.html and the stylesheets in
The template is entirely self-contained, not relying on any default behaviour from Sphinx. It specifies the CSS files to include, the favicon, and basic semantic information for the document structure.
The styles are defined in two parts:
style.csshandles the meat of the layout
mq.cssadds media queries for a responsive design
5. PEP 0
The generation of the index, PEP 0, happens in three phases. The reStructuredText source file is generated, it is then added to Sphinx, and finally the data is post processed.
5.1 File creation
pep-0000.rst is created during a callback, before documents are loaded by
We first parse the individual PEP files to get the RFC 2822 header, and then parse and validate that metadata.
After collecting and validating all the PEP data, the index itself is created in three steps:
- Output the header text
- Output the category and numerical indices
- Output the author index
AUTHOR_OVERRIDES.csv file can be used to override an author’s name in
the PEP 0 output.
We then add the newly created PEP 0 file to two Sphinx variables so that it will be processed as a normal source document.
5.2 Post processing
PEPHeaders transform schedules the PEP 0 post-processing code.
This serves two functions: masking email addresses and linking numeric
PEP references to the actual documents.
6. RSS Feed
The RSS feed is created by extracting the header metadata and abstract from the ten most recent PEPs.