From f05df0699d0795b8871db2ca57f444a017916e7a Mon Sep 17 00:00:00 2001 From: Christophe Dervieux Date: Tue, 4 Mar 2025 15:40:15 +0100 Subject: [PATCH 1/3] latexmk - Correctly detect missing files same way as tinytex - Don't add searchTerm if a file missing has extension - Replace possible prefix and suffix containting `:` on missing font - Add test for all known font detection in tinytex R package --- src/command/render/latexmk/parse-error.ts | 24 +++++++------- tests/unit/latexmk/parse-error.test.ts | 40 ++++++++++++++++++++--- 2 files changed, 48 insertions(+), 16 deletions(-) diff --git a/src/command/render/latexmk/parse-error.ts b/src/command/render/latexmk/parse-error.ts index 47f0ebb640b..d58e3ef785c 100644 --- a/src/command/render/latexmk/parse-error.ts +++ b/src/command/render/latexmk/parse-error.ts @@ -209,8 +209,11 @@ function findMissingFonts(dir: string): string[] { } const formatFontFilter = (match: string, _text: string) => { - const base = basename(match); - return fontSearchTerm(base); + // Remove special prefix / suffix e.g. 'file:HaranoAjiMincho-Regular.otf:-kern;jfm=ujis' + // https://github.com/quarto-dev/quarto-cli/issues/12194 + const base = basename(match).replace(/^.*?:|:.*$/g, ""); + // return found file directly if it has an extension + return /[.]/.test(base) ? base : fontSearchTerm(base); }; const estoPdfFilter = (_match: string, _text: string) => { @@ -231,21 +234,20 @@ const packageMatchers = [ regex: /.*!.+ error:.+\(file ([^)]+)\): .*/g, filter: formatFontFilter, }, - { - regex: /.*Package widetext error: Install the ([^ ]+) package.*/g, - filter: (match: string, _text: string) => { - return `${match}.sty`; - }, - }, { regex: /.*Unable to find TFM file "([^"]+)".*/g, filter: formatFontFilter, }, { - regex: - /.*! Package fontspec Error:\s+\(fontspec\)\s+The font "([^"]+)" cannot be\s+\(fontspec\)\s+found;+/g, + regex: /.*\(fontspec\)\s+The font "([^"]+)" cannot be.*/g, filter: formatFontFilter, }, + { + regex: /.*Package widetext error: Install the ([^ ]+) package.*/g, + filter: (match: string, _text: string) => { + return `${match}.sty`; + }, + }, { regex: /.* File `(.+eps-converted-to.pdf)'.*/g, filter: estoPdfFilter }, { regex: /.*xdvipdfmx:fatal: pdf_ref_obj.*/g, filter: estoPdfFilter }, @@ -303,7 +305,7 @@ function findMissingPackages(logFileText: string): string[] { packageMatcher.regex.lastIndex = 0; }); - // dedpulicated list of packages to attempt to install + // dedulicated list of packages to attempt to install return ld.uniq(toInstall); } diff --git a/tests/unit/latexmk/parse-error.test.ts b/tests/unit/latexmk/parse-error.test.ts index a3f2b37ff24..5581759e008 100644 --- a/tests/unit/latexmk/parse-error.test.ts +++ b/tests/unit/latexmk/parse-error.test.ts @@ -9,9 +9,39 @@ import { findMissingFontsAndPackages } from "../../../src/command/render/latexmk import { unitTest } from "../../test.ts"; import { assert } from "testing/asserts"; -unitTest("findMissingPackages", async () => { - const logText = Deno.readTextFileSync("expl3-aborted.log") - assert(findMissingFontsAndPackages(logText, ".")[0] === "expl3.sty" ); -}, { +function fontSearchTerm(font: string): string { + return `${font}(-(Bold|Italic|Regular).*)?[.](tfm|afm|mf|otf|ttf)`; +} + +function assertFound(logText: string, expected: string, file?: string) { + assert( + findMissingFontsAndPackages(logText, ".")[0] === expected, + `Expected \`${expected}\` in ${file ?? logText} but not found.` + ) +} + +unitTest("Detect missing files with `findMissingFontsAndPackages`", async () => { + // No package found + assert(findMissingFontsAndPackages("asdf qwer", ".").length === 0); + // Mismatched LaTeX support (https://github.com/quarto-dev/quarto#7417) + assertFound(Deno.readTextFileSync("expl3-aborted.log"), "expl3.sty", "expl3-aborted.log"); + // fonts + assertFound("! Font U/psy/m/n/10=psyr at 10.0pt not loadable: Metric (TFM) file not found", fontSearchTerm("psyr")); + assertFound('! The font "FandolSong-Regular" cannot be found.', fontSearchTerm("FandolSong-Regular")); + assertFound('! Package fontspec Error: The font "Caladea" cannot be found.', fontSearchTerm("caladea")); + assertFound('!pdfTeX error: /usr/local/bin/pdflatex (file tcrm0700): Font tcrm0700 at 600 not found', fontSearchTerm("tcrm0700")) + assertFound('(fontspec) The font "LibertinusSerif-Regular" cannot be', fontSearchTerm("LibertinusSerif-Regular")); + 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("! LaTeX Error: File `framed.sty' not found.", "framed.sty"); + assertFound("/usr/local/bin/mktexpk: line 123: mf: command not found", "mf"); + assertFound("or the language definition file ngerman.ldf was not found", "ngerman.ldf"); + assertFound("!pdfTeX error: pdflatex (file 8r.enc): cannot open encoding file for reading", "8r.enc"); + assertFound("! CTeX fontset `fandol' is unavailable in current mode", "fandol"); + assertFound('Package widetext error: Install the flushend package which is a part of sttools', "flushend.sty"); + assertFound('! Package isodate.sty Error: Package file substr.sty not found.', "substr.sty"); + assertFound("! Package fontenc Error: Encoding file `t2aenc.def' not found.", "t2aenc.def"); + assertFound("! I can't find file `hyph-de-1901.ec.tex'.", "hyph-de-1901.ec.tex"); + assertFound("luaotfload-features.lua:835: module 'lua-uni-normalize' not found:", "lua-uni-algos.lua"); +},{ cwd: () => "unit/latexmk/" -}); +}) \ No newline at end of file From 2df788674d50ff09a6c2733bef5ccd0cf1fb39fd Mon Sep 17 00:00:00 2001 From: Christophe Dervieux Date: Tue, 4 Mar 2025 15:42:41 +0100 Subject: [PATCH 2/3] Add to changelog --- news/changelog-1.7.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/news/changelog-1.7.md b/news/changelog-1.7.md index 38a7a2aa069..cf22e9fc688 100644 --- a/news/changelog-1.7.md +++ b/news/changelog-1.7.md @@ -44,6 +44,10 @@ All changes included in 1.7: - ([#11903](https://github.com/quarto-dev/quarto-cli/issues/11903)): `crossref` configuration like `fig-title` or `tbl-title` now correctly supports multi word values, e.g. `fig-title: 'Supplementary Figure'`. - ([#11878](https://github.com/quarto-dev/quarto-cli/issues/11878), [#12085](https://github.com/quarto-dev/quarto-cli/issues/12085)): Correctly fixup raw LaTeX table having an unexpected table env with options (e.g `\begin{table}[!ht]`) to be handled as crossref table. +### Quarto PDF engine + +- ([#12194](https://github.com/quarto-dev/quarto-cli/issues/12194)): More specific checks added in log parsing to automatically find missing fonts. + ## `typst` format - ([#11578](https://github.com/quarto-dev/quarto-cli/issues/11578)): Typst column layout widths use fractional `fr` units instead of percent `%` units for unitless and default widths in order to fill the enclosing block and not spill outside it. From d07b3ebb4dda40c646578c0b87e42ab7b6e38047 Mon Sep 17 00:00:00 2001 From: Christophe Dervieux Date: Tue, 4 Mar 2025 17:06:52 +0100 Subject: [PATCH 3/3] Correct font name --- tests/unit/latexmk/parse-error.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/unit/latexmk/parse-error.test.ts b/tests/unit/latexmk/parse-error.test.ts index 5581759e008..3888c636e42 100644 --- a/tests/unit/latexmk/parse-error.test.ts +++ b/tests/unit/latexmk/parse-error.test.ts @@ -16,7 +16,7 @@ function fontSearchTerm(font: string): string { function assertFound(logText: string, expected: string, file?: string) { assert( findMissingFontsAndPackages(logText, ".")[0] === expected, - `Expected \`${expected}\` in ${file ?? logText} but not found.` + `Expected \`${expected}\` in \"${file ?? logText}\" but not found.` ) } @@ -28,7 +28,7 @@ unitTest("Detect missing files with `findMissingFontsAndPackages`", async () => // fonts assertFound("! Font U/psy/m/n/10=psyr at 10.0pt not loadable: Metric (TFM) file not found", fontSearchTerm("psyr")); assertFound('! The font "FandolSong-Regular" cannot be found.', fontSearchTerm("FandolSong-Regular")); - assertFound('! Package fontspec Error: The font "Caladea" cannot be found.', fontSearchTerm("caladea")); + assertFound('! Package fontspec Error: The font "Caladea" cannot be found.', fontSearchTerm("Caladea")); assertFound('!pdfTeX error: /usr/local/bin/pdflatex (file tcrm0700): Font tcrm0700 at 600 not found', fontSearchTerm("tcrm0700")) assertFound('(fontspec) The font "LibertinusSerif-Regular" cannot be', fontSearchTerm("LibertinusSerif-Regular")); 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");