summaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorIan Wrzesinski <133046678+wrzian@users.noreply.github.com>2025-05-28 09:44:44 -0400
committerGitHub <noreply@github.com>2025-05-28 13:44:44 +0000
commit9a95966302bae4d795cd2fba4b3beb6f41629221 (patch)
treef98132c0cfab0c14748efad4d6ba089315cfb4d6 /crates
parent9ac21b8524632c70ab9e090488a70085eabe4189 (diff)
Remove line break opportunity when math operator precededes a closing paren (#6216)
Diffstat (limited to 'crates')
-rw-r--r--crates/typst-layout/src/math/run.rs31
1 files changed, 18 insertions, 13 deletions
diff --git a/crates/typst-layout/src/math/run.rs b/crates/typst-layout/src/math/run.rs
index ae64368d..4ec76c25 100644
--- a/crates/typst-layout/src/math/run.rs
+++ b/crates/typst-layout/src/math/run.rs
@@ -278,6 +278,9 @@ impl MathRun {
frame
}
+ /// Convert this run of math fragments into a vector of inline items for
+ /// paragraph layout. Creates multiple fragments when relation or binary
+ /// operators are present to allow for line-breaking opportunities later.
pub fn into_par_items(self) -> Vec<InlineItem> {
let mut items = vec![];
@@ -295,21 +298,24 @@ impl MathRun {
let mut space_is_visible = false;
- let is_relation = |f: &MathFragment| matches!(f.class(), MathClass::Relation);
let is_space = |f: &MathFragment| {
matches!(f, MathFragment::Space(_) | MathFragment::Spacing(_, _))
};
+ let is_line_break_opportunity = |class, next_fragment| match class {
+ // Don't split when two relations are in a row or when preceding a
+ // closing parenthesis.
+ MathClass::Binary => next_fragment != Some(MathClass::Closing),
+ MathClass::Relation => {
+ !matches!(next_fragment, Some(MathClass::Relation | MathClass::Closing))
+ }
+ _ => false,
+ };
let mut iter = self.0.into_iter().peekable();
while let Some(fragment) = iter.next() {
- if space_is_visible {
- match fragment {
- MathFragment::Space(width) | MathFragment::Spacing(width, _) => {
- items.push(InlineItem::Space(width, true));
- continue;
- }
- _ => {}
- }
+ if space_is_visible && is_space(&fragment) {
+ items.push(InlineItem::Space(fragment.width(), true));
+ continue;
}
let class = fragment.class();
@@ -323,10 +329,9 @@ impl MathRun {
frame.push_frame(pos, fragment.into_frame());
empty = false;
- if class == MathClass::Binary
- || (class == MathClass::Relation
- && !iter.peek().map(is_relation).unwrap_or_default())
- {
+ // Split our current frame when we encounter a binary operator or
+ // relation so that there is a line-breaking opportunity.
+ if is_line_break_opportunity(class, iter.peek().map(|f| f.class())) {
let mut frame_prev =
std::mem::replace(&mut frame, Frame::soft(Size::zero()));