1pub fn initex_lccode(c: u32) -> i64 {
11 match c {
12 0x41..=0x5A => i64::from(c + 32),
13 0x61..=0x7A => i64::from(c),
14 _ => 0,
15 }
16}
17
18pub fn initex_uccode(c: u32) -> i64 {
20 match c {
21 0x41..=0x5A => i64::from(c),
22 0x61..=0x7A => i64::from(c - 32),
23 _ => 0,
24 }
25}
26
27pub fn initex_sfcode(c: u32) -> i64 {
29 if (0x41..=0x5A).contains(&c) {
30 999
31 } else {
32 1000
33 }
34}
35
36pub const fn math_code(class: u32, fam: u32, chr: u32) -> i64 {
38 ((class as i64) << 21) + ((fam as i64) << 24) + chr as i64
39}
40
41pub const fn math_class(code: i64) -> u32 {
43 ((code >> 21) & 7) as u32
44}
45
46pub const fn math_fam(code: i64) -> u32 {
48 ((code >> 24) & 0xFF) as u32
49}
50
51pub const fn math_char(code: i64) -> u32 {
53 (code & 0x1F_FFFF) as u32
54}
55
56pub const MATH_GIVEN_PACKED: u32 = 1 << 31;
60
61pub const fn math_given_report(g: u32) -> i32 {
64 if g & MATH_GIVEN_PACKED == 0 {
65 return g as i32;
66 }
67 let code = (g & !MATH_GIVEN_PACKED) as i64;
68 (math_class(code) * 0x1000 + math_fam(code) * 0x100 + math_char(code)) as i32
69}
70
71pub const MATH_ACTIVE: i64 = 1 << 40;
75
76pub const fn math_code_report(code: i64) -> i32 {
79 if code == MATH_ACTIVE {
80 8 << 21
81 } else {
82 code as i32
83 }
84}
85
86pub fn initex_mathcode(c: u32) -> i64 {
89 match c {
90 0x30..=0x39 => math_code(7, 0, c),
91 0x41..=0x5A | 0x61..=0x7A => math_code(7, 1, c),
92 _ => i64::from(c),
93 }
94}
95
96pub fn initex_delcode(c: u32) -> i64 {
98 if c == u32::from(b'.') { 0 } else { -1 }
99}
100
101pub fn delcode_from_classic(v: i32) -> i64 {
104 if v < 0 {
105 return -1;
106 }
107 let v = v as i64;
108 let small_fam = (v >> 20) & 0xF;
109 let small_chr = (v >> 12) & 0xFF;
110 let large_fam = (v >> 8) & 0xF;
111 let large_chr = v & 0xFF;
112 (small_fam << 53) | (small_chr << 32) | (large_fam << 21) | large_chr | (1 << 62)
114}
115
116pub fn delcode_report(v: i64, _cmd: crate::cmd::Cmd) -> i32 {
118 if v < 0 {
119 return -1;
120 }
121 if v & (1 << 62) == 0 {
122 return v as i32;
123 }
124 let small_fam = (v >> 53) & 0xF;
125 let small_chr = (v >> 32) & 0xFF;
126 let large_fam = (v >> 21) & 0xF;
127 let large_chr = v & 0xFF;
128 ((small_fam << 20) | (small_chr << 12) | (large_fam << 8) | large_chr) as i32
129}
130
131pub fn math_param_is_glue(p: u32) -> bool {
133 (49..49 + 64).contains(&p)
134}
135
136pub const UNDEFINED_MATH_PARAM: i32 = 0x3FFF_FFFF;
138
139#[cfg(test)]
140mod tests {
141 use super::*;
142
143 #[test]
144 fn packing_matches_luatex() {
145 assert_eq!(initex_mathcode('a' as u32), 31457377);
147 assert_eq!(initex_mathcode('1' as u32), 14680113);
148 assert_eq!(math_code(1, 2, 0x3B1), 35652529);
149 assert_eq!(math_code_report(MATH_ACTIVE), 16777216);
150 }
151}