summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2023-01-22 13:31:16 +0100
committerLaurenz <laurmaedje@gmail.com>2023-01-22 13:31:16 +0100
commit2c48c8d7a10c89fe15c0e29083ab3f3b39585423 (patch)
tree91a0433f2dcb7f01e06f805d8f21d621d2199617
parent203d5779f804532f9fe76da9c00765434bf1b357 (diff)
Multi-line alignment with `&`
-rw-r--r--library/src/math/align.rs60
-rw-r--r--library/src/math/mod.rs1
2 files changed, 61 insertions, 0 deletions
diff --git a/library/src/math/align.rs b/library/src/math/align.rs
new file mode 100644
index 00000000..82b461e9
--- /dev/null
+++ b/library/src/math/align.rs
@@ -0,0 +1,60 @@
+use super::*;
+
+/// # Alignment Point
+/// A math alignment point: `&`, `&&`.
+///
+/// ## Parameters
+/// - index: usize (positional, required)
+/// The alignment point's index.
+///
+/// ## Category
+/// math
+#[func]
+#[capable(LayoutMath)]
+#[derive(Debug, Hash)]
+pub struct AlignPointNode;
+
+#[node]
+impl AlignPointNode {}
+
+impl LayoutMath for AlignPointNode {
+ fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> {
+ ctx.push(MathFragment::Align);
+ Ok(())
+ }
+}
+
+/// Determine the position of the alignment points.
+pub(super) fn alignments(rows: &[MathRow]) -> Vec<Abs> {
+ let count = rows
+ .iter()
+ .map(|row| {
+ row.0
+ .iter()
+ .filter(|fragment| matches!(fragment, MathFragment::Align))
+ .count()
+ })
+ .max()
+ .unwrap_or(0);
+
+ let mut points = vec![Abs::zero(); count];
+ for current in 0..count {
+ for row in rows {
+ let mut x = Abs::zero();
+ let mut i = 0;
+ for fragment in &row.0 {
+ if matches!(fragment, MathFragment::Align) {
+ if i < current {
+ x = points[i];
+ } else if i == current {
+ points[i].set_max(x);
+ }
+ i += 1;
+ }
+ x += fragment.width();
+ }
+ }
+ }
+
+ points
+}
diff --git a/library/src/math/mod.rs b/library/src/math/mod.rs
index de954fbf..35e005d0 100644
--- a/library/src/math/mod.rs
+++ b/library/src/math/mod.rs
@@ -3,6 +3,7 @@
#[macro_use]
mod ctx;
mod accent;
+mod align;
mod atom;
mod frac;
mod group;