Sphinx PDF Improvements

Generating documents only via the Sphinx HTML builder then building PDFs from that allows us to bypass LaTeX completely whilst retaining strong math and table functions.

Background

Previously, I worked hard to try and remove PDFs from my documentation workflows. This was due to the exponential complexity required with technical documents (hundreds of pages) and the general building and testing pipeline. Unfortunately, LaTeX was the only suitable builder thanks to its superior math and table handling.

PDFs are still useful -- as documentation for on-site machines that require checklists etc are often printed out and signed.

The tweak

Using Sphinx, we can generate our document using the singlehtml builder only. This also helps as when we develop some custom functions, we only have to make it work with one builder.

The change is that we then use weasyprint HTML --> PDF to generate a PDF from that HTML output. This reduces complexity as we are now only really dealing with Python and HTML instead of LaTeX and .tex files.

We have a Python build script that calls the Sphinx singlehtml builder with some functions added for the cover page and.. whatever else we can think of.

It's also lightning fast compared to LaTeX build times for large documents.

The one difficult part was getting similar LaTeX math functionality. For this, we use the imgmath extension and it corresponding format.

extensions = [
    ...
    'sphinx.ext.imgmath',
    ]

imgmath_image_format = 'svg'

I also had to inject some post-html build functions (namely cover page, toctree, variables) e.g.,

def build_one(folder: str, out: Path) -> str | None:
    clean_doc(out)
    if not build_doc(folder, out):
        return None
    post_process(out)
    inject_cover_page(folder, out)
    inject_toctree_break(out)
    inject_variables(folder, out)
    inject_css_variables(folder, out)
    remove_top_h1(out)
    return generate_pdf(folder, out)

So finally.. yes I'm happy to generate PDFs again.