diff --git a/library/src/math/fragment.rs b/library/src/math/fragment.rs index d85bd33c8..1d13e3b79 100644 --- a/library/src/math/fragment.rs +++ b/library/src/math/fragment.rs @@ -148,6 +148,7 @@ pub struct GlyphFragment { pub font_size: Abs, pub class: Option, pub span: Span, + pub meta: Vec, } impl GlyphFragment { @@ -194,6 +195,7 @@ impl GlyphFragment { _ => unicode_math_class::class(c), }, span, + meta: MetaElem::data_in(ctx.styles()), } } @@ -231,6 +233,7 @@ impl GlyphFragment { }; let size = Size::new(self.width, self.ascent + self.descent); let mut frame = Frame::new(size); + frame.meta_iter(self.meta); frame.set_baseline(self.ascent); frame.push(Point::with_y(self.ascent), FrameItem::Text(item)); frame @@ -273,8 +276,9 @@ pub struct FrameFragment { } impl FrameFragment { - pub fn new(ctx: &MathContext, frame: Frame) -> Self { + pub fn new(ctx: &MathContext, mut frame: Frame) -> Self { let base_ascent = frame.ascent(); + frame.meta(ctx.styles(), false); Self { frame, font_size: ctx.size, diff --git a/library/src/math/mod.rs b/library/src/math/mod.rs index 97e5548ee..9c8a9cdf3 100644 --- a/library/src/math/mod.rs +++ b/library/src/math/mod.rs @@ -344,9 +344,18 @@ impl LayoutMath for EquationElem { impl LayoutMath for Content { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { + // Directly layout the body of nested equations instead of handling it + // like a normal equation so that things like this work: + // ``` + // #let my = $pi$ + // $ my r^2 $ + // ``` + if let Some(elem) = self.to::() { + return elem.layout_math(ctx); + } + if let Some(realized) = ctx.realize(self)? { - realized.layout_math(ctx)?; - return Ok(()); + return realized.layout_math(ctx); } if let Some(children) = self.to_sequence() { diff --git a/library/src/math/stretch.rs b/library/src/math/stretch.rs index 226f3f4e7..bb454022b 100644 --- a/library/src/math/stretch.rs +++ b/library/src/math/stretch.rs @@ -162,6 +162,7 @@ fn assemble( let mut frame = Frame::new(size); let mut offset = Abs::zero(); frame.set_baseline(baseline); + frame.meta_iter(base.meta); for (fragment, advance) in selected { let pos = if horizontal { diff --git a/src/doc.rs b/src/doc.rs index 4f0428fb7..b7b1eacdb 100644 --- a/src/doc.rs +++ b/src/doc.rs @@ -273,13 +273,18 @@ impl Frame { /// Attach the metadata from this style chain to the frame. pub fn meta(&mut self, styles: StyleChain, force: bool) { if force || !self.is_empty() { - for meta in MetaElem::data_in(styles) { - if matches!(meta, Meta::Hide) { - self.clear(); - break; - } - self.prepend(Point::zero(), FrameItem::Meta(meta, self.size)); + self.meta_iter(MetaElem::data_in(styles)); + } + } + + /// Attach metadata from an iterator. + pub fn meta_iter(&mut self, iter: impl IntoIterator) { + for meta in iter { + if matches!(meta, Meta::Hide) { + self.clear(); + break; } + self.prepend(Point::zero(), FrameItem::Meta(meta, self.size)); } } diff --git a/tests/ref/bugs/math-realize.png b/tests/ref/bugs/math-realize.png new file mode 100644 index 000000000..d68fb923f Binary files /dev/null and b/tests/ref/bugs/math-realize.png differ diff --git a/tests/typ/bugs/math-realize.typ b/tests/typ/bugs/math-realize.typ new file mode 100644 index 000000000..c2772ab5b --- /dev/null +++ b/tests/typ/bugs/math-realize.typ @@ -0,0 +1,15 @@ +// Test that content in math can be realized without breaking +// nested equations. + +--- +#let my = $pi$ +#let f1 = box(baseline: 10pt, [f]) +#let f2 = style(sty => f1) +#show math.vec: [nope] + +$ pi a $ +$ my a $ +$ 1 + sqrt(x/2) + sqrt(#hide($x/2$)) $ +$ a x #link("url", $+ b$) $ +$ f f1 f2 $ +$ vec(1,2) * 2 $