Alternate between right/left alignment in equations (#936)
This commit is contained in:
parent
27771bc329
commit
e472b0347f
@ -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 fragments = self.0.into_iter().peekable();
|
||||
let mut i = 0;
|
||||
for fragment in fragments {
|
||||
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();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -183,3 +183,22 @@ impl Fold for GenAlign {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
|
||||
pub enum LeftRightAlternator {
|
||||
Left,
|
||||
Right,
|
||||
}
|
||||
|
||||
impl Iterator for LeftRightAlternator {
|
||||
type Item = LeftRightAlternator;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let r = Some(*self);
|
||||
match self {
|
||||
Self::Left => *self = Self::Right,
|
||||
Self::Right => *self = Self::Left,
|
||||
}
|
||||
r
|
||||
}
|
||||
}
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 7.9 KiB After Width: | Height: | Size: 7.9 KiB |
Binary file not shown.
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 14 KiB |
Binary file not shown.
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Loading…
x
Reference in New Issue
Block a user