简体   繁体   中英

Convertng Markdown admonition syntax to HTML, using Lua for Pandoc

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:

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

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

Here is a lua filter like Python-Markdown's Admonition extension syntax.

You can use many tags(CSS class names), and Quoted title ""

the different in this filter is you can't use indent, for pandoc do not thinkshould have a indent, so pandoc will render badly if you use indent.

!!! danger notes "title"
You should note that the title will be automatically capitalized.
```haskell
--code will be rendered
main::IO ()
main = main
```

*Emph string* and **strong string**

!!! important ""
admonition with no title

the lua filter

function Para(para)
  if para.content[1] and para.content[1].text == '!!!' and 
    para.content[2] and para.content[2].tag == 'Space' and 
    para.content[3] and para.content[3].tag == 'Str' then
    local text = para.content[3].text -- default title is tag
    tags = text
    title = string.upper(text)
    i = 4
    -- parse tags
    while para.content[i] and para.content[i].tag ~= 'SoftBreak'
    do
      -- tags can only be string or spaces
      if para.content[i].tag == 'Str' then
        tags = tags .. para.content[i].text
      elseif para.content[i].tag == 'Space' then
        tags = tags .. ' '
      -- Quoted is title
      elseif para.content[i].tag == 'Quoted' then
        title = pandoc.utils.stringify(para.content[i].content)
      end
      i = i + 1
    end
    if para.content[i] and para.content[i].tag == 'SoftBreak' then
      body = pandoc.List({table.unpack(para.content, i+1)})
    else
      body = '' -- no body
    end
    return pandoc.Blocks( -- merge into blocks
      {
        pandoc.RawInline(
          'html','<div class="admonition ' .. tags .. '">' ..
          '<p class="admonition-title">' .. title .. '</p>'
        ),
        pandoc.Plain(body),
        pandoc.RawInline('html', '</div>')
      }
    )
  end
end

preview output(the first paragraph)

$ pandoc test.md --lua-filter f.lua
<div class="admonition danger notes "><p class="admonition-title">title</p>
You should note that the title will be automatically capitalized.
</div>

you can add a stylesheet, for example H.html

<style>
div.note {
    background-color: #24502426;
}
div.danger {
    background-color: #8c24047a;
}
p.admonition-title {
    font-family: cursive;
}
</style>

then run

$ pandoc test.md --lua-filter f.lua -s -o main.html -H H.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM