From e9e37a313a292b8b2e406c6ed3e71c7ae35e579c Mon Sep 17 00:00:00 2001 From: PgBiel <9021226+PgBiel@users.noreply.github.com> Date: Thu, 17 Apr 2025 02:44:46 -0300 Subject: [PATCH] allow breaking apart consecutive subheaders on pathological cases - at the end of grid - right before footer --- crates/typst-layout/src/grid/repeated.rs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/crates/typst-layout/src/grid/repeated.rs b/crates/typst-layout/src/grid/repeated.rs index d638c5afc..0d39659c5 100644 --- a/crates/typst-layout/src/grid/repeated.rs +++ b/crates/typst-layout/src/grid/repeated.rs @@ -18,9 +18,27 @@ impl<'a> GridLayouter<'a> { self.upcoming_headers = new_upcoming_headers; let (non_conflicting_headers, conflicting_headers) = match conflicting_header { + // Headers succeeded by end of grid or footer are short lived and + // can be placed in separate regions (no orphan prevention). + // TODO: do this during grid resolving? + // might be needed for multiple footers. Or maybe not if we check + // "upcoming_footers" (O(1) here), however that looks like. + _ if consecutive_headers + .last() + .is_some_and(|x| x.unwrap().end == self.grid.rows.len()) + || self + .grid + .footer + .as_ref() + .zip(consecutive_headers.last()) + .is_some_and(|(f, h)| f.unwrap().start == h.unwrap().end) => + { + (Default::default(), consecutive_headers) + } + Some(conflicting_header) => { // All immediately conflicting headers will - // be placed as normal rows. + // be laid out without orphan prevention. consecutive_headers.split_at(consecutive_headers.partition_point(|h| { conflicting_header.unwrap().level > h.unwrap().level }))