summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/luatexdir/lua
diff options
context:
space:
mode:
authorAkira Kakuto <kakuto@fuk.kindai.ac.jp>2014-02-11 06:15:25 +0000
committerAkira Kakuto <kakuto@fuk.kindai.ac.jp>2014-02-11 06:15:25 +0000
commitf4c24b082d377124c0e5de05766d758ec059e964 (patch)
tree28d9b3d26c084c3ff16942f387ece9c7664ebec6 /Build/source/texk/web2c/luatexdir/lua
parent0a23d9a053200b27239415d5bb3c1452a6416050 (diff)
Import from LuaTeX r4794
git-svn-id: svn://tug.org/texlive/trunk@32938 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/lua')
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/lnodelib.c32
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/ltexlib.c13
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/luanode.w829
3 files changed, 452 insertions, 422 deletions
diff --git a/Build/source/texk/web2c/luatexdir/lua/lnodelib.c b/Build/source/texk/web2c/luatexdir/lua/lnodelib.c
index 78a468a7f1c..0a62151427d 100644
--- a/Build/source/texk/web2c/luatexdir/lua/lnodelib.c
+++ b/Build/source/texk/web2c/luatexdir/lua/lnodelib.c
@@ -96,7 +96,7 @@
*/
static const char _svn_version[] =
- "$Id: lnodelib.c 4740 2014-01-09 17:22:45Z luigi $ "
+ "$Id: lnodelib.c 4775 2014-02-07 12:36:34Z luigi $ "
"$URL: https://foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/lua/lnodelib.c $";
#include "ptexlib.h"
@@ -1347,12 +1347,16 @@ static int lua_nodelib_remove(lua_State * L)
if (lua_isnil(L, 2))
return 2; /* the arguments, as they are */
current = *(check_isnode(L, 2));
-
if (head == current) {
- if (alink(head) != null && vlink(current) != null)
- alink(vlink(current)) = alink(head);
- head = vlink(current);
- current = head;
+ if (alink(current)){
+ vlink(alink(current)) = vlink(current); // vlink(prev) = next
+ }
+ if (vlink(current)){
+ alink( vlink(current)) = alink(current); // alink(next) = prev
+ }
+
+ head = vlink(current); //head = next
+ current = vlink(current); //current = next
} else { /* head != current */
t = alink(current);
if (t == null || vlink(t) != current) {
@@ -1396,10 +1400,14 @@ static int lua_nodelib_direct_remove(lua_State * L)
return 2 ;
}
if (head == current) {
- if (alink(head) != null && vlink(current) != null)
- alink(vlink(current)) = alink(head);
- head = vlink(current);
- current = head;
+ if (alink(current)){
+ vlink( alink(current) ) = vlink(current); // vlink(prev) = next
+ }
+ if (vlink(current)){
+ alink( vlink(current) ) = alink(current); // alink(next) = prev
+ }
+ head = vlink(current); //head = next
+ current = vlink(current); //current = next
} else {
t = alink(current);
if (t == null || vlink(t) != current) {
@@ -2003,6 +2011,7 @@ static int lua_nodelib_mlist_to_hlist(lua_State * L)
luaL_checkany(L, 3);
m = lua_toboolean(L, 3);
mlist_to_hlist_args(n, w, m);
+ alink(vlink(temp_head)) = null; /*hh-ls */
lua_nodelib_push_fast(L, vlink(temp_head));
return 1;
}
@@ -4194,6 +4203,7 @@ static int font_tex_ligaturing(lua_State * L)
couple_nodes(tmp_head, *h);
tlink(tmp_head) = t;
t = handle_ligaturing(tmp_head, t);
+ alink(vlink(tmp_head)) = null ; /* hh-ls */
lua_pushnumber(L, vlink(tmp_head));
/* can be: lua_nodelib_push_fast(L, head); */
flush_node(tmp_head);
@@ -4227,6 +4237,7 @@ static int font_tex_kerning(lua_State * L)
couple_nodes(tmp_head, *h);
tlink(tmp_head) = t;
t = handle_kerning(tmp_head, t);
+ alink(vlink(tmp_head)) = null ; /* hh-ls */
lua_pushnumber(L, vlink(tmp_head));
/* can be: lua_nodelib_push_fast(L, head); */
flush_node(tmp_head);
@@ -4238,6 +4249,7 @@ static int font_tex_kerning(lua_State * L)
return 3;
}
+
/* node.protect_glyphs (returns also boolean because that signals callback) */
static int lua_nodelib_protect_glyphs(lua_State * L)
diff --git a/Build/source/texk/web2c/luatexdir/lua/ltexlib.c b/Build/source/texk/web2c/luatexdir/lua/ltexlib.c
index d448bd1aab3..cbc01ed4763 100644
--- a/Build/source/texk/web2c/luatexdir/lua/ltexlib.c
+++ b/Build/source/texk/web2c/luatexdir/lua/ltexlib.c
@@ -17,13 +17,17 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
+/* hh-ls: Because the lists start with a temp node, we have to set the prev link
+to nil because otherwise at the lua end we expose temp which can create havoc. In the
+setter no prev link is created so we can presume that it's not used later on. */
+
#include "ptexlib.h"
#include "lua/luatex-api.h"
static const char _svn_version[] =
- "$Id: ltexlib.c 4569 2013-01-30 10:08:33Z taco $ $URL: https://foundry.supelec.fr/svn/luatex/branches/ex-glyph/source/texk/web2c/luatexdir/lua/ltexlib.c $";
+ "$Id: ltexlib.c 4775 2014-02-07 12:36:34Z luigi $ $URL: https://foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/lua/ltexlib.c $";
#define attribute(A) eqtb[attribute_base+(A)].hh.rh
#define dimen(A) eqtb[scaled_base+(A)].hh.rh
@@ -1603,18 +1607,23 @@ static int getlist(lua_State * L)
lua_pushnumber(L, vlink(page_ins_head));
lua_nodelib_push(L);
} else if (strcmp(str, "contrib_head") == 0) {
+ alink(vlink(contrib_head)) = null ;
lua_pushnumber(L, vlink(contrib_head));
lua_nodelib_push(L);
} else if (strcmp(str, "page_head") == 0) {
+ alink(vlink(page_head)) = null ;/*hh-ls */
lua_pushnumber(L, vlink(page_head));
lua_nodelib_push(L);
} else if (strcmp(str, "temp_head") == 0) {
+ alink(vlink(temp_head)) = null ;/*hh-ls */
lua_pushnumber(L, vlink(temp_head));
lua_nodelib_push(L);
} else if (strcmp(str, "hold_head") == 0) {
+ alink(vlink(hold_head)) = null ;/*hh-ls */
lua_pushnumber(L, vlink(hold_head));
lua_nodelib_push(L);
} else if (strcmp(str, "adjust_head") == 0) {
+ alink(vlink(adjust_head)) = null ;/*hh-ls */
lua_pushnumber(L, vlink(adjust_head));
lua_nodelib_push(L);
} else if (strcmp(str, "best_page_break") == 0) {
@@ -1625,9 +1634,11 @@ static int getlist(lua_State * L)
} else if (strcmp(str, "best_size") == 0) {
lua_pushnumber(L, best_size);
} else if (strcmp(str, "pre_adjust_head") == 0) {
+ alink(vlink(pre_adjust_head)) = null ;/*hh-ls */
lua_pushnumber(L, vlink(pre_adjust_head));
lua_nodelib_push(L);
} else if (strcmp(str, "align_head") == 0) {
+ alink(vlink(align_head)) = null ;/*hh-ls */
lua_pushnumber(L, vlink(align_head));
lua_nodelib_push(L);
} else {
diff --git a/Build/source/texk/web2c/luatexdir/lua/luanode.w b/Build/source/texk/web2c/luatexdir/lua/luanode.w
index b7ed9fcd396..65f4c8a6310 100644
--- a/Build/source/texk/web2c/luatexdir/lua/luanode.w
+++ b/Build/source/texk/web2c/luatexdir/lua/luanode.w
@@ -1,411 +1,418 @@
-% luanode.w
-%
-% Copyright 2006-2008 Taco Hoekwater <taco@@luatex.org>
-%
-% This file is part of LuaTeX.
-%
-% LuaTeX is free software; you can redistribute it and/or modify it under
-% the terms of the GNU General Public License as published by the Free
-% Software Foundation; either version 2 of the License, or (at your
-% option) any later version.
-%
-% LuaTeX is distributed in the hope that it will be useful, but WITHOUT
-% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-% FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
-% License for more details.
-%
-% You should have received a copy of the GNU General Public License along
-% with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-
-@ @c
-static const char _svn_version[] =
- "$Id: luanode.w 4442 2012-05-25 22:40:34Z hhenkel $"
- "$URL: https://foundry.supelec.fr/svn/luatex/branches/ex-glyph/source/texk/web2c/luatexdir/lua/luanode.w $";
-
-#include "ptexlib.h"
-#include "lua/luatex-api.h"
-
-@ @c
-static const char *group_code_names[] = {
- "",
- "simple",
- "hbox",
- "adjusted_hbox",
- "vbox",
- "vtop",
- "align",
- "no_align",
- "output",
- "math",
- "disc",
- "insert",
- "vcenter",
- "math_choice",
- "semi_simple",
- "math_shift",
- "math_left",
- "local_box",
- "split_off",
- "split_keep",
- "preamble",
- "align_set",
- "fin_row"
-};
-
-const char *pack_type_name[] = { "exactly", "additional" };
-
-
-@ @c
-void lua_node_filter_s(int filterid, const char *extrainfo)
-{
- lua_State *L = Luas;
- int callback_id = callback_defined(filterid);
- int s_top = lua_gettop(L);
- if (callback_id <= 0) {
- lua_settop(L, s_top);
- return;
- }
- if (!get_callback(L, callback_id)) {
- lua_settop(L, s_top);
- return;
- }
- lua_pushstring(L, extrainfo); /* arg 1 */
- if (lua_pcall(L, 1, 0, 0) != 0) {
- fprintf(stdout, "error: %s\n", lua_tostring(L, -1));
- lua_settop(L, s_top);
- error();
- return;
- }
- lua_settop(L, s_top);
- return;
-}
-
-@ @c
-void
-lua_node_filter(int filterid, int xextrainfo, halfword head_node,
- halfword * tail_node)
-{
- halfword ret;
- int a;
- lua_State *L = Luas;
- int s_top = lua_gettop(L);
- const char *extrainfo = group_code_names[xextrainfo];
- int callback_id = callback_defined(filterid);
- if (head_node == null || vlink(head_node) == null || callback_id <= 0) {
- lua_settop(L, s_top);
- return;
- }
- if (!get_callback(L, callback_id)) {
- lua_settop(L, s_top);
- return;
- }
- nodelist_to_lua(L, vlink(head_node)); /* arg 1 */
- lua_pushstring(L, extrainfo); /* arg 2 */
- if (lua_pcall(L, 2, 1, 0) != 0) { /* no arg, 1 result */
- fprintf(stdout, "error: %s\n", lua_tostring(L, -1));
- lua_settop(L, s_top);
- error();
- return;
- }
- if (lua_isboolean(L, -1)) {
- if (lua_toboolean(L, -1) != 1) {
- flush_node_list(vlink(head_node));
- vlink(head_node) = null;
- }
- } else {
- a = nodelist_from_lua(L);
- try_couple_nodes(head_node,a);
- }
- lua_pop(L, 2); /* result and callback container table */
- if (fix_node_lists)
- fix_node_list(head_node);
- ret = vlink(head_node);
- if (ret != null) {
- while (vlink(ret) != null)
- ret = vlink(ret);
- *tail_node = ret;
- } else {
- *tail_node = head_node;
- }
- lua_settop(L, s_top);
- return;
-}
-
-
-@ @c
-int
-lua_linebreak_callback(int is_broken, halfword head_node, halfword * new_head)
-{
- int a;
- register halfword *p;
- int ret = 0; /* failure */
- lua_State *L = Luas;
- int s_top = lua_gettop(L);
- int callback_id = callback_defined(linebreak_filter_callback);
- if (head_node == null || vlink(head_node) == null || callback_id <= 0) {
- lua_settop(L, s_top);
- return ret;
- }
- if (!get_callback(L, callback_id)) {
- lua_settop(L, s_top);
- return ret;
- }
- nodelist_to_lua(L, vlink(head_node)); /* arg 1 */
- lua_pushboolean(L, is_broken); /* arg 2 */
- if (lua_pcall(L, 2, 1, 0) != 0) { /* no arg, 1 result */
- fprintf(stdout, "error: %s\n", lua_tostring(L, -1));
- lua_settop(L, s_top);
- error();
- return ret;
- }
-
- p = lua_touserdata(L, -1);
- if (p != NULL) {
- a = nodelist_from_lua(L);
- try_couple_nodes(*new_head,a);
- ret = 1;
- }
- lua_settop(L, s_top);
- return ret;
-}
-
-
-
-@ @c
-halfword
-lua_hpack_filter(halfword head_node, scaled size, int pack_type, int extrainfo,
- int pack_direction)
-{
- halfword ret;
- lua_State *L = Luas;
- int s_top = lua_gettop(L);
- int callback_id = callback_defined(hpack_filter_callback);
- if (head_node == null || callback_id <= 0) {
- lua_settop(L, s_top);
- return head_node;
- }
- if (!get_callback(L, callback_id)) {
- lua_settop(L, s_top);
- return head_node;
- }
- nodelist_to_lua(L, head_node);
- lua_pushstring(L, group_code_names[extrainfo]);
- lua_pushnumber(L, size);
- lua_pushstring(L, pack_type_name[pack_type]);
- if (pack_direction >= 0)
- lua_pushstring(L, string_dir(pack_direction));
- else
- lua_pushnil(L);
- if (lua_pcall(L, 5, 1, 0) != 0) { /* no arg, 1 result */
- fprintf(stdout, "error: %s\n", lua_tostring(L, -1));
- lua_settop(L, s_top);
- error();
- return head_node;
- }
- ret = head_node;
- if (lua_isboolean(L, -1)) {
- if (lua_toboolean(L, -1) != 1) {
- flush_node_list(head_node);
- ret = null;
- }
- } else {
- ret = nodelist_from_lua(L);
- }
- lua_settop(L, s_top);
-#if 0
- lua_gc(L,LUA_GCSTEP, LUA_GC_STEP_SIZE);
-#endif
- if (fix_node_lists)
- fix_node_list(ret);
- return ret;
-}
-
-@ @c
-halfword
-lua_vpack_filter(halfword head_node, scaled size, int pack_type, scaled maxd,
- int extrainfo, int pack_direction)
-{
- halfword ret;
- int callback_id;
- lua_State *L = Luas;
- int s_top = lua_gettop(L);
- if (head_node == null) {
- lua_settop(L, s_top);
- return head_node;
- }
- if (strcmp("output", group_code_names[extrainfo]) == 0) {
- callback_id = callback_defined(pre_output_filter_callback);
- } else {
- callback_id = callback_defined(vpack_filter_callback);
- }
- if (callback_id <= 0) {
- lua_settop(L, s_top);
- return head_node;
- }
- if (!get_callback(L, callback_id)) {
- lua_settop(L, s_top);
- return head_node;
- }
- nodelist_to_lua(L, head_node);
- lua_pushstring(L, group_code_names[extrainfo]);
- lua_pushnumber(L, size);
- lua_pushstring(L, pack_type_name[pack_type]);
- lua_pushnumber(L, maxd);
- if (pack_direction >= 0)
- lua_pushstring(L, string_dir(pack_direction));
- else
- lua_pushnil(L);
- if (lua_pcall(L, 6, 1, 0) != 0) { /* no arg, 1 result */
- fprintf(stdout, "error: %s\n", lua_tostring(L, -1));
- lua_settop(L, s_top);
- error();
- return head_node;
- }
- ret = head_node;
- if (lua_isboolean(L, -1)) {
- if (lua_toboolean(L, -1) != 1) {
- flush_node_list(head_node);
- ret = null;
- }
- } else {
- ret = nodelist_from_lua(L);
- }
- lua_settop(L, s_top);
-#if 0
- lua_gc(L,LUA_GCSTEP, LUA_GC_STEP_SIZE);
-#endif
- if (fix_node_lists)
- fix_node_list(ret);
- return ret;
-}
-
-
-@ This is a quick hack to fix etex's \.{\\lastnodetype} now that
- there are many more visible node types. TODO: check the
- eTeX manual for the expected return values.
-
-@c
-int visible_last_node_type(int n)
-{
- int i = type(n);
- if (i == whatsit_node && subtype(n) == local_par_node)
- return -1;
- if (i == glyph_node) {
- if (is_ligature(n))
- return 7; /* old ligature value */
- else
- return 0; /* old character value */
- }
- if (i <= unset_node) {
- return i + 1;
- } else if (i <= delim_node) {
- return 15; /* so-called math nodes */
- } else {
- return -1;
- }
-}
-
-@ @c
-void lua_pdf_literal(PDF pdf, int i)
-{
- const char *s = NULL;
- size_t l = 0;
- lua_rawgeti(Luas, LUA_REGISTRYINDEX, i);
- s = lua_tolstring(Luas, -1, &l);
- pdf_out_block(pdf, s, l);
- pdf_out(pdf, 10); /* |pdf_print_nl| */
- lua_pop(Luas, 1);
-}
-
-@ @c
-void copy_pdf_literal(pointer r, pointer p)
-{
- pdf_literal_type(r) = pdf_literal_type(p);
- pdf_literal_mode(r) = pdf_literal_mode(p);
- if (pdf_literal_type(p) == normal) {
- pdf_literal_data(r) = pdf_literal_data(p);
- add_token_ref(pdf_literal_data(p));
- } else {
- lua_rawgeti(Luas, LUA_REGISTRYINDEX, pdf_literal_data(p));
- pdf_literal_data(r) = luaL_ref(Luas, LUA_REGISTRYINDEX);
- }
-}
-
-void copy_late_lua(pointer r, pointer p)
-{
- late_lua_type(r) = late_lua_type(p);
- if (late_lua_name(p) > 0)
- add_token_ref(late_lua_name(p));
- if (late_lua_type(p) == normal) {
- late_lua_data(r) = late_lua_data(p);
- add_token_ref(late_lua_data(p));
- } else {
- lua_rawgeti(Luas, LUA_REGISTRYINDEX, late_lua_data(p));
- late_lua_data(r) = luaL_ref(Luas, LUA_REGISTRYINDEX);
- }
-}
-
-
-@ @c
-void free_pdf_literal(pointer p)
-{
- if (pdf_literal_type(p) == normal) {
- delete_token_ref(pdf_literal_data(p));
- } else {
- luaL_unref(Luas, LUA_REGISTRYINDEX, pdf_literal_data(p));
- }
-}
-
-void free_late_lua(pointer p)
-{
- if (late_lua_name(p) > 0)
- delete_token_ref(late_lua_name(p));
- if (late_lua_type(p) == normal) {
- delete_token_ref(late_lua_data(p));
- } else {
- luaL_unref(Luas, LUA_REGISTRYINDEX, late_lua_data(p));
- }
-}
-
-@ @c
-void show_pdf_literal(pointer p)
-{
- tprint_esc("pdfliteral");
- switch (pdf_literal_mode(p)) {
- case set_origin:
- break;
- case direct_page:
- tprint(" page");
- break;
- case direct_always:
- tprint(" direct");
- break;
- default:
- confusion("literal2");
- break;
- }
- if (pdf_literal_type(p) == normal) {
- print_mark(pdf_literal_data(p));
- } else {
- lua_rawgeti(Luas, LUA_REGISTRYINDEX, pdf_literal_data(p));
- tprint("\"");
- tprint(lua_tostring(Luas, -1));
- tprint("\"");
- lua_pop(Luas, 1);
- }
-}
-
-void show_late_lua(pointer p)
-{
- tprint_esc("latelua");
- print_int(late_lua_reg(p));
- if (late_lua_type(p) == normal) {
- print_mark(late_lua_data(p));
- } else {
- lua_rawgeti(Luas, LUA_REGISTRYINDEX, late_lua_data(p));
- tprint("\"");
- tprint(lua_tostring(Luas, -1));
- tprint("\"");
- lua_pop(Luas, 1);
- }
-}
+% luanode.w
+%
+% Copyright 2006-2008 Taco Hoekwater <taco@@luatex.org>
+%
+% This file is part of LuaTeX.
+%
+% LuaTeX is free software; you can redistribute it and/or modify it under
+% the terms of the GNU General Public License as published by the Free
+% Software Foundation; either version 2 of the License, or (at your
+% option) any later version.
+%
+% LuaTeX is distributed in the hope that it will be useful, but WITHOUT
+% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+% FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+% License for more details.
+%
+% You should have received a copy of the GNU General Public License along
+% with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
+
+/* hh-ls: we make sure that lua never sees prev of head but also that when
+nodes are removedor inserted, temp nodes don't interfere */
+
+@ @c
+static const char _svn_version[] =
+ "$Id: luanode.w 4775 2014-02-07 12:36:34Z luigi $"
+ "$URL: https://foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/lua/luanode.w $";
+
+#include "ptexlib.h"
+#include "lua/luatex-api.h"
+
+@ @c
+static const char *group_code_names[] = {
+ "",
+ "simple",
+ "hbox",
+ "adjusted_hbox",
+ "vbox",
+ "vtop",
+ "align",
+ "no_align",
+ "output",
+ "math",
+ "disc",
+ "insert",
+ "vcenter",
+ "math_choice",
+ "semi_simple",
+ "math_shift",
+ "math_left",
+ "local_box",
+ "split_off",
+ "split_keep",
+ "preamble",
+ "align_set",
+ "fin_row"
+};
+
+const char *pack_type_name[] = { "exactly", "additional" };
+
+
+@ @c
+void lua_node_filter_s(int filterid, const char *extrainfo)
+{
+ lua_State *L = Luas;
+ int callback_id = callback_defined(filterid);
+ int s_top = lua_gettop(L);
+ if (callback_id <= 0) {
+ lua_settop(L, s_top);
+ return;
+ }
+ if (!get_callback(L, callback_id)) {
+ lua_settop(L, s_top);
+ return;
+ }
+ lua_pushstring(L, extrainfo); /* arg 1 */
+ if (lua_pcall(L, 1, 0, 0) != 0) {
+ fprintf(stdout, "error: %s\n", lua_tostring(L, -1));
+ lua_settop(L, s_top);
+ error();
+ return;
+ }
+ lua_settop(L, s_top);
+ return;
+}
+
+@ @c
+void
+lua_node_filter(int filterid, int xextrainfo, halfword head_node,
+ halfword * tail_node)
+{
+ halfword ret;
+ int a;
+ lua_State *L = Luas;
+ int s_top = lua_gettop(L);
+ const char *extrainfo = group_code_names[xextrainfo];
+ int callback_id = callback_defined(filterid);
+ if (head_node == null || vlink(head_node) == null || callback_id <= 0) {
+ lua_settop(L, s_top);
+ return;
+ }
+ if (!get_callback(L, callback_id)) {
+ lua_settop(L, s_top);
+ return;
+ }
+ alink(vlink(head_node)) = null ; /* hh-ls */
+ nodelist_to_lua(L, vlink(head_node)); /* arg 1 */
+ lua_pushstring(L, extrainfo); /* arg 2 */
+ if (lua_pcall(L, 2, 1, 0) != 0) { /* no arg, 1 result */
+ fprintf(stdout, "error: %s\n", lua_tostring(L, -1));
+ lua_settop(L, s_top);
+ error();
+ return;
+ }
+ if (lua_isboolean(L, -1)) {
+ if (lua_toboolean(L, -1) != 1) {
+ flush_node_list(vlink(head_node));
+ vlink(head_node) = null;
+ }
+ } else {
+ a = nodelist_from_lua(L);
+ try_couple_nodes(head_node,a);
+ }
+ lua_pop(L, 2); /* result and callback container table */
+ if (fix_node_lists)
+ fix_node_list(head_node);
+ ret = vlink(head_node);
+ if (ret != null) {
+ while (vlink(ret) != null)
+ ret = vlink(ret);
+ *tail_node = ret;
+ } else {
+ *tail_node = head_node;
+ }
+ lua_settop(L, s_top);
+ return;
+}
+
+
+@ @c
+int
+lua_linebreak_callback(int is_broken, halfword head_node, halfword * new_head)
+{
+ int a;
+ register halfword *p;
+ int ret = 0; /* failure */
+ lua_State *L = Luas;
+ int s_top = lua_gettop(L);
+ int callback_id = callback_defined(linebreak_filter_callback);
+ if (head_node == null || vlink(head_node) == null || callback_id <= 0) {
+ lua_settop(L, s_top);
+ return ret;
+ }
+ if (!get_callback(L, callback_id)) {
+ lua_settop(L, s_top);
+ return ret;
+ }
+ alink(vlink(head_node)) = null ; /* hh-ls */
+ nodelist_to_lua(L, vlink(head_node)); /* arg 1 */
+ lua_pushboolean(L, is_broken); /* arg 2 */
+ if (lua_pcall(L, 2, 1, 0) != 0) { /* no arg, 1 result */
+ fprintf(stdout, "error: %s\n", lua_tostring(L, -1));
+ lua_settop(L, s_top);
+ error();
+ return ret;
+ }
+
+ p = lua_touserdata(L, -1);
+ if (p != NULL) {
+ a = nodelist_from_lua(L);
+ try_couple_nodes(*new_head,a);
+ ret = 1;
+ }
+ lua_settop(L, s_top);
+ return ret;
+}
+
+
+
+@ @c
+halfword
+lua_hpack_filter(halfword head_node, scaled size, int pack_type, int extrainfo,
+ int pack_direction)
+{
+ halfword ret;
+ lua_State *L = Luas;
+ int s_top = lua_gettop(L);
+ int callback_id = callback_defined(hpack_filter_callback);
+ if (head_node == null || callback_id <= 0) {
+ lua_settop(L, s_top);
+ return head_node;
+ }
+ if (!get_callback(L, callback_id)) {
+ lua_settop(L, s_top);
+ return head_node;
+ }
+ alink(head_node) = null ; /* hh-ls */
+ nodelist_to_lua(L, head_node);
+ lua_pushstring(L, group_code_names[extrainfo]);
+ lua_pushnumber(L, size);
+ lua_pushstring(L, pack_type_name[pack_type]);
+ if (pack_direction >= 0)
+ lua_pushstring(L, string_dir(pack_direction));
+ else
+ lua_pushnil(L);
+ if (lua_pcall(L, 5, 1, 0) != 0) { /* no arg, 1 result */
+ fprintf(stdout, "error: %s\n", lua_tostring(L, -1));
+ lua_settop(L, s_top);
+ error();
+ return head_node;
+ }
+ ret = head_node;
+ if (lua_isboolean(L, -1)) {
+ if (lua_toboolean(L, -1) != 1) {
+ flush_node_list(head_node);
+ ret = null;
+ }
+ } else {
+ ret = nodelist_from_lua(L);
+ }
+ lua_settop(L, s_top);
+#if 0
+ lua_gc(L,LUA_GCSTEP, LUA_GC_STEP_SIZE);
+#endif
+ if (fix_node_lists)
+ fix_node_list(ret);
+ return ret;
+}
+
+@ @c
+halfword
+lua_vpack_filter(halfword head_node, scaled size, int pack_type, scaled maxd,
+ int extrainfo, int pack_direction)
+{
+ halfword ret;
+ int callback_id;
+ lua_State *L = Luas;
+ int s_top = lua_gettop(L);
+ if (head_node == null) {
+ lua_settop(L, s_top);
+ return head_node;
+ }
+ if (strcmp("output", group_code_names[extrainfo]) == 0) {
+ callback_id = callback_defined(pre_output_filter_callback);
+ } else {
+ callback_id = callback_defined(vpack_filter_callback);
+ }
+ if (callback_id <= 0) {
+ lua_settop(L, s_top);
+ return head_node;
+ }
+ if (!get_callback(L, callback_id)) {
+ lua_settop(L, s_top);
+ return head_node;
+ }
+ alink(head_node) = null ; /* hh-ls */
+ nodelist_to_lua(L, head_node);
+ lua_pushstring(L, group_code_names[extrainfo]);
+ lua_pushnumber(L, size);
+ lua_pushstring(L, pack_type_name[pack_type]);
+ lua_pushnumber(L, maxd);
+ if (pack_direction >= 0)
+ lua_pushstring(L, string_dir(pack_direction));
+ else
+ lua_pushnil(L);
+ if (lua_pcall(L, 6, 1, 0) != 0) { /* no arg, 1 result */
+ fprintf(stdout, "error: %s\n", lua_tostring(L, -1));
+ lua_settop(L, s_top);
+ error();
+ return head_node;
+ }
+ ret = head_node;
+ if (lua_isboolean(L, -1)) {
+ if (lua_toboolean(L, -1) != 1) {
+ flush_node_list(head_node);
+ ret = null;
+ }
+ } else {
+ ret = nodelist_from_lua(L);
+ }
+ lua_settop(L, s_top);
+#if 0
+ lua_gc(L,LUA_GCSTEP, LUA_GC_STEP_SIZE);
+#endif
+ if (fix_node_lists)
+ fix_node_list(ret);
+ return ret;
+}
+
+
+@ This is a quick hack to fix etex's \.{\\lastnodetype} now that
+ there are many more visible node types. TODO: check the
+ eTeX manual for the expected return values.
+
+@c
+int visible_last_node_type(int n)
+{
+ int i = type(n);
+ if (i == whatsit_node && subtype(n) == local_par_node)
+ return -1;
+ if (i == glyph_node) {
+ if (is_ligature(n))
+ return 7; /* old ligature value */
+ else
+ return 0; /* old character value */
+ }
+ if (i <= unset_node) {
+ return i + 1;
+ } else if (i <= delim_node) {
+ return 15; /* so-called math nodes */
+ } else {
+ return -1;
+ }
+}
+
+@ @c
+void lua_pdf_literal(PDF pdf, int i)
+{
+ const char *s = NULL;
+ size_t l = 0;
+ lua_rawgeti(Luas, LUA_REGISTRYINDEX, i);
+ s = lua_tolstring(Luas, -1, &l);
+ pdf_out_block(pdf, s, l);
+ pdf_out(pdf, 10); /* |pdf_print_nl| */
+ lua_pop(Luas, 1);
+}
+
+@ @c
+void copy_pdf_literal(pointer r, pointer p)
+{
+ pdf_literal_type(r) = pdf_literal_type(p);
+ pdf_literal_mode(r) = pdf_literal_mode(p);
+ if (pdf_literal_type(p) == normal) {
+ pdf_literal_data(r) = pdf_literal_data(p);
+ add_token_ref(pdf_literal_data(p));
+ } else {
+ lua_rawgeti(Luas, LUA_REGISTRYINDEX, pdf_literal_data(p));
+ pdf_literal_data(r) = luaL_ref(Luas, LUA_REGISTRYINDEX);
+ }
+}
+
+void copy_late_lua(pointer r, pointer p)
+{
+ late_lua_type(r) = late_lua_type(p);
+ if (late_lua_name(p) > 0)
+ add_token_ref(late_lua_name(p));
+ if (late_lua_type(p) == normal) {
+ late_lua_data(r) = late_lua_data(p);
+ add_token_ref(late_lua_data(p));
+ } else {
+ lua_rawgeti(Luas, LUA_REGISTRYINDEX, late_lua_data(p));
+ late_lua_data(r) = luaL_ref(Luas, LUA_REGISTRYINDEX);
+ }
+}
+
+
+@ @c
+void free_pdf_literal(pointer p)
+{
+ if (pdf_literal_type(p) == normal) {
+ delete_token_ref(pdf_literal_data(p));
+ } else {
+ luaL_unref(Luas, LUA_REGISTRYINDEX, pdf_literal_data(p));
+ }
+}
+
+void free_late_lua(pointer p)
+{
+ if (late_lua_name(p) > 0)
+ delete_token_ref(late_lua_name(p));
+ if (late_lua_type(p) == normal) {
+ delete_token_ref(late_lua_data(p));
+ } else {
+ luaL_unref(Luas, LUA_REGISTRYINDEX, late_lua_data(p));
+ }
+}
+
+@ @c
+void show_pdf_literal(pointer p)
+{
+ tprint_esc("pdfliteral");
+ switch (pdf_literal_mode(p)) {
+ case set_origin:
+ break;
+ case direct_page:
+ tprint(" page");
+ break;
+ case direct_always:
+ tprint(" direct");
+ break;
+ default:
+ confusion("literal2");
+ break;
+ }
+ if (pdf_literal_type(p) == normal) {
+ print_mark(pdf_literal_data(p));
+ } else {
+ lua_rawgeti(Luas, LUA_REGISTRYINDEX, pdf_literal_data(p));
+ tprint("\"");
+ tprint(lua_tostring(Luas, -1));
+ tprint("\"");
+ lua_pop(Luas, 1);
+ }
+}
+
+void show_late_lua(pointer p)
+{
+ tprint_esc("latelua");
+ print_int(late_lua_reg(p));
+ if (late_lua_type(p) == normal) {
+ print_mark(late_lua_data(p));
+ } else {
+ lua_rawgeti(Luas, LUA_REGISTRYINDEX, late_lua_data(p));
+ tprint("\"");
+ tprint(lua_tostring(Luas, -1));
+ tprint("\"");
+ lua_pop(Luas, 1);
+ }
+}