1
+ -- Confluence Storage Format for Pandoc
2
+ -- https://confluence.atlassian.com/doc/confluence-storage-format-790796544.html
3
+ -- https://pandoc.org/MANUAL.html#custom-readers-and-writers
4
+
5
+ local stringify = (require " pandoc.utils" ).stringify
6
+ local confluence = require (' overrides' )
7
+
8
+ -- From https://stackoverflow.com/questions/9168058/how-to-dump-a-table-to-console
9
+ function dumpObject (o )
10
+ if type (o ) == ' table' then
11
+ local s = ' { '
12
+ for k ,v in pairs (o ) do
13
+ if type (k ) ~= ' number' then k = ' "' .. k .. ' "' end
14
+ s = s .. ' [' .. k .. ' ] = ' .. dumpObject (v ) .. ' ,'
15
+ end
16
+ return s .. ' } '
17
+ else
18
+ return tostring (o )
19
+ end
20
+ end
21
+
22
+
23
+ function dump (object , label )
24
+ print (label or ' ' .. ' : ' , dumpObject (object ))
25
+ end
26
+
27
+ -- The global variable PANDOC_DOCUMENT contains the full AST of
28
+ -- the document which is going to be written. It can be used to
29
+ -- configure the writer.
30
+ local meta = PANDOC_DOCUMENT .meta
31
+
32
+ -- Choose the image format based on the value of the
33
+ -- `image_format` meta value.
34
+ local image_format = meta .image_format
35
+ and stringify (meta .image_format )
36
+ or " png"
37
+ local image_mime_type = ({
38
+ jpeg = " image/jpeg" ,
39
+ jpg = " image/jpeg" ,
40
+ gif = " image/gif" ,
41
+ png = " image/png" ,
42
+ svg = " image/svg+xml" ,
43
+ })[image_format ]
44
+ or error (" unsupported image format `" .. image_format .. " `" )
45
+
46
+ -- Character escaping
47
+ local escape = confluence .escape
48
+
49
+ -- Helper function to convert an attributes table into
50
+ -- a string that can be put into HTML tags.
51
+ local function attributes (attr )
52
+ local attr_table = {}
53
+ for x ,y in pairs (attr ) do
54
+ if y and y ~= " " then
55
+ table.insert (attr_table , ' ' .. x .. ' ="' .. escape (y ,true ) .. ' "' )
56
+ end
57
+ end
58
+ return table.concat (attr_table )
59
+ end
60
+
61
+ -- Table to store footnotes, so they can be included at the end.
62
+ local notes = {}
63
+
64
+ -- Blocksep is used to separate block elements.
65
+ function Blocksep ()
66
+ return " \n\n "
67
+ end
68
+
69
+ -- This function is called once for the whole document. Parameters:
70
+ -- body is a string, metadata is a table, variables is a table.
71
+ -- This gives you a fragment. You could use the metadata table to
72
+ -- fill variables in a custom lua template. Or, pass `--template=...`
73
+ -- to pandoc, and pandoc will do the template processing as usual.
74
+ function Doc (body , metadata , variables )
75
+ local buffer = {}
76
+ local function add (s )
77
+ table.insert (buffer , s )
78
+ end
79
+ add (body )
80
+ if # notes > 0 then
81
+ add (' <ol class="footnotes">' )
82
+ for _ ,note in pairs (notes ) do
83
+ add (note )
84
+ end
85
+ add (' </ol>' )
86
+ end
87
+ return table.concat (buffer ,' \n ' ) .. ' \n '
88
+ end
89
+
90
+ -- The functions that follow render corresponding pandoc elements.
91
+ -- s is always a string, attr is always a table of attributes, and
92
+ -- items is always an array of strings (the items in a list).
93
+ -- Comments indicate the types of other variables.
94
+
95
+ function Str (s )
96
+ return escape (s )
97
+ end
98
+
99
+ function Space ()
100
+ return " "
101
+ end
102
+
103
+ function SoftBreak ()
104
+ return " \n "
105
+ end
106
+
107
+ function LineBreak ()
108
+ return " <br/>"
109
+ end
110
+
111
+ function Emph (s )
112
+ return " <em>" .. s .. " </em>"
113
+ end
114
+
115
+ function Strong (s )
116
+ return " <strong>" .. s .. " </strong>"
117
+ end
118
+
119
+ function Subscript (s )
120
+ return " <sub>" .. s .. " </sub>"
121
+ end
122
+
123
+ function Superscript (s )
124
+ return " <sup>" .. s .. " </sup>"
125
+ end
126
+
127
+ function SmallCaps (s )
128
+ return ' <span style="font-variant: small-caps;">' .. s .. ' </span>'
129
+ end
130
+
131
+ function Strikeout (s )
132
+ return ' <del>' .. s .. ' </del>'
133
+ end
134
+
135
+ function Link (s , tgt , tit , attr )
136
+ return confluence .LinkConfluence (s , tgt , tit , attr )
137
+ end
138
+
139
+ function Image (s , src , tit , attr )
140
+ return confluence .CaptionedImageConfluence (src , tit , ' ' , attr )
141
+ end
142
+
143
+ function Code (s , attr )
144
+ return " <code" .. attributes (attr ) .. " >" .. escape (s ) .. " </code>"
145
+ end
146
+
147
+ function InlineMath (s )
148
+ return " \\ (" .. escape (s ) .. " \\ )"
149
+ end
150
+
151
+ function DisplayMath (s )
152
+ return " \\ [" .. escape (s ) .. " \\ ]"
153
+ end
154
+
155
+ function SingleQuoted (s )
156
+ return " ‘" .. s .. " ’"
157
+ end
158
+
159
+ function DoubleQuoted (s )
160
+ return " “" .. s .. " ”"
161
+ end
162
+
163
+ function Note (s )
164
+ local num = # notes + 1
165
+ -- insert the back reference right before the final closing tag.
166
+ s = string.gsub (s ,
167
+ ' (.*)</' , ' %1 <a href="#fnref' .. num .. ' ">↩</a></' )
168
+ -- add a list item with the note to the note table.
169
+ table.insert (notes , ' <li id="fn' .. num .. ' ">' .. s .. ' </li>' )
170
+ -- return the footnote reference, linked to the note.
171
+ return ' <a id="fnref' .. num .. ' " href="#fn' .. num ..
172
+ ' "><sup>' .. num .. ' </sup></a>'
173
+ end
174
+
175
+ function Span (s , attr )
176
+ return " <span" .. attributes (attr ) .. " >" .. s .. " </span>"
177
+ end
178
+
179
+ function RawInline (format , str )
180
+ if format == " html" then
181
+ return str
182
+ else
183
+ return ' '
184
+ end
185
+ end
186
+
187
+ function Cite (s , cs )
188
+ local ids = {}
189
+ for _ ,cit in ipairs (cs ) do
190
+ table.insert (ids , cit .citationId )
191
+ end
192
+ return " <span class=\" cite\" data-citation-ids=\" " .. table.concat (ids , " ," ) ..
193
+ " \" >" .. s .. " </span>"
194
+ end
195
+
196
+ function Plain (s )
197
+ return s
198
+ end
199
+
200
+ function Para (s )
201
+ return " <p>" .. s .. " </p>"
202
+ end
203
+
204
+ -- lev is an integer, the header level.
205
+ function Header (lev , s , attr )
206
+ return " <h" .. lev .. attributes (attr ) .. " >" .. s .. " </h" .. lev .. " >"
207
+ end
208
+
209
+ function BlockQuote (s )
210
+ return confluence .BlockQuoteConfluence (s )
211
+ end
212
+
213
+ function HorizontalRule ()
214
+ return " <hr/>"
215
+ end
216
+
217
+ function LineBlock (ls )
218
+ return ' <div style="white-space: pre-line;">' .. table.concat (ls , ' \n ' ) ..
219
+ ' </div>'
220
+ end
221
+
222
+ function CodeBlock (s , attr )
223
+ return confluence .CodeBlockConfluence (s , attr )
224
+ end
225
+
226
+ function BulletList (items )
227
+ local buffer = {}
228
+ for _ , item in pairs (items ) do
229
+ table.insert (buffer , " <li>" .. item .. " </li>" )
230
+ end
231
+ return " <ul>\n " .. table.concat (buffer , " \n " ) .. " \n </ul>"
232
+ end
233
+
234
+ function OrderedList (items )
235
+ local buffer = {}
236
+ for _ , item in pairs (items ) do
237
+ table.insert (buffer , " <li>" .. item .. " </li>" )
238
+ end
239
+ return " <ol>\n " .. table.concat (buffer , " \n " ) .. " \n </ol>"
240
+ end
241
+
242
+ function DefinitionList (items )
243
+ local buffer = {}
244
+ for _ ,item in pairs (items ) do
245
+ local k , v = next (item )
246
+ table.insert (buffer , " <dt>" .. k .. " </dt>\n <dd>" ..
247
+ table.concat (v , " </dd>\n <dd>" ) .. " </dd>" )
248
+ end
249
+ return " <dl>\n " .. table.concat (buffer , " \n " ) .. " \n </dl>"
250
+ end
251
+
252
+ function CaptionedImage (src , tit , caption , attr )
253
+ return confluence .CaptionedImageConfluence (src , tit , caption , attr )
254
+ end
255
+
256
+ -- Caption is a string, aligns is an array of strings,
257
+ -- widths is an array of floats, headers is an array of
258
+ -- strings, rows is an array of arrays of strings.
259
+ function Table (caption , aligns , widths , headers , rows )
260
+ return TableConfluence (caption , aligns , widths , headers , rows )
261
+ end
262
+
263
+ function RawBlock (format , str )
264
+ if format == " html" then
265
+ return str
266
+ else
267
+ return ' '
268
+ end
269
+ end
270
+
271
+ function Div (s , attr )
272
+ return " <div" .. attributes (attr ) .. " >\n " .. s .. " </div>"
273
+ end
274
+
275
+ -- The following code will produce runtime warnings when you haven't defined
276
+ -- all of the functions you need for the custom writer, so it's useful
277
+ -- to include when you're working on a writer.
278
+ local meta = {}
279
+ meta .__index =
280
+ function (_ , key )
281
+ io.stderr :write (string.format (" WARNING: Undefined function '%s'\n " ,key ))
282
+ return function () return " " end
283
+ end
284
+ setmetatable (_G , meta )
0 commit comments