If you need to render a format not already handled by pandoc, or you want to change how pandoc renders a format, you can create a custom writer using the Lua language. Pandoc has a built-in Lua interpreter, so you needn't install any additional software to do this.
A custom writer is a Lua file that defines how to render the
document. Two styles of custom writers are supported: classic custom
writers must define rendering functions for each AST element. New style
writers, available since pandoc 2.17.2, must define just a single
function Writer
, which gets passed the document and writer
options, and then does all rendering.
A writer using the classic style defines rendering functions for each element of the pandoc AST.
For example,
function Para(s)
return "<paragraph>" .. s .. "</paragraph>"
end
The best way to go about creating a classic custom writer is to modify the example that comes with pandoc. To get the example, you can do
pandoc --print-default-data-file sample.lua > sample.lua
sample.lua
is a full-features HTML writer, with
explanatory comments. To use it, just use the path to the custom writer
as the writer name:
pandoc -t sample.lua myfile.md
sample.lua
defines all the functions needed by any
custom writer, so you can design your own custom writer by modifying the
functions in sample.lua
according to your needs.
New template variables can be added, or existing ones modified, by
returning a second value from function Doc
.
For example, the following will add the current date in variable
date
, unless date
is already defined as either
a metadata value or a variable:
function Doc (body, meta, vars)
.date = vars.date or meta.data or os.date '%B %e, %Y'
varsreturn body, vars
end
Custom writers using the new style must contain a global function
named Writer
. Pandoc calls this function with the document
and writer options as arguments, and expects the function to return a
string.
function Writer (doc, opts)
-- ...
end
Writers have access to all modules described in the Lua filters
documentation. This includes pandoc.write
, which can be
used to render a document in a format already supported by pandoc. The
document can be modified before this conversion, as demonstrated in the
following short example. It renders a document as GitHub Flavored
Markdown, but always uses fenced code blocks, never indented code.
function Writer (doc, opts)
local filter = {
CodeBlock = function (cb)
-- only modify if code block has no attributes
if cb.attr == pandoc.Attr() then
local delimited = '```\n' .. cb.text .. '\n```'
return pandoc.RawBlock('markdown', delimited)
end
end
}
return pandoc.write(doc:walk(filter), 'gfm', opts)
end