From 5c801b0aec55c72868873a1b0b60dd4c6614a7db Mon Sep 17 00:00:00 2001 From: Christophe Dervieux Date: Fri, 29 May 2026 16:24:01 +0200 Subject: [PATCH] fix(pdf): recognize luaotfload missing-font error for fallback fonts When a font listed in monofontfallback (or any *fontfallback) is absent, luaotfload reports it via 'luaotfload | ... reason: Font "X;-fallback" not found' and fontspec never raises its own catchable error, so Quarto's missing-package detector saw nothing and the PDF render failed with no auto-install attempt. The primary monofont case worked only because fontspec also fires there. Add a packageMatcher for the luaotfload format and strip the ;-fallback suffix luaotfload appends internally before building the tlmgr search term, so 'DejaVu Sans Mono' resolves to the dejavu CTAN package. Closes #14558 --- news/changelog-1.10.md | 1 + src/command/render/latexmk/parse-error.ts | 15 +++++++++++++++ tests/unit/latexmk/parse-error.test.ts | 3 +++ 3 files changed, 19 insertions(+) diff --git a/news/changelog-1.10.md b/news/changelog-1.10.md index e59c72deb4f..cde9ab05d03 100644 --- a/news/changelog-1.10.md +++ b/news/changelog-1.10.md @@ -25,6 +25,7 @@ All changes included in 1.10: ### `pdf` - ([#13588](https://github.com/quarto-dev/quarto-cli/issues/13588)): Fix Lua error when rendering PDF with `reference-location: margin` and a footnote alongside a figure with `fig-cap`. (author: @mcanouil) +- ([#14553](https://github.com/quarto-dev/quarto-cli/issues/14553), [#14558](https://github.com/quarto-dev/quarto-cli/issues/14558)): Fix PDF render failing instead of auto-installing a missing font referenced by `monofontfallback` (and other `mainfont`/`sansfont`/`monofont` fallbacks). ### `typst` diff --git a/src/command/render/latexmk/parse-error.ts b/src/command/render/latexmk/parse-error.ts index 09cb24949a3..e0ad5cf3539 100644 --- a/src/command/render/latexmk/parse-error.ts +++ b/src/command/render/latexmk/parse-error.ts @@ -265,6 +265,14 @@ const formatFontFilter = (match: string, _text: string) => { return /[.]/.test(base) ? base : fontSearchTerm(base); }; +// luaotfload appends ';-fallback' internally to each fallback-chain entry +// (registered via monofontfallback / luaotfload.add_fallback) to prevent +// recursive fallback resolution. Strip it before building the search term. +// https://github.com/quarto-dev/quarto-cli/issues/14558 +const luaotfloadFontFilter = (match: string, text: string) => { + return formatFontFilter(match.replace(/;-fallback$/, ""), text); +}; + const estoPdfFilter = (_match: string, _text: string) => { return "epstopdf"; }; @@ -291,6 +299,13 @@ const packageMatchers = [ regex: /.*\(fontspec\)\s+The font "([^"]+)" cannot be.*/g, filter: formatFontFilter, }, + { + // luaotfload fallback-chain font (monofontfallback) missing. fontspec does + // not fire its own error in this path, so this is the only signal. + // https://github.com/quarto-dev/quarto-cli/issues/14558 + regex: /.*luaotfload.*reason: Font "([^"]+)" not found.*/g, + filter: luaotfloadFontFilter, + }, { regex: /.*Package widetext error: Install the ([^ ]+) package.*/g, filter: (match: string, _text: string) => { diff --git a/tests/unit/latexmk/parse-error.test.ts b/tests/unit/latexmk/parse-error.test.ts index 4771a6d7b40..49d3edd7522 100644 --- a/tests/unit/latexmk/parse-error.test.ts +++ b/tests/unit/latexmk/parse-error.test.ts @@ -35,6 +35,9 @@ unitTest("Detect missing files with `findMissingFontsAndPackages`", async () => assertFound('! Font \\JY3/mc/m/n/10=file:HaranoAjiMincho-Regular.otf:-kern;jfm=ujis at 9.24713pt not loadable: metric data not found or bad.', "HaranoAjiMincho-Regular.otf"); assertFound('! The font "Noto Emoji" cannot be found.', fontSearchTerm("Noto Emoji")); assertFound('! Package fontspec Error: The font "DejaVu Sans" cannot be found.', fontSearchTerm("DejaVu Sans")); + // luaotfload fallback-chain font (monofontfallback) - https://github.com/quarto-dev/quarto-cli/issues/14558 + // luaotfload appends ;-fallback internally; it must be stripped before building the search term + assertFound('luaotfload | db : Reload initiated (formats: otf,ttf,ttc); reason: Font "DejaVu Sans Mono;-fallback" not found.', fontSearchTerm("DejaVu Sans Mono")); assertFound("! LaTeX Error: File `framed.sty' not found.", "framed.sty"); assertFound("! LaTeX Error: File 'framed.sty' not found.", "framed.sty"); assertFound("/usr/local/bin/mktexpk: line 123: mf: command not found", "mf");