1use ecow::EcoString;
2
3use crate::foundations::{elem, Content, NativeElement, Scope, SymbolElem};
4use crate::layout::HElem;
5use crate::math::{upright, Mathy, THIN};
6use crate::text::TextElem;
7
8#[elem(title = "Text Operator", Mathy)]
24pub struct OpElem {
25 #[required]
27 pub text: Content,
28
29 #[default(false)]
31 pub limits: bool,
32}
33
34macro_rules! ops {
35 ($($name:ident $(: $value:literal)? $(($tts:tt))?),* $(,)?) => {
36 pub(super) fn define(math: &mut Scope) {
37 $({
38 let operator = EcoString::from(ops!(@name $name $(: $value)?));
39 math.define(
40 stringify!($name),
41 OpElem::new(TextElem::new(operator).into())
43 .with_limits(ops!(@limit $($tts)*))
44 .pack()
45 );
46 })*
47
48 let dif = |d| {
49 HElem::new(THIN.into()).with_weak(true).pack()
50 + upright(SymbolElem::packed(d))
51 };
52 math.define("dif", dif('d'));
53 math.define("Dif", dif('D'));
54 }
55 };
56 (@name $name:ident) => { stringify!($name) };
57 (@name $name:ident: $value:literal) => { $value };
58 (@limit limits) => { true };
59 (@limit) => { false };
60}
61
62ops! {
63 arccos,
64 arcsin,
65 arctan,
66 arg,
67 cos,
68 cosh,
69 cot,
70 coth,
71 csc,
72 csch,
73 ctg,
74 deg,
75 det (limits),
76 dim,
77 exp,
78 gcd (limits),
79 lcm (limits),
80 hom,
81 id,
82 im,
83 inf (limits),
84 ker,
85 lg,
86 lim (limits),
87 liminf: "lim inf" (limits),
88 limsup: "lim sup" (limits),
89 ln,
90 log,
91 max (limits),
92 min (limits),
93 mod,
94 Pr (limits),
95 sec,
96 sech,
97 sin,
98 sinc,
99 sinh,
100 sup (limits),
101 tan,
102 tanh,
103 tg,
104 tr,
105}