@@ -265,59 +265,69 @@ local function get_type(v)
265265 return pandoc_type
266266end
267267
268- local function as_inlines (v )
269- if v == nil then
270- return pandoc .Inlines ({})
271- end
272- local t = pandoc .utils .type (v )
273- if t == " Inlines" then
274- --- @cast v pandoc.Inlines
275- return v
276- elseif t == " Blocks" then
277- return pandoc .utils .blocks_to_inlines (v )
278- elseif t == " Inline" then
279- return pandoc .Inlines ({v })
280- elseif t == " Block" then
281- return pandoc .utils .blocks_to_inlines ({v })
282- end
283-
284- if type (v ) == " table" then
285- local result = pandoc .Inlines ({})
286- for i , v in ipairs (v ) do
287- tappend (result , as_inlines (v ))
288- end
289- return result
290- end
291-
292- -- luacov: disable
293- fatal (" as_inlines: invalid type " .. t )
294- return pandoc .Inlines ({})
295- -- luacov: enable
296- end
268+ --- Blocks metatable
269+ local BlocksMT = getmetatable (pandoc .Blocks {})
270+ --- Inlines metatable
271+ local InlinesMT = getmetatable (pandoc .Inlines {})
297272
298- local function as_blocks ( v )
299- if v == nil then
300- return pandoc .Blocks ({})
301- end
302- local t = pandoc . utils . type ( v )
303- if t == " Blocks " then
304- return v
305- elseif t == " Inlines " then
306- return pandoc .Blocks ({ pandoc . Plain ( v )} )
307- elseif t == " Block " then
308- return pandoc . Blocks ({ v })
273+ --- Turns the given object into a `Inlines` list.
274+ --
275+ -- Works mostly like ` pandoc.Inlines`, but doesn't a do a full
276+ -- unmarshal/marshal roundtrip. This buys performance, at the cost of
277+ -- less thorough type checks.
278+ --
279+ -- NOTE: The input object might be modified *destructively*!
280+ local function as_inlines ( obj )
281+ local pt = pandoc .utils . type ( obj )
282+ if pt == ' Inlines ' then
283+ return obj
309284 elseif t == " Inline" then
310- return pandoc .Blocks ({pandoc .Plain (v )})
285+ -- Faster than calling pandoc.Inlines
286+ return setmetatable ({obj }, InlinesMT )
287+ elseif pt == ' List' or pt == ' table' then
288+ -- Faster than calling pandoc.Inlines
289+ return setmetatable (obj , InlinesMT )
290+ elseif pt == " Block" then
291+ return pandoc .utils .blocks_to_inlines ({obj })
292+ elseif pt == " Blocks" then
293+ return pandoc .utils .blocks_to_inlines (v )
294+ else
295+ return pandoc .Inlines (obj or {})
311296 end
297+ end
312298
313- if type (v ) == " table" then
314- return pandoc .Blocks (v )
299+ --- Turns the given object into a `Blocks` list.
300+ --
301+ -- Works mostly like `pandoc.Blocks`, but doesn't a do a full
302+ -- unmarshal/marshal roundtrip. This buys performance, at the cost of
303+ -- less thorough type checks.
304+ --
305+ -- NOTE: The input object might be modified *destructively*!
306+ --
307+ -- This might need some benchmarking.
308+ local function as_blocks (obj )
309+ local pt = pandoc .utils .type (obj )
310+ if pt == ' Blocks' then
311+ return obj
312+ elseif pt == ' Block' then
313+ return setmetatable ({obj }, BlocksMT )
314+ elseif pt == ' Inline' then
315+ return setmetatable ({pandoc .Plain {pt }}, BlocksMT )
316+ elseif pt == ' Inlines' then
317+ return setmetatable ({pandoc .Plain (pt )}, BlocksMT )
318+ elseif pt == ' List' or (pt == ' table' and obj [1 ]) then
319+ -- Assigning a metatable directly is faster than calling
320+ -- `pandoc.Blocks`.
321+ if pandoc .utils .type (obj [1 ]) == ' Inline' then
322+ obj = {pandoc .Plain (obj )}
323+ end
324+ return setmetatable (obj , BlocksMT )
325+ elseif (pt == ' table' and obj .long ) or pt == ' Caption' then
326+ -- Looks like a Caption
327+ return as_blocks (obj .long )
328+ else
329+ return pandoc .Blocks (obj or {})
315330 end
316-
317- -- luacov: disable
318- fatal (" as_blocks: invalid type " .. t )
319- return pandoc .Blocks ({})
320- -- luacov: enable
321331end
322332
323333local function match_fun (reset , ...)
0 commit comments