diff --git a/news/changelog-1.9.md b/news/changelog-1.9.md index 0f61d281a9..ac0efdd876 100644 --- a/news/changelog-1.9.md +++ b/news/changelog-1.9.md @@ -3,6 +3,7 @@ All changes included in 1.9: ## Shortcodes - ([#13342](https://github.com/quarto-dev/quarto-cli/issues/13342)): Ensure that the `contents` shortcode works inside metadata. +- ([#14061](https://github.com/quarto-dev/quarto-cli/issues/14061)): Fix `meta` shortcode not preserving line breaks in values. The shortcode now respects its usage context (block, inline, or text) and preserves paragraph breaks in block and code block contexts. ## Regression fixes diff --git a/src/resources/filters/quarto-pre/shortcodes-handlers.lua b/src/resources/filters/quarto-pre/shortcodes-handlers.lua index f9961de308..52f5d30fe2 100644 --- a/src/resources/filters/quarto-pre/shortcodes-handlers.lua +++ b/src/resources/filters/quarto-pre/shortcodes-handlers.lua @@ -251,12 +251,32 @@ function handleMeta(args, _kwargs, _meta, _raw_args, context) -- read the option value local optionValue = option(varName, nil) - if optionValue ~= nil then - return processValue(optionValue, varName, "meta") - else + if optionValue == nil then warn("Unknown meta key " .. varName .. " specified in a metadata Shortcode.") return { pandoc.Strong(pandoc.Inlines {pandoc.Str("?meta:" .. varName)}) } end + + if context == "block" then + return processValueInBlockContext(optionValue, varName, "meta") + elseif context == "inline" then + return processValue(optionValue, varName, "meta") + elseif context == "text" then + -- As a special case, we treat the result of using + -- + -- key2: '`Str "Something *with* a _line_ break\n\nI want to preserve"`{=pandoc-native}' + -- + -- differently to allow users to specify precisely the + -- string they want to use. + if type(optionValue) == "table" and #optionValue > 0 and optionValue[1].t == "Str" then + return optionValue[1].text + else + local blocks = pandoc.Blocks(optionValue) + return pandoc.write(pandoc.Pandoc(blocks), "markdown") + end + else + internal_error("Unknown context " .. context) + return nil + end else -- no args, we can't do anything return nil @@ -306,6 +326,25 @@ function processValue(val, name, t) end end +function processValueInBlockContext(val, name, t) + if type(val) == "table" then + if #val == 0 then + return { pandoc.Str( "") } + end + local pt = pandoc.utils.type(val) + if pt == "Inlines" or pt == "Blocks" then + return val + elseif pt == "List" and #val == 1 then + return processValueInBlockContext(val[1], name, t) + else + warn("Unsupported type '" .. pandoc.utils.type(val) .. "' for key " .. name .. " in a " .. t .. " shortcode.") + return { pandoc.Strong(pandoc.Inlines { pandoc.Str("?invalid " .. t .. " type:" .. name) } ) } + end + else + return { pandoc.Str( tostring(val) ) } + end +end + function handlePagebreak() diff --git a/tests/docs/smoke-all/2026/02/20/14061.qmd b/tests/docs/smoke-all/2026/02/20/14061.qmd new file mode 100644 index 0000000000..21802eab5a --- /dev/null +++ b/tests/docs/smoke-all/2026/02/20/14061.qmd @@ -0,0 +1,22 @@ +--- +format: html +key: | + Something with a line break + + I want to preserve. +_quarto: + tests: + html: + ensureFileRegexMatches: + - + - "Something with a line break" + - "I want to preserve" + - + - "line break I want" +--- + +``` yaml +{{< meta key >}} +``` + +{{< meta key >}}