mirror of
https://github.com/typst/typst
synced 2025-05-13 20:46:23 +08:00
550 lines
13 KiB
Typst
550 lines
13 KiB
Typst
--- grid-footer ---
|
|
#set page(width: auto, height: 15em)
|
|
#set text(6pt)
|
|
#set table(inset: 2pt, stroke: 0.5pt)
|
|
#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, 5).map(i => ([John \##i], table.cell(stroke: green)[123], table.cell(stroke: blue)[456], [789], [?], table.hline(start: 4, end: 5, stroke: red))).flatten(),
|
|
table.footer(
|
|
table.hline(start: 2, end: 3, stroke: yellow),
|
|
table.cell(stroke: red)[*Name*], table.cell(stroke: aqua)[*Number*], [*Data 1*], [*Data 2*], [*Etc*],
|
|
table.cell(colspan: 5)[*Cool Zone*]
|
|
)
|
|
)
|
|
|
|
--- grid-footer-gutter-and-no-repeat ---
|
|
// Gutter & no repetition
|
|
#set page(width: auto, height: 16em)
|
|
#set text(6pt)
|
|
#set table(inset: 2pt, stroke: 0.5pt)
|
|
#table(
|
|
columns: 5,
|
|
gutter: 2pt,
|
|
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, 5).map(i => ([John \##i], table.cell(stroke: green)[123], table.cell(stroke: blue)[456], [789], [?], table.hline(start: 4, end: 5, stroke: red))).flatten(),
|
|
table.footer(
|
|
repeat: false,
|
|
table.hline(start: 2, end: 3, stroke: yellow),
|
|
table.cell(stroke: red)[*Name*], table.cell(stroke: aqua)[*Number*], [*Data 1*], [*Data 2*], [*Etc*],
|
|
table.cell(colspan: 5)[*Cool Zone*]
|
|
)
|
|
)
|
|
|
|
--- grid-cell-override-in-header-and-footer ---
|
|
#table(
|
|
table.header(table.cell(stroke: red)[Hello]),
|
|
table.footer(table.cell(stroke: aqua)[Bye]),
|
|
)
|
|
|
|
--- grid-cell-override-in-header-and-footer-with-gutter ---
|
|
#table(
|
|
gutter: 3pt,
|
|
table.header(table.cell(stroke: red)[Hello]),
|
|
table.footer(table.cell(stroke: aqua)[Bye]),
|
|
)
|
|
|
|
--- grid-footer-top-stroke ---
|
|
// Footer's top stroke should win when repeated, but lose at the last page.
|
|
#set page(height: 10em)
|
|
#table(
|
|
stroke: green,
|
|
table.header(table.cell(stroke: red)[Hello]),
|
|
table.cell(stroke: yellow)[Hi],
|
|
table.cell(stroke: yellow)[Bye],
|
|
table.cell(stroke: yellow)[Ok],
|
|
table.footer[Bye],
|
|
)
|
|
|
|
--- grid-footer-relative-row-sizes ---
|
|
// Relative lengths
|
|
#set page(height: 10em)
|
|
#table(
|
|
rows: (30%, 30%, auto),
|
|
[C],
|
|
[C],
|
|
table.footer[*A*][*B*],
|
|
)
|
|
|
|
--- grid-footer-cell-with-y ---
|
|
#grid(
|
|
grid.footer(grid.cell(y: 2)[b]),
|
|
grid.cell(y: 0)[a],
|
|
grid.cell(y: 1)[c],
|
|
)
|
|
|
|
--- grid-footer-cell-with-x ---
|
|
#grid(
|
|
columns: 2,
|
|
stroke: black,
|
|
inset: 5pt,
|
|
grid.cell(x: 1)[a],
|
|
// Error: 3-56 footer must end at the last row
|
|
grid.footer(grid.cell(x: 0)[b1], grid.cell(x: 0)[b2]),
|
|
// This should skip the footer
|
|
grid.cell(x: 1)[c]
|
|
)
|
|
|
|
--- grid-footer-no-expand-with-col-and-row-pos-cell ---
|
|
#grid(
|
|
columns: 2,
|
|
[a], [],
|
|
[b], [],
|
|
fill: (_, y) => if calc.odd(y) { blue } else { red },
|
|
inset: 5pt,
|
|
grid.cell(x: 1, y: 3, rowspan: 4)[b],
|
|
grid.cell(y: 2, rowspan: 2)[a],
|
|
grid.footer(),
|
|
// Error: 3-27 cell would conflict with footer spanning the same position
|
|
// Hint: 3-27 try reducing the cell's rowspan or moving the footer
|
|
grid.cell(x: 1, y: 7)[d],
|
|
)
|
|
|
|
--- grid-footer-no-expand-with-row-pos-cell ---
|
|
#grid(
|
|
columns: 2,
|
|
[a], [],
|
|
[b], [],
|
|
fill: (_, y) => if calc.odd(y) { blue } else { red },
|
|
inset: 5pt,
|
|
grid.cell(x: 1, y: 3, rowspan: 4)[b],
|
|
grid.cell(y: 2, rowspan: 2)[a],
|
|
grid.footer(),
|
|
// Error: 3-33 cell would conflict with footer spanning the same position
|
|
// Hint: 3-33 try reducing the cell's rowspan or moving the footer
|
|
grid.cell(y: 6, rowspan: 2)[d],
|
|
)
|
|
|
|
--- grid-footer-moved-to-bottom-of-rowspans ---
|
|
#grid(
|
|
columns: 2,
|
|
[a], [],
|
|
[b], [],
|
|
stroke: red,
|
|
inset: 5pt,
|
|
grid.cell(x: 1, y: 3, rowspan: 4)[b],
|
|
grid.cell(y: 2, rowspan: 2)[a],
|
|
grid.footer(),
|
|
grid.cell(y: 4)[d],
|
|
grid.cell(y: 5)[e],
|
|
grid.cell(y: 6)[f],
|
|
)
|
|
|
|
--- grid-footer-not-at-last-row ---
|
|
// Error: 2:3-2:19 footer must end at the last row
|
|
#grid(
|
|
grid.footer([a]),
|
|
[b],
|
|
)
|
|
|
|
--- grid-footer-not-at-last-row-two-columns ---
|
|
// Error: 3:3-3:19 footer must end at the last row
|
|
#grid(
|
|
columns: 2,
|
|
grid.footer([a]),
|
|
[b],
|
|
)
|
|
|
|
--- grid-footer-overlap ---
|
|
#grid(
|
|
columns: 2,
|
|
grid.header(),
|
|
grid.footer(grid.cell(y: 2)[a]),
|
|
// Error: 3-39 cell would conflict with footer spanning the same position
|
|
// Hint: 3-39 try reducing the cell's rowspan or moving the footer
|
|
grid.cell(x: 1, y: 1, rowspan: 2)[a],
|
|
)
|
|
|
|
--- grid-footer-multiple ---
|
|
// Error: 4:3-4:19 cannot have more than one footer
|
|
#grid(
|
|
[a],
|
|
grid.footer([a]),
|
|
grid.footer([b]),
|
|
)
|
|
|
|
--- table-footer-in-grid ---
|
|
// Error: 3:3-3:20 cannot use `table.footer` as a grid footer
|
|
// Hint: 3:3-3:20 use `grid.footer` instead
|
|
#grid(
|
|
[a],
|
|
table.footer([a]),
|
|
)
|
|
|
|
--- grid-footer-in-table ---
|
|
// Error: 3:3-3:19 cannot use `grid.footer` as a table footer
|
|
// Hint: 3:3-3:19 use `table.footer` instead
|
|
#table(
|
|
[a],
|
|
grid.footer([a]),
|
|
)
|
|
|
|
--- grid-footer-in-grid-header ---
|
|
// Error: 14-28 cannot place a grid footer within another footer or header
|
|
#grid.header(grid.footer[a])
|
|
|
|
--- table-footer-in-grid-header ---
|
|
// Error: 14-29 cannot place a table footer within another footer or header
|
|
#grid.header(table.footer[a])
|
|
|
|
--- grid-footer-in-table-header ---
|
|
// Error: 15-29 cannot place a grid footer within another footer or header
|
|
#table.header(grid.footer[a])
|
|
|
|
--- table-footer-in-table-header ---
|
|
// Error: 15-30 cannot place a table footer within another footer or header
|
|
#table.header(table.footer[a])
|
|
|
|
--- grid-footer-in-grid-footer ---
|
|
// Error: 14-28 cannot place a grid footer within another footer or header
|
|
#grid.footer(grid.footer[a])
|
|
|
|
--- table-footer-in-grid-footer ---
|
|
// Error: 14-29 cannot place a table footer within another footer or header
|
|
#grid.footer(table.footer[a])
|
|
|
|
--- grid-footer-in-table-footer ---
|
|
// Error: 15-29 cannot place a grid footer within another footer or header
|
|
#table.footer(grid.footer[a])
|
|
|
|
--- table-footer-in-table-footer ---
|
|
// Error: 15-30 cannot place a table footer within another footer or header
|
|
#table.footer(table.footer[a])
|
|
|
|
--- grid-header-in-grid-footer ---
|
|
// Error: 14-28 cannot place a grid header within another header or footer
|
|
#grid.footer(grid.header[a])
|
|
|
|
--- table-header-in-grid-footer ---
|
|
// Error: 14-29 cannot place a table header within another header or footer
|
|
#grid.footer(table.header[a])
|
|
|
|
--- grid-header-in-table-footer ---
|
|
// Error: 15-29 cannot place a grid header within another header or footer
|
|
#table.footer(grid.header[a])
|
|
|
|
--- table-header-in-table-footer ---
|
|
// Error: 15-30 cannot place a table header within another header or footer
|
|
#table.footer(table.header[a])
|
|
|
|
--- grid-header-footer-block-with-fixed-height ---
|
|
#set page(height: 17em)
|
|
#table(
|
|
rows: (auto, 2.5em, auto),
|
|
table.header[*Hello*][*World*],
|
|
block(width: 2em, height: 10em, fill: red),
|
|
table.footer[*Bye*][*World*],
|
|
)
|
|
|
|
--- grid-header-footer-and-rowspan-non-contiguous-1 ---
|
|
// Rowspan sizing algorithm doesn't do the best job at non-contiguous content
|
|
// ATM.
|
|
#set page(height: 20em)
|
|
|
|
#table(
|
|
rows: (auto, 2.5em, 2em, auto, 5em, 2em, 2.5em),
|
|
table.header[*Hello*][*World*],
|
|
table.cell(rowspan: 3, lorem(20)),
|
|
table.footer[*Ok*][*Bye*],
|
|
)
|
|
|
|
--- grid-header-footer-and-rowspan-non-contiguous-2 ---
|
|
// This should look right
|
|
#set page(height: 20em)
|
|
|
|
#table(
|
|
rows: (auto, 2.5em, 2em, auto),
|
|
gutter: 3pt,
|
|
table.header[*Hello*][*World*],
|
|
table.cell(rowspan: 3, lorem(20)),
|
|
table.footer[*Ok*][*Bye*],
|
|
)
|
|
--- grid-header-and-footer-lack-of-space ---
|
|
// Test lack of space for header + text.
|
|
#set page(height: 9em + 2.5em + 1.5em)
|
|
|
|
#table(
|
|
rows: (auto, 2.5em, auto, auto, 10em, 2.5em, auto),
|
|
gutter: 3pt,
|
|
table.header[*Hello*][*World*],
|
|
table.cell(rowspan: 3, lorem(30)),
|
|
table.footer[*Ok*][*Bye*],
|
|
)
|
|
|
|
--- grid-header-and-footer-orphan-prevention ---
|
|
// Orphan header prevention test
|
|
#set page(height: 13em)
|
|
#v(8em)
|
|
#grid(
|
|
columns: 3,
|
|
gutter: 5pt,
|
|
grid.header(
|
|
[*Mui*], [*A*], grid.cell(rowspan: 2, fill: orange)[*B*],
|
|
[*Header*], [*Header* #v(0.1em)],
|
|
),
|
|
..([Test], [Test], [Test]) * 7,
|
|
grid.footer(
|
|
[*Mui*], [*A*], grid.cell(rowspan: 2, fill: orange)[*B*],
|
|
[*Footer*], [*Footer* #v(0.1em)],
|
|
),
|
|
)
|
|
|
|
--- grid-header-and-footer-empty ---
|
|
// Empty footer should just be a repeated blank row
|
|
#set page(height: 8em)
|
|
#table(
|
|
columns: 4,
|
|
align: center + horizon,
|
|
table.header(),
|
|
..range(0, 2).map(i => (
|
|
[John \##i],
|
|
table.cell(stroke: green)[123],
|
|
table.cell(stroke: blue)[456],
|
|
[789]
|
|
)).flatten(),
|
|
table.footer(),
|
|
)
|
|
|
|
--- grid-header-and-footer-containing-rowspan ---
|
|
// When a footer has a rowspan with an empty row, it should be displayed
|
|
// properly
|
|
#set page(height: 14em, width: auto)
|
|
|
|
#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(7)),
|
|
[d],
|
|
table.footer(
|
|
[eeec],
|
|
table.cell(rowspan: 2, count.step() + context count.display()),
|
|
)
|
|
)
|
|
#context count.display()
|
|
|
|
--- grid-nested-with-footers ---
|
|
// Nested table with footer should repeat both footers
|
|
#set page(height: 10em, width: auto)
|
|
#table(
|
|
table(
|
|
[a\ b\ c\ d],
|
|
table.footer[b],
|
|
),
|
|
table.footer[a],
|
|
)
|
|
|
|
--- grid-nested-footers ---
|
|
#set page(height: 12em, width: auto)
|
|
#table(
|
|
[a\ b\ c\ d],
|
|
table.footer(table(
|
|
[c],
|
|
[d],
|
|
table.footer[b],
|
|
))
|
|
)
|
|
|
|
--- grid-footer-rowspan ---
|
|
// General footer-only tests
|
|
#set page(height: 9em)
|
|
#table(
|
|
columns: 2,
|
|
[a], [],
|
|
[b], [],
|
|
[c], [],
|
|
[d], [],
|
|
[e], [],
|
|
table.footer(
|
|
[*Ok*], table.cell(rowspan: 2)[test],
|
|
[*Thanks*]
|
|
)
|
|
)
|
|
|
|
--- grid-footer-bare-1 ---
|
|
#set page(height: 5em)
|
|
#table(
|
|
table.footer[a][b][c]
|
|
)
|
|
|
|
--- grid-footer-bare-2 ---
|
|
#table(table.footer[a][b][c])
|
|
|
|
#table(
|
|
gutter: 3pt,
|
|
table.footer[a][b][c]
|
|
)
|
|
|
|
--- grid-footer-stroke-edge-cases ---
|
|
// Test footer stroke priority edge case
|
|
#set page(height: 10em)
|
|
#table(
|
|
columns: 2,
|
|
stroke: black,
|
|
..(table.cell(stroke: aqua)[d],) * 8,
|
|
table.footer(
|
|
table.cell(rowspan: 2, colspan: 2)[a],
|
|
[c], [d]
|
|
)
|
|
)
|
|
|
|
--- grid-footer-hline-and-vline-1 ---
|
|
// Footer should appear at the bottom. Red line should be above the footer.
|
|
// Green line should be on the left border.
|
|
#set page(margin: 2pt)
|
|
#set text(6pt)
|
|
#table(
|
|
columns: 2,
|
|
inset: 1.5pt,
|
|
table.cell(y: 0)[a],
|
|
table.cell(x: 1, y: 1)[a],
|
|
table.cell(y: 2)[a],
|
|
table.footer(
|
|
table.hline(stroke: red),
|
|
table.vline(stroke: green),
|
|
[b],
|
|
[c]
|
|
),
|
|
)
|
|
|
|
--- grid-footer-hline-and-vline-2 ---
|
|
// Table should be just one row. [c] appears at the third column.
|
|
#set page(margin: 2pt)
|
|
#set text(6pt)
|
|
#table(
|
|
columns: 3,
|
|
inset: 1.5pt,
|
|
table.footer(
|
|
table.cell(y: 0)[a],
|
|
table.hline(stroke: red),
|
|
table.hline(y: 1, stroke: aqua),
|
|
table.cell(y: 0)[b],
|
|
[c]
|
|
)
|
|
)
|
|
|
|
--- grid-footer-top-hlines-with-only-row-pos-cell ---
|
|
// Top hlines should attach to the top of the footer.
|
|
#set page(margin: 2pt)
|
|
#set text(6pt)
|
|
#table(
|
|
columns: 3,
|
|
inset: 2.5pt,
|
|
table.footer(
|
|
table.hline(stroke: red),
|
|
table.vline(stroke: blue),
|
|
table.cell(x: 2, y: 2)[a],
|
|
table.hline(stroke: 3pt),
|
|
table.vline(stroke: 3pt),
|
|
)
|
|
)
|
|
|
|
--- grid-footer-top-hlines-with-row-and-auto-pos-cell ---
|
|
#set page(margin: 2pt)
|
|
#set text(6pt)
|
|
#table(
|
|
columns: 3,
|
|
inset: 2.5pt,
|
|
table.footer(
|
|
table.hline(stroke: red),
|
|
table.vline(stroke: blue),
|
|
table.cell(x: 2, y: 2)[a],
|
|
[b],
|
|
table.hline(stroke: 3pt),
|
|
table.vline(stroke: 3pt),
|
|
)
|
|
)
|
|
|
|
--- grid-footer-below-rowspans ---
|
|
// Footer should go below the rowspans.
|
|
#set page(margin: 2pt)
|
|
#set text(6pt)
|
|
#table(
|
|
columns: 2,
|
|
inset: 1.5pt,
|
|
table.cell(rowspan: 2)[a], table.cell(rowspan: 2)[b],
|
|
table.footer()
|
|
)
|
|
|
|
--- grid-footer-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.footer(
|
|
table.hline(stroke: red),
|
|
table.hline(y: 1, stroke: aqua),
|
|
// Error: 5-24 cell would cause footer to expand to non-empty row 0
|
|
// Hint: 5-24 try moving its cells to available rows
|
|
table.cell(y: 0)[b],
|
|
[c]
|
|
)
|
|
)
|
|
|
|
--- grid-footer-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.footer(
|
|
[b], [c],
|
|
// Error: 6-7 cell would cause footer to expand to non-empty row 1
|
|
// Hint: 6-7 try moving its cells to available rows
|
|
[d],
|
|
),
|
|
)
|
|
|
|
--- grid-footer-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.footer(
|
|
[b], [c],
|
|
// Error: 5-24 cell would cause footer to expand to non-empty row 2
|
|
// Hint: 5-24 try moving its cells to available rows
|
|
table.cell(y: 3)[d],
|
|
),
|
|
)
|
|
|
|
--- grid-footer-conflicts-with-empty-header ---
|
|
#table(
|
|
columns: 2,
|
|
table.header(),
|
|
table.footer(
|
|
// Error: 5-24 cell would cause footer to expand to non-empty row 0
|
|
// Hint: 5-24 try moving its cells to available rows
|
|
table.cell(y: 0)[a]
|
|
),
|
|
)
|
|
|
|
--- issue-5359-column-override-stays-inside-footer ---
|
|
#table(
|
|
columns: 3,
|
|
[Outside],
|
|
table.footer(
|
|
[A], table.cell(x: 1)[B], [C],
|
|
table.cell(x: 1)[D],
|
|
),
|
|
)
|