boundary nodes made consistent (cleanup and document): WARNING: bump the format numbe...
[luatex.git] / source / texk / web2c / luatexdir / lua / luatoken.w
blob893519b592508f25301b97f376851ad243f8b39c
1 % luatoken.w
3 % Copyright 2006-2012 Taco Hoekwater <taco@@luatex.org>
5 % This file is part of LuaTeX.
7 % LuaTeX is free software; you can redistribute it and/or modify it under
8 % the terms of the GNU General Public License as published by the Free
9 % Software Foundation; either version 2 of the License, or (at your
10 % option) any later version.
12 % LuaTeX is distributed in the hope that it will be useful, but WITHOUT
13 % ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 % FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 % License for more details.
17 % You should have received a copy of the GNU General Public License along
18 % with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
20 @ @c
22 #include "ptexlib.h"
23 #include "lua/luatex-api.h"
25 @ @c
26 command_item command_names[] = {
27 {"relax", relax_cmd, NULL},
28 {"left_brace", left_brace_cmd, NULL},
29 {"right_brace", right_brace_cmd, NULL},
30 {"math_shift", math_shift_cmd, NULL},
31 {"tab_mark", tab_mark_cmd, NULL},
32 {"car_ret", car_ret_cmd, NULL},
33 {"mac_param", mac_param_cmd, NULL},
34 {"sup_mark", sup_mark_cmd, NULL},
35 {"sub_mark", sub_mark_cmd, NULL},
36 {"endv", endv_cmd, NULL},
37 {"spacer", spacer_cmd, NULL},
38 {"letter", letter_cmd, NULL},
39 {"other_char", other_char_cmd, NULL},
40 {"par_end", par_end_cmd, NULL},
41 {"stop", stop_cmd, NULL},
42 {"delim_num", delim_num_cmd, NULL},
43 {"char_num", char_num_cmd, NULL},
44 {"math_char_num", math_char_num_cmd, NULL},
45 {"mark", mark_cmd, NULL},
46 {"xray", xray_cmd, NULL},
47 {"make_box", make_box_cmd, NULL},
48 {"hmove", hmove_cmd, NULL},
49 {"vmove", vmove_cmd, NULL},
50 {"un_hbox", un_hbox_cmd, NULL},
51 {"un_vbox", un_vbox_cmd, NULL},
52 {"remove_item", remove_item_cmd, NULL},
53 {"hskip", hskip_cmd, NULL},
54 {"vskip", vskip_cmd, NULL},
55 {"mskip", mskip_cmd, NULL},
56 {"kern", kern_cmd, NULL},
57 {"mkern", mkern_cmd, NULL},
58 {"leader_ship", leader_ship_cmd, NULL},
59 {"halign", halign_cmd, NULL},
60 {"valign", valign_cmd, NULL},
61 {"no_align", no_align_cmd, NULL},
62 {"novrule", no_vrule_cmd, NULL},
63 {"nohrule", no_hrule_cmd, NULL},
64 {"vrule", vrule_cmd, NULL},
65 {"hrule", hrule_cmd, NULL},
66 {"insert", insert_cmd, NULL},
67 {"vadjust", vadjust_cmd, NULL},
68 {"ignore_spaces", ignore_spaces_cmd, NULL},
69 {"after_assignment", after_assignment_cmd, NULL},
70 {"after_group", after_group_cmd, NULL},
71 {"break_penalty", break_penalty_cmd, NULL},
72 {"start_par", start_par_cmd, NULL},
73 {"ital_corr", ital_corr_cmd, NULL},
74 {"accent", accent_cmd, NULL},
75 {"math_accent", math_accent_cmd, NULL},
76 {"discretionary", discretionary_cmd, NULL},
77 {"eq_no", eq_no_cmd, NULL},
78 {"left_right", left_right_cmd, NULL},
79 {"math_comp", math_comp_cmd, NULL},
80 {"limit_switch", limit_switch_cmd, NULL},
81 {"above", above_cmd, NULL},
82 {"math_style", math_style_cmd, NULL},
83 {"math_choice", math_choice_cmd, NULL},
84 {"non_script", non_script_cmd, NULL},
85 {"vcenter", vcenter_cmd, NULL},
86 {"case_shift", case_shift_cmd, NULL},
87 {"message", message_cmd, NULL},
88 {"normal", normal_cmd, NULL},
89 {"extension", extension_cmd, NULL},
90 {"option", option_cmd, NULL},
91 {"in_stream", in_stream_cmd, NULL},
92 {"begin_group", begin_group_cmd, NULL},
93 {"end_group", end_group_cmd, NULL},
94 {"omit", omit_cmd, NULL},
95 {"ex_space", ex_space_cmd, NULL},
96 {"boundary", boundary_cmd, NULL},
97 {"radical", radical_cmd, NULL},
98 {"super_sub_script", super_sub_script_cmd, NULL},
99 {"math_shift_cs", math_shift_cs_cmd, NULL},
100 {"end_cs_name", end_cs_name_cmd, NULL},
101 {"char_ghost", char_ghost_cmd, NULL},
102 {"assign_local_box", assign_local_box_cmd, NULL},
103 {"char_given", char_given_cmd, NULL},
104 {"math_given", math_given_cmd, NULL},
105 {"xmath_given", xmath_given_cmd, NULL},
106 {"last_item", last_item_cmd, NULL},
107 {"toks_register", toks_register_cmd, NULL},
108 {"assign_toks", assign_toks_cmd, NULL},
109 {"assign_int", assign_int_cmd, NULL},
110 {"assign_attr", assign_attr_cmd, NULL},
111 {"assign_dimen", assign_dimen_cmd, NULL},
112 {"assign_glue", assign_glue_cmd, NULL},
113 {"assign_mu_glue", assign_mu_glue_cmd, NULL},
114 {"assign_font_dimen", assign_font_dimen_cmd, NULL},
115 {"assign_font_int", assign_font_int_cmd, NULL},
116 {"set_aux", set_aux_cmd, NULL},
117 {"set_prev_graf", set_prev_graf_cmd, NULL},
118 {"set_page_dimen", set_page_dimen_cmd, NULL},
119 {"set_page_int", set_page_int_cmd, NULL},
120 {"set_box_dimen", set_box_dimen_cmd, NULL},
121 {"set_tex_shape", set_tex_shape_cmd, NULL},
122 {"set_etex_shape", set_etex_shape_cmd, NULL},
123 {"def_char_code", def_char_code_cmd, NULL},
124 {"def_del_code", def_del_code_cmd, NULL},
125 {"extdef_math_code", extdef_math_code_cmd, NULL},
126 {"extdef_del_code", extdef_del_code_cmd, NULL},
127 {"def_family", def_family_cmd, NULL},
128 {"set_math_param", set_math_param_cmd, NULL},
129 {"set_font", set_font_cmd, NULL},
130 {"def_font", def_font_cmd, NULL},
131 {"register", register_cmd, NULL},
132 {"assign_box_dir", assign_box_dir_cmd, NULL},
133 {"assign_dir", assign_dir_cmd, NULL},
134 {"advance", advance_cmd, NULL},
135 {"multiply", multiply_cmd, NULL},
136 {"divide", divide_cmd, NULL},
137 {"prefix", prefix_cmd, NULL},
138 {"let", let_cmd, NULL},
139 {"shorthand_def", shorthand_def_cmd, NULL},
140 {"read_to_cs", read_to_cs_cmd, NULL},
141 {"def", def_cmd, NULL},
142 {"set_box", set_box_cmd, NULL},
143 {"hyph_data", hyph_data_cmd, NULL},
144 {"set_interaction", set_interaction_cmd, NULL},
145 {"letterspace_font", letterspace_font_cmd, NULL},
146 {"expand_font",expand_font_cmd, NULL},
147 {"copy_font", copy_font_cmd, NULL},
148 {"set_font_id", set_font_id_cmd, NULL},
149 {"undefined_cs", undefined_cs_cmd, NULL},
150 {"expand_after", expand_after_cmd, NULL},
151 {"no_expand", no_expand_cmd, NULL},
152 {"input", input_cmd, NULL},
153 {"if_test", if_test_cmd, NULL},
154 {"fi_or_else", fi_or_else_cmd, NULL},
155 {"cs_name", cs_name_cmd, NULL},
156 {"convert", convert_cmd, NULL},
157 {"variable", variable_cmd, NULL},
158 {"feedback", feedback_cmd, NULL},
159 {"the", the_cmd, NULL},
160 {"combinetoks", combine_toks_cmd, NULL},
161 {"top_bot_mark", top_bot_mark_cmd, NULL},
162 {"call", call_cmd, NULL},
163 {"long_call", long_call_cmd, NULL},
164 {"outer_call", outer_call_cmd, NULL},
165 {"long_outer_call", long_outer_call_cmd, NULL},
166 {"end_template", end_template_cmd, NULL},
167 {"dont_expand", dont_expand_cmd, NULL},
168 {"glue_ref", glue_ref_cmd, NULL},
169 {"shape_ref", shape_ref_cmd, NULL},
170 {"box_ref", box_ref_cmd, NULL},
171 {"data", data_cmd, NULL},
172 {NULL, 0, NULL}
176 @ @c
177 int get_command_id(const char *s)
179 int i;
180 int cmd = -1;
181 for (i = 0; command_names[i].cmd_name != NULL; i++) {
182 if (strcmp(s, command_names[i].cmd_name) == 0)
183 break;
185 if (command_names[i].cmd_name != NULL) {
186 cmd = i;
188 return cmd;
192 static int get_cur_cmd(lua_State * L)
194 int r = 0;
195 size_t len = lua_rawlen(L, -1);
196 cur_cs = 0;
197 if (len == 3 || len == 2) {
198 r = 1;
199 lua_rawgeti(L, -1, 1);
200 cur_cmd = (int) lua_tointeger(L, -1);
201 lua_rawgeti(L, -2, 2);
202 cur_chr = (halfword) lua_tointeger(L, -1);
203 if (len == 3) {
204 lua_rawgeti(L, -3, 3);
205 cur_cs = (halfword) lua_tointeger(L, -1);
207 lua_pop(L, (int) len);
208 if (cur_cs == 0)
209 cur_tok = token_val(cur_cmd, cur_chr);
210 else
211 cur_tok = cs_token_flag + cur_cs;
213 return r;
217 @ @c
218 static int token_from_lua(lua_State * L)
220 int cmd, chr;
221 int cs = 0;
222 size_t len = lua_rawlen(L, -1);
223 if (len == 3 || len == 2) {
224 lua_rawgeti(L, -1, 1);
225 cmd = (int) lua_tointeger(L, -1);
226 lua_rawgeti(L, -2, 2);
227 chr = (int) lua_tointeger(L, -1);
228 if (len == 3) {
229 lua_rawgeti(L, -3, 3);
230 cs = (int) lua_tointeger(L, -1);
232 lua_pop(L, (int) len);
233 if (cs == 0) {
234 return token_val(cmd, chr);
235 } else {
236 return cs_token_flag + cs;
239 return -1;
243 static int get_cur_cs(lua_State * L)
245 const char *s;
246 unsigned j;
247 size_t l;
248 int cs;
249 int save_nncs;
250 int ret;
251 ret = 0;
252 cur_cs = 0;
253 lua_getfield(L, -1, "name");
254 if (lua_type(L, -1) == LUA_TSTRING) {
255 s = lua_tolstring(L, -1, &l);
256 if (l > 0) {
257 if ((last + (int) l) > buf_size)
258 check_buffer_overflow((last + (int) l));
259 for (j = 0; j < l; j++) {
260 buffer[(unsigned) last + 1 + j] = (packed_ASCII_code) * s++;
262 save_nncs = no_new_control_sequence;
263 no_new_control_sequence = false;
264 cs = id_lookup((last + 1), (int) l);
265 cur_tok = cs_token_flag + cs;
266 cur_cmd = eq_type(cs);
267 cur_chr = equiv(cs);
268 no_new_control_sequence = save_nncs;
269 ret = 1;
272 lua_pop(L, 1);
273 return ret;
277 @ @c
278 void tokenlist_to_lua(lua_State * L, int p)
280 int cmd, chr, cs;
281 int v;
282 int i = 1;
283 v = p;
284 while (v != null && v < (int) fix_mem_end) {
285 i++;
286 v = token_link(v);
288 i = 1;
289 lua_createtable(L, i, 0);
290 while (p != null && p < (int) fix_mem_end) {
291 if (token_info(p) >= cs_token_flag) {
292 cs = token_info(p) - cs_token_flag;
293 cmd = eq_type(cs);
294 chr = equiv(cs);
295 make_token_table(L, cmd, chr, cs);
296 } else {
297 cmd = token_cmd(token_info(p));
298 chr = token_chr(token_info(p));
299 make_token_table(L, cmd, chr, 0);
301 lua_rawseti(L, -2, i++);
302 p = token_link(p);
306 @ @c
307 void tokenlist_to_luastring(lua_State * L, int p)
309 int l;
310 char *s;
311 s = tokenlist_to_cstring(p, 1, &l);
312 lua_pushlstring(L, s, (size_t) l);
313 free(s);
317 @ @c
318 int tokenlist_from_lua(lua_State * L)
320 const char *s;
321 int tok, t;
322 size_t i, j;
323 halfword p, q, r;
324 r = get_avail();
325 token_info(r) = 0; /* ref count */
326 token_link(r) = null;
327 p = r;
328 t = lua_type(L, -1);
329 if (t == LUA_TTABLE) {
330 j = lua_rawlen(L, -1);
331 if (j > 0) {
332 for (i = 1; i <= j; i++) {
333 lua_rawgeti(L, -1, (int) i);
334 tok = token_from_lua(L);
335 if (tok >= 0) {
336 store_new_token(tok);
338 lua_pop(L, 1);
341 return r;
342 } else if (t == LUA_TSTRING) {
343 s = lua_tolstring(L, -1, &j);
344 for (i = 0; i < j; i++) {
345 if (s[i] == 32) {
346 tok = token_val(10, s[i]);
347 } else {
348 int j1 = (int) str2uni((const unsigned char *) (s + i));
349 i = i + (size_t) (utf8_size(j1) - 1);
350 tok = token_val(12, j1);
352 store_new_token(tok);
354 return r;
355 } else {
356 free_avail(r);
357 return null;
363 static void do_get_token_lua(int callback_id)
365 lua_State *L = Luas;
366 while (1) {
367 if (!get_callback(L, callback_id)) {
368 get_next();
369 lua_pop(L, 2);
370 break;
372 if (lua_pcall(L, 0, 1, 0) != 0) {
373 tex_error(lua_tostring(L, -1), NULL);
374 lua_pop(L, 2);
375 break;
377 if (lua_istable(L, -1)) {
378 lua_rawgeti(L, -1, 1);
379 if (lua_istable(L, -1)) {
380 int p, q, r;
381 size_t i, j;
382 lua_pop(L, 1);
383 r = get_avail();
384 p = r;
385 j = lua_rawlen(L, -1);
386 if (j > 0) {
387 for (i = 1; i <= j; i++) {
388 lua_rawgeti(L, -1, (int) i);
389 if (get_cur_cmd(L) || get_cur_cs(L)) {
390 store_new_token(cur_tok);
392 lua_pop(L, 1);
395 if (p != r) {
396 p = token_link(r);
397 free_avail(r);
398 begin_token_list(p, inserted);
399 cur_input.nofilter_field = true;
400 get_next();
401 } else {
402 tex_error("error: illegal or empty token list returned",
403 NULL);
405 lua_pop(L, 2);
406 break;
407 } else {
408 lua_pop(L, 1);
409 if (get_cur_cmd(L) || get_cur_cs(L)) {
410 lua_pop(L, 2);
411 break;
412 } else {
413 lua_pop(L, 2);
414 continue;
417 } else {
418 lua_pop(L, 2);
421 return;