@@ -1,7 +1,7 @@
4−Copyright (c) 2017 Albert Krewinkel
4+Copyright © 2017 Albert Krewinkel
6Permission to use, copy, modify, and/or distribute this software for any purpose
6Permission to use, copy, modify, and/or distribute this software for any purpose
7with or without fee is hereby granted, provided that the above copyright notice
7with or without fee is hereby granted, provided that the above copyright notice
@@ -16,21 +16,78 @@ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
16THIS SOFTWARE.
16THIS SOFTWARE.
20+-- Lua functions for pandoc scripts.
22+-- @author Albert Krewinkel
23+-- @copyright © 2017 Albert Krewinkel
20local M = {
25local M = {
21− _version = "0.1.0"
26+ _VERSION = "0.2.0"
32+setmetatable(M.Attributes, M.Attributes)
34+M.Attributes.__index = function(t, k)
37+ elseif k == "class" then
38+ return table.concat(t[2], ' ')
24--- Create a new set of attributes (Attr).
44--- Create a new set of attributes (Attr).
45+-- @function Attributes
25−function M.Attributes(id, classes, key_values)
46+M.Attributes.__call = function(t, key_values, id, classes)
48+ for i = 1, #key_values do
49+ kv[key_values[i][1]] = key_values[i][2]
52+ classes = classes or {}
26− return {id, classes, key_values}
53+ local attr = {id, classes, key_values, kv = kv}
54+ setmetatable(attr, t)
57+M.Attributes.empty = M.Attributes('', {}, {})
60+--- Creates a single citation.
62+-- @tparam string id citation identifier (like a bibtex key)
63+-- @tparam AuthorInText|SuppressAuthor|NormalCitation mode citation mode
64+-- @tparam[opt] {Inline,...} prefix citation prefix
65+-- @tparam[opt] {Inline,...} suffix citation suffix
66+-- @tparam[opt] int note_num note number
67+-- @tparam[opt] int note_num hash number
68+M.Citation = function(id, mode, prefix, suffix, note_num, hash)
69+ prefix = prefix or {}
70+ suffix = suffix or {}
71+ note_num = note_num or 0
75+ citationPrefix = prefix,
76+ citationSuffix = suffix,
78+ citationNoteNum = note_num,
29------------------------------------------------------------------------
83------------------------------------------------------------------------
30−--- Document AST elements
84+-- The base class for pandoc's AST elements.
31local Element = {}
87local Element = {}
33--- Create a new element subtype
89--- Create a new element subtype
34function Element:make_subtype(o)
91function Element:make_subtype(o)
35 o = o or {}
92 o = o or {}
36 setmetatable(o, self)
93 setmetatable(o, self)
@@ -39,6 +96,7 @@ function Element:make_subtype(o)
41--- Create a new element given its tag and arguments
98--- Create a new element given its tag and arguments
42function Element:new(tag, ...)
100function Element:new(tag, ...)
43 local element = { t = tag }
101 local element = { t = tag }
44 local content = {...}
102 local content = {...}
@@ -56,6 +114,7 @@ function Element:new(tag, ...)
58--- Create a new constructor
116--- Create a new constructor
59-- @param tag Tag used to identify the constructor
118-- @param tag Tag used to identify the constructor
60-- @param fn Function to be called when constructing a new element
119-- @param fn Function to be called when constructing a new element
61-- @return function that constructs a new element
120-- @return function that constructs a new element
@@ -75,222 +134,338 @@ function Element:create_constructor(tag, fn)
76 return obj
135 return obj
137+ self.constructor = self.constructor or {}
138+ self.constructor[tag] = constr
78 return constr
139 return constr
142+--- Calls the constructor, creating a new element.
81function Element.__call(t, ...)
144function Element.__call(t, ...)
82 return t:new(...)
145 return t:new(...)
85------------------------------------------------------------------------
148------------------------------------------------------------------------
86−-- Document
149+--- Pandoc Document
152+--- A complete pandoc document
154+-- @tparam {Block,...} blocks document content
155+-- @tparam[opt] Meta meta document meta data
87−local function Doc(blocks, meta)
156+function M.Doc(blocks, meta)
89 ["blocks"] = blocks,
159 ["blocks"] = blocks,
90 ["meta"] = meta,
160 ["meta"] = meta,
91 ["pandoc-api-version"] = {1,17,0,5},
161 ["pandoc-api-version"] = {1,17,0,5},
166+--- Inline element class
94−local Inline = Element:make_subtype{}
168+M.Inline = Element:make_subtype{}
95−function Inline.__call(t, ...)
169+M.Inline.__call = function (t, ...)
96 return t:new(...)
170 return t:new(...)
99−local Block = Element:make_subtype{}
101------------------------------------------------------------------------
173------------------------------------------------------------------------
102−-- Inline element constructors
174+-- Inline
103−-- @section
175+-- @section Inline
105−--- Create a Cite inline element
177+--- Creates a Cite inline element
106−-- @function Inline.Cite
178+-- @function Cite
179+-- @tparam {Inline,...} content List of inlines
180+-- @tparam {Citation,...} citations List of citations
181+-- @treturn Inline citations element
107−Inline.Cite = Inline:create_constructor(
182+M.Cite = M.Inline:create_constructor(
109− function(lst, cs) return {c = {cs, lst}} end
184+ function(content, citations) return {c = {citations, content}} end
111−--- Create a Code inline element
187+--- Creates a Code inline element
112−-- @function Inline.Code
188+-- @function Code
189+-- @tparam string code brief image description
190+-- @tparam[opt] Attributes attributes additional attributes
191+-- @treturn Inline code element
113−Inline.Code = Inline:create_constructor(
192+M.Code = M.Inline:create_constructor(
115− function(code, attr) return {c = {attr, code}} end
194+ function(code, attributes) return {c = {attributes, code}} end
117−--- Create a Emph inline element
196+
197+--- Creates an inline element representing emphasised text.
118−-- @function Inline.Emph
198+-- @function Emph
199+-- @tparam {Inline,..} content inline content
200+-- @treturn Inline emphasis element
119−Inline.Emph = Inline:create_constructor(
201+M.Emph = M.Inline:create_constructor(
121− function(xs) return {c = xs} end
203+ function(content) return {c = content} end
123−--- Create a Image inline element
206+--- Creates a Image inline element
124−-- @function Inline.Image
207+-- @function Image
208+-- @tparam {Inline,..} caption text used to describe the image
209+-- @tparam string src path to the image file
210+-- @tparam[opt] string title brief image description
211+-- @tparam[opt] Attributes attributes additional attributes
212+-- @treturn Inline image element
125−Inline.Image = Inline:create_constructor(
213+M.Image = M.Inline:create_constructor(
127− function(capt, src, tit, attr) return {c = {attr, capt, {src, tit}}} end
215+ function(caption, src, title, attributes)
217+ attributes = attributes or Attribute.empty
218+ return {c = {attributes, caption, {src, title}}}
129--- Create a LineBreak inline element
222--- Create a LineBreak inline element
130−-- @function Inline.LineBreak
223+-- @function LineBreak
224+-- @treturn Inline linebreak element
131−Inline.LineBreak = Inline:create_constructor(
225+M.LineBreak = M.Inline:create_constructor(
132 "LineBreak",
226 "LineBreak",
133 function() return {} end
227 function() return {} end
135−--- Create a Link inline element
230+--- Creates a link inline element, usually a hyperlink.
136−-- @function Inline.Link
231+-- @function Link
232+-- @tparam {Inline,..} content text for this link
233+-- @tparam string target the link target
234+-- @tparam[opt] string title brief link description
235+-- @tparam[opt] Attributes attributes additional attributes
236+-- @treturn Inline image element
137−Inline.Link = Inline:create_constructor(
237+M.Link = M.Inline:create_constructor(
139− function(txt, src, tit, attr) return {c = {attr, txt, {src, tit}}} end
239+ function(content, target, title, attributes)
241+ attributes = attributes or Attribute.empty
242+ return {c = {attributes, content, {target, title}}}
141−--- Create a Math inline element
246+--- Creates a Math inline element
142−-- @function Inline.Math
247+-- @function Math
248+-- @tparam InlineMath|DisplayMath mathtype Display specifier
249+-- @tparam string text Math content
250+-- @treturn Inline Math element
143−Inline.Math = Inline:create_constructor(
251+M.Math = M.Inline:create_constructor(
145− function(m, str) return {c = {m, str}} end
253+ function(mathtype, text)
254+ return {c = {mathtype, text}}
147−--- Create a Note inline element
258+--- Creates a Note inline element
148−-- @function Inline.Note
259+-- @function Note
260+-- @tparam {Block,...} content footnote block content
149−Inline.Note = Inline:create_constructor(
261+M.Note = M.Inline:create_constructor(
151 function(contents) return {c = contents} end
263 function(contents) return {c = contents} end
153−--- Create a Quoted inline element
266+--- Creates a Quoted inline element
154−-- @function Inline.Quoted
267+-- @function Quoted
268+-- @tparam DoubleQuote|SingleQuote quotetype type of quotes to be used
269+-- @tparam {Inline,..} content inline content
270+-- @treturn Inline quoted element
155−Inline.Quoted = Inline:create_constructor(
271+M.Quoted = M.Inline:create_constructor(
156 "Quoted",
272 "Quoted",
157− function(qt, lst) return {c = {qt, lst}} end
273+ function(quotetype, content) return {c = {quotetype, content}} end
159−--- Create a RawInline inline element
275+--- Creates a RawInline inline element
160−-- @function Inline.RawInline
276+-- @function RawInline
277+-- @tparam string format format of the contents
278+-- @tparam string text string content
279+-- @treturn Inline raw inline element
161−Inline.RawInline = Inline:create_constructor(
280+M.RawInline = M.Inline:create_constructor(
162 "RawInline",
281 "RawInline",
163− function(f, xs) return {c = {f, xs}} end
282+ function(format, text) return {c = {format, text}} end
165−--- Create a SmallCaps inline element
284+
166−-- @function Inline.SmallCaps
285+--- Creates text rendered in small caps
286+-- @function SmallCaps
287+-- @tparam {Inline,..} content inline content
288+-- @treturn Inline smallcaps element
167−Inline.SmallCaps = Inline:create_constructor(
289+M.SmallCaps = M.Inline:create_constructor(
168 "SmallCaps",
290 "SmallCaps",
169− function(xs) return {c = xs} end
291+ function(content) return {c = content} end
171−--- Create a SoftBreak inline element
294+--- Creates a SoftBreak inline element.
172−-- @function Inline.SoftBreak
295+-- @function SoftBreak
296+-- @treturn Inline softbreak element
173−Inline.SoftBreak = Inline:create_constructor(
297+M.SoftBreak = M.Inline:create_constructor(
174 "SoftBreak",
298 "SoftBreak",
175 function() return {} end
299 function() return {} end
177--- Create a Space inline element
302--- Create a Space inline element
178−-- @function Inline.Space
303+-- @function Space
304+-- @treturn Inline space element
179−Inline.Space = Inline:create_constructor(
305+M.Space = M.Inline:create_constructor(
181 function() return {} end
307 function() return {} end
183−--- Create a Span inline element
310+--- Creates a Span inline element
184−-- @function Inline.Span
311+-- @function Span
312+-- @tparam {Inline,..} content inline content
313+-- @tparam[opt] Attributes attributes additional attributes
314+-- @treturn Inline span element
185−Inline.Span = Inline:create_constructor(
315+M.Span = M.Inline:create_constructor(
187− function(ls, attr) return {c = {attr, xs}} end
317+ function(content, attributes) return {c = {attributes, content}} end
189−--- Create a Str inline element
320+--- Creates a Str inline element
190−-- @function Inline.Str
321+-- @function Str
322+-- @tparam string text content
323+-- @treturn Inline string element
191−Inline.Str = Inline:create_constructor(
324+M.Str = M.Inline:create_constructor(
193− function(str) return {c = str} end
326+ function(text) return {c = text} end
195−--- Create a Strikeout inline element
328+
196−-- @function Inline.Strikeout
329+--- Creates text which is striked out.
330+-- @function Strikeout
331+-- @tparam {Inline,..} content inline content
332+-- @treturn Inline strikeout element
197−Inline.Strikeout = Inline:create_constructor(
333+M.Strikeout = M.Inline:create_constructor(
198 "Strikeout",
334 "Strikeout",
199− function(xs) return {c = xs} end
335+ function(content) return {c = content} end
201−--- Create a Strong inline element
337+
338+--- Creates a Strong element, whose text is usually displayed in a bold font.
202−-- @function Inline.Strong
339+-- @function Strong
340+-- @tparam {Inline,..} content inline content
341+-- @treturn Inline strong element
203−Inline.Strong = Inline:create_constructor(
342+M.Strong = M.Inline:create_constructor(
204 "Strong",
343 "Strong",
205− function(xs) return {c = xs} end
344+ function(content) return {c = content} end
207−--- Create a Subscript inline element
347+--- Creates a Subscript inline element
208−-- @function Inline.Subscript
348+-- @function Subscript
349+-- @tparam {Inline,..} content inline content
350+-- @treturn Inline subscript element
209−Inline.Subscript = Inline:create_constructor(
351+M.Subscript = M.Inline:create_constructor(
210 "Subscript",
352 "Subscript",
211− function(xs) return {c = xs} end
353+ function(content) return {c = content} end
213−--- Create a Superscript inline element
356+--- Creates a Superscript inline element
214−-- @function Inline.Superscript
357+-- @function Superscript
358+-- @tparam {Inline,..} content inline content
359+-- @treturn Inline strong element
215−Inline.Superscript = Inline:create_constructor(
360+M.Superscript = M.Inline:create_constructor(
216 "Superscript",
361 "Superscript",
217− function(xs) return {c = xs} end
362+ function(content) return {c = content} end
238−M.inline_types = {
366+------------------------------------------------------------------------
239− "Cite",
367+-- Block elements
240− "Code",
368+-- @type Block
241− "Emph",
369+M.Block = Element:make_subtype{}
243− "LineBreak",
371+--- Block constructors
244− "Link",
372+M.Block.constructors = {
245− "Math",
373+ BlockQuote = true,
246− "Note",
374+ BulletList = true,
247− "Quoted",
375+ CodeBlock = true,
248− "RawInline",
376+ DefinitionList = true,
249− "SmallCaps",
377+ Div = true,
250− "SoftBreak",
378+ Header = true,
251− "Space",
379+ HorizontalRule = true,
252− "Span",
380+ HorizontalRule = true,
253− "Str",
381+ LineBlock = true,
254− "Strikeout",
382+ Null = true,
255− "Strong",
383+ OrderedList = true,
256− "Subscript",
384+ Para = true,
257− "Superscript"
385+ Plain = true,
390+local set_of_inline_types = {}
391+for k, _ in pairs(M.Inline.constructor) do
392+ set_of_inline_types[k] = true
261−for _, block_type in pairs(M.block_types) do
395+for block_type, _ in pairs(M.Block.constructors) do
262 M[block_type] = function(...)
396 M[block_type] = function(...)
263− return Block:new(block_type, ...)
397+ return M.Block:new(block_type, ...)
267−for _, inline_type in pairs(M.inline_types) do
268− M[inline_type] = Inline[inline_type]
271−--- Arrays to provide fast lookup of element types
402+------------------------------------------------------------------------
272−local set_of_inline_types = {}
403+-- Constants
273−local set_of_block_types = {}
404+-- @section constants
275−for i = 1, #M.inline_types do
406+--- Math content is to be displayed on a separate line.
276− set_of_inline_types[M.inline_types[i]] = true
407+-- @see Math
277−end
408+M.DisplayMath = {}
278−for i = 1, #M.block_types do
409+M.DisplayMath.t = "DisplayMath"
279− set_of_block_types[M.block_types[i]] = true
410+--- Math content is to be displayed inline within the paragraph
413+M.InlineMath.t = "InlineMath"
415+--- Double quoted content.
418+M.DoubleQuote.t = "DoubleQuote"
420+--- Single quoted content.
423+M.SingleQuote.t = "SingleQuote"
425+--- Author name is mentioned in the text.
429+M.AuthorInText.t = "AuthorInText"
431+--- Author name is suppressed.
434+M.SuppressAuthor = {}
435+M.SuppressAuthor.t = "SuppressAuthor"
437+--- Default citation style is used.
440+M.NormalCitation = {}
441+M.NormalCitation.t = "NormalCitation"
444+------------------------------------------------------------------------
448+--- Use functions defined in the global namespace to create a pandoc filter.
449+-- All globally defined functions which have names of pandoc elements are
450+-- collected into a new table.
451+-- @return A list of filter functions
453+-- -- within a file defining a pandoc filter:
454+-- function Str(text)
455+-- return pandoc.Str(utf8.upper(text))
458+-- return {pandoc.global_filter()}
459+-- -- the above is equivallent to
460+-- -- return {{Str = Str}}
282function M.global_filter()
461function M.global_filter()
283 local res = {}
462 local res = {}
284 for k, v in pairs(_G) do
463 for k, v in pairs(_G) do
285− if set_of_inline_types[k] or set_of_block_types[k] or k == "Doc" then
464+ if M.Inline.constructor[k] or M.Block.constructors[k] or k == "Doc" then
286 res[k] = v
465 res[k] = v
289 return res
468 return res