summaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorLeedehai <18319900+Leedehai@users.noreply.github.com>2023-11-27 06:02:51 -0500
committerGitHub <noreply@github.com>2023-11-27 12:02:51 +0100
commit34862b7b27ad0df34bc12e486cdfa3726f824c33 (patch)
treea00ab6e211dc7c73c80996bc4e4abb52f9722ba6 /crates
parentc354f00f79002bd51becf554a54cc99ef64e6f2d (diff)
Implement mid() for middle delimiters in lr() (#2760)
Diffstat (limited to 'crates')
-rw-r--r--crates/typst/src/math/fragment.rs2
-rw-r--r--crates/typst/src/math/lr.rs47
-rw-r--r--crates/typst/src/math/mod.rs1
-rw-r--r--crates/typst/src/math/stretch.rs1
4 files changed, 51 insertions, 0 deletions
diff --git a/crates/typst/src/math/fragment.rs b/crates/typst/src/math/fragment.rs
index fb1420bf..d176dd96 100644
--- a/crates/typst/src/math/fragment.rs
+++ b/crates/typst/src/math/fragment.rs
@@ -297,6 +297,7 @@ impl GlyphFragment {
span: self.span,
limits: self.limits,
frame: self.into_frame(),
+ mid_stretched: None,
}
}
@@ -360,6 +361,7 @@ pub struct VariantFragment {
pub class: Option<MathClass>,
pub span: Span,
pub limits: Limits,
+ pub mid_stretched: Option<bool>,
}
impl VariantFragment {
diff --git a/crates/typst/src/math/lr.rs b/crates/typst/src/math/lr.rs
index 93e5a43c..1631623b 100644
--- a/crates/typst/src/math/lr.rs
+++ b/crates/typst/src/math/lr.rs
@@ -57,6 +57,7 @@ impl LayoutMath for LrElem {
.resolve(ctx.styles())
.relative_to(2.0 * max_extent);
+ // Scale up fragments at both ends.
match fragments.as_mut_slice() {
[one] => scale(ctx, one, height, None),
[first, .., last] => {
@@ -66,12 +67,58 @@ impl LayoutMath for LrElem {
_ => {}
}
+ // Handle MathFragment::Variant fragments that should be scaled up.
+ for fragment in &mut fragments {
+ if let MathFragment::Variant(ref mut variant) = fragment {
+ if variant.mid_stretched == Some(false) {
+ variant.mid_stretched = Some(true);
+ scale(ctx, fragment, height, Some(MathClass::Large));
+ }
+ }
+ }
+
ctx.extend(fragments);
Ok(())
}
}
+/// Scales contents vertically to the nearest surrounding lr() group.
+///
+/// ```example
+/// $ { x mid(|) sum_(i=1)^oo phi_i (x) < 1 } $
+/// ```
+#[elem(LayoutMath)]
+pub struct MidElem {
+ /// The content to be scaled.
+ #[required]
+ pub body: Content,
+}
+
+impl LayoutMath for MidElem {
+ #[tracing::instrument(skip(ctx))]
+ fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> {
+ let mut fragments = ctx.layout_fragments(self.body())?;
+
+ for fragment in &mut fragments {
+ match fragment {
+ MathFragment::Glyph(glyph) => {
+ let mut new = glyph.clone().into_variant();
+ new.mid_stretched = Some(false);
+ *fragment = MathFragment::Variant(new);
+ }
+ MathFragment::Variant(variant) => {
+ variant.mid_stretched = Some(false);
+ }
+ _ => {}
+ }
+ }
+
+ ctx.extend(fragments);
+ Ok(())
+ }
+}
+
/// Scale a math fragment to a height.
fn scale(
ctx: &mut MathContext,
diff --git a/crates/typst/src/math/mod.rs b/crates/typst/src/math/mod.rs
index d84d9b40..85227fc1 100644
--- a/crates/typst/src/math/mod.rs
+++ b/crates/typst/src/math/mod.rs
@@ -161,6 +161,7 @@ pub fn module() -> Module {
math.define_elem::<EquationElem>();
math.define_elem::<TextElem>();
math.define_elem::<LrElem>();
+ math.define_elem::<MidElem>();
math.define_elem::<AttachElem>();
math.define_elem::<ScriptsElem>();
math.define_elem::<LimitsElem>();
diff --git a/crates/typst/src/math/stretch.rs b/crates/typst/src/math/stretch.rs
index a8e22af4..bfeb80ef 100644
--- a/crates/typst/src/math/stretch.rs
+++ b/crates/typst/src/math/stretch.rs
@@ -187,6 +187,7 @@ fn assemble(
class: base.class,
span: base.span,
limits: base.limits,
+ mid_stretched: None,
}
}