From d70dd5495d0723b75be7c1d6854a88aa95cd836e Mon Sep 17 00:00:00 2001 From: Igor Susic Date: Fri, 26 Jun 2026 10:05:36 +0200 Subject: [PATCH] Add PDF build via Sphinx + XeLaTeX --- conf.py | 26 ++++++++++ docs/BUILDING_PDF.md | 117 +++++++++++++++++++++++++++++++++++++++++++ scripts/build-pdf.sh | 49 ++++++++++++++++++ 3 files changed, 192 insertions(+) create mode 100644 docs/BUILDING_PDF.md create mode 100755 scripts/build-pdf.sh diff --git a/conf.py b/conf.py index 0a03f5a5..e15e8e81 100644 --- a/conf.py +++ b/conf.py @@ -7,6 +7,30 @@ copyright = "2026, MLC Community" release = "0.0.1" +# Unicode symbols (≈, ×, ≤, →, etc.) in the text require a Unicode-aware engine; +# pdflatex chokes on them. xelatex handles them natively. +latex_engine = "xelatex" + +# Sphinx's xelatex default uses GNU FreeFont (FreeSerif/FreeSans/FreeMono), which +# BasicTeX doesn't ship. Use the tex-gyre fonts (already installed) instead, and +# let xelatex fall back to a system font for any glyphs they lack. +latex_elements = { + "fontpkg": r""" +\setmainfont{texgyretermes-regular.otf}[ + BoldFont=texgyretermes-bold.otf, + ItalicFont=texgyretermes-italic.otf, + BoldItalicFont=texgyretermes-bolditalic.otf] +\setsansfont{texgyreheros-regular.otf}[ + BoldFont=texgyreheros-bold.otf, + ItalicFont=texgyreheros-italic.otf, + BoldItalicFont=texgyreheros-bolditalic.otf] +\setmonofont{texgyrecursor-regular.otf}[ + BoldFont=texgyrecursor-bold.otf, + ItalicFont=texgyrecursor-italic.otf, + BoldItalicFont=texgyrecursor-bolditalic.otf] +""", +} + extensions = ["myst_parser", "sphinx_copybutton"] # Markdown (MyST) is the primary source format. @@ -57,3 +81,5 @@ "use_download_button": False, "use_fullscreen_button": False, } + +extensions = ["myst_parser", "sphinx_copybutton", "sphinxcontrib.rsvgconverter"] diff --git a/docs/BUILDING_PDF.md b/docs/BUILDING_PDF.md new file mode 100644 index 00000000..c1266db2 --- /dev/null +++ b/docs/BUILDING_PDF.md @@ -0,0 +1,117 @@ +# Building the book as a PDF + +The book is a Sphinx + MyST-Markdown project that normally builds to **HTML** +(`sphinx-build -b html . _build/html`). This doc explains how to also produce a +**PDF** via the LaTeX builder. + +> TL;DR — once prerequisites are installed: +> ```bash +> ./scripts/build-pdf.sh +> open _build/latex/moderngpuprogrammingformlsys.pdf +> ``` + +## How it works + +`Sphinx (LaTeX builder) -> .tex -> xelatex (latexmk) -> PDF` + +We use **XeLaTeX**, not the default pdfLaTeX, because the text contains Unicode +symbols (`≈ × ≤ → …`) that pdfLaTeX cannot typeset. SVG figures are converted to +PDF on the fly via `rsvg-convert`. + +`conf.py` already contains the needed settings: + +```python +latex_engine = "xelatex" +latex_elements = { + "fontpkg": r""" +\setmainfont{texgyretermes-regular.otf}[ ... ] +\setsansfont{texgyreheros-regular.otf}[ ... ] +\setmonofont{texgyrecursor-regular.otf}[ ... ] +""", +} +# extensions list also includes "sphinxcontrib.rsvgconverter" +``` + +The tex-gyre fonts are referenced **by OTF filename** because a minimal TeX +install (BasicTeX) doesn't ship Sphinx's default GNU FreeFont, and the font +database doesn't always resolve tex-gyre by family name. + +## Prerequisites (one-time) + +These need admin rights (`brew`, `sudo tlmgr`) and a fair amount of download. + +### 1. Python build deps +```bash +pip install sphinx myst-parser sphinx-copybutton sphinxcontrib-svg2pdfconverter +``` + +### 2. A TeX distribution (provides xelatex + latexmk) +```bash +brew install --cask basictex # ~100 MB minimal TeX (or 'mactex' for the full ~5 GB) +# put TeX on PATH for the current shell: +eval "$(/usr/libexec/path_helper)" +export PATH="/Library/TeX/texbin:$PATH" +``` + +### 3. LaTeX packages Sphinx's output needs +```bash +sudo tlmgr update --self +sudo tlmgr install latexmk tex-gyre fncychap wrapfig capt-of needspace \ + tabulary varwidth titlesec framed upquote +``` +If a later build complains `LaTeX Error: File 'xxx.sty' not found`, install it: +`sudo tlmgr install xxx`. + +### 4. SVG -> PDF converter (for the figures) +```bash +brew install librsvg # provides rsvg-convert +``` + +## Build + +```bash +./scripts/build-pdf.sh +``` + +or manually: + +```bash +export PATH="/Library/TeX/texbin:$PATH" +sphinx-build -b latex . _build/latex +cd _build/latex && make # latexmk drives xelatex (multiple passes for TOC/refs) +``` + +**Output:** `_build/latex/moderngpuprogrammingformlsys.pdf` + +`_build/` is gitignored, so the PDF is a local artifact — it is not committed. + +## Known limitations of the PDF + +1. **Interactive demos are missing.** The book embeds self-contained HTML/JS + slide demos via `