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
/>.
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
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
)); \
50 #define two_hex
(A
) do
{ \
51 print_hex_digit
((A
)/16); \
52 print_hex_digit
((A
)%16); \
55 #define four_hex
(A
) do
{ \
60 #define six_hex
(A
) do
{ \
62 two_hex
(((A
)%65536)/256); \
67 mathcodeval mathchar_from_integer
(int value
, int extcode
)
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;
84 void show_mathcode_value
(mathcodeval c
)
87 print_hex_digit(c.class_value);
89 two_hex
(c.family_value
);
91 six_hex(c.character_value);
95 static void show_mathcode(int n)
97 mathcodeval c = get_math_code(n);
98 tprint_esc("Umathcode
");
101 show_mathcode_value(c);
105 static void unsavemathcode(quarterword gl)
108 if (mathcode_head->stack == NULL)
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];
113 rawset_sa_item(mathcode_head, st.code, st.value);
114 if (int_par(tracing_restores_code) > 1) {
119 show_mathcode(st.code);
121 end_diagnostic(false);
124 (mathcode_head->stack_ptr)--;
129 void set_math_code(int n, int mathclass, int mathfamily, int mathcharacter, quarterword level)
132 if (mathclass == 8 && mathfamily == 0 && mathcharacter == 0) {
133 v.uint_value = MATHCODEACTIVE;
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) {
147 end_diagnostic(false);
152 /* we could use two structs ... tex and umath */
154 mathcodeval get_math_code(int n)
157 sa_tree_item v = get_sa_item(mathcode_head, n);
158 if (v.uint_value == MATHCODEDEFAULT) {
161 d.character_value = n;
162 } else if (v.uint_value == MATHCODEACTIVE) {
165 d.character_value = 0;
167 d.class_value = v.math_code_value.class_value;
168 if (d.class_value == 8) {
170 d.character_value = n;
172 d.family_value = v.math_code_value.family_value;
173 d.character_value = v.math_code_value.character_value;
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;
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
");
205 static void show_delcode(int n)
209 tprint_esc("Udelcode
");
212 if (c.small_family_value < 0) {
217 two_hex
(c.small_family_value
);
218 six_hex
(c.small_character_value
);
223 static void unsavedelcode
(quarterword gl
)
226 if
(delcode_head-
>stack
== NULL)
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
];
231 rawset_sa_item
(delcode_head
, st.code
, st.value
);
232 if
(int_par
(tracing_restores_code
) > 1) {
237 show_delcode
(st.code
);
239 end_diagnostic
(false
);
242 (mathcode_head-
>stack_ptr
)--;
247 void set_del_code
(int n
, int smathfamily
, int smathcharacter
, int lmathfamily
, int lmathcharacter
, quarterword gl
)
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) {
264 end_diagnostic
(false
);
269 delcodeval get_del_code
(int n
)
272 sa_tree_item v
= get_sa_item
(delcode_head
, n
);
273 if
(v.uint_value
== DELCODEDEFAULT
) {
275 d.small_family_value
= -1;
276 d.small_character_value
= 0;
277 d.large_family_value
= 0;
278 d.large_character_value
= 0;
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
;
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) {
298 return
((d.small_family_value
* 256 + d.small_character_value
) * 4096 +
299 (d.large_family_value
* 256) + d.large_character_value
);
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
);
312 static void dumpdelcode
(void
)
314 dump_sa_tree
(delcode_head
,"delcodes");
317 static void undumpdelcode
(void
)
319 delcode_head
= undump_sa_tree
("delcodes");
323 void unsave_math_codes
(quarterword grouplevel
)
325 unsavemathcode
(grouplevel
);
326 unsavedelcode
(grouplevel
);
330 void initialize_math_codes
(void
)
332 initializemathcode
();
337 void free_math_codes
(void
)
339 destroy_sa_tree
(mathcode_head
);
340 destroy_sa_tree
(delcode_head
);
344 void dump_math_codes
(void
)
350 void undump_math_codes
(void
)