diff --git a/crates/typst/src/math/fragment.rs b/crates/typst/src/math/fragment.rs index da4cb0adc..c6de24863 100644 --- a/crates/typst/src/math/fragment.rs +++ b/crates/typst/src/math/fragment.rs @@ -71,6 +71,13 @@ impl MathFragment { } } + pub fn is_ignorant(&self) -> bool { + match self { + Self::Frame(fragment) => fragment.ignorant, + _ => false, + } + } + pub fn class(&self) -> MathClass { match self { Self::Glyph(glyph) => glyph.class, @@ -441,6 +448,7 @@ pub struct FrameFragment { pub italics_correction: Abs, pub accent_attach: Abs, pub text_like: bool, + pub ignorant: bool, } impl FrameFragment { @@ -459,6 +467,7 @@ impl FrameFragment { italics_correction: Abs::zero(), accent_attach, text_like: false, + ignorant: false, } } @@ -489,6 +498,10 @@ impl FrameFragment { pub fn with_text_like(self, text_like: bool) -> Self { Self { text_like, ..self } } + + pub fn with_ignorant(self, ignorant: bool) -> Self { + Self { ignorant, ..self } + } } #[derive(Debug, Clone)] diff --git a/crates/typst/src/math/mod.rs b/crates/typst/src/math/mod.rs index dc79f48b4..04db9efb1 100644 --- a/crates/typst/src/math/mod.rs +++ b/crates/typst/src/math/mod.rs @@ -49,6 +49,7 @@ use crate::foundations::{ }; use crate::introspection::TagElem; use crate::layout::{BoxElem, Frame, FrameItem, HElem, Point, Size, Spacing, VAlignment}; +use crate::realize::Behaviour; use crate::realize::{process, BehavedBuilder}; use crate::text::{LinebreakElem, SpaceElem, TextElem}; @@ -299,7 +300,7 @@ impl LayoutMath for Content { if let Some(elem) = self.to_packed::() { let mut frame = Frame::soft(Size::zero()); frame.push(Point::zero(), FrameItem::Tag(elem.tag.clone())); - ctx.push(FrameFragment::new(ctx, styles, frame)); + ctx.push(FrameFragment::new(ctx, styles, frame).with_ignorant(true)); return Ok(()); } @@ -312,7 +313,15 @@ impl LayoutMath for Content { let axis = scaled!(ctx, styles, axis_height); frame.set_baseline(frame.height() / 2.0 + axis); } - ctx.push(FrameFragment::new(ctx, styles, frame).with_spaced(true)); + + ctx.push( + FrameFragment::new(ctx, styles, frame) + .with_spaced(true) + .with_ignorant(matches!( + self.behaviour(), + Behaviour::Invisible | Behaviour::Ignorant + )), + ); Ok(()) } diff --git a/crates/typst/src/math/row.rs b/crates/typst/src/math/row.rs index cb909b0bc..5234ca2cd 100644 --- a/crates/typst/src/math/row.rs +++ b/crates/typst/src/math/row.rs @@ -77,14 +77,17 @@ impl MathRun { fragment.set_class(MathClass::Binary); } - // Insert spacing between the last and this item. - if let Some(i) = last { - if let Some(s) = spacing(&resolved[i], space.take(), &fragment) { - resolved.insert(i + 1, s); + // Insert spacing between the last and this non-ignorant item. + if !fragment.is_ignorant() { + if let Some(i) = last { + if let Some(s) = spacing(&resolved[i], space.take(), &fragment) { + resolved.insert(i + 1, s); + } } + + last = Some(resolved.len()); } - last = Some(resolved.len()); resolved.push(fragment); } diff --git a/tests/ref/math-spacing-ignorant.png b/tests/ref/math-spacing-ignorant.png new file mode 100644 index 000000000..6fead62e3 Binary files /dev/null and b/tests/ref/math-spacing-ignorant.png differ diff --git a/tests/suite/math/spacing.typ b/tests/suite/math/spacing.typ index 2a387f929..707c09bb8 100644 --- a/tests/suite/math/spacing.typ +++ b/tests/suite/math/spacing.typ @@ -49,6 +49,16 @@ $integral f(x) thin dif x$, // Both are weak, collide $integral f(x) #h(0.166em, weak: true)dif x$ +--- math-spacing-ignorant --- +// Test spacing with ignorant elements +$#metadata(none) "text"$ \ +$#place(dx: 5em)[Placed] "text"$ \ +// Operator spacing +$#counter("test").update(3) + b$ \ +$#place(dx: 5em)[a] + b$ +// Validate that ignorant elements are layouted +#context test(counter("test").get(), (3,)) + --- issue-1052-math-number-spacing --- // Test spacing after numbers in math. $