From a493c7029cf2bc8490d96fff04b0a0c624987601 Mon Sep 17 00:00:00 2001 From: Albert Krewinkel Date: Tue, 26 Oct 2021 14:40:10 +0200 Subject: Lua: marshal Block values as userdata objects Properties of Block values are marshalled lazily, which generally improves performance considerably. Script users may also notice the following differences: - Block element properties can no longer be accessed by numerical indexing of the `.c` field. The `.c` property now serves as an alias for `.content`, so some filter that used this undocumented method for property access may continue to work, while others will need to be updated and use proper property names. - The marshalled Block elements now have a `show` method, and a `__tostring` metamethod. Both return the Haskell string representation of the element. - Block values now have the Lua type `userdata` instead of `table`. --- data/pandoc.lua | 205 -------------------------------------------------------- 1 file changed, 205 deletions(-) (limited to 'data') diff --git a/data/pandoc.lua b/data/pandoc.lua index 47343b28c..a20ce1e8c 100644 --- a/data/pandoc.lua +++ b/data/pandoc.lua @@ -273,22 +273,6 @@ local function ensureInlineList (x) end end ---- Ensure that the given object is a definition pair, convert if necessary. --- @local -local function ensureDefinitionPairs (pair) - local inlines = ensureInlineList(pair[1] or {}) - local blocks = ensureList(pair[2] or {}):map(ensureList) - return {inlines, blocks} -end - ---- Try hard to turn the arguments into an Attr object. -local function ensureAttr(attr) - if type(attr) == 'userdata' then - return attr - end - return M.Attr(attr) -end - ------------------------------------------------------------------------ -- Meta -- @section Meta @@ -364,199 +348,10 @@ function M.MetaBool(bool) return bool end ------------------------------------------------------------------------- --- Blocks --- @section Block - ---- Block elements -M.Block = AstElement:make_subtype'Block' -M.Block.behavior.clone = M.types.clone.Block - ---- 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 = ensureList(content)} end, - "content" -) - ---- Creates a bullet (i.e. unordered) list. --- @function BulletList --- @tparam {{Block,...},...} content list of items --- @treturn Block bullet list element -M.BulletList = M.Block:create_constructor( - "BulletList", - function(content) return {c = ensureList(content):map(ensureList)} end, - "content" -) - ---- Creates a code block element --- @function CodeBlock --- @tparam string text code string --- @tparam[opt] Attr attr element attributes --- @treturn Block code block element -M.CodeBlock = M.Block:create_constructor( - "CodeBlock", - function(text, attr) return {c = {ensureAttr(attr), text}} end, - {{attr = {"identifier", "classes", "attributes"}}, "text"} -) - ---- Creates a definition list, containing terms and their explanation. --- @function DefinitionList --- @tparam {{{Inline,...},{{Block,...}}},...} content list of items --- @treturn Block definition list element -M.DefinitionList = M.Block:create_constructor( - "DefinitionList", - function(content) - return {c = ensureList(content):map(ensureDefinitionPairs)} - end, - "content" -) - ---- Creates a div element --- @function Div --- @tparam {Block,...} content block content --- @tparam[opt] Attr attr element attributes --- @treturn Block div element -M.Div = M.Block:create_constructor( - "Div", - function(content, attr) - return {c = {ensureAttr(attr), ensureList(content)}} - end, - {{attr = {"identifier", "classes", "attributes"}}, "content"} -) - ---- Creates a header element. --- @function Header --- @tparam int level header level --- @tparam {Inline,...} content inline content --- @tparam[opt] Attr attr element attributes --- @treturn Block header element -M.Header = M.Block:create_constructor( - "Header", - function(level, content, attr) - return {c = {level, ensureAttr(attr), ensureInlineList(content)}} - end, - {"level", {attr = {"identifier", "classes", "attributes"}}, "content"} -) - ---- Creates a horizontal rule. --- @function HorizontalRule --- @treturn Block horizontal rule -M.HorizontalRule = M.Block:create_constructor( - "HorizontalRule", - function() return {} end -) - ---- Creates a line block element. --- @function LineBlock --- @tparam {{Inline,...},...} content inline content --- @treturn Block line block element -M.LineBlock = M.Block:create_constructor( - "LineBlock", - function(content) return {c = ensureList(content):map(ensureInlineList)} end, - "content" -) - ---- 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 ordered list element -M.OrderedList = M.Block:create_constructor( - "OrderedList", - function(items, listAttributes) - listAttributes = listAttributes or M.ListAttributes() - return {c = {listAttributes, ensureList(items):map(ensureList)}} - end, - {{listAttributes = {"start", "style", "delimiter"}}, "content"} -) - ---- Creates a para element. --- @function Para --- @tparam {Inline,...} content inline content --- @treturn Block paragraph element -M.Para = M.Block:create_constructor( - "Para", - function(content) return {c = ensureInlineList(content)} end, - "content" -) - ---- Creates a plain element. --- @function Plain --- @tparam {Inline,...} content inline content --- @treturn Block plain element -M.Plain = M.Block:create_constructor( - "Plain", - function(content) return {c = ensureInlineList(content)} end, - "content" -) - ---- Creates a raw content block of the specified format. --- @function RawBlock --- @tparam string format format of content --- @tparam string text string content --- @treturn Block raw block element -M.RawBlock = M.Block:create_constructor( - "RawBlock", - function(format, text) return {c = {format, text}} end, - {"format", "text"} -) - ---- Creates a table element. --- @function Table --- @tparam Caption caption table caption --- @tparam {ColSpec,...} colspecs column alignments and widths --- @tparam TableHead head table head --- @tparam {TableBody,..} bodies table bodies --- @treturn TableFoot foot table foot --- @tparam[opt] Attr attr attributes -M.Table = M.Block:create_constructor( - "Table", - function(caption, colspecs, head, bodies, foot, attr) - return { - c = { - ensureAttr(attr), - caption, - List:new(colspecs), - head, - List:new(bodies), - foot - } - } - end, - {"attr", "caption", "colspecs", "head", "bodies", "foot"} -) - - ------------------------------------------------------------------------ -- Element components -- @section components --- Monkey-patch setters for `attr` fields to be more forgiving in the input that --- results in a valid Attr value. -function augment_attr_setter (setters) - if setters.attr then - local orig = setters.attr - setters.attr = function(k, v) - orig(k, ensureAttr(v)) - end - end -end -for _, blk in pairs(M.Block.constructor) do - augment_attr_setter(blk.behavior.setters) -end - -- ListAttributes M.ListAttributes = AstElement:make_subtype 'ListAttributes' M.ListAttributes.behavior.clone = M.types.clone.ListAttributes -- cgit v1.2.3