Making Pyodide (Python in the browser via WebAssembly) play well with scientific Python projects
Jupyter
PyData
Projects and communities: Python Packaging Authority member, a Scientific Python collaborator, on the NumFOCUS Security Committee, and an organiser of SciPy India, PyDelhi, and Write the Docs India
Documentation: Sphinx and its extensions, interactive documentation with JupyterLite, translation infrastructure for scientific projects, and web accessibility
! Undefined control sequence.
l.6 \includegraphic
LaTeX Warning: Reference `fig:diagram'
on page 1 undefined on input line 5.
Output written on broken.pdf (1 page).
…and 139 dreadful lines of logs
A project that stopped shipping PDF documentation: CPython
CPython 3.14 (and later) no longer ships prebuilt PDF documentation. Only HTML archives and an EPUB remain.
An issue titled “Please bring back the PDF documentation” was opened on 8 October 2025. A core developer responded that the PDFs were not well maintained and did not meet the standard of a technical manual.
It was closed on 4 September 2026: “not worth the resources”. A community member now builds the PDFs in a separate repository.
PostgreSQL ships its manual as a PDF with every major release. It has done so since version 8.0 in 2005. Version 18 runs to 3,156 pages, in A4 and US Letter, built from the same DocBook XML as the HTML and the man pages, with xsltproc and Apache FOP.
A tour of the tools
Where you are, and what to try
If you write in
Try
State of play
Sphinx
latexpdf, or rinohtype, or sphinx-simplepdf with WeasyPrint
rinohtype 0.5.6 in May 2026, WeasyPrint 70 in September 2026
MkDocs
mkdocs-print-site-plugin
v2.9 in September 2026. The old pdf-export plugin stopped in 2021
Markdown, mixed sources
Pandoc with --pdf-engine=typst or weasyprint
Pandoc 3.11, native Typst writer
Notebooks
Quarto, or MyST
Quarto 1.9 has a pdf-standard option, MyST 1.11 exports via Typst
or if you’re a reader
Zeal, DevDocs, Foliate, Calibre
Zeal 0.9.1 in July 2026, Calibre 9.15 in September 2026
All of the tools on this slide are FOSS!
What it costs in practice
numpydoc, the tooling behind the NumPy docstring standard, builds a PDF on every pull request:
-name: Setup for doc build run: | sudo apt-get update sudo apt install texlive texlive-latex-extra latexmk dvipng-name: Build documentation run: | make -C doc html SPHINXOPTS="-nT" make -C doc latexpdf SPHINXOPTS="-nT"
SciPy removed its LaTeX build from CI on 27 February 2022: “a LaTeX run for a document with more than 3K pages with questionable quality”, on every run
NumPy builds its two PDFs by hand at release time, following the release walkthrough, and commits them to the docs repository
Built with XeLaTeX from TeX Live. pdfinfo says Tagged: no
Pitfalls
Text you cannot copy back out: Devanagari, ligatures, and long code lines all depend on the font mapping the tool wrote
Figures: SVG is not native to the pipeline. NumPy added an extension in January 2025 so its SVG figures could go into the PDF, and CPython’s PDF target needs the same.
Math and equations: The site uses MathJax, the PDF engine typesets its own. PDF/UA-2 can carry MathML, and only some tools target it
Tagging: Typst tags by default since 0.14. LaTeX tagging left prototype status in TeX Live 2026, with LuaLaTeX. Sphinx’s default pipeline still writes untagged files today
EPUB: Reflows well on phones, but every reader app renders it a little differently
When not to build one
Your content changes daily and readers need the latest version
Your documentation is designed to be interactive or executable
Lack of maintainer time and resources to keep it up to date
“Keeping exported documentation up to date is not a trivial task. Large documentation sets can change frequently, making offline copies outdated almost immediately.”