diff options
Diffstat (limited to 'data')
-rw-r--r-- | data/pandoc.lua | 638 |
1 files changed, 602 insertions, 36 deletions
diff --git a/data/pandoc.lua b/data/pandoc.lua index d705b8566..eab565ca8 100644 --- a/data/pandoc.lua +++ b/data/pandoc.lua @@ -1,7 +1,7 @@ --[[ pandoc.lua -Copyright (c) 2017 Albert Krewinkel +Copyright © 2017 Albert Krewinkel Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice @@ -16,25 +16,87 @@ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ]] ---- The module +--- +-- Lua functions for pandoc scripts. +-- +-- @author Albert Krewinkel +-- @copyright © 2017 Albert Krewinkel +-- @license MIT local M = { - _version = "0.1.0" + _VERSION = "0.2.0" } +--- Attributes +-- @type Attributes +M.Attributes = {} +setmetatable(M.Attributes, M.Attributes) + +M.Attributes.__index = function(t, k) + if k == "id" then + return t[1] + elseif k == "class" then + return table.concat(t[2], ' ') + else + return t.kv[k] + end +end + --- Create a new set of attributes (Attr). -function M.Attributes(id, classes, key_values) - return {id, classes, key_values} +-- @function Attributes +M.Attributes.__call = function(t, key_values, id, classes) + local kv = {} + for i = 1, #key_values do + kv[key_values[i][1]] = key_values[i][2] + end + id = id or '' + classes = classes or {} + local attr = {id, classes, key_values, kv = kv} + setmetatable(attr, t) + return attr end +M.Attributes.empty = M.Attributes('', {}, {}) + +--- Creates a single citation. +-- @function Citation +-- @tparam string id citation identifier (like a bibtex key) +-- @tparam AuthorInText|SuppressAuthor|NormalCitation mode citation mode +-- @tparam[opt] {Inline,...} prefix citation prefix +-- @tparam[opt] {Inline,...} suffix citation suffix +-- @tparam[opt] int note_num note number +-- @tparam[opt] int note_num hash number +M.Citation = function(id, mode, prefix, suffix, note_num, hash) + prefix = prefix or {} + suffix = suffix or {} + note_num = note_num or 0 + hash = hash or 0 + return { + citationId = id, + citationPrefix = prefix, + citationSuffix = suffix, + citationMode = mode, + citationNoteNum = note_num, + citationHash = hash, + } +end + +------------------------------------------------------------------------ +-- The base class for pandoc's AST elements. +-- @type Element +-- @local local Element = {} + --- Create a new element subtype +-- @local function Element:make_subtype(o) o = o or {} setmetatable(o, self) self.__index = self return o end + --- Create a new element given its tag and arguments +-- @local function Element:new(tag, ...) local element = { t = tag } local content = {...} @@ -51,7 +113,48 @@ function Element:new(tag, ...) return element end -local function Doc(blocks, meta) +--- Create a new constructor +-- @local +-- @param tag Tag used to identify the constructor +-- @param fn Function to be called when constructing a new element +-- @return function that constructs a new element +function Element:create_constructor(tag, fn) + local constr = self:make_subtype({tag = tag}) + function constr:new(...) + local obj = fn(...) + setmetatable(obj, self) + self.__index = function(t, k) + if k == "c" then + return t["content"] + elseif k == "t" then + return getmetatable(t)["tag"] + else + return getmetatable(t)[k] + end + end + return obj + end + self.constructor = self.constructor or {} + self.constructor[tag] = constr + return constr +end + +--- Calls the constructor, creating a new element. +-- @local +function Element.__call(t, ...) + return t:new(...) +end + +------------------------------------------------------------------------ +--- Pandoc Document +-- @section document + +--- A complete pandoc document +-- @function Doc +-- @tparam {Block,...} blocks document content +-- @tparam[opt] Meta meta document meta data +function M.Doc(blocks, meta) + meta = meta or {} return { ["blocks"] = blocks, ["meta"] = meta, @@ -59,82 +162,545 @@ local function Doc(blocks, meta) } end -local Inline = Element:make_subtype{} -local Block = Element:make_subtype{} -M.block_types = { +------------------------------------------------------------------------ +-- MetaValue +-- @section MetaValue +M.MetaValue = Element:make_subtype{} +M.MetaValue.__call = function(t, ...) + return t:new(...) +end +--- Meta blocks +-- @function MetaBlocks +-- @tparam {Block,...} blocks blocks + +--- Meta inlines +-- @function MetaInlines +-- @tparam {Inline,...} inlines inlines + +--- Meta list +-- @function MetaList +-- @tparam {MetaValue,...} meta_values list of meta values + +--- Meta boolean +-- @function MetaBool +-- @tparam boolean bool boolean value + +--- Meta map +-- @function MetaMap +-- @tparam table a string-index map of meta values + +--- Meta string +-- @function MetaString +-- @tparam string str string value +M.meta_value_types = { + "MetaBlocks", + "MetaBool", + "MetaInlines", + "MetaList", + "MetaMap", + "MetaString" +} +for i = 1, #M.meta_value_types do + M[M.meta_value_types[i]] = M.MetaValue:create_constructor( + M.meta_value_types[i], + function(content) + return {c = content} + end + ) +end + +------------------------------------------------------------------------ +-- Block +-- @section Block + +M.Block = Element:make_subtype{} +M.Block.__call = function (t, ...) + return t:new(...) +end + +--- Creates a block quote element +-- @function BlockQuote +-- @tparam {Block,...} content block content +-- @treturn Block block quote element +M.BlockQuote = M.Block:create_constructor( "BlockQuote", + function(content) return {c = content} end +) + +--- Creates a bullet (i.e. unordered) list. +-- @function BulletList +-- @tparam {{Block,...},...} content list of items +-- @treturn Block block quote element +M.BulletList = M.Block:create_constructor( "BulletList", + function(content) return {c = content} end +) + +--- Creates a code block element +-- @function CodeBlock +-- @tparam string code code string +-- @tparam[opt] Attributes attributes element attributes +-- @treturn Block code block element +M.CodeBlock = M.Block:create_constructor( "CodeBlock", + function(code, attributes) return {c = {attributes, code}} end +) + +--- Creates a definition list, containing terms and their explanation. +-- @function DefinitionList +-- @tparam {{{Inline,...},{Block,...}},...} content list of items +-- @treturn Block block quote element +M.DefinitionList = M.Block:create_constructor( "DefinitionList", + function(content) return {c = content} end +) + +--- Creates a div element +-- @function Div +-- @tparam {Block,...} content block content +-- @tparam[opt] Attributes attributes element attributes +-- @treturn Block code block element +M.Div = M.Block:create_constructor( "Div", + function(content, attributes) return {c = {attributes, content}} end +) + +--- Creates a block quote element. +-- @function Header +-- @tparam int level header level +-- @tparam Attributes attributes element attributes +-- @tparam {Inline,...} content inline content +-- @treturn Block header element +M.Header = M.Block:create_constructor( "Header", + function(level, attributes, content) + return {c = {level, attributes, content}} + end +) + +--- Creates a horizontal rule. +-- @function HorizontalRule +-- @treturn Block horizontal rule +M.HorizontalRule = M.Block:create_constructor( "HorizontalRule", - "HorizontalRule", + function() return {} end +) + +--- Creates a line block element. +-- @function LineBlock +-- @tparam {{Inline,...},...} content inline content +-- @treturn Block block quote element +M.LineBlock = M.Block:create_constructor( "LineBlock", + function(content) return {c = content} end +) + +--- Creates a null element. +-- @function Null +-- @treturn Block null element +M.Null = M.Block:create_constructor( "Null", + function() return {} end +) + +--- Creates an ordered list. +-- @function OrderedList +-- @tparam {{Block,...},...} items list items +-- @param[opt] listAttributes list parameters +-- @treturn Block +M.OrderedList = M.Block:create_constructor( "OrderedList", + function(items, listAttributes) + return {c = {listAttributes,items}} + end +) + +--- Creates a para element. +-- @function Para +-- @tparam {Inline,...} content inline content +-- @treturn Block block quote element +M.Para = M.Block:create_constructor( "Para", + function(content) return {c = content} end +) + +--- Creates a plain element. +-- @function Plain +-- @tparam {Inline,...} content inline content +-- @treturn Block block quote element +M.Plain = M.Block:create_constructor( "Plain", + function(content) return {c = content} end +) + +--- Creates a raw content block of the specified format. +-- @function RawBlock +-- @tparam string format format of content +-- @tparam string content string content +-- @treturn Block block quote element +M.RawBlock = M.Block:create_constructor( "RawBlock", + function(format, content) return {c = {format, content}} end +) + +--- Creates a table element. +-- @function Table +-- @tparam {Inline,...} caption table caption +-- @tparam {AlignDefault|AlignLeft|AlignRight|AlignCenter,...} aligns alignments +-- @tparam {int,...} widths column widths +-- @tparam {Block,...} headers header row +-- @tparam {{Block,...}} rows table rows +-- @treturn Block block quote element +M.Table = M.Block:create_constructor( "Table", -} + function(caption, aligns, widths, headers, rows) + return {c = {caption, aligns, widths, headers, rows}} + end +) + + +------------------------------------------------------------------------ +-- Inline +-- @section Inline -M.inline_types = { +--- Inline element class +M.Inline = Element:make_subtype{} +M.Inline.__call = function (t, ...) + return t:new(...) +end + +--- Creates a Cite inline element +-- @function Cite +-- @tparam {Inline,...} content List of inlines +-- @tparam {Citation,...} citations List of citations +-- @treturn Inline citations element +M.Cite = M.Inline:create_constructor( "Cite", + function(content, citations) return {c = {citations, content}} end +) + +--- Creates a Code inline element +-- @function Code +-- @tparam string code brief image description +-- @tparam[opt] Attributes attributes additional attributes +-- @treturn Inline code element +M.Code = M.Inline:create_constructor( "Code", + function(code, attributes) return {c = {attributes, code}} end +) + +--- Creates an inline element representing emphasised text. +-- @function Emph +-- @tparam {Inline,..} content inline content +-- @treturn Inline emphasis element +M.Emph = M.Inline:create_constructor( "Emph", + function(content) return {c = content} end +) + +--- Creates a Image inline element +-- @function Image +-- @tparam {Inline,..} caption text used to describe the image +-- @tparam string src path to the image file +-- @tparam[opt] string title brief image description +-- @tparam[opt] Attributes attributes additional attributes +-- @treturn Inline image element +M.Image = M.Inline:create_constructor( "Image", + function(caption, src, title, attributes) + title = title or "" + attributes = attributes or Attribute.empty + return {c = {attributes, caption, {src, title}}} + end +) + +--- Create a LineBreak inline element +-- @function LineBreak +-- @treturn Inline linebreak element +M.LineBreak = M.Inline:create_constructor( "LineBreak", + function() return {} end +) + +--- Creates a link inline element, usually a hyperlink. +-- @function Link +-- @tparam {Inline,..} content text for this link +-- @tparam string target the link target +-- @tparam[opt] string title brief link description +-- @tparam[opt] Attributes attributes additional attributes +-- @treturn Inline image element +M.Link = M.Inline:create_constructor( "Link", + function(content, target, title, attributes) + title = title or "" + attributes = attributes or Attribute.empty + return {c = {attributes, content, {target, title}}} + end +) + +--- Creates a Math inline element +-- @function Math +-- @tparam InlineMath|DisplayMath mathtype Display specifier +-- @tparam string text Math content +-- @treturn Inline Math element +M.Math = M.Inline:create_constructor( "Math", + function(mathtype, text) + return {c = {mathtype, text}} + end +) + +--- Creates a Note inline element +-- @function Note +-- @tparam {Block,...} content footnote block content +M.Note = M.Inline:create_constructor( "Note", + function(contents) return {c = contents} end +) + +--- Creates a Quoted inline element +-- @function Quoted +-- @tparam DoubleQuote|SingleQuote quotetype type of quotes to be used +-- @tparam {Inline,..} content inline content +-- @treturn Inline quoted element +M.Quoted = M.Inline:create_constructor( "Quoted", + function(quotetype, content) return {c = {quotetype, content}} end +) +--- Creates a RawInline inline element +-- @function RawInline +-- @tparam string format format of the contents +-- @tparam string text string content +-- @treturn Inline raw inline element +M.RawInline = M.Inline:create_constructor( "RawInline", + function(format, text) return {c = {format, text}} end +) + +--- Creates text rendered in small caps +-- @function SmallCaps +-- @tparam {Inline,..} content inline content +-- @treturn Inline smallcaps element +M.SmallCaps = M.Inline:create_constructor( "SmallCaps", + function(content) return {c = content} end +) + +--- Creates a SoftBreak inline element. +-- @function SoftBreak +-- @treturn Inline softbreak element +M.SoftBreak = M.Inline:create_constructor( "SoftBreak", + function() return {} end +) + +--- Create a Space inline element +-- @function Space +-- @treturn Inline space element +M.Space = M.Inline:create_constructor( "Space", + function() return {} end +) + +--- Creates a Span inline element +-- @function Span +-- @tparam {Inline,..} content inline content +-- @tparam[opt] Attributes attributes additional attributes +-- @treturn Inline span element +M.Span = M.Inline:create_constructor( "Span", + function(content, attributes) return {c = {attributes, content}} end +) + +--- Creates a Str inline element +-- @function Str +-- @tparam string text content +-- @treturn Inline string element +M.Str = M.Inline:create_constructor( "Str", + function(text) return {c = text} end +) + +--- Creates text which is striked out. +-- @function Strikeout +-- @tparam {Inline,..} content inline content +-- @treturn Inline strikeout element +M.Strikeout = M.Inline:create_constructor( "Strikeout", + function(content) return {c = content} end +) + +--- Creates a Strong element, whose text is usually displayed in a bold font. +-- @function Strong +-- @tparam {Inline,..} content inline content +-- @treturn Inline strong element +M.Strong = M.Inline:create_constructor( "Strong", + function(content) return {c = content} end +) + +--- Creates a Subscript inline element +-- @function Subscript +-- @tparam {Inline,..} content inline content +-- @treturn Inline subscript element +M.Subscript = M.Inline:create_constructor( "Subscript", - "Superscript" -} + function(content) return {c = content} end +) -for _, block_type in pairs(M.block_types) do - M[block_type] = function(...) - return Block:new(block_type, ...) - end -end +--- Creates a Superscript inline element +-- @function Superscript +-- @tparam {Inline,..} content inline content +-- @treturn Inline strong element +M.Superscript = M.Inline:create_constructor( + "Superscript", + function(content) return {c = content} end +) -for _, inline_type in pairs(M.inline_types) do - M[inline_type] = function(...) - return Inline:new(inline_type, ...) - end -end ---- Arrays to provide fast lookup of element types -local set_of_inline_types = {} -local set_of_block_types = {} +------------------------------------------------------------------------ +-- Constants +-- @section constants -for i = 1, #M.inline_types do - set_of_inline_types[M.inline_types[i]] = true -end -for i = 1, #M.block_types do - set_of_block_types[M.block_types[i]] = true -end +--- Math content is to be displayed on a separate line. +-- @see Math +M.DisplayMath = {} +M.DisplayMath.t = "DisplayMath" +--- Math content is to be displayed inline within the paragraph +-- @see Math +M.InlineMath = {} +M.InlineMath.t = "InlineMath" + +--- Double quoted content. +-- @see Quoted +M.DoubleQuote = {} +M.DoubleQuote.t = "DoubleQuote" + +--- Single quoted content. +-- @see Quoted +M.SingleQuote = {} +M.SingleQuote.t = "SingleQuote" + +--- Author name is mentioned in the text. +-- @see Citation +-- @see Cite +M.AuthorInText = {} +M.AuthorInText.t = "AuthorInText" + +--- Author name is suppressed. +-- @see Citation +-- @see Cite +M.SuppressAuthor = {} +M.SuppressAuthor.t = "SuppressAuthor" + +--- Default citation style is used. +-- @see Citation +-- @see Cite +M.NormalCitation = {} +M.NormalCitation.t = "NormalCitation" + +--- Table cells aligned left. +-- @see Table +M.AlignLeft = {} +M.AlignLeft.t = "AlignLeft" + +--- Table cells right-aligned. +-- @see Table +M.AlignRight = {} +M.AlignRight.t = "AlignRight" + +--- Table cell content is centered. +-- @see Table +M.AlignCenter = {} +M.AlignCenter.t = "AlignCenter" + +--- Table cells are alignment is unaltered. +-- @see Table +M.AlignDefault = {} +M.AlignDefault.t = "AlignDefault" + +--- Default list number delimiters are used. +-- @see OrderedList +M.DefaultDelim = {} +M.DefaultDelim.t = "DefaultDelim" + +--- List numbers are delimited by a period. +-- @see OrderedList +M.Period = {} +M.Period.t = "Period" +--- List numbers are delimited by a single parenthesis. +-- @see OrderedList +M.OneParen = {} +M.OneParen.t = "OneParen" + +--- List numbers are delimited by a double parentheses. +-- @see OrderedList +M.TwoParens = {} +M.TwoParens.t = "TwoParens" + +--- List are numbered in the default style +-- @see OrderedList +M.DefaultStyle = {} +M.DefaultStyle.t = "DefaultStyle" + +--- List items are numbered as examples. +-- @see OrderedList +M.Example = {} +M.Example.t = "Example" + +--- List are numbered using decimal integers. +-- @see OrderedList +M.Decimal = {} +M.Decimal.t = "Decimal" + +--- List are numbered using lower-case roman numerals. +-- @see OrderedList +M.LowerRoman = {} +M.LowerRoman.t = "LowerRoman" + +--- List are numbered using upper-case roman numerals +-- @see OrderedList +M.UpperRoman = {} +M.UpperRoman.t = "UpperRoman" + +--- List are numbered using lower-case alphabetic characters. +-- @see OrderedList +M.LowerAlpha = {} +M.LowerAlpha.t = "LowerAlpha" + +--- List are numbered using upper-case alphabetic characters. +-- @see OrderedList +M.UpperAlpha = {} +M.UpperAlpha.t = "UpperAlpha" + + +------------------------------------------------------------------------ +-- Helper Functions +-- @section helpers + +--- Use functions defined in the global namespace to create a pandoc filter. +-- All globally defined functions which have names of pandoc elements are +-- collected into a new table. +-- @return A list of filter functions +-- @usage +-- -- within a file defining a pandoc filter: +-- function Str(text) +-- return pandoc.Str(utf8.upper(text)) +-- end +-- +-- return {pandoc.global_filter()} +-- -- the above is equivallent to +-- -- return {{Str = Str}} function M.global_filter() local res = {} for k, v in pairs(_G) do - if set_of_inline_types[k] or set_of_block_types[k] or k == "Doc" then + if M.Inline.constructor[k] or M.Block.constructor[k] or M.Block.constructors[k] or k == "Doc" then res[k] = v end end return res end -M["Doc"] = Doc - return M |