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 At some point we will drop the mathchardef
8 bit storage
(c_mathoption_umathcode_meaning_code
=> 1)
68 and then some of the conversion can go away. Like mathchar_from_integer
: only wide characters are
74 mathcodeval mathchar_from_integer
(int value
, int extcode
)
77 if
(extcode
== tex_mathcode
) {
78 /* printf
("can't happen: tex_mathcode\n"); */
79 mval.class_value
= (value
/ 0x1000);
80 mval.family_value
= ((value
% 0x1000) / 0x100);
81 mval.character_value
= (value
% 0x100);
83 int mfam
= (value
/ 0x200000) & 0x7FF;
84 mval.class_value
= mfam
% 0x08;
85 mval.family_value
= mfam
/ 0x08;
86 mval.character_value
= value
& 0x1FFFFF;
92 void show_mathcode_value_old
(int value
)
97 void show_mathcode_value(mathcodeval c)
100 print_hex_digit
(c.class_value
);
102 two_hex(c.family_value);
104 six_hex
(c.character_value
);
108 static void show_mathcode
(int n
)
110 mathcodeval c
= get_math_code
(n
);
111 tprint_esc
("Umathcode");
114 show_mathcode_value
(c
);
118 static void unsavemathcode
(quarterword gl
)
121 if
(mathcode_head-
>stack
== NULL)
123 while
(mathcode_head-
>stack_ptr
> 0 && abs(mathcode_head->stack[mathcode_head->stack_ptr].level) >= gl) {
124 st
= mathcode_head-
>stack
[mathcode_head-
>stack_ptr
];
126 rawset_sa_item
(mathcode_head
, st.code
, st.value
);
127 if
(tracing_restores_par
> 1) {
132 show_mathcode
(st.code
);
134 end_diagnostic
(false
);
137 (mathcode_head-
>stack_ptr
)--;
142 void set_math_code
(int n
, int mathclass
, int mathfamily
, int mathcharacter
, quarterword level
)
145 if
(mathclass
== 8 && mathfamily == 0 && mathcharacter == 0) {
146 v.uint_value
= MATHCODEACTIVE
;
148 v.math_code_value.class_value
= mathclass
;
149 v.math_code_value.family_value
= mathfamily
;
150 v.math_code_value.character_value
= mathcharacter
;
152 set_sa_item
(mathcode_head
, n
, v
, level
);
153 if
(tracing_assigns_par
> 1) {
160 end_diagnostic
(false
);
165 /* we could use two structs ... tex and umath
*/
167 mathcodeval get_math_code
(int n
)
170 sa_tree_item v
= get_sa_item
(mathcode_head
, n
);
171 if
(v.uint_value
== MATHCODEDEFAULT
) {
174 d.character_value
= n
;
175 } else if
(v.uint_value
== MATHCODEACTIVE
) {
178 d.character_value
= 0;
180 d.class_value
= v.math_code_value.class_value
;
181 if
(d.class_value
== 8) {
183 d.character_value
= n
;
185 d.family_value
= v.math_code_value.family_value
;
186 d.character_value
= v.math_code_value.character_value
;
193 int get_math_code_num
(int n
)
195 mathcodeval d
= get_math_code
(n
);
196 return
(d.class_value
+ (d.family_value
* 8)) * (65536 * 32) + d.character_value
;
200 static void initializemathcode
(void
)
202 sa_tree_item sa_value
= { 0 };
203 sa_value.uint_value
= MATHCODEDEFAULT
;
204 mathcode_head
= new_sa_tree
(MATHCODESTACK
, 1, sa_value
);
207 static void dumpmathcode
(void
)
209 dump_sa_tree
(mathcode_head
,"mathcodes");
212 static void undumpmathcode
(void
)
214 mathcode_head
= undump_sa_tree
("mathcodes");
218 static void show_delcode
(int n
)
222 tprint_esc
("Udelcode");
225 if
(c.small_family_value
< 0) {
230 two_hex(c.small_family_value);
231 six_hex(c.small_character_value);
236 static void unsavedelcode(quarterword gl)
239 if (delcode_head->stack == NULL)
241 while (delcode_head->stack_ptr > 0 && abs(delcode_head->stack[delcode_head->stack_ptr].level) >= gl) {
242 st = delcode_head->stack[delcode_head->stack_ptr];
244 rawset_sa_item(delcode_head, st.code, st.value);
245 if (tracing_restores_par > 1) {
250 show_delcode(st.code);
252 end_diagnostic(false);
255 (delcode_head->stack_ptr)--;
260 void set_del_code(int n, int smathfamily, int smathcharacter, int lmathfamily, int lmathcharacter, quarterword gl)
263 v.del_code_value.class_value = 0;
264 v.del_code_value.small_family_value = smathfamily;
265 v.del_code_value.small_character_value = smathcharacter;
266 v.del_code_value.dummy_value = 0;
267 v.del_code_value.large_family_value = lmathfamily;
268 v.del_code_value.large_character_value = lmathcharacter;
269 set_sa_item(delcode_head, n, v, gl); /* always global */
270 if (tracing_assigns_par > 1) {
277 end_diagnostic(false);
282 delcodeval get_del_code(int n)
285 sa_tree_item v = get_sa_item(delcode_head, n);
286 if (v.uint_value == DELCODEDEFAULT) {
288 d.small_family_value = -1;
289 d.small_character_value = 0;
290 d.large_family_value = 0;
291 d.large_character_value = 0;
293 d.class_value = v.del_code_value.class_value;
294 d.small_family_value = v.del_code_value.small_family_value;
295 d.small_character_value = v.del_code_value.small_character_value;
296 d.large_family_value = v.del_code_value.large_family_value;
297 d.large_character_value = v.del_code_value.large_character_value;
302 @ this really only works for old-style delcodes!
305 int get_del_code_num(int n)
307 delcodeval d = get_del_code(n);
308 if (d.small_family_value < 0) {
311 return ((d.small_family_value * 256 + d.small_character_value) * 4096 +
312 (d.large_family_value * 256) + d.large_character_value);
317 static void initializedelcode(void)
319 sa_tree_item sa_value = { 0 };
320 sa_value.uint_value = DELCODEDEFAULT;
321 delcode_head = new_sa_tree(DELCODESTACK, 2, sa_value);
325 static void dumpdelcode(void)
327 dump_sa_tree(delcode_head,"delcodes
");
330 static void undumpdelcode(void)
332 delcode_head = undump_sa_tree("delcodes
");
336 void unsave_math_codes(quarterword grouplevel)
338 unsavemathcode(grouplevel);
339 unsavedelcode(grouplevel);
343 void initialize_math_codes(void)
345 initializemathcode();
350 void free_math_codes(void)
352 destroy_sa_tree(mathcode_head);
353 destroy_sa_tree(delcode_head);
357 void dump_math_codes(void)
363 void undump_math_codes(void)