diff options
| author | Alex Saveau <saveau.alexandre@gmail.com> | 2023-05-11 05:56:17 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-05-11 14:56:17 +0200 |
| commit | e472b0347f84f39edf4655d39f8b5484870d0a76 (patch) | |
| tree | d722a59d87a2e438b06ed88eab2a313d2e4bfd13 /library/src | |
| parent | 27771bc329ab23cc551637fb3feac7b5689e64c7 (diff) | |
Alternate between right/left alignment in equations (#936)
Diffstat (limited to 'library/src')
| -rw-r--r-- | library/src/math/row.rs | 55 |
1 files changed, 36 insertions, 19 deletions
diff --git a/library/src/math/row.rs b/library/src/math/row.rs index a25178af..9b693bc1 100644 --- a/library/src/math/row.rs +++ b/library/src/math/row.rs @@ -1,3 +1,5 @@ +use std::iter::once; + use crate::layout::AlignElem; use super::*; @@ -172,31 +174,46 @@ impl MathRow { fn into_line_frame(self, points: &[Abs], align: Align) -> Frame { let ascent = self.ascent(); - let descent = self.descent(); - let size = Size::new(Abs::zero(), ascent + descent); - let mut frame = Frame::new(size); - let mut x = Abs::zero(); + let mut frame = Frame::new(Size::new(Abs::zero(), ascent + self.descent())); frame.set_baseline(ascent); - if let (Some(&first), Align::Center) = (points.first(), align) { - let mut offset = first; - for fragment in self.iter() { - offset -= fragment.width(); - if matches!(fragment, MathFragment::Align) { - x = offset; - break; + let mut next_x = { + let mut widths = Vec::new(); + if !points.is_empty() && align != Align::Left { + let mut width = Abs::zero(); + for fragment in self.iter() { + if matches!(fragment, MathFragment::Align) { + widths.push(width); + width = Abs::zero(); + } else { + width += fragment.width(); + } } + widths.push(width); } - } + let widths = widths; + + let mut prev_points = once(Abs::zero()).chain(points.iter().copied()); + let mut point_widths = points.iter().copied().zip(widths); + let mut alternator = LeftRightAlternator::Right; + move || match align { + Align::Left => prev_points.next(), + Align::Right => point_widths.next().map(|(point, width)| point - width), + _ => point_widths + .next() + .zip(prev_points.next()) + .zip(alternator.next()) + .map(|(((point, width), prev_point), alternator)| match alternator { + LeftRightAlternator::Left => prev_point, + LeftRightAlternator::Right => point - width, + }), + } + }; + let mut x = next_x().unwrap_or_default(); - let fragments = self.0.into_iter().peekable(); - let mut i = 0; - for fragment in fragments { + for fragment in self.0.into_iter() { if matches!(fragment, MathFragment::Align) { - if let Some(&point) = points.get(i) { - x = point; - } - i += 1; + x = next_x().unwrap_or(x); continue; } |
