@@ -265,59 +265,75 @@ 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
268+ --- Blocks metatable
269+ local BlocksMT = getmetatable (pandoc .Blocks {})
270+ --- Inlines metatable
271+ local InlinesMT = getmetatable (pandoc .Inlines {})
283272
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 ))
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
284+ elseif pt == " Inline" then
285+ -- Faster than calling pandoc.Inlines
286+ return setmetatable ({obj }, InlinesMT )
287+ elseif pt == ' List' or pt == ' table' then
288+ if obj [1 ] and pandoc .utils .type (obj [1 ]) == ' Block' then
289+ return pandoc .utils .blocks_to_inlines (obj )
288290 end
289- return result
291+ -- Faster than calling pandoc.Inlines
292+ return setmetatable (obj , InlinesMT )
293+ elseif pt == " Block" then
294+ return pandoc .utils .blocks_to_inlines ({obj })
295+ elseif pt == " Blocks" then
296+ return pandoc .utils .blocks_to_inlines (obj )
297+ else
298+ return pandoc .Inlines (obj or {})
290299 end
291-
292- -- luacov: disable
293- fatal (" as_inlines: invalid type " .. t )
294- return pandoc .Inlines ({})
295- -- luacov: enable
296300end
297301
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 })
309- elseif t == " Inline" then
310- return pandoc .Blocks ({pandoc .Plain (v )})
311- end
312-
313- if type (v ) == " table" then
314- return pandoc .Blocks (v )
302+ --- Turns the given object into a `Blocks` list.
303+ --
304+ -- Works mostly like `pandoc.Blocks`, but doesn't a do a full
305+ -- unmarshal/marshal roundtrip. This buys performance, at the cost of
306+ -- less thorough type checks.
307+ --
308+ -- NOTE: The input object might be modified *destructively*!
309+ --
310+ -- This might need some benchmarking.
311+ local function as_blocks (obj )
312+ local pt = pandoc .utils .type (obj )
313+ if pt == ' Blocks' then
314+ return obj
315+ elseif pt == ' Block' then
316+ -- Assigning a metatable directly is faster than calling
317+ -- `pandoc.Blocks`.
318+ return setmetatable ({obj }, BlocksMT )
319+ elseif pt == ' Inline' then
320+ return setmetatable ({pandoc .Plain {obj }}, BlocksMT )
321+ elseif pt == ' Inlines' then
322+ if next (obj ) then
323+ return setmetatable ({pandoc .Plain (obj )}, BlocksMT )
324+ end
325+ return setmetatable ({}, BlocksMT )
326+ elseif pt == ' List' or (pt == ' table' and obj [1 ]) then
327+ if pandoc .utils .type (obj [1 ]) == ' Inline' then
328+ obj = {pandoc .Plain (obj )}
329+ end
330+ return setmetatable (obj , BlocksMT )
331+ elseif (pt == ' table' and obj .long ) or pt == ' Caption' then
332+ -- Looks like a Caption
333+ return as_blocks (obj .long )
334+ else
335+ return pandoc .Blocks (obj or {})
315336 end
316-
317- -- luacov: disable
318- fatal (" as_blocks: invalid type " .. t )
319- return pandoc .Blocks ({})
320- -- luacov: enable
321337end
322338
323339local function match_fun (reset , ...)
0 commit comments