git.iko.soy/typeable/pandoc
on 76b051f help sign in
typeable/pandoc/data/pandoc.lua
747 lines 21 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------------------------------------------------------------------------
30-- The base class for pandoc's AST elements.
31-- @type Element
32-- @local
33local Element = {}
35--- Create a new element subtype
36-- @local
37function Element:make_subtype(o)
38 o = o or {}
39 setmetatable(o, self)
40 self.__index = self
41 return o
42end
44--- Create a new element given its tag and arguments
45-- @local
46function Element:new(tag, ...)
47 local element = { t = tag }
48 local content = {...}
49 -- special case for unary constructors
50 if #content == 1 then
51 element.c = content[1]
52 -- Don't set 'c' field if no further arguments were given. This is important
53 -- for nullary constructors like `Space` and `HorizontalRule`.
54 elseif #content > 0 then
55 element.c = content
56 end
57 setmetatable(element, self)
58 self.__index = self
59 return element
60end
62--- Create a new constructor
63-- @local
64-- @param tag Tag used to identify the constructor
65-- @param fn Function to be called when constructing a new element
66-- @return function that constructs a new element
67function Element:create_constructor(tag, fn)
68 local constr = self:make_subtype({tag = tag})
69 function constr:new(...)
70 local obj = fn(...)
71 setmetatable(obj, self)
72 self.__index = function(t, k)
73 if k == "c" then
74 return t["content"]
75 elseif k == "t" then
76 return getmetatable(t)["tag"]
77 else
78 return getmetatable(t)[k]
79 end
80 end
81 return obj
82 end
83 self.constructor = self.constructor or {}
84 self.constructor[tag] = constr
85 return constr
86end
88--- Calls the constructor, creating a new element.
89-- @local
90function Element.__call(t, ...)
91 return t:new(...)
92end
94------------------------------------------------------------------------
95--- Pandoc Document
96-- @section document
98--- A complete pandoc document
99-- @function Doc
100-- @tparam {Block,...} blocks document content
101-- @tparam[opt] Meta meta document meta data
102function M.Doc(blocks, meta)
103 meta = meta or {}
104 return {
105 ["blocks"] = blocks,
106 ["meta"] = meta,
107 ["pandoc-api-version"] = {1,17,0,5},
108 }
109end
112------------------------------------------------------------------------
113-- MetaValue
114-- @section MetaValue
115M.MetaValue = Element:make_subtype{}
116M.MetaValue.__call = function(t, ...)
117 return t:new(...)
118end
119--- Meta blocks
120-- @function MetaBlocks
121-- @tparam {Block,...} blocks blocks
123--- Meta inlines
124-- @function MetaInlines
125-- @tparam {Inline,...} inlines inlines
127--- Meta list
128-- @function MetaList
129-- @tparam {MetaValue,...} meta_values list of meta values
131--- Meta boolean
132-- @function MetaBool
133-- @tparam boolean bool boolean value
135--- Meta map
136-- @function MetaMap
137-- @tparam table a string-index map of meta values
139--- Meta string
140-- @function MetaString
141-- @tparam string str string value
142M.meta_value_types = {
143 "MetaBlocks",
144 "MetaBool",
145 "MetaInlines",
146 "MetaList",
147 "MetaMap",
148 "MetaString"
150for i = 1, #M.meta_value_types do
151 M[M.meta_value_types[i]] = M.MetaValue:create_constructor(
152 M.meta_value_types[i],
153 function(content)
154 return {c = content}
155 end
156 )
157end
159------------------------------------------------------------------------
160-- Blocks
161-- @section Block
163--- Block elements
164M.Block = Element:make_subtype{}
165M.Block.__call = function (t, ...)
166 return t:new(...)
167end
169--- Creates a block quote element
170-- @function BlockQuote
171-- @tparam {Block,...} content block content
172-- @treturn Block block quote element
173M.BlockQuote = M.Block:create_constructor(
174 "BlockQuote",
175 function(content) return {c = content} end
178--- Creates a bullet (i.e. unordered) list.
179-- @function BulletList
180-- @tparam {{Block,...},...} content list of items
181-- @treturn Block block quote element
182M.BulletList = M.Block:create_constructor(
183 "BulletList",
184 function(content) return {c = content} end
187--- Creates a code block element
188-- @function CodeBlock
189-- @tparam string code code string
190-- @tparam[opt] Attributes attributes element attributes
191-- @treturn Block code block element
192M.CodeBlock = M.Block:create_constructor(
193 "CodeBlock",
194 function(code, attributes) return {c = {attributes, code}} end
197--- Creates a definition list, containing terms and their explanation.
198-- @function DefinitionList
199-- @tparam {{{Inline,...},{Block,...}},...} content list of items
200-- @treturn Block block quote element
201M.DefinitionList = M.Block:create_constructor(
202 "DefinitionList",
203 function(content) return {c = content} end
206--- Creates a div element
207-- @function Div
208-- @tparam {Block,...} content block content
209-- @tparam[opt] Attributes attributes element attributes
210-- @treturn Block code block element
211M.Div = M.Block:create_constructor(
212 "Div",
213 function(content, attributes) return {c = {attributes, content}} end
216--- Creates a block quote element.
217-- @function Header
218-- @tparam int level header level
219-- @tparam Attributes attributes element attributes
220-- @tparam {Inline,...} content inline content
221-- @treturn Block header element
222M.Header = M.Block:create_constructor(
223 "Header",
224 function(level, attributes, content)
225 return {c = {level, attributes, content}}
226 end
229--- Creates a horizontal rule.
230-- @function HorizontalRule
231-- @treturn Block horizontal rule
232M.HorizontalRule = M.Block:create_constructor(
233 "HorizontalRule",
234 function() return {} end
237--- Creates a line block element.
238-- @function LineBlock
239-- @tparam {{Inline,...},...} content inline content
240-- @treturn Block block quote element
241M.LineBlock = M.Block:create_constructor(
242 "LineBlock",
243 function(content) return {c = content} end
246--- Creates a null element.
247-- @function Null
248-- @treturn Block null element
249M.Null = M.Block:create_constructor(
250 "Null",
251 function() return {} end
254--- Creates an ordered list.
255-- @function OrderedList
256-- @tparam {{Block,...},...} items list items
257-- @param[opt] listAttributes list parameters
258-- @treturn Block
259M.OrderedList = M.Block:create_constructor(
260 "OrderedList",
261 function(items, listAttributes)
262 return {c = {listAttributes,items}}
263 end
266--- Creates a para element.
267-- @function Para
268-- @tparam {Inline,...} content inline content
269-- @treturn Block block quote element
270M.Para = M.Block:create_constructor(
271 "Para",
272 function(content) return {c = content} end
275--- Creates a plain element.
276-- @function Plain
277-- @tparam {Inline,...} content inline content
278-- @treturn Block block quote element
279M.Plain = M.Block:create_constructor(
280 "Plain",
281 function(content) return {c = content} end
284--- Creates a raw content block of the specified format.
285-- @function RawBlock
286-- @tparam string format format of content
287-- @tparam string content string content
288-- @treturn Block block quote element
289M.RawBlock = M.Block:create_constructor(
290 "RawBlock",
291 function(format, content) return {c = {format, content}} end
294--- Creates a table element.
295-- @function Table
296-- @tparam {Inline,...} caption table caption
297-- @tparam {AlignDefault|AlignLeft|AlignRight|AlignCenter,...} aligns alignments
298-- @tparam {int,...} widths column widths
299-- @tparam {Block,...} headers header row
300-- @tparam {{Block,...}} rows table rows
301-- @treturn Block block quote element
302M.Table = M.Block:create_constructor(
303 "Table",
304 function(caption, aligns, widths, headers, rows)
305 return {c = {caption, aligns, widths, headers, rows}}
306 end
310------------------------------------------------------------------------
311-- Inline
312-- @section Inline
314--- Inline element class
315M.Inline = Element:make_subtype{}
316M.Inline.__call = function (t, ...)
317 return t:new(...)
318end
320--- Creates a Cite inline element
321-- @function Cite
322-- @tparam {Inline,...} content List of inlines
323-- @tparam {Citation,...} citations List of citations
324-- @treturn Inline citations element
325M.Cite = M.Inline:create_constructor(
326 "Cite",
327 function(content, citations) return {c = {citations, content}} end
330--- Creates a Code inline element
331-- @function Code
332-- @tparam string code brief image description
333-- @tparam[opt] Attributes attributes additional attributes
334-- @treturn Inline code element
335M.Code = M.Inline:create_constructor(
336 "Code",
337 function(code, attributes) return {c = {attributes, code}} end
340--- Creates an inline element representing emphasised text.
341-- @function Emph
342-- @tparam {Inline,..} content inline content
343-- @treturn Inline emphasis element
344M.Emph = M.Inline:create_constructor(
345 "Emph",
346 function(content) return {c = content} end
349--- Creates a Image inline element
350-- @function Image
351-- @tparam {Inline,..} caption text used to describe the image
352-- @tparam string src path to the image file
353-- @tparam[opt] string title brief image description
354-- @tparam[opt] Attributes attributes additional attributes
355-- @treturn Inline image element
356M.Image = M.Inline:create_constructor(
357 "Image",
358 function(caption, src, title, attributes)
359 title = title or ""
360 attributes = attributes or Attribute.empty
361 return {c = {attributes, caption, {src, title}}}
362 end
365--- Create a LineBreak inline element
366-- @function LineBreak
367-- @treturn Inline linebreak element
368M.LineBreak = M.Inline:create_constructor(
369 "LineBreak",
370 function() return {} end
373--- Creates a link inline element, usually a hyperlink.
374-- @function Link
375-- @tparam {Inline,..} content text for this link
376-- @tparam string target the link target
377-- @tparam[opt] string title brief link description
378-- @tparam[opt] Attributes attributes additional attributes
379-- @treturn Inline image element
380M.Link = M.Inline:create_constructor(
381 "Link",
382 function(content, target, title, attributes)
383 title = title or ""
384 attributes = attributes or Attribute.empty
385 return {c = {attributes, content, {target, title}}}
386 end
389--- Creates a Math element, either inline or displayed. It is usually simpler to
390-- use one of the specialized functions @{InlineMath} or @{DisplayMath} instead.
391-- @function Math
392-- @tparam "InlineMath"|"DisplayMath" mathtype rendering specifier
393-- @tparam string text Math content
394-- @treturn Inline Math element
395M.Math = M.Inline:create_constructor(
396 "Math",
397 function(mathtype, text)
398 return {c = {mathtype, text}}
399 end
401--- Creates a DisplayMath element.
402-- @function DisplayMath
403-- @tparam string text Math content
404-- @treturn Inline Math element
405M.DisplayMath = M.Inline:create_constructor(
406 "DisplayMath",
407 function(text) return M.Math("DisplayMath", text) end
409--- Creates an InlineMath inline element.
410-- @function InlineMath
411-- @tparam string text Math content
412-- @treturn Inline Math element
413M.InlineMath = M.Inline:create_constructor(
414 "InlineMath",
415 function(text) return M.Math("InlineMath", text) end
418--- Creates a Note inline element
419-- @function Note
420-- @tparam {Block,...} content footnote block content
421M.Note = M.Inline:create_constructor(
422 "Note",
423 function(contents) return {c = contents} end
426--- Creates a Quoted inline element given the quote type and quoted content. It
427-- is usually simpler to use one of the specialized functions @{SingleQuoted} or
428-- @{DoubleQuoted} instead.
429-- @function Quoted
430-- @tparam "DoubleQuote"|"SingleQuote" quotetype type of quotes to be used
431-- @tparam {Inline,..} content inline content
432-- @treturn Inline quoted element
433M.Quoted = M.Inline:create_constructor(
434 "Quoted",
435 function(quotetype, content) return {c = {quotetype, content}} end
437--- Creates a single-quoted inline element.
438-- @function SingleQuoted
439-- @tparam {Inline,..} content inline content
440-- @treturn Inline quoted element
441-- @see Quoted
442M.SingleQuoted = M.Inline:create_constructor(
443 "SingleQuoted",
444 function(content) return M.Quoted(M.SingleQuote, content) end
446--- Creates a single-quoted inline element.
447-- @function DoubleQuoted
448-- @tparam {Inline,..} content inline content
449-- @treturn Inline quoted element
450-- @see Quoted
451M.DoubleQuoted = M.Inline:create_constructor(
452 "DoubleQuoted",
453 function(content) return M.Quoted("DoubleQuote", content) end
456--- Creates a RawInline inline element
457-- @function RawInline
458-- @tparam string format format of the contents
459-- @tparam string text string content
460-- @treturn Inline raw inline element
461M.RawInline = M.Inline:create_constructor(
462 "RawInline",
463 function(format, text) return {c = {format, text}} end
466--- Creates text rendered in small caps
467-- @function SmallCaps
468-- @tparam {Inline,..} content inline content
469-- @treturn Inline smallcaps element
470M.SmallCaps = M.Inline:create_constructor(
471 "SmallCaps",
472 function(content) return {c = content} end
475--- Creates a SoftBreak inline element.
476-- @function SoftBreak
477-- @treturn Inline softbreak element
478M.SoftBreak = M.Inline:create_constructor(
479 "SoftBreak",
480 function() return {} end
483--- Create a Space inline element
484-- @function Space
485-- @treturn Inline space element
486M.Space = M.Inline:create_constructor(
487 "Space",
488 function() return {} end
491--- Creates a Span inline element
492-- @function Span
493-- @tparam {Inline,..} content inline content
494-- @tparam[opt] Attributes attributes additional attributes
495-- @treturn Inline span element
496M.Span = M.Inline:create_constructor(
497 "Span",
498 function(content, attributes) return {c = {attributes, content}} end
501--- Creates a Str inline element
502-- @function Str
503-- @tparam string text content
504-- @treturn Inline string element
505M.Str = M.Inline:create_constructor(
506 "Str",
507 function(text) return {c = text} end
510--- Creates text which is striked out.
511-- @function Strikeout
512-- @tparam {Inline,..} content inline content
513-- @treturn Inline strikeout element
514M.Strikeout = M.Inline:create_constructor(
515 "Strikeout",
516 function(content) return {c = content} end
519--- Creates a Strong element, whose text is usually displayed in a bold font.
520-- @function Strong
521-- @tparam {Inline,..} content inline content
522-- @treturn Inline strong element
523M.Strong = M.Inline:create_constructor(
524 "Strong",
525 function(content) return {c = content} end
528--- Creates a Subscript inline element
529-- @function Subscript
530-- @tparam {Inline,..} content inline content
531-- @treturn Inline subscript element
532M.Subscript = M.Inline:create_constructor(
533 "Subscript",
534 function(content) return {c = content} end
537--- Creates a Superscript inline element
538-- @function Superscript
539-- @tparam {Inline,..} content inline content
540-- @treturn Inline strong element
541M.Superscript = M.Inline:create_constructor(
542 "Superscript",
543 function(content) return {c = content} end
547------------------------------------------------------------------------
548-- Helpers
549-- @section helpers
551-- Attributes
552M.Attributes = {}
553--- Create a new set of attributes (Attr).
554-- @function Attributes
555-- @tparam table key_values table containing string keys and values
556-- @tparam[opt] string id element identifier
557-- @tparam[opt] {string,...} classes element classes
558-- @return element attributes
559M.Attributes.__call = function(t, key_values, id, classes)
560 id = id or ''
561 classes = classes or {}
562 local attr = {id, classes, key_values}
563 setmetatable(attr, t)
564 return attr
565end
566M.Attributes.__index = function(t, k)
567 if rawget(t, k) then
568 return rawget(t, k)
569 elseif k == "id" then
570 if rawget(t, 1) == '' then
571 return nil
572 else
573 return rawget(t, 1)
574 end
575 elseif k == "class" then
576 if #(rawget(t, 2)) == 0 then
577 return nil
578 else
579 return table.concat(t[2], ' ')
580 end
581 else
582 for _, p in ipairs(t[3]) do
583 if k == p[1] then
584 return p[2]
585 end
586 end
587 return nil
588 end
589end
590M.Attributes.__newindex = function(t, k, v)
591 if rawget(t, k) then
592 rawset(t, k, v)
593 elseif k == "id" then
594 rawset(t, 1, v)
595 elseif k == "class" then
596 if type(v) == "string" then
597 rawset(t, 2, {v})
598 else
599 rawset(t, 2, v)
600 end
601 else
602 for _, p in ipairs(rawget(t, 3)) do
603 if k == p[1] then
604 p[2] = v
605 return
606 end
607 end
608 kv = rawget(t, 3)
609 kv[#kv + 1] = {k, v}
610 rawset(t, 3, kv)
611 end
612end
613setmetatable(M.Attributes, M.Attributes)
616--- Creates a single citation.
617-- @function Citation
618-- @tparam string id citation identifier (like a bibtex key)
619-- @tparam AuthorInText|SuppressAuthor|NormalCitation mode citation mode
620-- @tparam[opt] {Inline,...} prefix citation prefix
621-- @tparam[opt] {Inline,...} suffix citation suffix
622-- @tparam[opt] int note_num note number
623-- @tparam[opt] int note_num hash number
624M.Citation = function(id, mode, prefix, suffix, note_num, hash)
625 prefix = prefix or {}
626 suffix = suffix or {}
627 note_num = note_num or 0
628 hash = hash or 0
629 return {
630 citationId = id,
631 citationPrefix = prefix,
632 citationSuffix = suffix,
633 citationMode = mode,
634 citationNoteNum = note_num,
635 citationHash = hash,
636 }
637end
640------------------------------------------------------------------------
641-- Constants
642-- @section constants
644--- Author name is mentioned in the text.
645-- @see Citation
646-- @see Cite
647M.AuthorInText = "AuthorInText"
649--- Author name is suppressed.
650-- @see Citation
651-- @see Cite
652M.SuppressAuthor = "SuppressAuthor"
654--- Default citation style is used.
655-- @see Citation
656-- @see Cite
657M.NormalCitation = "NormalCitation"
659--- Table cells aligned left.
660-- @see Table
661M.AlignLeft = "AlignLeft"
663--- Table cells right-aligned.
664-- @see Table
665M.AlignRight = "AlignRight"
667--- Table cell content is centered.
668-- @see Table
669M.AlignCenter = "AlignCenter"
671--- Table cells are alignment is unaltered.
672-- @see Table
673M.AlignDefault = "AlignDefault"
675--- Default list number delimiters are used.
676-- @see OrderedList
677M.DefaultDelim = "DefaultDelim"
679--- List numbers are delimited by a period.
680-- @see OrderedList
681M.Period = "Period"
683--- List numbers are delimited by a single parenthesis.
684-- @see OrderedList
685M.OneParen = "OneParen"
687--- List numbers are delimited by a double parentheses.
688-- @see OrderedList
689M.TwoParens = "TwoParens"
691--- List are numbered in the default style
692-- @see OrderedList
693M.DefaultStyle = "DefaultStyle"
695--- List items are numbered as examples.
696-- @see OrderedList
697M.Example = "Example"
699--- List are numbered using decimal integers.
700-- @see OrderedList
701M.Decimal = "Decimal"
703--- List are numbered using lower-case roman numerals.
704-- @see OrderedList
705M.LowerRoman = "LowerRoman"
707--- List are numbered using upper-case roman numerals
708-- @see OrderedList
709M.UpperRoman = "UpperRoman"
711--- List are numbered using lower-case alphabetic characters.
712-- @see OrderedList
713M.LowerAlpha = "LowerAlpha"
715--- List are numbered using upper-case alphabetic characters.
716-- @see OrderedList
717M.UpperAlpha = "UpperAlpha"
720------------------------------------------------------------------------
721-- Helper Functions
722-- @section helpers
724--- Use functions defined in the global namespace to create a pandoc filter.
725-- All globally defined functions which have names of pandoc elements are
726-- collected into a new table.
727-- @return A list of filter functions
728-- @usage
729-- -- within a file defining a pandoc filter:
730-- function Str(text)
731-- return pandoc.Str(utf8.upper(text))
732-- end
733--
734-- return {pandoc.global_filter()}
735-- -- the above is equivallent to
736-- -- return {{Str = Str}}
737function M.global_filter()
738 local res = {}
739 for k, v in pairs(_G) do
740 if M.Inline.constructor[k] or M.Block.constructor[k] or M.Block.constructors[k] or k == "Doc" then
741 res[k] = v
742 end
743 end
744 return res
745end
747return M