beta-0.89.2
[luatex.git] / source / texk / web2c / luatexdir / lua / luatoken.w
blob9001026ca45c72d1580293d919c6c4337bddca4f
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 {"no_boundary", no_boundary_cmd, NULL},
98 {"radical", radical_cmd, NULL},
99 {"super_sub_script", super_sub_script_cmd, NULL},
100 {"math_shift_cs", math_shift_cs_cmd, NULL},
101 {"end_cs_name", end_cs_name_cmd, NULL},
102 {"char_ghost", char_ghost_cmd, NULL},
103 {"assign_local_box", assign_local_box_cmd, NULL},
104 {"char_given", char_given_cmd, NULL},
105 {"math_given", math_given_cmd, NULL},
106 {"xmath_given", xmath_given_cmd, NULL},
107 {"last_item", last_item_cmd, NULL},
108 {"toks_register", toks_register_cmd, NULL},
109 {"assign_toks", assign_toks_cmd, NULL},
110 {"assign_int", assign_int_cmd, NULL},
111 {"assign_attr", assign_attr_cmd, NULL},
112 {"assign_dimen", assign_dimen_cmd, NULL},
113 {"assign_glue", assign_glue_cmd, NULL},
114 {"assign_mu_glue", assign_mu_glue_cmd, NULL},
115 {"assign_font_dimen", assign_font_dimen_cmd, NULL},
116 {"assign_font_int", assign_font_int_cmd, NULL},
117 {"set_aux", set_aux_cmd, NULL},
118 {"set_prev_graf", set_prev_graf_cmd, NULL},
119 {"set_page_dimen", set_page_dimen_cmd, NULL},
120 {"set_page_int", set_page_int_cmd, NULL},
121 {"set_box_dimen", set_box_dimen_cmd, NULL},
122 {"set_tex_shape", set_tex_shape_cmd, NULL},
123 {"set_etex_shape", set_etex_shape_cmd, NULL},
124 {"def_char_code", def_char_code_cmd, NULL},
125 {"def_del_code", def_del_code_cmd, NULL},
126 {"extdef_math_code", extdef_math_code_cmd, NULL},
127 {"extdef_del_code", extdef_del_code_cmd, NULL},
128 {"def_family", def_family_cmd, NULL},
129 {"set_math_param", set_math_param_cmd, NULL},
130 {"set_font", set_font_cmd, NULL},
131 {"def_font", def_font_cmd, NULL},
132 {"register", register_cmd, NULL},
133 {"assign_box_dir", assign_box_dir_cmd, NULL},
134 {"assign_dir", assign_dir_cmd, NULL},
135 {"advance", advance_cmd, NULL},
136 {"multiply", multiply_cmd, NULL},
137 {"divide", divide_cmd, NULL},
138 {"prefix", prefix_cmd, NULL},
139 {"let", let_cmd, NULL},
140 {"shorthand_def", shorthand_def_cmd, NULL},
141 {"read_to_cs", read_to_cs_cmd, NULL},
142 {"def", def_cmd, NULL},
143 {"set_box", set_box_cmd, NULL},
144 {"hyph_data", hyph_data_cmd, NULL},
145 {"set_interaction", set_interaction_cmd, NULL},
146 {"letterspace_font", letterspace_font_cmd, NULL},
147 {"expand_font",expand_font_cmd, NULL},
148 {"copy_font", copy_font_cmd, NULL},
149 {"set_font_id", set_font_id_cmd, NULL},
150 {"undefined_cs", undefined_cs_cmd, NULL},
151 {"expand_after", expand_after_cmd, NULL},
152 {"no_expand", no_expand_cmd, NULL},
153 {"input", input_cmd, NULL},
154 {"if_test", if_test_cmd, NULL},
155 {"fi_or_else", fi_or_else_cmd, NULL},
156 {"cs_name", cs_name_cmd, NULL},
157 {"convert", convert_cmd, NULL},
158 {"variable", variable_cmd, NULL},
159 {"feedback", feedback_cmd, NULL},
160 {"the", the_cmd, NULL},
161 {"combinetoks", combine_toks_cmd, NULL},
162 {"top_bot_mark", top_bot_mark_cmd, NULL},
163 {"call", call_cmd, NULL},
164 {"long_call", long_call_cmd, NULL},
165 {"outer_call", outer_call_cmd, NULL},
166 {"long_outer_call", long_outer_call_cmd, NULL},
167 {"end_template", end_template_cmd, NULL},
168 {"dont_expand", dont_expand_cmd, NULL},
169 {"glue_ref", glue_ref_cmd, NULL},
170 {"shape_ref", shape_ref_cmd, NULL},
171 {"box_ref", box_ref_cmd, NULL},
172 {"data", data_cmd, NULL},
173 {NULL, 0, NULL}
177 @ @c
178 int get_command_id(const char *s)
180 int i;
181 int cmd = -1;
182 for (i = 0; command_names[i].cmd_name != NULL; i++) {
183 if (strcmp(s, command_names[i].cmd_name) == 0)
184 break;
186 if (command_names[i].cmd_name != NULL) {
187 cmd = i;
189 return cmd;
193 static int get_cur_cmd(lua_State * L)
195 int r = 0;
196 size_t len = lua_rawlen(L, -1);
197 cur_cs = 0;
198 if (len == 3 || len == 2) {
199 r = 1;
200 lua_rawgeti(L, -1, 1);
201 cur_cmd = (int) lua_tointeger(L, -1);
202 lua_rawgeti(L, -2, 2);
203 cur_chr = (halfword) lua_tointeger(L, -1);
204 if (len == 3) {
205 lua_rawgeti(L, -3, 3);
206 cur_cs = (halfword) lua_tointeger(L, -1);
208 lua_pop(L, (int) len);
209 if (cur_cs == 0)
210 cur_tok = token_val(cur_cmd, cur_chr);
211 else
212 cur_tok = cs_token_flag + cur_cs;
214 return r;
218 @ @c
219 static int token_from_lua(lua_State * L)
221 int cmd, chr;
222 int cs = 0;
223 size_t len = lua_rawlen(L, -1);
224 if (len == 3 || len == 2) {
225 lua_rawgeti(L, -1, 1);
226 cmd = (int) lua_tointeger(L, -1);
227 lua_rawgeti(L, -2, 2);
228 chr = (int) lua_tointeger(L, -1);
229 if (len == 3) {
230 lua_rawgeti(L, -3, 3);
231 cs = (int) lua_tointeger(L, -1);
233 lua_pop(L, (int) len);
234 if (cs == 0) {
235 return token_val(cmd, chr);
236 } else {
237 return cs_token_flag + cs;
240 return -1;
244 static int get_cur_cs(lua_State * L)
246 const char *s;
247 unsigned j;
248 size_t l;
249 int cs;
250 int save_nncs;
251 int ret;
252 ret = 0;
253 cur_cs = 0;
254 lua_getfield(L, -1, "name");
255 if (lua_type(L, -1) == LUA_TSTRING) {
256 s = lua_tolstring(L, -1, &l);
257 if (l > 0) {
258 if ((last + (int) l) > buf_size)
259 check_buffer_overflow((last + (int) l));
260 for (j = 0; j < l; j++) {
261 buffer[(unsigned) last + 1 + j] = (packed_ASCII_code) * s++;
263 save_nncs = no_new_control_sequence;
264 no_new_control_sequence = false;
265 cs = id_lookup((last + 1), (int) l);
266 cur_tok = cs_token_flag + cs;
267 cur_cmd = eq_type(cs);
268 cur_chr = equiv(cs);
269 no_new_control_sequence = save_nncs;
270 ret = 1;
273 lua_pop(L, 1);
274 return ret;
278 @ @c
279 void tokenlist_to_lua(lua_State * L, int p)
281 int cmd, chr, cs;
282 int v;
283 int i = 1;
284 v = p;
285 while (v != null && v < (int) fix_mem_end) {
286 i++;
287 v = token_link(v);
289 i = 1;
290 lua_createtable(L, i, 0);
291 while (p != null && p < (int) fix_mem_end) {
292 if (token_info(p) >= cs_token_flag) {
293 cs = token_info(p) - cs_token_flag;
294 cmd = eq_type(cs);
295 chr = equiv(cs);
296 make_token_table(L, cmd, chr, cs);
297 } else {
298 cmd = token_cmd(token_info(p));
299 chr = token_chr(token_info(p));
300 make_token_table(L, cmd, chr, 0);
302 lua_rawseti(L, -2, i++);
303 p = token_link(p);
307 @ @c
308 void tokenlist_to_luastring(lua_State * L, int p)
310 int l;
311 char *s;
312 s = tokenlist_to_cstring(p, 1, &l);
313 lua_pushlstring(L, s, (size_t) l);
314 free(s);
318 @ @c
319 int tokenlist_from_lua(lua_State * L)
321 const char *s;
322 int tok, t;
323 size_t i, j;
324 halfword p, q, r;
325 r = get_avail();
326 token_info(r) = 0; /* ref count */
327 token_link(r) = null;
328 p = r;
329 t = lua_type(L, -1);
330 if (t == LUA_TTABLE) {
331 j = lua_rawlen(L, -1);
332 if (j > 0) {
333 for (i = 1; i <= j; i++) {
334 lua_rawgeti(L, -1, (int) i);
335 tok = token_from_lua(L);
336 if (tok >= 0) {
337 store_new_token(tok);
339 lua_pop(L, 1);
342 return r;
343 } else if (t == LUA_TSTRING) {
344 s = lua_tolstring(L, -1, &j);
345 for (i = 0; i < j; i++) {
346 if (s[i] == 32) {
347 tok = token_val(10, s[i]);
348 } else {
349 int j1 = (int) str2uni((const unsigned char *) (s + i));
350 i = i + (size_t) (utf8_size(j1) - 1);
351 tok = token_val(12, j1);
353 store_new_token(tok);
355 return r;
356 } else {
357 free_avail(r);
358 return null;
364 static void do_get_token_lua(int callback_id)
366 lua_State *L = Luas;
367 while (1) {
368 if (!get_callback(L, callback_id)) {
369 get_next();
370 lua_pop(L, 2);
371 break;
373 if (lua_pcall(L, 0, 1, 0) != 0) {
374 tex_error(lua_tostring(L, -1), NULL);
375 lua_pop(L, 2);
376 break;
378 if (lua_istable(L, -1)) {
379 lua_rawgeti(L, -1, 1);
380 if (lua_istable(L, -1)) {
381 int p, q, r;
382 size_t i, j;
383 lua_pop(L, 1);
384 r = get_avail();
385 p = r;
386 j = lua_rawlen(L, -1);
387 if (j > 0) {
388 for (i = 1; i <= j; i++) {
389 lua_rawgeti(L, -1, (int) i);
390 if (get_cur_cmd(L) || get_cur_cs(L)) {
391 store_new_token(cur_tok);
393 lua_pop(L, 1);
396 if (p != r) {
397 p = token_link(r);
398 free_avail(r);
399 begin_token_list(p, inserted);
400 cur_input.nofilter_field = true;
401 get_next();
402 } else {
403 tex_error("error: illegal or empty token list returned",
404 NULL);
406 lua_pop(L, 2);
407 break;
408 } else {
409 lua_pop(L, 1);
410 if (get_cur_cmd(L) || get_cur_cs(L)) {
411 lua_pop(L, 2);
412 break;
413 } else {
414 lua_pop(L, 2);
415 continue;
418 } else {
419 lua_pop(L, 2);
422 return;