Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 119 additions & 0 deletions src/resources/filters/ast/customnodes.lua
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,126 @@ function is_regular_node(node, name)
return node
end

local custom_walking_algorithms = {
["quarto-lua-mutable"] = function(node, filter)
local function handle(node)
local lt = type(node)
if lt ~= "table" and lt ~= "userdata" then
return node
end
local pt = pandoc.utils.type(node)
local t = node.tag
local handler = filter[t] or filter[pt]
if handler == nil then
return nil
end
return handler(node)
end
local dispatch

local function walk(node)
local lt = type(node)
if lt ~= "table" and lt ~= "userdata" then
return node
end
local t = node.tag
local pt = pandoc.utils.type(node)
return (dispatch[t] or dispatch[pt])(node)
end

local function dispatch_meta(meta)
local result, recurse = handle(meta)
if result ~= nil then
meta = result
end
if recurse == false then
return meta
end
for k, v in pairs(meta) do
meta[k] = walk(v)
end
return meta
end

local function list_function_factory(list_constructor)
return function(lst)
local function slow_path(lst, i, result)
local new_result = list_constructor({})
-- bring us up to the point where we need to switch to the slow path
for j = 1, i - 1 do
new_result:insert(lst[j])
end
new_result:extend(result)
for j = i + 1, #lst do
local inner_result = walk(lst[j]) or lst[j]
if type(inner_result) == "table" then
new_result:extend(inner_result)
else
new_result:insert(inner_result)
end
end
return new_result
end
local result, recurse = handle(lst)
if result ~= nil then
lst = result
end
if recurse == false then
return lst
end
local i = 0
local n = #lst
-- tricky algorithm here. We want a fast path
-- where we don't have to create a new table
-- but we also want to avoid the overhead of
-- creating a new table if we don't need to.
while i < n do
i = i + 1
local inline = lst[i]
local inner_result = walk(inline) or inline
if type(inner_result) == "table" then
return slow_path(lst, i, inner_result)
-- here we have to switch to the slow path
end
lst[i] = inner_result
end
return lst
end
end

local function dispatch_node(node)
local result, recurse = handle(node)
if result ~= nil then
node = result
end
if recurse == false then
return node
end
if node.content then
node.content = walk(node.content)
end
return node
end

dispatch = {
Meta = dispatch_meta,
table = dispatch_meta,
Inlines = list_function_factory(pandoc.Inlines),
List = list_function_factory(pandoc.List),
Blocks = list_function_factory(pandoc.Blocks),
Block = dispatch_node,
Inline = dispatch_node,
-- TODO handle missing nodes that have stuff other than content: Figure, Table, Image
-- TODO handle custom node dispatching on Span and Div
}
return walk(node)
end
}

function run_emulated_filter(doc, filter)
if custom_walking_algorithms[filter.traverse] then
return custom_walking_algorithms[filter.traverse](doc, filter)
end
if doc == nil then
return nil
end
Expand Down
4 changes: 2 additions & 2 deletions src/resources/filters/ast/runemulation.lua
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ local function run_emulated_filter_chain(doc, filters, afterFilterPass, profilin
-- We don't seem to need coverage for profiling
-- luacov: disable
if profiling then
profiler.category = v.name
profiler.setcategory(v.name)
end
-- luacov: enable

Expand Down Expand Up @@ -141,7 +141,7 @@ local function emulate_pandoc_filter(filters, afterFilterPass)
profiler = require('profiler')
end
pandoc.system.with_temporary_directory("temp", function(tmpdir)
profiler.start(tmpdir .. "/prof.txt")
profiler.start(tmpdir .. "/prof.txt", 1)
doc = run_emulated_filter_chain(doc, filters, afterFilterPass, profiling)
profiler.stop()
-- os.execute("cp " .. tmpdir .. "/prof.txt /tmp/prof.out")
Expand Down
6 changes: 3 additions & 3 deletions src/resources/filters/modules/astshortcode.lua
Original file line number Diff line number Diff line change
Expand Up @@ -281,11 +281,11 @@ function trimEmpty(contents)
end

local function parse(meta)
local doc = pandoc.Pandoc({}, meta)
return _quarto.ast.walk(doc, {
return _quarto.ast.walk(meta, {
traverse = "quarto-lua-mutable",
Blocks = transformShortcodeBlocks,
Inlines = transformShortcodeInlines,
}).meta
})
end

return {
Expand Down