The Markdown admonition syntax is based on https://python-markdown.github.io/extensions/admonition/:
!!! note Important note
You should note that the title will be automatically capitalized.
The Pandoc documentation is very poorly explained and badly written. I've trained myself with the following questions:
- Pandoc Lua : how to add a markdown block around a header without losing the markdown syntax #
- Extend Pandoc with custom Markdown syntax
- Replace HTML tags using Pandoc Lua filter when converting from markdown to HTML
- pandoc lua filter to replace tex macro
- Pandoc Lua filters: how to specify attributes for Span element
- Character escaping in Pandoc filter pandoc.Para Lua function
- PandocLuaError "all choices failed" in custom pandoc writer
I attempted to build in Lua:
function Para (para)
if para.content[1].text == "!!!" and para.content[1].text == "note" then
return pandoc.Plain(
{pandoc.RawInline('html', '<div class="admonition note">')} ..
{pandoc.RawInline('html', '<p class="admonition-title">')} ..
para.content[2].text ..
{pandoc.RawInline('html', '</p>')} ..
para.content[3].text ..
{pandoc.RawInline('html', '</div>')}
)
elseif para.content[1].text == "!!!" and para.content[1].text == "danger" then
return pandoc.Plain(
{pandoc.RawInline('html', '<div class="admonition danger">')} ..
{pandoc.RawInline('html', '<p class="admonition-title">')} ..
para.content[2].text ..
{pandoc.RawInline('html', '</p>')} ..
para.content[3].text ..
{pandoc.RawInline('html', '</div>')}
)
end
end
I would expect:
<div class="admonition note">
<p class="admonition-title">Important note</p>
<p>You should note that the title will be automatically capitalized.</p>
</div>
Update 1
It almost worked, I just didn't like para.content[number].text
because I need to surround "Important note" for admonition title and to catch the whole sentence after that admonition title for a paragraph.
function Para(para)
if para.content[1].text == '!!!' and para.content[2].tag == 'Space' and para.content[3].text == 'note' then
return pandoc.RawInline('html',
'<div class="admonition note">'
.. '\n\t' ..
'<p class="admonition-title">'
.. para.content[5].text ..
'</p>'
.. '\n\t' ..
para.content[5].text ..
'\n' ..
'</div>')
elseif para.content[1].text == '!!!' and para.content[2].tag == 'Space' and para.content[3].text == 'danger' then
return pandoc.Emph {pandoc.Str "Danger"}
end
end
Update 2
Your answer worked, but doesn't work with two codes:
- When no title, it looks like:
!!! important ""
But it gave an output:
<div class="admonition important ““"><p class="admonition-title">IMPORTANT</p>
admonition with no title
</div>
You can notice important ““"
. If I want to use ""
to hide the title, it would give an output: <div class="admonition important"><p class="admonition-title no-title">IMPORTANT</p></div>
.
- When I want to include one than paragraphs, containing italic, bold,
blockquote
,code
, etc., your filter takes only the first paragraph, therefore, ignores the rest of the text. You can see the the reference: https://github.com/qjebbs/vscode-markdown-extended#admonition. It should look like in HTML:
<div class="admonition important"><p class="admonition-title">IMPORTANT</p>
<p> Here is the first paragraph with a <code>code</code>...</p>
<p> Here is the second paragraph with <i>italic</i> and <b>boild</b>...
<pre><code class="language-css">.css { color: black; }</code></pre>
<blockquote>
Accidit in puncto, quod non contingit in anno
</blockquote>
Julius Caesarus
</div>
Update 3
Please forgive me for failing to deliver the full CSS code for you before. Get the full code below:
@font-face {
font-family: "Material Icons";
font-style: normal;
font-weight: 400;
src: local("Material Icons"), local("MaterialIcons-Regular"), url("data:application/x-font-woff;charset=utf-8;base64,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") format("woff");
}
.admonition {
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .14), 0 1px 5px 0 rgba(0, 0, 0, .12), 0 3px 1px -2px rgba(0, 0, 0, .2);
position: relative;
margin: 1.5625em 0;
padding: 0 1.2rem;
border-left: .4rem solid rgba(68, 138, 255, .8);
border-radius: .2rem;
background-color: rgba(255, 255, 255, 0.05);
overflow: auto;
}
.admonition>p {
margin-top: .8rem;
}
.admonition>.admonition-title {
margin: 0 -1.2rem;
padding: .8rem 1.2rem .8rem 3.6rem;
border-bottom: 1px solid rgba(68, 138, 255, .2);
background-color: rgba(68, 138, 255, .1);
font-weight: 700;
}
.admonition>.admonition-title:before {
position: absolute;
left: 1.2rem;
font-size: 1.5rem;
color: rgba(68, 138, 255, .8);
content: "\E3C9";
}
.admonition>.admonition-title:before {
font-family: Material Icons;
font-style: normal;
font-variant: normal;
font-weight: 400;
line-height: 2rem;
text-transform: none;
white-space: nowrap;
speak: none;
word-wrap: normal;
direction: ltr;
}
.admonition.summary,
.admonition.abstract,
.admonition.tldr {
border-left-color: rgba(0, 176, 255, .8);
}
.admonition.summary>.admonition-title,
.admonition.abstract>.admonition-title,
.admonition.tldr>.admonition-title {
background-color: rgba(0, 176, 255, .1);
border-bottom-color: rgba(0, 176, 255, .2);
}
.admonition.summary>.admonition-title:before,
.admonition.abstract>.admonition-title:before,
.admonition.tldr>.admonition-title:before {
color: rgba(0, 176, 255, 1);
;
content: "\E8D2";
}
.admonition.hint,
.admonition.tip {
border-left-color: rgba(0, 191, 165, .8);
}
.admonition.hint>.admonition-title,
.admonition.tip>.admonition-title {
background-color: rgba(0, 191, 165, .1);
border-bottom-color: rgba(0, 191, 165, .2);
}
.admonition.hint>.admonition-title:before,
.admonition.tip>.admonition-title:before {
color: rgba(0, 191, 165, 1);
content: "\E80E";
}
.admonition.info,
.admonition.todo {
border-left-color: rgba(0, 184, 212, .8);
}
.admonition.info>.admonition-title,
.admonition.todo>.admonition-title {
background-color: rgba(0, 184, 212, .1);
border-bottom-color: rgba(0, 184, 212, .2);
}
.admonition.info>.admonition-title:before,
.admonition.todo>.admonition-title:before {
color: rgba(0, 184, 212, 1);
;
content: "\E88E";
}
.admonition.success,
.admonition.check,
.admonition.done {
border-left-color: rgba(0, 200, 83, .8);
}
.admonition.success>.admonition-title,
.admonition.check>.admonition-title,
.admonition.done>.admonition-title {
background-color: rgba(0, 200, 83, .1);
border-bottom-color: rgba(0, 200, 83, .2);
}
.admonition.success>.admonition-title:before,
.admonition.check>.admonition-title:before,
.admonition.done>.admonition-title:before {
color: rgba(0, 200, 83, 1);
;
content: "\E876";
}
.admonition.question,
.admonition.help,
.admonition.faq {
border-left-color: rgba(100, 221, 23, .8);
}
.admonition.question>.admonition-title,
.admonition.help>.admonition-title,
.admonition.faq>.admonition-title {
background-color: rgba(100, 221, 23, .1);
border-bottom-color: rgba(100, 221, 23, .2);
}
.admonition.question>.admonition-title:before,
.admonition.help>.admonition-title:before,
.admonition.faq>.admonition-title:before {
color: rgba(100, 221, 23, 1);
;
content: "\E887";
}
.admonition.warning,
.admonition.attention,
.admonition.caution {
border-left-color: rgba(255, 145, 0, .8);
}
.admonition.warning>.admonition-title,
.admonition.attention>.admonition-title,
.admonition.caution>.admonition-title {
background-color: rgba(255, 145, 0, .1);
border-bottom-color: rgba(255, 145, 0, .2);
}
.admonition.attention>.admonition-title:before {
color: rgba(255, 145, 0, 1);
content: "\E417";
}
.admonition.warning>.admonition-title:before,
.admonition.caution>.admonition-title:before {
color: rgba(255, 145, 0, 1);
content: "\E002";
}
.admonition.failure,
.admonition.fail,
.admonition.missing {
border-left-color: rgba(255, 82, 82, .8);
}
.admonition.failure>.admonition-title,
.admonition.fail>.admonition-title,
.admonition.missing>.admonition-title {
background-color: rgba(255, 82, 82, .1);
border-bottom-color: rgba(255, 82, 82, .2);
}
.admonition.failure>.admonition-title:before,
.admonition.fail>.admonition-title:before,
.admonition.missing>.admonition-title:before {
color: rgba(255, 82, 82, 1);
;
content: "\E14C";
}
.admonition.danger,
.admonition.error,
.admonition.bug {
border-left-color: rgba(255, 23, 68, .8);
}
.admonition.danger>.admonition-title,
.admonition.error>.admonition-title,
.admonition.bug>.admonition-title {
background-color: rgba(255, 23, 68, .1);
border-bottom-color: rgba(255, 23, 68, .2);
}
.admonition.danger>.admonition-title:before {
color: rgba(255, 23, 68, 1);
content: "\E3E7";
}
.admonition.error>.admonition-title:before {
color: rgba(255, 23, 68, 1);
content: "\E14C";
}
.admonition.bug>.admonition-title:before {
color: rgba(255, 23, 68, 1);
content: "\E868";
}
.admonition.example,
.admonition.snippet {
border-left-color: rgba(0, 184, 212, .8);
}
.admonition.example>.admonition-title,
.admonition.snippet>.admonition-title {
background-color: rgba(0, 184, 212, .1);
border-bottom-color: rgba(0, 184, 212, .2);
}
.admonition.example>.admonition-title:before,
.admonition.snippet>.admonition-title:before {
color: rgba(0, 184, 212, 1);
;
content: "\E242";
}
.admonition.quote,
.admonition.cite {
border-left-color: rgba(158, 158, 158, .8);
}
.admonition.quote>.admonition-title,
.admonition.cite>.admonition-title {
background-color: rgba(158, 158, 158, .1);
border-bottom-color: rgba(158, 158, 158, .2);
}
.admonition.quote>.admonition-title:before,
.admonition.cite>.admonition-title:before {
color: rgba(158, 158, 158, 1);
;
content: "\E244";
}
.no-title
{
display: none;
}
I had acknowledged of Pandoc's new Markdown syntax definition, but it is a bad idea to use dl
, dt
and dd
for admonitions because they are designed for definitions, dictionaries, and glossaries. But anyway, I also tested with and without a Markdown syntax :
and it wasn't what I expected.
With your updated Lua code, here is the result (click the image to enlarge):
In the second admonition, your filter didn't remove the title.
Expected:
You can compare the images and understand it easily.
I prepared Markdown and HTML codes for you.
Here is the Markdown code:
<!-- With title -->
!!! note "Pay attention!"
Title for notes
some code and text
```C
int main(){
puts("Hello World!");
}
```
It is a good code.
!!! danger "Be careful!"
Title for denger
some code and text
```python
print
```
It is not a good
<!-- Without title -->
!!! note ""
Title for notes
some code and text
```C
int main(){
puts("Hello World!");
}
```
It is a good code.
!!! danger "Be careful!"
Title for denger
some code and text
```python
print
```
It is not a good
And the HTML code:
<!-- With title -->
<div class="admonition note">
<p class="admonition-title">Pay attention!</p>
<p>Title for notes</p>
<p>some code and text</p>
<div class="sourceCode" id="cb1">
<pre class="sourceCode C"><code class="sourceCode c"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> main<span class="op">(){</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a> puts<span class="op">(</span><span class="st">"Hello World!"</span><span class="op">);</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre>
</div>
<p>It is a good code.</p>
<div class="admonition danger">
<p class="admonition-title">Be careful!</p>
<p>Title for denger</p>
<p>some code and text</p>
<div class="sourceCode" id="cb2">
<pre
class="sourceCode python"><code class="sourceCode python"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="bu">print</span>(<span class="st">"!!!"</span>)</span></code></pre>
</div>
<p>It is not a good code.</p>
</div>
</div>
<!-- Without title -->
<div class="admonition note">
<p class="admonition-title no-title">Pay attention!</p>
<p>Title for notes</p>
<p>some code and text</p>
<div class="sourceCode" id="cb3">
<pre class="sourceCode C"><code class="sourceCode c"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> main<span class="op">(){</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a> puts<span class="op">(</span><span class="st">"Hello World!"</span><span class="op">);</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre>
</div>
<p>It is a good code.</p>
<div class="admonition danger">
<p class="admonition-title">Be careful!</p>
<p>Title for denger</p>
<p>some code and text</p>
<div class="sourceCode" id="cb4">
<pre
class="sourceCode python"><code class="sourceCode python"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="bu">print</span>(<span class="st">"!!!"</span>)</span></code></pre>
</div>
<p>It is not a good code.</p>
</div>
</div>
para.content[1].text == "!!!" and para.content[1].text == "note"
is always false, as ispara.content[1].text == "!!!" and para.content[1].text == "danger"
; yourif
s can't possibly execute. You'll want to matchpara.content[1].text
against something such aspara.content[1].text:match"^!!!%s+note
. – Unequivocal:
at next line of title and tags, and pandoc read it as a whole definition list include its child admonitions.see Update 3 of my answer. – Guimond