sync with experimental
[luatex.git] / source / texk / web2c / luatexdir / lua / luanode.w
blobde57e6cff04acdb1a1882d0986444d17784d447e
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
24 static const char _svn_version[] =
25 "$Id$"
26 "$URL$";
28 #include "ptexlib.h"
29 #include "lua/luatex-api.h"
31 /* TO BE REMOVED
32 static const char *group_code_names[] = {
33 "",
34 "simple",
35 "hbox",
36 "adjusted_hbox",
37 "vbox",
38 "vtop",
39 "align",
40 "no_align",
41 "output",
42 "math",
43 "disc",
44 "insert",
45 "vcenter",
46 "math_choice",
47 "semi_simple",
48 "math_shift",
49 "math_left",
50 "local_box",
51 "split_off",
52 "split_keep",
53 "preamble",
54 "align_set",
55 "fin_row"
58 const char *pack_type_name[] = { "exactly", "additional" };
61 @ @c
62 void
63 lua_node_filter_s(int filterid, int extrainfo)
65 lua_State *L = Luas;
66 int callback_id = callback_defined(filterid);
67 int s_top = lua_gettop(L);
68 if (callback_id <= 0) {
69 lua_settop(L, s_top);
70 return;
72 if (!get_callback(L, callback_id)) {
73 lua_settop(L, s_top);
74 return;
76 lua_push_string_by_index(L,extrainfo); /* arg 1 */
77 if (lua_pcall(L, 1, 0, 0) != 0) {
78 fprintf(stdout, "error: %s\n", lua_tostring(L, -1));
79 lua_settop(L, s_top);
80 error();
81 return;
83 lua_settop(L, s_top);
84 return;
88 @ @c
89 void
90 lua_node_filter(int filterid, int extrainfo, halfword head_node, halfword * tail_node)
92 halfword ret;
93 int a;
94 lua_State *L = Luas;
95 int s_top = lua_gettop(L);
96 int callback_id = callback_defined(filterid);
97 if (head_node == null || vlink(head_node) == null || callback_id <= 0) {
98 lua_settop(L, s_top);
99 return;
101 if (!get_callback(L, callback_id)) {
102 lua_settop(L, s_top);
103 return;
105 alink(vlink(head_node)) = null ; /* hh-ls */
106 nodelist_to_lua(L, vlink(head_node)); /* arg 1 */
107 lua_push_group_code(L,extrainfo); /* arg 2 */
108 if (lua_pcall(L, 2, 1, 0) != 0) { /* no arg, 1 result */
109 fprintf(stdout, "error: %s\n", lua_tostring(L, -1));
110 lua_settop(L, s_top);
111 error();
112 return;
114 if (lua_isboolean(L, -1)) {
115 if (lua_toboolean(L, -1) != 1) {
116 flush_node_list(vlink(head_node));
117 vlink(head_node) = null;
119 } else {
120 a = nodelist_from_lua(L);
121 try_couple_nodes(head_node,a);
123 lua_pop(L, 2); /* result and callback container table */
124 if (fix_node_lists)
125 fix_node_list(head_node);
126 ret = vlink(head_node);
127 if (ret != null) {
128 while (vlink(ret) != null)
129 ret = vlink(ret);
130 *tail_node = ret;
131 } else {
132 *tail_node = head_node;
134 lua_settop(L, s_top);
135 return;
138 @ @c
140 lua_linebreak_callback(int is_broken, halfword head_node, halfword * new_head)
142 int a;
143 register halfword *p;
144 int ret = 0; /* failure */
145 lua_State *L = Luas;
146 int s_top = lua_gettop(L);
147 int callback_id = callback_defined(linebreak_filter_callback);
148 if (head_node == null || vlink(head_node) == null || callback_id <= 0) {
149 lua_settop(L, s_top);
150 return ret;
152 if (!get_callback(L, callback_id)) {
153 lua_settop(L, s_top);
154 return ret;
156 alink(vlink(head_node)) = null ; /* hh-ls */
157 nodelist_to_lua(L, vlink(head_node)); /* arg 1 */
158 lua_pushboolean(L, is_broken); /* arg 2 */
159 if (lua_pcall(L, 2, 1, 0) != 0) { /* no arg, 1 result */
160 fprintf(stdout, "error: %s\n", lua_tostring(L, -1));
161 lua_settop(L, s_top);
162 error();
163 return ret;
166 p = lua_touserdata(L, -1);
167 if (p != NULL) {
168 a = nodelist_from_lua(L);
169 try_couple_nodes(*new_head,a);
170 ret = 1;
172 lua_settop(L, s_top);
173 return ret;
178 @ @c
179 halfword
180 lua_hpack_filter(halfword head_node, scaled size, int pack_type, int extrainfo,
181 int pack_direction)
183 halfword ret;
184 lua_State *L = Luas;
185 int s_top = lua_gettop(L);
186 int callback_id = callback_defined(hpack_filter_callback);
187 if (head_node == null || callback_id <= 0) {
188 lua_settop(L, s_top);
189 return head_node;
191 if (!get_callback(L, callback_id)) {
192 lua_settop(L, s_top);
193 return head_node;
195 alink(head_node) = null ; /* hh-ls */
196 nodelist_to_lua(L, head_node);
197 lua_push_group_code(L,extrainfo);
198 lua_pushnumber(L, size);
199 lua_push_pack_type(L,pack_type);
200 if (pack_direction >= 0)
201 lua_push_dir_par(L, pack_direction);
202 else
203 lua_pushnil(L);
204 if (lua_pcall(L, 5, 1, 0) != 0) { /* no arg, 1 result */
205 fprintf(stdout, "error: %s\n", lua_tostring(L, -1));
206 lua_settop(L, s_top);
207 error();
208 return head_node;
210 ret = head_node;
211 if (lua_isboolean(L, -1)) {
212 if (lua_toboolean(L, -1) != 1) {
213 flush_node_list(head_node);
214 ret = null;
216 } else {
217 ret = nodelist_from_lua(L);
219 lua_settop(L, s_top);
220 #if 0
221 lua_gc(L,LUA_GCSTEP, LUA_GC_STEP_SIZE);
222 #endif
223 if (fix_node_lists)
224 fix_node_list(ret);
225 return ret;
228 @ @c
229 halfword
230 lua_vpack_filter(halfword head_node, scaled size, int pack_type, scaled maxd,
231 int extrainfo, int pack_direction)
233 halfword ret;
234 int callback_id;
235 lua_State *L = Luas;
236 int s_top = lua_gettop(L);
237 if (head_node == null) {
238 lua_settop(L, s_top);
239 return head_node;
241 if (extrainfo == 8) { /* output */
242 callback_id = callback_defined(pre_output_filter_callback);
243 } else {
244 callback_id = callback_defined(vpack_filter_callback);
246 if (callback_id <= 0) {
247 lua_settop(L, s_top);
248 return head_node;
250 if (!get_callback(L, callback_id)) {
251 lua_settop(L, s_top);
252 return head_node;
254 alink(head_node) = null ; /* hh-ls */
255 nodelist_to_lua(L, head_node);
256 lua_push_group_code(L,extrainfo);
257 lua_pushnumber(L, size);
258 lua_push_pack_type(L,pack_type);
259 lua_pushnumber(L, maxd);
260 if (pack_direction >= 0)
261 lua_push_dir_par(L, pack_direction);
262 else
263 lua_pushnil(L);
264 if (lua_pcall(L, 6, 1, 0) != 0) { /* no arg, 1 result */
265 fprintf(stdout, "error: %s\n", lua_tostring(L, -1));
266 lua_settop(L, s_top);
267 error();
268 return head_node;
270 ret = head_node;
271 if (lua_isboolean(L, -1)) {
272 if (lua_toboolean(L, -1) != 1) {
273 flush_node_list(head_node);
274 ret = null;
276 } else {
277 ret = nodelist_from_lua(L);
279 lua_settop(L, s_top);
280 #if 0
281 lua_gc(L,LUA_GCSTEP, LUA_GC_STEP_SIZE);
282 #endif
283 if (fix_node_lists)
284 fix_node_list(ret);
285 return ret;
289 @ This is a quick hack to fix etex's \.{\\lastnodetype} now that
290 there are many more visible node types. TODO: check the
291 eTeX manual for the expected return values.
294 int visible_last_node_type(int n)
296 int i = type(n);
297 if (i == whatsit_node && subtype(n) == local_par_node)
298 return -1;
299 if (i == glyph_node) {
300 if (is_ligature(n))
301 return 7; /* old ligature value */
302 else
303 return 0; /* old character value */
305 if (i <= unset_node) {
306 return i + 1;
307 } else if (i <= delim_node) {
308 return 15; /* so-called math nodes */
309 } else {
310 return -1;
314 @ @c
315 void lua_pdf_literal(PDF pdf, int i)
317 const char *s = NULL;
318 size_t l = 0;
319 lua_rawgeti(Luas, LUA_REGISTRYINDEX, i);
320 s = lua_tolstring(Luas, -1, &l);
321 pdf_out_block(pdf, s, l);
322 pdf_out(pdf, 10); /* |pdf_print_nl| */
323 lua_pop(Luas, 1);
326 @ @c
327 void copy_pdf_literal(pointer r, pointer p)
329 pdf_literal_type(r) = pdf_literal_type(p);
330 pdf_literal_mode(r) = pdf_literal_mode(p);
331 if (pdf_literal_type(p) == normal) {
332 pdf_literal_data(r) = pdf_literal_data(p);
333 add_token_ref(pdf_literal_data(p));
334 } else {
335 lua_rawgeti(Luas, LUA_REGISTRYINDEX, pdf_literal_data(p));
336 pdf_literal_data(r) = luaL_ref(Luas, LUA_REGISTRYINDEX);
340 @ @c
341 void copy_late_lua(pointer r, pointer p)
343 late_lua_type(r) = late_lua_type(p);
344 if (late_lua_name(p) > 0)
345 add_token_ref(late_lua_name(p));
346 if (late_lua_type(p) == normal) {
347 late_lua_data(r) = late_lua_data(p);
348 add_token_ref(late_lua_data(p));
349 } else {
350 lua_rawgeti(Luas, LUA_REGISTRYINDEX, late_lua_data(p));
351 late_lua_data(r) = luaL_ref(Luas, LUA_REGISTRYINDEX);
355 @ @c
356 void copy_user_lua(pointer r, pointer p)
358 if (user_node_value(p) != 0) {
359 lua_rawgeti(Luas, LUA_REGISTRYINDEX, user_node_value(p));
360 user_node_value(r) = luaL_ref(Luas, LUA_REGISTRYINDEX);
365 @ @c
366 void free_pdf_literal(pointer p)
368 if (pdf_literal_type(p) == normal) {
369 delete_token_ref(pdf_literal_data(p));
370 } else {
371 luaL_unref(Luas, LUA_REGISTRYINDEX, pdf_literal_data(p));
375 void free_late_lua(pointer p)
377 if (late_lua_name(p) > 0)
378 delete_token_ref(late_lua_name(p));
379 if (late_lua_type(p) == normal) {
380 delete_token_ref(late_lua_data(p));
381 } else {
382 luaL_unref(Luas, LUA_REGISTRYINDEX, late_lua_data(p));
386 @ @c
387 void free_user_lua(pointer p)
389 if (user_node_value(p) != 0) {
390 luaL_unref(Luas, LUA_REGISTRYINDEX, user_node_value(p));
395 @ @c
396 void show_pdf_literal(pointer p)
398 tprint_esc("pdfliteral");
399 switch (pdf_literal_mode(p)) {
400 case set_origin:
401 break;
402 case direct_page:
403 tprint(" page");
404 break;
405 case direct_always:
406 tprint(" direct");
407 break;
408 default:
409 confusion("literal2");
410 break;
412 if (pdf_literal_type(p) == normal) {
413 print_mark(pdf_literal_data(p));
414 } else {
415 lua_rawgeti(Luas, LUA_REGISTRYINDEX, pdf_literal_data(p));
416 tprint("\"");
417 tprint(lua_tostring(Luas, -1));
418 tprint("\"");
419 lua_pop(Luas, 1);
423 void show_late_lua(pointer p)
425 tprint_esc("latelua");
426 print_int(late_lua_reg(p));
427 if (late_lua_type(p) == normal) {
428 print_mark(late_lua_data(p));
429 } else {
430 lua_rawgeti(Luas, LUA_REGISTRYINDEX, late_lua_data(p));
431 tprint("\"");
432 tprint(lua_tostring(Luas, -1));
433 tprint("\"");
434 lua_pop(Luas, 1);