diff --git a/src/resources/filters/ast/customnodes.lua b/src/resources/filters/ast/customnodes.lua
index ca61ebc39b9..ecda0ccb24a 100644
--- a/src/resources/filters/ast/customnodes.lua
+++ b/src/resources/filters/ast/customnodes.lua
@@ -336,16 +336,21 @@ _quarto.ast = {
return
end
local node = node_accessor(table)
- local t = pandoc.utils.type(value)
- quarto_assert(t ~= 'Div' and t ~= 'Span', "")
+ local valtype = pandoc.utils.type(value)
+ quarto_assert(valtype ~= 'Div' and valtype ~= 'Span', "")
if index > #node.content then
_quarto.ast.grow_scaffold(node, index)
end
- local pt = pandoc.utils.type(value)
- if pt == "Block" or pt == "Inline" then
- node.content[index].content = {value}
+ local inner_node = node.content[index]
+ local innertype = pandoc.utils.type(inner_node)
+ if innertype == 'Block' then
+ inner_node.content = quarto.utils.as_blocks(value)
+ elseif innertype == 'Inline' then
+ inner_node.content = quarto.utils.as_inlines(value)
else
- node.content[index].content = value
+ warn(debug.traceback(
+ 'Cannot find the right content type for value ' .. valtype))
+ inner_node.content = value
end
end
}
@@ -416,13 +421,15 @@ _quarto.ast = {
-- luacov: enable
end
- local forwarder = { }
+ local forwarder
if tisarray(handler.slots) then
+ forwarder = pandoc.List{}
for i, slot in ipairs(handler.slots) do
forwarder[slot] = i
end
- else
- forwarder = handler.slots
+ elseif handler.slots ~= nil then
+ warn('Expected `slots` to be either an array or nil, got ' ..
+ tostring(handler.slots))
end
quarto[handler.ast_name] = function(params)
diff --git a/src/resources/filters/crossref/equations.lua b/src/resources/filters/crossref/equations.lua
index f8a12e64f28..0ecb0e430b7 100644
--- a/src/resources/filters/crossref/equations.lua
+++ b/src/resources/filters/crossref/equations.lua
@@ -20,7 +20,7 @@ function process_equations(blockEl)
end
local mathInlines = nil
- local targetInlines = pandoc.List()
+ local targetInlines = pandoc.Inlines{}
for i, el in ipairs(inlines) do
diff --git a/src/resources/filters/crossref/index.lua b/src/resources/filters/crossref/index.lua
index 16ad656d1cc..68daa1ede38 100644
--- a/src/resources/filters/crossref/index.lua
+++ b/src/resources/filters/crossref/index.lua
@@ -65,9 +65,9 @@ end
-- add an entry to the index
function indexAddEntry(label, parent, order, caption, appendix)
if caption ~= nil then
- caption = pandoc.List(caption)
+ caption = quarto.utils.as_blocks(caption)
else
- caption = pandoc.List({})
+ caption = pandoc.Blocks({})
end
crossref.index.entries[label] = {
parent = parent,
diff --git a/src/resources/filters/crossref/preprocess.lua b/src/resources/filters/crossref/preprocess.lua
index 1b995b78a6c..6a7c113fe2d 100644
--- a/src/resources/filters/crossref/preprocess.lua
+++ b/src/resources/filters/crossref/preprocess.lua
@@ -7,7 +7,7 @@ function crossref_mark_subfloats()
return {
traverse = "topdown",
FloatRefTarget = function(float)
- float.content = _quarto.ast.walk(float.content, {
+ float.content = _quarto.ast.walk(float.content or pandoc.Blocks{}, {
FloatRefTarget = function(subfloat)
float.has_subfloats = true
crossref.subfloats[subfloat.identifier] = {
diff --git a/src/resources/filters/customnodes/callout.lua b/src/resources/filters/customnodes/callout.lua
index 8a9f4c17dee..929c9c5cb8a 100644
--- a/src/resources/filters/customnodes/callout.lua
+++ b/src/resources/filters/customnodes/callout.lua
@@ -264,7 +264,8 @@ function _callout_main()
return _quarto.format.typst.function_call("callout", {
{ "body", _quarto.format.typst.as_typst_content(callout.content) },
{ "title", _quarto.format.typst.as_typst_content(
- callout.title or pandoc.Plain(_quarto.modules.callouts.displayName(callout.type))
+ (not quarto.utils.is_empty_node(callout.title) and callout.title) or
+ pandoc.Plain(_quarto.modules.callouts.displayName(callout.type))
)},
{ "background_color", pandoc.RawInline("typst", background_color) },
{ "icon_color", pandoc.RawInline("typst", icon_color) },
@@ -406,4 +407,4 @@ function crossref_callouts()
return callout
end
}
-end
\ No newline at end of file
+end
diff --git a/src/resources/filters/customnodes/content-hidden.lua b/src/resources/filters/customnodes/content-hidden.lua
index f27af5a5418..9117085009a 100644
--- a/src/resources/filters/customnodes/content-hidden.lua
+++ b/src/resources/filters/customnodes/content-hidden.lua
@@ -105,7 +105,8 @@ local _content_hidden_meta = nil
function content_hidden_meta(meta)
-- return {
-- Meta = function(meta)
- _content_hidden_meta = meta
+ -- The call to `pandoc.Meta` ensures that we hold a copy.
+ _content_hidden_meta = pandoc.Meta(meta)
-- end
-- }
end
diff --git a/src/resources/filters/customnodes/floatreftarget.lua b/src/resources/filters/customnodes/floatreftarget.lua
index 03c7d35cc0d..9f75512fc0a 100644
--- a/src/resources/filters/customnodes/floatreftarget.lua
+++ b/src/resources/filters/customnodes/floatreftarget.lua
@@ -767,7 +767,7 @@ function float_reftarget_render_html_figure(float)
local float_content = pandoc.Div(_quarto.ast.walk(float.content, {
-- strip image captions
Image = function(image)
- image.caption = {}
+ image.caption = pandoc.Inlines{}
return image
end
}) or pandoc.Div({})) -- this should never happen but the lua analyzer doesn't know it
@@ -1098,4 +1098,4 @@ end, function(float)
return pandoc.Para({im})
end)
-global_table_guid_id = 0
\ No newline at end of file
+global_table_guid_id = 0
diff --git a/src/resources/filters/customnodes/shortcodes.lua b/src/resources/filters/customnodes/shortcodes.lua
index ffb5cc1c7a2..32ad1128e69 100644
--- a/src/resources/filters/customnodes/shortcodes.lua
+++ b/src/resources/filters/customnodes/shortcodes.lua
@@ -11,7 +11,7 @@ _quarto.ast.add_handler({
kind = "Inline",
parse = function(span)
- local inner_content = pandoc.List({})
+ local inner_content = pandoc.Inlines({})
span.content = span.content:filter(function(el)
return el.t == "Span"
@@ -78,9 +78,9 @@ _quarto.ast.add_handler({
end
local node = _quarto.ast.create_custom_node_scaffold("Shortcode", "Inline")
- node.content = inner_content:map(function(el)
- return pandoc.Span({el})
- end)
+ node.content = pandoc.Inlines(inner_content:map(function(el)
+ return pandoc.Span({el})
+ end))
local tbl = {
__quarto_custom_node = node,
name = name,
diff --git a/src/resources/filters/layout/html.lua b/src/resources/filters/layout/html.lua
index dc387110211..317cd855656 100644
--- a/src/resources/filters/layout/html.lua
+++ b/src/resources/filters/layout/html.lua
@@ -190,7 +190,7 @@ function renderHtmlFigure(el, render)
end)
-- remove identifier (it is now on the div)
- el.identifier = ""
+ el.attr.identifier = ""
if not figureDiv.classes:find_if(function(str) return str:match("quarto%-figure%-.+") end) then
-- apply standalone figure css if not already set
diff --git a/src/resources/filters/layout/lightbox.lua b/src/resources/filters/layout/lightbox.lua
index 15203c120fd..d2569bd68d5 100644
--- a/src/resources/filters/layout/lightbox.lua
+++ b/src/resources/filters/layout/lightbox.lua
@@ -176,10 +176,11 @@ function lightbox()
return {{
traverse = "topdown",
- Meta = function(meta)
+ Meta = function(meta)
-- Set auto lightbox mode, if need be
auto = lightbox_module.automatic(meta) == true
- end,
+ imgCount = 0
+ end,
-- Find images that are already within links
-- we'll use this to filter out these images if
-- the most is auto
diff --git a/src/resources/filters/layout/typst.lua b/src/resources/filters/layout/typst.lua
index 4c875f9b4fa..83fdcc3e2be 100644
--- a/src/resources/filters/layout/typst.lua
+++ b/src/resources/filters/layout/typst.lua
@@ -11,7 +11,7 @@ function make_typst_figure(tbl)
local identifier = tbl.identifier
local separator = tbl.separator
- if (not caption or #caption.content == 0) and tbl.separator == nil then
+ if quarto.utils.is_empty_node(caption) and tbl.separator == nil then
separator = ""
end
diff --git a/src/resources/filters/normalize/draft.lua b/src/resources/filters/normalize/draft.lua
index 7b9c718a18d..d3f043e6438 100644
--- a/src/resources/filters/normalize/draft.lua
+++ b/src/resources/filters/normalize/draft.lua
@@ -23,17 +23,17 @@ function normalize_draft()
end
is_draft = meta[kDraft] == true or tcontains(drafts, quarto.doc.input_file);
end,
- Pandoc = function(pandoc)
+ Pandoc = function(doc)
if _quarto.format.isHtmlOutput() and not _quarto.format.isHtmlSlideOutput() then
if is_draft and draft_mode == kDraftModeGone then
- pandoc.blocks = {}
+ doc.blocks = pandoc.Blocks{}
quarto.doc.includeText("in-header", '')
- return pandoc
+ return doc
elseif is_draft and draft_mode ~= kDraftModeGone then
quarto.doc.includeText("in-header", '')
- return pandoc
+ return doc
end
end
end
}
-end
\ No newline at end of file
+end
diff --git a/src/resources/filters/normalize/flags.lua b/src/resources/filters/normalize/flags.lua
index 8815da0a2fa..d695d39b452 100644
--- a/src/resources/filters/normalize/flags.lua
+++ b/src/resources/filters/normalize/flags.lua
@@ -107,8 +107,7 @@ function compute_flags()
-- FIXME: are we actually triggering this with FloatRefTargets?
-- table captions
local kTblCap = "tbl-cap"
- local tblCap = extractTblCapAttrib(node,kTblCap)
- if hasTableRef(node) or tblCap then
+ if hasTableRef(node) or node.attr.attributes[kTblCap] then
flags.has_table_captions = true
end
diff --git a/src/resources/filters/quarto-init/metainit.lua b/src/resources/filters/quarto-init/metainit.lua
index 9c3a22407db..9b63df41219 100644
--- a/src/resources/filters/quarto-init/metainit.lua
+++ b/src/resources/filters/quarto-init/metainit.lua
@@ -8,6 +8,7 @@ function quarto_meta_init()
read_includes(meta)
init_crossref_options(meta)
initialize_custom_crossref_categories(meta)
+ return meta
end
}
-end
\ No newline at end of file
+end
diff --git a/src/resources/filters/quarto-post/foldcode.lua b/src/resources/filters/quarto-post/foldcode.lua
index c5884a3da57..ab68552c298 100644
--- a/src/resources/filters/quarto-post/foldcode.lua
+++ b/src/resources/filters/quarto-post/foldcode.lua
@@ -65,7 +65,7 @@ function fold_code_and_lift_codeblocks()
local prev_annotated_code_block_scaffold = nil
local prev_annotated_code_block = nil
-- ok to lift codeblocks
- float.content = _quarto.ast.walk(float.content, {
+ float.content = _quarto.ast.walk(float.content or pandoc.Blocks{}, {
traverse = "topdown",
DecoratedCodeBlock = function(block)
-- defer the folding of code blocks to the DecoratedCodeBlock renderer
diff --git a/src/resources/filters/quarto-post/typst.lua b/src/resources/filters/quarto-post/typst.lua
index 4a2e7f8d6f5..8ebd9c87596 100644
--- a/src/resources/filters/quarto-post/typst.lua
+++ b/src/resources/filters/quarto-post/typst.lua
@@ -19,7 +19,9 @@ function render_typst()
return {
{
Meta = function(m)
- m["toc-depth"] = PANDOC_WRITER_OPTIONS["toc_depth"]
+ -- This should be a number, but we must represent it as a string,
+ -- as numbers are disallowed as metadata values.
+ m["toc-depth"] = tostring(PANDOC_WRITER_OPTIONS["toc_depth"])
m["toc-indent"] = option("toc-indent")
if m["number-depth"] then
number_depth = tonumber(pandoc.utils.stringify(m["number-depth"]))
@@ -138,7 +140,7 @@ function render_typst_fixups()
end
img.attributes["fig-align"] = nil
- return pandoc.Inlines({
+ return pandoc.Plain({
pandoc.RawInline("typst", "#align(" .. align .. ")["),
img,
pandoc.RawInline("typst", "]"),
diff --git a/src/resources/filters/quarto-pre/code-annotation.lua b/src/resources/filters/quarto-pre/code-annotation.lua
index 4fa26cf24a6..077a10077e6 100644
--- a/src/resources/filters/quarto-pre/code-annotation.lua
+++ b/src/resources/filters/quarto-pre/code-annotation.lua
@@ -310,7 +310,7 @@ function code_annotations()
-- if code annotations is false, then shut it down
if codeAnnotations ~= false then
- local outputs = pandoc.List()
+ local outputs = pandoc.Blocks{}
-- annotations[annotation-number] = {list of line numbers}
local pendingAnnotations = nil
diff --git a/src/resources/filters/quarto-pre/output-location.lua b/src/resources/filters/quarto-pre/output-location.lua
index eebe8bc2121..c50d388248a 100644
--- a/src/resources/filters/quarto-pre/output-location.lua
+++ b/src/resources/filters/quarto-pre/output-location.lua
@@ -71,7 +71,7 @@ function output_location()
if _quarto.format.isRevealJsOutput() then
return {
Blocks = function(blocks)
- local newBlocks = pandoc.List()
+ local newBlocks = pandoc.Blocks{}
for _,block in pairs(blocks) do
local outputLoc = collectCellOutputLocation(block)
if outputLoc then
diff --git a/src/resources/filters/quarto-pre/parsefiguredivs.lua b/src/resources/filters/quarto-pre/parsefiguredivs.lua
index ca075b0a5a9..868643cd308 100644
--- a/src/resources/filters/quarto-pre/parsefiguredivs.lua
+++ b/src/resources/filters/quarto-pre/parsefiguredivs.lua
@@ -236,7 +236,7 @@ function parse_floatreftargets()
end
local caption = refCaptionFromDiv(div)
if caption ~= nil then
- div.content:remove(#div.content)
+ div.content:remove() -- drop the last element
elseif div.attributes[caption_attr_key] ~= nil then
caption = pandoc.Plain(string_to_quarto_ast_inlines(div.attributes[caption_attr_key]))
div.attributes[caption_attr_key] = nil
@@ -246,10 +246,10 @@ function parse_floatreftargets()
local found_caption = false
content = _quarto.ast.walk(content, {
Table = function(table)
- if table.caption.long ~= nil then
+ -- check if caption is non-empty
+ if table.caption.long and next(table.caption.long) then
found_caption = true
caption = table.caption.long[1] -- what if there's more than one entry here?
- table.caption.long = nil
return table
end
end
@@ -458,7 +458,7 @@ function parse_floatreftargets()
fig_attr.classes:insert(v)
end
end
- image.caption = {}
+ image.caption = pandoc.Inlines{}
return image
end
}) or fig.content[1] -- this shouldn't be needed but the lua analyzer doesn't know it
@@ -494,7 +494,7 @@ function parse_floatreftargets()
end
-- we've parsed the caption, so we can remove it from the table
- el.caption.long = pandoc.List({})
+ el.caption.long = pandoc.Blocks({})
if label == "" then
return nil
@@ -602,7 +602,7 @@ function parse_floatreftargets()
if img.identifier == "" then
local caption = img.caption
if #caption > 0 then
- img.caption = nil
+ img.caption = pandoc.Inlines{}
return pandoc.Figure(link, { long = { caption } })
else
return nil
@@ -819,4 +819,4 @@ function forward_cell_subcaps()
return div
end
}
-end
\ No newline at end of file
+end
diff --git a/src/resources/filters/quarto-pre/table-captions.lua b/src/resources/filters/quarto-pre/table-captions.lua
index ede527f83e0..67a3917f75a 100644
--- a/src/resources/filters/quarto-pre/table-captions.lua
+++ b/src/resources/filters/quarto-pre/table-captions.lua
@@ -140,7 +140,7 @@ function applyTableCaptions(el, tblCaptions, tblLabels)
cap:insert(pandoc.Str("{#" .. tblLabels[idx] .. "}"))
end
idx = idx + 1
- el.caption.long = pandoc.Plain(cap)
+ el.caption.long = pandoc.Blocks{pandoc.Plain(cap)}
return el
end
end,
@@ -231,7 +231,7 @@ function extractTblCapAttrib(el, name, subcap)
else
value = pandoc.List({ value })
end
- el.attr.attributes[name] = nil
+ -- el.attr.attributes[name] = nil
return value
end
return nil
diff --git a/src/resources/filters/quarto-pre/table-rawhtml.lua b/src/resources/filters/quarto-pre/table-rawhtml.lua
index 41708cd51b0..e36e946c31b 100644
--- a/src/resources/filters/quarto-pre/table-rawhtml.lua
+++ b/src/resources/filters/quarto-pre/table-rawhtml.lua
@@ -14,23 +14,32 @@ function table_merge_raw_html()
return {
Blocks = function(blocks)
- local pendingRaw = pandoc.List()
- local merged = pandoc.List()
- for i,el in ipairs(blocks) do
- if _quarto.format.isRawHtml(el) and el.text:find(patterns.html_table_tag_name) then
- pendingRaw:insert(el.text)
+ local pending_raw = pandoc.List()
+ local next_element_idx = 1
+ for _, el in ipairs(blocks) do
+ if _quarto.format.isRawHtml(el) and
+ el.text:find(patterns.html_table_tag_name) then
+ pending_raw:insert(el.text)
else
- if #pendingRaw > 0 then
- merged:insert(pandoc.RawBlock("html", table.concat(pendingRaw, "\n")))
- pendingRaw = pandoc.List()
+ if next(pending_raw) then
+ blocks[next_element_idx] =
+ pandoc.RawBlock("html", table.concat(pending_raw, "\n"))
+ pending_raw = pandoc.List()
+ next_element_idx = next_element_idx + 1
end
- merged:insert(el)
+ blocks[next_element_idx] = el
+ next_element_idx = next_element_idx + 1
end
end
- if #pendingRaw > 0 then
- merged:insert(pandoc.RawBlock("html", table.concat(pendingRaw, "\n")))
+ if #pending_raw > 0 then
+ blocks[next_element_idx] =
+ pandoc.RawBlock("html", table.concat(pending_raw, "\n"))
+ next_element_idx = next_element_idx + 1
end
- return merged
+ for i = next_element_idx, #blocks do
+ blocks[i] = nil
+ end
+ return blocks
end
}
end
@@ -54,4 +63,4 @@ function table_respecify_gt_css()
return el
end
}
-end
\ No newline at end of file
+end
diff --git a/src/resources/pandoc/datadir/init.lua b/src/resources/pandoc/datadir/init.lua
index 1dc45ed14b4..4c7f1eecac5 100644
--- a/src/resources/pandoc/datadir/init.lua
+++ b/src/resources/pandoc/datadir/init.lua
@@ -1546,9 +1546,9 @@ local function processTextDependency(dependency, meta)
local textLoc = rawText.location
if meta[textLoc] == nil then
- meta[textLoc] = {}
+ meta[textLoc] = pandoc.List{}
end
- table.insert(meta[textLoc], pandoc.RawBlock(FORMAT, rawText.text))
+ meta[textLoc]:insert(pandoc.Blocks{pandoc.RawBlock(FORMAT, rawText.text)})
end
-- make the usePackage statement
@@ -1568,9 +1568,9 @@ local function usePackage(package, option)
local headerLoc = resolveLocation(kInHeader)
if meta[headerLoc] == nil then
- meta[headerLoc] = {}
+ meta[headerLoc] = pandoc.List{}
end
- table.insert(meta[headerLoc], usePackage(rawPackage.package, rawPackage.options))
+ meta[headerLoc]:insert(usePackage(rawPackage.package, rawPackage.options))
end
@@ -1584,28 +1584,28 @@ local function processDependencies(meta)
-- holds a list of hashes for dependencies that
-- have been processed. Process each dependency
-- only once
- local injectedText = {}
- local injectedFile = {}
- local injectedPackage = {}
+ local injectedText = pandoc.List{}
+ local injectedFile = pandoc.List{}
+ local injectedPackage = pandoc.List{}
-- each line was written as a dependency.
-- process them and contribute the appropriate headers
- for line in io.lines(dependenciesFile) do
+ for line in io.lines(dependenciesFile) do
local dependency = json.decode(line)
if dependency.type == 'text' then
if not utils.table.contains(injectedText, dependency.content) then
processTextDependency(dependency, meta)
- injectedText[#injectedText + 1] = dependency.content
+ injectedText:insert(dependency.content)
end
elseif dependency.type == "file" then
if not utils.table.contains(injectedFile, dependency.content.path) then
processFileDependency(dependency, meta)
- injectedFile[#injectedFile + 1] = dependency.content.path
+ injectedFile:insert(dependency.content.path)
end
elseif dependency.type == "usepackage" then
if not utils.table.contains(injectedPackage, dependency.content.package) then
processUsePackageDependency(dependency, meta)
- injectedPackage[#injectedPackage + 1] = dependency.content.package
+ injectedPackage:insert(dependency.content.package)
end
end
end