From 0fe03bae6e154c30934d9f25037fa57e7381780f Mon Sep 17 00:00:00 2001 From: Leedehai <18319900+Leedehai@users.noreply.github.com> Date: Thu, 22 Feb 2024 03:49:24 -0500 Subject: [PATCH] Add `number-align` to `math.equation` [Better Equation Numbering Pt.2] (#3446) --- crates/typst/src/layout/align.rs | 8 ++ crates/typst/src/math/equation.rs | 100 ++++++++++++------ ...alignment.png => equation-block-align.png} | Bin tests/ref/math/equation-number.png | Bin 0 -> 18851 bytes ...alignment.typ => equation-block-align.typ} | 0 tests/typ/math/equation-number.typ | 96 +++++++++++++++++ 6 files changed, 169 insertions(+), 35 deletions(-) rename tests/ref/math/{block-alignment.png => equation-block-align.png} (100%) create mode 100644 tests/ref/math/equation-number.png rename tests/typ/math/{block-alignment.typ => equation-block-align.typ} (100%) create mode 100644 tests/typ/math/equation-number.typ diff --git a/crates/typst/src/layout/align.rs b/crates/typst/src/layout/align.rs index 58dc7589d..5f516ebec 100644 --- a/crates/typst/src/layout/align.rs +++ b/crates/typst/src/layout/align.rs @@ -356,6 +356,14 @@ impl OuterHAlignment { } } +impl Resolve for OuterHAlignment { + type Output = FixedAlignment; + + fn resolve(self, styles: StyleChain) -> Self::Output { + self.fix(TextElem::dir_in(styles)) + } +} + impl From for HAlignment { fn from(value: OuterHAlignment) -> Self { match value { diff --git a/crates/typst/src/math/equation.rs b/crates/typst/src/math/equation.rs index e4744aeab..a272622e8 100644 --- a/crates/typst/src/math/equation.rs +++ b/crates/typst/src/math/equation.rs @@ -10,8 +10,8 @@ use crate::foundations::{ }; use crate::introspection::{Count, Counter, CounterUpdate, Locatable}; use crate::layout::{ - Abs, AlignElem, Alignment, Axes, Dir, Em, FixedAlignment, Frame, LayoutMultiple, - LayoutSingle, Point, Regions, Size, + Abs, AlignElem, Alignment, Axes, Em, FixedAlignment, Frame, LayoutMultiple, + LayoutSingle, OuterHAlignment, Point, Regions, Size, }; use crate::math::{scaled_font_size, LayoutMath, MathContext, MathSize, MathVariant}; use crate::model::{Numbering, Outlinable, ParElem, Refable, Supplement}; @@ -76,6 +76,21 @@ pub struct EquationElem { #[borrowed] pub numbering: Option, + /// The alignment of the equation numbering. + /// + /// By default, the number is put at the `{end}` of the equation block. Both + /// `{start}` and `{end}` respects text direction; for absolute positioning, + /// use `{left}` or `{right}`. + /// + /// ```example + /// #set math.equation(numbering: "(1)", number-align: start) + /// + /// With natural units, we know: + /// $ E^2 = m^2 + p^2 $ + /// ``` + #[default(OuterHAlignment::End)] + pub number_align: OuterHAlignment, + /// A supplement for the equation. /// /// For references to equations, this is added before the referenced number. @@ -192,7 +207,6 @@ impl Packed { ) -> SourceResult> { assert!(!self.block(styles)); - // Find a math font. let font = find_math_font(engine, styles, self.span())?; let mut ctx = MathContext::new(engine, styles, regions, &font); @@ -231,52 +245,34 @@ impl LayoutSingle for Packed { styles: StyleChain, regions: Regions, ) -> SourceResult { - const NUMBER_GUTTER: Em = Em::new(0.5); - assert!(self.block(styles)); - // Find a math font. - let font = find_math_font(engine, styles, self.span())?; + let span = self.span(); + let font = find_math_font(engine, styles, span)?; let mut ctx = MathContext::new(engine, styles, regions, &font); let mut frame = ctx.layout_into_frame(self, styles)?; if let Some(numbering) = (**self).numbering(styles) { let pod = Regions::one(regions.base(), Axes::splat(false)); - let counter = Counter::of(EquationElem::elem()) + let number = Counter::of(EquationElem::elem()) .at(engine, self.location().unwrap())? .display(engine, numbering)? - .spanned(self.span()) + .spanned(span) .layout(engine, styles, pod)? .into_frame(); - let full_counter_width = counter.width() + NUMBER_GUTTER.resolve(styles); - let width = if regions.size.x.is_finite() { - regions.size.x - } else { - frame.width() + 2.0 * full_counter_width - }; + static NUMBER_GUTTER: Em = Em::new(0.5); + let full_number_width = number.width() + NUMBER_GUTTER.resolve(styles); - let height = frame.height().max(counter.height()); - let align = AlignElem::alignment_in(styles).resolve(styles).x; - frame.resize(Size::new(width, height), Axes::splat(align)); - - let dir = TextElem::dir_in(styles); - let offset = match (align, dir) { - (FixedAlignment::Start, Dir::RTL) => full_counter_width, - (FixedAlignment::End, Dir::LTR) => -full_counter_width, - _ => Abs::zero(), - }; - frame.translate(Point::with_x(offset)); - - let x = if dir.is_positive() { - frame.width() - counter.width() - } else { - Abs::zero() - }; - let y = (frame.height() - counter.height()) / 2.0; - - frame.push_frame(Point::new(x, y), counter) + add_equation_number( + &mut frame, + number, + self.number_align(styles).resolve(styles), + AlignElem::alignment_in(styles).resolve(styles).x, + regions.size.x, + full_number_width, + ); } Ok(frame) @@ -398,3 +394,37 @@ fn find_math_font( }; Ok(font) } + +fn add_equation_number( + equation: &mut Frame, + number: Frame, + number_align: FixedAlignment, + equation_align: FixedAlignment, + region_size_x: Abs, + full_number_width: Abs, +) { + let width = if region_size_x.is_finite() { + region_size_x + } else { + equation.width() + 2.0 * full_number_width + }; + + let height = equation.height().max(number.height()); + equation.resize(Size::new(width, height), Axes::splat(equation_align)); + + let offset = match (equation_align, number_align) { + (FixedAlignment::Start, FixedAlignment::Start) => full_number_width, + (FixedAlignment::End, FixedAlignment::End) => -full_number_width, + _ => Abs::zero(), + }; + equation.translate(Point::with_x(offset)); + + let x = match number_align { + FixedAlignment::Start => Abs::zero(), + FixedAlignment::End => equation.width() - number.width(), + _ => unreachable!(), + }; + let y = (equation.height() - number.height()) / 2.0; + + equation.push_frame(Point::new(x, y), number); +} diff --git a/tests/ref/math/block-alignment.png b/tests/ref/math/equation-block-align.png similarity index 100% rename from tests/ref/math/block-alignment.png rename to tests/ref/math/equation-block-align.png diff --git a/tests/ref/math/equation-number.png b/tests/ref/math/equation-number.png new file mode 100644 index 0000000000000000000000000000000000000000..96a1f21ae637e8852e8432a2e3c9506348dea2bc GIT binary patch literal 18851 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 literal 0 HcmV?d00001 diff --git a/tests/typ/math/block-alignment.typ b/tests/typ/math/equation-block-align.typ similarity index 100% rename from tests/typ/math/block-alignment.typ rename to tests/typ/math/equation-block-align.typ diff --git a/tests/typ/math/equation-number.typ b/tests/typ/math/equation-number.typ new file mode 100644 index 000000000..aefa308a9 --- /dev/null +++ b/tests/typ/math/equation-number.typ @@ -0,0 +1,96 @@ +// Test equation number, and its interaction with equation +// block's alignment and text direction. + +--- +#set math.equation(numbering: "(1)") + +$ a + b = c $ + +#show math.equation: set align(center) +$ a + b = c $ +#show math.equation: set align(left) +$ a + b = c $ +#show math.equation: set align(right) +$ a + b = c $ + +#set text(dir: rtl) +#show math.equation: set align(start) +$ a + b = c $ +#show math.equation: set align(end) +$ a + b = c $ + +--- +#set math.equation(numbering: "(1)", number-align: start) + +$ a + b = c $ + +#show math.equation: set align(center) +$ a + b = c $ +#show math.equation: set align(left) +$ a + b = c $ +#show math.equation: set align(right) +$ a + b = c $ + +#set text(dir: rtl) +#show math.equation: set align(start) +$ a + b = c $ +#show math.equation: set align(end) +$ a + b = c $ + +--- +#set math.equation(numbering: "(1)", number-align: end) + +$ a + b = c $ + +#show math.equation: set align(center) +$ a + b = c $ +#show math.equation: set align(left) +$ a + b = c $ +#show math.equation: set align(right) +$ a + b = c $ + +#set text(dir: rtl) +#show math.equation: set align(start) +$ a + b = c $ +#show math.equation: set align(end) +$ a + b = c $ + +--- +#set math.equation(numbering: "(1)", number-align: left) + +$ a + b = c $ + +#show math.equation: set align(center) +$ a + b = c $ +#show math.equation: set align(left) +$ a + b = c $ +#show math.equation: set align(right) +$ a + b = c $ + +#set text(dir: rtl) +#show math.equation: set align(start) +$ a + b = c $ +#show math.equation: set align(end) +$ a + b = c $ + +--- +#set math.equation(numbering: "(1)", number-align: right) + +$ a + b = c $ + +#show math.equation: set align(center) +$ a + b = c $ +#show math.equation: set align(left) +$ a + b = c $ +#show math.equation: set align(right) +$ a + b = c $ + +#set text(dir: rtl) +#show math.equation: set align(start) +$ a + b = c $ +#show math.equation: set align(end) +$ a + b = c $ + +--- +// Error: 52-58 expected `start`, `left`, `right`, or `end`, found center +#set math.equation(numbering: "(1)", number-align: center)