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
106
107
|
use typst::model::Scope;
use super::*;
/// # Text Operator
/// A text operator in a math formula.
///
/// ## Parameters
/// - text: EcoString (positional, required)
/// The operator's text.
/// - limits: bool (named)
/// Whether the operator should force attachments to display as limits.
///
/// Defaults to `{false}`.
///
/// ## Category
/// math
#[func]
#[capable(LayoutMath)]
#[derive(Debug, Hash)]
pub struct OpNode {
/// The operator's text.
pub text: EcoString,
/// Whether the operator should force attachments to display as limits.
pub limits: bool,
}
#[node]
impl OpNode {
fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> {
Ok(Self {
text: args.expect("text")?,
limits: args.named("limits")?.unwrap_or(false),
}
.pack())
}
}
impl LayoutMath for OpNode {
fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> {
let frame = ctx.layout_content(&TextNode(self.text.clone()).pack())?;
ctx.push(
FrameFragment::new(ctx, frame)
.with_class(MathClass::Large)
.with_limits(self.limits),
);
Ok(())
}
}
macro_rules! ops {
($($name:ident $(: $value:literal)? $(($tts:tt))?),* $(,)?) => {
pub(super) fn define(math: &mut Scope) {
$(math.define(
stringify!($name),
OpNode {
text: ops!(@name $name $(: $value)?).into(),
limits: ops!(@limit $($tts)*),
}.pack()
);)*
let dif = |d| HNode::strong(THIN).pack() + UprightNode(TextNode::packed(d)).pack();
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,
deg,
det (limits),
dim,
exp,
gcd (limits),
hom,
mod,
inf (limits),
ker,
lg,
lim (limits),
ln,
log,
max (limits),
min (limits),
Pr (limits),
sec,
sin,
sinh,
sup (limits),
tan,
tanh,
liminf: "lim inf" (limits),
limsup: "lim sup" (limits),
}
|