Skip to main content

ratex_parser/
unicode_sup_sub.rs

1/// Unicode superscript/subscript character mappings.
2/// Mirrors KaTeX's unicodeSupOrSub module.
3/// Returns `Some((mapped_char, is_subscript))` if the character is a Unicode
4/// superscript or subscript; `None` otherwise.
5pub fn unicode_sub_sup(c: char) -> Option<(&'static str, bool)> {
6    let is_sub = matches!(c, '\u{2080}'..='\u{209C}' | '\u{1D62}'..='\u{1D6A}' | '\u{2C7C}');
7    let mapped = match c {
8        // ── Subscript digits ──
9        '\u{2080}' => "0",
10        '\u{2081}' => "1",
11        '\u{2082}' => "2",
12        '\u{2083}' => "3",
13        '\u{2084}' => "4",
14        '\u{2085}' => "5",
15        '\u{2086}' => "6",
16        '\u{2087}' => "7",
17        '\u{2088}' => "8",
18        '\u{2089}' => "9",
19        // ── Subscript operators ──
20        '\u{208A}' => "+",
21        '\u{208B}' => "\u{2212}", // minus sign
22        '\u{208C}' => "=",
23        '\u{208D}' => "(",
24        '\u{208E}' => ")",
25        // ── Subscript letters ──
26        '\u{2090}' => "a",
27        '\u{2091}' => "e",
28        '\u{2092}' => "o",
29        '\u{2093}' => "x",
30        '\u{2095}' => "h",
31        '\u{2096}' => "k",
32        '\u{2097}' => "l",
33        '\u{2098}' => "m",
34        '\u{2099}' => "n",
35        '\u{209A}' => "p",
36        '\u{209B}' => "s",
37        '\u{209C}' => "t",
38        '\u{1D62}' => "i",
39        '\u{1D63}' => "r",
40        '\u{1D64}' => "u",
41        '\u{1D65}' => "v",
42        '\u{2C7C}' => "j",
43        // ── Subscript Greek ──
44        '\u{1D66}' => "\u{03B2}", // β
45        '\u{1D67}' => "\u{03B3}", // γ
46        '\u{1D68}' => "\u{03C1}", // ρ
47        '\u{1D69}' => "\u{03C6}", // φ
48        '\u{1D6A}' => "\u{03C7}", // χ
49
50        // ── Superscript digits ──
51        '\u{2070}' => "0",
52        '\u{00B9}' => "1",
53        '\u{00B2}' => "2",
54        '\u{00B3}' => "3",
55        '\u{2074}' => "4",
56        '\u{2075}' => "5",
57        '\u{2076}' => "6",
58        '\u{2077}' => "7",
59        '\u{2078}' => "8",
60        '\u{2079}' => "9",
61        // ── Superscript operators ──
62        '\u{207A}' => "+",
63        '\u{207B}' => "\u{2212}", // minus sign
64        '\u{207C}' => "=",
65        '\u{207D}' => "(",
66        '\u{207E}' => ")",
67        // ── Superscript letters (lowercase) ──
68        '\u{2071}' => "i",
69        '\u{207F}' => "n",
70        '\u{1D43}' => "a",
71        '\u{1D47}' => "b",
72        '\u{1D48}' => "d",
73        '\u{1D49}' => "e",
74        '\u{1D4D}' => "g",
75        '\u{02B0}' => "h",
76        '\u{02B2}' => "j",
77        '\u{1D4F}' => "k",
78        '\u{02E1}' => "l",
79        '\u{1D50}' => "m",
80        '\u{1D52}' => "o",
81        '\u{1D56}' => "p",
82        '\u{02B3}' => "r",
83        '\u{02E2}' => "s",
84        '\u{1D57}' => "t",
85        '\u{1D58}' => "u",
86        '\u{1D5B}' => "v",
87        '\u{02B7}' => "w",
88        '\u{02E3}' => "x",
89        '\u{02B8}' => "y",
90        // ── Superscript letters (uppercase) ──
91        '\u{1D2C}' => "A",
92        '\u{1D2E}' => "B",
93        '\u{1D30}' => "D",
94        '\u{1D31}' => "E",
95        '\u{1D33}' => "G",
96        '\u{1D34}' => "H",
97        '\u{1D35}' => "I",
98        '\u{1D36}' => "J",
99        '\u{1D37}' => "K",
100        '\u{1D38}' => "L",
101        '\u{1D39}' => "M",
102        '\u{1D3A}' => "N",
103        '\u{1D3C}' => "O",
104        '\u{1D3E}' => "P",
105        '\u{1D3F}' => "R",
106        '\u{1D40}' => "T",
107        '\u{1D41}' => "U",
108        '\u{1D42}' => "W",
109        // ── Superscript Greek ──
110        '\u{1D5D}' => "\u{03B2}", // β
111        '\u{1D5E}' => "\u{03B3}", // γ
112        '\u{1D5F}' => "\u{03B4}", // δ
113        '\u{1D60}' => "\u{03C6}", // φ
114        '\u{1D61}' => "\u{03C7}", // χ
115        '\u{1DBF}' => "\u{03B8}", // θ
116
117        _ => return None,
118    };
119    Some((mapped, is_sub))
120}