From f3e5079f51af38f3fdc32c61b071ca132f1211ef Mon Sep 17 00:00:00 2001 From: Christophe Dervieux Date: Thu, 23 Oct 2025 20:19:54 +0200 Subject: [PATCH] Fix GFM callout rendering crash with empty content (#13603) The GFM callout renderer would crash with internal_error() when rendering callouts that had a title but no body content, because it didn't handle the case where callout.content is nil. This fix applies the same nil-safe pattern used by other format renderers (EPUB, RevealJS): default to empty Blocks when content is nil. --- news/changelog-1.9.md | 1 + src/resources/filters/customnodes/callout.lua | 7 +-- .../docs/smoke-all/2025/01/23/issue-13603.qmd | 43 +++++++++++++++++++ 3 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 tests/docs/smoke-all/2025/01/23/issue-13603.qmd diff --git a/news/changelog-1.9.md b/news/changelog-1.9.md index 4e2c3478ce3..637e292109f 100644 --- a/news/changelog-1.9.md +++ b/news/changelog-1.9.md @@ -17,6 +17,7 @@ All changes included in 1.9: ### `gfm` - ([#13421](https://github.com/quarto-dev/quarto-cli/issues/13421)): Do not word-wrap titles in header. +- ([#13603](https://github.com/quarto-dev/quarto-cli/issues/13603)): Fix callouts with title but no body content causing fatal error when rendering to GitHub Flavored Markdown. ### `html` diff --git a/src/resources/filters/customnodes/callout.lua b/src/resources/filters/customnodes/callout.lua index cd10970ddcf..8556981a0a8 100644 --- a/src/resources/filters/customnodes/callout.lua +++ b/src/resources/filters/customnodes/callout.lua @@ -207,11 +207,12 @@ function _callout_main() if tt ~= "nil" then result:insert(pandoc.Header(3, quarto.utils.as_inlines(callout.title))) end - local ct = pandoc.utils.type(callout.content) + local content = callout.content or pandoc.Blocks({}) + local ct = pandoc.utils.type(content) if ct == "Block" then - result:insert(callout.content) + result:insert(content) elseif ct == "Blocks" then - result:extend(callout.content) + result:extend(content) else internal_error() end diff --git a/tests/docs/smoke-all/2025/01/23/issue-13603.qmd b/tests/docs/smoke-all/2025/01/23/issue-13603.qmd new file mode 100644 index 00000000000..11a15f12cae --- /dev/null +++ b/tests/docs/smoke-all/2025/01/23/issue-13603.qmd @@ -0,0 +1,43 @@ +--- +title: "Callout with title but no body (#13603)" +format: gfm +_quarto: + tests: + gfm: + ensureFileRegexMatches: + - + # Should render both callouts with proper GFM structure + - '\[!TIP\]' + - '\[!NOTE\]' + # Both should be in blockquotes with titles + - '>\s*###\s*Title Only' + - '>\s*###\s*With Body' + # The second callout should have content + - '>\s*Content here' + - [] + noErrors: true +--- + +## Test callout with title but no body + +This tests the fix for issue #13603: callouts with a title but no body content +should render to GitHub Flavored Markdown without crashing. + +The issue occurred because the GFM renderer didn't handle the case where +`callout.content` is nil/empty. + +::: {.callout-tip} + +## Title Only + +::: + +## Callout with title and body (for comparison) + +::: {.callout-note} + +## With Body + +Content here. + +:::