4Copyright © 2017–2019 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
20-- Lua functions for pandoc scripts.
22-- @author Albert Krewinkel
23-- @copyright © 2017–2019 Albert Krewinkel
27-- Re-export bundled modules
28M.List = require 'pandoc.List'
29M.mediabag = require 'pandoc.mediabag'
30M.system = require 'pandoc.system'
31M.types = require 'pandoc.types'
32M.utils = require 'pandoc.utils'
33M.text = require 'text'
35-- Local names for modules which this module depends on.
40------------------------------------------------------------------------
43-- Create metatables which allow to access numerical indices via accessor
48--- Create a new indexing function.
49-- @param template function template
50-- @param indices list of indices, starting with the most deeply nested
51-- @return newly created function
53function make_indexing_function(template, ...)
55 local loadstring = loadstring or load
57 for i = 1, #indices do
58 local idx = indices[#indices - i + 1]
59 bracketed[i] = type(idx) == 'number'
60 and string.format('[%d]', idx)
61 or string.format('.%s', idx)
63 local fnstr = string.format('return ' .. template, table.concat(bracketed))
64 return assert(loadstring(fnstr))()
67--- Create accessor functions using a function template.
68-- @param fn_template function template in which '%s' is replacd with indices
69-- @param accessors list of accessors
70-- @return mapping from accessor names to accessor functions
72local function create_accessor_functions (fn_template, accessors)
74 function add_accessors(acc, ...)
75 if type(acc) == 'string' then
76 res[acc] = make_indexing_function(fn_template, ...)
77 elseif type(acc) == 'table' and #acc == 0 and next(acc) then
78 -- Named substructure: the given names are accessed via the substructure,
79 -- but the accessors are also added to the result table, enabling direct
80 -- access from the parent element. Mainly used for `attr`.
81 local name, substructure = next(acc)
82 res[name] = make_indexing_function(fn_template, ...)
83 for _, subname in ipairs(substructure) do
84 res[subname] = make_indexing_function(fn_template, subname, ...)
87 for i = 1, #(acc or {}) do
88 add_accessors(acc[i], i, ...)
92 add_accessors(accessors)
96--- Get list of top-level fields from field descriptor table.
97-- E.g.: `top_level_fields{'foo', {bar='baz'}, {'qux', 'quux'}}`
98-- gives {'foo, 'bar', 'qux', 'quux'}
100local function top_level_fields (fields)
101 local result = List:new{}
102 for _, v in ipairs(fields) do
103 if type(v) == 'string' then
104 table.insert(result, v)
105 elseif type(v) == 'table' and #v == 0 and next(v) then
106 table.insert(result, (next(v)))
108 result:extend(top_level_fields(v))
114--- Creates a function which behaves like next, but respects field names.
116local function make_next_function (fields)
117 local field_indices = {}
118 for i, f in ipairs(fields) do
122 return function (t, field)
123 local raw_idx = field == nil and 0 or field_indices[field]
124 local next_field = fields[raw_idx + 1]
125 return next_field, t[next_field]
129--- Create a new table which allows to access numerical indices via accessor
132local function create_accessor_behavior (tag, accessors)
133 local behavior = {tag = tag}
134 behavior.getters = create_accessor_functions(
135 'function (x) return x.c%s end',
138 behavior.setters = create_accessor_functions(
139 'function (x, v) x.c%s = v end',
142 behavior.__eq = utils.equals
143 behavior.__index = function(t, k)
144 if getmetatable(t).getters[k] then
145 return getmetatable(t).getters[k](t)
147 return getmetatable(t)["tag"]
149 return getmetatable(t)[k]
152 behavior.__newindex = function(t, k, v)
153 if getmetatable(t).setters[k] then
154 getmetatable(t).setters[k](t, v)
159 behavior.__pairs = function (t)
160 if accessors == nil then
163 local iterable_fields = type(accessors) == 'string'
165 or top_level_fields(accessors)
166 return make_next_function(iterable_fields), t
172------------------------------------------------------------------------
173-- The base class for types
183 setmetatable(obj, self)
187Type.behavior.__index = Type.behavior
189--- Set a new behavior for the type, inheriting that of the parent type if none
190--- is specified explicitly
191-- @param behavior the behavior object for this type.
193function Type:set_behavior (behavior)
194 behavior = behavior or {}
195 behavior.__index = rawget(behavior, '__index') or behavior
196 behavior.__type = self
197 if not getmetatable(behavior) and getmetatable(self) then
198 setmetatable(behavior, getmetatable(self).behavior)
200 self.behavior = behavior
203--- Create a new subtype, using the given table as base.
204-- @param name name of the new type
205-- @param[opt] behavior behavioral object for the new type.
208function Type:make_subtype(name, behavior)
209 local newtype = setmetatable({}, self)
211 newtype.__index = newtype
212 newtype:set_behavior(behavior)
217------------------------------------------------------------------------
218-- The base class for pandoc's AST elements.
221local AstElement = Type:make_subtype 'AstElement'
222AstElement.__call = function(t, ...)
223 local success, ret = pcall(t.new, t, ...)
225 return setmetatable(ret, t.behavior)
227 error(string.format('Constructor for %s failed: %s\n', t.name, ret))
231--- Make a new subtype which constructs a new value when called.
233function AstElement:make_subtype(...)
234 local newtype = Type.make_subtype(self, ...)
235 newtype.__call = self.__call
239--- Create a new constructor
241-- @param tag Tag used to identify the constructor
242-- @param fn Function to be called when constructing a new element
243-- @param accessors names to use as accessors for numerical fields
244-- @return function that constructs a new element
245function AstElement:create_constructor(tag, fn, accessors)
246 local constr = self:make_subtype(tag, create_accessor_behavior(tag, accessors))
247 function constr:new(...)
248 return setmetatable(fn(...), self.behavior)
250 self.constructor = self.constructor or {}
251 self.constructor[tag] = constr
255--- Convert AstElement input into a list if necessary.
257local function ensureList (x)
259 -- Lists are not tagged, but all elements are
266--- Ensure a given object is an Inline element, or convert it into one.
268local function ensureInlineList (x)
269 if type(x) == 'string' then
270 return List:new{M.Str(x)}
276--- Ensure that the given object is a definition pair, convert if necessary.
278local function ensureDefinitionPairs (pair)
279 local inlines = ensureInlineList(pair[1] or {})
280 local blocks = ensureList(pair[2] or {}):map(ensureList)
281 return {inlines, blocks}
284--- Split a string into it's words, using whitespace as separators.
285local function words (str)
287 for w in str:gmatch("([^%s]+)") do ws[#ws + 1] = w end
291--- Try hard to turn the arguments into an Attr object.
292local function ensureAttr(attr)
293 if type(attr) == 'table' then
294 if #attr > 0 then return M.Attr(table.unpack(attr)) end
296 -- assume HTML-like key-value pairs
297 local ident = attr.id or ''
298 local classes = words(attr.class or '')
299 local attributes = attr
301 attributes.class = nil
302 return M.Attr(ident, classes, attributes)
303 elseif attr == nil then
305 elseif type(attr) == 'string' then
306 -- treat argument as ID
310 error('Could not convert to Attr')
313------------------------------------------------------------------------
317--- A complete pandoc document
319-- @tparam {Block,...} blocks document content
320-- @tparam[opt] Meta meta document meta data
321M.Pandoc = AstElement:make_subtype'Pandoc'
322M.Pandoc.behavior.clone = M.types.clone.Pandoc
323function M.Pandoc:new (blocks, meta)
325 blocks = ensureList(blocks),
330-- DEPRECATED synonym:
333------------------------------------------------------------------------
337--- Create a new Meta object. It sets the metatable of the given table to
340-- @tparam meta table table containing document meta information
341M.Meta = AstElement:make_subtype'Meta'
342M.Meta.behavior.clone = M.types.clone.Meta
343function M.Meta:new (meta) return meta end
346------------------------------------------------------------------------
349M.MetaValue = AstElement:make_subtype('MetaValue')
350M.MetaValue.behavior.clone = M.types.clone.MetaValue
353-- @function MetaBlocks
354-- @tparam {Block,...} blocks blocks
355M.MetaBlocks = M.MetaValue:create_constructor(
357 function (content) return ensureList(content) end
361-- @function MetaInlines
362-- @tparam {Inline,...} inlines inlines
363M.MetaInlines = M.MetaValue:create_constructor(
365 function (content) return ensureInlineList(content) end
370-- @tparam {MetaValue,...} meta_values list of meta values
371M.MetaList = M.MetaValue:create_constructor(
374 if content.tag == 'MetaList' then
377 return ensureList(content)
380for k, v in pairs(List) do
381 M.MetaList.behavior[k] = v
386-- @tparam table key_value_map a string-indexed map of meta values
387M.MetaMap = M.MetaValue:create_constructor(
389 function (mm) return mm end
392--- Creates string to be used in meta data.
393-- Does nothing, lua strings are meta strings.
394-- @function MetaString
395-- @tparam string str string value
396function M.MetaString(str)
400--- Creates boolean to be used in meta data.
401-- Does nothing, lua booleans are meta booleans.
403-- @tparam boolean bool boolean value
404function M.MetaBool(bool)
408------------------------------------------------------------------------
413M.Block = AstElement:make_subtype'Block'
414M.Block.behavior.clone = M.types.clone.Block
416--- Creates a block quote element
417-- @function BlockQuote
418-- @tparam {Block,...} content block content
419-- @treturn Block block quote element
420M.BlockQuote = M.Block:create_constructor(
422 function(content) return {c = ensureList(content)} end,
426--- Creates a bullet (i.e. unordered) list.
427-- @function BulletList
428-- @tparam {{Block,...},...} content list of items
429-- @treturn Block bullet list element
430M.BulletList = M.Block:create_constructor(
432 function(content) return {c = ensureList(content):map(ensureList)} end,
436--- Creates a code block element
437-- @function CodeBlock
438-- @tparam string text code string
439-- @tparam[opt] Attr attr element attributes
440-- @treturn Block code block element
441M.CodeBlock = M.Block:create_constructor(
443 function(text, attr) return {c = {ensureAttr(attr), text}} end,
444 {{attr = {"identifier", "classes", "attributes"}}, "text"}
447--- Creates a definition list, containing terms and their explanation.
448-- @function DefinitionList
449-- @tparam {{{Inline,...},{{Block,...}}},...} content list of items
450-- @treturn Block definition list element
451M.DefinitionList = M.Block:create_constructor(
454 return {c = ensureList(content):map(ensureDefinitionPairs)}
459--- Creates a div element
461-- @tparam {Block,...} content block content
462-- @tparam[opt] Attr attr element attributes
463-- @treturn Block div element
464M.Div = M.Block:create_constructor(
466 function(content, attr)
467 return {c = {ensureAttr(attr), ensureList(content)}}
469 {{attr = {"identifier", "classes", "attributes"}}, "content"}
472--- Creates a header element.
474-- @tparam int level header level
475-- @tparam {Inline,...} content inline content
476-- @tparam[opt] Attr attr element attributes
477-- @treturn Block header element
478M.Header = M.Block:create_constructor(
480 function(level, content, attr)
481 return {c = {level, ensureAttr(attr), ensureInlineList(content)}}
483 {"level", {attr = {"identifier", "classes", "attributes"}}, "content"}
486--- Creates a horizontal rule.
487-- @function HorizontalRule
488-- @treturn Block horizontal rule
489M.HorizontalRule = M.Block:create_constructor(
491 function() return {} end
494--- Creates a line block element.
495-- @function LineBlock
496-- @tparam {{Inline,...},...} content inline content
497-- @treturn Block line block element
498M.LineBlock = M.Block:create_constructor(
500 function(content) return {c = ensureList(content):map(ensureInlineList)} end,
504--- Creates a null element.
506-- @treturn Block null element
507M.Null = M.Block:create_constructor(
509 function() return {} end
512--- Creates an ordered list.
513-- @function OrderedList
514-- @tparam {{Block,...},...} items list items
515-- @param[opt] listAttributes list parameters
516-- @treturn Block ordered list element
517M.OrderedList = M.Block:create_constructor(
519 function(items, listAttributes)
520 listAttributes = listAttributes or M.ListAttributes()
521 return {c = {listAttributes, ensureList(items):map(ensureList)}}
523 {{listAttributes = {"start", "style", "delimiter"}}, "content"}
526--- Creates a para element.
528-- @tparam {Inline,...} content inline content
529-- @treturn Block paragraph element
530M.Para = M.Block:create_constructor(
532 function(content) return {c = ensureInlineList(content)} end,
536--- Creates a plain element.
538-- @tparam {Inline,...} content inline content
539-- @treturn Block plain element
540M.Plain = M.Block:create_constructor(
542 function(content) return {c = ensureInlineList(content)} end,
546--- Creates a raw content block of the specified format.
548-- @tparam string format format of content
549-- @tparam string text string content
550-- @treturn Block raw block element
551M.RawBlock = M.Block:create_constructor(
553 function(format, text) return {c = {format, text}} end,
557--- Creates a table element.
559-- @tparam Caption caption table caption
560-- @tparam {ColSpec,...} colspecs column alignments and widths
561-- @tparam TableHead head table head
562-- @tparam {TableBody,..} bodies table bodies
563-- @treturn TableFoot foot table foot
564-- @tparam[opt] Attr attr attributes
565M.Table = M.Block:create_constructor(
567 function(caption, colspecs, head, bodies, foot, attr)
579 {"attr", "caption", "colspecs", "head", "bodies", "foot"}
583------------------------------------------------------------------------
587--- Inline element class
588M.Inline = AstElement:make_subtype'Inline'
589M.Inline.behavior.clone = M.types.clone.Inline
591--- Creates a Cite inline element
593-- @tparam {Inline,...} content List of inlines
594-- @tparam {Citation,...} citations List of citations
595-- @treturn Inline citations element
596M.Cite = M.Inline:create_constructor(
598 function(content, citations)
599 return {c = {ensureList(citations), ensureInlineList(content)}}
601 {"citations", "content"}
604--- Creates a Code inline element
606-- @tparam string text code string
607-- @tparam[opt] Attr attr additional attributes
608-- @treturn Inline code element
609M.Code = M.Inline:create_constructor(
611 function(text, attr) return {c = {ensureAttr(attr), text}} end,
612 {{attr = {"identifier", "classes", "attributes"}}, "text"}
615--- Creates an inline element representing emphasised text.
617-- @tparam {Inline,..} content inline content
618-- @treturn Inline emphasis element
619M.Emph = M.Inline:create_constructor(
621 function(content) return {c = ensureInlineList(content)} end,
625--- Creates a Image inline element
627-- @tparam {Inline,..} caption text used to describe the image
628-- @tparam string src path to the image file
629-- @tparam[opt] string title brief image description
630-- @tparam[opt] Attr attr additional attributes
631-- @treturn Inline image element
632M.Image = M.Inline:create_constructor(
634 function(caption, src, title, attr)
636 return {c = {ensureAttr(attr), ensureInlineList(caption), {src, title}}}
638 {{attr = {"identifier", "classes", "attributes"}}, "caption", {"src", "title"}}
641--- Create a LineBreak inline element
642-- @function LineBreak
643-- @treturn Inline linebreak element
644M.LineBreak = M.Inline:create_constructor(
646 function() return {} end
649--- Creates a link inline element, usually a hyperlink.
651-- @tparam {Inline,..} content text for this link
652-- @tparam string target the link target
653-- @tparam[opt] string title brief link description
654-- @tparam[opt] Attr attr additional attributes
655-- @treturn Inline image element
656M.Link = M.Inline:create_constructor(
658 function(content, target, title, attr)
660 attr = ensureAttr(attr)
661 return {c = {attr, ensureInlineList(content), {target, title}}}
663 {{attr = {"identifier", "classes", "attributes"}}, "content", {"target", "title"}}
666--- Creates a Math element, either inline or displayed.
668-- @tparam "InlineMath"|"DisplayMath" mathtype rendering specifier
669-- @tparam string text Math content
670-- @treturn Inline Math element
671M.Math = M.Inline:create_constructor(
673 function(mathtype, text)
674 return {c = {mathtype, text}}
678--- Creates a DisplayMath element (DEPRECATED).
679-- @function DisplayMath
680-- @tparam string text Math content
681-- @treturn Inline Math element
682M.DisplayMath = M.Inline:create_constructor(
684 function(text) return M.Math("DisplayMath", text) end,
687--- Creates an InlineMath inline element (DEPRECATED).
688-- @function InlineMath
689-- @tparam string text Math content
690-- @treturn Inline Math element
691M.InlineMath = M.Inline:create_constructor(
693 function(text) return M.Math("InlineMath", text) end,
697--- Creates a Note inline element
699-- @tparam {Block,...} content footnote block content
700M.Note = M.Inline:create_constructor(
702 function(content) return {c = ensureList(content)} end,
706--- Creates a Quoted inline element given the quote type and quoted content.
708-- @tparam "DoubleQuote"|"SingleQuote" quotetype type of quotes to be used
709-- @tparam {Inline,..} content inline content
710-- @treturn Inline quoted element
711M.Quoted = M.Inline:create_constructor(
713 function(quotetype, content)
714 return {c = {quotetype, ensureInlineList(content)}}
716 {"quotetype", "content"}
718--- Creates a single-quoted inline element (DEPRECATED).
719-- @function SingleQuoted
720-- @tparam {Inline,..} content inline content
721-- @treturn Inline quoted element
723M.SingleQuoted = M.Inline:create_constructor(
725 function(content) return M.Quoted(M.SingleQuote, content) end,
726 {"quotetype", "content"}
728--- Creates a single-quoted inline element (DEPRECATED).
729-- @function DoubleQuoted
730-- @tparam {Inline,..} content inline content
731-- @treturn Inline quoted element
733M.DoubleQuoted = M.Inline:create_constructor(
735 function(content) return M.Quoted("DoubleQuote", content) end,
736 {"quotetype", "content"}
739--- Creates a RawInline inline element
740-- @function RawInline
741-- @tparam string format format of the contents
742-- @tparam string text string content
743-- @treturn Inline raw inline element
744M.RawInline = M.Inline:create_constructor(
746 function(format, text) return {c = {format, text}} end,
750--- Creates text rendered in small caps
751-- @function SmallCaps
752-- @tparam {Inline,..} content inline content
753-- @treturn Inline smallcaps element
754M.SmallCaps = M.Inline:create_constructor(
756 function(content) return {c = ensureInlineList(content)} end,
760--- Creates a SoftBreak inline element.
761-- @function SoftBreak
762-- @treturn Inline softbreak element
763M.SoftBreak = M.Inline:create_constructor(
765 function() return {} end
768--- Create a Space inline element
770-- @treturn Inline space element
771M.Space = M.Inline:create_constructor(
773 function() return {} end
776--- Creates a Span inline element
778-- @tparam {Inline,..} content inline content
779-- @tparam[opt] Attr attr additional attributes
780-- @treturn Inline span element
781M.Span = M.Inline:create_constructor(
783 function(content, attr)
784 return {c = {ensureAttr(attr), ensureInlineList(content)}}
786 {{attr = {"identifier", "classes", "attributes"}}, "content"}
789--- Creates a Str inline element
791-- @tparam string text content
792-- @treturn Inline string element
793M.Str = M.Inline:create_constructor(
795 function(text) return {c = text} end,
799--- Creates text which is striked out.
800-- @function Strikeout
801-- @tparam {Inline,..} content inline content
802-- @treturn Inline strikeout element
803M.Strikeout = M.Inline:create_constructor(
805 function(content) return {c = ensureInlineList(content)} end,
809--- Creates a Strong element, whose text is usually displayed in a bold font.
811-- @tparam {Inline,..} content inline content
812-- @treturn Inline strong element
813M.Strong = M.Inline:create_constructor(
815 function(content) return {c = ensureInlineList(content)} end,
819--- Creates a Subscript inline element
820-- @function Subscript
821-- @tparam {Inline,..} content inline content
822-- @treturn Inline subscript element
823M.Subscript = M.Inline:create_constructor(
825 function(content) return {c = ensureInlineList(content)} end,
829--- Creates a Superscript inline element
830-- @function Superscript
831-- @tparam {Inline,..} content inline content
832-- @treturn Inline superscript element
833M.Superscript = M.Inline:create_constructor(
835 function(content) return {c = ensureInlineList(content)} end,
839--- Creates an Underline inline element
840-- @function Underline
841-- @tparam {Inline,..} content inline content
842-- @treturn Inline underline element
843M.Underline = M.Inline:create_constructor(
845 function(content) return {c = ensureInlineList(content)} end,
850------------------------------------------------------------------------
852-- @section components
854--- Check if the first element of a pair matches the given value.
855-- @param x key value to be checked
856-- @return function returning true iff first element of its argument matches x
858local function assoc_key_equals (x)
859 return function (y) return y[1] == x end
862--- Lookup a value in an associative list
865-- @tparam {{key, value},...} alist associative list
866-- @param key key for which the associated value is to be looked up
867local function lookup(alist, key)
868 return (List.find_if(alist, assoc_key_equals(key)) or {})[2]
871--- Return an iterator which returns key-value pairs of an associative list.
874-- @tparam {{key, value},...} alist associative list
875local apairs = function (alist)
879 cur = rawget(alist, i)
882 return cur[1], cur[2]
889--- AttributeList, a metatable to allow table-like access to attribute lists
890-- represented by associative lists.
892local AttributeList = {
893 __index = function (t, k)
894 if type(k) == "number" then
901 __newindex = function (t, k, v)
902 local cur, idx = List.find_if(t, assoc_key_equals(k))
903 if v == nil and not cur then
904 -- deleted key does not exists in list
910 elseif type(k) == "number" then
913 rawset(t, #t + 1, {k, v})
920--- Convert a table to an associative list. The order of key-value pairs in the
921-- alist is undefined. The table should either contain no numeric keys or
922-- already be an associative list.
924-- @tparam table tbl associative list or table without numeric keys.
925-- @treturn table associative list
926local to_alist = function (tbl)
927 if #tbl ~= 0 or next(tbl) == nil then
928 -- probably already an alist
933 for k, v in pairs(tbl) do
942--- Create a new set of attributes (Attr).
944-- @tparam[opt] string identifier element identifier
945-- @tparam[opt] {string,...} classes element classes
946-- @tparam[opt] table attributes table containing string keys and values
947-- @return element attributes
948M.Attr = AstElement:make_subtype'Attr'
949function M.Attr:new (identifier, classes, attributes)
950 identifier = identifier or ''
951 classes = ensureList(classes or {})
952 attributes = setmetatable(to_alist(attributes or {}), AttributeList)
953 return setmetatable({identifier, classes, attributes}, self.behavior)
955M.Attr.behavior.clone = M.types.clone.Attr
956M.Attr.behavior.tag = 'Attr'
957M.Attr.behavior._field_names = {identifier = 1, classes = 2, attributes = 3}
958M.Attr.behavior.__eq = utils.equals
959M.Attr.behavior.__index = function(t, k)
960 return (k == 't' and t.tag) or
961 rawget(t, getmetatable(t)._field_names[k]) or
964M.Attr.behavior.__newindex = function(t, k, v)
965 if k == 'attributes' then
966 rawset(t, 3, setmetatable(to_alist(v or {}), AttributeList))
967 elseif getmetatable(t)._field_names[k] then
968 rawset(t, getmetatable(t)._field_names[k], v)
973M.Attr.behavior.__pairs = function(t)
974 local field_names = M.Attr.behavior._field_names
976 for name, i in pairs(field_names) do
979 return make_next_function(fields), t, nil
982-- Monkey-patch setters for `attr` fields to be more forgiving in the input that
983-- results in a valid Attr value.
984function augment_attr_setter (setters)
986 local orig = setters.attr
987 setters.attr = function(k, v)
988 orig(k, ensureAttr(v))
992for _, blk in pairs(M.Block.constructor) do
993 augment_attr_setter(blk.behavior.setters)
995for _, inln in pairs(M.Inline.constructor) do
996 augment_attr_setter(inln.behavior.setters)
1001M.Citation = AstElement:make_subtype'Citation'
1002M.Citation.behavior.clone = M.types.clone.Citation
1004--- Creates a single citation.
1005-- @function Citation
1006-- @tparam string id citation identifier (like a bibtex key)
1007-- @tparam AuthorInText|SuppressAuthor|NormalCitation mode citation mode
1008-- @tparam[opt] {Inline,...} prefix citation prefix
1009-- @tparam[opt] {Inline,...} suffix citation suffix
1010-- @tparam[opt] int note_num note number
1011-- @tparam[opt] int hash hash number
1012function M.Citation:new (id, mode, prefix, suffix, note_num, hash)
1016 prefix = ensureList(prefix or {}),
1017 suffix = ensureList(suffix or {}),
1018 note_num = note_num or 0,
1024M.ListAttributes = AstElement:make_subtype 'ListAttributes'
1025M.ListAttributes.behavior.clone = M.types.clone.ListAttributes
1027--- Creates a set of list attributes.
1028-- @function ListAttributes
1029-- @tparam[opt] integer start number of the first list item
1030-- @tparam[opt] string style style used for list numbering
1031-- @tparam[opt] DefaultDelim|Period|OneParen|TwoParens delimiter delimiter of list numbers
1032-- @treturn table list attributes table
1033function M.ListAttributes:new (start, style, delimiter)
1035 style = style or 'DefaultStyle'
1036 delimiter = delimiter or 'DefaultDelim'
1037 return {start, style, delimiter}
1039M.ListAttributes.behavior._field_names = {start = 1, style = 2, delimiter = 3}
1040M.ListAttributes.behavior.__eq = utils.equals
1041M.ListAttributes.behavior.__index = function (t, k)
1042 return rawget(t, getmetatable(t)._field_names[k]) or
1045M.ListAttributes.behavior.__newindex = function (t, k, v)
1046 if getmetatable(t)._field_names[k] then
1047 rawset(t, getmetatable(t)._field_names[k], v)
1052M.ListAttributes.behavior.__pairs = function(t)
1053 local field_names = M.ListAttributes.behavior._field_names
1055 for name, i in pairs(field_names) do
1058 return make_next_function(fields), t, nil
1062-- Legacy and compatibility types
1065--- Creates a simple (old style) table element.
1066-- @function SimpleTable
1067-- @tparam {Inline,...} caption table caption
1068-- @tparam {AlignDefault|AlignLeft|AlignRight|AlignCenter,...} aligns alignments
1069-- @tparam {int,...} widths column widths
1070-- @tparam {Block,...} headers header row
1071-- @tparam {{Block,...}} rows table rows
1072-- @treturn Block table element
1073M.SimpleTable = function(caption, aligns, widths, headers, rows)
1075 caption = ensureInlineList(caption),
1076 aligns = List:new(aligns),
1077 widths = List:new(widths),
1078 headers = List:new(headers),
1079 rows = List:new(rows),
1080 tag = "SimpleTable",
1086------------------------------------------------------------------------
1088-- @section constants
1090--- Author name is mentioned in the text.
1093M.AuthorInText = "AuthorInText"
1095--- Author name is suppressed.
1098M.SuppressAuthor = "SuppressAuthor"
1100--- Default citation style is used.
1103M.NormalCitation = "NormalCitation"
1105--- Table cells aligned left.
1107M.AlignLeft = "AlignLeft"
1109--- Table cells right-aligned.
1111M.AlignRight = "AlignRight"
1113--- Table cell content is centered.
1115M.AlignCenter = "AlignCenter"
1117--- Table cells are alignment is unaltered.
1119M.AlignDefault = "AlignDefault"
1121--- Default list number delimiters are used.
1123M.DefaultDelim = "DefaultDelim"
1125--- List numbers are delimited by a period.
1129--- List numbers are delimited by a single parenthesis.
1131M.OneParen = "OneParen"
1133--- List numbers are delimited by a double parentheses.
1135M.TwoParens = "TwoParens"
1137--- List are numbered in the default style
1139M.DefaultStyle = "DefaultStyle"
1141--- List items are numbered as examples.
1143M.Example = "Example"
1145--- List are numbered using decimal integers.
1147M.Decimal = "Decimal"
1149--- List are numbered using lower-case roman numerals.
1151M.LowerRoman = "LowerRoman"
1153--- List are numbered using upper-case roman numerals
1155M.UpperRoman = "UpperRoman"
1157--- List are numbered using lower-case alphabetic characters.
1159M.LowerAlpha = "LowerAlpha"
1161--- List are numbered using upper-case alphabetic characters.
1163M.UpperAlpha = "UpperAlpha"
1165------------------------------------------------------------------------
1166-- Functions which have moved to different modules
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list