Repository: typst/typst
File: crates/typst-layout/src/math/run.rs (Rust)

Code before:

                _ => {}
            }

            // Convert variable operators into binary operators if something
            // precedes them and they are not preceded by a operator or comparator.
            if fragment.class() == MathClass::Vary
                && matches!(
                    last.map(|i| resolved[i].class()),
                    Some(
                        MathClass::Normal
                            | MathClass::Alphabetic
                            | MathClass::Closing
                            | MathClass::Fence
                    )
                )
            {
                fragment.set_class(MathClass::Binary);
            }

            // Insert spacing between the last and this non-ignorant item.
            if !fragment.is_ignorant() {
                if let Some(i) = last
                    && let Some(s) = spacing(&resolved[i], space.take(), &fragment)
                {
                    let idx = if matches!(resolved.last(), Some(MathFragment::Align)) {
                        // Only one alignment point should be skipped when
                        // inserting spacing.
                        resolved.len() - 1
                    } else {
                        i + 1
                    };
                    resolved.insert(idx, s);
                }

                last = Some(resolved.len());
            }

            resolved.push(fragment);
        }

        if let Some(MathFragment::Spacing(_, true)) = resolved.last() {
            resolved.pop();
        }

        Self(resolved)
    }

    pub fn iter(&self) -> std::slice::Iter<'_, MathFragment> {
        self.0.iter()
    }

Review comment (bug):
Could it happen that the presence of a trailing tag makes the different between `resolved.last()` matching here and not? Maybe not, but if it can happen that would be a bug since tags should never affect layout.

Code after:
                // Alignment points are resolved later.
                MathFragment::Align => {
                    resolved.push(fragment);
                    continue;
                }

                // New line, new things.
                MathFragment::Linebreak => {
                    resolved.push(fragment);
                    space = None;
                    last = None;
                    continue;
                }

                _ => {}
            }

            // Convert variable operators into binary operators if something
            // precedes them and they are not preceded by a operator or comparator.
            if fragment.class() == MathClass::Vary
                && matches!(
                    last.map(|i| resolved[i].class()),
                    Some(
                        MathClass::Normal
                            | MathClass::Alphabetic
                            | MathClass::Closing
                            | MathClass::Fence
                    )
                )
            {
                fragment.set_class(MathClass::Binary);
            }

            // Insert spacing between the last and this non-ignorant item.
            if !fragment.is_ignorant() {
                if let Some(i) = last
                    && let Some(s) = spacing(&resolved[i], space.take(), &fragment)
                {
                    // Only one alignment point should be skipped when inserting
                    // spacing.
                    let idx = resolved
                        .last_index()
                        .filter(|&k| matches!(resolved[k], MathFragment::Align))
                        .unwrap_or(i + 1);

                    resolved.insert(idx, s);
                }

                last = Some(resolved.len());
            }