Skip to content

Commit

Permalink
Merge pull request #9904 from quarto-dev/bugfix/9903
Browse files Browse the repository at this point in the history
Shortcodes - resolve inside element attributes
  • Loading branch information
cscheid authored Jun 6, 2024
2 parents 13d3126 + 4871572 commit 21980e4
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 3 deletions.
1 change: 1 addition & 0 deletions news/changelog-1.5.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ All changes included in 1.5:
- ([#9664](https://github.com/quarto-dev/quarto-cli/pull/9664)): Add `placeholder` shortcode to produce placeholder images.
- ([#9665](https://github.com/quarto-dev/quarto-cli/issues/9665)): Fix issue with key-value arguments of shortcode handlers in code contexts.
- ([#9793](https://github.com/quarto-dev/quarto-cli/issues/9793)): `embed` shortcode now correctly retrieve svg image from embdedded cell.
- ([#9903](https://github.com/quarto-dev/quarto-cli/issues/9903)): Allow shortcode resolution inside element attributes (currently headers, divs, spans, images, links). Currently, this requires attributes to be specified with single quotes, see issue for details.

## Lightbox Images

Expand Down
4 changes: 2 additions & 2 deletions src/core/markdown-pipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,11 @@ export function processMarkdownRenderEnvelope(
const markdownEnvelopeWriter = (envelopeId: string) => {
const renderList: string[] = [];
const hiddenSpan = (id: string, contents: string) => {
return `[${contents}]{.hidden render-id="${id}"}`;
return `[${contents}]{.hidden .quarto-markdown-envelope-contents render-id="${id}"}`;
};

const hiddenDiv = (id: string, contents: string) => {
return `\n:::{.hidden render-id="${id}"}\n${contents}\n:::\n`;
return `\n:::{.hidden .quarto-markdown-envelope-contents render-id="${id}"}\n${contents}\n:::\n`;
};

return {
Expand Down
29 changes: 29 additions & 0 deletions src/resources/filters/customnodes/shortcodes.lua
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,15 @@ function shortcodes_filter()
return el
end

local attr_handler = function(el)
for k,v in pairs(el.attributes) do
if type(v) == "string" then
el.attributes[k] = shortcode_lpeg.wrap_lpeg_match(code_shortcode, v)
end
end
return el
end

filter = {
Pandoc = function(doc)
-- first walk them in block context
Expand All @@ -274,22 +283,42 @@ function shortcodes_filter()
Code = code_handler,
RawBlock = code_handler,
CodeBlock = code_handler,
Header = attr_handler,
Div = function(el)
if el.classes:includes("quarto-markdown-envelope-contents") then
return nil
end
if el.classes:includes("quarto-shortcode__-escaped") then
return pandoc.Plain(pandoc.Str(el.attributes["data-value"]))
else
el = attr_handler(el)
return el
end
end,
})

doc = _quarto.ast.walk(doc, {
Shortcode = inline_handler,
RawInline = code_handler,
Image = function(el)
el = attr_handler(el)
el.src = shortcode_lpeg.wrap_lpeg_match(code_shortcode, el.src)
return el
end,
Link = function(el)
el = attr_handler(el)
el.target = shortcode_lpeg.wrap_lpeg_match(code_shortcode, el.target)
return el
end,
Span = function(el)
if el.classes:includes("quarto-markdown-envelope-contents") then
return nil
end
if el.classes:includes("quarto-shortcode__-escaped") then
return pandoc.Str(el.attributes["data-value"])
else
el = attr_handler(el)
return el
end
end,
})
Expand Down
2 changes: 1 addition & 1 deletion src/resources/pandoc/datadir/lpegshortcode.lua
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ md_shortcode = make_shortcode_parser({
keyvalue = md_keyvalue_param,
shortcode = md_shortcode,

ignore_pattern = lpeg.P("{.hidden render-id=\"") * (lpeg.P(1) - lpeg.P("\"}"))^1 * lpeg.P("\"}")
ignore_pattern = lpeg.P("{.hidden .quarto-markdown-envelope-contents render-id=\"") * (lpeg.P(1) - lpeg.P("\"}"))^1 * lpeg.P("\"}")
})

local escaped_string = into_string(
Expand Down
15 changes: 15 additions & 0 deletions src/resources/pandoc/datadir/readqmd.lua
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,16 @@ local function readqmd(txt, opts)
return c
end

local function filter_attrs(el)
for k,v in pairs(el.attributes) do
if type(v) == "string" and v:match("data%-is%-shortcode%=%\"1%\"") then
local new_v = md_shortcode.unparse_md_shortcode(v)
el.attributes[k] = new_v
end
end
return el
end

local doc = pandoc.read(txt or "", flavor, opts):walk {
CodeBlock = function (cb)
cb.classes = cb.classes:map(restore_invalid_tags)
Expand All @@ -166,13 +176,18 @@ local function readqmd(txt, opts)
Code = unshortcode_text,
RawInline = unshortcode_text,
RawBlock = unshortcode_text,
Header = filter_attrs,
Span = filter_attrs,
Div = filter_attrs,
Link = function (l)
l = filter_attrs(l)
if l.target:match("data%-is%-shortcode%=%%221%%22") then
l.target = md_shortcode.unparse_md_shortcode(urldecode(l.target))
return l
end
end,
Image = function (i)
i = filter_attrs(i)
if i.src:match("data%-is%-shortcode%=%%221%%22") then
i.src = md_shortcode.unparse_md_shortcode(urldecode(i.src))
return i
Expand Down
28 changes: 28 additions & 0 deletions tests/docs/smoke-all/2024/06/06/9903.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
format: html
htmllink: "https://www.example.com"
_quarto:
tests:
html:
ensureHtmlElements:
-
- "h2[data-background-iframe='https://www.example.com']"
- "a[data-attr='https://www.example.com']"
- "span#foo[data-attr='https://www.example.com']"
- "div#div-1[data-attr='https://www.example.com']"
- []
---

## Slide Title {background-iframe='{{< meta htmllink >}}'}

[A link]({{< meta htmllink >}}){attr='{{< meta htmllink >}}'}.

![An image]({{< placeholder >}}){attr='{{< meta htmllink >}}'}

[A span]{#foo attr='{{< meta htmllink >}}'}.

::: {#div-1 attr='{{< meta htmllink >}}'}

A div.

:::

0 comments on commit 21980e4

Please sign in to comment.