summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/typst-library/src/layout/mod.rs2
-rw-r--r--crates/typst-library/src/layout/spacing.rs4
-rw-r--r--crates/typst-library/src/meta/metadata.rs2
-rw-r--r--crates/typst-library/src/shared/behave.rs14
-rw-r--r--crates/typst/src/model/content.rs2
-rw-r--r--crates/typst/src/model/realize.rs4
-rw-r--r--tests/ref/layout/pagebreak-empty.pngbin0 -> 18958 bytes
-rw-r--r--tests/typ/layout/pagebreak-empty.typ30
8 files changed, 46 insertions, 12 deletions
diff --git a/crates/typst-library/src/layout/mod.rs b/crates/typst-library/src/layout/mod.rs
index ce728ccb..3334d5aa 100644
--- a/crates/typst-library/src/layout/mod.rs
+++ b/crates/typst-library/src/layout/mod.rs
@@ -467,7 +467,7 @@ impl<'a, 'v, 't> Builder<'a, 'v, 't> {
fn interrupt_page(&mut self, styles: Option<StyleChain<'a>>) -> SourceResult<()> {
self.interrupt_par()?;
let Some(doc) = &mut self.doc else { return Ok(()) };
- if !self.flow.0.is_empty() || (doc.keep_next && styles.is_some()) {
+ if !self.flow.0.is_basically_empty() || (doc.keep_next && styles.is_some()) {
let (flow, shared) = mem::take(&mut self.flow).0.finish();
let styles = if shared == StyleChain::default() {
styles.unwrap_or_default()
diff --git a/crates/typst-library/src/layout/spacing.rs b/crates/typst-library/src/layout/spacing.rs
index 950f024f..69a5d952 100644
--- a/crates/typst-library/src/layout/spacing.rs
+++ b/crates/typst-library/src/layout/spacing.rs
@@ -63,7 +63,7 @@ impl Behave for HElem {
} else if self.weak(StyleChain::default()) {
Behaviour::Weak(1)
} else {
- Behaviour::Ignorant
+ Behaviour::Invisible
}
}
@@ -158,7 +158,7 @@ impl Behave for VElem {
} else if self.weakness(StyleChain::default()) > 0 {
Behaviour::Weak(self.weakness(StyleChain::default()))
} else {
- Behaviour::Ignorant
+ Behaviour::Invisible
}
}
diff --git a/crates/typst-library/src/meta/metadata.rs b/crates/typst-library/src/meta/metadata.rs
index ed0d1986..89d1409a 100644
--- a/crates/typst-library/src/meta/metadata.rs
+++ b/crates/typst-library/src/meta/metadata.rs
@@ -38,6 +38,6 @@ impl Show for MetadataElem {
impl Behave for MetadataElem {
fn behaviour(&self) -> Behaviour {
- Behaviour::Ignorant
+ Behaviour::Invisible
}
}
diff --git a/crates/typst-library/src/shared/behave.rs b/crates/typst-library/src/shared/behave.rs
index 6a1aa127..471daa18 100644
--- a/crates/typst-library/src/shared/behave.rs
+++ b/crates/typst-library/src/shared/behave.rs
@@ -34,10 +34,9 @@ impl<'a> BehavedBuilder<'a> {
/// probably collapse.
pub fn is_basically_empty(&self) -> bool {
self.builder.is_empty()
- && self
- .staged
- .iter()
- .all(|(_, behaviour, _)| matches!(behaviour, Behaviour::Weak(_)))
+ && self.staged.iter().all(|(_, behaviour, _)| {
+ matches!(behaviour, Behaviour::Weak(_) | Behaviour::Invisible)
+ })
}
/// Push an item into the sequence.
@@ -74,7 +73,7 @@ impl<'a> BehavedBuilder<'a> {
self.builder.push(elem, styles);
self.last = interaction;
}
- Behaviour::Ignorant => {
+ Behaviour::Ignorant | Behaviour::Invisible => {
self.staged.push((elem, interaction, styles));
}
}
@@ -95,7 +94,10 @@ impl<'a> BehavedBuilder<'a> {
/// false.
fn flush(&mut self, supportive: bool) {
for (item, interaction, styles) in self.staged.drain(..) {
- if supportive || interaction == Behaviour::Ignorant {
+ if supportive
+ || interaction == Behaviour::Ignorant
+ || interaction == Behaviour::Invisible
+ {
self.builder.push(item, styles);
}
}
diff --git a/crates/typst/src/model/content.rs b/crates/typst/src/model/content.rs
index f1600f25..6541ab6b 100644
--- a/crates/typst/src/model/content.rs
+++ b/crates/typst/src/model/content.rs
@@ -610,7 +610,7 @@ pub struct MetaElem {
impl Behave for MetaElem {
fn behaviour(&self) -> Behaviour {
- Behaviour::Ignorant
+ Behaviour::Invisible
}
}
diff --git a/crates/typst/src/model/realize.rs b/crates/typst/src/model/realize.rs
index 01c46b81..3e683d3e 100644
--- a/crates/typst/src/model/realize.rs
+++ b/crates/typst/src/model/realize.rs
@@ -214,8 +214,10 @@ pub enum Behaviour {
/// An element that destroys adjacent weak elements.
Destructive,
/// An element that does not interact at all with other elements, having the
- /// same effect as if it didn't exist.
+ /// same effect as if it didn't exist, but has a visual representation.
Ignorant,
+ /// An element that does not have a visual representation.
+ Invisible,
}
/// Guards content against being affected by the same show rule multiple times.
diff --git a/tests/ref/layout/pagebreak-empty.png b/tests/ref/layout/pagebreak-empty.png
new file mode 100644
index 00000000..412c4e8d
--- /dev/null
+++ b/tests/ref/layout/pagebreak-empty.png
Binary files differ
diff --git a/tests/typ/layout/pagebreak-empty.typ b/tests/typ/layout/pagebreak-empty.typ
new file mode 100644
index 00000000..c228959e
--- /dev/null
+++ b/tests/typ/layout/pagebreak-empty.typ
@@ -0,0 +1,30 @@
+// Test page breaks on basically empty pages.
+
+---
+// After place
+// Should result in three pages.
+First
+#pagebreak(weak: true)
+#place(right)[placed A]
+#pagebreak(weak: true)
+Third
+
+---
+// After only ignorables & invisibles
+// Should result in two pages.
+First
+#pagebreak(weak: true)
+#counter(page).update(1)
+#metadata("Some")
+#pagebreak(weak: true)
+Second
+
+---
+// After only ignorables, but regular break
+// Should result in three pages.
+First
+#pagebreak()
+#counter(page).update(1)
+#metadata("Some")
+#pagebreak()
+Third