summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/typst/src/math/fragment.rs16
-rw-r--r--crates/typst/src/math/lr.rs17
-rw-r--r--crates/typst/src/math/mod.rs5
-rw-r--r--crates/typst/src/math/row.rs7
-rw-r--r--crates/typst/src/math/spacing.rs7
-rw-r--r--tests/ref/math/delimited.pngbin29096 -> 101279 bytes
-rw-r--r--tests/typ/math/delimited.typ6
7 files changed, 49 insertions, 9 deletions
diff --git a/crates/typst/src/math/fragment.rs b/crates/typst/src/math/fragment.rs
index cad79c67..64bc3078 100644
--- a/crates/typst/src/math/fragment.rs
+++ b/crates/typst/src/math/fragment.rs
@@ -18,7 +18,7 @@ pub enum MathFragment {
Glyph(GlyphFragment),
Variant(VariantFragment),
Frame(FrameFragment),
- Spacing(Abs),
+ Spacing(SpacingFragment),
Space(Abs),
Linebreak,
Align,
@@ -34,7 +34,7 @@ impl MathFragment {
Self::Glyph(glyph) => glyph.width,
Self::Variant(variant) => variant.frame.width(),
Self::Frame(fragment) => fragment.frame.width(),
- Self::Spacing(amount) => *amount,
+ Self::Spacing(spacing) => spacing.width,
Self::Space(amount) => *amount,
_ => Abs::zero(),
}
@@ -205,6 +205,12 @@ impl From<FrameFragment> for MathFragment {
}
}
+impl From<SpacingFragment> for MathFragment {
+ fn from(fragment: SpacingFragment) -> Self {
+ Self::Spacing(fragment)
+ }
+}
+
#[derive(Clone)]
pub struct GlyphFragment {
pub id: GlyphId,
@@ -467,6 +473,12 @@ impl FrameFragment {
}
}
+#[derive(Debug, Clone)]
+pub struct SpacingFragment {
+ pub width: Abs,
+ pub weak: bool,
+}
+
/// Look up the italics correction for a glyph.
fn italics_correction(ctx: &MathContext, id: GlyphId) -> Option<Abs> {
Some(ctx.table.glyph_info?.italic_corrections?.get(id)?.scaled(ctx))
diff --git a/crates/typst/src/math/lr.rs b/crates/typst/src/math/lr.rs
index 35012050..4a1e758b 100644
--- a/crates/typst/src/math/lr.rs
+++ b/crates/typst/src/math/lr.rs
@@ -3,7 +3,9 @@ use unicode_math_class::MathClass;
use crate::diag::SourceResult;
use crate::foundations::{elem, func, Content, NativeElement, Resolve, Smart};
use crate::layout::{Abs, Em, Length, Rel};
-use crate::math::{GlyphFragment, LayoutMath, MathContext, MathFragment, Scaled};
+use crate::math::{
+ GlyphFragment, LayoutMath, MathContext, MathFragment, Scaled, SpacingFragment,
+};
use crate::text::TextElem;
/// How much less high scaled delimiters can be than what they wrap.
@@ -77,6 +79,19 @@ impl LayoutMath for LrElem {
}
}
+ // Remove weak SpacingFragment immediately after the opening or immediately
+ // before the closing.
+ let original_len = fragments.len();
+ let mut index = 0;
+ fragments.retain(|fragment| {
+ index += 1;
+ (index != 2 && index + 1 != original_len)
+ || !matches!(
+ fragment,
+ MathFragment::Spacing(SpacingFragment { weak: true, .. })
+ )
+ });
+
ctx.extend(fragments);
Ok(())
diff --git a/crates/typst/src/math/mod.rs b/crates/typst/src/math/mod.rs
index 10bece1b..e355cca1 100644
--- a/crates/typst/src/math/mod.rs
+++ b/crates/typst/src/math/mod.rs
@@ -279,7 +279,10 @@ impl LayoutMath for Content {
if let Some(elem) = self.to::<HElem>() {
if let Spacing::Rel(rel) = elem.amount() {
if rel.rel.is_zero() {
- ctx.push(MathFragment::Spacing(rel.abs.resolve(ctx.styles())));
+ ctx.push(SpacingFragment {
+ width: rel.abs.resolve(ctx.styles()),
+ weak: elem.weak(ctx.styles()),
+ });
}
}
return Ok(());
diff --git a/crates/typst/src/math/row.rs b/crates/typst/src/math/row.rs
index 48b33934..4f3e6390 100644
--- a/crates/typst/src/math/row.rs
+++ b/crates/typst/src/math/row.rs
@@ -10,6 +10,8 @@ use crate::math::{
};
use crate::model::ParElem;
+use super::fragment::SpacingFragment;
+
pub const TIGHT_LEADING: Em = Em::new(0.25);
#[derive(Debug, Default, Clone)]
@@ -279,8 +281,9 @@ impl MathRow {
while let Some(fragment) = iter.next() {
if space_is_visible {
match fragment {
- MathFragment::Space(s) | MathFragment::Spacing(s) => {
- items.push(MathParItem::Space(s));
+ MathFragment::Space(width)
+ | MathFragment::Spacing(SpacingFragment { width, .. }) => {
+ items.push(MathParItem::Space(width));
continue;
}
_ => {}
diff --git a/crates/typst/src/math/spacing.rs b/crates/typst/src/math/spacing.rs
index f358aa50..c6c697fe 100644
--- a/crates/typst/src/math/spacing.rs
+++ b/crates/typst/src/math/spacing.rs
@@ -2,7 +2,7 @@ use unicode_math_class::MathClass;
use crate::foundations::{NativeElement, Scope};
use crate::layout::{Abs, Em, HElem};
-use crate::math::{MathFragment, MathSize};
+use crate::math::{MathFragment, MathSize, SpacingFragment};
pub(super) const THIN: Em = Em::new(1.0 / 6.0);
pub(super) const MEDIUM: Em = Em::new(2.0 / 9.0);
@@ -28,8 +28,9 @@ pub(super) fn spacing(
use MathClass::*;
let class = |f: &MathFragment| f.class().unwrap_or(Special);
- let resolve = |v: Em, f: &MathFragment| {
- Some(MathFragment::Spacing(f.font_size().map_or(Abs::zero(), |size| v.at(size))))
+ let resolve = |v: Em, size_ref: &MathFragment| -> Option<MathFragment> {
+ let width = size_ref.font_size().map_or(Abs::zero(), |size| v.at(size));
+ Some(SpacingFragment { width, weak: false }.into())
};
let script =
|f: &MathFragment| f.style().map_or(false, |s| s.size <= MathSize::Script);
diff --git a/tests/ref/math/delimited.png b/tests/ref/math/delimited.png
index a89e4917..6126f58a 100644
--- a/tests/ref/math/delimited.png
+++ b/tests/ref/math/delimited.png
Binary files differ
diff --git a/tests/typ/math/delimited.typ b/tests/typ/math/delimited.typ
index ba623b34..8500aec2 100644
--- a/tests/typ/math/delimited.typ
+++ b/tests/typ/math/delimited.typ
@@ -51,3 +51,9 @@ $ { 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) } $
+
+---
+// Test ignoring weak spacing immediately after the opening
+// and immediately before the closing.
+
+$ [#h(1em, weak: true)A(dif x, f(x) dif x)sum#h(1em, weak: true)] $