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::{Content, Module, NativeElement, Scope, elem};
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::<scr>();
84    math.define_func::<cal>();
85    math.define_func::<frak>();
86    math.define_func::<mono>();
87    math.define_func::<bb>();
88    math.define_func::<display>();
89    math.define_func::<inline>();
90    math.define_func::<script>();
91    math.define_func::<sscript>();
92
93    // Text operators.
94    op::define(&mut math);
95
96    // Spacings.
97    math.define("thin", HElem::new(THIN.into()).pack());
98    math.define("med", HElem::new(MEDIUM.into()).pack());
99    math.define("thick", HElem::new(THICK.into()).pack());
100    math.define("quad", HElem::new(QUAD.into()).pack());
101    math.define("wide", HElem::new(WIDE.into()).pack());
102
103    // Symbols.
104    crate::symbols::define_math(&mut math);
105
106    Module::new("math", math)
107}
108
109/// Trait for recognizing math elements and auto-wrapping them in equations.
110pub trait Mathy {}
111
112/// A math alignment point: `&`, `&&`.
113#[elem(title = "Alignment Point", Mathy)]
114pub struct AlignPointElem {}
115
116impl AlignPointElem {
117    /// Get the globally shared alignment point element.
118    pub fn shared() -> &'static Content {
119        singleton!(Content, AlignPointElem::new().pack())
120    }
121}
122
123/// Forced use of a certain math class.
124///
125/// This is useful to treat certain symbols as if they were of a different
126/// class, e.g. to make a symbol behave like a relation. The class of a symbol
127/// defines the way it is laid out, including spacing around it, and how its
128/// scripts are attached by default. Note that the latter can always be
129/// overridden using [`{limits}`](math.limits) and [`{scripts}`](math.scripts).
130///
131/// # Example
132/// ```example
133/// #let loves = math.class(
134///   "relation",
135///   sym.suit.heart,
136/// )
137///
138/// $x loves y and y loves 5$
139/// ```
140#[elem(Mathy)]
141pub struct ClassElem {
142    /// The class to apply to the content.
143    #[required]
144    pub class: MathClass,
145
146    /// The content to which the class is applied.
147    #[required]
148    pub body: Content,
149}