Skip to content

Commit 95ce1e1

Browse files
use fraction units for typst column layouts
fixes #11578
1 parent a35d0c9 commit 95ce1e1

File tree

5 files changed

+149
-8
lines changed

5 files changed

+149
-8
lines changed

src/resources/filters/layout/layout.lua

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -203,9 +203,13 @@ function layout_cells(float_or_div, cells)
203203
end
204204
rows[#rows]:insert(cell)
205205
end
206-
-- convert width units to percentages
207-
widthsToPercent(rows, layoutCols)
208-
206+
if _quarto.format.isTypstOutput() then
207+
widthsToFraction(rows, layoutCols)
208+
else
209+
-- convert width units to percentages
210+
widthsToPercent(rows, layoutCols)
211+
end
212+
209213
-- check for layout
210214
elseif layout ~= nil then
211215
-- parse the layout

src/resources/filters/layout/width.lua

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,16 @@ function parseLayoutWidths(figLayout, figureCount)
4040
return cols:map(function(width)
4141
figureLayoutCount = figureLayoutCount + 1
4242
if type(width) == "number" then
43-
if numericTotal ~= 0 then
44-
width = round((width / numericTotal) * 100, 2)
45-
elseif width <= 1 then
46-
width = round(width * 100, 2)
43+
if _quarto.format.isTypstOutput() then
44+
width = tostring(width) .. "fr"
45+
else
46+
if numericTotal ~= 0 then
47+
width = round((width / numericTotal) * 100, 2)
48+
elseif width <= 1 then
49+
width = round(width * 100, 2)
50+
end
51+
width = tostring(width) .. "%"
4752
end
48-
width = tostring(width) .. "%"
4953
end
5054
-- negative widths are "spacers" so we need to bump our total fig count
5155
if isSpacerWidth(width) then
@@ -119,6 +123,41 @@ function widthsToPercent(layout, cols)
119123
end
120124

121125

126+
-- convert widths to typst fractions
127+
function widthsToFraction(layout, cols)
128+
129+
-- for each row
130+
for _,row in ipairs(layout) do
131+
132+
-- initialize widths with 0 or length string
133+
-- currently we assume the width unit is appropriate for the output format
134+
local widths = pandoc.List()
135+
for _,fig in ipairs(row) do
136+
widths[#widths+1] = 0
137+
local width = attribute(fig, "width", nil)
138+
if width then
139+
widths[#widths] = width
140+
end
141+
end
142+
143+
-- create virtual fig widths as needed and note the total width
144+
local defaultWidth = "1fr"
145+
for i=1,cols do
146+
if (i > #widths) or widths[i] == 0 then
147+
widths[i] = defaultWidth
148+
end
149+
end
150+
-- allocate widths
151+
for i,fig in ipairs(row) do
152+
local width = widths[i];
153+
fig.attr.attributes["width"] = width
154+
fig.attr.attributes["height"] = nil
155+
end
156+
157+
end
158+
end
159+
160+
122161
-- elements with a percentage width and no height have a 'layout percent'
123162
-- which means then should be laid out at a higher level in the tree than
124163
-- the individual figure element
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
---
2+
title: "Fraction layout"
3+
format:
4+
typst:
5+
keep-typ: true
6+
_quarto:
7+
tests:
8+
typst:
9+
ensureTypstFileRegexMatches:
10+
-
11+
['#grid\((\r\n?|\n)columns: \(1fr, 2fr, 2fr, 1fr, 3fr, 1fr, 1fr\), gutter: 1em, rows: 1,']
12+
---
13+
14+
::: {layout="[1, 2, 2, 1, 3, 1, 1]"}
15+
16+
![Placeholder]({{< placeholder 200 >}})
17+
18+
![Placeholder]({{< placeholder 200 >}})
19+
20+
![Placeholder]({{< placeholder 200 >}})
21+
22+
![Placeholder]({{< placeholder 200 >}})
23+
24+
![Placeholder]({{< placeholder 200 >}})
25+
26+
![Placeholder]({{< placeholder 200 >}})
27+
28+
![Placeholder]({{< placeholder 200 >}})
29+
30+
:::
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
---
2+
title: Test
3+
format: typst
4+
keep-md: true
5+
keep-typ: true
6+
_quarto:
7+
tests:
8+
typst:
9+
ensureTypstFileRegexMatches:
10+
-
11+
['#grid\((\r\n?|\n)columns: \(1fr, 1fr, 100pt, 1fr, 1fr, 1fr, 1fr\), gutter: 1em, rows: 1,']
12+
13+
---
14+
15+
::: {.callout-note}
16+
17+
## Plots
18+
19+
::: {layout-ncol=7}
20+
21+
![]({{< placeholder format=svg >}})
22+
23+
![]({{< placeholder format=svg >}})
24+
25+
![]({{< placeholder format=svg >}}){width="100pt"}
26+
27+
![]({{< placeholder format=svg >}})
28+
29+
![]({{< placeholder format=svg >}})
30+
31+
![]({{< placeholder format=svg >}})
32+
33+
![]({{< placeholder format=svg >}})
34+
:::
35+
:::
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
---
2+
title: Test
3+
format: typst
4+
keep-md: true
5+
keep-typ: true
6+
_quarto:
7+
tests:
8+
typst:
9+
ensureTypstFileRegexMatches:
10+
-
11+
['#grid\((\r\n?|\n)columns: \(1fr, 1fr, 1fr, 1fr, 1fr\), gutter: 1em, rows: 1,']
12+
---
13+
14+
::: {.callout-note}
15+
16+
## Plots
17+
18+
::: {layout-ncol=5}
19+
20+
![]({{< placeholder format=svg >}})
21+
22+
![]({{< placeholder format=svg >}})
23+
24+
![]({{< placeholder format=svg >}})
25+
26+
![]({{< placeholder format=svg >}})
27+
28+
![]({{< placeholder format=svg >}})
29+
:::
30+
31+
a) Beschreiben Sie die 5 Verteilungsformen. [5 Punkte]
32+
33+
:::

0 commit comments

Comments
 (0)