Lua module: provide accessors to element properties

This commit is contained in:
Albert Krewinkel 2017-04-15 20:00:35 +02:00
parent 629c6494a5
commit 291e4f39e8
No known key found for this signature in database
GPG key ID: 388DC0B21F631124

View file

@ -64,20 +64,58 @@ end
-- @param tag Tag used to identify the constructor -- @param tag Tag used to identify the constructor
-- @param fn Function to be called when constructing a new element -- @param fn Function to be called when constructing a new element
-- @return function that constructs a new element -- @return function that constructs a new element
function Element:create_constructor(tag, fn) function Element:create_constructor(tag, fn, accessors)
local constr = self:make_subtype({tag = tag}) local constr = self:make_subtype({tag = tag, getters = {}, setters = {}})
-- Add accessors to the metatable
if type(accessors) == "string" then
constr.getters[accessors] = function(elem)
return elem.c
end
constr.setters[accessors] = function(elem, v)
elem.c = v
end
else
for i = 1, #(accessors or {}) do
if type(accessors[i]) == "string" then
constr.getters[accessors[i]] = function(elem)
return elem.c[i]
end
constr.setters[accessors[i]] = function(elem, v)
elem.c[i] = v
end
else -- only two levels of nesting are supported
for k, v in ipairs(accessors[i]) do
constr.getters[v] = function(elem)
return elem.c[i][k]
end
constr.setters[v] = function(elem, v)
elem.c[i][k] = v
end
end
end
end
end
function constr:new(...) function constr:new(...)
local obj = fn(...) local obj = fn(...)
setmetatable(obj, self) setmetatable(obj, self)
self.__index = function(t, k) self.__index = function(t, k)
if k == "c" then if getmetatable(t).getters[k] then
return t["content"] return getmetatable(t).getters[k](t)
elseif k == "t" then elseif k == "t" then
return getmetatable(t)["tag"] return getmetatable(t)["tag"]
else else
return getmetatable(t)[k] return getmetatable(t)[k]
end end
end end
self.__newindex = function(t, k, v)
if getmetatable(t).setters[k] then
getmetatable(t).setters[k](t, v)
else
rawset(t, k, v)
end
end
return obj return obj
end end
self.constructor = self.constructor or {} self.constructor = self.constructor or {}
@ -152,7 +190,8 @@ for i = 1, #M.meta_value_types do
M.meta_value_types[i], M.meta_value_types[i],
function(content) function(content)
return {c = content} return {c = content}
end end,
"content"
) )
end end
@ -172,7 +211,8 @@ end
-- @treturn Block block quote element -- @treturn Block block quote element
M.BlockQuote = M.Block:create_constructor( M.BlockQuote = M.Block:create_constructor(
"BlockQuote", "BlockQuote",
function(content) return {c = content} end function(content) return {c = content} end,
"content"
) )
--- Creates a bullet (i.e. unordered) list. --- Creates a bullet (i.e. unordered) list.
@ -181,17 +221,19 @@ M.BlockQuote = M.Block:create_constructor(
-- @treturn Block block quote element -- @treturn Block block quote element
M.BulletList = M.Block:create_constructor( M.BulletList = M.Block:create_constructor(
"BulletList", "BulletList",
function(content) return {c = content} end function(content) return {c = content} end,
"content"
) )
--- Creates a code block element --- Creates a code block element
-- @function CodeBlock -- @function CodeBlock
-- @tparam string code code string -- @tparam string text code string
-- @tparam[opt] Attributes attributes element attributes -- @tparam[opt] Attributes attributes element attributes
-- @treturn Block code block element -- @treturn Block code block element
M.CodeBlock = M.Block:create_constructor( M.CodeBlock = M.Block:create_constructor(
"CodeBlock", "CodeBlock",
function(code, attributes) return {c = {attributes, code}} end function(text, attributes) return {c = {attributes, text}} end,
{{"identifier", "classes", "attributes"}, "text"}
) )
--- Creates a definition list, containing terms and their explanation. --- Creates a definition list, containing terms and their explanation.
@ -200,7 +242,8 @@ M.CodeBlock = M.Block:create_constructor(
-- @treturn Block block quote element -- @treturn Block block quote element
M.DefinitionList = M.Block:create_constructor( M.DefinitionList = M.Block:create_constructor(
"DefinitionList", "DefinitionList",
function(content) return {c = content} end function(content) return {c = content} end,
"content"
) )
--- Creates a div element --- Creates a div element
@ -210,7 +253,8 @@ M.DefinitionList = M.Block:create_constructor(
-- @treturn Block code block element -- @treturn Block code block element
M.Div = M.Block:create_constructor( M.Div = M.Block:create_constructor(
"Div", "Div",
function(content, attributes) return {c = {attributes, content}} end function(content, attributes) return {c = {attributes, content}} end,
{{"identifier", "classes", "attributes"}, "content"}
) )
--- Creates a block quote element. --- Creates a block quote element.
@ -223,7 +267,8 @@ M.Header = M.Block:create_constructor(
"Header", "Header",
function(level, attributes, content) function(level, attributes, content)
return {c = {level, attributes, content}} return {c = {level, attributes, content}}
end end,
{"level", {"identifier", "classes", "attributes"}, "content"}
) )
--- Creates a horizontal rule. --- Creates a horizontal rule.
@ -240,7 +285,8 @@ M.HorizontalRule = M.Block:create_constructor(
-- @treturn Block block quote element -- @treturn Block block quote element
M.LineBlock = M.Block:create_constructor( M.LineBlock = M.Block:create_constructor(
"LineBlock", "LineBlock",
function(content) return {c = content} end function(content) return {c = content} end,
"content"
) )
--- Creates a null element. --- Creates a null element.
@ -260,7 +306,8 @@ M.OrderedList = M.Block:create_constructor(
"OrderedList", "OrderedList",
function(items, listAttributes) function(items, listAttributes)
return {c = {listAttributes,items}} return {c = {listAttributes,items}}
end end,
{{"start", "style", "delimiter"}, "content"}
) )
--- Creates a para element. --- Creates a para element.
@ -269,7 +316,8 @@ M.OrderedList = M.Block:create_constructor(
-- @treturn Block block quote element -- @treturn Block block quote element
M.Para = M.Block:create_constructor( M.Para = M.Block:create_constructor(
"Para", "Para",
function(content) return {c = content} end function(content) return {c = content} end,
"content"
) )
--- Creates a plain element. --- Creates a plain element.
@ -278,17 +326,19 @@ M.Para = M.Block:create_constructor(
-- @treturn Block block quote element -- @treturn Block block quote element
M.Plain = M.Block:create_constructor( M.Plain = M.Block:create_constructor(
"Plain", "Plain",
function(content) return {c = content} end function(content) return {c = content} end,
"content"
) )
--- Creates a raw content block of the specified format. --- Creates a raw content block of the specified format.
-- @function RawBlock -- @function RawBlock
-- @tparam string format format of content -- @tparam string format format of content
-- @tparam string content string content -- @tparam string text string content
-- @treturn Block block quote element -- @treturn Block block quote element
M.RawBlock = M.Block:create_constructor( M.RawBlock = M.Block:create_constructor(
"RawBlock", "RawBlock",
function(format, content) return {c = {format, content}} end function(format, text) return {c = {format, text}} end,
{"format", "text"}
) )
--- Creates a table element. --- Creates a table element.
@ -324,17 +374,19 @@ end
-- @treturn Inline citations element -- @treturn Inline citations element
M.Cite = M.Inline:create_constructor( M.Cite = M.Inline:create_constructor(
"Cite", "Cite",
function(content, citations) return {c = {citations, content}} end function(content, citations) return {c = {citations, content}} end,
{"citations", "content"}
) )
--- Creates a Code inline element --- Creates a Code inline element
-- @function Code -- @function Code
-- @tparam string code brief image description -- @tparam string text brief image description
-- @tparam[opt] Attributes attributes additional attributes -- @tparam[opt] Attributes attributes additional attributes
-- @treturn Inline code element -- @treturn Inline code element
M.Code = M.Inline:create_constructor( M.Code = M.Inline:create_constructor(
"Code", "Code",
function(code, attributes) return {c = {attributes, code}} end function(text, attributes) return {c = {attributes, text}} end,
{{"identifier", "classes", "attributes"}, "text"}
) )
--- Creates an inline element representing emphasised text. --- Creates an inline element representing emphasised text.
@ -343,7 +395,8 @@ M.Code = M.Inline:create_constructor(
-- @treturn Inline emphasis element -- @treturn Inline emphasis element
M.Emph = M.Inline:create_constructor( M.Emph = M.Inline:create_constructor(
"Emph", "Emph",
function(content) return {c = content} end function(content) return {c = content} end,
"content"
) )
--- Creates a Image inline element --- Creates a Image inline element
@ -359,7 +412,8 @@ M.Image = M.Inline:create_constructor(
title = title or "" title = title or ""
attributes = attributes or Attribute.empty attributes = attributes or Attribute.empty
return {c = {attributes, caption, {src, title}}} return {c = {attributes, caption, {src, title}}}
end end,
{"attributes", "caption", {"src", "title"}}
) )
--- Create a LineBreak inline element --- Create a LineBreak inline element
@ -383,7 +437,8 @@ M.Link = M.Inline:create_constructor(
title = title or "" title = title or ""
attributes = attributes or Attribute.empty attributes = attributes or Attribute.empty
return {c = {attributes, content, {target, title}}} return {c = {attributes, content, {target, title}}}
end end,
{"attributes", "content", {"target", "title"}}
) )
--- Creates a Math element, either inline or displayed. It is usually simpler to --- Creates a Math element, either inline or displayed. It is usually simpler to
@ -396,7 +451,8 @@ M.Math = M.Inline:create_constructor(
"Math", "Math",
function(mathtype, text) function(mathtype, text)
return {c = {mathtype, text}} return {c = {mathtype, text}}
end end,
{"mathtype", "text"}
) )
--- Creates a DisplayMath element. --- Creates a DisplayMath element.
-- @function DisplayMath -- @function DisplayMath
@ -404,7 +460,8 @@ M.Math = M.Inline:create_constructor(
-- @treturn Inline Math element -- @treturn Inline Math element
M.DisplayMath = M.Inline:create_constructor( M.DisplayMath = M.Inline:create_constructor(
"DisplayMath", "DisplayMath",
function(text) return M.Math("DisplayMath", text) end function(text) return M.Math("DisplayMath", text) end,
{"mathtype", "text"}
) )
--- Creates an InlineMath inline element. --- Creates an InlineMath inline element.
-- @function InlineMath -- @function InlineMath
@ -412,7 +469,8 @@ M.DisplayMath = M.Inline:create_constructor(
-- @treturn Inline Math element -- @treturn Inline Math element
M.InlineMath = M.Inline:create_constructor( M.InlineMath = M.Inline:create_constructor(
"InlineMath", "InlineMath",
function(text) return M.Math("InlineMath", text) end function(text) return M.Math("InlineMath", text) end,
{"mathtype", "text"}
) )
--- Creates a Note inline element --- Creates a Note inline element
@ -420,7 +478,8 @@ M.InlineMath = M.Inline:create_constructor(
-- @tparam {Block,...} content footnote block content -- @tparam {Block,...} content footnote block content
M.Note = M.Inline:create_constructor( M.Note = M.Inline:create_constructor(
"Note", "Note",
function(contents) return {c = contents} end function(content) return {c = content} end,
"content"
) )
--- Creates a Quoted inline element given the quote type and quoted content. It --- Creates a Quoted inline element given the quote type and quoted content. It
@ -432,7 +491,8 @@ M.Note = M.Inline:create_constructor(
-- @treturn Inline quoted element -- @treturn Inline quoted element
M.Quoted = M.Inline:create_constructor( M.Quoted = M.Inline:create_constructor(
"Quoted", "Quoted",
function(quotetype, content) return {c = {quotetype, content}} end function(quotetype, content) return {c = {quotetype, content}} end,
{"quotetype", "content"}
) )
--- Creates a single-quoted inline element. --- Creates a single-quoted inline element.
-- @function SingleQuoted -- @function SingleQuoted
@ -441,7 +501,8 @@ M.Quoted = M.Inline:create_constructor(
-- @see Quoted -- @see Quoted
M.SingleQuoted = M.Inline:create_constructor( M.SingleQuoted = M.Inline:create_constructor(
"SingleQuoted", "SingleQuoted",
function(content) return M.Quoted(M.SingleQuote, content) end function(content) return M.Quoted(M.SingleQuote, content) end,
{"quotetype", "content"}
) )
--- Creates a single-quoted inline element. --- Creates a single-quoted inline element.
-- @function DoubleQuoted -- @function DoubleQuoted
@ -450,7 +511,8 @@ M.SingleQuoted = M.Inline:create_constructor(
-- @see Quoted -- @see Quoted
M.DoubleQuoted = M.Inline:create_constructor( M.DoubleQuoted = M.Inline:create_constructor(
"DoubleQuoted", "DoubleQuoted",
function(content) return M.Quoted("DoubleQuote", content) end function(content) return M.Quoted("DoubleQuote", content) end,
{"quotetype", "content"}
) )
--- Creates a RawInline inline element --- Creates a RawInline inline element
@ -460,7 +522,8 @@ M.DoubleQuoted = M.Inline:create_constructor(
-- @treturn Inline raw inline element -- @treturn Inline raw inline element
M.RawInline = M.Inline:create_constructor( M.RawInline = M.Inline:create_constructor(
"RawInline", "RawInline",
function(format, text) return {c = {format, text}} end function(format, text) return {c = {format, text}} end,
{"format", "text"}
) )
--- Creates text rendered in small caps --- Creates text rendered in small caps
@ -469,7 +532,8 @@ M.RawInline = M.Inline:create_constructor(
-- @treturn Inline smallcaps element -- @treturn Inline smallcaps element
M.SmallCaps = M.Inline:create_constructor( M.SmallCaps = M.Inline:create_constructor(
"SmallCaps", "SmallCaps",
function(content) return {c = content} end function(content) return {c = content} end,
"content"
) )
--- Creates a SoftBreak inline element. --- Creates a SoftBreak inline element.
@ -495,7 +559,8 @@ M.Space = M.Inline:create_constructor(
-- @treturn Inline span element -- @treturn Inline span element
M.Span = M.Inline:create_constructor( M.Span = M.Inline:create_constructor(
"Span", "Span",
function(content, attributes) return {c = {attributes, content}} end function(content, attributes) return {c = {attributes, content}} end,
{{"identifier", "classes", "attributes"}, "content"}
) )
--- Creates a Str inline element --- Creates a Str inline element
@ -504,7 +569,8 @@ M.Span = M.Inline:create_constructor(
-- @treturn Inline string element -- @treturn Inline string element
M.Str = M.Inline:create_constructor( M.Str = M.Inline:create_constructor(
"Str", "Str",
function(text) return {c = text} end function(text) return {c = text} end,
"text"
) )
--- Creates text which is striked out. --- Creates text which is striked out.
@ -513,7 +579,8 @@ M.Str = M.Inline:create_constructor(
-- @treturn Inline strikeout element -- @treturn Inline strikeout element
M.Strikeout = M.Inline:create_constructor( M.Strikeout = M.Inline:create_constructor(
"Strikeout", "Strikeout",
function(content) return {c = content} end function(content) return {c = content} end,
"content"
) )
--- Creates a Strong element, whose text is usually displayed in a bold font. --- Creates a Strong element, whose text is usually displayed in a bold font.
@ -522,7 +589,8 @@ M.Strikeout = M.Inline:create_constructor(
-- @treturn Inline strong element -- @treturn Inline strong element
M.Strong = M.Inline:create_constructor( M.Strong = M.Inline:create_constructor(
"Strong", "Strong",
function(content) return {c = content} end function(content) return {c = content} end,
"content"
) )
--- Creates a Subscript inline element --- Creates a Subscript inline element
@ -531,7 +599,8 @@ M.Strong = M.Inline:create_constructor(
-- @treturn Inline subscript element -- @treturn Inline subscript element
M.Subscript = M.Inline:create_constructor( M.Subscript = M.Inline:create_constructor(
"Subscript", "Subscript",
function(content) return {c = content} end function(content) return {c = content} end,
"content"
) )
--- Creates a Superscript inline element --- Creates a Superscript inline element
@ -540,7 +609,8 @@ M.Subscript = M.Inline:create_constructor(
-- @treturn Inline strong element -- @treturn Inline strong element
M.Superscript = M.Inline:create_constructor( M.Superscript = M.Inline:create_constructor(
"Superscript", "Superscript",
function(content) return {c = content} end function(content) return {c = content} end,
"content"
) )