diff --git a/news/changelog-1.7.md b/news/changelog-1.7.md index 2071de93890..4916027fa3d 100644 --- a/news/changelog-1.7.md +++ b/news/changelog-1.7.md @@ -78,6 +78,7 @@ All changes included in 1.7: ## `pdf` +- ([#11695](https://github.com/quarto-dev/quarto-cli/issues/11695)): Translate ANSI color codes more carefully inside `highlighting` environments. - ([#11835](https://github.com/quarto-dev/quarto-cli/issues/11835)): Take markdown structure into account when detecting minimum heading level. - ([#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. - ([#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'`. diff --git a/src/resources/filters/quarto-post/latex.lua b/src/resources/filters/quarto-post/latex.lua index b70a26c85be..e08a4c83d1b 100644 --- a/src/resources/filters/quarto-post/latex.lua +++ b/src/resources/filters/quarto-post/latex.lua @@ -587,6 +587,23 @@ function render_latex_fixups() end end, CodeBlock = function(code) + local function escape_latex(line) + -- unfortunately, we can't use stringEscape here (or pandoc.write(..., "latex") + -- more generally) because it doesn't preserve multiple spaces, which the + -- "highlighting" environment does + + -- In addition, we have the following tricky situation: + -- \ -> \textbackslash{} + -- { -> \{ + -- + -- these two replacement rules both generate \ and {, and + -- so there's no order that works. We need to use a + -- unique replacement for \ first. + + -- obtained by a local call to uuid and removing dashes + local uuid = "edbdf4a3bc424f5b8ac0e95c92ef5015" + return line:gsub("[\\]", uuid):gsub("([{}$%&%_])", "\\%1"):gsub("[%^]", "\\textasciicaret{}"):gsub("[~]", "\\textasciitilde{}"):gsub(uuid, "\\textbackslash{}") + end if code.text:match("\027%[[0-9;]+m") and #code.classes == 0 then local lines = split(code.text, "\n") local new_lines = pandoc.List({ @@ -595,6 +612,7 @@ function render_latex_fixups() local cur_color = "\\textcolor{black}" for _, line in ipairs(lines) do local start_color = cur_color + line = escape_latex(line) line = line:gsub("\027%[([0-9;]+)m", function(n) local this_color = "\\textcolor" .. emit_quarto_ansi_color(n) cur_color = this_color diff --git a/tests/docs/smoke-all/2025/04/09/issue-11695.qmd b/tests/docs/smoke-all/2025/04/09/issue-11695.qmd new file mode 100644 index 00000000000..a120b847915 --- /dev/null +++ b/tests/docs/smoke-all/2025/04/09/issue-11695.qmd @@ -0,0 +1,20 @@ +--- +title: "foo" +format: pdf +keep-tex: true +--- + +::: {.cell execution_count=1} +``` {.python .cell-code} +stuff +``` + +::: {.cell-output .cell-output-error} +``` + 793 err_msg += '\n' + '\n'.join(remarks) +``` +``` +Bad but handled somehow: \n +``` +::: +::: \ No newline at end of file