Blame data/sample.lua

Packit dda32d
-- This is a sample custom writer for pandoc.  It produces output
Packit dda32d
-- that is very similar to that of pandoc's HTML writer.
Packit dda32d
-- There is one new feature: code blocks marked with class 'dot'
Packit dda32d
-- are piped through graphviz and images are included in the HTML
Packit dda32d
-- output using 'data:' URLs.
Packit dda32d
--
Packit dda32d
-- Invoke with: pandoc -t sample.lua
Packit dda32d
--
Packit dda32d
-- Note:  you need not have lua installed on your system to use this
Packit dda32d
-- custom writer.  However, if you do have lua installed, you can
Packit dda32d
-- use it to test changes to the script.  'lua sample.lua' will
Packit dda32d
-- produce informative error messages if your code contains
Packit dda32d
-- syntax errors.
Packit dda32d
Packit dda32d
-- Character escaping
Packit dda32d
local function escape(s, in_attribute)
Packit dda32d
  return s:gsub("[<>&\"']",
Packit dda32d
    function(x)
Packit dda32d
      if x == '<' then
Packit dda32d
        return '<'
Packit dda32d
      elseif x == '>' then
Packit dda32d
        return '>'
Packit dda32d
      elseif x == '&' then
Packit dda32d
        return '&'
Packit dda32d
      elseif x == '"' then
Packit dda32d
        return '"'
Packit dda32d
      elseif x == "'" then
Packit dda32d
        return '''
Packit dda32d
      else
Packit dda32d
        return x
Packit dda32d
      end
Packit dda32d
    end)
Packit dda32d
end
Packit dda32d
Packit dda32d
-- Helper function to convert an attributes table into
Packit dda32d
-- a string that can be put into HTML tags.
Packit dda32d
local function attributes(attr)
Packit dda32d
  local attr_table = {}
Packit dda32d
  for x,y in pairs(attr) do
Packit dda32d
    if y and y ~= "" then
Packit dda32d
      table.insert(attr_table, ' ' .. x .. '="' .. escape(y,true) .. '"')
Packit dda32d
    end
Packit dda32d
  end
Packit dda32d
  return table.concat(attr_table)
Packit dda32d
end
Packit dda32d
Packit dda32d
-- Run cmd on a temporary file containing inp and return result.
Packit dda32d
local function pipe(cmd, inp)
Packit dda32d
  local tmp = os.tmpname()
Packit dda32d
  local tmph = io.open(tmp, "w")
Packit dda32d
  tmph:write(inp)
Packit dda32d
  tmph:close()
Packit dda32d
  local outh = io.popen(cmd .. " " .. tmp,"r")
Packit dda32d
  local result = outh:read("*all")
Packit dda32d
  outh:close()
Packit dda32d
  os.remove(tmp)
Packit dda32d
  return result
Packit dda32d
end
Packit dda32d
Packit dda32d
-- Table to store footnotes, so they can be included at the end.
Packit dda32d
local notes = {}
Packit dda32d
Packit dda32d
-- Blocksep is used to separate block elements.
Packit dda32d
function Blocksep()
Packit dda32d
  return "\n\n"
Packit dda32d
end
Packit dda32d
Packit dda32d
-- This function is called once for the whole document. Parameters:
Packit dda32d
-- body is a string, metadata is a table, variables is a table.
Packit dda32d
-- This gives you a fragment.  You could use the metadata table to
Packit dda32d
-- fill variables in a custom lua template.  Or, pass `--template=...`
Packit dda32d
-- to pandoc, and pandoc will add do the template processing as
Packit dda32d
-- usual.
Packit dda32d
function Doc(body, metadata, variables)
Packit dda32d
  local buffer = {}
Packit dda32d
  local function add(s)
Packit dda32d
    table.insert(buffer, s)
Packit dda32d
  end
Packit dda32d
  add(body)
Packit dda32d
  if #notes > 0 then
Packit dda32d
    add('
    ')
Packit dda32d
    for _,note in pairs(notes) do
Packit dda32d
      add(note)
Packit dda32d
    end
Packit dda32d
    add('')
Packit dda32d
  end
Packit dda32d
  return table.concat(buffer,'\n') .. '\n'
Packit dda32d
end
Packit dda32d
Packit dda32d
-- The functions that follow render corresponding pandoc elements.
Packit dda32d
-- s is always a string, attr is always a table of attributes, and
Packit dda32d
-- items is always an array of strings (the items in a list).
Packit dda32d
-- Comments indicate the types of other variables.
Packit dda32d
Packit dda32d
function Str(s)
Packit dda32d
  return escape(s)
Packit dda32d
end
Packit dda32d
Packit dda32d
function Space()
Packit dda32d
  return " "
Packit dda32d
end
Packit dda32d
Packit dda32d
function SoftBreak()
Packit dda32d
  return "\n"
Packit dda32d
end
Packit dda32d
Packit dda32d
function LineBreak()
Packit dda32d
  return "
"
Packit dda32d
end
Packit dda32d
Packit dda32d
function Emph(s)
Packit dda32d
  return "" .. s .. ""
Packit dda32d
end
Packit dda32d
Packit dda32d
function Strong(s)
Packit dda32d
  return "" .. s .. ""
Packit dda32d
end
Packit dda32d
Packit dda32d
function Subscript(s)
Packit dda32d
  return "<sub>" .. s .. "</sub>"
Packit dda32d
end
Packit dda32d
Packit dda32d
function Superscript(s)
Packit dda32d
  return "<sup>" .. s .. "</sup>"
Packit dda32d
end
Packit dda32d
Packit dda32d
function SmallCaps(s)
Packit dda32d
  return '' .. s .. ''
Packit dda32d
end
Packit dda32d
Packit dda32d
function Strikeout(s)
Packit dda32d
  return '' .. s .. ''
Packit dda32d
end
Packit dda32d
Packit dda32d
function Link(s, src, tit, attr)
Packit dda32d
  return "
Packit dda32d
         escape(tit,true) .. "'>" .. s .. ""
Packit dda32d
end
Packit dda32d
Packit dda32d
function Image(s, src, tit, attr)
Packit dda32d
  return "
Packit dda32d
         escape(tit,true) .. "'/>"
Packit dda32d
end
Packit dda32d
Packit dda32d
function Code(s, attr)
Packit dda32d
  return "<code" .. attributes(attr) .. ">" .. escape(s) .. ""
Packit dda32d
end
Packit dda32d
Packit dda32d
function InlineMath(s)
Packit dda32d
  return "\\(" .. escape(s) .. "\\)"
Packit dda32d
end
Packit dda32d
Packit dda32d
function DisplayMath(s)
Packit dda32d
  return "\\[" .. escape(s) .. "\\]"
Packit dda32d
end
Packit dda32d
Packit dda32d
function Note(s)
Packit dda32d
  local num = #notes + 1
Packit dda32d
  -- insert the back reference right before the final closing tag.
Packit dda32d
  s = string.gsub(s,
Packit dda32d
          '(.*)</', '%1 <a href="#fnref' .. num ..  '">↩</')
Packit dda32d
  -- add a list item with the note to the note table.
Packit dda32d
  table.insert(notes, '
  • ' .. s .. '
  • ')
    Packit dda32d
      -- return the footnote reference, linked to the note.
    Packit dda32d
      return '
    Packit dda32d
                '"><sup>' .. num .. '</sup>'
    Packit dda32d
    end
    Packit dda32d
    Packit dda32d
    function Span(s, attr)
    Packit dda32d
      return "<span" .. attributes(attr) .. ">" .. s .. ""
    Packit dda32d
    end
    Packit dda32d
    Packit dda32d
    function RawInline(format, str)
    Packit dda32d
      if format == "html" then
    Packit dda32d
        return str
    Packit dda32d
      else
    Packit dda32d
        return ''
    Packit dda32d
      end
    Packit dda32d
    end
    Packit dda32d
    Packit dda32d
    function Cite(s, cs)
    Packit dda32d
      local ids = {}
    Packit dda32d
      for _,cit in ipairs(cs) do
    Packit dda32d
        table.insert(ids, cit.citationId)
    Packit dda32d
      end
    Packit dda32d
      return "
    Packit dda32d
        "\">" .. s .. ""
    Packit dda32d
    end
    Packit dda32d
    Packit dda32d
    function Plain(s)
    Packit dda32d
      return s
    Packit dda32d
    end
    Packit dda32d
    Packit dda32d
    function Para(s)
    Packit dda32d
      return "

    " .. s .. "

    "
    Packit dda32d
    end
    Packit dda32d
    Packit dda32d
    -- lev is an integer, the header level.
    Packit dda32d
    function Header(lev, s, attr)
    Packit dda32d
      return "<h" .. lev .. attributes(attr) ..  ">" .. s .. "</h" .. lev .. ">"
    Packit dda32d
    end
    Packit dda32d
    Packit dda32d
    function BlockQuote(s)
    Packit dda32d
      return "
    \n" .. s .. "\n
    "
    Packit dda32d
    end
    Packit dda32d
    Packit dda32d
    function HorizontalRule()
    Packit dda32d
      return "
    "
    Packit dda32d
    end
    Packit dda32d
    Packit dda32d
    function LineBlock(ls)
    Packit dda32d
      return '
    ' .. table.concat(ls, '\n') ..
    Packit dda32d
             ''
    Packit dda32d
    end
    Packit dda32d
    Packit dda32d
    function CodeBlock(s, attr)
    Packit dda32d
      -- If code block has class 'dot', pipe the contents through dot
    Packit dda32d
      -- and base64, and include the base64-encoded png as a data: URL.
    Packit dda32d
      if attr.class and string.match(' ' .. attr.class .. ' ',' dot ') then
    Packit dda32d
        local png = pipe("base64", pipe("dot -Tpng", s))
    Packit dda32d
        return ''
    Packit dda32d
      -- otherwise treat as code (one could pipe through a highlighter)
    Packit dda32d
      else
    Packit dda32d
        return "
    <code" .. attributes(attr) .. ">" .. escape(s) ..
    Packit dda32d
               ""
    Packit dda32d
      end
    Packit dda32d
    end
    Packit dda32d
    Packit dda32d
    function BulletList(items)
    Packit dda32d
      local buffer = {}
    Packit dda32d
      for _, item in pairs(items) do
    Packit dda32d
        table.insert(buffer, "
  • " .. item .. "
  • ")
    Packit dda32d
      end
    Packit dda32d
      return "
      \n" .. table.concat(buffer, "\n") .. "\n
    "
    Packit dda32d
    end
    Packit dda32d
    Packit dda32d
    function OrderedList(items)
    Packit dda32d
      local buffer = {}
    Packit dda32d
      for _, item in pairs(items) do
    Packit dda32d
        table.insert(buffer, "
  • " .. item .. "
  • ")
    Packit dda32d
      end
    Packit dda32d
      return "
      \n" .. table.concat(buffer, "\n") .. "\n
    "
    Packit dda32d
    end
    Packit dda32d
    Packit dda32d
    function DefinitionList(items)
    Packit dda32d
      local buffer = {}
    Packit dda32d
      for _,item in pairs(items) do
    Packit dda32d
        local k, v = next(item)
    Packit dda32d
        table.insert(buffer, "
    " .. k .. "
    \n
    " ..
    Packit dda32d
                       table.concat(v, "\n
    ") .. "
    ")
    Packit dda32d
      end
    Packit dda32d
      return "
    \n" .. table.concat(buffer, "\n") .. "\n
    "
    Packit dda32d
    end
    Packit dda32d
    Packit dda32d
    -- Convert pandoc alignment to something HTML can use.
    Packit dda32d
    -- align is AlignLeft, AlignRight, AlignCenter, or AlignDefault.
    Packit dda32d
    function html_align(align)
    Packit dda32d
      if align == 'AlignLeft' then
    Packit dda32d
        return 'left'
    Packit dda32d
      elseif align == 'AlignRight' then
    Packit dda32d
        return 'right'
    Packit dda32d
      elseif align == 'AlignCenter' then
    Packit dda32d
        return 'center'
    Packit dda32d
      else
    Packit dda32d
        return 'left'
    Packit dda32d
      end
    Packit dda32d
    end
    Packit dda32d
    Packit dda32d
    function CaptionedImage(src, tit, caption, attr)
    Packit dda32d
       return '
    \n
    Packit dda32d
          '" title="' .. escape(tit,true) .. '"/>\n' ..
    Packit dda32d
          '

    ' .. caption .. '

    \n'
    Packit dda32d
    end
    Packit dda32d
    Packit dda32d
    -- Caption is a string, aligns is an array of strings,
    Packit dda32d
    -- widths is an array of floats, headers is an array of
    Packit dda32d
    -- strings, rows is an array of arrays of strings.
    Packit dda32d
    function Table(caption, aligns, widths, headers, rows)
    Packit dda32d
      local buffer = {}
    Packit dda32d
      local function add(s)
    Packit dda32d
        table.insert(buffer, s)
    Packit dda32d
      end
    Packit dda32d
      add("")
    Packit dda32d
      if caption ~= "" then
    Packit dda32d
        add("<caption>" .. caption .. "</caption>")
    Packit dda32d
      end
    Packit dda32d
      if widths and widths[1] ~= 0 then
    Packit dda32d
        for _, w in pairs(widths) do
    Packit dda32d
          add('')
    Packit dda32d
        end
    Packit dda32d
      end
    Packit dda32d
      local header_row = {}
    Packit dda32d
      local empty_header = true
    Packit dda32d
      for i, h in pairs(headers) do
    Packit dda32d
        local align = html_align(aligns[i])
    Packit dda32d
        table.insert(header_row,'' .. h .. '')
    Packit dda32d
        empty_header = empty_header and h == ""
    Packit dda32d
      end
    Packit dda32d
      if empty_header then
    Packit dda32d
        head = ""
    Packit dda32d
      else
    Packit dda32d
        add('')
    Packit dda32d
        for _,h in pairs(header_row) do
    Packit dda32d
          add(h)
    Packit dda32d
        end
    Packit dda32d
        add('')
    Packit dda32d
      end
    Packit dda32d
      local class = "even"
    Packit dda32d
      for _, row in pairs(rows) do
    Packit dda32d
        class = (class == "even" and "odd") or "even"
    Packit dda32d
        add('')
    Packit dda32d
        for i,c in pairs(row) do
    Packit dda32d
          add('' .. c .. '')
    Packit dda32d
        end
    Packit dda32d
        add('')
    Packit dda32d
      end
    Packit dda32d
      add('
    Packit dda32d
      return table.concat(buffer,'\n')
    Packit dda32d
    end
    Packit dda32d
    Packit dda32d
    function RawBlock(format, str)
    Packit dda32d
      if format == "html" then
    Packit dda32d
        return str
    Packit dda32d
      else
    Packit dda32d
        return ''
    Packit dda32d
      end
    Packit dda32d
    end
    Packit dda32d
    Packit dda32d
    function Div(s, attr)
    Packit dda32d
      return "<div" .. attributes(attr) .. ">\n" .. s .. ""
    Packit dda32d
    end
    Packit dda32d
    Packit dda32d
    -- The following code will produce runtime warnings when you haven't defined
    Packit dda32d
    -- all of the functions you need for the custom writer, so it's useful
    Packit dda32d
    -- to include when you're working on a writer.
    Packit dda32d
    local meta = {}
    Packit dda32d
    meta.__index =
    Packit dda32d
      function(_, key)
    Packit dda32d
        io.stderr:write(string.format("WARNING: Undefined function '%s'\n",key))
    Packit dda32d
        return function() return "" end
    Packit dda32d
      end
    Packit dda32d
    setmetatable(_G, meta)
    Packit dda32d