Implement mid() for middle delimiters in lr() (#2760)

This commit is contained in:
Leedehai 2023-11-27 06:02:51 -05:00 committed by GitHub
parent c354f00f79
commit 34862b7b27
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 58 additions and 0 deletions

View File

@ -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 {

View File

@ -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,

View File

@ -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>();

View File

@ -187,6 +187,7 @@ fn assemble(
class: base.class,
span: base.span,
limits: base.limits,
mid_stretched: None,
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 29 KiB

View File

@ -43,3 +43,10 @@ $ lr(
text("(", fill: #green) a/b
text(")", fill: #blue)
) $
---
// Test middle functions
$ { x mid(|) sum_(i=1)^oo phi_i (x) < 1 } \
{ integral |x| dif x
mid(bar.v.double)
floor(hat(A) mid(|) { x mid(|) y } mid(|) A) } $