docs: Studio's PDF export needs LaTeX, in AGENTS.md and Dockerfile.base too
Lint / skill-floor (push) Successful in 9s
Lint / hadolint (push) Successful in 12s
Lint / doc-drift (push) Successful in 14s
Lint / actionlint (push) Successful in 22s

AGENTS.md ("What we DON'T install") and two comments in Dockerfile.base's
typst block still said pi-studio's PDF export uses typst. Same correction
as 77929b7 for the README. AGENTS.md also warns maintainers not to ship
ENV PANDOC_PDF_ENGINE=typst, since pi-studio's LaTeX header is printed as
page text under typst while pandoc exits 0.

Corrects 77929b7: "texlive-xetex alone is not enough" holds only with
--no-install-recommends. With apt's defaults, texlive-xetex (and the old
AGENTS recipe, texlive-xetex texlive-latex-recommended: the same set) works,
but installs 202 packages / 1053 MB including systemd, D-Bus and a JRE.
The README recipe (4 packages, --no-install-recommends) is 37 / 491 MB.
All three recipes measured from the image's 401 packages on v1.11.2 +
pi-studio 0.10.1, checking the exported page, not only the exit code.

Dockerfile.base changes are comments only, but base_tag hashes the whole
file; the next release rebuilds the base anyway.
This commit is contained in:
2026-10-15 01:04:40 +02:00
parent 77929b73df
commit 5becbba6c8
4 changed files with 54 additions and 27 deletions
+18 -8
View File
@@ -354,14 +354,24 @@ deprecated artifacts (to be removed in opencode-devbox v2.0.0).
## What we DON'T install (and why) ## What we DON'T install (and why)
- **No texlive** (~600 MB–1 GB). PDF export from pandoc / pi-studio works - **No texlive** (~0.5–1 GB). The base ships **`typst`** (~30 MB static
out of the box via **`typst`** (~30 MB static binary), which the base ships binary) as a PDF engine for pandoc, so
as the pandoc PDF engine (`pandoc --pdf-engine=typst`) — small enough to live `pandoc doc.md --pdf-engine=typst -o doc.pdf` works out of the box. That
in base rather than a dedicated `:latest-studio-tex` variant. We don't bake in covers the common Markdown→PDF case, small enough to live in base rather
a full TeX Live: it's heavy and typst covers the common Markdown→PDF case. than in a dedicated `:latest-studio-tex` variant. Callers must ask for
Users needing LaTeX-exact output can install the higher-fidelity fallback on typst: pandoc's own default engine is `pdflatex`, which is not installed.
demand: `sudo apt-get install texlive-xetex texlive-latex-recommended` (then **pi-studio's PDF export (`/studio-pdf`, `studio_export_pdf`) does not use
`pandoc --pdf-engine=xelatex`). typst.** It runs pandoc with `$PANDOC_PDF_ENGINE`, defaulting to `xelatex`,
so in this image it fails with `xelatex not found`. Do not "fix" that with
`ENV PANDOC_PDF_ENGINE=typst`. pi-studio adds its own LaTeX header to the
document, and typst prints that header as page text while pandoc exits 0.
That ENV only becomes a fix once pi-studio stops sending its LaTeX header
to non-LaTeX engines. Until then, users who need Studio's PDF export, or
LaTeX output, install TeX Live on demand with the recipe in README
"PDF export from Studio needs LaTeX" (37 packages, ~490 MB with
`--no-install-recommends`). A plain `sudo apt-get install texlive-xetex`
also works, but its recommends make it 202 packages and ~1 GB, including
systemd and a Java runtime.
- **pi-studio** ships in the `:latest-studio` variant (since v1.1.0), - **pi-studio** ships in the `:latest-studio` variant (since v1.1.0),
vendored to `/opt/pi-studio` and registered at container start via vendored to `/opt/pi-studio` and registered at container start via
`pi install /opt/pi-studio` (see Dockerfile.variant `INSTALL_STUDIO`). `pi install /opt/pi-studio` (see Dockerfile.variant `INSTALL_STUDIO`).
+17 -8
View File
@@ -84,15 +84,24 @@ base** rather than reusing `base-6f3b20266de1`.
(unless the document sets `header-includes`). Under typst, pandoc exits (unless the document sets `header-includes`). Under typst, pandoc exits
0 and prints that header as text above the first heading. Seen in the same PDF through two renderers, MuPDF and 0 and prints that header as text above the first heading. Seen in the same PDF through two renderers, MuPDF and
Chromium. Chromium.
- **`texlive-xetex` alone, which the README offered as the fallback, is - **`texlive-xetex`, the README's old fallback, works but is twice the
not enough.** The export then still lacks `lmodern.sty`, `ulem.sty` size it needs to be.** Installed with apt's defaults it pulls in its
and the `pzdr` font. Adding `lmodern texlive-plain-generic recommends: 202 packages and 1053 MB, including systemd, D-Bus and a
texlive-fonts-recommended` makes it work: 37 packages and 491 MB Java runtime (`openjdk-21-jre-headless`, 194 MB). The same 202 come from
installed, after `apt-get update`. Measured on v1.11.2 with pi-studio the old `AGENTS.md` recipe, `texlive-xetex texlive-latex-recommended`.
0.10.1. The exported page was looked at, not only its exit code. With `--no-install-recommends`, `texlive-xetex` alone is not enough:
the export then lacks `lmodern.sty`, `ulem.sty` and the `pzdr` font.
The README's recipe adds the three packages that provide them,
`lmodern texlive-plain-generic texlive-fonts-recommended`, and comes to
37 packages and 491 MB, after `apt-get update`. Each recipe was
measured from the image's own 401 packages on v1.11.2 with pi-studio
0.10.1, and the exported page was looked at, not only its exit code.
The same claim also appears in `AGENTS.md` ("What we DON'T install") and The same claim is corrected in `AGENTS.md` ("What we DON'T install"),
in comments in `Dockerfile.base`. Neither is changed here. which now also warns against `ENV PANDOC_PDF_ENGINE=typst`, and in two
comments in `Dockerfile.base`'s typst block. `base_tag` hashes all of
`Dockerfile.base`, comments included, so this changes the base hash too.
The base is rebuilt in the next release anyway (above).
## v1.11.2 — 2026-10-14 ## v1.11.2 — 2026-10-14
+12 -7
View File
@@ -822,12 +822,16 @@ RUN ARCH=$(case "${TARGETARCH}" in amd64) echo "x86_64" ;; arm64) echo "aarch64"
# ── typst — lightweight PDF engine for pandoc (Markdown→PDF) ───────── # ── typst — lightweight PDF engine for pandoc (Markdown→PDF) ─────────
# pandoc (apt-installed above) is only a front-end; rendering PDF needs a # pandoc (apt-installed above) is only a front-end; rendering PDF needs a
# back-end engine. Rather than a ~600 MB TeX Live install, we ship typst: # back-end engine. Rather than a ~0.5–1 GB TeX Live install, we ship typst:
# a single ~30 MB static Rust binary with no LaTeX dependency. pi-studio's # a single ~30 MB static Rust binary with no LaTeX dependency. Callers must
# PDF export (studio_export_pdf) and pandoc invocations use it via # ask for it with `pandoc --pdf-engine=typst`, because pandoc's own default
# `pandoc --pdf-engine=typst`. A fuller TeX Live remains the higher- # engine is pdflatex, which is not installed. pi-studio's PDF export
# fidelity fallback for anyone who needs LaTeX-exact output (not shipped # (studio_export_pdf, /studio-pdf) does NOT use typst. It runs pandoc with
# here — install on demand or in a future variant). # $PANDOC_PDF_ENGINE, defaulting to xelatex, so it fails with "xelatex not
# found". Setting PANDOC_PDF_ENGINE=typst is not a fix: pi-studio adds its
# own LaTeX header, and typst prints that header as page text while pandoc
# exits 0. TeX Live is not shipped here; README "PDF export from Studio needs
# LaTeX" has the on-demand recipe (~490 MB).
# #
# Follows the `latest` GitHub-release convention (like tealdeer/uv/bat). # Follows the `latest` GitHub-release convention (like tealdeer/uv/bat).
# typst ships a `.tar.xz` asset (hence xz-utils in the apt layer above) # typst ships a `.tar.xz` asset (hence xz-utils in the apt layer above)
@@ -839,7 +843,8 @@ RUN ARCH=$(case "${TARGETARCH}" in amd64) echo "x86_64" ;; arm64) echo "aarch64"
# document font to an empty tuple (`font: ()`), so a naked # document font to an empty tuple (`font: ()`), so a naked
# `pandoc --pdf-engine=typst` fails with "font fallback list must not be empty" # `pandoc --pdf-engine=typst` fails with "font fallback list must not be empty"
# unless the caller passes `-V mainfont=...`. We default it to Libertinus Serif # unless the caller passes `-V mainfont=...`. We default it to Libertinus Serif
# (typst's own bundled default font) so PDF export works out-of-the-box. # (typst's own bundled default font) so a naked `pandoc --pdf-engine=typst`
# works out of the box.
ARG TYPST_VERSION=latest ARG TYPST_VERSION=latest
RUN ARCH=$(case "${TARGETARCH}" in amd64) echo "x86_64" ;; arm64) echo "aarch64" ;; *) echo "x86_64" ;; esac) && \ RUN ARCH=$(case "${TARGETARCH}" in amd64) echo "x86_64" ;; arm64) echo "aarch64" ;; *) echo "x86_64" ;; esac) && \
V="${TYPST_VERSION}" && \ V="${TYPST_VERSION}" && \
+7 -4
View File
@@ -380,10 +380,13 @@ There are two ways out:
texlive-xetex lmodern texlive-plain-generic texlive-fonts-recommended texlive-xetex lmodern texlive-plain-generic texlive-fonts-recommended
``` ```
`texlive-xetex` on its own is not enough. Studio's export then still lacks The image starts with an empty package index, so run `apt-get update`
`lmodern.sty`, `ulem.sty` and the `pzdr` font, which come from the other first. With `--no-install-recommends`, `texlive-xetex` on its own is not
three packages. The image starts with an empty package index, so run enough: Studio's export then lacks `lmodern.sty`, `ulem.sty` and the `pzdr`
`apt-get update` first. (Measured on v1.11.2 with pi-studio 0.10.1.) font, which the other three packages provide. A plain
`sudo apt-get install texlive-xetex` also works, but its recommended
packages make it 202 packages and about 1 GB, including systemd, D-Bus and
a Java runtime. (Measured on v1.11.2 with pi-studio 0.10.1.)
### Generating a PDF with pandoc + typst ### Generating a PDF with pandoc + typst