synch with TL 37803
[luatex.git] / source / texk / web2c / luatexdir / lua / luanode.w
bloba9da3cb1c34623f60db0a0b1ea51974cae81fb2c
1 % luanode.w
3 % Copyright 2006-2008 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 /* hh-ls: we make sure that lua never sees prev of head but also that when
21 nodes are removedor inserted, temp nodes don't interfere */
23 @ @c
26 #include "ptexlib.h"
27 #include "lua/luatex-api.h"
29 /* TO BE REMOVED
30 static const char *group_code_names[] = {
31 "",
32 "simple",
33 "hbox",
34 "adjusted_hbox",
35 "vbox",
36 "vtop",
37 "align",
38 "no_align",
39 "output",
40 "math",
41 "disc",
42 "insert",
43 "vcenter",
44 "math_choice",
45 "semi_simple",
46 "math_shift",
47 "math_left",
48 "local_box",
49 "split_off",
50 "split_keep",
51 "preamble",
52 "align_set",
53 "fin_row"
56 const char *pack_type_name[] = { "exactly", "additional" };
59 @ @c
60 void
61 lua_node_filter_s(int filterid, int extrainfo)
63 lua_State *L = Luas;
64 int callback_id = callback_defined(filterid);
65 int s_top = lua_gettop(L);
66 if (callback_id <= 0) {
67 lua_settop(L, s_top);
68 return;
70 if (!get_callback(L, callback_id)) {
71 lua_settop(L, s_top);
72 return;
74 lua_push_string_by_index(L,extrainfo); /* arg 1 */
75 if (lua_pcall(L, 1, 0, 0) != 0) {
76 fprintf(stdout, "error: %s\n", lua_tostring(L, -1));
77 lua_settop(L, s_top);
78 error();
79 return;
81 lua_settop(L, s_top);
82 return;
86 @ @c
87 void
88 lua_node_filter(int filterid, int extrainfo, halfword head_node, halfword * tail_node)
90 halfword ret;
91 int a;
92 lua_State *L = Luas;
93 int s_top = lua_gettop(L);
94 int callback_id = callback_defined(filterid);
95 if (head_node == null || vlink(head_node) == null || callback_id <= 0) {
96 lua_settop(L, s_top);
97 return;
99 if (!get_callback(L, callback_id)) {
100 lua_settop(L, s_top);
101 return;
103 alink(vlink(head_node)) = null ; /* hh-ls */
104 nodelist_to_lua(L, vlink(head_node)); /* arg 1 */
105 lua_push_group_code(L,extrainfo); /* arg 2 */
106 if (lua_pcall(L, 2, 1, 0) != 0) { /* no arg, 1 result */
107 fprintf(stdout, "error: %s\n", lua_tostring(L, -1));
108 lua_settop(L, s_top);
109 error();
110 return;
112 if (lua_isboolean(L, -1)) {
113 if (lua_toboolean(L, -1) != 1) {
114 flush_node_list(vlink(head_node));
115 vlink(head_node) = null;
117 } else {
118 a = nodelist_from_lua(L);
119 try_couple_nodes(head_node,a);
121 lua_pop(L, 2); /* result and callback container table */
122 if (fix_node_lists)
123 fix_node_list(head_node);
124 ret = vlink(head_node);
125 if (ret != null) {
126 while (vlink(ret) != null)
127 ret = vlink(ret);
128 *tail_node = ret;
129 } else {
130 *tail_node = head_node;
132 lua_settop(L, s_top);
133 return;
136 @ @c
138 lua_linebreak_callback(int is_broken, halfword head_node, halfword * new_head)
140 int a;
141 register halfword *p;
142 int ret = 0; /* failure */
143 lua_State *L = Luas;
144 int s_top = lua_gettop(L);
145 int callback_id = callback_defined(linebreak_filter_callback);
146 if (head_node == null || vlink(head_node) == null || callback_id <= 0) {
147 lua_settop(L, s_top);
148 return ret;
150 if (!get_callback(L, callback_id)) {
151 lua_settop(L, s_top);
152 return ret;
154 alink(vlink(head_node)) = null ; /* hh-ls */
155 nodelist_to_lua(L, vlink(head_node)); /* arg 1 */
156 lua_pushboolean(L, is_broken); /* arg 2 */
157 if (lua_pcall(L, 2, 1, 0) != 0) { /* no arg, 1 result */
158 fprintf(stdout, "error: %s\n", lua_tostring(L, -1));
159 lua_settop(L, s_top);
160 error();
161 return ret;
164 p = lua_touserdata(L, -1);
165 if (p != NULL) {
166 a = nodelist_from_lua(L);
167 try_couple_nodes(*new_head,a);
168 ret = 1;
170 lua_settop(L, s_top);
171 return ret;
176 @ @c
177 halfword
178 lua_hpack_filter(halfword head_node, scaled size, int pack_type, int extrainfo,
179 int pack_direction)
181 halfword ret;
182 lua_State *L = Luas;
183 int s_top = lua_gettop(L);
184 int callback_id = callback_defined(hpack_filter_callback);
185 if (head_node == null || callback_id <= 0) {
186 lua_settop(L, s_top);
187 return head_node;
189 if (!get_callback(L, callback_id)) {
190 lua_settop(L, s_top);
191 return head_node;
193 alink(head_node) = null ; /* hh-ls */
194 nodelist_to_lua(L, head_node);
195 lua_push_group_code(L,extrainfo);
196 lua_pushnumber(L, size);
197 lua_push_pack_type(L,pack_type);
198 if (pack_direction >= 0)
199 lua_push_dir_par(L, pack_direction);
200 else
201 lua_pushnil(L);
202 if (lua_pcall(L, 5, 1, 0) != 0) { /* no arg, 1 result */
203 fprintf(stdout, "error: %s\n", lua_tostring(L, -1));
204 lua_settop(L, s_top);
205 error();
206 return head_node;
208 ret = head_node;
209 if (lua_isboolean(L, -1)) {
210 if (lua_toboolean(L, -1) != 1) {
211 flush_node_list(head_node);
212 ret = null;
214 } else {
215 ret = nodelist_from_lua(L);
217 lua_settop(L, s_top);
218 #if 0
219 lua_gc(L,LUA_GCSTEP, LUA_GC_STEP_SIZE);
220 #endif
221 if (fix_node_lists)
222 fix_node_list(ret);
223 return ret;
226 @ @c
227 halfword
228 lua_vpack_filter(halfword head_node, scaled size, int pack_type, scaled maxd,
229 int extrainfo, int pack_direction)
231 halfword ret;
232 int callback_id;
233 lua_State *L = Luas;
234 int s_top = lua_gettop(L);
235 if (head_node == null) {
236 lua_settop(L, s_top);
237 return head_node;
239 if (extrainfo == 8) { /* output */
240 callback_id = callback_defined(pre_output_filter_callback);
241 } else {
242 callback_id = callback_defined(vpack_filter_callback);
244 if (callback_id <= 0) {
245 lua_settop(L, s_top);
246 return head_node;
248 if (!get_callback(L, callback_id)) {
249 lua_settop(L, s_top);
250 return head_node;
252 alink(head_node) = null ; /* hh-ls */
253 nodelist_to_lua(L, head_node);
254 lua_push_group_code(L,extrainfo);
255 lua_pushnumber(L, size);
256 lua_push_pack_type(L,pack_type);
257 lua_pushnumber(L, maxd);
258 if (pack_direction >= 0)
259 lua_push_dir_par(L, pack_direction);
260 else
261 lua_pushnil(L);
262 if (lua_pcall(L, 6, 1, 0) != 0) { /* no arg, 1 result */
263 fprintf(stdout, "error: %s\n", lua_tostring(L, -1));
264 lua_settop(L, s_top);
265 error();
266 return head_node;
268 ret = head_node;
269 if (lua_isboolean(L, -1)) {
270 if (lua_toboolean(L, -1) != 1) {
271 flush_node_list(head_node);
272 ret = null;
274 } else {
275 ret = nodelist_from_lua(L);
277 lua_settop(L, s_top);
278 #if 0
279 lua_gc(L,LUA_GCSTEP, LUA_GC_STEP_SIZE);
280 #endif
281 if (fix_node_lists)
282 fix_node_list(ret);
283 return ret;
287 @ This is a quick hack to fix etex's \.{\\lastnodetype} now that
288 there are many more visible node types. TODO: check the
289 eTeX manual for the expected return values.
292 int visible_last_node_type(int n)
294 int i = type(n);
295 if (i == whatsit_node && subtype(n) == local_par_node)
296 return -1;
297 if (i == glyph_node) {
298 if (is_ligature(n))
299 return 7; /* old ligature value */
300 else
301 return 0; /* old character value */
303 if (i <= unset_node) {
304 return i + 1;
305 } else if (i <= delim_node) {
306 return 15; /* so-called math nodes */
307 } else {
308 return -1;
312 @ @c
313 void lua_pdf_literal(PDF pdf, int i)
315 const char *s = NULL;
316 size_t l = 0;
317 lua_rawgeti(Luas, LUA_REGISTRYINDEX, i);
318 s = lua_tolstring(Luas, -1, &l);
319 pdf_out_block(pdf, s, l);
320 pdf_out(pdf, 10); /* |pdf_print_nl| */
321 lua_pop(Luas, 1);
324 @ @c
325 void copy_pdf_literal(pointer r, pointer p)
327 pdf_literal_type(r) = pdf_literal_type(p);
328 pdf_literal_mode(r) = pdf_literal_mode(p);
329 if (pdf_literal_type(p) == normal) {
330 pdf_literal_data(r) = pdf_literal_data(p);
331 add_token_ref(pdf_literal_data(p));
332 } else {
333 lua_rawgeti(Luas, LUA_REGISTRYINDEX, pdf_literal_data(p));
334 pdf_literal_data(r) = luaL_ref(Luas, LUA_REGISTRYINDEX);
338 @ @c
339 void copy_late_lua(pointer r, pointer p)
341 late_lua_type(r) = late_lua_type(p);
342 if (late_lua_name(p) > 0)
343 add_token_ref(late_lua_name(p));
344 if (late_lua_type(p) == normal) {
345 late_lua_data(r) = late_lua_data(p);
346 add_token_ref(late_lua_data(p));
347 } else {
348 lua_rawgeti(Luas, LUA_REGISTRYINDEX, late_lua_data(p));
349 late_lua_data(r) = luaL_ref(Luas, LUA_REGISTRYINDEX);
353 @ @c
354 void copy_user_lua(pointer r, pointer p)
356 if (user_node_value(p) != 0) {
357 lua_rawgeti(Luas, LUA_REGISTRYINDEX, user_node_value(p));
358 user_node_value(r) = luaL_ref(Luas, LUA_REGISTRYINDEX);
363 @ @c
364 void free_pdf_literal(pointer p)
366 if (pdf_literal_type(p) == normal) {
367 delete_token_ref(pdf_literal_data(p));
368 } else {
369 luaL_unref(Luas, LUA_REGISTRYINDEX, pdf_literal_data(p));
373 void free_late_lua(pointer p)
375 if (late_lua_name(p) > 0)
376 delete_token_ref(late_lua_name(p));
377 if (late_lua_type(p) == normal) {
378 delete_token_ref(late_lua_data(p));
379 } else {
380 luaL_unref(Luas, LUA_REGISTRYINDEX, late_lua_data(p));
384 @ @c
385 void free_user_lua(pointer p)
387 if (user_node_value(p) != 0) {
388 luaL_unref(Luas, LUA_REGISTRYINDEX, user_node_value(p));
393 @ @c
394 void show_pdf_literal(pointer p)
396 tprint_esc("pdfliteral");
397 switch (pdf_literal_mode(p)) {
398 case set_origin:
399 break;
400 case direct_page:
401 tprint(" page");
402 break;
403 case direct_always:
404 tprint(" direct");
405 break;
406 default:
407 confusion("literal2");
408 break;
410 if (pdf_literal_type(p) == normal) {
411 print_mark(pdf_literal_data(p));
412 } else {
413 lua_rawgeti(Luas, LUA_REGISTRYINDEX, pdf_literal_data(p));
414 tprint("\"");
415 tprint(lua_tostring(Luas, -1));
416 tprint("\"");
417 lua_pop(Luas, 1);
421 @ @c
422 void show_late_lua(pointer p)
424 tprint_esc("latelua");
425 print_int(late_lua_reg(p));
426 if (late_lua_type(p) == normal) {
427 print_mark(late_lua_data(p));
428 } else {
429 tprint(" <function ");
430 print_int(late_lua_data(p));
431 tprint(">");