Skip to content

monofontfallback fonts not auto-installed — luaotfload error format not recognized #14558

@cderv

Description

@cderv

When monofontfallback lists a font not installed on the system, lualatex fails and Quarto does not attempt to auto-install the missing font. The error format luaotfload emits for fallback-chain fonts is not recognized by Quarto's missing-package detector.

Error

The log contains:

luaotfload | db : Reload initiated (formats: otf,ttf,ttc); reason: Font "DejaVu Sans Mono;-fallback" not found.
luaotfload | resolve : sequence of 3 lookups yielded nothing appropriate.

Quarto's packageMatchers covers ! Font ... not loadable, ! .*The font "X" cannot be found, (fontspec) The font "X" cannot be, and similar patterns — but none match luaotfload | ... reason: Font "X" not found.

const packageMatchers = [
// Fonts
{
regex: /.*! Font [^=]+=([^ ]+).+ not loadable.*/g,
filter: formatFontFilter,
},
{
regex: /.*! .*The font "([^"]+)" cannot be found.*/g,
filter: formatFontFilter,
},
{
regex: /.*!.+ error:.+\(file ([^)]+)\): .*/g,
filter: formatFontFilter,
},
{
regex: /.*Unable to find TFM file "([^"]+)".*/g,
filter: formatFontFilter,
},
{
regex: /.*\(fontspec\)\s+The font "([^"]+)" cannot be.*/g,
filter: formatFontFilter,
},

Why the primary font case works but monofontfallback does not

When the primary monofont is missing, luaotfload fails first but fontspec then also emits ! Package fontspec Error: The font "X" cannot be found, which is matched. The monofontfallback path registers fonts via luaotfload.add_fallback() — when that fails, fontspec does not fire its own error, so only the unrecognized luaotfload message appears.

Secondary issue: ;-fallback suffix corrupts the search term

luaotfload appends ;-fallback internally to each fallback-chain entry to prevent recursive fallback resolution. Even if a pattern matched, the extracted name DejaVu Sans Mono;-fallback would produce a broken fontSearchTerm regex:

DejaVu\s*Sans\s*Mono;-fallback(-(Bold|Italic|Regular).*)?[.](tfm|afm|mf|otf|ttf)

function fontSearchTerm(font: string): string {
const fontPattern = font.replace(/\s+/g, "\\s*");
return `${fontPattern}(-(Bold|Italic|Regular).*)?[.](tfm|afm|mf|otf|ttf)`;
}

After stripping ;-fallback, fontSearchTerm("DejaVu Sans Mono") produces DejaVu\s*Sans\s*Mono(-(Bold|Italic|Regular).*)?[.](tfm|afm|mf|otf|ttf) — the \s* matches zero whitespace, so DejaVuSansMono.otf would match and tlmgr search would find the dejavu CTAN package.

Fix direction

Two changes to parse-error.ts:

  1. A new pattern for the luaotfload format: /.*luaotfload.*reason: Font "([^"]+)" not found.*/g
  2. A filter that strips the ;-fallback suffix before passing to formatFontFilter

A unit test case can go in the existing tests/unit/latexmk/parse-error.test.ts.

Related

Metadata

Metadata

Assignees

Labels

enhancementNew feature or requestlatexLaTeX engines related libraries and technologies

Type

No type
No fields configured for issues without a type.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions