typst_library/math/
mod.rs1pub mod accent;
4mod attach;
5mod cancel;
6mod equation;
7mod frac;
8pub mod ir;
9mod lr;
10mod matrix;
11mod op;
12mod root;
13mod style;
14mod underover;
15
16pub use self::accent::{ACCENT_SHORT_FALL, Accent, AccentElem};
17pub use self::attach::*;
18pub use self::cancel::*;
19pub use self::equation::*;
20pub use self::frac::*;
21pub use self::lr::*;
22pub use self::matrix::*;
23pub use self::op::*;
24pub use self::root::*;
25pub use self::style::*;
26pub use self::underover::*;
27
28use typst_utils::singleton;
29use unicode_math_class::MathClass;
30
31use crate::foundations::{Content, Module, NativeElement, Scope, StyleChain, elem};
32use crate::layout::{Em, HElem};
33use crate::text::{FontFamily, TextElem};
34
35pub const THIN: Em = Em::new(1.0 / 6.0);
37pub const MEDIUM: Em = Em::new(2.0 / 9.0);
38pub const THICK: Em = Em::new(5.0 / 18.0);
39pub const QUAD: Em = Em::new(1.0);
40pub const WIDE: Em = Em::new(2.0);
41
42pub fn module() -> Module {
44 let mut math = Scope::deduplicating();
45 math.start_category(crate::Category::Math);
46 math.define_elem::<EquationElem>();
47 math.define_elem::<TextElem>();
48 math.define_elem::<LrElem>();
49 math.define_elem::<MidElem>();
50 math.define_elem::<AttachElem>();
51 math.define_elem::<StretchElem>();
52 math.define_elem::<ScriptsElem>();
53 math.define_elem::<LimitsElem>();
54 math.define_elem::<AccentElem>();
55 math.define_elem::<UnderlineElem>();
56 math.define_elem::<OverlineElem>();
57 math.define_elem::<UnderbraceElem>();
58 math.define_elem::<OverbraceElem>();
59 math.define_elem::<UnderbracketElem>();
60 math.define_elem::<OverbracketElem>();
61 math.define_elem::<UnderparenElem>();
62 math.define_elem::<OverparenElem>();
63 math.define_elem::<UndershellElem>();
64 math.define_elem::<OvershellElem>();
65 math.define_elem::<CancelElem>();
66 math.define_elem::<FracElem>();
67 math.define_elem::<BinomElem>();
68 math.define_elem::<VecElem>();
69 math.define_elem::<MatElem>();
70 math.define_elem::<CasesElem>();
71 math.define_elem::<RootElem>();
72 math.define_elem::<ClassElem>();
73 math.define_elem::<OpElem>();
74 math.define_elem::<PrimesElem>();
75 math.define_func::<abs>();
76 math.define_func::<norm>();
77 math.define_func::<round>();
78 math.define_func::<sqrt>();
79 math.define_func::<upright>();
80 math.define_func::<bold>();
81 math.define_func::<italic>();
82 math.define_func::<serif>();
83 math.define_func::<sans>();
84 math.define_func::<scr>();
85 math.define_func::<cal>();
86 math.define_func::<frak>();
87 math.define_func::<mono>();
88 math.define_func::<bb>();
89 math.define_func::<display>();
90 math.define_func::<inline>();
91 math.define_func::<script>();
92 math.define_func::<sscript>();
93
94 op::define(&mut math);
96
97 math.define("thin", HElem::new(THIN.into()).pack());
99 math.define("med", HElem::new(MEDIUM.into()).pack());
100 math.define("thick", HElem::new(THICK.into()).pack());
101 math.define("quad", HElem::new(QUAD.into()).pack());
102 math.define("wide", HElem::new(WIDE.into()).pack());
103
104 crate::symbols::define_math(&mut math);
106
107 Module::new("math", math)
108}
109
110pub trait Mathy {}
112
113#[elem(title = "Alignment Point", Mathy)]
115pub struct AlignPointElem {}
116
117impl AlignPointElem {
118 pub fn shared() -> &'static Content {
120 singleton!(Content, AlignPointElem::new().pack())
121 }
122}
123
124#[elem(Mathy)]
142pub struct ClassElem {
143 #[required]
145 pub class: MathClass,
146
147 #[required]
149 pub body: Content,
150}
151
152#[derive(Debug, Copy, Clone, Eq, PartialEq)]
155pub enum LeftRightAlternator {
156 None,
157 Left,
158 Right,
159}
160
161impl Iterator for LeftRightAlternator {
162 type Item = LeftRightAlternator;
163
164 fn next(&mut self) -> Option<Self::Item> {
165 let r = Some(*self);
166 match self {
167 Self::None => {}
168 Self::Left => *self = Self::Right,
169 Self::Right => *self = Self::Left,
170 }
171 r
172 }
173}
174
175pub fn families(styles: StyleChain<'_>) -> impl Iterator<Item = &'_ FontFamily> + Clone {
177 let fallbacks = singleton!(Vec<FontFamily>, {
178 [
179 "new computer modern math",
180 "libertinus serif",
181 "twitter color emoji",
182 "noto color emoji",
183 "apple color emoji",
184 "segoe ui emoji",
185 ]
186 .into_iter()
187 .map(FontFamily::new)
188 .collect()
189 });
190
191 let tail = if styles.get(TextElem::fallback) { fallbacks.as_slice() } else { &[] };
192 styles.get_ref(TextElem::font).into_iter().chain(tail.iter())
193}