diff options
| author | Laurenz <laurmaedje@gmail.com> | 2023-09-11 14:40:22 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2023-09-11 14:40:22 +0200 |
| commit | b471ac7d590abd2398ce25193b4e4df373bf2e9c (patch) | |
| tree | b5f7a6fdc807ee3340a4f42b0ad3cc563fe45429 /crates/typst-library/src/math | |
| parent | 8f36fca68447a5d42a3d54b5fac7e5546ee244be (diff) | |
First-class types
Makes types first-class values.
Diffstat (limited to 'crates/typst-library/src/math')
| -rw-r--r-- | crates/typst-library/src/math/accent.rs | 7 | ||||
| -rw-r--r-- | crates/typst-library/src/math/align.rs | 5 | ||||
| -rw-r--r-- | crates/typst-library/src/math/attach.rs | 35 | ||||
| -rw-r--r-- | crates/typst-library/src/math/cancel.rs | 26 | ||||
| -rw-r--r-- | crates/typst-library/src/math/class.rs | 7 | ||||
| -rw-r--r-- | crates/typst-library/src/math/frac.rs | 20 | ||||
| -rw-r--r-- | crates/typst-library/src/math/lr.rs (renamed from crates/typst-library/src/math/delimited.rs) | 32 | ||||
| -rw-r--r-- | crates/typst-library/src/math/matrix.rs | 47 | ||||
| -rw-r--r-- | crates/typst-library/src/math/mod.rs | 130 | ||||
| -rw-r--r-- | crates/typst-library/src/math/op.rs | 9 | ||||
| -rw-r--r-- | crates/typst-library/src/math/root.rs | 16 | ||||
| -rw-r--r-- | crates/typst-library/src/math/row.rs | 71 | ||||
| -rw-r--r-- | crates/typst-library/src/math/style.rs | 73 | ||||
| -rw-r--r-- | crates/typst-library/src/math/underover.rs | 44 |
14 files changed, 167 insertions, 355 deletions
diff --git a/crates/typst-library/src/math/accent.rs b/crates/typst-library/src/math/accent.rs index d1bee198..c92f9585 100644 --- a/crates/typst-library/src/math/accent.rs +++ b/crates/typst-library/src/math/accent.rs @@ -5,16 +5,13 @@ const ACCENT_SHORT_FALL: Em = Em::new(0.5); /// Attaches an accent to a base. /// -/// ## Example { #example } +/// # Example /// ```example /// $grave(a) = accent(a, `)$ \ /// $arrow(a) = accent(a, arrow)$ \ /// $tilde(a) = accent(a, \u{0303})$ /// ``` -/// -/// Display: Accent -/// Category: math -#[element(LayoutMath)] +#[elem(LayoutMath)] pub struct AccentElem { /// The base to which the accent is applied. /// May consist of multiple letters. diff --git a/crates/typst-library/src/math/align.rs b/crates/typst-library/src/math/align.rs index aee89a89..bf81597c 100644 --- a/crates/typst-library/src/math/align.rs +++ b/crates/typst-library/src/math/align.rs @@ -1,10 +1,7 @@ use super::*; /// A math alignment point: `&`, `&&`. -/// -/// Display: Alignment Point -/// Category: math -#[element(LayoutMath)] +#[elem(title = "Alignment Point", LayoutMath)] pub struct AlignPointElem {} impl LayoutMath for AlignPointElem { diff --git a/crates/typst-library/src/math/attach.rs b/crates/typst-library/src/math/attach.rs index d74beafe..c33b58e4 100644 --- a/crates/typst-library/src/math/attach.rs +++ b/crates/typst-library/src/math/attach.rs @@ -2,26 +2,13 @@ use super::*; /// A base with optional attachments. /// -/// ## Example { #example } /// ```example -/// // With syntax. -/// $ sum_(i=0)^n a_i = 2^(1+i) $ -/// -/// // With function call. /// $ attach( /// Pi, t: alpha, b: beta, /// tl: 1, tr: 2+3, bl: 4+5, br: 6, /// ) $ /// ``` -/// -/// ## Syntax { #syntax } -/// This function also has dedicated syntax for attachments after the base: Use -/// the underscore (`_`) to indicate a subscript i.e. bottom attachment and the -/// hat (`^`) to indicate a superscript i.e. top attachment. -/// -/// Display: Attachment -/// Category: math -#[element(LayoutMath)] +#[elem(LayoutMath)] pub struct AttachElem { /// The base to which things are attached. #[required] @@ -86,19 +73,15 @@ impl LayoutMath for AttachElem { /// Grouped primes. /// -/// ## Example { #example } /// ```example /// $ a'''_b = a^'''_b $ /// ``` /// -/// ## Syntax +/// # Syntax /// This function has dedicated syntax: use apostrophes instead of primes. They /// will automatically attach to the previous element, moving superscripts to /// the next level. -/// -/// Display: Attachment -/// Category: math -#[element(LayoutMath)] +#[elem(LayoutMath)] pub struct PrimesElem { /// The number of grouped primes. #[required] @@ -141,14 +124,10 @@ impl LayoutMath for PrimesElem { /// Forces a base to display attachments as scripts. /// -/// ## Example { #example } /// ```example /// $ scripts(sum)_1^2 != sum_1^2 $ /// ``` -/// -/// Display: Scripts -/// Category: math -#[element(LayoutMath)] +#[elem(LayoutMath)] pub struct ScriptsElem { /// The base to attach the scripts to. #[required] @@ -167,14 +146,10 @@ impl LayoutMath for ScriptsElem { /// Forces a base to display attachments as limits. /// -/// ## Example { #example } /// ```example /// $ limits(A)_1^2 != A_1^2 $ /// ``` -/// -/// Display: Limits -/// Category: math -#[element(LayoutMath)] +#[elem(LayoutMath)] pub struct LimitsElem { /// The base to attach the limits to. #[required] diff --git a/crates/typst-library/src/math/cancel.rs b/crates/typst-library/src/math/cancel.rs index f576a727..d27031b9 100644 --- a/crates/typst-library/src/math/cancel.rs +++ b/crates/typst-library/src/math/cancel.rs @@ -4,17 +4,14 @@ use super::*; /// /// This is commonly used to show the elimination of a term. /// -/// ## Example { #example } +/// # Example /// ```example /// >>> #set page(width: 140pt) /// Here, we can simplify: /// $ (a dot b dot cancel(x)) / /// cancel(x) $ /// ``` -/// -/// Display: Cancel -/// Category: math -#[element(LayoutMath)] +#[elem(LayoutMath)] pub struct CancelElem { /// The content over which the line should be placed. #[required] @@ -53,8 +50,8 @@ pub struct CancelElem { #[default(false)] pub cross: bool, - /// How to rotate the cancel line. See the [line's - /// documentation]($func/line.angle) for more details. + /// How to rotate the cancel line. See the + /// [line's documentation]($line.angle) for more details. /// /// ```example /// >>> #set page(width: 140pt) @@ -63,8 +60,7 @@ pub struct CancelElem { #[default(Angle::zero())] pub rotation: Angle, - /// How to stroke the cancel line. See the - /// [line's documentation]($func/line.stroke) for more details. + /// How to [stroke]($stroke) the cancel line. /// /// ```example /// >>> #set page(width: 140pt) @@ -79,12 +75,12 @@ pub struct CancelElem { /// ``` #[resolve] #[fold] - #[default(PartialStroke { + #[default(Stroke { // Default stroke has 0.5pt for better visuals. thickness: Smart::Custom(Abs::pt(0.5)), ..Default::default() })] - pub stroke: PartialStroke, + pub stroke: Stroke, } impl LayoutMath for CancelElem { @@ -99,7 +95,7 @@ impl LayoutMath for CancelElem { let span = self.span(); let length = self.length(styles).resolve(styles); - let stroke = self.stroke(styles).unwrap_or(Stroke { + let stroke = self.stroke(styles).unwrap_or(FixedStroke { paint: TextElem::fill_in(styles), ..Default::default() }); @@ -139,7 +135,7 @@ impl LayoutMath for CancelElem { /// Draws a cancel line. fn draw_cancel_line( length: Rel<Abs>, - stroke: Stroke, + stroke: FixedStroke, invert: bool, angle: Angle, body_size: Size, @@ -172,8 +168,8 @@ fn draw_cancel_line( // (-width / 2, height / 2) with length components (width, -height) (sign is // inverted in the y-axis). After applying the scale, the line will have the // correct length and orientation (inverted if needed). - let start = Axes::new(-mid.x, mid.y).zip(scales).map(|(l, s)| l * s); - let delta = Axes::new(width, -height).zip(scales).map(|(l, s)| l * s); + let start = Axes::new(-mid.x, mid.y).zip_map(scales, |l, s| l * s); + let delta = Axes::new(width, -height).zip_map(scales, |l, s| l * s); let mut frame = Frame::new(body_size); frame.push( diff --git a/crates/typst-library/src/math/class.rs b/crates/typst-library/src/math/class.rs index 69635c62..fc8a6c79 100644 --- a/crates/typst-library/src/math/class.rs +++ b/crates/typst-library/src/math/class.rs @@ -5,7 +5,7 @@ use super::*; /// This is useful to treat certain symbols as if they were of a different /// class, e.g. to make a symbol behave like a relation. /// -/// ## Example { #example } +/// # Example /// ```example /// #let loves = math.class( /// "relation", @@ -14,10 +14,7 @@ use super::*; /// /// $x loves y and y loves 5$ /// ``` -/// -/// Display: Class -/// Category: math -#[element(LayoutMath)] +#[elem(LayoutMath)] pub struct ClassElem { /// The class to apply to the content. #[required] diff --git a/crates/typst-library/src/math/frac.rs b/crates/typst-library/src/math/frac.rs index cf1d38e9..6a296203 100644 --- a/crates/typst-library/src/math/frac.rs +++ b/crates/typst-library/src/math/frac.rs @@ -4,21 +4,18 @@ const FRAC_AROUND: Em = Em::new(0.1); /// A mathematical fraction. /// -/// ## Example { #example } +/// # Example /// ```example /// $ 1/2 < (x+1)/2 $ /// $ ((x+1)) / 2 = frac(a, b) $ /// ``` /// -/// ## Syntax { #syntax } +/// # Syntax /// This function also has dedicated syntax: Use a slash to turn neighbouring /// expressions into a fraction. Multiple atoms can be grouped into a single /// expression using round grouping parenthesis. Such parentheses are removed /// from the output, but you can nest multiple to force them. -/// -/// Display: Fraction -/// Category: math -#[element(LayoutMath)] +#[elem(title = "Fraction", LayoutMath)] pub struct FracElem { /// The fraction's numerator. #[required] @@ -38,14 +35,11 @@ impl LayoutMath for FracElem { /// A binomial expression. /// -/// ## Example { #example } +/// # Example /// ```example /// $ binom(n, k) $ /// ``` -/// -/// Display: Binomial -/// Category: math -#[element(LayoutMath)] +#[elem(title = "Binomial", LayoutMath)] pub struct BinomElem { /// The binomial's upper index. #[required] @@ -135,10 +129,10 @@ fn layout( frame.push( line_pos, FrameItem::Shape( - Geometry::Line(Point::with_x(line_width)).stroked(Stroke { + Geometry::Line(Point::with_x(line_width)).stroked(FixedStroke { paint: TextElem::fill_in(ctx.styles()), thickness, - ..Stroke::default() + ..FixedStroke::default() }), span, ), diff --git a/crates/typst-library/src/math/delimited.rs b/crates/typst-library/src/math/lr.rs index 25ecf623..0d3c855e 100644 --- a/crates/typst-library/src/math/delimited.rs +++ b/crates/typst-library/src/math/lr.rs @@ -7,16 +7,7 @@ pub(super) const DELIM_SHORT_FALL: Em = Em::new(0.1); /// /// While matched delimiters scale by default, this can be used to scale /// unmatched delimiters and to control the delimiter scaling more precisely. -/// -/// ## Example { #example } -/// ```example -/// $ lr(]a, b/2]) $ -/// $ lr(]sum_(x=1)^n] x, size: #50%) $ -/// ``` -/// -/// Display: Left/Right -/// Category: math -#[element(LayoutMath)] +#[elem(title = "Left/Right", LayoutMath)] pub struct LrElem { /// The size of the brackets, relative to the height of the wrapped content. pub size: Smart<Rel<Length>>, @@ -107,13 +98,9 @@ fn scale( /// Floors an expression. /// -/// ## Example { #example } /// ```example /// $ floor(x/2) $ /// ``` -/// -/// Display: Floor -/// Category: math #[func] pub fn floor( /// The expression to floor. @@ -124,13 +111,9 @@ pub fn floor( /// Ceils an expression. /// -/// ## Example { #example } /// ```example /// $ ceil(x/2) $ /// ``` -/// -/// Display: Ceil -/// Category: math #[func] pub fn ceil( /// The expression to ceil. @@ -141,13 +124,9 @@ pub fn ceil( /// Rounds an expression. /// -/// ## Example { #example } /// ```example /// $ round(x/2) $ /// ``` -/// -/// Display: Round -/// Category: math #[func] pub fn round( /// The expression to round. @@ -158,14 +137,9 @@ pub fn round( /// Takes the absolute value of an expression. /// -/// ## Example { #example } /// ```example /// $ abs(x/2) $ /// ``` -/// -/// -/// Display: Abs -/// Category: math #[func] pub fn abs( /// The expression to take the absolute value of. @@ -176,13 +150,9 @@ pub fn abs( /// Takes the norm of an expression. /// -/// ## Example { #example } /// ```example /// $ norm(x/2) $ /// ``` -/// -/// Display: Norm -/// Category: math #[func] pub fn norm( /// The expression to take the norm of. diff --git a/crates/typst-library/src/math/matrix.rs b/crates/typst-library/src/math/matrix.rs index c913592d..abb0da35 100644 --- a/crates/typst-library/src/math/matrix.rs +++ b/crates/typst-library/src/math/matrix.rs @@ -12,15 +12,12 @@ const DEFAULT_STROKE_THICKNESS: Em = Em::new(0.05); /// /// Content in the vector's elements can be aligned with the `&` symbol. /// -/// ## Example { #example } +/// # Example /// ```example /// $ vec(a, b, c) dot vec(1, 2, 3) /// = a + 2b + 3c $ /// ``` -/// -/// Display: Vector -/// Category: math -#[element(LayoutMath)] +#[elem(title = "Vector", LayoutMath)] pub struct VecElem { /// The delimiter to use. /// @@ -40,7 +37,7 @@ impl LayoutMath for VecElem { #[tracing::instrument(skip(ctx))] fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { let delim = self.delim(ctx.styles()); - let frame = layout_vec_body(ctx, &self.children(), Align::Center)?; + let frame = layout_vec_body(ctx, &self.children(), FixedAlign::Center)?; layout_delimiters( ctx, frame, @@ -61,7 +58,7 @@ impl LayoutMath for VecElem { /// /// Content in cells that are in the same row can be aligned with the `&` symbol. /// -/// ## Example { #example } +/// # Example /// ```example /// $ mat( /// 1, 2, ..., 10; @@ -70,10 +67,7 @@ impl LayoutMath for VecElem { /// 10, 10, ..., 10; /// ) $ /// ``` -/// -/// Display: Matrix -/// Category: math -#[element(LayoutMath)] +#[elem(title = "Matrix", LayoutMath)] pub struct MatElem { /// The delimiter to use. /// @@ -102,10 +96,8 @@ pub struct MatElem { /// drawn after the second column of the matrix. Accepts either an /// integer for a single line, or an array of integers /// for multiple lines. - /// - `stroke`: How to stroke the line. See the - /// [line's documentation]($func/line.stroke) - /// for more details. If set to `{auto}`, takes on a thickness of - /// 0.05em and square line caps. + /// - `stroke`: How to [stroke]($stroke) the line. If set to `{auto}`, + /// takes on a thickness of 0.05em and square line caps. /// /// ```example /// $ mat(1, 0, 1; 0, 1, 2; augment: #2) $ @@ -204,7 +196,7 @@ impl LayoutMath for MatElem { /// /// Content across different branches can be aligned with the `&` symbol. /// -/// ## Example { #example } +/// # Example /// ```example /// $ f(x, y) := cases( /// 1 "if" (x dot y)/2 <= 0, @@ -213,10 +205,7 @@ impl LayoutMath for MatElem { /// 4 "else", /// ) $ /// ``` -/// -/// Display: Cases -/// Category: math -#[element(LayoutMath)] +#[elem(LayoutMath)] pub struct CasesElem { /// The delimiter to use. /// @@ -236,7 +225,7 @@ impl LayoutMath for CasesElem { #[tracing::instrument(skip(ctx))] fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { let delim = self.delim(ctx.styles()); - let frame = layout_vec_body(ctx, &self.children(), Align::Left)?; + let frame = layout_vec_body(ctx, &self.children(), FixedAlign::Start)?; layout_delimiters(ctx, frame, Some(delim.open()), None, self.span()) } } @@ -289,7 +278,7 @@ impl Delimiter { fn layout_vec_body( ctx: &mut MathContext, column: &[Content], - align: Align, + align: FixedAlign, ) -> SourceResult<Frame> { let gap = ROW_GAP.scaled(ctx); ctx.style(ctx.style.for_denominator()); @@ -319,7 +308,7 @@ fn layout_mat_body( // look correct by default at all matrix sizes. // The line cap is also set to square because it looks more "correct". let default_stroke_thickness = DEFAULT_STROKE_THICKNESS.scaled(ctx); - let default_stroke = Stroke { + let default_stroke = FixedStroke { thickness: default_stroke_thickness, line_cap: LineCap::Square, ..Default::default() @@ -383,7 +372,7 @@ fn layout_mat_body( let mut y = Abs::zero(); for (cell, &(ascent, descent)) in col.into_iter().zip(&heights) { - let cell = cell.into_aligned_frame(ctx, &points, Align::Center); + let cell = cell.into_aligned_frame(ctx, &points, FixedAlign::Center); let pos = Point::new( if points.is_empty() { x + (rcol - cell.width()) / 2.0 } else { x }, y + ascent - cell.ascent(), @@ -429,7 +418,7 @@ fn layout_mat_body( Ok(frame) } -fn line_item(length: Abs, vertical: bool, stroke: Stroke, span: Span) -> FrameItem { +fn line_item(length: Abs, vertical: bool, stroke: FixedStroke, span: Span) -> FrameItem { let line_geom = if vertical { Geometry::Line(Point::with_y(length)) } else { @@ -482,14 +471,14 @@ fn layout_delimiters( /// Parameters specifying how augmentation lines /// should be drawn on a matrix. #[derive(Default, Clone, Hash)] -pub struct Augment<T = Length> { +pub struct Augment<T: Numeric = Length> { pub hline: Offsets, pub vline: Offsets, - pub stroke: Smart<PartialStroke<T>>, + pub stroke: Smart<Stroke<T>>, } impl Augment<Abs> { - fn stroke_or(&self, fallback: Stroke) -> Stroke { + fn stroke_or(&self, fallback: FixedStroke) -> FixedStroke { match &self.stroke { Smart::Custom(v) => v.clone().unwrap_or(fallback), _ => fallback, @@ -543,7 +532,7 @@ cast! { let vline = dict.take("vline").ok().map(Offsets::from_value) .transpose().unwrap_or_default().unwrap_or_default(); - let stroke = dict.take("stroke").ok().map(PartialStroke::from_value) + let stroke = dict.take("stroke").ok().map(Stroke::from_value) .transpose()?.map(Smart::Custom).unwrap_or(Smart::Auto); Augment { hline, vline, stroke } diff --git a/crates/typst-library/src/math/mod.rs b/crates/typst-library/src/math/mod.rs index 5d32af64..578064ba 100644 --- a/crates/typst-library/src/math/mod.rs +++ b/crates/typst-library/src/math/mod.rs @@ -7,9 +7,9 @@ mod align; mod attach; mod cancel; mod class; -mod delimited; mod frac; mod fragment; +mod lr; mod matrix; mod op; mod root; @@ -24,8 +24,8 @@ pub use self::align::*; pub use self::attach::*; pub use self::cancel::*; pub use self::class::*; -pub use self::delimited::*; pub use self::frac::*; +pub use self::lr::*; pub use self::matrix::*; pub use self::op::*; pub use self::root::*; @@ -57,79 +57,64 @@ use crate::text::{ /// Create a module with all math definitions. pub fn module() -> Module { let mut math = Scope::deduplicating(); - math.define("equation", EquationElem::func()); - math.define("text", TextElem::func()); - - // Grouping. - math.define("lr", LrElem::func()); - math.define("abs", abs_func()); - math.define("norm", norm_func()); - math.define("floor", floor_func()); - math.define("ceil", ceil_func()); - math.define("round", round_func()); - - // Attachments and accents. - math.define("attach", AttachElem::func()); - math.define("scripts", ScriptsElem::func()); - math.define("limits", LimitsElem::func()); - math.define("accent", AccentElem::func()); - math.define("underline", UnderlineElem::func()); - math.define("overline", OverlineElem::func()); - math.define("underbrace", UnderbraceElem::func()); - math.define("overbrace", OverbraceElem::func()); - math.define("underbracket", UnderbracketElem::func()); - math.define("overbracket", OverbracketElem::func()); - math.define("cancel", CancelElem::func()); - - // Fractions and matrix-likes. - math.define("frac", FracElem::func()); - math.define("binom", BinomElem::func()); - math.define("vec", VecElem::func()); - math.define("mat", MatElem::func()); - math.define("cases", CasesElem::func()); - - // Roots. - math.define("sqrt", sqrt_func()); - math.define("root", RootElem::func()); - - // Styles. - math.define("upright", upright_func()); - math.define("bold", bold_func()); - math.define("italic", italic_func()); - math.define("serif", serif_func()); - math.define("sans", sans_func()); - math.define("cal", cal_func()); - math.define("frak", frak_func()); - math.define("mono", mono_func()); - math.define("bb", bb_func()); - - math.define("display", display_func()); - math.define("inline", inline_func()); - math.define("script", script_func()); - math.define("sscript", sscript_func()); - - math.define("class", ClassElem::func()); - - // Text operators. - math.define("op", OpElem::func()); + math.category("math"); + math.define_elem::<EquationElem>(); + math.define_elem::<TextElem>(); + math.define_elem::<LrElem>(); + math.define_elem::<AttachElem>(); + math.define_elem::<ScriptsElem>(); + math.define_elem::<LimitsElem>(); + math.define_elem::<AccentElem>(); + math.define_elem::<UnderlineElem>(); + math.define_elem::<OverlineElem>(); + math.define_elem::<UnderbraceElem>(); + math.define_elem::<OverbraceElem>(); + math.define_elem::<UnderbracketElem>(); + math.define_elem::<OverbracketElem>(); + math.define_elem::<CancelElem>(); + math.define_elem::<FracElem>(); + math.define_elem::<BinomElem>(); + math.define_elem::<VecElem>(); + math.define_elem::<MatElem>(); + math.define_elem::<CasesElem>(); + math.define_elem::<RootElem>(); + math.define_elem::<ClassElem>(); + math.define_elem::<OpElem>(); + math.define_func::<abs>(); + math.define_func::<norm>(); + math.define_func::<floor>(); + math.define_func::<ceil>(); + math.define_func::<round>(); + math.define_func::<sqrt>(); + math.define_func::<upright>(); + math.define_func::<bold>(); + math.define_func::<italic>(); + math.define_func::<serif>(); + math.define_func::<sans>(); + math.define_func::<cal>(); + math.define_func::<frak>(); + math.define_func::<mono>(); + math.define_func::<bb>(); + math.define_func::<display>(); + math.define_func::<inline>(); + math.define_func::<script>(); + math.define_func::<sscript>(); + + // Text operators, spacings, and symbols. op::define(&mut math); - - // Spacings. spacing::define(&mut math); - - // Symbols. for (name, symbol) in crate::symbols::SYM { math.define(*name, symbol.clone()); } - Module::new("math").with_scope(math) + Module::new("math", math) } /// A mathematical equation. /// /// Can be displayed inline with text or as a separate block. /// -/// ## Example { #example } +/// # Example /// ```example /// #set text(font: "New Computer Modern") /// @@ -142,16 +127,13 @@ pub fn module() -> Module { /// $ sum_(k=1)^n k = (n(n+1)) / 2 $ /// ``` /// -/// ## Syntax { #syntax } +/// # Syntax /// This function also has dedicated syntax: Write mathematical markup within /// dollar signs to create an equation. Starting and ending the equation with at /// least one space lifts it into a separate block that is centered /// horizontally. For more details about math syntax, see the /// [main math page]($category/math). -/// -/// Display: Equation -/// Category: math -#[element( +#[elem( Locatable, Synthesize, Show, Finalize, Layout, LayoutMath, Count, LocalName, Refable, Outlinable )] @@ -160,7 +142,7 @@ pub struct EquationElem { #[default(false)] pub block: bool, - /// How to [number]($func/numbering) block-level equations. + /// How to [number]($numbering) block-level equations. /// /// ```example /// #set math.equation(numbering: "(1)") @@ -216,9 +198,9 @@ impl Synthesize for EquationElem { impl Show for EquationElem { #[tracing::instrument(name = "EquationElem::show", skip_all)] fn show(&self, _: &mut Vt, styles: StyleChain) -> SourceResult<Content> { - let mut realized = self.clone().pack().guarded(Guard::Base(Self::func())); + let mut realized = self.clone().pack().guarded(Guard::Base(Self::elem())); if self.block(styles) { - realized = realized.aligned(Axes::with_x(Some(Align::Center.into()))) + realized = realized.aligned(Align::CENTER); } Ok(realized) } @@ -264,7 +246,7 @@ impl Layout for EquationElem { if block { if let Some(numbering) = self.numbering(styles) { let pod = Regions::one(regions.base(), Axes::splat(false)); - let counter = Counter::of(Self::func()) + let counter = Counter::of(Self::elem()) .display(Some(numbering), false) .layout(vt, styles, pod)? .into_frame(); @@ -277,7 +259,7 @@ impl Layout for EquationElem { }; let height = frame.height().max(counter.height()); - frame.resize(Size::new(width, height), Align::CENTER_HORIZON); + frame.resize(Size::new(width, height), Axes::splat(FixedAlign::Center)); let x = if TextElem::dir_in(styles).is_positive() { frame.width() - counter.width() @@ -358,7 +340,7 @@ impl Refable for EquationElem { } fn counter(&self) -> Counter { - Counter::of(Self::func()) + Counter::of(Self::elem()) } fn numbering(&self) -> Option<Numbering> { diff --git a/crates/typst-library/src/math/op.rs b/crates/typst-library/src/math/op.rs index 4016d24f..eed16465 100644 --- a/crates/typst-library/src/math/op.rs +++ b/crates/typst-library/src/math/op.rs @@ -4,23 +4,20 @@ use super::*; /// A text operator in an equation. /// -/// ## Example { #example } +/// # Example /// ```example /// $ tan x = (sin x)/(cos x) $ /// $ op("custom", /// limits: #true)_(n->oo) n $ /// ``` /// -/// ## Predefined Operators { #predefined } +/// # Predefined Operators { #predefined } /// Typst predefines the operators `arccos`, `arcsin`, `arctan`, `arg`, `cos`, /// `cosh`, `cot`, `coth`, `csc`, `ctg`, `deg`, `det`, `dim`, `exp`, `gcd`, /// `hom`, `id`, `im`, `inf`, `ker`, `lg`, `lim`, `liminf`, `limsup`, `ln`, /// `log`, `max`, `min`, `mod`, `Pr`, `sec`, `sin`, `sinc`, `sinh`, `sup`, /// `tan`, `tanh`, `tg` and `tr`. -/// -/// Display: Text Operator -/// Category: math -#[element(LayoutMath)] +#[elem(title = "Text Operator", LayoutMath)] pub struct OpElem { /// The operator's text. #[required] diff --git a/crates/typst-library/src/math/root.rs b/crates/typst-library/src/math/root.rs index b889f1cb..03d0a212 100644 --- a/crates/typst-library/src/math/root.rs +++ b/crates/typst-library/src/math/root.rs @@ -2,14 +2,10 @@ use super::*; /// A square root. /// -/// ## Example { #example } /// ```example /// $ sqrt(3 - 2 sqrt(2)) = sqrt(2) - 1 $ /// ``` -/// -/// Display: Square Root -/// Category: math -#[func] +#[func(title = "Square Root")] pub fn sqrt( /// The expression to take the square root of. radicand: Content, @@ -19,14 +15,10 @@ pub fn sqrt( /// A general root. /// -/// ## Example { #example } /// ```example /// $ root(3, x) $ /// ``` -/// -/// Display: Root -/// Category: math -#[element(LayoutMath)] +#[elem(LayoutMath)] pub struct RootElem { /// Which root of the radicand to take. #[positional] @@ -129,10 +121,10 @@ fn layout( frame.push( line_pos, FrameItem::Shape( - Geometry::Line(Point::with_x(radicand.width())).stroked(Stroke { + Geometry::Line(Point::with_x(radicand.width())).stroked(FixedStroke { paint: TextElem::fill_in(ctx.styles()), thickness, - ..Stroke::default() + ..FixedStroke::default() }), span, ), diff --git a/crates/typst-library/src/math/row.rs b/crates/typst-library/src/math/row.rs index 687f82b8..cf3a8af2 100644 --- a/crates/typst-library/src/math/row.rs +++ b/crates/typst-library/src/math/row.rs @@ -121,7 +121,7 @@ impl MathRow { pub fn into_frame(self, ctx: &MathContext) -> Frame { let styles = ctx.styles(); - let align = AlignElem::alignment_in(styles).x.resolve(styles); + let align = AlignElem::alignment_in(styles).resolve(styles).x; self.into_aligned_frame(ctx, &[], align) } @@ -137,53 +137,54 @@ impl MathRow { self, ctx: &MathContext, points: &[Abs], - align: Align, + align: FixedAlign, ) -> Frame { - if self.iter().any(|frag| matches!(frag, MathFragment::Linebreak)) { - let leading = if ctx.style.size >= MathSize::Text { - ParElem::leading_in(ctx.styles()) - } else { - TIGHT_LEADING.scaled(ctx) - }; + if !self.iter().any(|frag| matches!(frag, MathFragment::Linebreak)) { + return self.into_line_frame(points, align); + } - let mut rows: Vec<_> = self.rows(); + let leading = if ctx.style.size >= MathSize::Text { + ParElem::leading_in(ctx.styles()) + } else { + TIGHT_LEADING.scaled(ctx) + }; - if matches!(rows.last(), Some(row) if row.0.is_empty()) { - rows.pop(); - } + let mut rows: Vec<_> = self.rows(); - let AlignmentResult { points, width } = alignments(&rows); - let mut frame = Frame::new(Size::zero()); + if matches!(rows.last(), Some(row) if row.0.is_empty()) { + rows.pop(); + } - for (i, row) in rows.into_iter().enumerate() { - let sub = row.into_line_frame(&points, align); - let size = frame.size_mut(); - if i > 0 { - size.y += leading; - } + let AlignmentResult { points, width } = alignments(&rows); + let mut frame = Frame::new(Size::zero()); - let mut pos = Point::with_y(size.y); - if points.is_empty() { - pos.x = align.position(width - sub.width()); - } - size.y += sub.height(); - size.x.set_max(sub.width()); - frame.push_frame(pos, sub); + for (i, row) in rows.into_iter().enumerate() { + let sub = row.into_line_frame(&points, align); + let size = frame.size_mut(); + if i > 0 { + size.y += leading; } - frame - } else { - self.into_line_frame(points, align) + + let mut pos = Point::with_y(size.y); + if points.is_empty() { + pos.x = align.position(width - sub.width()); + } + size.y += sub.height(); + size.x.set_max(sub.width()); + frame.push_frame(pos, sub); } + + frame } - fn into_line_frame(self, points: &[Abs], align: Align) -> Frame { + fn into_line_frame(self, points: &[Abs], align: FixedAlign) -> Frame { let ascent = self.ascent(); let mut frame = Frame::new(Size::new(Abs::zero(), ascent + self.descent())); frame.set_baseline(ascent); let mut next_x = { let mut widths = Vec::new(); - if !points.is_empty() && align != Align::Left { + if !points.is_empty() && align != FixedAlign::Start { let mut width = Abs::zero(); for fragment in self.iter() { if matches!(fragment, MathFragment::Align) { @@ -201,8 +202,10 @@ impl MathRow { 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), + FixedAlign::Start => prev_points.next(), + FixedAlign::End => { + point_widths.next().map(|(point, width)| point - width) + } _ => point_widths .next() .zip(prev_points.next()) diff --git a/crates/typst-library/src/math/style.rs b/crates/typst-library/src/math/style.rs index 35a4cfdb..4d80a235 100644 --- a/crates/typst-library/src/math/style.rs +++ b/crates/typst-library/src/math/style.rs @@ -2,13 +2,9 @@ use super::*; /// Bold font style in math. /// -/// ## Example { #example } /// ```example /// $ bold(A) := B^+ $ /// ``` -/// -/// Display: Bold -/// Category: math #[func] pub fn bold( /// The content to style. @@ -19,13 +15,9 @@ pub fn bold( /// Upright (non-italic) font style in math. /// -/// ## Example { #example } /// ```example /// $ upright(A) != A $ /// ``` -/// -/// Display: Upright -/// Category: math #[func] pub fn upright( /// The content to style. @@ -37,9 +29,6 @@ pub fn upright( /// Italic font style in math. /// /// For roman letters and greek lowercase letters, this is already the default. -/// -/// Display: Italic -/// Category: math #[func] pub fn italic( /// The content to style. @@ -50,9 +39,6 @@ pub fn italic( /// Serif (roman) font style in math. /// /// This is already the default. -/// -/// Display: Serif -/// Category: math #[func] pub fn serif( /// The content to style. @@ -63,14 +49,10 @@ pub fn serif( /// Sans-serif font style in math. /// -/// ## Example { #example } /// ```example /// $ sans(A B C) $ /// ``` -/// -/// Display: Sans-serif -/// Category: math -#[func] +#[func(title = "Sans Serif")] pub fn sans( /// The content to style. body: Content, @@ -80,14 +62,10 @@ pub fn sans( /// Calligraphic font style in math. /// -/// ## Example { #example } /// ```example /// Let $cal(P)$ be the set of ... /// ``` -/// -/// Display: Calligraphic -/// Category: math -#[func] +#[func(title = "Calligraphic")] pub fn cal( /// The content to style. body: Content, @@ -97,14 +75,10 @@ pub fn cal( /// Fraktur font style in math. /// -/// ## Example { #example } /// ```example /// $ frak(P) $ /// ``` -/// -/// Display: Fraktur -/// Category: math -#[func] +#[func(title = "Fraktur")] pub fn frak( /// The content to style. body: Content, @@ -114,14 +88,10 @@ pub fn frak( /// Monospace font style in math. /// -/// ## Example { #example } /// ```example /// $ mono(x + y = z) $ /// ``` -/// -/// Display: Monospace -/// Category: math -#[func] +#[func(title = "Monospace")] pub fn mono( /// The content to style. body: Content, @@ -134,16 +104,12 @@ pub fn mono( /// For uppercase latin letters, blackboard bold is additionally available /// through [symbols]($category/symbols/sym) of the form `NN` and `RR`. /// -/// ## Example { #example } /// ```example /// $ bb(b) $ /// $ bb(N) = NN $ /// $ f: NN -> RR $ /// ``` -/// -/// Display: Blackboard Bold -/// Category: math -#[func] +#[func(title = "Blackboard Bold")] pub fn bb( /// The content to style. body: Content, @@ -155,14 +121,10 @@ pub fn bb( /// /// This is the normal size for block equations. /// -/// ## Example { #example } /// ```example /// $sum_i x_i/2 = display(sum_i x_i/2)$ /// ``` -/// -/// Display: Display Size -/// Category: math -#[func] +#[func(title = "Display Size")] pub fn display( /// The content to size. body: Content, @@ -182,15 +144,11 @@ pub fn display( /// /// This is the normal size for inline equations. /// -/// ## Example { #example } /// ```example /// $ sum_i x_i/2 /// = inline(sum_i x_i/2) $ /// ``` -/// -/// Display: Inline Size -/// Category: math -#[func] +#[func(title = "Inline Size")] pub fn inline( /// The content to size. body: Content, @@ -210,14 +168,10 @@ pub fn inline( /// /// This is the smaller size used in powers or sub- or superscripts. /// -/// ## Example { #example } /// ```example /// $sum_i x_i/2 = script(sum_i x_i/2)$ /// ``` -/// -/// Display: Script Size -/// Category: math -#[func] +#[func(title = "Script Size")] pub fn script( /// The content to size. body: Content, @@ -238,14 +192,10 @@ pub fn script( /// This is the smallest size, used in second-level sub- and superscripts /// (script of the script). /// -/// ## Example { #example } /// ```example /// $sum_i x_i/2 = sscript(sum_i x_i/2)$ /// ``` -/// -/// Display: Script-Script Size -/// Category: math -#[func] +#[func(title = "Script-Script Size")] pub fn sscript( /// The content to size. body: Content, @@ -262,10 +212,7 @@ pub fn sscript( } /// A font variant in math. -/// -/// Display: Bold -/// Category: math -#[element(LayoutMath)] +#[elem(LayoutMath)] pub struct MathStyleElem { /// The content to style. #[required] diff --git a/crates/typst-library/src/math/underover.rs b/crates/typst-library/src/math/underover.rs index 796c9ebc..3e8dba1a 100644 --- a/crates/typst-library/src/math/underover.rs +++ b/crates/typst-library/src/math/underover.rs @@ -11,14 +11,10 @@ enum LineKind { /// A horizontal line under content. /// -/// ## Example { #example } /// ```example /// $ underline(1 + 2 + ... + 5) $ /// ``` -/// -/// Display: Underline -/// Category: math -#[element(LayoutMath)] +#[elem(LayoutMath)] pub struct UnderlineElem { /// The content above the line. #[required] @@ -34,14 +30,10 @@ impl LayoutMath for UnderlineElem { /// A horizontal line over content. /// -/// ## Example { #example } /// ```example /// $ overline(1 + 2 + ... + 5) $ /// ``` -/// -/// Display: Overline -/// Category: math -#[element(LayoutMath)] +#[elem(LayoutMath)] pub struct OverlineElem { /// The content below the line. #[required] @@ -103,10 +95,10 @@ fn layout_underoverline( frame.push( line_pos, FrameItem::Shape( - Geometry::Line(Point::with_x(width)).stroked(Stroke { + Geometry::Line(Point::with_x(width)).stroked(FixedStroke { paint: TextElem::fill_in(ctx.styles()), thickness: bar_height, - ..Stroke::default() + ..FixedStroke::default() }), span, ), @@ -119,14 +111,10 @@ fn layout_underoverline( /// A horizontal brace under content, with an optional annotation below. /// -/// ## Example { #example } /// ```example /// $ underbrace(1 + 2 + ... + 5, "numbers") $ /// ``` -/// -/// Display: Underbrace -/// Category: math -#[element(LayoutMath)] +#[elem(LayoutMath)] pub struct UnderbraceElem { /// The content above the brace. #[required] @@ -154,14 +142,10 @@ impl LayoutMath for UnderbraceElem { /// A horizontal brace over content, with an optional annotation above. /// -/// ## Example { #example } /// ```example /// $ overbrace(1 + 2 + ... + 5, "numbers") $ /// ``` -/// -/// Display: Overbrace -/// Category: math -#[element(LayoutMath)] +#[elem(LayoutMath)] pub struct OverbraceElem { /// The content below the brace. #[required] @@ -189,14 +173,10 @@ impl LayoutMath for OverbraceElem { /// A horizontal bracket under content, with an optional annotation below. /// -/// ## Example { #example } /// ```example /// $ underbracket(1 + 2 + ... + 5, "numbers") $ /// ``` -/// -/// Display: Underbracket -/// Category: math -#[element(LayoutMath)] +#[elem(LayoutMath)] pub struct UnderbracketElem { /// The content above the bracket. #[required] @@ -224,14 +204,10 @@ impl LayoutMath for UnderbracketElem { /// A horizontal bracket over content, with an optional annotation above. /// -/// ## Example { #example } /// ```example /// $ overbracket(1 + 2 + ... + 5, "numbers") $ /// ``` -/// -/// Display: Overbracket -/// Category: math -#[element(LayoutMath)] +#[elem(LayoutMath)] pub struct OverbracketElem { /// The content below the bracket. #[required] @@ -294,7 +270,7 @@ fn layout_underoverspreader( baseline = rows.len() - 1; } - let frame = stack(ctx, rows, Align::Center, gap, baseline); + let frame = stack(ctx, rows, FixedAlign::Center, gap, baseline); ctx.push(FrameFragment::new(ctx, frame).with_class(body_class)); Ok(()) @@ -307,7 +283,7 @@ fn layout_underoverspreader( pub(super) fn stack( ctx: &MathContext, rows: Vec<MathRow>, - align: Align, + align: FixedAlign, gap: Abs, baseline: usize, ) -> Frame { |
