Skip to content
Merged
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
1 change: 1 addition & 0 deletions news/changelog-1.5.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ All changes included in 1.5:
- ([#8711](https://github.com/quarto-dev/quarto-cli/issues/8711)): Enforce rendering of tables as `tabular` environments when custom float environments are present.
- ([#8841](https://github.com/quarto-dev/quarto-cli/issues/8841)): Do not parse LaTeX table when crossref label doesn't start with `tbl-`.
- ([#9582](https://github.com/quarto-dev/quarto-cli/issues/9582)): Forward column classes and attributes correctly to floats inside divs with column classes.
- ([#9729](https://github.com/quarto-dev/quarto-cli/issues/9729)): Fix performance issue with Lua pattern matching and multiple capture groups.

## RevealJS Format

Expand Down
2 changes: 1 addition & 1 deletion src/resources/filters/common/tables.lua
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ end
function hasRawLatexTable(raw)
if _quarto.format.isRawLatex(raw) and _quarto.format.isLatexOutput() then
for i,pattern in ipairs(_quarto.patterns.latexTablePatterns) do
if raw.text:match(pattern) then
if _quarto.modules.patterns.match_all_in_table(pattern)(raw.text) then
return true
end
end
Expand Down
82 changes: 0 additions & 82 deletions src/resources/filters/crossref/#crossref.lua#

This file was deleted.

10 changes: 7 additions & 3 deletions src/resources/filters/customnodes/floatreftarget.lua
Original file line number Diff line number Diff line change
Expand Up @@ -444,12 +444,16 @@ end, function(float)
local made_fix = false
local function fix_raw(is_star_env)
local function set_raw(el)
if _quarto.format.isRawLatex(el) and el.text:match(_quarto.patterns.latexLongtablePattern) then
if _quarto.format.isRawLatex(el) and _quarto.modules.patterns.match_all_in_table(_quarto.patterns.latexLongtablePattern)(el.text) then
made_fix = true
local raw = el
-- special case for longtable floats in LaTeX
local extended_pattern = "(.-)" .. _quarto.patterns.latexLongtablePattern .. "(.*)"
local longtable_preamble, longtable_begin, longtable_content, longtable_end, longtable_postamble = raw.text:match(extended_pattern)
local extended_pattern = {".-"}
for _, pattern in ipairs(_quarto.patterns.latexLongtablePattern) do
table.insert(extended_pattern, pattern)
end
table.insert(extended_pattern, ".*")
local longtable_preamble, longtable_begin, longtable_content, longtable_end, longtable_postamble = _quarto.modules.patterns.match_all_in_table(extended_pattern)(raw.text)
if longtable_preamble == nil or longtable_begin == nil or longtable_content == nil or longtable_end == nil or longtable_postamble == nil then
warn("Could not parse longtable parameters. This could happen because the longtable parameters\n" ..
"are not well-formed or because of a bug in quarto. Please consider filing a bug report at\n" ..
Expand Down
26 changes: 26 additions & 0 deletions src/resources/filters/modules/patterns.lua
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,29 @@ local latex_tabular = "(\\begin{tabular}.*\\end{tabular})"
local latex_table = "(\\begin{table})(.*)(\\end{table})"
local latex_table_star = "(\\begin{table%*})(.*)(\\end{table%*})"

local function combine_patterns(pattern_table)
local combined_pattern = {}
for i, v in ipairs(pattern_table) do
table.insert(combined_pattern, "(" .. v .. ")")
end
return table.concat(combined_pattern)
end

-- see https://github.com/quarto-dev/quarto-cli/issues/9729#issuecomment-2122907870
-- for why this is necessary.
local function match_all_in_table(pattern_table)
local function inner(text)
for i, v in ipairs(pattern_table) do
if text:match(v) == nil then
return nil
end
end
-- return the combined matches for the combined pattern
return text:match(combine_patterns(pattern_table))
end
return inner
end

return {
attr_identifier = attr_identifier,
engine_escape = engine_escape,
Expand All @@ -68,4 +91,7 @@ return {
latex_tabular = latex_tabular,
latex_table = latex_table,
latex_table_star = latex_table_star,

match_all_in_table = match_all_in_table,
combine_patterns = combine_patterns
}
15 changes: 13 additions & 2 deletions src/resources/filters/normalize/extractquartodom.lua
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ function extract_latex_quartomarkdown_commands()
return nil
end
local text = el.text
-- provide an early exit if the text does not contain the pattern
-- because Lua's pattern matching apparently takes a long time
-- to fail: https://github.com/quarto-dev/quarto-cli/issues/9729
if text:match("\\QuartoMarkdownBase64{") == nil then
return nil
end
local pattern = "(.*)(\\QuartoMarkdownBase64{)([^}]*)(})(.*)"
local pre, _, content, _, post = text:match(pattern)
if pre == nil then
Expand Down Expand Up @@ -103,12 +109,17 @@ function inject_vault_content_into_rawlatex()
return nil
-- luacov: enable
end
local text = el.text
-- provide an early exit if the text does not contain the pattern
-- because Lua's pattern matching apparently takes a long time
-- to fail: https://github.com/quarto-dev/quarto-cli/issues/9729
if el.text:match("3ab579b5%-63b4%-445d%-bc1d%-85bf6c4c04de") == nil then
return nil
end

local pattern = "(.*)(3ab579b5%-63b4%-445d%-bc1d%-85bf6c4c04de%-[0-9]+)(.*)"
local text = el.text
local pre, content_id, post = text:match(pattern)


while pre do
local found = false
vault.content = _quarto.ast.walk(vault.content, {
Expand Down
6 changes: 4 additions & 2 deletions src/resources/filters/normalize/flags.lua
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,10 @@ function compute_flags()
end

if _quarto.format.isRawLatex(el) then
if (el.text:match(_quarto.patterns.latexLongtablePattern) and
not el.text:match(_quarto.patterns.latexCaptionPattern)) then
local long_table_match = _quarto.modules.patterns.match_all_in_table(_quarto.patterns.latexLongtablePattern)
local caption_match = _quarto.modules.patterns.match_all_in_table(_quarto.patterns.latexCaptionPattern)
if (long_table_match(el.text) and
not caption_match(el.text)) then
flags.has_longtable_no_caption_fixup = true
end
end
Expand Down
7 changes: 4 additions & 3 deletions src/resources/filters/quarto-post/latex.lua
Original file line number Diff line number Diff line change
Expand Up @@ -436,10 +436,11 @@ function render_latex_fixups()
return {
RawBlock = function(raw)
if _quarto.format.isRawLatex(raw) then
if (raw.text:match(_quarto.patterns.latexLongtablePattern) and
not raw.text:match(_quarto.patterns.latexCaptionPattern)) then
local long_table_match = _quarto.modules.patterns.match_all_in_table(_quarto.patterns.latexLongtablePattern)
local caption_match = _quarto.modules.patterns.match_all_in_table(_quarto.patterns.latexCaptionPattern)
if long_table_match(raw.text) and caption_match(raw.text) then
raw.text = raw.text:gsub(
_quarto.patterns.latexLongtablePattern, "\\begin{longtable*}%2\\end{longtable*}", 1)
_quarto.modules.patterns.combine_patterns(_quarto.patterns.latexLongtablePattern), "\\begin{longtable*}%2\\end{longtable*}", 1)
return raw
end
end
Expand Down
27 changes: 17 additions & 10 deletions src/resources/filters/quarto-pre/table-captions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,14 @@ function table_captions()
el = _quarto.ast.walk(el, {
RawBlock = function(raw)
if _quarto.format.isRawLatex(raw) then
if raw.text:match(_quarto.patterns.latexTabularPattern) and not raw.text:match(_quarto.patterns.latexTablePattern) then
raw.text = raw.text:gsub(_quarto.patterns.latexTabularPattern,
"\\begin{table}\n\\centering\n%1%2%3\n\\end{table}\n",
1)
return raw
local tabular_match = _quarto.modules.patterns.match_all_in_table(_quarto.patterns.latexTabularPattern)
local table_match = _quarto.modules.patterns.match_all_in_table(_quarto.patterns.latexTablePattern)
if tabular_match(raw.text) and not table_match(raw.text) then
raw.text = raw.text:gsub(
_quarto.modules.patterns.combine_patterns(_quarto.patterns.latexTabularPattern),
"\\begin{table}\n\\centering\n%1%2%3\n\\end{table}\n",
1)
return raw
end
end
end
Expand Down Expand Up @@ -169,8 +172,10 @@ function applyTableCaptions(el, tblCaptions, tblLabels)
idx = idx + 1
elseif hasRawLatexTable(raw) then
for i,pattern in ipairs(_quarto.patterns.latexTablePatterns) do
if raw.text:match(pattern) then
raw.text = applyLatexTableCaption(raw.text, tblCaptions[idx], tblLabels[idx], pattern)
local match_fun = _quarto.modules.patterns.match_all_in_table(pattern)
if match_fun(raw.text) then
local combined_pattern = _quarto.modules.patterns.combine_patterns(pattern)
raw.text = applyLatexTableCaption(raw.text, tblCaptions[idx], tblLabels[idx], combined_pattern)
break
end
end
Expand Down Expand Up @@ -198,20 +203,22 @@ end

function applyLatexTableCaption(latex, tblCaption, tblLabel, tablePattern)
local latexCaptionPattern = _quarto.patterns.latexCaptionPattern
local latex_caption_match = _quarto.modules.patterns.match_all_in_table(latexCaptionPattern)
-- insert caption if there is none
local beginCaption, caption = latex:match(latexCaptionPattern)
local beginCaption, caption = latex_caption_match(latex)
if not beginCaption then
latex = latex:gsub(tablePattern, "%1" .. "\n\\caption{ }\\tabularnewline\n" .. "%2%3", 1)
end
-- apply table caption and label
local beginCaption, captionText, endCaption = latex:match(latexCaptionPattern)
local beginCaption, captionText, endCaption = latex_caption_match(latex)
if #tblCaption > 0 then
captionText = stringEscape(tblCaption, "latex")
end
if #tblLabel > 0 then
captionText = captionText .. " {#" .. tblLabel .. "}"
end
latex = latex:gsub(latexCaptionPattern, "%1" .. captionText:gsub("%%", "%%%%") .. "%3", 1)
assert(captionText)
latex = latex:gsub(_quarto.modules.patterns.combine_patterns(latexCaptionPattern), "%1" .. captionText:gsub("%%", "%%%%") .. "%3", 1)
return latex
end

Expand Down
52 changes: 26 additions & 26 deletions src/resources/pandoc/datadir/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1705,32 +1705,32 @@ local function resolveServiceWorkers(serviceworkers)
else
return nil
end
end
end


local latexTableWithOptionsPattern = "(\\begin{table}%[[^%]]+%])(.*)(\\end{table})"
local latexTablePattern = "(\\begin{table})(.*)(\\end{table})"
local latexLongtablePatternwWithPosAndAlign = "(\\begin{longtable}%[[^%]]+%]{[^\n]*})(.*)(\\end{longtable})"
local latexLongtablePatternWithPos = "(\\begin{longtable}%[[^%]]+%])(.*)(\\end{longtable})"
local latexLongtablePatternWithAlign = "(\\begin{longtable}{[^\n]*})(.*)(\\end{longtable})"
local latexLongtablePattern = "(\\begin{longtable})(.*)(\\end{longtable})"
local latexTabularPatternWithPosAndAlign = "(\\begin{tabular}%[[^%]]+%]{[^\n]*})(.*)(\\end{tabular})"
local latexTabularPatternWithPos = "(\\begin{tabular}%[[^%]]+%])(.*)(\\end{tabular})"
local latexTabularPatternWithAlign = "(\\begin{tabular}{[^\n]*})(.*)(\\end{tabular})"
local latexTabularPattern = "(\\begin{tabular})(.*)(\\end{tabular})"
local latexCaptionPattern = "(\\caption{)(.-)(}[^\n]*\n)"
local latexTableWithOptionsPattern_table = { "\\begin{table}%[[^%]]+%]", ".*", "\\end{table}" }
local latexTablePattern_table = { "\\begin{table}", ".*", "\\end{table}" }
local latexLongtablePatternWithPosAndAlign_table = { "\\begin{longtable}%[[^%]]+%]{[^\n]*}", ".*", "\\end{longtable}" }
local latexLongtablePatternWithPos_table = { "\\begin{longtable}%[[^%]]+%]", ".*", "\\end{longtable}" }
local latexLongtablePatternWithAlign_table = { "\\begin{longtable}{[^\n]*}", ".*", "\\end{longtable}" }
local latexLongtablePattern_table = { "\\begin{longtable}", ".*", "\\end{longtable}" }
local latexTabularPatternWithPosAndAlign_table = { "\\begin{tabular}%[[^%]]+%]{[^\n]*}", ".*", "\\end{tabular}" }
local latexTabularPatternWithPos_table = { "\\begin{tabular}%[[^%]]+%]", ".*", "\\end{tabular}" }
local latexTabularPatternWithAlign_table = { "\\begin{tabular}{[^\n]*}", ".*", "\\end{tabular}" }
local latexTabularPattern_table = { "\\begin{tabular}", ".*", "\\end{tabular}" }
local latexCaptionPattern_table = { "\\caption{", ".-", "}[^\n]*\n" }

local latexTablePatterns = pandoc.List({
latexTableWithOptionsPattern,
latexTablePattern,
latexLongtablePatternwWithPosAndAlign,
latexLongtablePatternWithPos,
latexLongtablePatternWithAlign,
latexLongtablePattern,
latexTabularPatternWithPosAndAlign,
latexTabularPatternWithPos,
latexTabularPatternWithAlign,
latexTabularPattern,
latexTableWithOptionsPattern_table,
latexTablePattern_table,
latexLongtablePatternWithPosAndAlign_table,
latexLongtablePatternWithPos_table,
latexLongtablePatternWithAlign_table,
latexLongtablePattern_table,
latexTabularPatternWithPosAndAlign_table,
latexTabularPatternWithPos_table,
latexTabularPatternWithAlign_table,
latexTabularPattern_table,
})

-- global quarto params
Expand Down Expand Up @@ -1876,11 +1876,11 @@ _quarto = {
processDependencies = processDependencies,
format = format,
patterns = {
latexTabularPattern = latexTabularPattern,
latexTablePattern = latexTablePattern,
latexLongtablePattern = latexLongtablePattern,
latexTabularPattern = latexTabularPattern_table,
latexTablePattern = latexTablePattern_table,
latexLongtablePattern = latexLongtablePattern_table,
latexTablePatterns = latexTablePatterns,
latexCaptionPattern = latexCaptionPattern
latexCaptionPattern = latexCaptionPattern_table
},
utils = utils,
withScriptFile = function(file, callback)
Expand Down