1% luanode.w 2% 3% Copyright 2006-2008 Taco Hoekwater <taco@@luatex.org> 4% 5% This file is part of LuaTeX. 6% 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. 11% 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. 16% 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/>. 19 20/* hh-ls: we make sure that lua never sees prev of head but also that when 21nodes are removedor inserted, temp nodes don't interfere */ 22 23@ @c 24 25 26#include "ptexlib.h" 27#include "lua/luatex-api.h" 28 29/* TO BE REMOVED 30static 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" 54}; 55 56const char *pack_type_name[] = { "exactly", "additional" }; 57*/ 58 59@ @c 60void 61lua_node_filter_s(int filterid, int extrainfo) 62{ 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; 69 } 70 if (!get_callback(L, callback_id)) { 71 lua_settop(L, s_top); 72 return; 73 } 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; 80 } 81 lua_settop(L, s_top); 82 return; 83} 84 85 86@ @c 87void 88lua_node_filter(int filterid, int extrainfo, halfword head_node, halfword * tail_node) 89{ 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; 98 } 99 if (!get_callback(L, callback_id)) { 100 lua_settop(L, s_top); 101 return; 102 } 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; 111 } 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; 116 } 117 } else { 118 a = nodelist_from_lua(L); 119 try_couple_nodes(head_node,a); 120 } 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; 131 } 132 lua_settop(L, s_top); 133 return; 134} 135 136@ @c 137int 138lua_linebreak_callback(int is_broken, halfword head_node, halfword * new_head) 139{ 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; 149 } 150 if (!get_callback(L, callback_id)) { 151 lua_settop(L, s_top); 152 return ret; 153 } 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; 162 } 163 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; 169 } 170 lua_settop(L, s_top); 171 return ret; 172} 173 174 175 176@ @c 177halfword 178lua_hpack_filter(halfword head_node, scaled size, int pack_type, int extrainfo, 179 int pack_direction) 180{ 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; 188 } 189 if (!get_callback(L, callback_id)) { 190 lua_settop(L, s_top); 191 return head_node; 192 } 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; 207 } 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; 213 } 214 } else { 215 ret = nodelist_from_lua(L); 216 } 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; 224} 225 226@ @c 227halfword 228lua_vpack_filter(halfword head_node, scaled size, int pack_type, scaled maxd, 229 int extrainfo, int pack_direction) 230{ 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; 238 } 239 if (extrainfo == 8) { /* output */ 240 callback_id = callback_defined(pre_output_filter_callback); 241 } else { 242 callback_id = callback_defined(vpack_filter_callback); 243 } 244 if (callback_id <= 0) { 245 lua_settop(L, s_top); 246 return head_node; 247 } 248 if (!get_callback(L, callback_id)) { 249 lua_settop(L, s_top); 250 return head_node; 251 } 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; 267 } 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; 273 } 274 } else { 275 ret = nodelist_from_lua(L); 276 } 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; 284} 285 286 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. 290 291@c 292int visible_last_node_type(int n) 293{ 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 */ 302 } 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; 309 } 310} 311 312@ @c 313void lua_pdf_literal(PDF pdf, int i) 314{ 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); 322} 323 324@ @c 325void copy_pdf_literal(pointer r, pointer p) 326{ 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); 335 } 336} 337 338@ @c 339void copy_late_lua(pointer r, pointer p) 340{ 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); 350 } 351} 352 353@ @c 354void copy_user_lua(pointer r, pointer p) 355{ 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); 359 } 360} 361 362 363@ @c 364void free_pdf_literal(pointer p) 365{ 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)); 370 } 371} 372 373void free_late_lua(pointer p) 374{ 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)); 381 } 382} 383 384@ @c 385void free_user_lua(pointer p) 386{ 387 if (user_node_value(p) != 0) { 388 luaL_unref(Luas, LUA_REGISTRYINDEX, user_node_value(p)); 389 } 390} 391 392 393@ @c 394void show_pdf_literal(pointer p) 395{ 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; 409 } 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); 418 } 419} 420 421@ @c 422void show_late_lua(pointer p) 423{ 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(">"); 432 } 433} 434