From 69a9f0b88d31412c258015e064f0600c317f888c Mon Sep 17 00:00:00 2001 From: Christophe Dervieux Date: Wed, 12 Nov 2025 18:17:31 +0100 Subject: [PATCH 01/17] Add smoke test for mermaid-format:svg with Beamer/PDF (#13661) Test expects SVG files to be used directly via \includesvg without HTML script tags in LaTeX output. This test should fail initially because setupMermaidSvgJsRuntime() adds script tags that break LaTeX compilation. --- tests/docs/smoke-all/2025/11/10/13661.qmd | 35 +++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 tests/docs/smoke-all/2025/11/10/13661.qmd diff --git a/tests/docs/smoke-all/2025/11/10/13661.qmd b/tests/docs/smoke-all/2025/11/10/13661.qmd new file mode 100644 index 0000000000..2128ebb1d6 --- /dev/null +++ b/tests/docs/smoke-all/2025/11/10/13661.qmd @@ -0,0 +1,35 @@ +--- +title: "Mermaid SVG format with Beamer (#13661)" +format: + beamer: + mermaid-format: svg + keep-tex: true + pdf: + mermaid-format: svg + keep-tex: true +_quarto: + tests: + beamer: + ensureLatexFileRegexMatches: + - ["\\\\includesvg(\\[.*?\\])?\\{[^}]*mermaid-figure-[^}]*\\}"] + - ["]*>", "mermaid-postprocess-shim"] + pdf: + ensureLatexFileRegexMatches: + - ["\\\\includesvg(\\[.*?\\])?\\{[^}]*mermaid-figure-[^}]*\\}"] + - ["]*>", "mermaid-postprocess-shim"] +--- + +## Test Diagram + +Simple mermaid diagram to test SVG format with PDF/Beamer outputs: + +```{mermaid} +graph TD + A[Start] --> B{Decision} + B -->|Yes| C[Good] + B -->|No| D[Bad] + C --> E[End] + D --> E +``` + +This should generate an SVG file and use LaTeX's `\includesvg` command without any HTML script tags. From c84239e878f7486ed008da6ae661c8eeb5bc09b7 Mon Sep 17 00:00:00 2001 From: Christophe Dervieux Date: Wed, 12 Nov 2025 18:48:06 +0100 Subject: [PATCH 02/17] lua - path var does not exist It is `image.src` --- src/resources/filters/quarto-post/pdf-images.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/resources/filters/quarto-post/pdf-images.lua b/src/resources/filters/quarto-post/pdf-images.lua index fc21e3e002..a7a1c86700 100644 --- a/src/resources/filters/quarto-post/pdf-images.lua +++ b/src/resources/filters/quarto-post/pdf-images.lua @@ -36,7 +36,7 @@ local function convert_svg(image) local stem = pandoc.path.split_extension(image.src) local output = stem .. '.pdf' if not _quarto.file.exists(output) then - warn("Skipping SVG conversion for " .. path .. " because use-rsvg-convert is false, but required PDF file does not exist: " .. output) + warn("Skipping SVG conversion for " .. image.src .. " because use-rsvg-convert is false, but required PDF file does not exist: " .. output) else image.src = output return image From beb64f8a0ec6ac74906283e74cb168f5b4cbfdfc Mon Sep 17 00:00:00 2001 From: Christophe Dervieux Date: Wed, 12 Nov 2025 18:49:36 +0100 Subject: [PATCH 03/17] lua - and return nil for true skipping --- src/resources/filters/quarto-post/pdf-images.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/src/resources/filters/quarto-post/pdf-images.lua b/src/resources/filters/quarto-post/pdf-images.lua index a7a1c86700..daf8a3e5fa 100644 --- a/src/resources/filters/quarto-post/pdf-images.lua +++ b/src/resources/filters/quarto-post/pdf-images.lua @@ -37,6 +37,7 @@ local function convert_svg(image) local output = stem .. '.pdf' if not _quarto.file.exists(output) then warn("Skipping SVG conversion for " .. image.src .. " because use-rsvg-convert is false, but required PDF file does not exist: " .. output) + return nil else image.src = output return image From 6a8e07db5457b37afbebb8a860ee64b66d813cbc Mon Sep 17 00:00:00 2001 From: Christophe Dervieux Date: Wed, 12 Nov 2025 20:23:18 +0100 Subject: [PATCH 04/17] Don't include script tag in non-html outputs when svg format is selected. --- src/core/handlers/mermaid.ts | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/core/handlers/mermaid.ts b/src/core/handlers/mermaid.ts index edb5484bc0..b188e89a02 100644 --- a/src/core/handlers/mermaid.ts +++ b/src/core/handlers/mermaid.ts @@ -39,7 +39,7 @@ import { convertFromYaml } from "../lib/yaml-schema/from-yaml.ts"; import { readYamlFromString } from "../yaml.ts"; import { pandocHtmlBlock, pandocRawStr } from "../pandoc/codegen.ts"; import { LocalizedError } from "../lib/located-error.ts"; -import { warning } from "../../deno_ral/log.ts"; +import { info, warning } from "../../deno_ral/log.ts"; import { FormatDependency } from "../../config/types.ts"; import { mappedDiff } from "../mapped-text.ts"; import { escape } from "../../core/lodash.ts"; @@ -228,7 +228,7 @@ mermaid.initialize(${JSON.stringify(mermaidOpts)}); ?.[kFigResponsive]; const makeSvg = async () => { - setupMermaidSvgJsRuntime(); + // Extract and process SVG let svg = asMappedString( (await handlerContext.extractHtml({ html: content, @@ -306,7 +306,22 @@ mermaid.initialize(${JSON.stringify(mermaidOpts)}); svg = mappedDiff(svg, oldSvgSrc); } - if (isMarkdownOutput(handlerContext.options.format, ["gfm"])) { + // For formats that don't support JavaScript runtime (LaTeX/PDF, DOCX, Typst, etc.), + // write SVG file directly without postprocess script. This avoids LaTeX compilation + // errors from HTML script tags but may result in text clipping in diagrams with + // multi-line labels (see https://github.com/quarto-dev/quarto-cli/issues/1622). + if ( + isMarkdownOutput(handlerContext.options.format, ["gfm"]) || + !isJavascriptCompatible(handlerContext.options.format) + ) { + // Emit info message for non-JS formats (excluding GFM which doesn't have the issue) + if (!isMarkdownOutput(handlerContext.options.format, ["gfm"])) { + info( + `Using mermaid-format: svg with ${ + handlerContext.options.format.pandoc.to ?? "non-HTML" + } format. Note: diagrams with multi-line text labels may experience clipping. Consider using mermaid-format: png if issues occur.`, + ); + } const { sourceName, fullName } = handlerContext .uniqueFigureName( "mermaid-figure-", @@ -323,6 +338,8 @@ mermaid.initialize(${JSON.stringify(mermaidOpts)}); makeFigLink(sourceName, widthInInches, heightInInches, true), ); } else { + // For JavaScript-compatible formats, use runtime postprocessing + setupMermaidSvgJsRuntime(); return this.build( handlerContext, cell, From 64a810c1f96bcc7df29cce43443e00be8af27b79 Mon Sep 17 00:00:00 2001 From: Christophe Dervieux Date: Fri, 14 Nov 2025 20:41:43 +0100 Subject: [PATCH 05/17] Make mermaid-format:svg warning PDF/LaTeX-specific The warning was shown for all non-JavaScript formats (PDF, LaTeX, Beamer, DOCX, Typst), but only PDF/LaTeX/Beamer require external tooling (rsvg-convert or Inkscape). DOCX and Typst handle SVG natively. Changed mermaid.ts to use isLatexOutput() instead of !isJavascriptCompatible(). --- src/core/handlers/mermaid.ts | 8 +- tests/docs/manual/mermaid-svg-pdf-tooling.qmd | 129 ++++++++++++++++++ tests/docs/smoke-all/2025/11/10/13661.qmd | 35 +++-- .../smoke-all/2025/11/14/mermaid-svg-docx.qmd | 30 ++++ 4 files changed, 183 insertions(+), 19 deletions(-) create mode 100644 tests/docs/manual/mermaid-svg-pdf-tooling.qmd create mode 100644 tests/docs/smoke-all/2025/11/14/mermaid-svg-docx.qmd diff --git a/src/core/handlers/mermaid.ts b/src/core/handlers/mermaid.ts index b188e89a02..1deb2027e6 100644 --- a/src/core/handlers/mermaid.ts +++ b/src/core/handlers/mermaid.ts @@ -314,12 +314,12 @@ mermaid.initialize(${JSON.stringify(mermaidOpts)}); isMarkdownOutput(handlerContext.options.format, ["gfm"]) || !isJavascriptCompatible(handlerContext.options.format) ) { - // Emit info message for non-JS formats (excluding GFM which doesn't have the issue) - if (!isMarkdownOutput(handlerContext.options.format, ["gfm"])) { + // Emit info message for PDF/LaTeX formats (which require external tooling) + if (isLatexOutput(handlerContext.options.format.pandoc)) { info( `Using mermaid-format: svg with ${ - handlerContext.options.format.pandoc.to ?? "non-HTML" - } format. Note: diagrams with multi-line text labels may experience clipping. Consider using mermaid-format: png if issues occur.`, + handlerContext.options.format.pandoc.to ?? "PDF" + } format requires external tooling (rsvg-convert or Inkscape). Consider using mermaid-format: png if you encounter issues.`, ); } const { sourceName, fullName } = handlerContext diff --git a/tests/docs/manual/mermaid-svg-pdf-tooling.qmd b/tests/docs/manual/mermaid-svg-pdf-tooling.qmd new file mode 100644 index 0000000000..593b364ac3 --- /dev/null +++ b/tests/docs/manual/mermaid-svg-pdf-tooling.qmd @@ -0,0 +1,129 @@ +--- +title: "Manual Test: Mermaid SVG with PDF - External Tooling" +format: + pdf: + mermaid-format: svg + keep-tex: true +--- + +## Purpose + +This document is for **manual testing** of mermaid-format:svg with PDF output, +specifically to verify behavior with different external tooling configurations. + +**Why manual?** Automated CI tests cannot easily verify: +- Actual PDF generation with rsvg-convert +- Inkscape fallback behavior +- Platform-specific tooling issues (especially Windows) +- Full conversion pipeline end-to-end + +## Simple Diagram + +```{mermaid} +graph TD + A[Start] --> B{Decision} + B -->|Yes| C[Good] + B -->|No| D[Bad] + C --> E[End] + D --> E +``` + +## Multi-line Labels (Clipping Test) + +This tests potential text clipping issues with multi-line labels: + +```{mermaid} +graph TD + A["Line 1
Line 2
Line 3"] --> B["Another
Multi
Line
Label"] + B --> C["Final
Node"] +``` + +## Manual Testing Checklist + +### Test 1: With rsvg-convert (Default) +- [ ] Ensure `rsvg-convert` is on PATH +- [ ] Run: `quarto render mermaid-svg-pdf-tooling.qmd` +- [ ] Verify: INFO message includes "requires external tooling" +- [ ] Verify: PDF generates successfully +- [ ] Check `.tex` file for `\includesvg` commands +- [ ] Verify: No script tags in LaTeX output +- [ ] Open PDF: Diagrams render correctly + +### Test 2: Without rsvg-convert +- [ ] Remove rsvg-convert from PATH or rename binary temporarily +- [ ] Run: `quarto render mermaid-svg-pdf-tooling.qmd` +- [ ] Verify: INFO message about tooling requirement +- [ ] Verify: Error about missing rsvg-convert +- [ ] Expected behavior: Render fails with clear error + +### Test 3: Inkscape Fallback (use-rsvg-convert: false) +Create variant document with: +```yaml +format: + pdf: + mermaid-format: svg + use-rsvg-convert: false + pdf-engine-opt: ["-shell-escape"] + keep-tex: true +``` + +- [ ] Ensure Inkscape is installed +- [ ] Run render with above config +- [ ] Verify: INFO message about tooling +- [ ] Verify: PDF generates via Inkscape (check logs) +- [ ] Check `.tex` file: uses `\includesvg` with Inkscape +- [ ] Open PDF: Diagrams render correctly + +### Test 4: Windows-Specific +- [ ] Test on Windows with rsvg-convert (if available via Scoop/other) +- [ ] Test on Windows without rsvg-convert +- [ ] Test Inkscape fallback on Windows +- [ ] Document any Windows-specific issues + +### Test 5: Comparison with PNG (Control) +Create variant with `mermaid-format: png`: + +- [ ] Run: `quarto render` with png format +- [ ] Verify: NO warning about external tooling +- [ ] Verify: PDF generates successfully +- [ ] Quality comparison: SVG vs PNG in final PDF + +## Expected Results Summary + +| Scenario | Warning | PDF Generation | Notes | +|----------|---------|----------------|-------| +| rsvg-convert available | ✅ Yes | ✅ Success | Default path | +| No rsvg-convert | ✅ Yes | ❌ Error | Clear error message | +| Inkscape + shell-escape | ✅ Yes | ✅ Success | Fallback works | +| PNG format | ❌ No | ✅ Success | No tooling needed | + +## Platform-Specific Notes + +### Linux/Mac +- rsvg-convert typically available via package managers +- `librsvg` package usually includes rsvg-convert +- Inkscape widely available + +### Windows +- rsvg-convert NOT easily available (complex setup) +- Can use Scoop: `scoop install rsvg-convert` (if r-bucket configured) +- Inkscape available but requires shell-escape configuration +- Most users should prefer PNG format on Windows + +## Recording Results + +After completing manual tests, document results in the beads issue notes field +for quarto-cli-idi. Include: + +- Platforms tested (OS, versions) +- Which scenarios passed/failed +- Any unexpected behavior +- Screenshots if helpful +- Recommendations for users + +## See Also + +- Automated test: `tests/docs/smoke-all/2025/11/10/13661.qmd` +- DOCX test: `tests/docs/smoke-all/2025/11/14/mermaid-svg-docx.qmd` +- Beads issue: quarto-cli-idi +- GitHub issue: #13661 diff --git a/tests/docs/smoke-all/2025/11/10/13661.qmd b/tests/docs/smoke-all/2025/11/10/13661.qmd index 2128ebb1d6..c49f96e44e 100644 --- a/tests/docs/smoke-all/2025/11/10/13661.qmd +++ b/tests/docs/smoke-all/2025/11/10/13661.qmd @@ -1,27 +1,34 @@ --- -title: "Mermaid SVG format with Beamer (#13661)" +title: "Mermaid SVG format with LaTeX - No script tags (#13661)" +# Test strategy: Use format:latex with use-rsvg-convert:false to: +# - Test mermaid-format:svg (the actual bug scenario) +# - Generate .tex file without compiling PDF (avoids needing rsvg-convert/Inkscape in CI) +# - Verify warning message about external tooling +# - Verify LaTeX uses \includesvg (not \includegraphics) +# - Verify NO HTML