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. 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..3888c636e42 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