mirror of
https://github.com/typst/typst
synced 2025-05-13 20:46:23 +08:00
473 lines
11 KiB
Typst
473 lines
11 KiB
Typst
--- grid-headers ---
|
|
#set page(width: auto, height: 12em)
|
|
#table(
|
|
columns: 5,
|
|
align: center + horizon,
|
|
table.header(
|
|
table.cell(colspan: 5)[*Cool Zone*],
|
|
table.cell(stroke: red)[*Name*], table.cell(stroke: aqua)[*Number*], [*Data 1*], [*Data 2*], [*Etc*],
|
|
table.hline(start: 2, end: 3, stroke: yellow)
|
|
),
|
|
..range(0, 6).map(i => ([John \##i], table.cell(stroke: green)[123], table.cell(stroke: blue)[456], [789], [?], table.hline(start: 4, end: 5, stroke: red))).flatten()
|
|
)
|
|
|
|
--- grid-headers-no-repeat ---
|
|
// Disable repetition
|
|
#set page(width: auto, height: 12em)
|
|
#table(
|
|
columns: 5,
|
|
align: center + horizon,
|
|
table.header(
|
|
table.cell(colspan: 5)[*Cool Zone*],
|
|
table.cell(stroke: red)[*Name*], table.cell(stroke: aqua)[*Number*], [*Data 1*], [*Data 2*], [*Etc*],
|
|
table.hline(start: 2, end: 3, stroke: yellow),
|
|
repeat: false
|
|
),
|
|
..range(0, 6).map(i => ([John \##i], table.cell(stroke: green)[123], table.cell(stroke: blue)[456], [789], [?], table.hline(start: 4, end: 5, stroke: red))).flatten()
|
|
)
|
|
|
|
--- grid-headers-gutter ---
|
|
#set page(width: auto, height: 12em)
|
|
#table(
|
|
columns: 5,
|
|
align: center + horizon,
|
|
gutter: 3pt,
|
|
table.header(
|
|
table.cell(colspan: 5)[*Cool Zone*],
|
|
table.cell(stroke: red)[*Name*], table.cell(stroke: aqua)[*Number*], [*Data 1*], [*Data 2*], [*Etc*],
|
|
table.hline(start: 2, end: 3, stroke: yellow),
|
|
),
|
|
..range(0, 6).map(i => ([John \##i], table.cell(stroke: green)[123], table.cell(stroke: blue)[456], [789], [?], table.hline(start: 4, end: 5, stroke: red))).flatten()
|
|
)
|
|
|
|
--- grid-header-relative-row-sizes ---
|
|
// Relative lengths
|
|
#set page(height: 10em)
|
|
#table(
|
|
rows: (30%, 30%, auto),
|
|
table.header(
|
|
[*A*],
|
|
[*B*]
|
|
),
|
|
[C],
|
|
[C]
|
|
)
|
|
|
|
--- grid-header-cell-with-y ---
|
|
#grid(
|
|
grid.cell(y: 1)[a],
|
|
grid.header(grid.cell(y: 0)[b]),
|
|
grid.cell(y: 2)[c]
|
|
)
|
|
|
|
--- grid-header-cell-with-x ---
|
|
#grid(
|
|
columns: 2,
|
|
stroke: black,
|
|
inset: 5pt,
|
|
grid.header(grid.cell(x: 0)[b1], grid.cell(x: 0)[b2]),
|
|
// This should skip the header
|
|
grid.cell(x: 1)[c]
|
|
)
|
|
|
|
--- grid-header-last-child ---
|
|
// When the header is the last grid child, it shouldn't include the gutter row
|
|
// after it, because there is none.
|
|
#grid(
|
|
columns: 2,
|
|
gutter: 3pt,
|
|
grid.header(
|
|
[a], [b],
|
|
[c], [d]
|
|
)
|
|
)
|
|
|
|
--- grid-header-nested ---
|
|
#set page(height: 14em)
|
|
#let t(n) = table(
|
|
columns: 3,
|
|
align: center + horizon,
|
|
gutter: 3pt,
|
|
table.header(
|
|
table.cell(colspan: 3)[*Cool Zone #n*],
|
|
[*Name*], [*Num*], [*Data*]
|
|
),
|
|
..range(0, 5).map(i => ([\##i], table.cell(stroke: green)[123], table.cell(stroke: blue)[456])).flatten()
|
|
)
|
|
#grid(
|
|
gutter: 3pt,
|
|
t(0),
|
|
t(1)
|
|
)
|
|
|
|
--- grid-header-hline-and-vline ---
|
|
// Test line positioning in header
|
|
#table(
|
|
columns: 3,
|
|
stroke: none,
|
|
table.hline(stroke: red, end: 2),
|
|
table.vline(stroke: red, end: 3),
|
|
table.header(
|
|
table.hline(stroke: aqua, start: 2),
|
|
table.vline(stroke: aqua, start: 3), [*A*], table.hline(stroke: orange), table.vline(stroke: orange), [*B*],
|
|
[*C*], [*D*]
|
|
),
|
|
[a], [b],
|
|
[c], [d],
|
|
[e], [f]
|
|
)
|
|
|
|
--- grid-header-not-at-first-row ---
|
|
// Error: 3:3-3:19 header must start at the first row
|
|
// Hint: 3:3-3:19 remove any rows before the header
|
|
#grid(
|
|
[a],
|
|
grid.header([b])
|
|
)
|
|
|
|
--- grid-header-not-at-first-row-two-columns ---
|
|
// Error: 4:3-4:19 header must start at the first row
|
|
// Hint: 4:3-4:19 remove any rows before the header
|
|
#grid(
|
|
columns: 2,
|
|
[a],
|
|
grid.header([b])
|
|
)
|
|
|
|
--- grow-header-multiple ---
|
|
// Error: 3:3-3:19 cannot have more than one header
|
|
#grid(
|
|
grid.header([a]),
|
|
grid.header([b]),
|
|
[a],
|
|
)
|
|
|
|
--- table-header-in-grid ---
|
|
// Error: 2:3-2:20 cannot use `table.header` as a grid header
|
|
// Hint: 2:3-2:20 use `grid.header` instead
|
|
#grid(
|
|
table.header([a]),
|
|
[a],
|
|
)
|
|
|
|
--- grid-header-in-table ---
|
|
// Error: 2:3-2:19 cannot use `grid.header` as a table header
|
|
// Hint: 2:3-2:19 use `table.header` instead
|
|
#table(
|
|
grid.header([a]),
|
|
[a],
|
|
)
|
|
|
|
--- grid-header-in-grid-header ---
|
|
// Error: 14-28 cannot place a grid header within another header or footer
|
|
#grid.header(grid.header[a])
|
|
|
|
--- table-header-in-grid-header ---
|
|
// Error: 14-29 cannot place a table header within another header or footer
|
|
#grid.header(table.header[a])
|
|
|
|
--- grid-header-in-table-header ---
|
|
// Error: 15-29 cannot place a grid header within another header or footer
|
|
#table.header(grid.header[a])
|
|
|
|
--- table-header-in-table-header ---
|
|
// Error: 15-30 cannot place a table header within another header or footer
|
|
#table.header(table.header[a])
|
|
|
|
--- grid-header-block-with-fixed-height ---
|
|
#set page(height: 15em)
|
|
#table(
|
|
rows: (auto, 2.5em, auto),
|
|
table.header(
|
|
[*Hello*],
|
|
[*World*]
|
|
),
|
|
block(width: 2em, height: 20em, fill: red)
|
|
)
|
|
|
|
--- grid-header-and-rowspan-non-contiguous-1 ---
|
|
// Rowspan sizing algorithm doesn't do the best job at non-contiguous content
|
|
// ATM.
|
|
#set page(height: 15em)
|
|
|
|
#table(
|
|
rows: (auto, 2.5em, 2em, auto, 5em),
|
|
table.header(
|
|
[*Hello*],
|
|
[*World*]
|
|
),
|
|
table.cell(rowspan: 3, lines(15))
|
|
)
|
|
|
|
--- grid-header-and-rowspan-non-contiguous-2 ---
|
|
// Rowspan sizing algorithm doesn't do the best job at non-contiguous content
|
|
// ATM.
|
|
#set page(height: 15em)
|
|
|
|
#table(
|
|
rows: (auto, 2.5em, 2em, auto, 5em),
|
|
gutter: 3pt,
|
|
table.header(
|
|
[*Hello*],
|
|
[*World*]
|
|
),
|
|
table.cell(rowspan: 3, lines(15))
|
|
)
|
|
|
|
--- grid-header-and-rowspan-non-contiguous-3 ---
|
|
// This should look right
|
|
#set page(height: 15em)
|
|
|
|
#table(
|
|
rows: (auto, 2.5em, 2em, auto),
|
|
gutter: 3pt,
|
|
table.header(
|
|
[*Hello*],
|
|
[*World*]
|
|
),
|
|
table.cell(rowspan: 3, lines(15))
|
|
)
|
|
|
|
--- grid-header-lack-of-space ---
|
|
// Test lack of space for header + text.
|
|
#set page(height: 8em)
|
|
|
|
#table(
|
|
rows: (auto, 2.5em, auto, auto, 10em),
|
|
gutter: 3pt,
|
|
table.header(
|
|
[*Hello*],
|
|
[*World*]
|
|
),
|
|
table.cell(rowspan: 3, lorem(80))
|
|
)
|
|
|
|
--- grid-header-orphan-prevention ---
|
|
// Orphan header prevention test
|
|
#set page(height: 12em)
|
|
#v(8em)
|
|
#grid(
|
|
columns: 3,
|
|
grid.header(
|
|
[*Mui*], [*A*], grid.cell(rowspan: 2, fill: orange)[*B*],
|
|
[*Header*], [*Header* #v(0.1em)]
|
|
),
|
|
..([Test], [Test], [Test]) * 20
|
|
)
|
|
|
|
--- grid-header-empty ---
|
|
// Empty header should just be a repeated blank row
|
|
#set page(height: 12em)
|
|
#table(
|
|
columns: 4,
|
|
align: center + horizon,
|
|
table.header(),
|
|
..range(0, 4).map(i => ([John \##i], table.cell(stroke: green)[123], table.cell(stroke: blue)[456], [789])).flatten()
|
|
)
|
|
|
|
--- grid-header-containing-rowspan ---
|
|
// When a header has a rowspan with an empty row, it should be displayed
|
|
// properly
|
|
#set page(height: 10em)
|
|
|
|
#let count = counter("g")
|
|
#table(
|
|
rows: (auto, 2em, auto, auto),
|
|
table.header(
|
|
[eeec],
|
|
table.cell(rowspan: 2, count.step() + context count.display()),
|
|
),
|
|
[d],
|
|
block(width: 5em, fill: yellow, lorem(15)),
|
|
[d]
|
|
)
|
|
#context count.display()
|
|
|
|
--- grid-header-no-expand-with-col-and-row-pos-cell ---
|
|
#set page(height: 10em)
|
|
#table(
|
|
columns: 2,
|
|
table.header(
|
|
[a], [b],
|
|
[c],
|
|
),
|
|
// Error: 3-48 cell would conflict with header spanning the same position
|
|
// Hint: 3-48 try moving the cell or the header
|
|
table.cell(x: 1, y: 1, rowspan: 2, lorem(80))
|
|
)
|
|
|
|
--- grid-header-no-expand-with-row-pos-cell ---
|
|
#set page(height: 10em)
|
|
#table(
|
|
columns: 2,
|
|
table.header(
|
|
[a], [b],
|
|
[c],
|
|
),
|
|
// Error: 3-42 cell would conflict with header spanning the same position
|
|
// Hint: 3-42 try moving the cell or the header
|
|
table.cell(y: 1, rowspan: 2, lorem(80))
|
|
)
|
|
|
|
--- grid-nested-with-headers ---
|
|
// Nested table with header should repeat both headers
|
|
#set page(height: 10em)
|
|
#table(
|
|
table.header(
|
|
[a]
|
|
),
|
|
table(
|
|
table.header(
|
|
[b]
|
|
),
|
|
[a\ b\ c\ d]
|
|
)
|
|
)
|
|
|
|
--- grid-nested-headers ---
|
|
#set page(height: 12em)
|
|
#table(
|
|
table.header(
|
|
table(
|
|
table.header(
|
|
[b]
|
|
),
|
|
[c],
|
|
[d]
|
|
)
|
|
),
|
|
[a\ b]
|
|
)
|
|
|
|
--- grid-header-stroke-edge-cases ---
|
|
// Test header stroke priority edge case (last header row removed)
|
|
#set page(height: 8em)
|
|
#table(
|
|
columns: 2,
|
|
stroke: black,
|
|
gutter: (auto, 3pt),
|
|
table.header(
|
|
[c], [d],
|
|
),
|
|
..(table.cell(stroke: aqua)[d],) * 8,
|
|
)
|
|
|
|
--- grid-header-hline-bottom ---
|
|
// Yellow line should be kept here
|
|
#set text(6pt)
|
|
#table(
|
|
column-gutter: 3pt,
|
|
inset: 1pt,
|
|
table.header(
|
|
[a],
|
|
table.hline(stroke: yellow),
|
|
),
|
|
table.cell(rowspan: 2)[b]
|
|
)
|
|
|
|
--- grid-header-hline-bottom-manually ---
|
|
// Red line should be kept here
|
|
#set page(height: 6em)
|
|
#set text(6pt)
|
|
#table(
|
|
column-gutter: 3pt,
|
|
inset: 1pt,
|
|
table.header(
|
|
table.hline(stroke: red, position: bottom),
|
|
[a],
|
|
),
|
|
[a],
|
|
table.cell(stroke: aqua)[b]
|
|
)
|
|
|
|
--- grid-header-rowspan-base ---
|
|
#set page(height: 7em)
|
|
#set text(6pt)
|
|
#let full-block = block(width: 2em, height: 100%, fill: red)
|
|
#table(
|
|
columns: 3,
|
|
inset: 1.5pt,
|
|
table.header(
|
|
[a], full-block, table.cell(rowspan: 2, full-block),
|
|
[b]
|
|
)
|
|
)
|
|
|
|
--- grid-header-row-pos-cell-inside-conflicts-with-row-before ---
|
|
#set page(margin: 2pt)
|
|
#set text(6pt)
|
|
#table(
|
|
columns: 3,
|
|
inset: 1.5pt,
|
|
table.cell(y: 0)[a],
|
|
table.header(
|
|
table.hline(stroke: red),
|
|
table.hline(y: 1, stroke: aqua),
|
|
// Error: 5-24 cell would cause header to expand to non-empty row 0
|
|
// Hint: 5-24 try moving its cells to available rows
|
|
table.cell(y: 0)[b],
|
|
[c]
|
|
)
|
|
)
|
|
|
|
--- grid-header-row-pos-cell-inside-conflicts-with-row-before-after-first-empty-row ---
|
|
#set page(margin: 2pt)
|
|
#set text(6pt)
|
|
#table(
|
|
columns: 3,
|
|
inset: 1.5pt,
|
|
// Rows: Occupied, Empty, Occupied, Empty, Empty, ...
|
|
// Should not be able to expand header from the second Empty to the second Occupied.
|
|
table.cell(y: 0)[a],
|
|
table.cell(y: 2)[a],
|
|
table.header(
|
|
table.hline(stroke: red),
|
|
table.hline(y: 3, stroke: aqua),
|
|
// Error: 5-24 cell would cause header to expand to non-empty row 2
|
|
// Hint: 5-24 try moving its cells to available rows
|
|
table.cell(y: 2)[b],
|
|
)
|
|
)
|
|
|
|
--- grid-header-auto-pos-cell-inside-conflicts-with-row-after ---
|
|
#set page(margin: 2pt)
|
|
#set text(6pt)
|
|
#table(
|
|
columns: 2,
|
|
inset: 1.5pt,
|
|
table.cell(y: 1)[a],
|
|
table.header(
|
|
[b], [c],
|
|
// Error: 6-7 cell would cause header to expand to non-empty row 1
|
|
// Hint: 6-7 try moving its cells to available rows
|
|
[d],
|
|
),
|
|
)
|
|
|
|
--- grid-header-row-pos-cell-inside-conflicts-with-row-after ---
|
|
#set page(margin: 2pt)
|
|
#set text(6pt)
|
|
#table(
|
|
columns: 2,
|
|
inset: 1.5pt,
|
|
table.cell(y: 2)[a],
|
|
table.header(
|
|
[b], [c],
|
|
// Error: 5-24 cell would cause header to expand to non-empty row 2
|
|
// Hint: 5-24 try moving its cells to available rows
|
|
table.cell(y: 3)[d],
|
|
),
|
|
)
|
|
|
|
--- issue-5359-column-override-stays-inside-header ---
|
|
#table(
|
|
columns: 3,
|
|
[Outside],
|
|
// Error: 1:3-4:4 header must start at the first row
|
|
// Hint: 1:3-4:4 remove any rows before the header
|
|
table.header(
|
|
[A], table.cell(x: 1)[B], [C],
|
|
table.cell(x: 1)[D],
|
|
),
|
|
)
|