diff options
| author | PgBiel <9021226+PgBiel@users.noreply.github.com> | 2025-06-10 11:41:16 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-06-10 14:41:16 +0000 |
| commit | 7c7b962b98a09c1baabdd03ff4ccad8f6d817b37 (patch) | |
| tree | c44c9b82e3c7ec7bf8feb44cedeae9fa71a107cb /tests/suite | |
| parent | a18ca3481da17a4de1cc7f9890f0c61efb480655 (diff) | |
Table multiple headers and subheaders (#6168)
Diffstat (limited to 'tests/suite')
| -rw-r--r-- | tests/suite/layout/grid/footers.typ | 23 | ||||
| -rw-r--r-- | tests/suite/layout/grid/headers.typ | 171 | ||||
| -rw-r--r-- | tests/suite/layout/grid/html.typ | 75 | ||||
| -rw-r--r-- | tests/suite/layout/grid/subheaders.typ | 602 |
4 files changed, 863 insertions, 8 deletions
diff --git a/tests/suite/layout/grid/footers.typ b/tests/suite/layout/grid/footers.typ index f7f1deb0..c0b03f50 100644 --- a/tests/suite/layout/grid/footers.typ +++ b/tests/suite/layout/grid/footers.typ @@ -389,6 +389,29 @@ table.footer[a][b][c] ) +--- grid-footer-repeatable-unbreakable --- +#set page(height: 8em, width: auto) +#table( + [h], + table.footer( + [a], + [b], + [c], + ) +) + +--- grid-footer-non-repeatable-unbreakable --- +#set page(height: 8em, width: auto) +#table( + [h], + table.footer( + [a], + [b], + [c], + repeat: false, + ) +) + --- grid-footer-stroke-edge-cases --- // Test footer stroke priority edge case #set page(height: 10em) diff --git a/tests/suite/layout/grid/headers.typ b/tests/suite/layout/grid/headers.typ index 229bce61..ea222ee8 100644 --- a/tests/suite/layout/grid/headers.typ +++ b/tests/suite/layout/grid/headers.typ @@ -118,30 +118,81 @@ ) --- 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-header-multiple --- #grid( grid.header([a]), grid.header([b]), [a], ) +--- grid-header-skip --- +#grid( + columns: 2, + [x], [y], + grid.header([a]), + grid.header([b]), + grid.cell(x: 1)[c], [d], + grid.header([e]), + [f], grid.cell(x: 1)[g] +) + +--- grid-header-too-large-non-repeating-orphan --- +#set page(height: 8em) +#grid( + grid.header( + [a\ ] * 5, + repeat: false, + ), + [b] +) + +--- grid-header-too-large-repeating-orphan --- +#set page(height: 8em) +#grid( + grid.header( + [a\ ] * 5, + repeat: true, + ), + [b] +) + +--- grid-header-too-large-repeating-orphan-with-footer --- +#set page(height: 8em) +#grid( + grid.header( + [a\ ] * 5, + repeat: true, + ), + [b], + grid.footer( + [c], + repeat: true, + ) +) + +--- grid-header-too-large-repeating-orphan-not-at-first-row --- +#set page(height: 8em) +#grid( + [b], + grid.header( + [a\ ] * 5, + repeat: true, + ), + [c], +) + --- 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 @@ -228,6 +279,51 @@ table.cell(rowspan: 3, lines(15)) ) +--- grid-header-and-rowspan-contiguous-1 --- +// Block should occupy all space +#set page(height: 15em) + +#table( + rows: (auto, 2.5em, 2em, auto), + gutter: 3pt, + inset: 0pt, + table.header( + [*H*], + [*W*] + ), + table.cell(rowspan: 3, block(height: 2.5em + 2em + 20em, width: 100%, fill: red)) +) + +--- grid-header-and-rowspan-contiguous-2 --- +// Block should occupy all space +#set page(height: 15em) + +#table( + rows: (auto, 2.5em, 10em, 5em, auto), + gutter: 3pt, + inset: 0pt, + table.header( + [*H*], + [*W*] + ), + table.cell(rowspan: 3, block(height: 2.5em + 2em + 20em, width: 100%, fill: red)) +) + +--- grid-header-and-large-auto-contiguous --- +// Block should occupy all space +#set page(height: 15em) + +#table( + rows: (auto, 4.5em, auto), + gutter: 3pt, + inset: 0pt, + table.header( + [*H*], + [*W*] + ), + block(height: 2.5em + 2em + 20em, width: 100%, fill: red) +) + --- grid-header-lack-of-space --- // Test lack of space for header + text. #set page(height: 8em) @@ -255,6 +351,17 @@ ..([Test], [Test], [Test]) * 20 ) +--- grid-header-non-repeating-orphan-prevention --- +#set page(height: 5em) +#v(2em) +#grid( + grid.header(repeat: false)[*Abc*], + [a], + [b], + [c], + [d] +) + --- grid-header-empty --- // Empty header should just be a repeated blank row #set page(height: 12em) @@ -339,6 +446,56 @@ [a\ b] ) +--- grid-header-not-at-the-top --- +#set page(height: 5em) +#v(2em) +#grid( + [a], + [b], + grid.header[*Abc*], + [d], + [e], + [f], +) + +--- grid-header-replace --- +#set page(height: 5em) +#v(1.5em) +#grid( + grid.header[*Abc*], + [a], + [b], + grid.header[*Def*], + [d], + [e], + [f], +) + +--- grid-header-replace-orphan --- +#set page(height: 5em) +#grid( + grid.header[*Abc*], + [a], + [b], + grid.header[*Def*], + [d], + [e], + [f], +) + +--- grid-header-replace-doesnt-fit --- +#set page(height: 5em) +#v(0.8em) +#grid( + grid.header[*Abc*], + [a], + [b], + grid.header[*Def*], + [d], + [e], + [f], +) + --- grid-header-stroke-edge-cases --- // Test header stroke priority edge case (last header row removed) #set page(height: 8em) @@ -463,8 +620,6 @@ #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], diff --git a/tests/suite/layout/grid/html.typ b/tests/suite/layout/grid/html.typ index 10345cb0..cf98d4bc 100644 --- a/tests/suite/layout/grid/html.typ +++ b/tests/suite/layout/grid/html.typ @@ -57,3 +57,78 @@ [d], [e], [f], [g], [h], [i] ) + +--- multi-header-table html --- +#table( + columns: 2, + + table.header( + [First], [Header] + ), + table.header( + [Second], [Header] + ), + table.header( + [Level 2], [Header], + level: 2, + ), + table.header( + [Level 3], [Header], + level: 3, + ), + + [Body], [Cells], + [Yet], [More], + + table.footer( + [Footer], [Row], + [Ending], [Table], + ), +) + +--- multi-header-inside-table html --- +#table( + columns: 2, + + table.header( + [First], [Header] + ), + table.header( + [Second], [Header] + ), + table.header( + [Level 2], [Header], + level: 2, + ), + table.header( + [Level 3], [Header], + level: 3, + ), + + [Body], [Cells], + [Yet], [More], + + table.header( + [Level 2], [Header Inside], + level: 2, + ), + table.header( + [Level 3], + level: 3, + ), + + [Even], [More], + [Body], [Cells], + + table.header( + [One Last Header], + [For Good Measure], + repeat: false, + level: 4, + ), + + table.footer( + [Footer], [Row], + [Ending], [Table], + ), +) diff --git a/tests/suite/layout/grid/subheaders.typ b/tests/suite/layout/grid/subheaders.typ new file mode 100644 index 00000000..56bed6a5 --- /dev/null +++ b/tests/suite/layout/grid/subheaders.typ @@ -0,0 +1,602 @@ +--- grid-subheaders-demo --- +#set page(height: 15.2em) +#table( + columns: 2, + align: center, + table.header( + table.cell(colspan: 2)[*Regional User Data*], + ), + table.header( + level: 2, + table.cell(colspan: 2)[*Germany*], + [*Username*], [*Joined*] + ), + [john123], [2024], + [rob8], [2025], + [joe1], [2025], + [joe2], [2025], + [martha], [2025], + [pear], [2025], + table.header( + level: 2, + table.cell(colspan: 2)[*United States*], + [*Username*], [*Joined*] + ), + [cool4], [2023], + [roger], [2023], + [bigfan55], [2022] +) + +--- grid-subheaders-colorful --- +#set page(width: auto, height: 12em) +#let rows(n) = { + range(n).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( + columns: 5, + align: center + horizon, + table.header( + table.cell(colspan: 5)[*Cool Zone*], + ), + table.header( + level: 2, + table.cell(stroke: red)[*Name*], table.cell(stroke: aqua)[*Number*], [*Data 1*], [*Data 2*], [*Etc*], + table.hline(start: 2, end: 3, stroke: yellow) + ), + ..rows(2), + table.header( + level: 2, + table.cell(stroke: red)[*New Name*], table.cell(stroke: aqua, colspan: 4)[*Other Data*], + table.hline(start: 2, end: 3, stroke: yellow) + ), + ..rows(3) +) + +--- grid-subheaders-basic --- +#grid( + grid.header([a]), + grid.header(level: 2, [b]), + [c] +) + +--- grid-subheaders-basic-non-consecutive --- +#grid( + grid.header([a]), + [x], + grid.header(level: 2, [b]), + [y], +) + +--- grid-subheaders-basic-replace --- +#grid( + grid.header([a]), + [x], + grid.header(level: 2, [b]), + [y], + grid.header(level: 2, [c]), + [z], +) + +--- grid-subheaders-basic-with-footer --- +#grid( + grid.header([a]), + grid.header(level: 2, [b]), + [c], + grid.footer([d]) +) + +--- grid-subheaders-basic-non-consecutive-with-footer --- +#grid( + grid.header([a]), + [x], + grid.header(level: 2, [b]), + [y], + grid.footer([f]) +) + +--- grid-subheaders-repeat --- +#set page(height: 8em) +#grid( + grid.header([a]), + grid.header(level: 2, [b]), + ..([c],) * 10, +) + +--- grid-subheaders-repeat-non-consecutive --- +#set page(height: 8em) +#grid( + grid.header([a]), + [x], + grid.header(level: 2, [b]), + ..([y],) * 10, +) + +--- grid-subheaders-repeat-with-footer --- +#set page(height: 8em) +#grid( + grid.header([a]), + [m], + grid.header(level: 2, [b]), + ..([c],) * 10, + grid.footer([f]) +) + +--- grid-subheaders-repeat-gutter --- +// Gutter below the header is also repeated +#set page(height: 8em) +#grid( + inset: (bottom: 0.5pt), + stroke: (bottom: 1pt), + gutter: (1pt, 6pt, 1pt), + grid.header([a]), + grid.header(level: 2, [b]), + ..([c],) * 10, +) + +--- grid-subheaders-repeat-replace --- +#set page(height: 8em) +#grid( + grid.header([a]), + [x], + grid.header(level: 2, [b]), + ..([y],) * 10, + grid.header(level: 2, [c]), + ..([z],) * 10, +) + +--- grid-subheaders-repeat-replace-multiple-levels --- +#set page(height: 8em) +#grid( + grid.header([a]), + [x], + grid.header(level: 2, [b]), + grid.header(level: 3, [c]), + ..([y],) * 10, + grid.header(level: 2, [d]), + ..([z],) * 6, +) + +--- grid-subheaders-repeat-replace-gutter --- +#set page(height: 8em) +#grid( + gutter: 3pt, + grid.header([a]), + [x], + grid.header(level: 2, [b]), + ..([y],) * 8, + grid.header(level: 2, [c]), + ..([z],) * 4, +) + +--- grid-subheaders-repeat-replace-orphan --- +#set page(height: 8em) +#grid( + grid.header([a]), + [x], + grid.header(level: 2, [b]), + ..([y],) * 12, + grid.header(level: 2, [c]), + ..([z],) * 10, +) + +--- grid-subheaders-repeat-replace-double-orphan --- +#set page(height: 8em) +#grid( + grid.header([a]), + [x], + grid.header(level: 2, [b]), + ..([y],) * 11, + grid.header(level: 2, [c]), + grid.header(level: 3, [d]), + ..([z],) * 10, +) + +--- grid-subheaders-repeat-replace-gutter-orphan-at-child --- +#set page(height: 8em) +#grid( + gutter: 3pt, + grid.header([a]), + [x], + grid.header(level: 2, [b]), + ..([y],) * 9, + grid.header(level: 2, [c]), + [z \ z], + ..([z],) * 3, +) + +--- grid-subheaders-repeat-replace-gutter-orphan-at-gutter --- +#set page(height: 8em) +#grid( + gutter: 3pt, + grid.header([a]), + [x], + grid.header(level: 2, [b]), + ..([y],) * 9, + box(height: 3pt), + grid.header(level: 2, [c]), + ..([z],) * 4, +) + +--- grid-subheaders-repeat-replace-didnt-fit-once --- +#set page(height: 8em) +#grid( + grid.header([a]), + [x], + grid.header(level: 2, [b]), + ..([y],) * 10, + grid.header(level: 2, [c\ c\ c]), + ..([z],) * 4, +) + +--- grid-subheaders-repeat-replace-with-footer --- +#set page(height: 8em) +#grid( + grid.header([a]), + [x], + grid.header(level: 2, [b]), + grid.header(level: 3, [c]), + ..([y],) * 10, + grid.header(level: 2, [d]), + ..([z],) * 6, + grid.footer([f]) +) + +--- grid-subheaders-repeat-replace-with-footer-orphan --- +#set page(height: 8em) +#grid( + grid.header([a]), + [x], + grid.header(level: 2, [b]), + ..([y],) * 10, + grid.header(level: 2, [c]), + ..([z],) * 10, + grid.footer([f]) +) + +--- grid-subheaders-repeat-replace-short-lived --- +// No orphan prevention for short-lived headers +// (followed by replacing headers). +#set page(height: 8em) +#grid( + grid.header([a]), + grid.header(level: 2, [b]), + grid.header(level: 2, [c]), + grid.header(level: 2, [d]), + grid.header(level: 2, [e]), + grid.header(level: 2, [f]), + grid.header(level: 2, [g]), + grid.header(level: 2, [h]), + grid.header(level: 2, [i]), + grid.header(level: 2, [j]), + grid.header(level: 3, [k]), + ..([z],) * 10, +) + +--- grid-subheaders-repeat-short-lived-also-replaces --- +// Short-lived subheaders must still replace their conflicting predecessors. +#set page(height: 8em) +#grid( + // This has to go + grid.header(level: 3, [a]), + [w], + grid.header(level: 2, [b]), + grid.header(level: 2, [c]), + grid.header(level: 2, [d]), + grid.header(level: 2, [e]), + grid.header(level: 2, [f]), + grid.header(level: 2, [g]), + grid.header(level: 2, [h]), + grid.header(level: 2, [i]), + grid.header(level: 2, [j]), + grid.header(level: 3, [k]), + ..([z],) * 10, +) + +--- grid-subheaders-multi-page-row --- +#set page(height: 8em) +#grid( + columns: 2, + grid.header([a]), + [x], + grid.header(level: 2, [b]), + [y], + grid.header(level: 3, [c]), + [a], [b], + grid.cell( + block(fill: red, width: 1.5em, height: 6.4em) + ), + [y], + ..([z],) * 10, +) + +--- grid-subheaders-non-repeat --- +#set page(height: 8em) +#grid( + grid.header(repeat: false, [a]), + [x], + grid.header(level: 2, repeat: false, [b]), + ..([y],) * 10, +) + +--- grid-subheaders-non-repeat-replace --- +#set page(height: 8em) +#grid( + grid.header([a]), + [x], + grid.header(level: 2, [b]), + grid.header(level: 3, [c]), + ..([y],) * 9, + grid.header(level: 2, repeat: false, [d]), + ..([z],) * 6, +) + +--- grid-subheaders-non-repeating-replace-orphan --- +#set page(height: 8em) +#grid( + grid.header([a]), + [x], + grid.header(level: 2, [b]), + ..([y],) * 12, + grid.header(level: 2, repeat: false, [c]), + ..([z],) * 10, +) + +--- grid-subheaders-non-repeating-replace-didnt-fit-once --- +#set page(height: 8em) +#grid( + grid.header([a]), + [x], + grid.header(level: 2, [b]), + ..([y],) * 10, + grid.header(level: 2, repeat: false, [c\ c\ c]), + ..([z],) * 4, +) + +--- grid-subheaders-multi-page-rowspan --- +#set page(height: 8em) +#grid( + columns: 2, + grid.header([a]), + [x], + grid.header(level: 2, [b]), + [y], + grid.header(level: 3, [c]), + [z], [z], + grid.cell( + rowspan: 5, + block(fill: red, width: 1.5em, height: 6.4em) + ), + [cell], + [cell] +) + +--- grid-subheaders-multi-page-row-right-after --- +#set page(height: 8em) +#grid( + columns: 1, + grid.header([a]), + [x], + grid.header(level: 2, [b]), + grid.header(level: 3, [c]), + grid.cell( + block(fill: red, width: 1.5em, height: 6.4em) + ), + [done.], + [done.] +) + +--- grid-subheaders-multi-page-rowspan-right-after --- +#set page(height: 8em) +#grid( + columns: 2, + grid.header([a]), + [x], [y], + grid.header(level: 2, [b]), + grid.header(level: 3, [c]), + grid.cell( + rowspan: 5, + block(fill: red, width: 1.5em, height: 6.4em) + ), + [cell], + [cell], + grid.cell(x: 0)[done.], + grid.cell(x: 0)[done.] +) + +--- grid-subheaders-multi-page-row-with-footer --- +#set page(height: 8em) +#grid( + columns: 2, + grid.header([a]), + [x], + grid.header(level: 2, [b]), + [y], + grid.header(level: 3, [c]), + [a], [b], + grid.cell( + block(fill: red, width: 1.5em, height: 6.4em) + ), + [y], + ..([z],) * 10, + grid.footer([f]) +) + +--- grid-subheaders-multi-page-rowspan-with-footer --- +#set page(height: 8em) +#grid( + columns: 2, + grid.header([a]), + [x], + grid.header(level: 2, [b]), + [y], + grid.header(level: 3, [c]), + [z], [z], + grid.cell( + rowspan: 5, + block(fill: red, width: 1.5em, height: 6.4em) + ), + [cell], + [cell], + grid.footer([f]) +) + +--- grid-subheaders-multi-page-row-right-after-with-footer --- +#set page(height: 8em) +#grid( + columns: 1, + grid.header([a]), + [x], + grid.header(level: 2, [b]), + grid.header(level: 3, [c]), + grid.cell( + block(fill: red, width: 1.5em, height: 6.4em) + ), + [done.], + [done.], + grid.footer([f]) +) + +--- grid-subheaders-multi-page-rowspan-gutter --- +#set page(height: 9em) +#grid( + columns: 2, + column-gutter: 4pt, + row-gutter: (0pt, 4pt, 8pt, 4pt), + inset: (bottom: 0.5pt), + stroke: (bottom: 1pt), + grid.header([a]), + [x], + grid.header(level: 2, [b]), + [y], + grid.header(level: 3, [c]), + [z], [z], + grid.cell( + rowspan: 5, + block(fill: red, width: 1.5em, height: 6.4em) + ), + [cell], + [cell], + [a\ b], + grid.cell(x: 0)[end], +) + +--- grid-subheaders-non-repeating-header-before-multi-page-row --- +#set page(height: 6em) +#grid( + grid.header(repeat: false, [h]), + [row #colbreak() row] +) + + +--- grid-subheaders-short-lived-no-orphan-prevention --- +// No orphan prevention for short-lived headers. +#set page(height: 8em) +#v(5em) +#grid( + grid.header(level: 2, [b]), + grid.header(level: 2, [c]), + [d] +) + +--- grid-subheaders-repeating-orphan-prevention --- +#set page(height: 8em) +#v(4.5em) +#grid( + grid.header(repeat: true, level: 2, [L2]), + grid.header(repeat: true, level: 4, [L4]), + [a] +) + +--- grid-subheaders-non-repeating-orphan-prevention --- +#set page(height: 8em) +#v(4.5em) +#grid( + grid.header(repeat: false, level: 2, [L2]), + grid.header(repeat: false, level: 4, [L4]), + [a] +) + +--- grid-subheaders-alone --- +#table( + table.header([a]), + table.header(level: 2, [b]), +) + +--- grid-subheaders-alone-no-orphan-prevention --- +#set page(height: 5.3em) +#v(2em) +#grid( + grid.header([L1]), + grid.header(level: 2, [L2]), +) + +--- grid-subheaders-alone-with-gutter-no-orphan-prevention --- +#set page(height: 5.3em) +#v(2em) +#grid( + gutter: 3pt, + grid.header([L1]), + grid.header(level: 2, [L2]), +) + +--- grid-subheaders-alone-with-footer --- +#table( + table.header([a]), + table.header(level: 2, [b]), + table.footer([c]) +) + +--- grid-subheaders-alone-with-footer-no-orphan-prevention --- +#set page(height: 5.3em) +#table( + table.header([L1]), + table.header(level: 2, [L2]), + table.footer([a]) +) + +--- grid-subheaders-alone-with-gutter-and-footer-no-orphan-prevention --- +#set page(height: 5.5em) +#table( + gutter: 4pt, + table.header([L1]), + table.header(level: 2, [L2]), + table.footer([a]) +) + +--- grid-subheaders-too-large-non-repeating-orphan-before-auto --- +#set page(height: 8em) +#grid( + grid.header([1]), + grid.header([a\ ] * 2, level: 2, repeat: false), + grid.header([2], level: 3), + [b\ b\ b], +) + +--- grid-subheaders-too-large-repeating-orphan-before-auto --- +#set page(height: 8em) +#grid( + grid.header([1]), + grid.header([a\ ] * 2, level: 2, repeat: true), + grid.header([2], level: 3), + rect(width: 10pt, height: 3em, fill: red), +) + +--- grid-subheaders-too-large-repeating-orphan-before-relative --- +#set page(height: 8em) +#grid( + rows: (auto, auto, auto, 3em), + grid.header([1]), + grid.header([a\ ] * 2, level: 2, repeat: true), + grid.header([2], level: 3), + rect(width: 10pt, height: 3em, fill: red), +) + +--- grid-subheaders-too-large-non-repeating-orphan-before-relative --- +#set page(height: 8em) +#grid( + rows: (auto, auto, auto, 3em), + grid.header([1]), + grid.header([a\ ] * 2, level: 2, repeat: false), + grid.header([2], level: 3), + rect(width: 10pt, height: 3em, fill: red), +) |
