quarto-dev / quarto-dev/quarto-cli
`book + format: typst`: brand base font (`typography.base` / `mainfont`) not passed to orange-book template — body text falls back to Libertinus Serif (headings OK)
@cderv is already working on this.
Since Jun 16, 2026.
- Dominant language
- JavaScript
- Stars
- 6k
- Forks
- 458
- Avg merge
- 1d 9h
- Merged PRs (30d)
- 41
Description
Bug
When rendering a Quarto book (project.type: book) to Typst, the document body font declared by _brand.yml typography.base (or by mainfont) is not applied. The generated book.with(...) call omits the font: argument entirely, so orange-book's font parameter stays at its none default and Typst falls back to its default serif (Libertinus). Headings are unaffected (the brand headings font is emitted via a separate #show heading: set text(...) rule).
This is book-mode specific: a standalone format: typst document with the same _brand.yml correctly emits font: ("Inter",) and embeds Inter.
This is distinct from #14511 / #14517 (which were about font availability — --font-path not passed → headings fell back + unknown font family warning). Here the fonts are available, headings render correctly, no warning is emitted; only the body font request is missing.
Minimal reproduction (no R, brand only)
mybook/
├── _quarto.yml
├── _brand.yml
├── _fonts/Starjedi.ttf # any local font for headings (optional)
└── index.qmd # # Préface + one paragraph
_quarto.yml
project:
type: book
lang: fr
book:
title: "Anatomie d'une saga"
subtitle: "Portrait statistique des personnages de Star Wars"
author: "Mon Mothma"
chapters:
- index.qmd
format:
typst:
keep-typ: true
# mainfont: Inter # <- also tested: IGNORED in book mode
font-paths: [.quarto/typst/fonts, _fonts]
_brand.yml
typography:
fonts:
- { family: "Star Jedi", source: file, files: [ { path: _fonts/Starjedi.ttf, weight: 400 } ] }
- { family: Inter, source: google, weight: [400, 600, 700] }
base: Inter
headings: "Star Jedi"
quarto render → _book/Anatomie-d-une-saga.pdf.
Expected
Body text in Inter (the brand base), same as a standalone format: typst document.
Actual
Body text in Libertinus Serif. No warning (the font is never requested).
Control comparison — same _brand.yml, single doc vs book
generated .typ |
pdffonts (body) |
|
|---|---|---|
format: typst (single doc, type: default) |
font: ("Inter",) passed to template |
Inter-Regular embedded |
type: book (orange-book) |
#show: book.with(title, subtitle, author, lang, main-color, logo, …) — no font: |
LibertinusSerif-Regular/Bold/Italic (no Inter) |
In book mode the string Inter never appears in the generated index.typ. orange-book's book() does expose a font parameter (default none, applied via set text(font: font) when font != none) — it simply isn't filled. Setting mainfont: Inter explicitly does not help in book mode either (still absent from book.with(...)).
Workaround (verified)
Force the body font with raw Typst injected in the header:
format:
typst:
include-in-header:
- text: |
#set text(font: "Inter")
After this, pdffonts shows Inter-Regular/Bold (Libertinus gone), headings still Star Jedi.
Root-cause hypothesis
The book → orange-book template generation maps brand/format metadata to book.with(...) arguments (title, subtitle, author, lang, main-color, logo, …) but does not map typography.base / mainfont to the font: argument. For standalone Typst the default template path does emit font: (...), so the mapping exists per-file but is dropped on the book-assembly path — parallel to the earlier font-paths book-mode wiring gap of #14517, which was on the availability side. Likely the same family as the format-state-at-construction-time issue tracked in #14516.
Suggested fix
Pass the resolved base/main font to book.with(font: ...) (orange-book already supports it), or emit a document-level #set text(font: (...)) for books as is done for standalone docs.
Environment
- Quarto 1.10.11 (reproduces) and 1.9.36 (reproduces)
- Typst bundled, orange-book 0.7.1
_brand.yml typography.base: Inter(source: google),headingslocal file- Reproduces with
format: typst(auto orange-book); no R, brand only - Headings render correctly; only the body font is missing → distinct from #14517
Related
- #14517 / #14511 — book brand fonts not passed as
--font-path(RESOLVED — headings/availability side) - #14516 — typst recipe
completecallbacks read format state from the captured construction-timeformatparameter (suspected shared root cause) - #13548 — Variants fonts from same family with Brand YAML
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.