about summary refs log tree commit diff stats
path: root/lua
diff options
context:
space:
mode:
authorCase Duckworth2015-03-06 22:08:20 -0700
committerCase Duckworth2015-03-06 22:08:20 -0700
commite01ed83975933e4c8eafcda7950db98342ddfd63 (patch)
tree0739c8cea3fb07b5ee48870ed096b093e33e8c3b /lua
parentChange compile.sh to also compile RIVER files (diff)
downloadautocento-e01ed83975933e4c8eafcda7950db98342ddfd63.tar.gz
autocento-e01ed83975933e4c8eafcda7950db98342ddfd63.zip
Switch to compile.lua for reasons
Diffstat (limited to 'lua')
-rw-r--r--lua/allwords.lua17
-rw-r--r--lua/jttm.lua193
-rw-r--r--lua/river.lua226
-rw-r--r--lua/sample.lua324
-rw-r--r--lua/test.lua304
5 files changed, 1064 insertions, 0 deletions
diff --git a/lua/allwords.lua b/lua/allwords.lua new file mode 100644 index 0000000..b87f08a --- /dev/null +++ b/lua/allwords.lua
@@ -0,0 +1,17 @@
1function allwords ()
2 local line = io.read()
3 local pos = 1
4 return function ()
5 while line do
6 local s, e = string.find(line, "%w+", pos)
7 if s then
8 pos = e + 1
9 return string.sub(line, s, e)
10 else
11 line = io.read()
12 pos = 1
13 end
14 end
15 return nil
16 end
17end
diff --git a/lua/jttm.lua b/lua/jttm.lua new file mode 100644 index 0000000..2ba101a --- /dev/null +++ b/lua/jttm.lua
@@ -0,0 +1,193 @@
1-- Pandoc "Just the text, Ma'am"
2-- (JTTM): a custom writer that
3-- strips everything except for
4-- the TEXT from a pandoc source
5-- vim: fdm=marker
6-- invoke with: pandoc -t jttm/jttm.lua
7
8-- Table to store footnotes so they are at the END of the document
9local notes = {}
10
11-- This function is called once for the whole document. Parameters:
12-- body is a string, metadata is a table, variables is a table.
13-- One could use some kind of templating
14-- system here; this just gives you a simple standalone HTML file.
15function Doc(body, metadata, variables)
16 local buffer = {}
17 local function add(s)
18 table.insert(buffer, s)
19 end
20 if metadata['title'] and metadata['title'] ~= "" then
21 add(string.upper(metadata['title']))
22 end
23 if metadata['subtitle'] and metadata['subtitle'] ~= "" then
24 add(": " .. metadata['subtitle'])
25 end
26 add("\n")
27 -- TODO: epigraph.content, epigraph.attrib, dedication, other metadata?
28 add(body)
29 -- TODO: add notes at the end.
30 return table.concat(buffer, '\n')
31end
32
33-- TODOs {{{
34function align(align)
35 -- TODO: is this necessary?
36end
37
38function Note(s)
39 -- TODO
40end
41
42-- convert Tables to csv? or tab-separated?
43function Table(caption, aligns, widths, headers, rows)
44 local buffer = {}
45 local function add(s)
46 table.insert(buffer, s)
47 end
48 add("\n\n")
49 if caption ~= "" then
50 add("[" .. caption .. "]")
51 end
52 -- TODO: finish
53end
54
55-- }}}
56-- Remove all formatting {{{
57function Blocksep()
58 return "\n\n"
59end
60function Emph(s)
61 return s
62end
63
64function Strong(s)
65 return s
66end
67
68function Subscript(s)
69 return s
70end
71
72function Superscript(s)
73 return s
74end
75
76function SmallCaps(s)
77 return s
78end
79
80function Strikeout(s)
81 return s
82end
83
84function Code(s, attr)
85 return s
86end
87
88function CodeBlock(s, attr)
89 return s
90end
91
92function InlineMath(s)
93 return s
94end
95
96function DisplayMath(s)
97 return s
98end
99
100function Span(s, attr)
101 return s
102end
103
104function Cite(s)
105 return s
106end
107
108function Plain(s)
109 return s
110end
111
112-- Links only include the link text
113function Link(s, src, tit)
114 return s
115end
116
117-- Images have nothing to give us
118-- (but add a space just in case)
119function Image(s, src, tit)
120 return " "
121end
122
123function Str(s)
124 return s
125end
126
127function Div(s, attr)
128 return s
129end
130
131function Space(s)
132 return " "
133end
134
135function LineBreak()
136 return "\n"
137end
138
139function Para(s)
140 -- add paragraphing
141 return s .. "\n\n"
142end
143-- }}}
144-- Leave just a little formatting {{{
145function Header(lev, s, attr)
146 if lev == 1 then
147 return "\n\n " .. string.upper(s) .. "\n\n"
148 elseif lev == 2 then
149 return "\n " .. string.upper(s) .. "\n"
150 else
151 return s
152 end
153end
154
155function Blockquote(s)
156 return "\n\n" .. string.gsub(s, "*\n", " %0")
157end
158
159function HorizontalRule(s)
160 return "\n\n\n"
161end
162
163function BulletList(items)
164 local buffer = {}
165 for _, item in pairs(items) do
166 table.insert(buffer, "- " .. item .. "\n")
167 end
168 return "\n\n" .. table.concat(buffer, "\n") .. "\n\n"
169end
170
171function DefinitionList(items)
172 local buffer = {}
173 for _, item in pairs(items) do
174 for k, v in pairs(item) do
175 table.insert(buffer, "\n" .. k .. ":\n " ..
176 table.concat(v, "\n "))
177 end
178 end
179 return "\n\n" .. table.concat(buffer, "\n") .. "\n\n"
180end
181-- }}}
182
183-- The following code will produce runtime warnings when you haven't defined
184-- all of the functions you need for the custom writer, so it's useful
185-- to include when you're working on a writer.
186local meta = {}
187meta.__index =
188 function(_, key)
189 io.stderr:write(string.format("WARNING: Undefined function '%s'\n",key))
190 return function() return "" end
191 end
192setmetatable(_G, meta)
193
diff --git a/lua/river.lua b/lua/river.lua new file mode 100644 index 0000000..d060ba9 --- /dev/null +++ b/lua/river.lua
@@ -0,0 +1,226 @@
1-- Pandoc River writer
2-- it takes out all formatting, leaving only a river of text
3-- running down the page: one word per line
4-- vim: fdm=marker
5-- invoke with: pandoc -t river.lua
6
7local function flow(s)
8 return s:gsub("%s+", "\n")
9end
10
11local function nude(s)
12 -- Expand contractions
13 s = s:gsub("'%a+%s", function (x)
14 if x == "'ll" then
15 return " will "
16 elseif x == "'ve" then
17 return " have "
18 elseif x == "'re" then
19 return " are "
20 else
21 return x
22 end
23 end)
24 -- Get rid of quotes around words
25 s = s:gsub('"', ' ')
26 s = s:gsub("%s+'", ' ')
27 s = s:gsub("'%s+", ' ')
28 -- Remove HTML entities
29 s = s:gsub('&.-;', ' ')
30 s = s:gsub('%b<>', ' ')
31 -- Remove end-of-line backslashes
32 s = s:gsub('%s+\\$', ' ')
33 -- Remove dashes (not hyphens)
34 s = s:gsub('%-%-+', ' ')
35 s = s:gsub('%-%s', ' ')
36 -- Remove general punctuation
37 s = s:gsub('[%.!%?:;,%[%]%(%)<>]', ' ')
38 -- Remove extra spaces
39 s = s:gsub('%s+', ' ')
40 return s:lower()
41end
42
43-- This function is called once for the whole document. Parameters:
44-- body is a string, metadata is a table, variables is a table.
45-- One could use some kind of templating
46-- system here; this just gives you a simple standalone HTML file.
47function Doc(body, metadata, variables)
48 local buffer = ""
49 local function add(s)
50 buffer = buffer .. nude(s) .. "\n"
51 end
52 if metadata['title'] then
53 add(metadata['title'])
54 end
55 if metadata['subtitle'] then
56 add(metadata['subtitle'])
57 end
58 -- TODO: epigraph.content, epigraph.attrib, dedication, other metadata?
59 add(body)
60 return flow(buffer)
61end
62
63-- Remove all formatting {{{
64function Note(s)
65 return nude(s)
66end
67
68function Blocksep()
69 return "\n"
70end
71function Emph(s)
72 return nude(s)
73end
74
75function Strong(s)
76 return nude(s)
77end
78
79function Subscript(s)
80 return nude(s)
81end
82
83function Superscript(s)
84 return nude(s)
85end
86
87function SmallCaps(s)
88 return nude(s)
89end
90
91function Strikeout(s)
92 return nude(s)
93end
94
95function Code(s, attr)
96 return nude(s)
97end
98
99function CodeBlock(s, attr)
100 return nude(s)
101end
102
103function InlineMath(s)
104 return nude(s)
105end
106
107function DisplayMath(s)
108 return nude(s)
109end
110
111function Span(s, attr)
112 return nude(s)
113end
114
115function Cite(s)
116 return nude(s)
117end
118
119function Plain(s)
120 return nude(s)
121end
122
123-- Links only include the link text
124function Link(s, src, tit)
125 return nude(s)
126end
127
128-- Images have nothing to give us
129-- (but add a space just in case)
130function Image(s, src, tit)
131 return "\n"
132end
133
134function CaptionedImage(s, src, tit)
135 return "\n"
136end
137
138function Str(s)
139 return nude(s)
140end
141
142function Div(s, attr)
143 return nude(s)
144end
145
146function Space(s)
147 return "\n"
148end
149
150function LineBreak()
151 return "\n"
152end
153
154function Para(s)
155 return nude(s)
156end
157
158function Header(lev, s, attr)
159 return nude(s)
160end
161
162function BlockQuote(s)
163 return nude(s)
164end
165
166function HorizontalRule()
167 return "\n"
168end
169
170function BulletList(items)
171 local buffer = ""
172 for _, item in pairs(items) do
173 buffer = buffer .. nude(item) .. "\n"
174 end
175 return buffer .. "\n"
176end
177
178function OrderedList(items)
179 local buffer = ""
180 for _, item in pairs(items) do
181 buffer = buffer .. nude(item) .. "\n"
182 end
183 return buffer .. "\n"
184end
185
186function DefinitionList(items)
187 local buffer = ""
188 for _, item in pairs(items) do
189 for k, v in pairs(item) do
190 buffer = buffer .. nude(k) .. "\n" .. nude(v) .. "\n"
191 end
192 end
193 return buffer .. "\n"
194end
195
196function Table(caption, aligns, widths, headers, rows)
197 local buffer = ""
198 local function add(s)
199 buffer = buffer .. nude(s) .. "\n"
200 end
201 if caption ~= "" then
202 add(caption)
203 end
204 for _,h in pairs(headers) do
205 add(h)
206 end
207 for _, row in pairs(rows) do
208 for _, cell in pairs(row) do
209 add(cell)
210 end
211 end
212 return buffer
213end
214-- }}}
215
216-- The following code will produce runtime warnings when you haven't defined
217-- all of the functions you need for the custom writer, so it's useful
218-- to include when you're working on a writer.
219local meta = {}
220meta.__index =
221 function(_, key)
222 io.stderr:write(string.format("WARNING: Undefined function '%s'\n",key))
223 return function() return "" end
224 end
225setmetatable(_G, meta)
226
diff --git a/lua/sample.lua b/lua/sample.lua new file mode 100644 index 0000000..a0c3c29 --- /dev/null +++ b/lua/sample.lua
@@ -0,0 +1,324 @@
1-- This is a sample custom writer for pandoc. It produces output
2-- that is very similar to that of pandoc's HTML writer.
3-- There is one new feature: code blocks marked with class 'dot'
4-- are piped through graphviz and images are included in the HTML
5-- output using 'data:' URLs.
6--
7-- Invoke with: pandoc -t sample.lua
8--
9-- Note: you need not have lua installed on your system to use this
10-- custom writer. However, if you do have lua installed, you can
11-- use it to test changes to the script. 'lua sample.lua' will
12-- produce informative error messages if your code contains
13-- syntax errors.
14
15-- Character escaping
16local function escape(s, in_attribute)
17 return s:gsub("[<>&\"']",
18 function(x)
19 if x == '<' then
20 return '&lt;'
21 elseif x == '>' then
22 return '&gt;'
23 elseif x == '&' then
24 return '&amp;'
25 elseif x == '"' then
26 return '&quot;'
27 elseif x == "'" then
28 return '&#39;'
29 else
30 return x
31 end
32 end)
33end
34
35-- Helper function to convert an attributes table into
36-- a string that can be put into HTML tags.
37local function attributes(attr)
38 local attr_table = {}
39 for x,y in pairs(attr) do
40 if y and y ~= "" then
41 table.insert(attr_table, ' ' .. x .. '="' .. escape(y,true) .. '"')
42 end
43 end
44 return table.concat(attr_table)
45end
46
47-- Run cmd on a temporary file containing inp and return result.
48local function pipe(cmd, inp)
49 local tmp = os.tmpname()
50 local tmph = io.open(tmp, "w")
51 tmph:write(inp)
52 tmph:close()
53 local outh = io.popen(cmd .. " " .. tmp,"r")
54 local result = outh:read("*all")
55 outh:close()
56 os.remove(tmp)
57 return result
58end
59
60-- Table to store footnotes, so they can be included at the end.
61local notes = {}
62
63-- Blocksep is used to separate block elements.
64function Blocksep()
65 return "\n\n"
66end
67
68-- This function is called once for the whole document. Parameters:
69-- body is a string, metadata is a table, variables is a table.
70-- One could use some kind of templating
71-- system here; this just gives you a simple standalone HTML file.
72function Doc(body, metadata, variables)
73 local buffer = {}
74 local function add(s)
75 table.insert(buffer, s)
76 end
77 add('<!DOCTYPE html>')
78 add('<html>')
79 add('<head>')
80 add('<title>' .. (metadata['title'] or '') .. '</title>')
81 add('</head>')
82 add('<body>')
83 if metadata['title'] and metadata['title'] ~= "" then
84 add('<h1 class="title">' .. metadata['title'] .. '</h1>')
85 end
86 for _, author in pairs(metadata['author'] or {}) do
87 add('<h2 class="author">' .. author .. '</h2>')
88 end
89 if metadata['date'] and metadata['date'] ~= "" then
90 add('<h3 class="date">' .. metadata.date .. '</h3>')
91 end
92 add(body)
93 if #notes > 0 then
94 add('<ol class="footnotes">')
95 for _,note in pairs(notes) do
96 add(note)
97 end
98 add('</ol>')
99 end
100 add('</body>')
101 add('</html>')
102 return table.concat(buffer,'\n')
103end
104
105-- The functions that follow render corresponding pandoc elements.
106-- s is always a string, attr is always a table of attributes, and
107-- items is always an array of strings (the items in a list).
108-- Comments indicate the types of other variables.
109
110function Str(s)
111 return escape(s)
112end
113
114function Space()
115 return " "
116end
117
118function LineBreak()
119 return "<br/>"
120end
121
122function Emph(s)
123 return "<em>" .. s .. "</em>"
124end
125
126function Strong(s)
127 return "<strong>" .. s .. "</strong>"
128end
129
130function Subscript(s)
131 return "<sub>" .. s .. "</sub>"
132end
133
134function Superscript(s)
135 return "<sup>" .. s .. "</sup>"
136end
137
138function SmallCaps(s)
139 return '<span style="font-variant: small-caps;">' .. s .. '</span>'
140end
141
142function Strikeout(s)
143 return '<del>' .. s .. '</del>'
144end
145
146function Link(s, src, tit)
147 return "<a href='" .. escape(src,true) .. "' title='" ..
148 escape(tit,true) .. "'>" .. s .. "</a>"
149end
150
151function Image(s, src, tit)
152 return "<img src='" .. escape(src,true) .. "' title='" ..
153 escape(tit,true) .. "'/>"
154end
155
156function Code(s, attr)
157 return "<code" .. attributes(attr) .. ">" .. escape(s) .. "</code>"
158end
159
160function InlineMath(s)
161 return "\\(" .. escape(s) .. "\\)"
162end
163
164function DisplayMath(s)
165 return "\\[" .. escape(s) .. "\\]"
166end
167
168function Note(s)
169 local num = #notes + 1
170 -- insert the back reference right before the final closing tag.
171 s = string.gsub(s,
172 '(.*)</', '%1 <a href="#fnref' .. num .. '">&#8617;</a></')
173 -- add a list item with the note to the note table.
174 table.insert(notes, '<li id="fn' .. num .. '">' .. s .. '</li>')
175 -- return the footnote reference, linked to the note.
176 return '<a id="fnref' .. num .. '" href="#fn' .. num ..
177 '"><sup>' .. num .. '</sup></a>'
178end
179
180function Span(s, attr)
181 return "<span" .. attributes(attr) .. ">" .. s .. "</span>"
182end
183
184function Cite(s)
185 return "<span class=\"cite\">" .. s .. "</span>"
186end
187
188function Plain(s)
189 return s
190end
191
192function Para(s)
193 return "<p>" .. s .. "</p>"
194end
195
196-- lev is an integer, the header level.
197function Header(lev, s, attr)
198 return "<h" .. lev .. attributes(attr) .. ">" .. s .. "</h" .. lev .. ">"
199end
200
201function BlockQuote(s)
202 return "<blockquote>\n" .. s .. "\n</blockquote>"
203end
204
205function HorizontalRule()
206 return "<hr/>"
207end
208
209function CodeBlock(s, attr)
210 -- If code block has class 'dot', pipe the contents through dot
211 -- and base64, and include the base64-encoded png as a data: URL.
212 if attr.class and string.match(' ' .. attr.class .. ' ',' dot ') then
213 local png = pipe("base64", pipe("dot -Tpng", s))
214 return '<img src="data:image/png;base64,' .. png .. '"/>'
215 -- otherwise treat as code (one could pipe through a highlighter)
216 else
217 return "<pre><code" .. attributes(attr) .. ">" .. escape(s) ..
218 "</code></pre>"
219 end
220end
221
222function BulletList(items)
223 local buffer = {}
224 for _, item in pairs(items) do
225 table.insert(buffer, "<li>" .. item .. "</li>")
226 end
227 return "<ul>\n" .. table.concat(buffer, "\n") .. "\n</ul>"
228end
229
230function OrderedList(items)
231 local buffer = {}
232 for _, item in pairs(items) do
233 table.insert(buffer, "<li>" .. item .. "</li>")
234 end
235 return "<ol>\n" .. table.concat(buffer, "\n") .. "\n</ol>"
236end
237
238-- Revisit association list STackValue instance.
239function DefinitionList(items)
240 local buffer = {}
241 for _,item in pairs(items) do
242 for k, v in pairs(item) do
243 table.insert(buffer,"<dt>" .. k .. "</dt>\n<dd>" ..
244 table.concat(v,"</dd>\n<dd>") .. "</dd>")
245 end
246 end
247 return "<dl>\n" .. table.concat(buffer, "\n") .. "\n</dl>"
248end
249
250-- Convert pandoc alignment to something HTML can use.
251-- align is AlignLeft, AlignRight, AlignCenter, or AlignDefault.
252function html_align(align)
253 if align == 'AlignLeft' then
254 return 'left'
255 elseif align == 'AlignRight' then
256 return 'right'
257 elseif align == 'AlignCenter' then
258 return 'center'
259 else
260 return 'left'
261 end
262end
263
264-- Caption is a string, aligns is an array of strings,
265-- widths is an array of floats, headers is an array of
266-- strings, rows is an array of arrays of strings.
267function Table(caption, aligns, widths, headers, rows)
268 local buffer = {}
269 local function add(s)
270 table.insert(buffer, s)
271 end
272 add("<table>")
273 if caption ~= "" then
274 add("<caption>" .. caption .. "</caption>")
275 end
276 if widths and widths[1] ~= 0 then
277 for _, w in pairs(widths) do
278 add('<col width="' .. string.format("%d%%", w * 100) .. '" />')
279 end
280 end
281 local header_row = {}
282 local empty_header = true
283 for i, h in pairs(headers) do
284 local align = html_align(aligns[i])
285 table.insert(header_row,'<th align="' .. align .. '">' .. h .. '</th>')
286 empty_header = empty_header and h == ""
287 end
288 if empty_header then
289 head = ""
290 else
291 add('<tr class="header">')
292 for _,h in pairs(header_row) do
293 add(h)
294 end
295 add('</tr>')
296 end
297 local class = "even"
298 for _, row in pairs(rows) do
299 class = (class == "even" and "odd") or "even"
300 add('<tr class="' .. class .. '">')
301 for i,c in pairs(row) do
302 add('<td align="' .. html_align(aligns[i]) .. '">' .. c .. '</td>')
303 end
304 add('</tr>')
305 end
306 add('</table')
307 return table.concat(buffer,'\n')
308end
309
310function Div(s, attr)
311 return "<div" .. attributes(attr) .. ">\n" .. s .. "</div>"
312end
313
314-- The following code will produce runtime warnings when you haven't defined
315-- all of the functions you need for the custom writer, so it's useful
316-- to include when you're working on a writer.
317local meta = {}
318meta.__index =
319 function(_, key)
320 io.stderr:write(string.format("WARNING: Undefined function '%s'\n",key))
321 return function() return "" end
322 end
323setmetatable(_G, meta)
324
diff --git a/lua/test.lua b/lua/test.lua new file mode 100644 index 0000000..bfbafc2 --- /dev/null +++ b/lua/test.lua
@@ -0,0 +1,304 @@
1-- This is a sample custom writer for pandoc. It produces output
2-- that is very similar to that of pandoc's HTML writer.
3-- There is one new feature: code blocks marked with class 'dot'
4-- are piped through graphviz and images are included in the HTML
5-- output using 'data:' URLs.
6--
7-- Invoke with: pandoc -t sample.lua
8--
9-- Note: you need not have lua installed on your system to use this
10-- custom writer. However, if you do have lua installed, you can
11-- use it to test changes to the script. 'lua sample.lua' will
12-- produce informative error messages if your code contains
13-- syntax errors.
14
15-- Character escaping
16local function escape(s, in_attribute)
17 return s:gsub("[<>&\"']",
18 function(x)
19 if x == '<' then
20 return '&lt;'
21 elseif x == '>' then
22 return '&gt;'
23 elseif x == '&' then
24 return '&amp;'
25 elseif x == '"' then
26 return '&quot;'
27 elseif x == "'" then
28 return '&#39;'
29 else
30 return x
31 end
32 end)
33end
34
35-- Helper function to convert an attributes table into
36-- a string that can be put into HTML tags.
37local function attributes(attr)
38 local attr_table = {}
39 for x,y in pairs(attr) do
40 if y and y ~= "" then
41 table.insert(attr_table, ' ' .. x .. '="' .. escape(y,true) .. '"')
42 end
43 end
44 return table.concat(attr_table)
45end
46
47-- Run cmd on a temporary file containing inp and return result.
48local function pipe(cmd, inp)
49 local tmp = os.tmpname()
50 local tmph = io.open(tmp, "w")
51 tmph:write(inp)
52 tmph:close()
53 local outh = io.popen(cmd .. " " .. tmp,"r")
54 local result = outh:read("*all")
55 outh:close()
56 os.remove(tmp)
57 return result
58end
59
60-- Table to store footnotes, so they can be included at the end.
61local notes = {}
62
63-- Blocksep is used to separate block elements.
64function Blocksep()
65 return "\n\n"
66end
67
68-- This function is called once for the whole document. Parameters:
69-- body is a string, metadata is a table, variables is a table.
70-- One could use some kind of templating
71-- system here; this just gives you a simple standalone HTML file.
72function Doc(body, metadata, variables)
73 local buffer = {}
74 for k, v in pairs(metadata) do
75 if type(v) == "string" then
76 table.insert(buffer, string.upper(k) .. ': ' .. v)
77 else
78 table.insert(buffer, string.upper(k) .. ': ' .. table.concat(v))
79 end
80 end
81 return table.concat(buffer, "\n")
82end
83
84-- The functions that follow render corresponding pandoc elements.
85-- s is always a string, attr is always a table of attributes, and
86-- items is always an array of strings (the items in a list).
87-- Comments indicate the types of other variables.
88
89function Str(s)
90 return escape(s)
91end
92
93function Space()
94 return " "
95end
96
97function LineBreak()
98 return "<br/>"
99end
100
101function Emph(s)
102 return "<em>" .. s .. "</em>"
103end
104
105function Strong(s)
106 return "<strong>" .. s .. "</strong>"
107end
108
109function Subscript(s)
110 return "<sub>" .. s .. "</sub>"
111end
112
113function Superscript(s)
114 return "<sup>" .. s .. "</sup>"
115end
116
117function SmallCaps(s)
118 return '<span style="font-variant: small-caps;">' .. s .. '</span>'
119end
120
121function Strikeout(s)
122 return '<del>' .. s .. '</del>'
123end
124
125function Link(s, src, tit)
126 return "<a href='" .. escape(src,true) .. "' title='" ..
127 escape(tit,true) .. "'>" .. s .. "</a>"
128end
129
130function Image(s, src, tit)
131 return "<img src='" .. escape(src,true) .. "' title='" ..
132 escape(tit,true) .. "'/>"
133end
134
135function Code(s, attr)
136 return "<code" .. attributes(attr) .. ">" .. escape(s) .. "</code>"
137end
138
139function InlineMath(s)
140 return "\\(" .. escape(s) .. "\\)"
141end
142
143function DisplayMath(s)
144 return "\\[" .. escape(s) .. "\\]"
145end
146
147function Note(s)
148 local num = #notes + 1
149 -- insert the back reference right before the final closing tag.
150 s = string.gsub(s,
151 '(.*)</', '%1 <a href="#fnref' .. num .. '">&#8617;</a></')
152 -- add a list item with the note to the note table.
153 table.insert(notes, '<li id="fn' .. num .. '">' .. s .. '</li>')
154 -- return the footnote reference, linked to the note.
155 return '<a id="fnref' .. num .. '" href="#fn' .. num ..
156 '"><sup>' .. num .. '</sup></a>'
157end
158
159function Span(s, attr)
160 return "<span" .. attributes(attr) .. ">" .. s .. "</span>"
161end
162
163function Cite(s)
164 return "<span class=\"cite\">" .. s .. "</span>"
165end
166
167function Plain(s)
168 return s
169end
170
171function Para(s)
172 return "<p>" .. s .. "</p>"
173end
174
175-- lev is an integer, the header level.
176function Header(lev, s, attr)
177 return "<h" .. lev .. attributes(attr) .. ">" .. s .. "</h" .. lev .. ">"
178end
179
180function BlockQuote(s)
181 return "<blockquote>\n" .. s .. "\n</blockquote>"
182end
183
184function HorizontalRule()
185 return "<hr/>"
186end
187
188function CodeBlock(s, attr)
189 -- If code block has class 'dot', pipe the contents through dot
190 -- and base64, and include the base64-encoded png as a data: URL.
191 if attr.class and string.match(' ' .. attr.class .. ' ',' dot ') then
192 local png = pipe("base64", pipe("dot -Tpng", s))
193 return '<img src="data:image/png;base64,' .. png .. '"/>'
194 -- otherwise treat as code (one could pipe through a highlighter)
195 else
196 return "<pre><code" .. attributes(attr) .. ">" .. escape(s) ..
197 "</code></pre>"
198 end
199end
200
201function BulletList(items)
202 local buffer = {}
203 for _, item in pairs(items) do
204 table.insert(buffer, "<li>" .. item .. "</li>")
205 end
206 return "<ul>\n" .. table.concat(buffer, "\n") .. "\n</ul>"
207end
208
209function OrderedList(items)
210 local buffer = {}
211 for _, item in pairs(items) do
212 table.insert(buffer, "<li>" .. item .. "</li>")
213 end
214 return "<ol>\n" .. table.concat(buffer, "\n") .. "\n</ol>"
215end
216
217-- Revisit association list STackValue instance.
218function DefinitionList(items)
219 local buffer = {}
220 for _,item in pairs(items) do
221 for k, v in pairs(item) do
222 table.insert(buffer,"<dt>" .. k .. "</dt>\n<dd>" ..
223 table.concat(v,"</dd>\n<dd>") .. "</dd>")
224 end
225 end
226 return "<dl>\n" .. table.concat(buffer, "\n") .. "\n</dl>"
227end
228
229-- Convert pandoc alignment to something HTML can use.
230-- align is AlignLeft, AlignRight, AlignCenter, or AlignDefault.
231function html_align(align)
232 if align == 'AlignLeft' then
233 return 'left'
234 elseif align == 'AlignRight' then
235 return 'right'
236 elseif align == 'AlignCenter' then
237 return 'center'
238 else
239 return 'left'
240 end
241end
242
243-- Caption is a string, aligns is an array of strings,
244-- widths is an array of floats, headers is an array of
245-- strings, rows is an array of arrays of strings.
246function Table(caption, aligns, widths, headers, rows)
247 local buffer = {}
248 local function add(s)
249 table.insert(buffer, s)
250 end
251 add("<table>")
252 if caption ~= "" then
253 add("<caption>" .. caption .. "</caption>")
254 end
255 if widths and widths[1] ~= 0 then
256 for _, w in pairs(widths) do
257 add('<col width="' .. string.format("%d%%", w * 100) .. '" />')
258 end
259 end
260 local header_row = {}
261 local empty_header = true
262 for i, h in pairs(headers) do
263 local align = html_align(aligns[i])
264 table.insert(header_row,'<th align="' .. align .. '">' .. h .. '</th>')
265 empty_header = empty_header and h == ""
266 end
267 if empty_header then
268 head = ""
269 else
270 add('<tr class="header">')
271 for _,h in pairs(header_row) do
272 add(h)
273 end
274 add('</tr>')
275 end
276 local class = "even"
277 for _, row in pairs(rows) do
278 class = (class == "even" and "odd") or "even"
279 add('<tr class="' .. class .. '">')
280 for i,c in pairs(row) do
281 add('<td align="' .. html_align(aligns[i]) .. '">' .. c .. '</td>')
282 end
283 add('</tr>')
284 end
285 add('</table')
286 return table.concat(buffer,'\n')
287end
288
289function Div(s, attr)
290 return "<div" .. attributes(attr) .. ">\n" .. s .. "</div>"
291end
292
293-- The following code will produce runtime warnings when you haven't defined
294-- all of the functions you need for the custom writer, so it's useful
295-- to include when you're working on a writer.
296local meta = {}
297meta.__index =
298 function(_, key)
299 io.stderr:write(string.format("WARNING: Undefined function '%s'\n",key))
300 return function() return "" end
301 end
302setmetatable(_G, meta)
303
304