-
-
Save tarleb/634b409be0af62ca210cc9e96d41ca8c to your computer and use it in GitHub Desktop.
Produce "native" pandoc XML
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local stringify = pandoc.utils.stringify | |
local List = pandoc.List | |
-- The global variable PANDOC_DOCUMENT contains the full AST of | |
-- the document which is going to be written. It can be used to | |
-- configure the writer. | |
local meta = PANDOC_DOCUMENT.meta | |
-- Character escaping | |
local function escape(s, in_attribute) | |
return s:gsub("[<>&\"']", | |
function(x) | |
if x == '<' then | |
return '<' | |
elseif x == '>' then | |
return '>' | |
elseif x == '&' then | |
return '&' | |
elseif in_attribute and x == '"' then | |
return '"' | |
elseif in_attribute and x == "'" then | |
return ''' | |
else | |
return x | |
end | |
end) | |
end | |
-- Helper function to convert an attributes table into | |
-- a string that can be put into HTML tags. | |
local function attributes(attr) | |
local attr_table = {} | |
for x,y in pairs(attr) do | |
if y and y ~= "" then | |
table.insert(attr_table, ' ' .. x .. '="' .. escape(y,true) .. '"') | |
end | |
end | |
return table.concat(attr_table) | |
end | |
-- Blocksep is used to separate block elements. | |
function Blocksep() | |
return "\n" | |
end | |
-- This function is called once for the whole document. Parameters: | |
-- body is a string, metadata is a table, variables is a table. | |
-- This gives you a fragment. You could use the metadata table to | |
-- fill variables in a custom lua template. Or, pass `--template=...` | |
-- to pandoc, and pandoc will do the template processing as usual. | |
function Doc(body, metadata, variables) | |
return '<pandoc>' .. body .. '</pandoc>' | |
end | |
-- The functions that follow render corresponding pandoc elements. | |
-- s is always a string, attr is always a table of attributes, and | |
-- items is always an array of strings (the items in a list). | |
-- Comments indicate the types of other variables. | |
function Str(s) | |
return '<str>' .. escape(s) .. '</str>' | |
end | |
function Space() | |
return '<space/>' | |
end | |
function SoftBreak() | |
return "<softbreak/>" | |
end | |
function LineBreak() | |
return "<linebreak/>" | |
end | |
function Emph(s) | |
return "<emph>" .. s .. "</emph>" | |
end | |
function Strong(s) | |
return "<strong>" .. s .. "</strong>" | |
end | |
function Subscript(s) | |
return "<subscript>" .. s .. "</subscript>" | |
end | |
function Superscript(s) | |
return "<superscript>" .. s .. "</superscript>" | |
end | |
function SmallCaps(s) | |
return '<smallcaps>' .. s .. '</smallcaps>' | |
end | |
function Strikeout(s) | |
return '<strikeout>' .. s .. '</strikeout>' | |
end | |
local link_template = '<link href="%s" title="%s" %s>%s</link>' | |
function Link(s, tgt, tit, attr) | |
return link_template:format( | |
escape(tgt, true), | |
escape(tit,true), | |
attributes(attr), | |
s | |
) | |
end | |
local image_template = '<image src="%s" title="%s" %s>%s</image>' | |
function Image(s, src, tit, attr) | |
return image_template:format( | |
escape(src, true), | |
escape(tit,true), | |
attributes(attr), | |
s | |
) | |
end | |
function Code(s, attr) | |
return "<code" .. attributes(attr) .. ">" .. escape(s) .. "</code>" | |
end | |
function InlineMath(s) | |
return '<math type="inline">'.. s .. '</math>' | |
end | |
function DisplayMath(s) | |
return '<math type="display">'.. s .. '</math>' | |
end | |
function SingleQuoted(s) | |
return '<quoted type="single">'.. s .. '</quoted>' | |
end | |
function DoubleQuoted(s) | |
return '<quoted type="double">'.. s .. '</quoted>' | |
end | |
function Note(s) | |
return '<note>' .. s .. '</note>' | |
end | |
function Span(s, attr) | |
return "<span" .. attributes(attr) .. ">" .. s .. "</span>" | |
end | |
function RawInline(format, str) | |
return ('<raw-inline format="%s">%s</raw-inline'):format(format, str) | |
end | |
function Cite(s, cs) | |
error 'Cite has not been implemented yet' | |
end | |
function Plain(s) | |
return '<plain>' .. s .. '</plain>' | |
end | |
function Para(s) | |
return "<para>" .. s .. "</para>" | |
end | |
-- lev is an integer, the header level. | |
function Header(lev, s, attr) | |
return ('<header level="%d" %s>%s</header>'):format(lev, attributes(attr), s) | |
end | |
function BlockQuote(s) | |
return "<blockquote>" .. s .. "</blockquote>" | |
end | |
function HorizontalRule() | |
return "<horizontal-rule/>" | |
end | |
function LineBlock(ls) | |
error 'LineBlock has not been implemented yet' | |
end | |
function CodeBlock(s, attr) | |
return ('<code-block %s>%s</code-block>'):format(attributes(attr), s) | |
end | |
function BulletList(items) | |
return '<bullet-list>\n' .. | |
table.concat( | |
List.map(items, function (item) return '<item>' .. item .. '</item>' end) | |
) .. | |
'</bullet-list>\n' | |
end | |
function OrderedList(items) | |
return '<ordered-list>\n' .. | |
table.concat( | |
List.map(items, function (item) return '<item>' .. item .. '</item>' end) | |
) .. | |
'</ordered-list>\n' | |
end | |
function DefinitionList(items) | |
error 'DefinitionList has not been implemented yet' | |
end | |
function CaptionedImage(src, tit, caption, attr) | |
return Para(Image(src, tit, caption, attr)) | |
end | |
-- Caption is a string, aligns is an array of strings, | |
-- widths is an array of floats, headers is an array of | |
-- strings, rows is an array of arrays of strings. | |
function Table(caption, aligns, widths, headers, rows) | |
error 'Table has not been implemented yet' | |
end | |
function RawBlock(format, str) | |
return ('<raw-block format="%s">%s</raw-block>'):format(format, str) | |
end | |
function Div(s, attr) | |
return "<div" .. attributes(attr) .. ">" .. s .. "</div>" | |
end | |
-- The following code will produce runtime warnings when you haven't defined | |
-- all of the functions you need for the custom writer, so it's useful | |
-- to include when you're working on a writer. | |
local meta = {} | |
meta.__index = | |
function(_, key) | |
io.stderr:write(string.format("WARNING: Undefined function '%s'\n",key)) | |
return function() return "" end | |
end | |
setmetatable(_G, meta) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment