Skip to content

Commit f6ecb11

Browse files
cscheidclaude
andauthored
Fix meta shortcode not preserving line breaks in values (#14061) (#14073)
The meta shortcode handler previously used processValue() for all contexts, which collapses multi-line metadata into inline content. Now handleMeta() dispatches based on context: block context returns Blocks directly via processValueInBlockContext(), inline context preserves the existing behavior, and text context (e.g. inside code blocks) writes blocks back as markdown to preserve structure. Closes #14061 Co-authored-by: Claude Opus 4.6 <[email protected]>
1 parent b4c5561 commit f6ecb11

3 files changed

Lines changed: 65 additions & 3 deletions

File tree

news/changelog-1.9.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ All changes included in 1.9:
33
## Shortcodes
44

55
- ([#13342](https://github.com/quarto-dev/quarto-cli/issues/13342)): Ensure that the `contents` shortcode works inside metadata.
6+
- ([#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.
67

78
## Regression fixes
89

src/resources/filters/quarto-pre/shortcodes-handlers.lua

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -251,12 +251,32 @@ function handleMeta(args, _kwargs, _meta, _raw_args, context)
251251

252252
-- read the option value
253253
local optionValue = option(varName, nil)
254-
if optionValue ~= nil then
255-
return processValue(optionValue, varName, "meta")
256-
else
254+
if optionValue == nil then
257255
warn("Unknown meta key " .. varName .. " specified in a metadata Shortcode.")
258256
return { pandoc.Strong(pandoc.Inlines {pandoc.Str("?meta:" .. varName)}) }
259257
end
258+
259+
if context == "block" then
260+
return processValueInBlockContext(optionValue, varName, "meta")
261+
elseif context == "inline" then
262+
return processValue(optionValue, varName, "meta")
263+
elseif context == "text" then
264+
-- As a special case, we treat the result of using
265+
--
266+
-- key2: '`Str "Something *with* a _line_ break\n\nI want to preserve"`{=pandoc-native}'
267+
--
268+
-- differently to allow users to specify precisely the
269+
-- string they want to use.
270+
if type(optionValue) == "table" and #optionValue > 0 and optionValue[1].t == "Str" then
271+
return optionValue[1].text
272+
else
273+
local blocks = pandoc.Blocks(optionValue)
274+
return pandoc.write(pandoc.Pandoc(blocks), "markdown")
275+
end
276+
else
277+
internal_error("Unknown context " .. context)
278+
return nil
279+
end
260280
else
261281
-- no args, we can't do anything
262282
return nil
@@ -306,6 +326,25 @@ function processValue(val, name, t)
306326
end
307327
end
308328

329+
function processValueInBlockContext(val, name, t)
330+
if type(val) == "table" then
331+
if #val == 0 then
332+
return { pandoc.Str( "") }
333+
end
334+
local pt = pandoc.utils.type(val)
335+
if pt == "Inlines" or pt == "Blocks" then
336+
return val
337+
elseif pt == "List" and #val == 1 then
338+
return processValueInBlockContext(val[1], name, t)
339+
else
340+
warn("Unsupported type '" .. pandoc.utils.type(val) .. "' for key " .. name .. " in a " .. t .. " shortcode.")
341+
return { pandoc.Strong(pandoc.Inlines { pandoc.Str("?invalid " .. t .. " type:" .. name) } ) }
342+
end
343+
else
344+
return { pandoc.Str( tostring(val) ) }
345+
end
346+
end
347+
309348

310349
function handlePagebreak()
311350

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
---
2+
format: html
3+
key: |
4+
Something with a line break
5+
6+
I want to preserve.
7+
_quarto:
8+
tests:
9+
html:
10+
ensureFileRegexMatches:
11+
-
12+
- "Something with a line break"
13+
- "I want to preserve"
14+
-
15+
- "line break I want"
16+
---
17+
18+
``` yaml
19+
{{< meta key >}}
20+
```
21+
22+
{{< meta key >}}

0 commit comments

Comments
 (0)