1use std::collections::HashMap;
2
3use crate::error::ParseResult;
4use crate::functions::{define_function_full, FunctionContext, FunctionSpec};
5use crate::parse_node::ParseNode;
6
7pub fn register(map: &mut HashMap<&'static str, FunctionSpec>) {
8 define_function_full(
10 map,
11 &[
12 "\\coprod", "\\bigvee", "\\bigwedge", "\\biguplus", "\\bigcap",
13 "\\bigcup", "\\intop", "\\prod", "\\sum", "\\bigotimes",
14 "\\bigoplus", "\\bigodot", "\\bigsqcup", "\\smallint",
15 "\u{220F}", "\u{2210}", "\u{2211}", "\u{22C0}", "\u{22C1}",
16 "\u{22C2}", "\u{22C3}", "\u{2A00}", "\u{2A01}", "\u{2A02}",
17 "\u{2A04}", "\u{2A06}",
18 ],
19 "op",
20 0, 0, None,
21 false, false, true, false, false,
22 handle_op_symbol_limits,
23 );
24
25 define_function_full(
27 map,
28 &[
29 "\\arcsin", "\\arccos", "\\arctan", "\\arctg", "\\arcctg",
30 "\\arg", "\\ch", "\\cos", "\\cosec", "\\cosh", "\\cot", "\\cotg",
31 "\\coth", "\\csc", "\\ctg", "\\cth", "\\deg", "\\dim", "\\exp",
32 "\\hom", "\\ker", "\\lg", "\\ln", "\\log", "\\sec", "\\sin",
33 "\\sinh", "\\sh", "\\tan", "\\tanh", "\\tg", "\\th",
34 ],
35 "op",
36 0, 0, None,
37 false, false, true, false, false,
38 handle_op_text_nolimits,
39 );
40
41 define_function_full(
43 map,
44 &[
45 "\\det", "\\gcd", "\\inf", "\\lim", "\\max", "\\min", "\\Pr", "\\sup",
46 ],
47 "op",
48 0, 0, None,
49 false, false, true, false, false,
50 handle_op_text_limits,
51 );
52
53 define_function_full(
55 map,
56 &[
57 "\\int", "\\iint", "\\iiint", "\\oint", "\\oiint", "\\oiiint",
58 ],
59 "op",
60 0, 0, None,
61 true, false, true, false, false,
63 handle_op_symbol_nolimits,
64 );
65
66 define_function_full(
68 map,
69 &["\\mathop"],
70 "op",
71 1, 0, None,
72 false, false, true, false,
73 true, handle_mathop,
75 );
76}
77
78fn single_char_big_op(c: &str) -> Option<&'static str> {
79 match c {
80 "\u{220F}" => Some("\\prod"),
81 "\u{2210}" => Some("\\coprod"),
82 "\u{2211}" => Some("\\sum"),
83 "\u{22C0}" => Some("\\bigwedge"),
84 "\u{22C1}" => Some("\\bigvee"),
85 "\u{22C2}" => Some("\\bigcap"),
86 "\u{22C3}" => Some("\\bigcup"),
87 "\u{2A00}" => Some("\\bigodot"),
88 "\u{2A01}" => Some("\\bigoplus"),
89 "\u{2A02}" => Some("\\bigotimes"),
90 "\u{2A04}" => Some("\\biguplus"),
91 "\u{2A06}" => Some("\\bigsqcup"),
92 _ => None,
93 }
94}
95
96fn handle_op_symbol_limits(
97 ctx: &mut FunctionContext,
98 _args: Vec<ParseNode>,
99 _opt_args: Vec<Option<ParseNode>>,
100) -> ParseResult<ParseNode> {
101 let name = single_char_big_op(&ctx.func_name)
102 .map(|s| s.to_string())
103 .unwrap_or_else(|| ctx.func_name.clone());
104 Ok(ParseNode::Op {
105 mode: ctx.parser.mode,
106 limits: true,
107 always_handle_sup_sub: None,
108 suppress_base_shift: None,
109 parent_is_sup_sub: false,
110 symbol: true,
111 name: Some(name),
112 body: None,
113 loc: None,
114 })
115}
116
117fn handle_op_text_nolimits(
118 ctx: &mut FunctionContext,
119 _args: Vec<ParseNode>,
120 _opt_args: Vec<Option<ParseNode>>,
121) -> ParseResult<ParseNode> {
122 Ok(ParseNode::Op {
123 mode: ctx.parser.mode,
124 limits: false,
125 always_handle_sup_sub: None,
126 suppress_base_shift: None,
127 parent_is_sup_sub: false,
128 symbol: false,
129 name: Some(ctx.func_name.clone()),
130 body: None,
131 loc: None,
132 })
133}
134
135fn handle_op_text_limits(
136 ctx: &mut FunctionContext,
137 _args: Vec<ParseNode>,
138 _opt_args: Vec<Option<ParseNode>>,
139) -> ParseResult<ParseNode> {
140 Ok(ParseNode::Op {
141 mode: ctx.parser.mode,
142 limits: true,
143 always_handle_sup_sub: None,
144 suppress_base_shift: None,
145 parent_is_sup_sub: false,
146 symbol: false,
147 name: Some(ctx.func_name.clone()),
148 body: None,
149 loc: None,
150 })
151}
152
153fn handle_op_symbol_nolimits(
154 ctx: &mut FunctionContext,
155 _args: Vec<ParseNode>,
156 _opt_args: Vec<Option<ParseNode>>,
157) -> ParseResult<ParseNode> {
158 Ok(ParseNode::Op {
159 mode: ctx.parser.mode,
160 limits: false,
161 always_handle_sup_sub: None,
162 suppress_base_shift: None,
163 parent_is_sup_sub: false,
164 symbol: true,
165 name: Some(ctx.func_name.clone()),
166 body: None,
167 loc: None,
168 })
169}
170
171fn handle_mathop(
172 ctx: &mut FunctionContext,
173 args: Vec<ParseNode>,
174 _opt_args: Vec<Option<ParseNode>>,
175) -> ParseResult<ParseNode> {
176 let body = ParseNode::ord_argument(args.into_iter().next().unwrap());
177 Ok(ParseNode::Op {
178 mode: ctx.parser.mode,
179 limits: false,
180 always_handle_sup_sub: None,
181 suppress_base_shift: None,
182 parent_is_sup_sub: false,
183 symbol: false,
184 name: None,
185 body: Some(body),
186 loc: None,
187 })
188}