diff --git a/crates/typst-library/src/layout/page.rs b/crates/typst-library/src/layout/page.rs index 05d0731d3..19184d22b 100644 --- a/crates/typst-library/src/layout/page.rs +++ b/crates/typst-library/src/layout/page.rs @@ -310,7 +310,6 @@ pub struct PageElem { pub body: Content, /// Whether the page should be aligned to an even or odd page. - /// Not part of the public API for now. #[internal] pub clear_to: Option, } @@ -328,6 +327,7 @@ impl PageElem { vt: &mut Vt, styles: StyleChain, page_counter: &mut ManualPageCounter, + extend_to: Option, ) -> SourceResult { tracing::info!("Page layout"); @@ -378,12 +378,10 @@ impl PageElem { let mut frames = child.layout(vt, styles, regions)?.into_frames(); // Align the child to the pagebreak's parity. - if self - .clear_to(styles) - .is_some_and(|p| !p.matches(page_counter.physical().get())) - { + if extend_to.is_some_and(|p| p.matches(page_counter.physical().get())) { + // Insert empty page after the current pages. let size = area.map(Abs::is_finite).select(area, Size::zero()); - frames.insert(0, Frame::new(size)); + frames.push(Frame::new(size)); } let fill = self.fill(styles); diff --git a/crates/typst-library/src/meta/document.rs b/crates/typst-library/src/meta/document.rs index 01095dc93..200b5d9dd 100644 --- a/crates/typst-library/src/meta/document.rs +++ b/crates/typst-library/src/meta/document.rs @@ -48,7 +48,10 @@ impl LayoutRoot for DocumentElem { let mut pages = vec![]; let mut page_counter = ManualPageCounter::new(); - for mut child in &self.children() { + let children = self.children(); + let mut iter = children.iter().peekable(); + + while let Some(mut child) = iter.next() { let outer = styles; let mut styles = styles; if let Some((elem, local)) = child.to_styled() { @@ -57,7 +60,13 @@ impl LayoutRoot for DocumentElem { } if let Some(page) = child.to::() { - let fragment = page.layout(vt, styles, &mut page_counter)?; + let extend_to = iter.peek().and_then(|&next| { + next.to_styled() + .map_or(next, |(elem, _)| elem) + .to::()? + .clear_to(styles) + }); + let fragment = page.layout(vt, styles, &mut page_counter, extend_to)?; pages.extend(fragment); } else { bail!(child.span(), "unexpected document child"); diff --git a/tests/ref/bugs/pagebreak-numbering.png b/tests/ref/bugs/pagebreak-numbering.png new file mode 100644 index 000000000..96f047a88 Binary files /dev/null and b/tests/ref/bugs/pagebreak-numbering.png differ diff --git a/tests/ref/bugs/pagebreak-set-style.png b/tests/ref/bugs/pagebreak-set-style.png new file mode 100644 index 000000000..f81b8c2f2 Binary files /dev/null and b/tests/ref/bugs/pagebreak-set-style.png differ diff --git a/tests/typ/bugs/pagebreak-numbering.typ b/tests/typ/bugs/pagebreak-numbering.typ new file mode 100644 index 000000000..d805c2c6b --- /dev/null +++ b/tests/typ/bugs/pagebreak-numbering.typ @@ -0,0 +1,13 @@ +// https://github.com/typst/typst/issues/2095 +// The empty page 2 should not have a page number + +#set page(numbering: none) +This and next page should not be numbered + +#pagebreak(weak: true, to: "odd") + +#set page(numbering: "1") +#counter(page).update(1) + +This page should + diff --git a/tests/typ/bugs/pagebreak-set-style.typ b/tests/typ/bugs/pagebreak-set-style.typ new file mode 100644 index 000000000..1ac24652c --- /dev/null +++ b/tests/typ/bugs/pagebreak-set-style.typ @@ -0,0 +1,12 @@ +// https://github.com/typst/typst/issues/2162 +// The styles should not be applied to the pagebreak empty page, +// it should only be applied after that. + +#pagebreak(to: "even") // We should now skip to page 2 + +Some text on page 2 + +#pagebreak(to: "even") // We should now skip to page 4 + +#set page(fill: orange) // This sets the color of the page starting from page 4 +Some text on page 4