Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions news/changelog-1.9.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ All changes included in 1.9:
- ([#13441](https://github.com/quarto-dev/quarto-cli/pull/13441)): Catch `undefined` exceptions in Pandoc failure to avoid spurious error message.
- ([#13046](https://github.com/quarto-dev/quarto-cli/issues/13046)): Use new url for multiplex socket.io server <https://multiplex.up.railway.app/> as default for `format: revealjs` and `revealjs.multiplex: true`.
- ([#13506](https://github.com/quarto-dev/quarto-cli/issues/13506)): Fix navbar active state detection when sidebar has no logo configured. Prevents empty logo links from interfering with navigation highlighting.
- ([#13633](https://github.com/quarto-dev/quarto-cli/issues/13633)): Fix detection and auto-installation of babel language packages from newer error format that doesn't explicitly mention `.ldf` filename.

## Dependencies

Expand Down Expand Up @@ -37,6 +38,7 @@ All changes included in 1.9:

### `pdf`

- ([#10291](https://github.com/quarto-dev/quarto-cli/issues/10291)): Fix detection of babel hyphenation warnings with straight-quote format instead of backtick-quote format.
- ([rstudio/tinytex-releases#49](https://github.com/rstudio/tinytex-releases/issues/49)): Fix detection of LuaTeX-ja missing file errors by matching both "File" and "file" in error messages.

## Projects
Expand Down
8 changes: 7 additions & 1 deletion src/command/render/latexmk/parse-error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ export function findMissingHyphenationFiles(logText: string) {
const babelWarningRegex = /^Package babel Warning:/m;
const hasWarning = logText.match(babelWarningRegex);
if (hasWarning) {
const languageRegex = /^\(babel\).* language `(\S+)'.*$/m;
const languageRegex = /^\(babel\).* language [`'](\S+)[`'].*$/m;
const languageMatch = logText.match(languageRegex);
if (languageMatch) {
return filterLang(languageMatch[1]);
Expand Down Expand Up @@ -283,6 +283,12 @@ const packageMatchers = [
{ regex: /.*! LaTeX Error: File [`']([^']+)' not found.*/g },
{ regex: /.* [fF]ile ['`]?([^' ]+)'? not found.*/g },
{ regex: /.*the language definition file ([^\s]*).*/g },
{
regex: /.*! Package babel Error: Unknown option [`']([^'`]+)'[.].*/g,
filter: (match: string, _text: string) => {
return `${match}.ldf`;
},
},
{ regex: /.* \\(file ([^)]+)\\): cannot open .*/g },
{ regex: /.*file [`']([^']+)' .*is missing.*/g },
{ regex: /.*! CTeX fontset [`']([^']+)' is unavailable.*/g },
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
---
format: pdf
# new babel support in Pandoc 3.6.3 solves missing package when specific lang is used.
lang: es
latex-auto-install: false
_quarto:
tests-on-ci: false
tests:
pdf: default
pdf:
noErrors: true
printsMessage:
level: WARN
regex: "Possibly missing hyphenation"
---

** This test is to be run manually as we don't want to uninstall and reinstall package in CI**

```{r}
#| include: false

#| messages: 'NA'
# Remove the hyphen package for spanish so that the test is meaningful
if (tinytex::check_installed("hyphen-spanish")) {
message("Removing 'hyphen-spanish' package for the render")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,21 @@ _quarto:
pdf: null
---

**Only remove package on CI**
```{r}
#| eval: !expr isFALSE(as.logical(Sys.getenv("CI", "false")))
#| include: false
#| messages: "NA"

# Remove the hyphen package for spanish
if (tinytex::check_installed("hyphen-spanish")) {
message("Removing 'hyphen-spanish' package for the render")
tinytex::tlmgr_remove("hyphen-spanish")
}
if (tinytex::check_installed("babel-spanish")) {
message("Removing 'babel-spanish' package for the render")
tinytex::tlmgr_remove("babel-spanish")
}
```

# Hola !
Expand Down
22 changes: 22 additions & 0 deletions tests/docs/smoke-all/2025/11/04/13633.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
title: "Babel English Auto-Install (#13633)"
format: pdf
lang: en
_quarto:
tests:
pdf: null
---

```{r}
#| eval: !expr isFALSE(as.logical(Sys.getenv("CI", "false")))
#| include: false
#| messages: "NA"

# Remove babel-english package to test auto-installation
if (tinytex::check_installed("babel-english")) {
message("Removing 'babel-english' package for the render")
tinytex::tlmgr_remove("babel-english")
}
```

This document tests that Quarto correctly detects and auto-installs babel-english when rendering with `lang: en`.
63 changes: 62 additions & 1 deletion tests/unit/latexmk/parse-error.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*
*/

import { findMissingFontsAndPackages } from "../../../src/command/render/latexmk/parse-error.ts"
import { findMissingFontsAndPackages, findMissingHyphenationFiles } from "../../../src/command/render/latexmk/parse-error.ts"
import { unitTest } from "../../test.ts";
import { assert } from "testing/asserts";

Expand Down Expand Up @@ -42,6 +42,10 @@ unitTest("Detect missing files with `findMissingFontsAndPackages`", async () =>
(babel) There is a locale ini file for this language.
(babel) If it’s the main language, try adding \`provide=*'
(babel) to the babel package options.`, "ngerman.ldf")
assertFound("! Package babel Error: Unknown option 'english'.", "english.ldf");
assertFound(`! Package babel Error: Unknown option 'ngerman'.
(babel) Suggested actions:
(babel) * Make sure you haven't misspelled it`, "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("! CTeX fontset 'fandol' is unavailable in current mode", "fandol");
Expand Down Expand Up @@ -70,4 +74,61 @@ unitTest("Detect missing files with `findMissingFontsAndPackages`", async () =>
assertFound("No file LGRcmr.fd. ! LaTeX Error: This NFSS system isn't set up properly.", "lgrcmr.fd");
},{
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
(babel) the language \`Spanish' into the format.
(babel) Please, configure your TeX system to add them and
(babel) rebuild the format. Now I will use the patterns
(babel) preloaded for \\language=0 instead on input line 51.`;
assert(
findMissingHyphenationFiles(logWithBacktick) === "hyphen-spanish",
"Should detect hyphen-spanish from backtick-quote format"
);

// Test straight-quote format (new format - the bug we're fixing)
const logWithStraightQuotes = `Package babel Warning: No hyphenation patterns were preloaded for
(babel) the language 'Spanish' into the format.
(babel) Please, configure your TeX system to add them and
(babel) rebuild the format. Now I will use the patterns
(babel) preloaded for \\language=0 instead on input line 51.`;
assert(
findMissingHyphenationFiles(logWithStraightQuotes) === "hyphen-spanish",
"Should detect hyphen-spanish from straight-quote format"
);

// Test ngerman special case (should return hyphen-german, not hyphen-ngerman)
const logGerman = `Package babel Warning: No hyphenation patterns were preloaded for
(babel) the language 'ngerman' into the format.`;
assert(
findMissingHyphenationFiles(logGerman) === "hyphen-german",
"Should map ngerman to hyphen-german"
);

// Test Chinese - no hyphen package exists
const logChinese = `Package babel Warning: No hyphenation patterns were preloaded for
(babel) the language 'chinese' into the format.`;
assert(
findMissingHyphenationFiles(logChinese) === undefined,
"Should return undefined for Chinese (no hyphen package)"
);

// Test alternative Info pattern (issue #10291)
const logInfoChinese = `Package babel Info: Hyphen rules for 'chinese-hans' set to \\l@nil
(babel) (\\language10). Reported on input line 143.`;
assert(
findMissingHyphenationFiles(logInfoChinese) === undefined,
"Should return undefined for chinese-hans via Info pattern"
);

// Test no warning present
const logNoWarning = "Some other log text without babel warnings";
assert(
findMissingHyphenationFiles(logNoWarning) === undefined,
"Should return undefined when no babel warning present"
);
}, {
cwd: () => "unit/latexmk/"
})
Loading