From 315612b1f7be637c0c1a6a123f8802e09bee332a Mon Sep 17 00:00:00 2001 From: PgBiel <9021226+PgBiel@users.noreply.github.com> Date: Sat, 14 Jun 2025 19:31:27 -0300 Subject: [PATCH] detect short lived headers and footers at the table edges even if headers and footers are interleaved --- .../typst-library/src/layout/grid/resolve.rs | 83 +++++++++---------- 1 file changed, 40 insertions(+), 43 deletions(-) diff --git a/crates/typst-library/src/layout/grid/resolve.rs b/crates/typst-library/src/layout/grid/resolve.rs index d51b55516..1fe7ae277 100644 --- a/crates/typst-library/src/layout/grid/resolve.rs +++ b/crates/typst-library/src/layout/grid/resolve.rs @@ -1042,9 +1042,11 @@ impl<'x> CellGridResolver<'_, '_, 'x> { let mut headers: Vec> = vec![]; let mut footers: Vec> = vec![]; - // If true, there has been at least one cell besides headers and - // footers. When false, footers at the end are forced to not repeat. - let mut at_least_one_cell = false; + // The first and last rows containing a cell outside a row group, that + // is, outside a header or footer. Headers after the last such row and + // footers before the first such row have no "children" cells and thus + // are not repeated. + let mut first_last_cell_rows = None; // We can't just use the cell's index in the 'cells' vector to // determine its automatic position, since cells could have arbitrary @@ -1094,7 +1096,7 @@ impl<'x> CellGridResolver<'_, '_, 'x> { &mut next_header, &mut next_footer, &mut resolved_cells, - &mut at_least_one_cell, + &mut first_last_cell_rows, child, )?; } @@ -1115,7 +1117,7 @@ impl<'x> CellGridResolver<'_, '_, 'x> { &mut headers, &mut footers, row_amount, - at_least_one_cell, + first_last_cell_rows, )?; Ok(CellGrid::new_internal( @@ -1149,7 +1151,7 @@ impl<'x> CellGridResolver<'_, '_, 'x> { next_header: &mut usize, next_footer: &mut usize, resolved_cells: &mut Vec>>, - at_least_one_cell: &mut bool, + first_last_cell_rows: &mut Option<(usize, usize)>, child: ResolvableGridChild, ) -> SourceResult<()> where @@ -1260,13 +1262,7 @@ impl<'x> CellGridResolver<'_, '_, 'x> { (Some(items), None) } - ResolvableGridChild::Item(item) => { - if matches!(item, ResolvableGridItem::Cell(_)) { - *at_least_one_cell = true; - } - - (None, Some(item)) - } + ResolvableGridChild::Item(item) => (None, Some(item)), }; let items = header_footer_items.into_iter().flatten().chain(simple_item); @@ -1448,6 +1444,13 @@ impl<'x> CellGridResolver<'_, '_, 'x> { // no longer appear at the top. *top_hlines_end = Some(pending_hlines.len()); } + } else { + // This is a cell outside a row group. + *first_last_cell_rows = Some( + first_last_cell_rows + .map(|(first, last)| (first.min(y), last.max(y))) + .unwrap_or((y, y)), + ); } // Let's resolve the cell so it can determine its own fields @@ -1788,42 +1791,41 @@ impl<'x> CellGridResolver<'_, '_, 'x> { /// an adjacent gutter row to be repeated alongside that header or /// footer, if there is gutter; /// 3. Wrap headers and footers in the correct [`Repeatable`] variant. - #[allow(clippy::type_complexity)] fn finalize_headers_and_footers( &self, has_gutter: bool, headers: &mut [Repeatable
], footers: &mut [Repeatable