diff --git a/library/src/math/ctx.rs b/library/src/math/ctx.rs index aed826b53..904c43331 100644 --- a/library/src/math/ctx.rs +++ b/library/src/math/ctx.rs @@ -124,11 +124,11 @@ impl<'a, 'b, 'v> MathContext<'a, 'b, 'v> { .into_frame()) } - pub fn layout_text(&mut self, elem: &TextElem) -> SourceResult<()> { + pub fn layout_text(&mut self, elem: &TextElem) -> SourceResult { let text = elem.text(); let span = elem.span(); let mut chars = text.chars(); - if let Some(glyph) = chars + let fragment = if let Some(glyph) = chars .next() .filter(|_| chars.next().is_none()) .map(|c| self.style.styled_char(c)) @@ -139,9 +139,9 @@ impl<'a, 'b, 'v> MathContext<'a, 'b, 'v> { && glyph.class == Some(MathClass::Large) { let height = scaled!(self, display_operator_min_height); - self.push(glyph.stretch_vertical(self, height, Abs::zero())); + glyph.stretch_vertical(self, height, Abs::zero()).into() } else { - self.push(glyph); + glyph.into() } } else if text.chars().all(|c| c.is_ascii_digit()) { // Numbers aren't that difficult. @@ -151,7 +151,7 @@ impl<'a, 'b, 'v> MathContext<'a, 'b, 'v> { fragments.push(GlyphFragment::new(self, c, span).into()); } let frame = MathRow::new(fragments).to_frame(self); - self.push(FrameFragment::new(self, frame)); + FrameFragment::new(self, frame).into() } else { // Anything else is handled by Typst's standard text layout. let spaced = text.graphemes(true).count() > 1; @@ -161,14 +161,12 @@ impl<'a, 'b, 'v> MathContext<'a, 'b, 'v> { } let text: EcoString = text.chars().map(|c| style.styled_char(c)).collect(); let frame = self.layout_content(&TextElem::packed(text).spanned(span))?; - self.push( - FrameFragment::new(self, frame) - .with_class(MathClass::Alphabetic) - .with_spaced(spaced), - ); - } - - Ok(()) + FrameFragment::new(self, frame) + .with_class(MathClass::Alphabetic) + .with_spaced(spaced) + .into() + }; + Ok(fragment) } pub fn styles(&self) -> StyleChain { diff --git a/library/src/math/mod.rs b/library/src/math/mod.rs index b4a5b1567..286d189a6 100644 --- a/library/src/math/mod.rs +++ b/library/src/math/mod.rs @@ -331,7 +331,8 @@ impl LayoutMath for Content { } if let Some(elem) = self.to::() { - ctx.layout_text(elem)?; + let fragment = ctx.layout_text(elem)?; + ctx.push(fragment); return Ok(()); } diff --git a/library/src/math/op.rs b/library/src/math/op.rs index e8db0c5db..2d8266cc1 100644 --- a/library/src/math/op.rs +++ b/library/src/math/op.rs @@ -35,9 +35,10 @@ pub struct OpElem { impl LayoutMath for OpElem { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { - let frame = ctx.layout_content(&TextElem::packed(self.text()))?; + let fragment = + ctx.layout_text(&TextElem::new(self.text()).spanned(self.span()))?; ctx.push( - FrameFragment::new(ctx, frame) + FrameFragment::new(ctx, fragment.to_frame()) .with_class(MathClass::Large) .with_limits(self.limits(ctx.styles())), ); diff --git a/macros/src/element.rs b/macros/src/element.rs index dd837754b..37ca19eb7 100644 --- a/macros/src/element.rs +++ b/macros/src/element.rs @@ -204,6 +204,11 @@ fn create(element: &Elem) -> TokenStream { pub fn span(&self) -> ::typst::syntax::Span { self.0.span() } + + /// Set the element's span. + pub fn spanned(self, span: ::typst::syntax::Span) -> Self { + Self(self.0.spanned(span)) + } } #element_impl diff --git a/tests/ref/math/op.png b/tests/ref/math/op.png index b4878438c..08d8b93ba 100644 Binary files a/tests/ref/math/op.png and b/tests/ref/math/op.png differ diff --git a/tests/typ/math/op.typ b/tests/typ/math/op.typ index 2a1c20444..08395de0b 100644 --- a/tests/typ/math/op.typ +++ b/tests/typ/math/op.typ @@ -19,3 +19,7 @@ $ lim_(n->infinity) 1/n = 0 $ // Test custom operator. $ op("myop", limits: #false)_(x:=1) x \ op("myop", limits: #true)_(x:=1) x $ + +--- +// Test styled operator. +$ bold(op("bold", limits: #true))_x y $