Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
quarto-dev
GitHub Repository: quarto-dev/quarto-cli
Path: blob/main/tests/unit/latexmk/parse-error.test.ts
6451 views
1
/*
2
* parse-error.test.ts
3
*
4
* Copyright (C) 2023 Posit Software, PBC
5
*
6
*/
7
8
import { findMissingFontsAndPackages, findMissingHyphenationFiles } from "../../../src/command/render/latexmk/parse-error.ts"
9
import { unitTest } from "../../test.ts";
10
import { assert } from "testing/asserts";
11
12
function fontSearchTerm(font: string): string {
13
const fontPattern = font.replace(/\s+/g, '\\s*');
14
return `${fontPattern}(-(Bold|Italic|Regular).*)?[.](tfm|afm|mf|otf|ttf)`;
15
}
16
17
function assertFound(logText: string, expected: string, file?: string) {
18
assert(
19
findMissingFontsAndPackages(logText, ".")[0] === expected,
20
`Expected \`${expected}\` in \"${file ?? logText}\" but not found.`
21
)
22
}
23
24
unitTest("Detect missing files with `findMissingFontsAndPackages`", async () => {
25
// No package found
26
assert(findMissingFontsAndPackages("asdf qwer", ".").length === 0);
27
// Mismatched LaTeX support (https://github.com/quarto-dev/quarto#7417)
28
assertFound(Deno.readTextFileSync("expl3-aborted.log"), "expl3.sty", "expl3-aborted.log");
29
// fonts
30
assertFound("! Font U/psy/m/n/10=psyr at 10.0pt not loadable: Metric (TFM) file not found", fontSearchTerm("psyr"));
31
assertFound('! The font "FandolSong-Regular" cannot be found.', fontSearchTerm("FandolSong-Regular"));
32
assertFound('! Package fontspec Error: The font "Caladea" cannot be found.', fontSearchTerm("Caladea"));
33
assertFound('!pdfTeX error: /usr/local/bin/pdflatex (file tcrm0700): Font tcrm0700 at 600 not found', fontSearchTerm("tcrm0700"))
34
assertFound('(fontspec) The font "LibertinusSerif-Regular" cannot be', fontSearchTerm("LibertinusSerif-Regular"));
35
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");
36
assertFound('! The font "Noto Emoji" cannot be found.', fontSearchTerm("Noto Emoji"));
37
assertFound('! Package fontspec Error: The font "DejaVu Sans" cannot be found.', fontSearchTerm("DejaVu Sans"));
38
assertFound("! LaTeX Error: File `framed.sty' not found.", "framed.sty");
39
assertFound("! LaTeX Error: File 'framed.sty' not found.", "framed.sty");
40
assertFound("/usr/local/bin/mktexpk: line 123: mf: command not found", "mf");
41
assertFound("or the language definition file ngerman.ldf was not found", "ngerman.ldf");
42
assertFound(`Package babel Error: Unknown option 'ngerman'. Either you misspelled it
43
(babel) or the language definition file ngerman.ldf
44
(babel) was not found.
45
(babel) There is a locale ini file for this language.
46
(babel) If it’s the main language, try adding \`provide=*'
47
(babel) to the babel package options.`, "ngerman.ldf")
48
assertFound("! Package babel Error: Unknown option 'english'.", "english.ldf");
49
assertFound(`! Package babel Error: Unknown option 'ngerman'.
50
(babel) Suggested actions:
51
(babel) * Make sure you haven't misspelled it`, "ngerman.ldf");
52
assertFound("!pdfTeX error: pdflatex (file 8r.enc): cannot open encoding file for reading", "8r.enc");
53
assertFound("! CTeX fontset `fandol' is unavailable in current mode", "fandol");
54
assertFound("! CTeX fontset 'fandol' is unavailable in current mode", "fandol");
55
assertFound('Package widetext error: Install the flushend package which is a part of sttools', "flushend.sty");
56
assertFound('! Package isodate.sty Error: Package file substr.sty not found.', "substr.sty");
57
assertFound("! Package fontenc Error: Encoding file `t2aenc.def' not found.", "t2aenc.def");
58
assertFound("! I can't find file `hyph-de-1901.ec.tex'.", "hyph-de-1901.ec.tex");
59
assertFound("! I can't find file 'hyph-de-1901.ec.tex'.", "hyph-de-1901.ec.tex");
60
assertFound("luaotfload-features.lua:835: module 'lua-uni-normalize' not found:", "lua-uni-algos.lua");
61
assertFound("! LuaTeX-ja error: File 'jfm-zh_CN.lua' not found.", "jfm-zh_CN.lua");
62
63
// Additional test cases from tinytex R package examples (latex.R lines 537-607)
64
// https://github.com/rstudio/tinytex/blob/e96be3143b9af07768a124215b5fb5a1e6d183d3/R/latex.R#L538-L558
65
assertFound('xdvipdfmx:fatal: Unable to find TFM file "rsfs10"', fontSearchTerm("rsfs10"));
66
assertFound("Package biblatex Info: ... file 'trad-abbrv.bbx' not found", "trad-abbrv.bbx");
67
assertFound("! Package pdftex.def Error: File `logo-mdpi-eps-converted-to.pdf' not found", "epstopdf");
68
assertFound("! Package pdftex.def Error: File 'logo-mdpi-eps-converted-to.pdf' not found", "epstopdf");
69
assertFound("! xdvipdfmx:fatal: pdf_ref_obj(): passed invalid object.", "epstopdf");
70
assertFound(
71
"! Package tikz Error: I did not find the tikz library 'hobby'. This error message was issued because the library or one of its sublibraries could not be found, probably because of a misspelling. Processed options: \"library={hobby}\". The possibly misspelled library name is \"hobby\". The library name should be one of the following (or you misspelled it): named tikzlibraryhobby.code.tex",
72
"tikzlibraryhobby.code.tex"
73
);
74
assertFound("support file `supp-pdf.mkii' (supp-pdf.tex) is missing", "supp-pdf.mkii");
75
assertFound("support file 'supp-pdf.mkii' (supp-pdf.tex) is missing", "supp-pdf.mkii");
76
assertFound("! Package pdfx Error: No color profile sRGB_IEC61966-2-1_black_scaled.icc found", "colorprofiles.sty");
77
assertFound("No file LGRcmr.fd. ! LaTeX Error: This NFSS system isn't set up properly.", "lgrcmr.fd");
78
},{
79
cwd: () => "unit/latexmk/"
80
})
81
82
unitTest("Detect missing hyphenation with babel warnings", async () => {
83
// Test backtick-quote format (old format)
84
const logWithBacktick = `Package babel Warning: No hyphenation patterns were preloaded for
85
(babel) the language \`Spanish' into the format.
86
(babel) Please, configure your TeX system to add them and
87
(babel) rebuild the format. Now I will use the patterns
88
(babel) preloaded for \\language=0 instead on input line 51.`;
89
assert(
90
findMissingHyphenationFiles(logWithBacktick) === "hyphen-spanish",
91
"Should detect hyphen-spanish from backtick-quote format"
92
);
93
94
// Test straight-quote format (new format - the bug we're fixing)
95
const logWithStraightQuotes = `Package babel Warning: No hyphenation patterns were preloaded for
96
(babel) the language 'Spanish' into the format.
97
(babel) Please, configure your TeX system to add them and
98
(babel) rebuild the format. Now I will use the patterns
99
(babel) preloaded for \\language=0 instead on input line 51.`;
100
assert(
101
findMissingHyphenationFiles(logWithStraightQuotes) === "hyphen-spanish",
102
"Should detect hyphen-spanish from straight-quote format"
103
);
104
105
// Test ngerman special case (should return hyphen-german, not hyphen-ngerman)
106
const logGerman = `Package babel Warning: No hyphenation patterns were preloaded for
107
(babel) the language 'ngerman' into the format.`;
108
assert(
109
findMissingHyphenationFiles(logGerman) === "hyphen-german",
110
"Should map ngerman to hyphen-german"
111
);
112
113
// Test Chinese - no hyphen package exists
114
const logChinese = `Package babel Warning: No hyphenation patterns were preloaded for
115
(babel) the language 'chinese' into the format.`;
116
assert(
117
findMissingHyphenationFiles(logChinese) === undefined,
118
"Should return undefined for Chinese (no hyphen package)"
119
);
120
121
// Test alternative Info pattern (issue #10291)
122
const logInfoChinese = `Package babel Info: Hyphen rules for 'chinese-hans' set to \\l@nil
123
(babel) (\\language10). Reported on input line 143.`;
124
assert(
125
findMissingHyphenationFiles(logInfoChinese) === undefined,
126
"Should return undefined for chinese-hans via Info pattern"
127
);
128
129
// Test no warning present
130
const logNoWarning = "Some other log text without babel warnings";
131
assert(
132
findMissingHyphenationFiles(logNoWarning) === undefined,
133
"Should return undefined when no babel warning present"
134
);
135
}, {
136
cwd: () => "unit/latexmk/"
137
})
138