diff --git a/crates/typst-library/src/math/mod.rs b/crates/typst-library/src/math/mod.rs index 1f87ff81d..40df524fb 100644 --- a/crates/typst-library/src/math/mod.rs +++ b/crates/typst-library/src/math/mod.rs @@ -418,11 +418,12 @@ impl LayoutMath for Content { return realized.layout_math(ctx); } - if let Some(children) = self.to_sequence() { + if self.is_sequence() { let mut bb = BehavedBuilder::new(); - for child in children { - bb.push(child.clone(), StyleChain::default()); - } + self.sequence_recursive_for_each(&mut |child: &Content| { + bb.push(child.clone(), StyleChain::default()) + }); + for (child, _) in bb.finish().0.iter() { child.layout_math(ctx)?; } diff --git a/crates/typst/src/model/content.rs b/crates/typst/src/model/content.rs index 0c79d02ca..f1600f251 100644 --- a/crates/typst/src/model/content.rs +++ b/crates/typst/src/model/content.rs @@ -85,12 +85,25 @@ impl Content { /// Access the children if this is a sequence. pub fn to_sequence(&self) -> Option> { - if !self.is::() { + if !self.is_sequence() { return None; } Some(self.attrs.iter().filter_map(Attr::child)) } + pub fn is_sequence(&self) -> bool { + self.is::() + } + + /// Also auto expands sequence of sequences into flat sequence + pub fn sequence_recursive_for_each(&self, f: &mut impl FnMut(&Self)) { + if let Some(childs) = self.to_sequence() { + childs.for_each(|c| c.sequence_recursive_for_each(f)); + } else { + f(self); + } + } + /// Access the child and styles. pub fn to_styled(&self) -> Option<(&Content, &Styles)> { if !self.is::() { diff --git a/tests/ref/math/spacing.png b/tests/ref/math/spacing.png index 0430060bb..c9522b368 100644 Binary files a/tests/ref/math/spacing.png and b/tests/ref/math/spacing.png differ diff --git a/tests/typ/math/spacing.typ b/tests/typ/math/spacing.typ index 87bfb0028..9b64d92d2 100644 --- a/tests/typ/math/spacing.typ +++ b/tests/typ/math/spacing.typ @@ -39,3 +39,10 @@ $a cancel(equiv) b overline(+) c arrow(-) d hat(=>) e cancel(log) 5 dot(op("ln") $a overbrace(equiv) b underline(+) c grave(-) d underbracket(=>) e circle(log) 5 caron(op("ln")) 6$ \ \ $a attach(equiv, tl: a, tr: b) b attach(limits(+), t: a, b: b) c tilde(-) d breve(=>) e attach(limits(log), t: a, b: b) 5 attach(op("ln"), tr: a, bl: b) 6$ +--- +// Test weak spacing +$integral f(x) dif x$, +// Not weak +$integral f(x) thin dif x$, +// Both are weak, collide +$integral f(x) #h(0.166em, weak: true)dif x$