mirror of
https://github.com/getzola/zola
synced 2024-12-13 22:02:29 +00:00
Fix shortcode handling in code-fences (#1720)
* rendering/markdown: fix shortcode handling in codefences * rendering/tests: add a bunch of tests for codefence + shortcode usages
This commit is contained in:
parent
ef3a16f3a8
commit
684bc2dd74
2 changed files with 297 additions and 1 deletions
|
@ -242,7 +242,32 @@ pub fn markdown_to_html(
|
|||
match event {
|
||||
Event::Text(text) => {
|
||||
if let Some(ref mut code_block) = code_block {
|
||||
let html = code_block.highlight(&text);
|
||||
let html;
|
||||
if contains_shortcode(text.as_ref()) {
|
||||
let mut accumulated_block = String::new();
|
||||
// mark the start of the code block events
|
||||
let stack_start = events.len();
|
||||
render_shortcodes!(true, text, range);
|
||||
// after rendering the shortcodes we will collect all the text events
|
||||
// and re-render them as code blocks
|
||||
for event in events[stack_start..].iter() {
|
||||
match event {
|
||||
Event::Html(t) | Event::Text(t) => accumulated_block += t,
|
||||
_ => {
|
||||
error = Some(Error::msg(format!(
|
||||
"Unexpected event while expanding the code block: {:?}",
|
||||
event
|
||||
)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
html = code_block.highlight(&accumulated_block);
|
||||
// remove all the original events from shortcode rendering
|
||||
events.truncate(stack_start);
|
||||
} else {
|
||||
html = code_block.highlight(&text);
|
||||
}
|
||||
events.push(Event::Html(html.into()));
|
||||
} else {
|
||||
let text = if context.config.markdown.render_emoji {
|
||||
|
|
271
components/rendering/tests/codeblock_shortcode_mix.rs
Normal file
271
components/rendering/tests/codeblock_shortcode_mix.rs
Normal file
|
@ -0,0 +1,271 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use config::Config;
|
||||
use front_matter::InsertAnchor;
|
||||
use templates::ZOLA_TERA;
|
||||
use rendering::{render_content, RenderContext};
|
||||
|
||||
#[test]
|
||||
fn can_render_shortcode_in_codeblock() {
|
||||
let permalinks_ctx = HashMap::new();
|
||||
let config = Config::default_for_test();
|
||||
let mut context = RenderContext::new(
|
||||
&ZOLA_TERA,
|
||||
&config,
|
||||
&config.default_language,
|
||||
"",
|
||||
&permalinks_ctx,
|
||||
InsertAnchor::None,
|
||||
);
|
||||
let shortcode_def = utils::templates::get_shortcodes(&ZOLA_TERA);
|
||||
context.set_shortcode_definitions(&shortcode_def);
|
||||
// simple case
|
||||
let res = render_content(
|
||||
r#"
|
||||
```
|
||||
{{ youtube(id="dQw4w9WgXcQ") }}
|
||||
```
|
||||
"#,
|
||||
&context,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
res.body,
|
||||
"<pre><code><div >\n <iframe src="https://www.youtube-nocookie.com/embed/dQw4w9WgXcQ" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>\n</div>\n\n</code></pre>\n"
|
||||
);
|
||||
// mixed with other contents
|
||||
let res = render_content(
|
||||
r#"
|
||||
```
|
||||
<div id="custom-attr">
|
||||
{{ youtube(id="dQw4w9WgXcQ") }}
|
||||
</div>
|
||||
```
|
||||
"#,
|
||||
&context,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
res.body,
|
||||
"<pre><code><div id="custom-attr">\n<div >\n <iframe src="https://www.youtube-nocookie.com/embed/dQw4w9WgXcQ" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>\n</div>\n\n</div>\n</code></pre>\n"
|
||||
);
|
||||
// mixed content with syntax and line numbers
|
||||
let res = render_content(
|
||||
r#"
|
||||
```html,linenos
|
||||
<div id="custom-attr">
|
||||
{{ youtube(id="dQw4w9WgXcQ") }}
|
||||
</div>
|
||||
```
|
||||
"#,
|
||||
&context,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
res.body,
|
||||
"<pre data-linenos data-lang=\"html\" class=\"language-html \"><code class=\"language-html\" data-lang=\"html\"><table><tbody><tr><td>1</td><td><div id="custom-attr">\n<tr><td>2</td><td><div >\n<tr><td>3</td><td> <iframe src="https://www.youtube-nocookie.com/embed/dQw4w9WgXcQ" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>\n<tr><td>4</td><td></div>\n<tr><td>5</td><td>\n<tr><td>6</td><td></div>\n</tr></tbody></table></code></pre>\n"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_render_multiple_shortcodes_in_codeblock() {
|
||||
let permalinks_ctx = HashMap::new();
|
||||
let config = Config::default_for_test();
|
||||
let mut context = RenderContext::new(
|
||||
&ZOLA_TERA,
|
||||
&config,
|
||||
&config.default_language,
|
||||
"",
|
||||
&permalinks_ctx,
|
||||
InsertAnchor::None,
|
||||
);
|
||||
let shortcode_def = utils::templates::get_shortcodes(&ZOLA_TERA);
|
||||
context.set_shortcode_definitions(&shortcode_def);
|
||||
// simple case
|
||||
let res = render_content(
|
||||
r#"
|
||||
```
|
||||
{{ youtube(id="dQw4w9WgXcQ") }}
|
||||
{{ gist(url="https://gist.github.com/Keats/e5fb6aad409f28721c0ba14161644c57", class="gist") }}
|
||||
```
|
||||
"#,
|
||||
&context,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
res.body,
|
||||
"<pre><code><div >\n <iframe src="https://www.youtube-nocookie.com/embed/dQw4w9WgXcQ" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>\n</div>\n\n<div class="gist">\n <script src="https:&#x2F;&#x2F;gist.github.com&#x2F;Keats&#x2F;e5fb6aad409f28721c0ba14161644c57.js"></script>\n</div>\n\n</code></pre>\n"
|
||||
);
|
||||
// mixed with other contents
|
||||
let res = render_content(
|
||||
r#"
|
||||
```
|
||||
text 1
|
||||
{{ youtube(id="dQw4w9WgXcQ") }}
|
||||
text 2
|
||||
{{ gist(url="https://gist.github.com/Keats/e5fb6aad409f28721c0ba14161644c57", class="gist") }}
|
||||
text 3
|
||||
```
|
||||
"#,
|
||||
&context,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
res.body,
|
||||
"<pre><code>text 1\n<div >\n <iframe src="https://www.youtube-nocookie.com/embed/dQw4w9WgXcQ" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>\n</div>\n\ntext 2\n<div class="gist">\n <script src="https:&#x2F;&#x2F;gist.github.com&#x2F;Keats&#x2F;e5fb6aad409f28721c0ba14161644c57.js"></script>\n</div>\n\ntext 3\n</code></pre>\n"
|
||||
);
|
||||
// mixed content with syntax and line numbers
|
||||
let res = render_content(
|
||||
r#"
|
||||
```html,linenos
|
||||
<span>text 1</span>
|
||||
{{ youtube(id="dQw4w9WgXcQ") }}
|
||||
<span>text 2</span>
|
||||
{{ gist(url="https://gist.github.com/Keats/e5fb6aad409f28721c0ba14161644c57", class="gist") }}
|
||||
<span>text 3</span>
|
||||
```
|
||||
"#,
|
||||
&context,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
res.body,
|
||||
r#"<pre data-linenos data-lang="html" class="language-html "><code class="language-html" data-lang="html"><table><tbody><tr><td>1</td><td><span>text 1</span>
|
||||
<tr><td>2</td><td><div >
|
||||
<tr><td>3</td><td> <iframe src="https://www.youtube-nocookie.com/embed/dQw4w9WgXcQ" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
|
||||
<tr><td>4</td><td></div>
|
||||
<tr><td>5</td><td>
|
||||
<tr><td>6</td><td><span>text 2</span>
|
||||
<tr><td>7</td><td><div class="gist">
|
||||
<tr><td>8</td><td> <script src="https:&#x2F;&#x2F;gist.github.com&#x2F;Keats&#x2F;e5fb6aad409f28721c0ba14161644c57.js"></script>
|
||||
<tr><td>9</td><td></div>
|
||||
<tr><td>10</td><td>
|
||||
<tr><td>11</td><td><span>text 3</span>
|
||||
</tr></tbody></table></code></pre>
|
||||
"#
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn is_highlighting_linenos_still_working() {
|
||||
let permalinks_ctx = HashMap::new();
|
||||
let mut config = Config::default_for_test();
|
||||
config.markdown.highlight_code = true;
|
||||
let mut context = RenderContext::new(
|
||||
&ZOLA_TERA,
|
||||
&config,
|
||||
&config.default_language,
|
||||
"",
|
||||
&permalinks_ctx,
|
||||
InsertAnchor::None,
|
||||
);
|
||||
let shortcode_def = utils::templates::get_shortcodes(&ZOLA_TERA);
|
||||
context.set_shortcode_definitions(&shortcode_def);
|
||||
// single shortcode mixed with syntax and line numbers
|
||||
let res = render_content(
|
||||
r#"
|
||||
```html,linenos
|
||||
<div id="custom-attr">
|
||||
{{ youtube(id="dQw4w9WgXcQ") }}
|
||||
</div>
|
||||
```
|
||||
"#,
|
||||
&context,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
res.body,
|
||||
"<pre data-linenos data-lang=\"html\" style=\"background-color:#2b303b;color:#c0c5ce;\" class=\"language-html \"><code class=\"language-html\" data-lang=\"html\"><table><tbody><tr><td>1</td><td><span><</span><span style=\"color:#bf616a;\">div </span><span style=\"color:#8fa1b3;\">id</span><span>="</span><span style=\"color:#a3be8c;\">custom-attr</span><span>">\n</span><tr><td>2</td><td><span><</span><span style=\"color:#bf616a;\">div </span><span>>\n</span><tr><td>3</td><td><span> <</span><span style=\"color:#bf616a;\">iframe </span><span style=\"color:#d08770;\">src</span><span>="</span><span style=\"color:#a3be8c;\">https://www.youtube-nocookie.com/embed/dQw4w9WgXcQ</span><span>" </span><span style=\"color:#d08770;\">webkitallowfullscreen mozallowfullscreen allowfullscreen</span><span>></</span><span style=\"color:#bf616a;\">iframe</span><span>>\n</span><tr><td>4</td><td><span></</span><span style=\"color:#bf616a;\">div</span><span>>\n</span><tr><td>5</td><td><span>\n</span><tr><td>6</td><td><span></</span><span style=\"color:#bf616a;\">div</span><span>>\n</span></tr></tbody></table></code></pre>\n"
|
||||
);
|
||||
// multiple shortcode mixed with syntax and line numbers
|
||||
let res = render_content(
|
||||
r#"
|
||||
```html,linenos
|
||||
<span>text 1</span>
|
||||
{{ youtube(id="dQw4w9WgXcQ") }}
|
||||
<span>text 2</span>
|
||||
{{ gist(url="https://gist.github.com/Keats/e5fb6aad409f28721c0ba14161644c57", class="gist") }}
|
||||
<span>text 3</span>
|
||||
```
|
||||
"#,
|
||||
&context,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
res.body,
|
||||
r#"<pre data-linenos data-lang="html" style="background-color:#2b303b;color:#c0c5ce;" class="language-html "><code class="language-html" data-lang="html"><table><tbody><tr><td>1</td><td><span><</span><span style="color:#bf616a;">span</span><span>>text 1</</span><span style="color:#bf616a;">span</span><span>>
|
||||
</span><tr><td>2</td><td><span><</span><span style="color:#bf616a;">div </span><span>>
|
||||
</span><tr><td>3</td><td><span> <</span><span style="color:#bf616a;">iframe </span><span style="color:#d08770;">src</span><span>="</span><span style="color:#a3be8c;">https://www.youtube-nocookie.com/embed/dQw4w9WgXcQ</span><span>" </span><span style="color:#d08770;">webkitallowfullscreen mozallowfullscreen allowfullscreen</span><span>></</span><span style="color:#bf616a;">iframe</span><span>>
|
||||
</span><tr><td>4</td><td><span></</span><span style="color:#bf616a;">div</span><span>>
|
||||
</span><tr><td>5</td><td><span>
|
||||
</span><tr><td>6</td><td><span><</span><span style="color:#bf616a;">span</span><span>>text 2</</span><span style="color:#bf616a;">span</span><span>>
|
||||
</span><tr><td>7</td><td><span><</span><span style="color:#bf616a;">div </span><span style="color:#d08770;">class</span><span>="</span><span style="color:#a3be8c;">gist</span><span>">
|
||||
</span><tr><td>8</td><td><span> <</span><span style="color:#bf616a;">script </span><span style="color:#d08770;">src</span><span>="</span><span style="color:#a3be8c;">https:</span><span style="color:#8fa1b3;">&#x</span><span style="color:#d08770;">2F;</span><span style="color:#8fa1b3;">&#x</span><span style="color:#d08770;">2F;</span><span style="color:#a3be8c;">gist.github.com</span><span style="color:#8fa1b3;">&#x</span><span style="color:#d08770;">2F;</span><span style="color:#a3be8c;">Keats</span><span style="color:#8fa1b3;">&#x</span><span style="color:#d08770;">2F;</span><span style="color:#a3be8c;">e5fb6aad409f28721c0ba14161644c57.js</span><span>"></</span><span style="color:#bf616a;">script</span><span>>
|
||||
</span><tr><td>9</td><td><span></</span><span style="color:#bf616a;">div</span><span>>
|
||||
</span><tr><td>10</td><td><span>
|
||||
</span><tr><td>11</td><td><span><</span><span style="color:#bf616a;">span</span><span>>text 3</</span><span style="color:#bf616a;">span</span><span>>
|
||||
</span></tr></tbody></table></code></pre>
|
||||
"#
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn codeblock_shortcode_mix_all_stars() {
|
||||
let permalinks_ctx = HashMap::new();
|
||||
let mut config = Config::default_for_test();
|
||||
config.markdown.highlight_code = true;
|
||||
let mut context = RenderContext::new(
|
||||
&ZOLA_TERA,
|
||||
&config,
|
||||
&config.default_language,
|
||||
"",
|
||||
&permalinks_ctx,
|
||||
InsertAnchor::None,
|
||||
);
|
||||
let shortcode_def = utils::templates::get_shortcodes(&ZOLA_TERA);
|
||||
context.set_shortcode_definitions(&shortcode_def);
|
||||
// single shortcode mixed with syntax and line numbers
|
||||
let res = render_content(
|
||||
r#"
|
||||
```html,linenos
|
||||
<a href="javascript:void(0);">{{/* before(texts="1") */}}</a>
|
||||
Normally people would not write something & like <> this:
|
||||
<div id="custom-attr">
|
||||
An inline {{ youtube(id="dQw4w9WgXcQ", autoplay=true, class="youtube") }} shortcode
|
||||
</div>
|
||||
Plain text in-between
|
||||
{%/* quote(author="Vincent") */%}
|
||||
A quote
|
||||
{%/* end */%}
|
||||
{{ gist(url="https://gist.github.com/Keats/e5fb6aad409f28721c0ba14161644c57", class="gist") }}
|
||||
{# A Tera comment, you should see it #}
|
||||
<!-- end text goes here -->
|
||||
```
|
||||
"#,
|
||||
&context,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
res.body,
|
||||
r#"<pre data-linenos data-lang="html" style="background-color:#2b303b;color:#c0c5ce;" class="language-html "><code class="language-html" data-lang="html"><table><tbody><tr><td>1</td><td><span><</span><span style="color:#bf616a;">a </span><span style="color:#d08770;">href</span><span>="</span><span style="color:#a3be8c;">javascript:void(0);</span><span>">{{ before(texts="1") }}</</span><span style="color:#bf616a;">a</span><span>>
|
||||
</span><tr><td>2</td><td><span>Normally people would not write something & like </span><span style="background-color:#bf616a;color:#2b303b;"><></span><span> this:
|
||||
</span><tr><td>3</td><td><span><</span><span style="color:#bf616a;">div </span><span style="color:#8fa1b3;">id</span><span>="</span><span style="color:#a3be8c;">custom-attr</span><span>">
|
||||
</span><tr><td>4</td><td><span>An inline <</span><span style="color:#bf616a;">div </span><span style="color:#d08770;">class</span><span>="</span><span style="color:#a3be8c;">youtube</span><span>">
|
||||
</span><tr><td>5</td><td><span> <</span><span style="color:#bf616a;">iframe </span><span style="color:#d08770;">src</span><span>="</span><span style="color:#a3be8c;">https://www.youtube-nocookie.com/embed/dQw4w9WgXcQ?autoplay=1</span><span>" </span><span style="color:#d08770;">webkitallowfullscreen mozallowfullscreen allowfullscreen</span><span>></</span><span style="color:#bf616a;">iframe</span><span>>
|
||||
</span><tr><td>6</td><td><span></</span><span style="color:#bf616a;">div</span><span>>
|
||||
</span><tr><td>7</td><td><span> shortcode
|
||||
</span><tr><td>8</td><td><span></</span><span style="color:#bf616a;">div</span><span>>
|
||||
</span><tr><td>9</td><td><span>Plain text in-between
|
||||
</span><tr><td>10</td><td><span>{% quote(author="Vincent") %}
|
||||
</span><tr><td>11</td><td><span>A quote
|
||||
</span><tr><td>12</td><td><span>{% end %}
|
||||
</span><tr><td>13</td><td><span><</span><span style="color:#bf616a;">div </span><span style="color:#d08770;">class</span><span>="</span><span style="color:#a3be8c;">gist</span><span>">
|
||||
</span><tr><td>14</td><td><span> <</span><span style="color:#bf616a;">script </span><span style="color:#d08770;">src</span><span>="</span><span style="color:#a3be8c;">https:</span><span style="color:#8fa1b3;">&#x</span><span style="color:#d08770;">2F;</span><span style="color:#8fa1b3;">&#x</span><span style="color:#d08770;">2F;</span><span style="color:#a3be8c;">gist.github.com</span><span style="color:#8fa1b3;">&#x</span><span style="color:#d08770;">2F;</span><span style="color:#a3be8c;">Keats</span><span style="color:#8fa1b3;">&#x</span><span style="color:#d08770;">2F;</span><span style="color:#a3be8c;">e5fb6aad409f28721c0ba14161644c57.js</span><span>"></</span><span style="color:#bf616a;">script</span><span>>
|
||||
</span><tr><td>15</td><td><span></</span><span style="color:#bf616a;">div</span><span>>
|
||||
</span><tr><td>16</td><td><span>
|
||||
</span><tr><td>17</td><td><span>{# A Tera comment, you should see it #}
|
||||
</span><tr><td>18</td><td><span style="color:#65737e;"><!-- end text goes here -->
|
||||
</span></tr></tbody></table></code></pre>
|
||||
"#
|
||||
);
|
||||
}
|
Loading…
Reference in a new issue