Search code examples
luamarkdownpandocdocbook

formatting docbook admonitions with pandoc


Trying to use pandoc to format docbook admonitions as mkdocs flavour markdown admonitions in the following format:

!!! note
    This is a note

I have a lua filter that picks up the docbook admonition type + admonition body, and inserts the correct admonition type markup, but I can't figure out how to indent the actual text of the admonition which requires four spaces to be correctly formatted.

local stringify = (require 'pandoc.utils').stringify

local admonitions = {
  warning   = {pandoc.Str("!!! warning")},
  note      = {pandoc.Str("!!! note")},
  tip       = {pandoc.Str("!!! tip")},
  important = {pandoc.Str("!!! important")},
  caution   = {pandoc.Str("!!! caution")}
  }

function Div(el)
  local admonition_text = admonitions[el.classes[1]]
  if admonition_text then
    table.insert(el.content, 1,
        pandoc.Plain{ pandoc.Str(stringify(admonition_text)) })
  end
  return el
end

The above lua filter produces the following:

!!! note
This is a note

Solution

  • Answered here: https://groups.google.com/g/pandoc-discuss/c/65G0Kuih1wA

    -- requires pandoc 2.19+
    
    local admonitions = {
      warning   = '!!! warning',
      note      = '!!! note',
      tip       = '!!! tip',
      important = '!!! important',
      caution   = '!!! caution'
    }
    
    local opts = PANDOC_WRITER_OPTIONS -- reuse options to render snippets
    opts.columns = opts.columns - 4    -- admons are indented by four spaces
    opts.template = nil                -- render a snippet
    
    function Div (div)
      local admonition_text = admonitions[div.classes[1]]
      if not admonition_text then return nil end  -- not an admonition: exit
    
      local md = admonition_text .. '\n' ..
        pandoc.write(pandoc.Pandoc(div.content), 'markdown', opts)
      return pandoc.RawBlock(
        'markdown',
        md:gsub('\n*$', '')     -- remove trailing newlines
          :gsub('\n', '\n    ') -- indent block
      )
    end