typst_library/math/op.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
use ecow::EcoString;
use crate::foundations::{elem, Content, NativeElement, Scope, SymbolElem};
use crate::layout::HElem;
use crate::math::{upright, Mathy, THIN};
use crate::text::TextElem;
/// A text operator in an equation.
///
/// # Example
/// ```example
/// $ tan x = (sin x)/(cos x) $
/// $ op("custom",
/// limits: #true)_(n->oo) n $
/// ```
///
/// # Predefined Operators { #predefined }
/// Typst predefines the operators `arccos`, `arcsin`, `arctan`, `arg`, `cos`,
/// `cosh`, `cot`, `coth`, `csc`, `csch`, `ctg`, `deg`, `det`, `dim`, `exp`,
/// `gcd`, `lcm`, `hom`, `id`, `im`, `inf`, `ker`, `lg`, `lim`, `liminf`,
/// `limsup`, `ln`, `log`, `max`, `min`, `mod`, `Pr`, `sec`, `sech`, `sin`,
/// `sinc`, `sinh`, `sup`, `tan`, `tanh`, `tg` and `tr`.
#[elem(title = "Text Operator", Mathy)]
pub struct OpElem {
/// The operator's text.
#[required]
pub text: Content,
/// Whether the operator should show attachments as limits in display mode.
#[default(false)]
pub limits: bool,
}
macro_rules! ops {
($($name:ident $(: $value:literal)? $(($tts:tt))?),* $(,)?) => {
pub(super) fn define(math: &mut Scope) {
$({
let operator = EcoString::from(ops!(@name $name $(: $value)?));
math.define(
stringify!($name),
// Latex also uses their equivalent of `TextElem` here.
OpElem::new(TextElem::new(operator).into())
.with_limits(ops!(@limit $($tts)*))
.pack()
);
})*
let dif = |d| {
HElem::new(THIN.into()).with_weak(true).pack()
+ upright(SymbolElem::packed(d))
};
math.define("dif", dif('d'));
math.define("Dif", dif('D'));
}
};
(@name $name:ident) => { stringify!($name) };
(@name $name:ident: $value:literal) => { $value };
(@limit limits) => { true };
(@limit) => { false };
}
ops! {
arccos,
arcsin,
arctan,
arg,
cos,
cosh,
cot,
coth,
csc,
csch,
ctg,
deg,
det (limits),
dim,
exp,
gcd (limits),
lcm (limits),
hom,
id,
im,
inf (limits),
ker,
lg,
lim (limits),
liminf: "lim inf" (limits),
limsup: "lim sup" (limits),
ln,
log,
max (limits),
min (limits),
mod,
Pr (limits),
sec,
sech,
sin,
sinc,
sinh,
sup (limits),
tan,
tanh,
tg,
tr,
}