typst_library/math/
mod.rs

1//! Mathematical formulas.
2
3pub mod accent;
4mod attach;
5mod cancel;
6mod equation;
7mod frac;
8mod lr;
9mod matrix;
10mod op;
11mod root;
12mod style;
13mod underover;
14
15pub use self::accent::{Accent, AccentElem};
16pub use self::attach::*;
17pub use self::cancel::*;
18pub use self::equation::*;
19pub use self::frac::*;
20pub use self::lr::*;
21pub use self::matrix::*;
22pub use self::op::*;
23pub use self::root::*;
24pub use self::style::*;
25pub use self::underover::*;
26
27use typst_utils::singleton;
28use unicode_math_class::MathClass;
29
30use crate::foundations::{elem, Content, Module, NativeElement, Scope};
31use crate::layout::{Em, HElem};
32use crate::text::TextElem;
33
34// Spacings.
35pub const THIN: Em = Em::new(1.0 / 6.0);
36pub const MEDIUM: Em = Em::new(2.0 / 9.0);
37pub const THICK: Em = Em::new(5.0 / 18.0);
38pub const QUAD: Em = Em::new(1.0);
39pub const WIDE: Em = Em::new(2.0);
40
41/// Create a module with all math definitions.
42pub fn module() -> Module {
43    let mut math = Scope::deduplicating();
44    math.start_category(crate::Category::Math);
45    math.define_elem::<EquationElem>();
46    math.define_elem::<TextElem>();
47    math.define_elem::<LrElem>();
48    math.define_elem::<MidElem>();
49    math.define_elem::<AttachElem>();
50    math.define_elem::<StretchElem>();
51    math.define_elem::<ScriptsElem>();
52    math.define_elem::<LimitsElem>();
53    math.define_elem::<AccentElem>();
54    math.define_elem::<UnderlineElem>();
55    math.define_elem::<OverlineElem>();
56    math.define_elem::<UnderbraceElem>();
57    math.define_elem::<OverbraceElem>();
58    math.define_elem::<UnderbracketElem>();
59    math.define_elem::<OverbracketElem>();
60    math.define_elem::<UnderparenElem>();
61    math.define_elem::<OverparenElem>();
62    math.define_elem::<UndershellElem>();
63    math.define_elem::<OvershellElem>();
64    math.define_elem::<CancelElem>();
65    math.define_elem::<FracElem>();
66    math.define_elem::<BinomElem>();
67    math.define_elem::<VecElem>();
68    math.define_elem::<MatElem>();
69    math.define_elem::<CasesElem>();
70    math.define_elem::<RootElem>();
71    math.define_elem::<ClassElem>();
72    math.define_elem::<OpElem>();
73    math.define_elem::<PrimesElem>();
74    math.define_func::<abs>();
75    math.define_func::<norm>();
76    math.define_func::<round>();
77    math.define_func::<sqrt>();
78    math.define_func::<upright>();
79    math.define_func::<bold>();
80    math.define_func::<italic>();
81    math.define_func::<serif>();
82    math.define_func::<sans>();
83    math.define_func::<cal>();
84    math.define_func::<frak>();
85    math.define_func::<mono>();
86    math.define_func::<bb>();
87    math.define_func::<display>();
88    math.define_func::<inline>();
89    math.define_func::<script>();
90    math.define_func::<sscript>();
91
92    // Text operators.
93    op::define(&mut math);
94
95    // Spacings.
96    math.define("thin", HElem::new(THIN.into()).pack());
97    math.define("med", HElem::new(MEDIUM.into()).pack());
98    math.define("thick", HElem::new(THICK.into()).pack());
99    math.define("quad", HElem::new(QUAD.into()).pack());
100    math.define("wide", HElem::new(WIDE.into()).pack());
101
102    // Symbols.
103    crate::symbols::define_math(&mut math);
104
105    Module::new("math", math)
106}
107
108/// Trait for recognizing math elements and auto-wrapping them in equations.
109pub trait Mathy {}
110
111/// A math alignment point: `&`, `&&`.
112#[elem(title = "Alignment Point", Mathy)]
113pub struct AlignPointElem {}
114
115impl AlignPointElem {
116    /// Get the globally shared alignment point element.
117    pub fn shared() -> &'static Content {
118        singleton!(Content, AlignPointElem::new().pack())
119    }
120}
121
122/// Forced use of a certain math class.
123///
124/// This is useful to treat certain symbols as if they were of a different
125/// class, e.g. to make a symbol behave like a relation. The class of a symbol
126/// defines the way it is laid out, including spacing around it, and how its
127/// scripts are attached by default. Note that the latter can always be
128/// overridden using [`{limits}`](math.limits) and [`{scripts}`](math.scripts).
129///
130/// # Example
131/// ```example
132/// #let loves = math.class(
133///   "relation",
134///   sym.suit.heart,
135/// )
136///
137/// $x loves y and y loves 5$
138/// ```
139#[elem(Mathy)]
140pub struct ClassElem {
141    /// The class to apply to the content.
142    #[required]
143    pub class: MathClass,
144
145    /// The content to which the class is applied.
146    #[required]
147    pub body: Content,
148}