beta-0.89.2
[luatex.git] / source / texk / web2c / luatexdir / lua / luanode.w
blobbd328b8c2f2a80942150cc4809975f38cd255b8a
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 removed or inserted, temp nodes don't interfere */
23 @ @c
25 #include "ptexlib.h"
26 #include "lua/luatex-api.h"
28 @ @c
29 void lua_node_filter_s(int filterid, int extrainfo)
31 lua_State *L = Luas;
32 int callback_id = callback_defined(filterid);
33 int s_top = lua_gettop(L);
34 if (callback_id <= 0) {
35 lua_settop(L, s_top);
36 return;
38 if (!get_callback(L, callback_id)) {
39 lua_settop(L, s_top);
40 return;
42 lua_push_string_by_index(L,extrainfo); /* arg 1 */
43 if (lua_pcall(L, 1, 0, 0) != 0) {
44 fprintf(stdout, "error: %s\n", lua_tostring(L, -1));
45 lua_settop(L, s_top);
46 error();
47 return;
49 lua_settop(L, s_top);
50 return;
53 @ @c
54 void lua_node_filter(int filterid, int extrainfo, halfword head_node, halfword * tail_node)
56 halfword ret;
57 int a;
58 lua_State *L = Luas;
59 int s_top = lua_gettop(L);
60 int callback_id = callback_defined(filterid);
61 if (head_node == null || vlink(head_node) == null || callback_id <= 0) {
62 lua_settop(L, s_top);
63 return;
65 if (!get_callback(L, callback_id)) {
66 lua_settop(L, s_top);
67 return;
69 alink(vlink(head_node)) = null ; /* hh-ls */
70 nodelist_to_lua(L, vlink(head_node)); /* arg 1 */
71 lua_push_group_code(L,extrainfo); /* arg 2 */
72 if (lua_pcall(L, 2, 1, 0) != 0) { /* no arg, 1 result */
73 fprintf(stdout, "error: %s\n", lua_tostring(L, -1));
74 lua_settop(L, s_top);
75 error();
76 return;
78 if (lua_isboolean(L, -1)) {
79 if (lua_toboolean(L, -1) != 1) {
80 flush_node_list(vlink(head_node));
81 vlink(head_node) = null;
83 } else {
84 a = nodelist_from_lua(L);
85 try_couple_nodes(head_node,a);
87 lua_pop(L, 2); /* result and callback container table */
88 if (fix_node_lists)
89 fix_node_list(head_node);
90 ret = vlink(head_node);
91 if (ret != null) {
92 while (vlink(ret) != null)
93 ret = vlink(ret);
94 *tail_node = ret;
95 } else {
96 *tail_node = head_node;
98 lua_settop(L, s_top);
99 return;
102 @ @c
103 int lua_linebreak_callback(int is_broken, halfword head_node, halfword * new_head)
105 int a;
106 register halfword *p;
107 int ret = 0; /* failure */
108 lua_State *L = Luas;
109 int s_top = lua_gettop(L);
110 int callback_id = callback_defined(linebreak_filter_callback);
111 if (head_node == null || vlink(head_node) == null || callback_id <= 0) {
112 lua_settop(L, s_top);
113 return ret;
115 if (!get_callback(L, callback_id)) {
116 lua_settop(L, s_top);
117 return ret;
119 alink(vlink(head_node)) = null ; /* hh-ls */
120 nodelist_to_lua(L, vlink(head_node)); /* arg 1 */
121 lua_pushboolean(L, is_broken); /* arg 2 */
122 if (lua_pcall(L, 2, 1, 0) != 0) { /* no arg, 1 result */
123 fprintf(stdout, "error: %s\n", lua_tostring(L, -1));
124 lua_settop(L, s_top);
125 error();
126 return ret;
128 p = lua_touserdata(L, -1);
129 if (p != NULL) {
130 a = nodelist_from_lua(L);
131 try_couple_nodes(*new_head,a);
132 ret = 1;
134 lua_settop(L, s_top);
135 return ret;
138 @ @c
139 int lua_appendtovlist_callback(halfword box, int location, halfword prev_depth, boolean is_mirrored, halfword * result, int * next_depth, boolean * prev_set)
141 register halfword *p;
142 lua_State *L = Luas;
143 int s_top = lua_gettop(L);
144 int callback_id = callback_defined(append_to_vlist_filter_callback);
145 if (box == null || callback_id <= 0) {
146 lua_settop(L, s_top);
147 return 0;
149 if (!get_callback(L, callback_id)) {
150 lua_settop(L, s_top);
151 return 0;
153 nodelist_to_lua(L, box);
154 lua_push_string_by_index(L,location);
155 lua_pushinteger(L, (int) prev_depth);
156 lua_pushboolean(L, is_mirrored);
157 if (lua_pcall(L, 4, 2, 0) != 0) {
158 fprintf(stdout, "error: %s\n", lua_tostring(L, -1));
159 lua_settop(L, s_top);
160 error();
161 return 0;
163 if (lua_type(L,-1) == LUA_TNUMBER) {
164 *next_depth = lua_tointeger(L,-1);
165 *prev_set = true;
166 if (lua_type(L, -2) != LUA_TNIL) {
167 p = check_isnode(L, -2);
168 *result = *p;
170 } else if (lua_type(L, -1) != LUA_TNIL) {
171 p = check_isnode(L, -1);
172 *result = *p;
174 lua_settop(L, s_top);
175 return 1;
178 @ @c
179 halfword lua_hpack_filter(halfword head_node, scaled size, int pack_type, int extrainfo, 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_pushinteger(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 lua_vpack_filter(halfword head_node, scaled size, int pack_type, scaled maxd,
228 int extrainfo, int pack_direction)
230 halfword ret;
231 int callback_id;
232 lua_State *L = Luas;
233 int s_top = lua_gettop(L);
234 if (head_node == null) {
235 lua_settop(L, s_top);
236 return head_node;
238 if (extrainfo == 8) { /* output */
239 callback_id = callback_defined(pre_output_filter_callback);
240 } else {
241 callback_id = callback_defined(vpack_filter_callback);
243 if (callback_id <= 0) {
244 lua_settop(L, s_top);
245 return head_node;
247 if (!get_callback(L, callback_id)) {
248 lua_settop(L, s_top);
249 return head_node;
251 alink(head_node) = null ; /* hh-ls */
252 nodelist_to_lua(L, head_node);
253 lua_push_group_code(L,extrainfo);
254 lua_pushinteger(L, size);
255 lua_push_pack_type(L,pack_type);
256 lua_pushinteger(L, maxd);
257 if (pack_direction >= 0)
258 lua_push_dir_par(L, pack_direction);
259 else
260 lua_pushnil(L);
261 if (lua_pcall(L, 6, 1, 0) != 0) { /* no arg, 1 result */
262 fprintf(stdout, "error: %s\n", lua_tostring(L, -1));
263 lua_settop(L, s_top);
264 error();
265 return head_node;
267 ret = head_node;
268 if (lua_isboolean(L, -1)) {
269 if (lua_toboolean(L, -1) != 1) {
270 flush_node_list(head_node);
271 ret = null;
273 } else {
274 ret = nodelist_from_lua(L);
276 lua_settop(L, s_top);
277 #if 0
278 lua_gc(L,LUA_GCSTEP, LUA_GC_STEP_SIZE);
279 #endif
280 if (fix_node_lists)
281 fix_node_list(ret);
282 return ret;
285 @ This is a quick hack to fix etex's \.{\\lastnodetype} now that
286 there are many more visible node types. TODO: check the
287 eTeX manual for the expected return values.
290 int visible_last_node_type(int n)
292 int i = type(n);
293 if (i != glyph_node) {
294 return get_etex_code(i);
295 } else if (is_ligature(n)) {
296 return 7; /* old ligature value */
297 } else {
298 return 0; /* old character value */
302 @ @c
303 void lua_pdf_literal(PDF pdf, int i)
305 const char *s = NULL;
306 size_t l = 0;
307 lua_rawgeti(Luas, LUA_REGISTRYINDEX, i);
308 s = lua_tolstring(Luas, -1, &l);
309 pdf_out_block(pdf, s, l);
310 pdf_out(pdf, 10); /* |pdf_print_nl| */
311 lua_pop(Luas, 1);
314 @ @c
315 void copy_pdf_literal(pointer r, pointer p)
317 pdf_literal_type(r) = pdf_literal_type(p);
318 pdf_literal_mode(r) = pdf_literal_mode(p);
319 if (pdf_literal_type(p) == normal) {
320 pdf_literal_data(r) = pdf_literal_data(p);
321 add_token_ref(pdf_literal_data(p));
322 } else {
323 lua_rawgeti(Luas, LUA_REGISTRYINDEX, pdf_literal_data(p));
324 pdf_literal_data(r) = luaL_ref(Luas, LUA_REGISTRYINDEX);
328 @ @c
329 void copy_late_lua(pointer r, pointer p)
331 late_lua_type(r) = late_lua_type(p);
332 if (late_lua_name(p) > 0)
333 add_token_ref(late_lua_name(p));
334 if (late_lua_type(p) == normal) {
335 late_lua_data(r) = late_lua_data(p);
336 add_token_ref(late_lua_data(p));
337 } else {
338 lua_rawgeti(Luas, LUA_REGISTRYINDEX, late_lua_data(p));
339 late_lua_data(r) = luaL_ref(Luas, LUA_REGISTRYINDEX);
343 @ @c
344 void copy_user_lua(pointer r, pointer p)
346 if (user_node_value(p) != 0) {
347 lua_rawgeti(Luas, LUA_REGISTRYINDEX, user_node_value(p));
348 user_node_value(r) = luaL_ref(Luas, LUA_REGISTRYINDEX);
352 @ @c
353 void free_pdf_literal(pointer p)
355 if (pdf_literal_type(p) == normal) {
356 delete_token_ref(pdf_literal_data(p));
357 } else {
358 luaL_unref(Luas, LUA_REGISTRYINDEX, pdf_literal_data(p));
362 void free_late_lua(pointer p)
364 if (late_lua_name(p) > 0)
365 delete_token_ref(late_lua_name(p));
366 if (late_lua_type(p) == normal) {
367 delete_token_ref(late_lua_data(p));
368 } else {
369 luaL_unref(Luas, LUA_REGISTRYINDEX, late_lua_data(p));
373 @ @c
374 void free_user_lua(pointer p)
376 if (user_node_value(p) != 0) {
377 luaL_unref(Luas, LUA_REGISTRYINDEX, user_node_value(p));
381 @ @c
382 void show_pdf_literal(pointer p)
384 tprint_esc("pdfliteral");
385 switch (pdf_literal_mode(p)) {
386 case set_origin:
387 break;
388 case direct_page:
389 tprint(" page");
390 break;
391 case direct_always:
392 tprint(" direct");
393 break;
394 default:
395 confusion("literal2");
396 break;
398 if (pdf_literal_type(p) == normal) {
399 print_mark(pdf_literal_data(p));
400 } else {
401 lua_rawgeti(Luas, LUA_REGISTRYINDEX, pdf_literal_data(p));
402 tprint("\"");
403 tprint(lua_tostring(Luas, -1));
404 tprint("\"");
405 lua_pop(Luas, 1);
409 @ @c
410 void show_late_lua(pointer p)
412 tprint_esc("latelua");
413 print_int(late_lua_reg(p));
414 if (late_lua_type(p) == normal) {
415 print_mark(late_lua_data(p));
416 } else {
417 tprint(" <function ");
418 print_int(late_lua_data(p));
419 tprint(">");