summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/luatexdir/lua/luanode.w
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/lua/luanode.w')
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/luanode.w360
1 files changed, 360 insertions, 0 deletions
diff --git a/Build/source/texk/web2c/luatexdir/lua/luanode.w b/Build/source/texk/web2c/luatexdir/lua/luanode.w
new file mode 100644
index 00000000000..81e6b4fa74e
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/lua/luanode.w
@@ -0,0 +1,360 @@
+% 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
+#include "lua/luatex-api.h"
+#include "ptexlib.h"
+
+
+static const char _svn_version[] =
+ "$Id: luanode.w 3583 2010-04-02 17:40:44Z hhenkel $ "
+"$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/lua/luanode.w $";
+
+@ @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 s_top = lua_gettop(L);
+ int callback_id = callback_defined(filterid);
+ if (callback_id <= 0)
+ 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;
+ const char *extrainfo = group_code_names[xextrainfo];
+ int callback_id = callback_defined(filterid);
+ if (head_node == null || vlink(head_node) == null || callback_id <= 0)
+ return;
+ if (!get_callback(L, callback_id)) {
+ lua_pop(L, 2);
+ 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_pop(L, 2);
+ 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);
+ vlink(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;
+ }
+ 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 callback_id = callback_defined(linebreak_filter_callback);
+ if (head_node == null || vlink(head_node) == null || callback_id <= 0)
+ return ret;
+ if (!get_callback(L, callback_id)) {
+ lua_pop(L, 2);
+ 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_pop(L, 2);
+ error();
+ return ret;
+ }
+
+ p = lua_touserdata(L, -1);
+ if (p != NULL) {
+ a = nodelist_from_lua(L);
+ vlink(*new_head) = a;
+ ret = 1;
+ }
+ lua_pop(L, 2); /* result and callback container table */
+ 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 callback_id = callback_defined(hpack_filter_callback);
+ if (head_node == null || callback_id <= 0)
+ return head_node;
+ if (!get_callback(L, callback_id)) {
+ lua_pop(L, 2);
+ 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_pop(L, 2);
+ 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_pop(L, 2); /* result and callback container table */
+#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;
+ if (head_node == null)
+ 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) {
+ return head_node;
+ }
+ if (!get_callback(L, callback_id)) {
+ lua_pop(L, 2);
+ 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_pop(L, 2);
+ 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_pop(L, 2); /* result and callback container table */
+#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);
+ if (l < max_single_pdf_print) {
+ pdf_out_block(pdf, s, l);
+ } else {
+ while (l--) {
+ pdf_out(pdf, *s++);
+ }
+ }
+ 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);
+ }
+}
+
+
+@ @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));
+ }
+}
+
+@ @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(lua_tostring(Luas, -1));
+ lua_pop(Luas, 1);
+ }
+}