diff --git a/news/changelog-1.10.md b/news/changelog-1.10.md index 034e6f5649..128f53efce 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)): Report a clear, actionable error when a font fallback (`mainfontfallback`, `monofontfallback`, ...) crashes LuaLaTeX on recent TeX Live, pointing to a single-font workaround, instead of a generic compilation failure. - ([#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 e0ad5cf353..2b76024323 100644 --- a/src/command/render/latexmk/parse-error.ts +++ b/src/command/render/latexmk/parse-error.ts @@ -205,10 +205,24 @@ export function findMissingHyphenationFiles(logText: string) { const kErrorRegex = /^\!\s([\s\S]+)?Here is how much/m; const kEmptyRegex = /(No pages of output)\./; +// luaotfload's font-fallback resolver crashes on recent TeX Live (luaotfload +// v3.29): when a fallback is set (mainfontfallback / monofontfallback / ...), +// define_font of the internal `;-fallback` name returns nil and +// luaotfload-fallback.lua dereferences it. The crash is a Lua runtime error +// with no `! ...Here is how much` block, so the generic extraction below finds +// nothing — detect it directly and give actionable guidance. +// Upstream: https://github.com/latex3/luaotfload/issues/331 +const kLuaotfloadFallbackCrash = + /luaotfload-fallback\.lua:\d+: attempt to index a nil value/; + export function findLatexError( logText: string, stderr?: string, ): string | undefined { + if (kLuaotfloadFallbackCrash.test(logText)) { + return "A font fallback (e.g. 'mainfontfallback' or 'monofontfallback') triggered a known luaotfload bug on this TeX Live version, which crashes LuaLaTeX before a PDF is produced. Until it is fixed upstream, set a single font that covers the required glyphs (e.g. 'monofont: JuliaMono') instead of a fallback list. See https://github.com/latex3/luaotfload/issues/331"; + } + const errors: string[] = []; const match = logText.match(kErrorRegex); diff --git a/tests/unit/latexmk/parse-error.test.ts b/tests/unit/latexmk/parse-error.test.ts index 49d3edd752..2410e00a66 100644 --- a/tests/unit/latexmk/parse-error.test.ts +++ b/tests/unit/latexmk/parse-error.test.ts @@ -5,7 +5,7 @@ * */ -import { findMissingFontsAndPackages, findMissingHyphenationFiles } from "../../../src/command/render/latexmk/parse-error.ts" +import { findLatexError, findMissingFontsAndPackages, findMissingHyphenationFiles } from "../../../src/command/render/latexmk/parse-error.ts" import { unitTest } from "../../test.ts"; import { assert } from "testing/asserts"; @@ -82,6 +82,32 @@ unitTest("Detect missing files with `findMissingFontsAndPackages`", async () => cwd: () => "unit/latexmk/" }) +// deno-lint-ignore require-await +unitTest("Detect luaotfload font fallback crash and surface an actionable hint", async () => { + // The luaotfload font-fallback resolver crashes on recent TeX Live when a + // fallback font is set (mainfontfallback/monofontfallback): define_font of the + // internal `;-fallback` name returns nil and luaotfload-fallback.lua + // dereferences it. There is no `! ...Here is how much` block, so the generic + // error extraction finds nothing — we want a specific, actionable message. + // Upstream: https://github.com/latex3/luaotfload/issues/331 + const fallbackCrashLog = + `luaotfload | db : Reload initiated (formats: otf,ttf,ttc); reason: Font "Latin Modern Roman;-fallback" not found. +luaotfload | resolve : sequence of 3 lookups yielded nothing appropriate....texmf-dist/tex/luatex/luaotfload/luaotfload-fallback.lua:50: attempt to index a nil value (local 'f'). +! ==> Fatal error occurred, no output PDF file produced!`; + + const message = findLatexError(fallbackCrashLog) ?? ""; + assert( + message.includes("font fallback"), + `Expected a font-fallback hint, got: "${message}"`, + ); + assert( + message.includes("luaotfload/issues/331"), + `Expected the upstream issue link, got: "${message}"`, + ); +}, { + cwd: () => "unit/latexmk/" +}) + unitTest("Detect missing hyphenation with babel warnings", async () => { // Test backtick-quote format (old format) const logWithBacktick = `Package babel Warning: No hyphenation patterns were preloaded for