diff options
| author | Max <me@mkor.je> | 2024-09-26 14:30:47 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-09-26 14:30:47 +0000 |
| commit | a40e068590895562f0d1a4aa17fe97b9bf5630a3 (patch) | |
| tree | e4d5ca3264d056b7b8fc172492de921abbaeef07 | |
| parent | cf35c2f44c6fdd8d6ef6f5df81f144db7355286d (diff) | |
Add alignment parameter to matrices and vectors (#4998)
| -rw-r--r-- | crates/typst/src/math/matrix.rs | 40 | ||||
| -rw-r--r-- | crates/typst/src/math/underover.rs | 6 | ||||
| -rw-r--r-- | tests/ref/math-mat-align-explicit-alternating.png (renamed from tests/ref/math-mat-align-explicit--alternating.png) | bin | 1009 -> 1009 bytes | |||
| -rw-r--r-- | tests/ref/math-mat-align-explicit-mixed.png | bin | 0 -> 2523 bytes | |||
| -rw-r--r-- | tests/ref/math-mat-align.png | bin | 0 -> 1564 bytes | |||
| -rw-r--r-- | tests/ref/math-vec-align.png | bin | 0 -> 1098 bytes | |||
| -rw-r--r-- | tests/suite/math/mat.typ | 18 | ||||
| -rw-r--r-- | tests/suite/math/vec.typ | 4 |
8 files changed, 61 insertions, 7 deletions
diff --git a/crates/typst/src/math/matrix.rs b/crates/typst/src/math/matrix.rs index 9f9b82bc..5b9b17a7 100644 --- a/crates/typst/src/math/matrix.rs +++ b/crates/typst/src/math/matrix.rs @@ -7,7 +7,8 @@ use crate::foundations::{ Smart, StyleChain, Value, }; use crate::layout::{ - Abs, Axes, Em, FixedAlignment, Frame, FrameItem, Length, Point, Ratio, Rel, Size, + Abs, Axes, Em, FixedAlignment, Frame, FrameItem, HAlignment, Length, Point, Ratio, + Rel, Size, }; use crate::math::{ alignments, scaled_font_size, stack, style_for_denominator, AlignmentResult, @@ -29,7 +30,8 @@ const DEFAULT_STROKE_THICKNESS: Em = Em::new(0.05); /// A column vector. /// -/// Content in the vector's elements can be aligned with the `&` symbol. +/// Content in the vector's elements can be aligned with the +/// [`align`]($math.vec.align) parameter, or the `&` symbol. /// /// # Example /// ```example @@ -47,6 +49,16 @@ pub struct VecElem { #[default(DelimiterPair::PAREN)] pub delim: DelimiterPair, + /// The horizontal alignment that each element should have. + /// + /// ```example + /// #set math.vec(align: right) + /// $ vec(-1, 1, -1) $ + /// ``` + #[resolve] + #[default(HAlignment::Center)] + pub align: HAlignment, + /// The gap between elements. /// /// ```example @@ -70,7 +82,7 @@ impl LayoutMath for Packed<VecElem> { ctx, styles, self.children(), - FixedAlignment::Center, + self.align(styles), self.gap(styles), LeftRightAlternator::Right, )?; @@ -87,7 +99,9 @@ impl LayoutMath for Packed<VecElem> { /// special syntax of math function calls to define custom functions that take /// 2D data. /// -/// Content in cells that are in the same row can be aligned with the `&` symbol. +/// Content in cells can be aligned with the [`align`]($math.mat.align) +/// parameter, or content in cells that are in the same row can be aligned with +/// the `&` symbol. /// /// # Example /// ```example @@ -109,6 +123,16 @@ pub struct MatElem { #[default(DelimiterPair::PAREN)] pub delim: DelimiterPair, + /// The horizontal alignment that each cell should have. + /// + /// ```example + /// #set math.mat(align: right) + /// $ mat(-1, 1, 1; 1, -1, 1; 1, 1, -1) $ + /// ``` + #[resolve] + #[default(HAlignment::Center)] + pub align: HAlignment, + /// Draws augmentation lines in a matrix. /// /// - `{none}`: No lines are drawn. @@ -249,6 +273,7 @@ impl LayoutMath for Packed<MatElem> { ctx, styles, rows, + self.align(styles), augment, Axes::new(self.column_gap(styles), self.row_gap(styles)), self.span(), @@ -454,6 +479,7 @@ fn layout_mat_body( ctx: &mut MathContext, styles: StyleChain, rows: &[Vec<Content>], + align: FixedAlignment, augment: Option<Augment<Abs>>, gap: Axes<Rel<Abs>>, span: Span, @@ -538,7 +564,11 @@ fn layout_mat_body( for (cell, &(ascent, descent)) in col.into_iter().zip(&heights) { let cell = cell.into_line_frame(&points, LeftRightAlternator::Right); let pos = Point::new( - if points.is_empty() { x + (rcol - cell.width()) / 2.0 } else { x }, + if points.is_empty() { + x + align.position(rcol - cell.width()) + } else { + x + }, y + ascent - cell.ascent(), ); diff --git a/crates/typst/src/math/underover.rs b/crates/typst/src/math/underover.rs index f1789b7a..5ad7f457 100644 --- a/crates/typst/src/math/underover.rs +++ b/crates/typst/src/math/underover.rs @@ -476,7 +476,11 @@ pub(super) fn stack( let mut y = Abs::zero(); for (i, row) in rows.into_iter().enumerate() { - let x = align.position(width - row.width()); + let x = if points.is_empty() { + align.position(width - row.width()) + } else { + Abs::zero() + }; let ascent_padded_part = minimum_ascent_descent .map_or(Abs::zero(), |(a, _)| (a - row.ascent())) .max(Abs::zero()); diff --git a/tests/ref/math-mat-align-explicit--alternating.png b/tests/ref/math-mat-align-explicit-alternating.png Binary files differindex 37e8dc06..37e8dc06 100644 --- a/tests/ref/math-mat-align-explicit--alternating.png +++ b/tests/ref/math-mat-align-explicit-alternating.png diff --git a/tests/ref/math-mat-align-explicit-mixed.png b/tests/ref/math-mat-align-explicit-mixed.png Binary files differnew file mode 100644 index 00000000..88ccd6de --- /dev/null +++ b/tests/ref/math-mat-align-explicit-mixed.png diff --git a/tests/ref/math-mat-align.png b/tests/ref/math-mat-align.png Binary files differnew file mode 100644 index 00000000..66513dd5 --- /dev/null +++ b/tests/ref/math-mat-align.png diff --git a/tests/ref/math-vec-align.png b/tests/ref/math-vec-align.png Binary files differnew file mode 100644 index 00000000..680d0936 --- /dev/null +++ b/tests/ref/math-vec-align.png diff --git a/tests/suite/math/mat.typ b/tests/suite/math/mat.typ index 1f6716d7..baec53ee 100644 --- a/tests/suite/math/mat.typ +++ b/tests/suite/math/mat.typ @@ -92,7 +92,12 @@ $ mat(1, 0, 0, 0; 0, 1, 0, 0; 0, 0, 1, 1) $ // Error: 3-37 cannot draw a vertical line after column 3 of a matrix with 3 columns $ mat(1, 0, 0; 0, 1, 1; augment: #3) $, ---- math-mat-align-explicit--alternating --- +--- math-mat-align --- +$ mat(-1, 1, 1; 1, -1, 1; 1, 1, -1; align: #left) $ +$ mat(-1, 1, 1; 1, -1, 1; 1, 1, -1; align: #center) $ +$ mat(-1, 1, 1; 1, -1, 1; 1, 1, -1; align: #right) $ + +--- math-mat-align-explicit-alternating --- // Test alternating explicit alignment in a matrix. $ mat( "a" & "a a a" & "a a"; @@ -124,6 +129,17 @@ $ mat( "a a a"&, "a"&, "a a a"&; ) $ +--- math-mat-align-explicit-mixed --- +// Test explicit alignment in some columns with align parameter in a matrix. +#let data = ( + ($&18&&.02$, $1$, $+1$), + ($-&9&&.3$, $-1$, $-&21$), + ($&&&.011$, $1$, $&0$) +) +$ #math.mat(align: left, ..data) $ +$ #math.mat(align: center, ..data) $ +$ #math.mat(align: right, ..data) $ + --- math-mat-align-complex --- // Test #460 equations. #let stop = { diff --git a/tests/suite/math/vec.typ b/tests/suite/math/vec.typ index d7bc0b6c..cf7057f3 100644 --- a/tests/suite/math/vec.typ +++ b/tests/suite/math/vec.typ @@ -4,6 +4,10 @@ #set math.vec(gap: 1em) $ vec(1, 2) $ +--- math-vec-align --- +$ vec(-1, 1, -1, align: #left) + vec(-1, 1, -1, align: #center) + vec(-1, 1, -1, align: #right) $ --- math-vec-align-explicit-alternating --- // Test alternating alignment in a vector. |
