Skip to content

Commit f57620e

Browse files
authored
Merge pull request #8866 from quarto-dev/bugfix/8785
lua - tweak order of figure rendering
2 parents 6646230 + 3f821dd commit f57620e

File tree

6 files changed

+101
-51
lines changed

6 files changed

+101
-51
lines changed

src/resources/filters/common/figures.lua

+8
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,14 @@ function isFigAttribute(name)
1515
return string.find(name, "^fig%-")
1616
end
1717

18+
function figAlignAttributeDefault(el, default)
19+
local align = attribute(el, kFigAlign, default)
20+
if align == "default" then
21+
align = default
22+
end
23+
return validatedAlign(align, default)
24+
end
25+
1826
function figAlignAttribute(el)
1927
local default = pandoc.utils.stringify(
2028
param(kFigAlign, pandoc.Str("default"))

src/resources/filters/layout/html.lua

+11-1
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,17 @@ end
156156
function renderHtmlFigure(el, render)
157157

158158
-- capture relevant figure attributes then strip them
159-
local align = figAlignAttribute(el)
159+
local align = figAlignAttributeDefault(el, nil)
160+
if align == nil then
161+
local img = quarto.utils.match("[1]/Para/[1]/Image")(el) or quarto.utils.match("[1]/Para/[1]/Link/[1]/Image")(el)
162+
if img then
163+
align = figAlignAttribute(img)
164+
else
165+
-- fallback to center default
166+
align = figAlignAttribute(el)
167+
end
168+
end
169+
160170
local keys = tkeys(el.attr.attributes)
161171
for _,k in pairs(keys) do
162172
if isFigAttribute(k) then

src/resources/filters/layout/latex.lua

+4-9
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,10 @@ function latexJoinParas(content)
9999
return blocks
100100
end
101101

102-
function latexCaptionEnv(el)
102+
function latexCaptionEnv(el)
103+
if el.attributes['quarto-caption-env'] then
104+
return el.attributes['quarto-caption-env']
105+
end
103106
if el.classes:includes(kSideCaptionClass) then
104107
return kSideCaptionEnv
105108
else
@@ -672,14 +675,6 @@ function renderLatexFigure(el, render)
672675

673676
end
674677

675-
function latexCaptionEnv(el)
676-
if el.classes:includes(kSideCaptionClass) then
677-
return kSideCaptionEnv
678-
else
679-
return 'caption'
680-
end
681-
end
682-
683678
function insertLatexCaption(divEl, content, captionInlines)
684679
local captionEnv = latexCaptionEnv(divEl)
685680
markupLatexCaption(divEl, captionInlines, captionEnv)

src/resources/filters/layout/pandoc3_figure.lua

+56-39
Original file line numberDiff line numberDiff line change
@@ -75,19 +75,66 @@ function render_pandoc3_figure()
7575
local filter
7676
filter = function(state)
7777
state = state or {}
78+
local function figure_renderer(figure, is_subfig)
79+
-- this is a figure that is not cross-referenceable
80+
-- if this ends up in a layout without fig-pos = H, it'll fail
81+
-- 'H' forces it to not float
82+
if figure.identifier == "" then
83+
figure = _quarto.ast.walk(figure, {
84+
Image = function(image)
85+
image.attributes['fig-pos'] = 'H'
86+
return image
87+
end
88+
})
89+
end
90+
local image
91+
_quarto.ast.walk(figure, {
92+
Image = function(img)
93+
image = img
94+
end
95+
})
96+
if image == nil then
97+
return figure
98+
end
99+
if figure.caption.long ~= nil then
100+
image.caption = quarto.utils.as_inlines(figure.caption.long)
101+
end
102+
for k, v in pairs(figure.attributes) do
103+
image.attributes[k] = v
104+
end
105+
if is_subfig then
106+
image.attributes['quarto-caption-env'] = 'subcaption'
107+
end
108+
image.classes:extend(figure.classes)
109+
if state.in_column_margin then
110+
image.classes:insert("column-margin")
111+
end
112+
return latexImageFigure(image)
113+
end
114+
local function float_renderer(float)
115+
local count = 0
116+
local new_content = _quarto.ast.walk(float.content, {
117+
Figure = function(fig)
118+
count = count + 1
119+
return figure_renderer(fig, true), false
120+
end
121+
})
122+
if count > 0 then
123+
float.content = new_content
124+
return float, false
125+
end
126+
end
78127
return {
79128
traverse = "topdown",
80-
FloatRefTarget = function(float)
81-
local count = 0
82-
_quarto.ast.walk(float.content, {
83-
Figure = function()
84-
count = count + 1
129+
PanelLayout = function(panel)
130+
panel.rows = _quarto.ast.walk(panel.rows, {
131+
Figure = function(fig)
132+
return figure_renderer(fig, true), false
85133
end
86134
})
87-
if count > 0 then
88-
return nil, false
89-
end
135+
return panel, false
90136
end,
137+
FloatRefTarget = float_renderer,
91138
Div = function(div)
92139
if div.classes:includes("column-margin") then
93140
local new_state = {}
@@ -102,37 +149,7 @@ function render_pandoc3_figure()
102149
end
103150
end,
104151
Figure = function(figure)
105-
-- this is a figure that is not cross-referenceable
106-
-- if this ends up in a layout without fig-pos = H, it'll fail
107-
-- 'H' forces it to not float
108-
if figure.identifier == "" then
109-
figure = _quarto.ast.walk(figure, {
110-
Image = function(image)
111-
image.attributes['fig-pos'] = 'H'
112-
return image
113-
end
114-
})
115-
end
116-
local image
117-
_quarto.ast.walk(figure, {
118-
Image = function(img)
119-
image = img
120-
end
121-
})
122-
if image == nil then
123-
return figure
124-
end
125-
if figure.caption.long ~= nil then
126-
image.caption = quarto.utils.as_inlines(figure.caption.long)
127-
end
128-
for k, v in pairs(figure.attributes) do
129-
image.attributes[k] = v
130-
end
131-
image.classes:extend(figure.classes)
132-
if state.in_column_margin then
133-
image.classes:insert("column-margin")
134-
end
135-
return latexImageFigure(image)
152+
return figure_renderer(figure, false)
136153
end
137154
}
138155
end

src/resources/filters/main.lua

+3-2
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,9 @@ local quarto_post_filters = {
348348

349349
{ name = "post-ojs", filter = ojs() },
350350

351+
{ name = "post-render-pandoc3-figure", filter = render_pandoc3_figure(),
352+
flags = { "has_pandoc3_figure" } },
353+
351354
-- extensible rendering
352355
{ name = "post-render_extended_nodes", filter = render_extended_nodes() },
353356

@@ -361,8 +364,6 @@ local quarto_post_filters = {
361364
{ name = "post-render-typst-fixups", filter = render_typst_fixups() },
362365
{ name = "post-render-gfm-fixups", filter = render_gfm_fixups() },
363366
{ name = "post-render-hugo-fixups", filter = render_hugo_fixups() },
364-
{ name = "post-render-pandoc3-figure", filter = render_pandoc3_figure(),
365-
flags = { "has_pandoc3_figure" } },
366367
{ name = "post-render-email", filters = render_email() },
367368
}
368369

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
---
2+
format: latex
3+
_quarto:
4+
tests:
5+
latex:
6+
ensureFileRegexMatches:
7+
- ["centering"]
8+
- []
9+
---
10+
11+
## Radiator Widths
12+
13+
::: {layout-ncol=3 layout-valign="bottom"}
14+
![A logo](https://placehold.co/50x40.png){height=30mm}
15+
16+
![Another logo](https://placehold.co/50x40.png)
17+
18+
![Look at that, another logo!](https://placehold.co/50x40.png)
19+
:::

0 commit comments

Comments
 (0)