git.iko.soy/typeable/pandoc
on 425df8f help sign in
typeable/pandoc/data/pandoc.lua
513 lines 14 kB history raw
1--[[
2pandoc.lua
4Copyright © 2017 Albert Krewinkel
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
8and this permission notice appear in all copies.
10THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
11REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
12FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
13INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
14OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
16THIS SOFTWARE.
17]]
19---
20-- Lua functions for pandoc scripts.
21--
22-- @author Albert Krewinkel
23-- @copyright © 2017 Albert Krewinkel
24-- @license MIT
25local M = {
26 _VERSION = "0.2.0"
29--- Attributes
30-- @type Attributes
31M.Attributes = {}
32setmetatable(M.Attributes, M.Attributes)
34M.Attributes.__index = function(t, k)
35 if k == "id" then
36 return t[1]
37 elseif k == "class" then
38 return table.concat(t[2], ' ')
39 else
40 return t.kv[k]
41 end
42end
44--- Create a new set of attributes (Attr).
45-- @function Attributes
46M.Attributes.__call = function(t, key_values, id, classes)
47 local kv = {}
48 for i = 1, #key_values do
49 kv[key_values[i][1]] = key_values[i][2]
50 end
51 id = id or ''
52 classes = classes or {}
53 local attr = {id, classes, key_values, kv = kv}
54 setmetatable(attr, t)
55 return attr
56end
57M.Attributes.empty = M.Attributes('', {}, {})
60--- Creates a single citation.
61-- @function 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
68M.Citation = function(id, mode, prefix, suffix, note_num, hash)
69 prefix = prefix or {}
70 suffix = suffix or {}
71 note_num = note_num or 0
72 hash = hash or 0
73 return {
74 citationId = id,
75 citationPrefix = prefix,
76 citationSuffix = suffix,
77 citationMode = mode,
78 citationNoteNum = note_num,
79 citationHash = hash,
80 }
81end
83------------------------------------------------------------------------
84-- The base class for pandoc's AST elements.
85-- @type Element
86-- @local
87local Element = {}
89--- Create a new element subtype
90-- @local
91function Element:make_subtype(o)
92 o = o or {}
93 setmetatable(o, self)
94 self.__index = self
95 return o
96end
98--- Create a new element given its tag and arguments
99-- @local
100function Element:new(tag, ...)
101 local element = { t = tag }
102 local content = {...}
103 -- special case for unary constructors
104 if #content == 1 then
105 element.c = content[1]
106 -- Don't set 'c' field if no further arguments were given. This is important
107 -- for nullary constructors like `Space` and `HorizontalRule`.
108 elseif #content > 0 then
109 element.c = content
110 end
111 setmetatable(element, self)
112 self.__index = self
113 return element
114end
116--- Create a new constructor
117-- @local
118-- @param tag Tag used to identify the constructor
119-- @param fn Function to be called when constructing a new element
120-- @return function that constructs a new element
121function Element:create_constructor(tag, fn)
122 local constr = self:make_subtype({tag = tag})
123 function constr:new(...)
124 local obj = fn(...)
125 setmetatable(obj, self)
126 self.__index = function(t, k)
127 if k == "c" then
128 return t["content"]
129 elseif k == "t" then
130 return getmetatable(t)["tag"]
131 else
132 return getmetatable(t)[k]
133 end
134 end
135 return obj
136 end
137 self.constructor = self.constructor or {}
138 self.constructor[tag] = constr
139 return constr
140end
142--- Calls the constructor, creating a new element.
143-- @local
144function Element.__call(t, ...)
145 return t:new(...)
146end
148------------------------------------------------------------------------
149--- Pandoc Document
150-- @section document
152--- A complete pandoc document
153-- @function Doc
154-- @tparam {Block,...} blocks document content
155-- @tparam[opt] Meta meta document meta data
156function M.Doc(blocks, meta)
157 meta = meta or {}
158 return {
159 ["blocks"] = blocks,
160 ["meta"] = meta,
161 ["pandoc-api-version"] = {1,17,0,5},
162 }
163end
166------------------------------------------------------------------------
167-- MetaValue
168-- @section MetaValue
169M.MetaValue = Element:make_subtype{}
170M.MetaValue.__call = function(t, ...)
171 return t:new(...)
172end
173--- Meta blocks
174-- @function MetaBlocks
175-- @tparam {Block,...} blocks blocks
176--- Meta inlines
177-- @function MetaInlines
178-- @tparam {Inline,...} inlines inlines
179--- Meta list
180-- @function MetaList
181-- @tparam {MetaValue,...} meta_values list of meta values
182--- Meta boolean
183-- @function MetaBool
184-- @tparam boolean bool boolean value
185--- Meta map
186-- @function MetaMap
187-- @tparam table a string-index map of meta values
188--- Meta string
189-- @function MetaString
190-- @tparam string str string value
191M.meta_value_types = {
192 "MetaBlocks",
193 "MetaBool",
194 "MetaInlines",
195 "MetaList",
196 "MetaMap",
197 "MetaString"
199for i = 1, #M.meta_value_types do
200 M[M.meta_value_types[i]] = M.MetaValue:create_constructor(
201 M.meta_value_types[i],
202 function(content)
203 return {c = content}
204 end
205 )
206end
208--- Inline element class
209-- @type Inline
210M.Inline = Element:make_subtype{}
211M.Inline.__call = function (t, ...)
212 return t:new(...)
213end
215------------------------------------------------------------------------
216-- Inline
217-- @section Inline
219--- Creates a Cite inline element
220-- @function Cite
221-- @tparam {Inline,...} content List of inlines
222-- @tparam {Citation,...} citations List of citations
223-- @treturn Inline citations element
224M.Cite = M.Inline:create_constructor(
225 "Cite",
226 function(content, citations) return {c = {citations, content}} end
229--- Creates a Code inline element
230-- @function Code
231-- @tparam string code brief image description
232-- @tparam[opt] Attributes attributes additional attributes
233-- @treturn Inline code element
234M.Code = M.Inline:create_constructor(
235 "Code",
236 function(code, attributes) return {c = {attributes, code}} end
239--- Creates an inline element representing emphasised text.
240-- @function Emph
241-- @tparam {Inline,..} content inline content
242-- @treturn Inline emphasis element
243M.Emph = M.Inline:create_constructor(
244 "Emph",
245 function(content) return {c = content} end
248--- Creates a Image inline element
249-- @function Image
250-- @tparam {Inline,..} caption text used to describe the image
251-- @tparam string src path to the image file
252-- @tparam[opt] string title brief image description
253-- @tparam[opt] Attributes attributes additional attributes
254-- @treturn Inline image element
255M.Image = M.Inline:create_constructor(
256 "Image",
257 function(caption, src, title, attributes)
258 title = title or ""
259 attributes = attributes or Attribute.empty
260 return {c = {attributes, caption, {src, title}}}
261 end
264--- Create a LineBreak inline element
265-- @function LineBreak
266-- @treturn Inline linebreak element
267M.LineBreak = M.Inline:create_constructor(
268 "LineBreak",
269 function() return {} end
272--- Creates a link inline element, usually a hyperlink.
273-- @function Link
274-- @tparam {Inline,..} content text for this link
275-- @tparam string target the link target
276-- @tparam[opt] string title brief link description
277-- @tparam[opt] Attributes attributes additional attributes
278-- @treturn Inline image element
279M.Link = M.Inline:create_constructor(
280 "Link",
281 function(content, target, title, attributes)
282 title = title or ""
283 attributes = attributes or Attribute.empty
284 return {c = {attributes, content, {target, title}}}
285 end
288--- Creates a Math inline element
289-- @function Math
290-- @tparam InlineMath|DisplayMath mathtype Display specifier
291-- @tparam string text Math content
292-- @treturn Inline Math element
293M.Math = M.Inline:create_constructor(
294 "Math",
295 function(mathtype, text)
296 return {c = {mathtype, text}}
297 end
300--- Creates a Note inline element
301-- @function Note
302-- @tparam {Block,...} content footnote block content
303M.Note = M.Inline:create_constructor(
304 "Note",
305 function(contents) return {c = contents} end
308--- Creates a Quoted inline element
309-- @function Quoted
310-- @tparam DoubleQuote|SingleQuote quotetype type of quotes to be used
311-- @tparam {Inline,..} content inline content
312-- @treturn Inline quoted element
313M.Quoted = M.Inline:create_constructor(
314 "Quoted",
315 function(quotetype, content) return {c = {quotetype, content}} end
317--- Creates a RawInline inline element
318-- @function RawInline
319-- @tparam string format format of the contents
320-- @tparam string text string content
321-- @treturn Inline raw inline element
322M.RawInline = M.Inline:create_constructor(
323 "RawInline",
324 function(format, text) return {c = {format, text}} end
327--- Creates text rendered in small caps
328-- @function SmallCaps
329-- @tparam {Inline,..} content inline content
330-- @treturn Inline smallcaps element
331M.SmallCaps = M.Inline:create_constructor(
332 "SmallCaps",
333 function(content) return {c = content} end
336--- Creates a SoftBreak inline element.
337-- @function SoftBreak
338-- @treturn Inline softbreak element
339M.SoftBreak = M.Inline:create_constructor(
340 "SoftBreak",
341 function() return {} end
344--- Create a Space inline element
345-- @function Space
346-- @treturn Inline space element
347M.Space = M.Inline:create_constructor(
348 "Space",
349 function() return {} end
352--- Creates a Span inline element
353-- @function Span
354-- @tparam {Inline,..} content inline content
355-- @tparam[opt] Attributes attributes additional attributes
356-- @treturn Inline span element
357M.Span = M.Inline:create_constructor(
358 "Span",
359 function(content, attributes) return {c = {attributes, content}} end
362--- Creates a Str inline element
363-- @function Str
364-- @tparam string text content
365-- @treturn Inline string element
366M.Str = M.Inline:create_constructor(
367 "Str",
368 function(text) return {c = text} end
371--- Creates text which is striked out.
372-- @function Strikeout
373-- @tparam {Inline,..} content inline content
374-- @treturn Inline strikeout element
375M.Strikeout = M.Inline:create_constructor(
376 "Strikeout",
377 function(content) return {c = content} end
380--- Creates a Strong element, whose text is usually displayed in a bold font.
381-- @function Strong
382-- @tparam {Inline,..} content inline content
383-- @treturn Inline strong element
384M.Strong = M.Inline:create_constructor(
385 "Strong",
386 function(content) return {c = content} end
389--- Creates a Subscript inline element
390-- @function Subscript
391-- @tparam {Inline,..} content inline content
392-- @treturn Inline subscript element
393M.Subscript = M.Inline:create_constructor(
394 "Subscript",
395 function(content) return {c = content} end
398--- Creates a Superscript inline element
399-- @function Superscript
400-- @tparam {Inline,..} content inline content
401-- @treturn Inline strong element
402M.Superscript = M.Inline:create_constructor(
403 "Superscript",
404 function(content) return {c = content} end
408------------------------------------------------------------------------
409-- Block elements
410-- @type Block
411M.Block = Element:make_subtype{}
413--- Block constructors
414M.Block.constructors = {
415 BlockQuote = true,
416 BulletList = true,
417 CodeBlock = true,
418 DefinitionList = true,
419 Div = true,
420 Header = true,
421 HorizontalRule = true,
422 HorizontalRule = true,
423 LineBlock = true,
424 Null = true,
425 OrderedList = true,
426 Para = true,
427 Plain = true,
428 RawBlock = true,
429 Table = true,
432local set_of_inline_types = {}
433for k, _ in pairs(M.Inline.constructor) do
434 set_of_inline_types[k] = true
435end
437for block_type, _ in pairs(M.Block.constructors) do
438 M[block_type] = function(...)
439 return M.Block:new(block_type, ...)
440 end
441end
444------------------------------------------------------------------------
445-- Constants
446-- @section constants
448--- Math content is to be displayed on a separate line.
449-- @see Math
450M.DisplayMath = {}
451M.DisplayMath.t = "DisplayMath"
452--- Math content is to be displayed inline within the paragraph
453-- @see Math
454M.InlineMath = {}
455M.InlineMath.t = "InlineMath"
457--- Double quoted content.
458-- @see Quoted
459M.DoubleQuote = {}
460M.DoubleQuote.t = "DoubleQuote"
462--- Single quoted content.
463-- @see Quoted
464M.SingleQuote = {}
465M.SingleQuote.t = "SingleQuote"
467--- Author name is mentioned in the text.
468-- @see Citation
469-- @see Cite
470M.AuthorInText = {}
471M.AuthorInText.t = "AuthorInText"
473--- Author name is suppressed.
474-- @see Citation
475-- @see Cite
476M.SuppressAuthor = {}
477M.SuppressAuthor.t = "SuppressAuthor"
479--- Default citation style is used.
480-- @see Citation
481-- @see Cite
482M.NormalCitation = {}
483M.NormalCitation.t = "NormalCitation"
486------------------------------------------------------------------------
487-- Helper Functions
488-- @section helpers
490--- Use functions defined in the global namespace to create a pandoc filter.
491-- All globally defined functions which have names of pandoc elements are
492-- collected into a new table.
493-- @return A list of filter functions
494-- @usage
495-- -- within a file defining a pandoc filter:
496-- function Str(text)
497-- return pandoc.Str(utf8.upper(text))
498-- end
499--
500-- return {pandoc.global_filter()}
501-- -- the above is equivallent to
502-- -- return {{Str = Str}}
503function M.global_filter()
504 local res = {}
505 for k, v in pairs(_G) do
506 if M.Inline.constructor[k] or M.Block.constructors[k] or k == "Doc" then
507 res[k] = v
508 end
509 end
510 return res
511end
513return M