diff options
| author | Melody Horn <melody@boringcactus.com> | 2020-10-26 23:22:29 -0600 | 
|---|---|---|
| committer | Melody Horn <melody@boringcactus.com> | 2020-10-26 23:22:29 -0600 | 
| commit | 5ada504d5667a6f17ee2631dd471b073b332dd33 (patch) | |
| tree | 130ed731247e5fe01ed2fae366e7bf08aef46b37 /etc | |
| parent | c7ce2058a94c7fbd22fc409738ad8d15af30b170 (diff) | |
| download | spec-5ada504d5667a6f17ee2631dd471b073b332dd33.tar.gz spec-5ada504d5667a6f17ee2631dd471b073b332dd33.zip  | |
build spec in gemtext too
Diffstat (limited to 'etc')
| -rw-r--r-- | etc/gemtext.lua | 297 | ||||
| -rw-r--r-- | etc/template.gmi | 1 | 
2 files changed, 298 insertions, 0 deletions
diff --git a/etc/gemtext.lua b/etc/gemtext.lua new file mode 100644 index 0000000..5fdff59 --- /dev/null +++ b/etc/gemtext.lua @@ -0,0 +1,297 @@ +-- Invoke with: pandoc -t gemtext.lua + +-- Tables to store links and footnotes, so they can be included correctly. +local links = {} +local notes = {} + +-- 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) +    local buffer = {} +    local function add(s) +        table.insert(buffer, s) +    end +    add(body) +    if #notes > 0 then +        add('') +        for _,note in pairs(notes) do +            add(note) +        end +    end +    return table.concat(buffer, '\n') +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 s +end + +function Space() +    return " " +end + +function SoftBreak() +    return " " +end + +function LineBreak() +    return "\n" +end + +function Emph(s) +    return "_" .. s .. "_" +end + +function Strong(s) +    return "**" .. s .. "**" +end + +function Subscript(s) +    return "_" .. s +end + +function Superscript(s) +    return "^" .. s +end + +function SmallCaps(s) +    return s +end + +function Strikeout(s) +    return '~~' .. s .. '~~' +end + +function Link(s, tgt, tit, attr) +    if tgt:match("%.html$") and not tgt:match("^https?://") then +        tgt = tgt:gsub("%.html$", ".gmi") +    end +    table.insert(links, "=> " .. tgt .. " " .. s) +    return s +end + +function Image(s, src, tit, attr) +    table.insert(links, "=> " .. src .. " [IMG] " .. s) +    return s +end + +function Code(s, attr) +    return "`" .. s .. "`" +end + +function InlineMath(s) +    return "\\(" .. s .. "\\)" +end + +function DisplayMath(s) +    return "\\[" .. s .. "\\]" +end + +function SingleQuoted(s) +    return "‘" .. s .. "’" +end + +function DoubleQuoted(s) +    return "“" .. s .. "”" +end + +function Note(s) +    local num = #notes + 1 +    local num_fn = string.gsub(num, '0', '⁰') +        :gsub('1', '¹') +        :gsub('2', '²') +        :gsub('3', '³') +        :gsub('4', '⁴') +        :gsub('5', '⁵') +        :gsub('6', '⁶') +        :gsub('7', '⁷') +        :gsub('8', '⁸') +        :gsub('9', '⁹') +    -- add a list item with the note to the note table. +    table.insert(notes, num_fn .. ' ' .. s) +    -- return the footnote reference, linked to the note. +    return num_fn +end + +function Span(s, attr) +    return s +end + +function RawInline(format, str) +    if format == "gemtext" then +        return str +    else +        return '' +    end +end + +function Cite(s, cs) +    local ids = {} +    for _,cit in ipairs(cs) do +        table.insert(ids, cit.citationId) +    end +    return s .. ids:concat(",") +end + +function Plain(s) +    return s +end + +function Para(s) +    local finished = s .. "\n" +    if #links > 0 then +        local link_text = links[1]:match('=> [^ ]+ (.+)') +        if link_text == s and #links == 1 then +            finished = links[1] .. "\n" +        else +            finished = finished .. table.concat(links, "\n") .. "\n" +        end +    end +    links = {} +    return finished +end + +-- lev is an integer, the header level. +function Header(lev, s, attr) +    return string.rep("#", lev) .. " " .. s .. "\n" +end + +function BlockQuote(s) +    return "> " .. s:gsub("\n", "\n> "):gsub("\n> $", "\n") +end + +function HorizontalRule() +    return "-----\n" +end + +function LineBlock(ls) +    return table.concat(ls, '\n') .. "\n" +end + +function CodeBlock(s, attr) +    return "```\n" .. s .. "\n```\n" +end + +function BulletList(items) +    local buffer = {} +    for _, item in pairs(items) do +        local finished = false +        if #links > 0 then +            local link_text = links[1]:match('=> [^ ]+ (.+)') +            if link_text == item then +                table.insert(buffer, links[1]) +                table.remove(links, 1) +                finished = true +            end +        end +        if not finished then +            table.insert(buffer, "* " .. item) +            for _,link in pairs(links) do +                table.insert(buffer, link) +            end +            links = {} +        end +    end +    return table.concat(buffer, "\n") .. "\n" +end + +function OrderedList(items) +  local buffer = {} +  for i, item in pairs(items) do +    table.insert(buffer, i .. ". " .. item) +  end +  return table.concat(buffer, "\n") .. "\n" +end + +function DefinitionList(items) +  local buffer = {} +  for _,item in pairs(items) do +    local k, v = next(item) +    table.insert(buffer, k .. ":\n" .. table.concat(v, "\n")) +  end +  return table.concat(buffer, "\n") .. "\n" +end + +function CaptionedImage(src, tit, caption, attr) +   return '=> ' .. src .. ' [IMG] ' .. caption .. '\n' +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) +    local buffer = {} +    local function add(s) +        table.insert(buffer, s) +    end +    add("<table>") +    if caption ~= "" then +        add("<caption>" .. caption .. "</caption>") +    end +    if widths and widths[1] ~= 0 then +        for _, w in pairs(widths) do +            add('<col width="' .. string.format("%.0f%%", w * 100) .. '" />') +        end +    end +    local header_row = {} +    local empty_header = true +    for i, h in pairs(headers) do +        table.insert(header_row,'<th>' .. h .. '</th>') +        empty_header = empty_header and h == "" +    end +    if empty_header then +        head = "" +    else +        add('<tr class="header">') +        for _,h in pairs(header_row) do +            add(h) +        end +        add('</tr>') +    end +    local class = "even" +    for _, row in pairs(rows) do +        class = (class == "even" and "odd") or "even" +        add('<tr class="' .. class .. '">') +        for i,c in pairs(row) do +            add('<td>' .. c .. '</td>') +        end +        add('</tr>') +    end +    add('</table>') +    return table.concat(buffer,'\n') .. "\n" +end + +function RawBlock(format, str) +    if format == "gemtext" then +        return str +    else +        return '' +    end +end + +function Div(s, attr) +    return s +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) diff --git a/etc/template.gmi b/etc/template.gmi new file mode 100644 index 0000000..36d66c2 --- /dev/null +++ b/etc/template.gmi @@ -0,0 +1 @@ +$body$  |