Skip to main content

katex_parser/
symbol_registry.rs

1use std::collections::HashMap;
2use std::sync::OnceLock;
3
4use crate::ast::Mode;
5
6#[allow(clippy::enum_variant_names)]
7#[derive(Clone, Copy, PartialEq, Eq, Debug)]
8pub(crate) enum SymbolGroup {
9    AccentTokenGroup,
10    BinaryGroup,
11    CloseGroup,
12    InnerGroup,
13    MathOrdGroup,
14    OperatorTokenGroup,
15    OpenGroup,
16    PunctuationGroup,
17    RelationGroup,
18    SpacingGroup,
19    TextOrdGroup,
20}
21
22#[derive(Clone, Debug)]
23pub(crate) struct SymbolSpec {
24    pub(crate) group: SymbolGroup,
25    pub(crate) replacement: String,
26}
27
28pub(crate) struct SymbolRegistry {
29    pub(crate) math: HashMap<String, SymbolSpec>,
30    pub(crate) text: HashMap<String, SymbolSpec>,
31}
32
33impl SymbolRegistry {
34    fn new() -> Self {
35        SymbolRegistry {
36            math: HashMap::new(),
37            text: HashMap::new(),
38        }
39    }
40
41    fn define_symbol(
42        &mut self,
43        mode: Mode,
44        group: SymbolGroup,
45        replacement: &str,
46        name: &str,
47        accept_unicode: bool,
48    ) {
49        let table = if mode == Mode::Math { &mut self.math } else { &mut self.text };
50        let spec = SymbolSpec {
51            group,
52            replacement: replacement.to_string(),
53        };
54        table.insert(name.to_string(), spec.clone());
55        if accept_unicode && !replacement.is_empty() {
56            table.insert(replacement.to_string(), spec);
57        }
58    }
59}
60
61fn codepoint_string(codepoint: u32) -> String {
62    char::from_u32(codepoint).unwrap().to_string()
63}
64
65fn build_builtin_symbols() -> SymbolRegistry {
66    let mut registry = SymbolRegistry::new();
67    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2261}", "\\equiv", true);
68    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{227A}", "\\prec", true);
69    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{227B}", "\\succ", true);
70    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{223C}", "\\sim", true);
71    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{22A5}", "\\perp", false);
72    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2AAF}", "\\preceq", true);
73    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2AB0}", "\\succeq", true);
74    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2243}", "\\simeq", true);
75    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2223}", "\\mid", true);
76    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{226A}", "\\ll", true);
77    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{226B}", "\\gg", true);
78    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{224D}", "\\asymp", true);
79    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2225}", "\\parallel", false);
80    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{22C8}", "\\bowtie", true);
81    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2323}", "\\smile", true);
82    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2291}", "\\sqsubseteq", true);
83    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2292}", "\\sqsupseteq", true);
84    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2250}", "\\doteq", true);
85    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2322}", "\\frown", true);
86    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{220B}", "\\ni", true);
87    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{221D}", "\\propto", true);
88    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{22A2}", "\\vdash", true);
89    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{22A3}", "\\dashv", true);
90    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{220B}", "\\owns", false);
91    registry.define_symbol(Mode::Math, SymbolGroup::PunctuationGroup, ".", "\\ldotp", false);
92    registry.define_symbol(Mode::Math, SymbolGroup::PunctuationGroup, "\u{22C5}", "\\cdotp", false);
93    registry.define_symbol(Mode::Math, SymbolGroup::PunctuationGroup, "\u{22C5}", "\u{B7}", false);
94    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "\u{22C5}", "\u{B7}", false);
95    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "#", "\\#", false);
96    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "#", "\\#", false);
97    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "&", "\\&", false);
98    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "&", "\\&", false);
99    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{2135}", "\\aleph", true);
100    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{2200}", "\\forall", true);
101    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{210F}", "\\hbar", true);
102    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{2203}", "\\exists", true);
103    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{2207}", "\\nabla", true);
104    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{266D}", "\\flat", true);
105    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{2113}", "\\ell", true);
106    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{266E}", "\\natural", true);
107    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{2663}", "\\clubsuit", true);
108    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{2118}", "\\wp", true);
109    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{266F}", "\\sharp", true);
110    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{2662}", "\\diamondsuit", true);
111    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{211C}", "\\Re", true);
112    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{2661}", "\\heartsuit", true);
113    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{2111}", "\\Im", true);
114    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{2660}", "\\spadesuit", true);
115    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{A7}", "\\S", true);
116    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "\u{A7}", "\\S", false);
117    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{B6}", "\\P", true);
118    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "\u{B6}", "\\P", false);
119    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{2020}", "\\dag", false);
120    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "\u{2020}", "\\dag", false);
121    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "\u{2020}", "\\textdagger", false);
122    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{2021}", "\\ddag", false);
123    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "\u{2021}", "\\ddag", false);
124    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "\u{2021}", "\\textdaggerdbl", false);
125    registry.define_symbol(Mode::Math, SymbolGroup::CloseGroup, "\u{23B1}", "\\rmoustache", true);
126    registry.define_symbol(Mode::Math, SymbolGroup::OpenGroup, "\u{23B0}", "\\lmoustache", true);
127    registry.define_symbol(Mode::Math, SymbolGroup::CloseGroup, "\u{27EF}", "\\rgroup", true);
128    registry.define_symbol(Mode::Math, SymbolGroup::OpenGroup, "\u{27EE}", "\\lgroup", true);
129    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{2213}", "\\mp", true);
130    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{2296}", "\\ominus", true);
131    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{228E}", "\\uplus", true);
132    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{2293}", "\\sqcap", true);
133    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{2217}", "\\ast", false);
134    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{2294}", "\\sqcup", true);
135    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{25EF}", "\\bigcirc", true);
136    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{2219}", "\\bullet", true);
137    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{2021}", "\\ddagger", false);
138    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{2240}", "\\wr", true);
139    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{2A3F}", "\\amalg", false);
140    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "&", "\\And", false);
141    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{27F5}", "\\longleftarrow", true);
142    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21D0}", "\\Leftarrow", true);
143    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{27F8}", "\\Longleftarrow", true);
144    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{27F6}", "\\longrightarrow", true);
145    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21D2}", "\\Rightarrow", true);
146    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{27F9}", "\\Longrightarrow", true);
147    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2194}", "\\leftrightarrow", true);
148    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{27F7}", "\\longleftrightarrow", true);
149    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21D4}", "\\Leftrightarrow", true);
150    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{27FA}", "\\Longleftrightarrow", true);
151    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21A6}", "\\mapsto", true);
152    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{27FC}", "\\longmapsto", true);
153    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2197}", "\\nearrow", true);
154    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21A9}", "\\hookleftarrow", true);
155    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21AA}", "\\hookrightarrow", true);
156    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2198}", "\\searrow", true);
157    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21BC}", "\\leftharpoonup", true);
158    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21C0}", "\\rightharpoonup", true);
159    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2199}", "\\swarrow", true);
160    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21BD}", "\\leftharpoondown", true);
161    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21C1}", "\\rightharpoondown", true);
162    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2196}", "\\nwarrow", true);
163    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21CC}", "\\rightleftharpoons", true);
164    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{226E}", "\\nless", true);
165    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{E010}", "\\@nleqslant", false);
166    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{E011}", "\\@nleqq", false);
167    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2A87}", "\\lneq", true);
168    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2268}", "\\lneqq", true);
169    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{E00C}", "\\@lvertneqq", false);
170    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{22E6}", "\\lnsim", true);
171    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2A89}", "\\lnapprox", true);
172    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2280}", "\\nprec", true);
173    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{22E0}", "\\npreceq", true);
174    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{22E8}", "\\precnsim", true);
175    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2AB9}", "\\precnapprox", true);
176    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2241}", "\\nsim", true);
177    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{E006}", "\\@nshortmid", false);
178    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2224}", "\\nmid", true);
179    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{22AC}", "\\nvdash", true);
180    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{22AD}", "\\nvDash", true);
181    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{22EA}", "\\ntriangleleft", false);
182    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{22EC}", "\\ntrianglelefteq", true);
183    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{228A}", "\\subsetneq", true);
184    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{E01A}", "\\@varsubsetneq", false);
185    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2ACB}", "\\subsetneqq", true);
186    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{E017}", "\\@varsubsetneqq", false);
187    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{226F}", "\\ngtr", true);
188    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{E00F}", "\\@ngeqslant", false);
189    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{E00E}", "\\@ngeqq", false);
190    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2A88}", "\\gneq", true);
191    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2269}", "\\gneqq", true);
192    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{E00D}", "\\@gvertneqq", false);
193    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{22E7}", "\\gnsim", true);
194    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2A8A}", "\\gnapprox", true);
195    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2281}", "\\nsucc", true);
196    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{22E1}", "\\nsucceq", true);
197    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{22E9}", "\\succnsim", true);
198    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2ABA}", "\\succnapprox", true);
199    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2246}", "\\ncong", true);
200    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{E007}", "\\@nshortparallel", false);
201    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2226}", "\\nparallel", true);
202    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{22AF}", "\\nVDash", true);
203    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{22EB}", "\\ntriangleright", false);
204    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{22ED}", "\\ntrianglerighteq", true);
205    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{E018}", "\\@nsupseteqq", false);
206    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{228B}", "\\supsetneq", true);
207    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{E01B}", "\\@varsupsetneq", false);
208    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2ACC}", "\\supsetneqq", true);
209    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{E019}", "\\@varsupsetneqq", false);
210    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{22AE}", "\\nVdash", true);
211    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2AB5}", "\\precneqq", true);
212    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2AB6}", "\\succneqq", true);
213    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{E016}", "\\@nsubseteqq", false);
214    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{22B4}", "\\unlhd", false);
215    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{22B5}", "\\unrhd", false);
216    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{219A}", "\\nleftarrow", true);
217    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{219B}", "\\nrightarrow", true);
218    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21CD}", "\\nLeftarrow", true);
219    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21CF}", "\\nRightarrow", true);
220    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21AE}", "\\nleftrightarrow", true);
221    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21CE}", "\\nLeftrightarrow", true);
222    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{25B3}", "\\vartriangle", false);
223    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{210F}", "\\hslash", false);
224    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{25BD}", "\\triangledown", false);
225    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{25CA}", "\\lozenge", false);
226    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{24C8}", "\\circledS", false);
227    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{AE}", "\\circledR", false);
228    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "\u{AE}", "\\circledR", false);
229    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{2221}", "\\measuredangle", true);
230    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{2204}", "\\nexists", false);
231    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{2127}", "\\mho", false);
232    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{2132}", "\\Finv", true);
233    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{2141}", "\\Game", true);
234    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{2035}", "\\backprime", false);
235    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{25B2}", "\\blacktriangle", false);
236    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{25BC}", "\\blacktriangledown", false);
237    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{25A0}", "\\blacksquare", false);
238    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{29EB}", "\\blacklozenge", false);
239    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{2605}", "\\bigstar", false);
240    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{2222}", "\\sphericalangle", true);
241    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{2201}", "\\complement", true);
242    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "\u{F0}", "\u{F0}", false);
243    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{2571}", "\\diagup", false);
244    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{2572}", "\\diagdown", false);
245    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{25A1}", "\\square", false);
246    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{25A1}", "\\Box", false);
247    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{25CA}", "\\Diamond", false);
248    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "\u{A5}", "\\yen", true);
249    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{2713}", "\\checkmark", true);
250    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "\u{2713}", "\\checkmark", false);
251    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{2136}", "\\beth", true);
252    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{2138}", "\\daleth", true);
253    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{2137}", "\\gimel", true);
254    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{3DD}", "\\digamma", true);
255    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{3F0}", "\\varkappa", false);
256    registry.define_symbol(Mode::Math, SymbolGroup::OpenGroup, "\u{250C}", "\\@ulcorner", true);
257    registry.define_symbol(Mode::Math, SymbolGroup::CloseGroup, "\u{2510}", "\\@urcorner", true);
258    registry.define_symbol(Mode::Math, SymbolGroup::OpenGroup, "\u{2514}", "\\@llcorner", true);
259    registry.define_symbol(Mode::Math, SymbolGroup::CloseGroup, "\u{2518}", "\\@lrcorner", true);
260    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2266}", "\\leqq", true);
261    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2A7D}", "\\leqslant", true);
262    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2A95}", "\\eqslantless", true);
263    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2272}", "\\lesssim", true);
264    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2A85}", "\\lessapprox", true);
265    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{224A}", "\\approxeq", true);
266    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{22D6}", "\\lessdot", false);
267    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{22D8}", "\\lll", true);
268    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2276}", "\\lessgtr", true);
269    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{22DA}", "\\lesseqgtr", true);
270    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2A8B}", "\\lesseqqgtr", true);
271    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2251}", "\\doteqdot", false);
272    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2253}", "\\risingdotseq", true);
273    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2252}", "\\fallingdotseq", true);
274    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{223D}", "\\backsim", true);
275    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{22CD}", "\\backsimeq", true);
276    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2AC5}", "\\subseteqq", true);
277    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{22D0}", "\\Subset", true);
278    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{228F}", "\\sqsubset", true);
279    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{227C}", "\\preccurlyeq", true);
280    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{22DE}", "\\curlyeqprec", true);
281    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{227E}", "\\precsim", true);
282    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2AB7}", "\\precapprox", true);
283    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{22B2}", "\\vartriangleleft", false);
284    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{22B4}", "\\trianglelefteq", false);
285    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{22A8}", "\\vDash", true);
286    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{22AA}", "\\Vvdash", true);
287    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2323}", "\\smallsmile", false);
288    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2322}", "\\smallfrown", false);
289    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{224F}", "\\bumpeq", true);
290    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{224E}", "\\Bumpeq", true);
291    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2267}", "\\geqq", true);
292    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2A7E}", "\\geqslant", true);
293    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2A96}", "\\eqslantgtr", true);
294    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2273}", "\\gtrsim", true);
295    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2A86}", "\\gtrapprox", true);
296    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{22D7}", "\\gtrdot", false);
297    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{22D9}", "\\ggg", true);
298    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2277}", "\\gtrless", true);
299    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{22DB}", "\\gtreqless", true);
300    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2A8C}", "\\gtreqqless", true);
301    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2256}", "\\eqcirc", true);
302    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2257}", "\\circeq", true);
303    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{225C}", "\\triangleq", true);
304    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{223C}", "\\thicksim", false);
305    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2248}", "\\thickapprox", false);
306    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2AC6}", "\\supseteqq", true);
307    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{22D1}", "\\Supset", true);
308    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2290}", "\\sqsupset", true);
309    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{227D}", "\\succcurlyeq", true);
310    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{22DF}", "\\curlyeqsucc", true);
311    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{227F}", "\\succsim", true);
312    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2AB8}", "\\succapprox", true);
313    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{22B3}", "\\vartriangleright", false);
314    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{22B5}", "\\trianglerighteq", false);
315    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{22A9}", "\\Vdash", true);
316    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2223}", "\\shortmid", false);
317    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2225}", "\\shortparallel", false);
318    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{226C}", "\\between", true);
319    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{22D4}", "\\pitchfork", true);
320    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{221D}", "\\varpropto", false);
321    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{25C0}", "\\blacktriangleleft", false);
322    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2234}", "\\therefore", true);
323    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{220D}", "\\backepsilon", false);
324    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{25B6}", "\\blacktriangleright", false);
325    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2235}", "\\because", true);
326    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{22D8}", "\\llless", false);
327    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{22D9}", "\\gggtr", false);
328    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{22B2}", "\\lhd", false);
329    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{22B3}", "\\rhd", false);
330    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2242}", "\\eqsim", true);
331    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{22C8}", "\\Join", false);
332    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2251}", "\\Doteq", true);
333    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{2214}", "\\dotplus", true);
334    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{2216}", "\\smallsetminus", false);
335    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{22D2}", "\\Cap", true);
336    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{22D3}", "\\Cup", true);
337    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{2A5E}", "\\doublebarwedge", true);
338    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{229F}", "\\boxminus", true);
339    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{229E}", "\\boxplus", true);
340    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{22C7}", "\\divideontimes", true);
341    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{22C9}", "\\ltimes", true);
342    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{22CA}", "\\rtimes", true);
343    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{22CB}", "\\leftthreetimes", true);
344    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{22CC}", "\\rightthreetimes", true);
345    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{22CF}", "\\curlywedge", true);
346    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{22CE}", "\\curlyvee", true);
347    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{229D}", "\\circleddash", true);
348    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{229B}", "\\circledast", true);
349    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{22C5}", "\\centerdot", false);
350    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{22BA}", "\\intercal", true);
351    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{22D2}", "\\doublecap", false);
352    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{22D3}", "\\doublecup", false);
353    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{22A0}", "\\boxtimes", true);
354    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21E2}", "\\dashrightarrow", true);
355    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21E0}", "\\dashleftarrow", true);
356    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21C7}", "\\leftleftarrows", true);
357    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21C6}", "\\leftrightarrows", true);
358    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21DA}", "\\Lleftarrow", true);
359    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{219E}", "\\twoheadleftarrow", true);
360    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21A2}", "\\leftarrowtail", true);
361    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21AB}", "\\looparrowleft", true);
362    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21CB}", "\\leftrightharpoons", true);
363    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21B6}", "\\curvearrowleft", true);
364    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21BA}", "\\circlearrowleft", true);
365    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21B0}", "\\Lsh", true);
366    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21C8}", "\\upuparrows", true);
367    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21BF}", "\\upharpoonleft", true);
368    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21C3}", "\\downharpoonleft", true);
369    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{22B6}", "\\origof", true);
370    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{22B7}", "\\imageof", true);
371    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{22B8}", "\\multimap", true);
372    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21AD}", "\\leftrightsquigarrow", true);
373    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21C9}", "\\rightrightarrows", true);
374    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21C4}", "\\rightleftarrows", true);
375    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21A0}", "\\twoheadrightarrow", true);
376    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21A3}", "\\rightarrowtail", true);
377    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21AC}", "\\looparrowright", true);
378    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21B7}", "\\curvearrowright", true);
379    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21BB}", "\\circlearrowright", true);
380    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21B1}", "\\Rsh", true);
381    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21CA}", "\\downdownarrows", true);
382    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21BE}", "\\upharpoonright", true);
383    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21C2}", "\\downharpoonright", true);
384    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21DD}", "\\rightsquigarrow", true);
385    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21DD}", "\\leadsto", false);
386    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21DB}", "\\Rrightarrow", true);
387    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21BE}", "\\restriction", false);
388    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{2018}", "`", false);
389    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "$", "\\$", false);
390    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "$", "\\$", false);
391    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "$", "\\textdollar", false);
392    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "%", "\\%", false);
393    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "%", "\\%", false);
394    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "_", "\\_", false);
395    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "_", "\\_", false);
396    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "_", "\\textunderscore", false);
397    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{2220}", "\\angle", true);
398    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{221E}", "\\infty", true);
399    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{2032}", "\\prime", false);
400    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{25B3}", "\\triangle", false);
401    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{393}", "\\Gamma", true);
402    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{394}", "\\Delta", true);
403    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{398}", "\\Theta", true);
404    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{39B}", "\\Lambda", true);
405    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{39E}", "\\Xi", true);
406    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{3A0}", "\\Pi", true);
407    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{3A3}", "\\Sigma", true);
408    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{3A5}", "\\Upsilon", true);
409    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{3A6}", "\\Phi", true);
410    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{3A8}", "\\Psi", true);
411    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{3A9}", "\\Omega", true);
412    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "A", "\u{391}", false);
413    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "B", "\u{392}", false);
414    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "E", "\u{395}", false);
415    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "Z", "\u{396}", false);
416    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "H", "\u{397}", false);
417    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "I", "\u{399}", false);
418    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "K", "\u{39A}", false);
419    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "M", "\u{39C}", false);
420    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "N", "\u{39D}", false);
421    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "O", "\u{39F}", false);
422    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "P", "\u{3A1}", false);
423    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "T", "\u{3A4}", false);
424    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "X", "\u{3A7}", false);
425    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{AC}", "\\neg", true);
426    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{AC}", "\\lnot", false);
427    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{22A4}", "\\top", false);
428    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{22A5}", "\\bot", false);
429    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{2205}", "\\emptyset", false);
430    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{2205}", "\\varnothing", false);
431    registry.define_symbol(Mode::Math, SymbolGroup::MathOrdGroup, "\u{3B1}", "\\alpha", true);
432    registry.define_symbol(Mode::Math, SymbolGroup::MathOrdGroup, "\u{3B2}", "\\beta", true);
433    registry.define_symbol(Mode::Math, SymbolGroup::MathOrdGroup, "\u{3B3}", "\\gamma", true);
434    registry.define_symbol(Mode::Math, SymbolGroup::MathOrdGroup, "\u{3B4}", "\\delta", true);
435    registry.define_symbol(Mode::Math, SymbolGroup::MathOrdGroup, "\u{3F5}", "\\epsilon", true);
436    registry.define_symbol(Mode::Math, SymbolGroup::MathOrdGroup, "\u{3B6}", "\\zeta", true);
437    registry.define_symbol(Mode::Math, SymbolGroup::MathOrdGroup, "\u{3B7}", "\\eta", true);
438    registry.define_symbol(Mode::Math, SymbolGroup::MathOrdGroup, "\u{3B8}", "\\theta", true);
439    registry.define_symbol(Mode::Math, SymbolGroup::MathOrdGroup, "\u{3B9}", "\\iota", true);
440    registry.define_symbol(Mode::Math, SymbolGroup::MathOrdGroup, "\u{3BA}", "\\kappa", true);
441    registry.define_symbol(Mode::Math, SymbolGroup::MathOrdGroup, "\u{3BB}", "\\lambda", true);
442    registry.define_symbol(Mode::Math, SymbolGroup::MathOrdGroup, "\u{3BC}", "\\mu", true);
443    registry.define_symbol(Mode::Math, SymbolGroup::MathOrdGroup, "\u{3BD}", "\\nu", true);
444    registry.define_symbol(Mode::Math, SymbolGroup::MathOrdGroup, "\u{3BE}", "\\xi", true);
445    registry.define_symbol(Mode::Math, SymbolGroup::MathOrdGroup, "\u{3BF}", "\\omicron", true);
446    registry.define_symbol(Mode::Math, SymbolGroup::MathOrdGroup, "\u{3C0}", "\\pi", true);
447    registry.define_symbol(Mode::Math, SymbolGroup::MathOrdGroup, "\u{3C1}", "\\rho", true);
448    registry.define_symbol(Mode::Math, SymbolGroup::MathOrdGroup, "\u{3C3}", "\\sigma", true);
449    registry.define_symbol(Mode::Math, SymbolGroup::MathOrdGroup, "\u{3C4}", "\\tau", true);
450    registry.define_symbol(Mode::Math, SymbolGroup::MathOrdGroup, "\u{3C5}", "\\upsilon", true);
451    registry.define_symbol(Mode::Math, SymbolGroup::MathOrdGroup, "\u{3D5}", "\\phi", true);
452    registry.define_symbol(Mode::Math, SymbolGroup::MathOrdGroup, "\u{3C7}", "\\chi", true);
453    registry.define_symbol(Mode::Math, SymbolGroup::MathOrdGroup, "\u{3C8}", "\\psi", true);
454    registry.define_symbol(Mode::Math, SymbolGroup::MathOrdGroup, "\u{3C9}", "\\omega", true);
455    registry.define_symbol(Mode::Math, SymbolGroup::MathOrdGroup, "\u{3B5}", "\\varepsilon", true);
456    registry.define_symbol(Mode::Math, SymbolGroup::MathOrdGroup, "\u{3D1}", "\\vartheta", true);
457    registry.define_symbol(Mode::Math, SymbolGroup::MathOrdGroup, "\u{3D6}", "\\varpi", true);
458    registry.define_symbol(Mode::Math, SymbolGroup::MathOrdGroup, "\u{3F1}", "\\varrho", true);
459    registry.define_symbol(Mode::Math, SymbolGroup::MathOrdGroup, "\u{3C2}", "\\varsigma", true);
460    registry.define_symbol(Mode::Math, SymbolGroup::MathOrdGroup, "\u{3C6}", "\\varphi", true);
461    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{2217}", "*", true);
462    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "+", "+", false);
463    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{2212}", "-", true);
464    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{22C5}", "\\cdot", true);
465    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{2218}", "\\circ", true);
466    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{F7}", "\\div", true);
467    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{B1}", "\\pm", true);
468    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{D7}", "\\times", true);
469    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{2229}", "\\cap", true);
470    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{222A}", "\\cup", true);
471    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{2216}", "\\setminus", true);
472    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{2227}", "\\land", false);
473    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{2228}", "\\lor", false);
474    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{2227}", "\\wedge", true);
475    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{2228}", "\\vee", true);
476    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{221A}", "\\surd", false);
477    registry.define_symbol(Mode::Math, SymbolGroup::OpenGroup, "\u{27E8}", "\\langle", true);
478    registry.define_symbol(Mode::Math, SymbolGroup::OpenGroup, "\u{2223}", "\\lvert", false);
479    registry.define_symbol(Mode::Math, SymbolGroup::OpenGroup, "\u{2016}", "\\lVert", false);
480    registry.define_symbol(Mode::Math, SymbolGroup::CloseGroup, "?", "?", false);
481    registry.define_symbol(Mode::Math, SymbolGroup::CloseGroup, "!", "!", false);
482    registry.define_symbol(Mode::Math, SymbolGroup::CloseGroup, "\u{27E9}", "\\rangle", true);
483    registry.define_symbol(Mode::Math, SymbolGroup::CloseGroup, "\u{2223}", "\\rvert", false);
484    registry.define_symbol(Mode::Math, SymbolGroup::CloseGroup, "\u{2016}", "\\rVert", false);
485    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "=", "=", false);
486    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, ":", ":", false);
487    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2248}", "\\approx", true);
488    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2245}", "\\cong", true);
489    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2265}", "\\ge", false);
490    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2265}", "\\geq", true);
491    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2190}", "\\gets", false);
492    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, ">", "\\gt", true);
493    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2208}", "\\in", true);
494    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{E020}", "\\@not", false);
495    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2282}", "\\subset", true);
496    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2283}", "\\supset", true);
497    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2286}", "\\subseteq", true);
498    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2287}", "\\supseteq", true);
499    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2288}", "\\nsubseteq", true);
500    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2289}", "\\nsupseteq", true);
501    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{22A8}", "\\models", false);
502    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2190}", "\\leftarrow", true);
503    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2264}", "\\le", false);
504    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2264}", "\\leq", true);
505    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "<", "\\lt", true);
506    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2192}", "\\rightarrow", true);
507    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2192}", "\\to", false);
508    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2271}", "\\ngeq", true);
509    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2270}", "\\nleq", true);
510    registry.define_symbol(Mode::Math, SymbolGroup::SpacingGroup, "\u{A0}", "\\ ", false);
511    registry.define_symbol(Mode::Math, SymbolGroup::SpacingGroup, "\u{A0}", "\\space", false);
512    registry.define_symbol(Mode::Math, SymbolGroup::SpacingGroup, "\u{A0}", "\\nobreakspace", false);
513    registry.define_symbol(Mode::Text, SymbolGroup::SpacingGroup, "\u{A0}", "\\ ", false);
514    registry.define_symbol(Mode::Text, SymbolGroup::SpacingGroup, "\u{A0}", " ", false);
515    registry.define_symbol(Mode::Text, SymbolGroup::SpacingGroup, "\u{A0}", "\\space", false);
516    registry.define_symbol(Mode::Text, SymbolGroup::SpacingGroup, "\u{A0}", "\\nobreakspace", false);
517    registry.define_symbol(Mode::Math, SymbolGroup::SpacingGroup, "", "\\nobreak", false);
518    registry.define_symbol(Mode::Math, SymbolGroup::SpacingGroup, "", "\\allowbreak", false);
519    registry.define_symbol(Mode::Math, SymbolGroup::PunctuationGroup, ",", ",", false);
520    registry.define_symbol(Mode::Math, SymbolGroup::PunctuationGroup, ";", ";", false);
521    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{22BC}", "\\barwedge", true);
522    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{22BB}", "\\veebar", true);
523    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{2299}", "\\odot", true);
524    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{2295}", "\\oplus", true);
525    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{2297}", "\\otimes", true);
526    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{2202}", "\\partial", true);
527    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{2298}", "\\oslash", true);
528    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{229A}", "\\circledcirc", true);
529    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{22A1}", "\\boxdot", true);
530    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{25B3}", "\\bigtriangleup", false);
531    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{25BD}", "\\bigtriangledown", false);
532    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{2020}", "\\dagger", false);
533    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{22C4}", "\\diamond", false);
534    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{22C6}", "\\star", false);
535    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{25C3}", "\\triangleleft", false);
536    registry.define_symbol(Mode::Math, SymbolGroup::BinaryGroup, "\u{25B9}", "\\triangleright", false);
537    registry.define_symbol(Mode::Math, SymbolGroup::OpenGroup, "{", "\\{", false);
538    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "{", "\\{", false);
539    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "{", "\\textbraceleft", false);
540    registry.define_symbol(Mode::Math, SymbolGroup::CloseGroup, "}", "\\}", false);
541    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "}", "\\}", false);
542    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "}", "\\textbraceright", false);
543    registry.define_symbol(Mode::Math, SymbolGroup::OpenGroup, "{", "\\lbrace", false);
544    registry.define_symbol(Mode::Math, SymbolGroup::CloseGroup, "}", "\\rbrace", false);
545    registry.define_symbol(Mode::Math, SymbolGroup::OpenGroup, "[", "\\lbrack", true);
546    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "[", "\\lbrack", true);
547    registry.define_symbol(Mode::Math, SymbolGroup::CloseGroup, "]", "\\rbrack", true);
548    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "]", "\\rbrack", true);
549    registry.define_symbol(Mode::Math, SymbolGroup::OpenGroup, "(", "\\lparen", true);
550    registry.define_symbol(Mode::Math, SymbolGroup::CloseGroup, ")", "\\rparen", true);
551    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "<", "\\textless", true);
552    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, ">", "\\textgreater", true);
553    registry.define_symbol(Mode::Math, SymbolGroup::OpenGroup, "\u{230A}", "\\lfloor", true);
554    registry.define_symbol(Mode::Math, SymbolGroup::CloseGroup, "\u{230B}", "\\rfloor", true);
555    registry.define_symbol(Mode::Math, SymbolGroup::OpenGroup, "\u{2308}", "\\lceil", true);
556    registry.define_symbol(Mode::Math, SymbolGroup::CloseGroup, "\u{2309}", "\\rceil", true);
557    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\\", "\\backslash", false);
558    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{2223}", "|", false);
559    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{2223}", "\\vert", false);
560    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "|", "\\textbar", true);
561    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{2016}", "\\|", false);
562    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{2016}", "\\Vert", false);
563    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "\u{2016}", "\\textbardbl", false);
564    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "~", "\\textasciitilde", false);
565    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "\\", "\\textbackslash", false);
566    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "^", "\\textasciicircum", false);
567    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2191}", "\\uparrow", true);
568    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21D1}", "\\Uparrow", true);
569    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2193}", "\\downarrow", true);
570    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21D3}", "\\Downarrow", true);
571    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{2195}", "\\updownarrow", true);
572    registry.define_symbol(Mode::Math, SymbolGroup::RelationGroup, "\u{21D5}", "\\Updownarrow", true);
573    registry.define_symbol(Mode::Math, SymbolGroup::OperatorTokenGroup, "\u{2210}", "\\coprod", false);
574    registry.define_symbol(Mode::Math, SymbolGroup::OperatorTokenGroup, "\u{22C1}", "\\bigvee", false);
575    registry.define_symbol(Mode::Math, SymbolGroup::OperatorTokenGroup, "\u{22C0}", "\\bigwedge", false);
576    registry.define_symbol(Mode::Math, SymbolGroup::OperatorTokenGroup, "\u{2A04}", "\\biguplus", false);
577    registry.define_symbol(Mode::Math, SymbolGroup::OperatorTokenGroup, "\u{22C2}", "\\bigcap", false);
578    registry.define_symbol(Mode::Math, SymbolGroup::OperatorTokenGroup, "\u{22C3}", "\\bigcup", false);
579    registry.define_symbol(Mode::Math, SymbolGroup::OperatorTokenGroup, "\u{222B}", "\\int", false);
580    registry.define_symbol(Mode::Math, SymbolGroup::OperatorTokenGroup, "\u{222B}", "\\intop", false);
581    registry.define_symbol(Mode::Math, SymbolGroup::OperatorTokenGroup, "\u{222C}", "\\iint", false);
582    registry.define_symbol(Mode::Math, SymbolGroup::OperatorTokenGroup, "\u{222D}", "\\iiint", false);
583    registry.define_symbol(Mode::Math, SymbolGroup::OperatorTokenGroup, "\u{220F}", "\\prod", false);
584    registry.define_symbol(Mode::Math, SymbolGroup::OperatorTokenGroup, "\u{2211}", "\\sum", false);
585    registry.define_symbol(Mode::Math, SymbolGroup::OperatorTokenGroup, "\u{2A02}", "\\bigotimes", false);
586    registry.define_symbol(Mode::Math, SymbolGroup::OperatorTokenGroup, "\u{2A01}", "\\bigoplus", false);
587    registry.define_symbol(Mode::Math, SymbolGroup::OperatorTokenGroup, "\u{2A00}", "\\bigodot", false);
588    registry.define_symbol(Mode::Math, SymbolGroup::OperatorTokenGroup, "\u{222E}", "\\oint", false);
589    registry.define_symbol(Mode::Math, SymbolGroup::OperatorTokenGroup, "\u{222F}", "\\oiint", false);
590    registry.define_symbol(Mode::Math, SymbolGroup::OperatorTokenGroup, "\u{2230}", "\\oiiint", false);
591    registry.define_symbol(Mode::Math, SymbolGroup::OperatorTokenGroup, "\u{2A06}", "\\bigsqcup", false);
592    registry.define_symbol(Mode::Math, SymbolGroup::OperatorTokenGroup, "\u{222B}", "\\smallint", false);
593    registry.define_symbol(Mode::Text, SymbolGroup::InnerGroup, "\u{2026}", "\\textellipsis", false);
594    registry.define_symbol(Mode::Math, SymbolGroup::InnerGroup, "\u{2026}", "\\mathellipsis", false);
595    registry.define_symbol(Mode::Text, SymbolGroup::InnerGroup, "\u{2026}", "\\ldots", true);
596    registry.define_symbol(Mode::Math, SymbolGroup::InnerGroup, "\u{2026}", "\\ldots", true);
597    registry.define_symbol(Mode::Math, SymbolGroup::InnerGroup, "\u{22EF}", "\\@cdots", true);
598    registry.define_symbol(Mode::Math, SymbolGroup::InnerGroup, "\u{22F1}", "\\ddots", true);
599    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{22EE}", "\\varvdots", false);
600    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "\u{22EE}", "\\varvdots", false);
601    registry.define_symbol(Mode::Math, SymbolGroup::AccentTokenGroup, "\u{2CA}", "\\acute", false);
602    registry.define_symbol(Mode::Math, SymbolGroup::AccentTokenGroup, "\u{2CB}", "\\grave", false);
603    registry.define_symbol(Mode::Math, SymbolGroup::AccentTokenGroup, "\u{A8}", "\\ddot", false);
604    registry.define_symbol(Mode::Math, SymbolGroup::AccentTokenGroup, "~", "\\tilde", false);
605    registry.define_symbol(Mode::Math, SymbolGroup::AccentTokenGroup, "\u{2C9}", "\\bar", false);
606    registry.define_symbol(Mode::Math, SymbolGroup::AccentTokenGroup, "\u{2D8}", "\\breve", false);
607    registry.define_symbol(Mode::Math, SymbolGroup::AccentTokenGroup, "\u{2C7}", "\\check", false);
608    registry.define_symbol(Mode::Math, SymbolGroup::AccentTokenGroup, "^", "\\hat", false);
609    registry.define_symbol(Mode::Math, SymbolGroup::AccentTokenGroup, "\u{20D7}", "\\vec", false);
610    registry.define_symbol(Mode::Math, SymbolGroup::AccentTokenGroup, "\u{2D9}", "\\dot", false);
611    registry.define_symbol(Mode::Math, SymbolGroup::AccentTokenGroup, "\u{2DA}", "\\mathring", false);
612    registry.define_symbol(Mode::Math, SymbolGroup::MathOrdGroup, "\u{E131}", "\\@imath", false);
613    registry.define_symbol(Mode::Math, SymbolGroup::MathOrdGroup, "\u{E237}", "\\@jmath", false);
614    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{131}", "\u{131}", false);
615    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{237}", "\u{237}", false);
616    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "\u{131}", "\\i", true);
617    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "\u{237}", "\\j", true);
618    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "\u{DF}", "\\ss", true);
619    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "\u{E6}", "\\ae", true);
620    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "\u{153}", "\\oe", true);
621    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "\u{F8}", "\\o", true);
622    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "\u{C6}", "\\AE", true);
623    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "\u{152}", "\\OE", true);
624    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "\u{D8}", "\\O", true);
625    registry.define_symbol(Mode::Text, SymbolGroup::AccentTokenGroup, "\u{2CA}", "\\'", false);
626    registry.define_symbol(Mode::Text, SymbolGroup::AccentTokenGroup, "\u{2CB}", "\\`", false);
627    registry.define_symbol(Mode::Text, SymbolGroup::AccentTokenGroup, "\u{2C6}", "\\^", false);
628    registry.define_symbol(Mode::Text, SymbolGroup::AccentTokenGroup, "\u{2DC}", "\\~", false);
629    registry.define_symbol(Mode::Text, SymbolGroup::AccentTokenGroup, "\u{2C9}", "\\=", false);
630    registry.define_symbol(Mode::Text, SymbolGroup::AccentTokenGroup, "\u{2D8}", "\\u", false);
631    registry.define_symbol(Mode::Text, SymbolGroup::AccentTokenGroup, "\u{2D9}", "\\.", false);
632    registry.define_symbol(Mode::Text, SymbolGroup::AccentTokenGroup, "\u{B8}", "\\c", false);
633    registry.define_symbol(Mode::Text, SymbolGroup::AccentTokenGroup, "\u{2DA}", "\\r", false);
634    registry.define_symbol(Mode::Text, SymbolGroup::AccentTokenGroup, "\u{2C7}", "\\v", false);
635    registry.define_symbol(Mode::Text, SymbolGroup::AccentTokenGroup, "\u{A8}", "\\\"", false);
636    registry.define_symbol(Mode::Text, SymbolGroup::AccentTokenGroup, "\u{2DD}", "\\H", false);
637    registry.define_symbol(Mode::Text, SymbolGroup::AccentTokenGroup, "\u{25EF}", "\\textcircled", false);
638    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "\u{2013}", "--", true);
639    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "\u{2013}", "\\textendash", false);
640    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "\u{2014}", "---", true);
641    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "\u{2014}", "\\textemdash", false);
642    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "\u{2018}", "`", true);
643    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "\u{2018}", "\\textquoteleft", false);
644    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "\u{2019}", "'", true);
645    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "\u{2019}", "\\textquoteright", false);
646    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "\u{201C}", "``", true);
647    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "\u{201C}", "\\textquotedblleft", false);
648    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "\u{201D}", "''", true);
649    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "\u{201D}", "\\textquotedblright", false);
650    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{B0}", "\\degree", true);
651    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "\u{B0}", "\\degree", false);
652    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "\u{B0}", "\\textdegree", true);
653    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{A3}", "\\pounds", false);
654    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{A3}", "\\mathsterling", true);
655    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "\u{A3}", "\\pounds", false);
656    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "\u{A3}", "\\textsterling", true);
657    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{2720}", "\\maltese", false);
658    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "\u{2720}", "\\maltese", false);
659    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "C", "\u{2102}", false);
660    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "C", "\u{2102}", false);
661    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "H", "\u{210D}", false);
662    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "H", "\u{210D}", false);
663    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "N", "\u{2115}", false);
664    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "N", "\u{2115}", false);
665    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "P", "\u{2119}", false);
666    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "P", "\u{2119}", false);
667    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "Q", "\u{211A}", false);
668    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "Q", "\u{211A}", false);
669    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "R", "\u{211D}", false);
670    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "R", "\u{211D}", false);
671    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "Z", "\u{2124}", false);
672    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "Z", "\u{2124}", false);
673    registry.define_symbol(Mode::Math, SymbolGroup::MathOrdGroup, "h", "\u{210E}", false);
674    registry.define_symbol(Mode::Text, SymbolGroup::MathOrdGroup, "h", "\u{210E}", false);
675    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{F0}", "\\eth", true);
676    registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, "\u{A5}", "\\yen", true);
677    for ch in "0123456789/@.\"".chars() {
678        let text = ch.to_string();
679        registry.define_symbol(Mode::Math, SymbolGroup::TextOrdGroup, &text, &text, false);
680    }
681    for ch in "0123456789!@*()-=+\";:?/.,".chars() {
682        let text = ch.to_string();
683        registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, &text, &text, false);
684    }
685    let letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
686    for (index, ch) in letters.chars().enumerate() {
687        let text = ch.to_string();
688        registry.define_symbol(Mode::Math, SymbolGroup::MathOrdGroup, &text, &text, false);
689        registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, &text, &text, false);
690        for start in [
691            0x1D400, 0x1D434, 0x1D468, 0x1D504, 0x1D56C, 0x1D5A0, 0x1D5D4, 0x1D608, 0x1D670,
692        ] {
693            let wide = codepoint_string(start + index as u32);
694            registry.define_symbol(Mode::Math, SymbolGroup::MathOrdGroup, &text, &wide, false);
695            registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, &text, &wide, false);
696        }
697        if index < 26 {
698            for start in [0x1D538, 0x1D49C] {
699                let wide = codepoint_string(start + index as u32);
700                registry.define_symbol(Mode::Math, SymbolGroup::MathOrdGroup, &text, &wide, false);
701                registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, &text, &wide, false);
702            }
703        }
704    }
705    let double_struck_k = codepoint_string(0x1D55C);
706    registry.define_symbol(Mode::Math, SymbolGroup::MathOrdGroup, "k", &double_struck_k, false);
707    registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, "k", &double_struck_k, false);
708    for (index, ch) in "0123456789".chars().enumerate() {
709        let text = ch.to_string();
710        for start in [0x1D7CE, 0x1D7E2, 0x1D7EC, 0x1D7F6] {
711            let wide = codepoint_string(start + index as u32);
712            registry.define_symbol(Mode::Math, SymbolGroup::MathOrdGroup, &text, &wide, false);
713            registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, &text, &wide, false);
714        }
715    }
716    for ch in "ÐÞþ".chars() {
717        let text = ch.to_string();
718        registry.define_symbol(Mode::Math, SymbolGroup::MathOrdGroup, &text, &text, false);
719        registry.define_symbol(Mode::Text, SymbolGroup::TextOrdGroup, &text, &text, false);
720    }
721    registry
722}
723
724static BUILTIN_SYMBOLS: OnceLock<SymbolRegistry> = OnceLock::new();
725
726fn builtin_symbols() -> &'static SymbolRegistry {
727    BUILTIN_SYMBOLS.get_or_init(build_builtin_symbols)
728}
729
730pub(crate) fn lookup_symbol(mode: Mode, name: &str) -> Option<&'static SymbolSpec> {
731    let builtins = builtin_symbols();
732    if mode == Mode::Math {
733        builtins.math.get(name)
734    } else {
735        builtins.text.get(name)
736    }
737}
738
739/// Returns a registered symbol's Unicode replacement, if it has one.
740pub fn unicode_symbol(name: &str) -> Option<String> {
741    let builtins = builtin_symbols();
742    if let Some(symbol) = builtins.math.get(name)
743        && !symbol.replacement.is_empty() {
744            return Some(symbol.replacement.clone());
745        }
746    if let Some(symbol) = builtins.text.get(name)
747        && !symbol.replacement.is_empty() {
748            return Some(symbol.replacement.clone());
749        }
750    None
751}
752
753pub(crate) fn is_registered_symbol(name: &str) -> bool {
754    let builtins = builtin_symbols();
755    builtins.math.contains_key(name) || builtins.text.contains_key(name)
756}