beta-0.89.2
[luatex.git] / source / texk / web2c / luatexdir / tex / mathcodes.w
blobe161af0fe547727b81fd0b3662f72e0d9d05ee3f
1 % mathnodes.w
3 % Copyright 2006-2012 Taco Hoekwater <taco@@luatex.org>
4 % Copyright 2012 Khaled Hosny <khaledhosny@@eglug.org>
6 % This file is part of LuaTeX.
8 % LuaTeX is free software; you can redistribute it and/or modify it under
9 % the terms of the GNU General Public License as published by the Free
10 % Software Foundation; either version 2 of the License, or (at your
11 % option) any later version.
13 % LuaTeX is distributed in the hope that it will be useful, but WITHOUT
14 % ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 % FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16 % License for more details.
18 % You should have received a copy of the GNU General Public License along
19 % with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
21 @ @c
23 #include "ptexlib.h"
25 @ math codes
27 static sa_tree mathcode_head = NULL;
29 /* the 0xFFFFFFFF is a flag value */
31 #define MATHCODESTACK 8
32 #define MATHCODEDEFAULT 0xFFFFFFFF
33 #define MATHCODEACTIVE 0xFFFFFFFE
35 @ delcodes
37 static sa_tree delcode_head = NULL;
39 #define DELCODESTACK 4
40 #define DELCODEDEFAULT 0xFFFFFFFF
42 @ some helpers for mathcode printing
45 #define print_hex_digit(A) do { \
46 if ((A)>=10) print_char('A'+(A)-10); \
47 else print_char('0'+(A)); \
48 } while (0)
50 #define two_hex(A) do { \
51 print_hex_digit((A)/16); \
52 print_hex_digit((A)%16); \
53 } while (0)
55 #define four_hex(A) do { \
56 two_hex((A)/256); \
57 two_hex((A)%256); \
58 } while (0)
60 #define six_hex(A) do { \
61 two_hex((A)/65536); \
62 two_hex(((A)%65536)/256); \
63 two_hex((A)%256); \
64 } while (0)
66 @ @c
67 mathcodeval mathchar_from_integer(int value, int extcode)
69 mathcodeval mval;
70 if (extcode == tex_mathcode) {
71 mval.class_value = (value / 0x1000);
72 mval.family_value = ((value % 0x1000) / 0x100);
73 mval.character_value = (value % 0x100);
74 } else { /* some xetexended xetex thing */
75 int mfam = (value / 0x200000) & 0x7FF;
76 mval.class_value = mfam % 0x08;
77 mval.family_value = mfam / 0x08;
78 mval.character_value = value & 0x1FFFFF;
80 return mval;
83 @ @c
84 void show_mathcode_value(mathcodeval c)
86 print_char('"');
87 print_hex_digit(c.class_value);
88 print_char('"');
89 two_hex(c.family_value);
90 print_char('"');
91 six_hex(c.character_value);
94 @ @c
95 static void show_mathcode(int n)
97 mathcodeval c = get_math_code(n);
98 tprint_esc("Umathcode");
99 print_int(n);
100 print_char('=');
101 show_mathcode_value(c);
104 @ @c
105 static void unsavemathcode(quarterword gl)
107 sa_stack_item st;
108 if (mathcode_head->stack == NULL)
109 return;
110 while (mathcode_head->stack_ptr > 0 && abs(mathcode_head->stack[mathcode_head->stack_ptr].level) >= gl) {
111 st = mathcode_head->stack[mathcode_head->stack_ptr];
112 if (st.level > 0) {
113 rawset_sa_item(mathcode_head, st.code, st.value);
114 if (int_par(tracing_restores_code) > 1) {
115 begin_diagnostic();
116 print_char('{');
117 tprint("restoring");
118 print_char(' ');
119 show_mathcode(st.code);
120 print_char('}');
121 end_diagnostic(false);
124 (mathcode_head->stack_ptr)--;
128 @ @c
129 void set_math_code(int n, int mathclass, int mathfamily, int mathcharacter, quarterword level)
131 sa_tree_item v;
132 if (mathclass == 8 && mathfamily == 0 && mathcharacter == 0) {
133 v.uint_value = MATHCODEACTIVE;
134 } else {
135 v.math_code_value.class_value = mathclass;
136 v.math_code_value.family_value = mathfamily;
137 v.math_code_value.character_value = mathcharacter;
139 set_sa_item(mathcode_head, n, v, level);
140 if (int_par(tracing_assigns_code) > 1) {
141 begin_diagnostic();
142 print_char('{');
143 tprint("assigning");
144 print_char(' ');
145 show_mathcode(n);
146 print_char('}');
147 end_diagnostic(false);
151 @ @c
152 /* we could use two structs ... tex and umath */
154 mathcodeval get_math_code(int n)
156 mathcodeval d;
157 sa_tree_item v = get_sa_item(mathcode_head, n);
158 if (v.uint_value == MATHCODEDEFAULT) {
159 d.class_value = 0;
160 d.family_value = 0;
161 d.character_value = n;
162 } else if (v.uint_value == MATHCODEACTIVE) {
163 d.class_value = 8;
164 d.family_value = 0;
165 d.character_value = 0;
166 } else {
167 d.class_value = v.math_code_value.class_value;
168 if (d.class_value == 8) {
169 d.family_value = 0;
170 d.character_value = n;
171 } else {
172 d.family_value = v.math_code_value.family_value;
173 d.character_value = v.math_code_value.character_value;
176 return d;
179 @ @c
180 int get_math_code_num(int n)
182 mathcodeval d = get_math_code(n);
183 return (d.class_value + (d.family_value * 8)) * (65536 * 32) + d.character_value;
186 @ @c
187 static void initializemathcode(void)
189 sa_tree_item sa_value = { 0 };
190 sa_value.uint_value = MATHCODEDEFAULT;
191 mathcode_head = new_sa_tree(MATHCODESTACK, 1, sa_value);
194 static void dumpmathcode(void)
196 dump_sa_tree(mathcode_head,"mathcodes");
199 static void undumpmathcode(void)
201 mathcode_head = undump_sa_tree("mathcodes");
204 @ @c
205 static void show_delcode(int n)
207 delcodeval c;
208 c = get_del_code(n);
209 tprint_esc("Udelcode");
210 print_int(n);
211 print_char('=');
212 if (c.small_family_value < 0) {
213 print_char('-');
214 print_char('1');
215 } else {
216 print_char('"');
217 two_hex(c.small_family_value);
218 six_hex(c.small_character_value);
222 @ @c
223 static void unsavedelcode(quarterword gl)
225 sa_stack_item st;
226 if (delcode_head->stack == NULL)
227 return;
228 while (delcode_head->stack_ptr > 0 && abs(delcode_head->stack[delcode_head->stack_ptr].level) >= gl) {
229 st = delcode_head->stack[delcode_head->stack_ptr];
230 if (st.level > 0) {
231 rawset_sa_item(delcode_head, st.code, st.value);
232 if (int_par(tracing_restores_code) > 1) {
233 begin_diagnostic();
234 print_char('{');
235 tprint("restoring");
236 print_char(' ');
237 show_delcode(st.code);
238 print_char('}');
239 end_diagnostic(false);
242 (mathcode_head->stack_ptr)--;
246 @ @c
247 void set_del_code(int n, int smathfamily, int smathcharacter, int lmathfamily, int lmathcharacter, quarterword gl)
249 sa_tree_item v;
250 v.del_code_value.class_value = 0;
251 v.del_code_value.small_family_value = smathfamily;
252 v.del_code_value.small_character_value = smathcharacter;
253 v.del_code_value.dummy_value = 0;
254 v.del_code_value.large_family_value = lmathfamily;
255 v.del_code_value.large_character_value = lmathcharacter;
256 set_sa_item(delcode_head, n, v, gl); /* always global */
257 if (int_par(tracing_assigns_code) > 1) {
258 begin_diagnostic();
259 print_char('{');
260 tprint("assigning");
261 print_char(' ');
262 show_delcode(n);
263 print_char('}');
264 end_diagnostic(false);
268 @ @c
269 delcodeval get_del_code(int n)
271 delcodeval d;
272 sa_tree_item v = get_sa_item(delcode_head, n);
273 if (v.uint_value == DELCODEDEFAULT) {
274 d.class_value = 0;
275 d.small_family_value = -1;
276 d.small_character_value = 0;
277 d.large_family_value = 0;
278 d.large_character_value = 0;
279 } else {
280 d.class_value = v.del_code_value.class_value;
281 d.small_family_value = v.del_code_value.small_family_value;
282 d.small_character_value = v.del_code_value.small_character_value;
283 d.large_family_value = v.del_code_value.large_family_value;
284 d.large_character_value = v.del_code_value.large_character_value;
286 return d;
289 @ this really only works for old-style delcodes!
292 int get_del_code_num(int n)
294 delcodeval d = get_del_code(n);
295 if (d.small_family_value < 0) {
296 return -1;
297 } else {
298 return ((d.small_family_value * 256 + d.small_character_value) * 4096 +
299 (d.large_family_value * 256) + d.large_character_value);
303 @ @c
304 static void initializedelcode(void)
306 sa_tree_item sa_value = { 0 };
307 sa_value.uint_value = DELCODEDEFAULT;
308 delcode_head = new_sa_tree(DELCODESTACK, 2, sa_value);
311 @ @c
312 static void dumpdelcode(void)
314 dump_sa_tree(delcode_head,"delcodes");
317 static void undumpdelcode(void)
319 delcode_head = undump_sa_tree("delcodes");
322 @ @c
323 void unsave_math_codes(quarterword grouplevel)
325 unsavemathcode(grouplevel);
326 unsavedelcode(grouplevel);
329 @ @c
330 void initialize_math_codes(void)
332 initializemathcode();
333 initializedelcode();
336 @ @c
337 void free_math_codes(void)
339 destroy_sa_tree(mathcode_head);
340 destroy_sa_tree(delcode_head);
343 @ @c
344 void dump_math_codes(void)
346 dumpmathcode();
347 dumpdelcode();
350 void undump_math_codes(void)
352 undumpmathcode();
353 undumpdelcode();