Skip to content

Commit dd9271d

Browse files
committed
[perf] lua - combine finalize filters
1 parent fc561e6 commit dd9271d

File tree

2 files changed

+98
-13
lines changed

2 files changed

+98
-13
lines changed

src/resources/filters/main.lua

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,9 @@ import("./quarto-finalize/dependencies.lua")
9292
import("./quarto-finalize/book-cleanup.lua")
9393
import("./quarto-finalize/mediabag.lua")
9494
import("./quarto-finalize/meta-cleanup.lua")
95-
import("./quarto-finalize/coalesceraw.lua")
96-
import("./quarto-finalize/descaffold.lua")
95+
-- import("./quarto-finalize/coalesceraw.lua")
96+
-- import("./quarto-finalize/descaffold.lua")
97+
import("./quarto-finalize/finalize-combined-1.lua")
9798
import("./quarto-finalize/typst.lua")
9899

99100
import("./normalize/flags.lua")
@@ -550,22 +551,26 @@ local quarto_finalize_filters = {
550551
filter = dependencies(),
551552
traverser = 'jog',
552553
},
553-
{ name = "finalize-coalesce-raw",
554-
filters = coalesce_raw(),
555-
traverser = 'jog',
556-
},
557-
{ name = "finalize-descaffold",
558-
filter = descaffold(),
554+
{ name = "finalize-combined-1",
555+
filter = finalize_combined_1(),
559556
traverser = 'jog',
560557
},
558+
-- { name = "finalize-coalesce-raw",
559+
-- filters = coalesce_raw(),
560+
-- traverser = 'jog',
561+
-- },
562+
-- { name = "finalize-descaffold",
563+
-- filter = descaffold(),
564+
-- traverser = 'jog',
565+
-- },
561566
{ name = "finalize-wrapped-writer",
562567
filter = wrapped_writer(),
563568
traverser = 'jog',
564569
},
565-
{ name = "finalize-typst-state",
566-
filter = setup_typst_state(),
567-
traverser = 'jog',
568-
},
570+
-- { name = "finalize-typst-state",
571+
-- filter = setup_typst_state(),
572+
-- traverser = 'jog',
573+
-- },
569574
}
570575

571576
local quarto_layout_filters = {
@@ -665,7 +670,11 @@ tappend(quarto_filter_list, quarto_post_filters)
665670
table.insert(quarto_filter_list, { name = "post-render", filter = {} }) -- entry point for user filters
666671
table.insert(quarto_filter_list, { name = "pre-finalize", filter = {} }) -- entry point for user filters
667672
tappend(quarto_filter_list, quarto_finalize_filters)
668-
table.insert(quarto_filter_list, { name = "post-finalize", filter = {} }) -- entry point for user filters
673+
table.insert(quarto_filter_list, { name = "post-finalize", filter = {
674+
-- Pandoc = function(doc)
675+
-- quarto_prof.stop()
676+
-- end
677+
} }) -- entry point for user filters
669678

670679
-- now inject user-defined filters on appropriate positions
671680
inject_user_filters_at_entry_points(quarto_filter_list)
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
-- finalize_combined_1.lua
2+
--
3+
-- An optimized implementation of the following filters in a single pass:
4+
-- - coalesce_raw
5+
-- - descaffold
6+
--
7+
-- Copyright (C) 2025 Posit Software, PBC
8+
--
9+
-- Raw blocks are selectively coalesced if they're written
10+
-- to:
11+
-- - the same format
12+
-- - with a suffix of -merge
13+
--
14+
-- This specifically matters in the case of some latex rawblocks which
15+
-- cannot be separated by a newline (like minipages in a figure)
16+
--
17+
-- note that in LaTeX output, we need to strip Div nodes, since they
18+
-- can "delimit" two raw blocks and prevent them from being coalesced.
19+
20+
function finalize_combined_1()
21+
local changed = false
22+
23+
return {
24+
Plain = function(plain) -- descaffold
25+
if #plain.content == 0 then
26+
return {}
27+
end
28+
end,
29+
Span = function(el) -- descaffold
30+
if el.classes:includes("quarto-scaffold") then
31+
return el.content
32+
end
33+
end,
34+
Div = function(el)
35+
if (quarto.doc.isFormat("latex") and #el.classes == 0 and #el.attributes == 0 and el.identifier == "") or -- coalesce_raw
36+
el.classes:includes("quarto-scaffold") then -- descaffold
37+
return el.content
38+
end
39+
end,
40+
Inlines = function(inlines) -- coalesce_raw
41+
local current_node = nil
42+
for i = 1, #inlines do
43+
if inlines[i].t ~= "RawInline" then
44+
current_node = nil
45+
else
46+
if current_node and inlines[i].format == current_node.format then
47+
changed = true
48+
current_node.text = current_node.text .. inlines[i].text
49+
inlines[i].text = ""
50+
else
51+
current_node = inlines[i]
52+
end
53+
end
54+
end
55+
return inlines
56+
end,
57+
Blocks = function(blocks) -- coalesce_raw
58+
local current_node = nil
59+
for i = 1, #blocks do
60+
if blocks[i].t ~= "RawBlock" or not blocks[i].format:match(".*-merge$") then
61+
current_node = nil
62+
else
63+
blocks[i].format = blocks[i].format:gsub("-merge$", "")
64+
if current_node and blocks[i].format == current_node.format then
65+
changed = true
66+
current_node.text = current_node.text .. blocks[i].text
67+
blocks[i].text = ""
68+
else
69+
current_node = blocks[i]
70+
end
71+
end
72+
end
73+
return blocks
74+
end
75+
}
76+
end

0 commit comments

Comments
 (0)