Skip to content

Commit 1e75fa3

Browse files
committed
Let captioned tables break across pages in Typst
Typst figures do not break across pages, so a captioned table taller than the page ran past the page bottom and its last rows were lost. Several test documents worked around this with a hand-written `#show figure: set block(breakable: true)`. The float filter now adds a show rule that makes table figures breakable, once per document, next to the existing alignment rule for listing figures.
1 parent d326386 commit 1e75fa3

2 files changed

Lines changed: 104 additions & 0 deletions

File tree

‎src/resources/filters/customnodes/floatreftarget.lua‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ local drop_class = require("modules/filters").drop_class
55

66
-- Track whether we've injected the Typst show rule for listing alignment
77
local injected_listing_align_rule = false
8+
local injected_table_breakable_rule = false
89

910
local function split_longtable_start(content_str)
1011
-- we use a hack here to split the content into params and actual content
@@ -1040,6 +1041,16 @@ end, function(float)
10401041
]])
10411042
end
10421043

1044+
-- Inject show rule to let table figures break across pages (only once per
1045+
-- document); Typst figures are unbreakable by default, so long captioned
1046+
-- tables were cut off at the page bottom
1047+
if ref == "tbl" and not injected_table_breakable_rule then
1048+
injected_table_breakable_rule = true
1049+
quarto.doc.include_text("before-body", [[
1050+
#show figure.where(kind: "quarto-float-tbl"): set block(breakable: true)
1051+
]])
1052+
end
1053+
10431054
-- Check if this is a margin figure (has .column-margin or .aside class)
10441055
-- Skip margin handling for subfloats - the parent handles margin placement
10451056
if hasMarginColumn(float) and not float.parent_id then
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
---
2+
title: Long captioned table breaks across pages
3+
format: typst
4+
_quarto:
5+
tests:
6+
typst:
7+
ensurePdfTextPositions:
8+
- # The table is taller than a page. A breakable figure starts on
9+
# page 1 below the title; an unbreakable one moves whole to page 2
10+
# and its last rows run past the page bottom.
11+
- subject: "FIRSTROW_MARKER"
12+
relation: above
13+
object:
14+
role: Page
15+
page: 1
16+
edge: bottom
17+
- []
18+
---
19+
20+
| A | B |
21+
|---|---|
22+
| 1 | FIRSTROW_MARKER |
23+
| 2 | row 2 |
24+
| 3 | row 3 |
25+
| 4 | row 4 |
26+
| 5 | row 5 |
27+
| 6 | row 6 |
28+
| 7 | row 7 |
29+
| 8 | row 8 |
30+
| 9 | row 9 |
31+
| 10 | row 10 |
32+
| 11 | row 11 |
33+
| 12 | row 12 |
34+
| 13 | row 13 |
35+
| 14 | row 14 |
36+
| 15 | row 15 |
37+
| 16 | row 16 |
38+
| 17 | row 17 |
39+
| 18 | row 18 |
40+
| 19 | row 19 |
41+
| 20 | row 20 |
42+
| 21 | row 21 |
43+
| 22 | row 22 |
44+
| 23 | row 23 |
45+
| 24 | row 24 |
46+
| 25 | row 25 |
47+
| 26 | row 26 |
48+
| 27 | row 27 |
49+
| 28 | row 28 |
50+
| 29 | row 29 |
51+
| 30 | row 30 |
52+
| 31 | row 31 |
53+
| 32 | row 32 |
54+
| 33 | row 33 |
55+
| 34 | row 34 |
56+
| 35 | row 35 |
57+
| 36 | row 36 |
58+
| 37 | row 37 |
59+
| 38 | row 38 |
60+
| 39 | row 39 |
61+
| 40 | row 40 |
62+
| 41 | row 41 |
63+
| 42 | row 42 |
64+
| 43 | row 43 |
65+
| 44 | row 44 |
66+
| 45 | row 45 |
67+
| 46 | row 46 |
68+
| 47 | row 47 |
69+
| 48 | row 48 |
70+
| 49 | row 49 |
71+
| 50 | row 50 |
72+
| 51 | row 51 |
73+
| 52 | row 52 |
74+
| 53 | row 53 |
75+
| 54 | row 54 |
76+
| 55 | row 55 |
77+
| 56 | row 56 |
78+
| 57 | row 57 |
79+
| 58 | row 58 |
80+
| 59 | row 59 |
81+
| 60 | row 60 |
82+
| 61 | row 61 |
83+
| 62 | row 62 |
84+
| 63 | row 63 |
85+
| 64 | row 64 |
86+
| 65 | row 65 |
87+
| 66 | row 66 |
88+
| 67 | row 67 |
89+
| 68 | row 68 |
90+
| 69 | row 69 |
91+
| 70 | row 70 |
92+
93+
: Long table {#tbl-long}

0 commit comments

Comments
 (0)