3 Copyright 2006-2013 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/>.
24 After doing lots of tests with luatex and luajittex, with and without jit,
25 and with and without ffi, we came to the conclusion that userdata prevents
26 a speedup. We also found that the checking of metatables as well as assignment
27 comes with overhead that can't be neglected. This is normally not really a
28 problem but when processing fonts for more complex scripts it's quite some
31 Because the userdata approach has some benefits, we stick to this. We did
32 some experiments with fast access (assuming nodes) and kept some of the code
33 commented here, but eventually settled for the direct approach. For code that
34 is proven to be okay, one can use the direct variants and operate on nodes
35 more directly. Currently these are numbers, but that might become light
36 userdata at one point, so *never* rely on that property. An important aspect
37 is that one cannot mix both methods, although with node.direct.tonode and
38 node.direct.todirect one can cast both representations.
40 So the advice is: use the indexed approach when possible and investigate the
41 direct one when speed might be an issue. For that reason we also provide the
42 get* and set* functions in the top level node namespace. There is a limited set
43 of getters and a generic getfield to complement them.
45 Keep in mind that these only make sense when we're calling them millions of
46 times (which happens in font processing for instance). Setters are less important
47 as documents have not that many content related nodes (and setting many thousands
48 of properties is hardly a burden contrary to millions of consultations.)
50 Another change is that __index and __newindex are (as expected) exposed to
51 users but do no checking. The getfield and setfield functions do check. In
52 fact, a fast mode can be simulated by fast_getfield = __index but the (measured)
53 benefit on average runs is not that large (some 5% when we also use the other
54 fast ones) which is easily nilled by inefficient coding. The direct variants
55 on the other hand can be significantly faster but with the drawback of lack
56 of userdata features. With respect to speed: keep in mind that measuring
57 a speedup on these functions is not representative for a normal run, where
63 #include "lua/luatex-api.h"
65 #include "lua/lauxlib_bridge.h"
72 These macros create and access pointers (indices) to keys which is faster. The
73 shortcuts are created as part of the initialization.
79 When the first argument to an accessor is a node, we can use it's metatable
80 entry when we are returning nodes, which saves a lookup.
84 #define fast_metatable(n) do { \
85 a = (halfword *) lua_newuserdata(L, sizeof(halfword)); \
87 lua_getmetatable(L,1); \
88 lua_setmetatable(L,-2); \
91 #define fast_metatable_or_nil(n) do { \
93 a = (halfword *) lua_newuserdata(L, sizeof(halfword)); \
95 lua_getmetatable(L,1); \
96 lua_setmetatable(L,-2); \
102 #define fast_metatable_or_nil_alink(n) do { \
105 a = (halfword *) lua_newuserdata(L, sizeof(halfword)); \
107 lua_getmetatable(L,1); \
108 lua_setmetatable(L,-2); \
114 #define fast_metatable_top(n) do { \
115 a = (halfword *) lua_newuserdata(L, sizeof(halfword)); \
117 lua_getmetatable(L,-2); \
118 lua_setmetatable(L,-2); \
123 This is a first step towards abstract direct nodes. When we have Lua 5.3 we
124 need to check all returned values for being integers. This might be another
129 #define nodelib_pushdirect(n) lua_pushinteger(L,n)
130 #define nodelib_popdirect(n) lua_tointeger(L,n)
132 #define nodelib_pushdirect_or_nil(n) do { \
136 lua_pushinteger(L,n); \
140 #define nodelib_pushdirect_or_nil_alink(n) do { \
145 lua_pushinteger(L,n); \
149 #define nodelib_setattr(L, s, n) reassign_attribute(n,nodelib_getlist(L,s))
151 #define nodelib_gettoks(L,a) tokenlist_from_lua(L)
153 #define nodelib_getspec nodelib_getlist
154 #define nodelib_getaction nodelib_getlist
156 /* fetching a field from a node .. we can often use the reuse bot-of-stack metatable */
158 #define nodelib_pushlist(L,n) { lua_pushinteger(L,n); lua_nodelib_push(L); } /* can be: fast_metatable_or_nil(n) */
159 #define nodelib_pushattr(L,n) { lua_pushinteger(L,n); lua_nodelib_push(L); } /* can be: fast_metatable_or_nil(n) */
160 #define nodelib_pushaction(L,n) { lua_pushinteger(L,n); lua_nodelib_push(L); } /* can be: fast_metatable_or_nil(n) */
161 #define nodelib_pushstring(L,n) { char *ss=makecstring(n); lua_pushstring(L,ss); free(ss); }
163 /* find prev, and fix backlinks .. can be a macro instead (only used a few times) */
165 #define set_t_to_prev(head,current) \
167 while (vlink(t)!=current && t != null) { \
168 if (vlink(t)!=null) \
169 alink(vlink(t)) = t; \
173 #define box(A) eqtb[box_base+(A)].hh.rh
174 #define direct_check_index_range(j,s) \
175 if (j<0 || j > 65535) { \
176 luaL_error(L, "incorrect index value %d for tex.%s()", (int)j, s); \
179 #define NODE_METATABLE "luatex.node"
182 #define DEBUG_OUT stdout
184 /* maybe these qualify as macros, not functions */
186 static halfword
*maybe_isnode(lua_State
* L
, int i
)
188 halfword
*p
= lua_touserdata(L
, i
);
190 if (lua_getmetatable(L
, i
)) {
191 lua_get_metatablelua(luatex_node
);
192 if (!lua_rawequal(L
, -1, -2))
200 /* we could make the message a function and just inline the rest (via a macro) */
202 halfword
*check_isnode(lua_State
* L
, int i
)
204 halfword
*p
= maybe_isnode(L
, i
);
207 formatted_error("node lib","lua <node> expected, not an object with type %s", luaL_typename(L
, i
));
213 This routine finds the numerical value of a string (or number) at
214 lua stack index |n|. If it is not a valid node type, returns -1
218 static int get_node_type_id_from_name(lua_State
* L
, int n
, node_info
* data
)
221 const char *s
= lua_tostring(L
, n
);
222 for (j
= 0; data
[j
].id
!= -1; j
++) {
223 if (strcmp(s
, data
[j
].name
) == 0) {
230 static int get_valid_node_type_id(lua_State
* L
, int n
)
233 int t
= lua_type(L
, n
);
234 if (t
== LUA_TSTRING
) {
235 i
= get_node_type_id_from_name(L
,n
,node_data
);
237 luaL_error(L
, "invalid node type id: %s", lua_tostring(L
, n
));
239 } else if (t
== LUA_TNUMBER
) {
240 i
= lua_tointeger(L
,n
);
241 if (! known_node_type(i
)) {
242 luaL_error(L
, "invalid node type id: %d", i
);
245 luaL_error(L
, "invalid node type id");
250 static int get_valid_node_subtype_id(lua_State
* L
, int n
)
253 int t
= lua_type(L
, n
);
254 if (t
== LUA_TSTRING
) {
255 i
= get_node_type_id_from_name(L
,n
,whatsit_node_data
);
257 luaL_error(L
, "invalid whatsit type id: %s", lua_tostring(L
, n
));
259 } else if (t
== LUA_TNUMBER
) {
260 i
= lua_tointeger(L
,n
);
261 if (! known_whatsit_type(i
)) {
262 luaL_error(L
, "invalid whatsit type id: %d", i
);
265 luaL_error(L
, "invalid whatsit type id");
270 /* two simple helpers to speed up and simplify lua code (replaced by getnext and getprev) */
272 static int lua_nodelib_next(lua_State
* L
)
274 halfword
*p
= maybe_isnode(L
,1);
275 if (p
!= NULL
&& *p
&& vlink(*p
)) {
276 lua_nodelib_push_fast(L
,vlink(*p
));
283 static int lua_nodelib_prev(lua_State
* L
)
285 halfword
*p
= maybe_isnode(L
,1);
286 if (p
!= NULL
&& *p
&& alink(*p
)) {
287 lua_nodelib_push_fast(L
,alink(*p
));
296 Creates a userdata object for a number found at the stack top, if it is
297 representing a node (i.e. an pointer into |varmem|). It replaces the
298 stack entry with the new userdata, or pushes |nil| if the number is |null|,
299 or if the index is definately out of range. This test could be improved.
303 void lua_nodelib_push(lua_State
* L
)
308 if (lua_type(L
, -1) == LUA_TNUMBER
)
309 n
= (int) lua_tointeger(L
, -1);
311 if ((n
== null
) || (n
< 0) || (n
> var_mem_max
)) {
314 a
= lua_newuserdata(L
, sizeof(halfword
));
316 lua_get_metatablelua(luatex_node
);
317 lua_setmetatable(L
, -2);
322 void lua_nodelib_push_fast(lua_State
* L
, halfword n
)
326 a
= lua_newuserdata(L
, sizeof(halfword
));
328 lua_get_metatablelua(luatex_node
);
329 lua_setmetatable(L
, -2);
336 /* converts type strings to type ids */
338 static int lua_nodelib_id(lua_State
* L
)
340 if (lua_type(L
,1) == LUA_TSTRING
) {
341 int i
= get_node_type_id_from_name(L
, 1, node_data
);
343 lua_pushinteger(L
, i
);
355 static int lua_nodelib_getid(lua_State
* L
)
357 /* [given-node] [...] */
358 halfword
*p
= lua_touserdata(L
, 1);
359 if ( (p
== NULL
) || (! lua_getmetatable(L
,1)) ) {
363 /* [given-node] [mt-given-node] */
364 lua_get_metatablelua(luatex_node
);
365 /* [given-node] [mt-given-node] [mt-node] */
366 if (!lua_rawequal(L
, -1, -2)) {
369 lua_pushinteger(L
, type(*p
));
376 static int lua_nodelib_fast_getid(lua_State * L)
379 n = (halfword *) lua_touserdata(L, 1);
380 lua_pushinteger(L, type(*n));
386 /* node.direct.getid */
388 static int lua_nodelib_direct_getid(lua_State
* L
)
390 halfword n
= lua_tointeger(L
, 1);
394 lua_pushinteger(L
, type(n
));
399 /* node.getsubtype */
401 static int lua_nodelib_getsubtype(lua_State
* L
)
403 halfword
*p
= lua_touserdata(L
, 1);
404 if ( (p
== NULL
) || (! lua_getmetatable(L
,1)) ) {
407 lua_get_metatablelua(luatex_node
);
408 if ( (!lua_rawequal(L
, -1, -2)) || (! nodetype_has_subtype(*p
))) {
411 lua_pushinteger(L
, subtype(*p
));
417 /* node.fast.getsubtype
419 static int lua_nodelib_fast_getsubtype(lua_State * L)
422 n = (halfword *) lua_touserdata(L, 1);
423 lua_pushinteger(L, subtype(*n));
429 /* node.direct.getsubtype */
431 static int lua_nodelib_direct_getsubtype(lua_State
* L
)
433 halfword n
= lua_tointeger(L
, 1);
434 if (n
== null
) { /* no check, we assume sane use */
437 lua_pushinteger(L
, subtype(n
));
442 static int lua_nodelib_direct_setsubtype(lua_State
* L
)
444 halfword n
= lua_tointeger(L
, 1);
445 if ((n
!= null
) && (lua_type(L
,2) == LUA_TNUMBER
)) {
446 subtype(n
) = (halfword
) lua_tointeger(L
, 2);
453 static int lua_nodelib_getfont(lua_State
* L
)
455 halfword
*n
= lua_touserdata(L
, 1);
456 if ( (n
== NULL
) || (! lua_getmetatable(L
,1)) ) {
459 halfword t
= type(*n
);
460 if (t
== glyph_node
) {
461 lua_pushinteger(L
, font(*n
));
462 } else if ((t
== math_char_node
) || (t
== math_text_char_node
)) {
463 lua_pushinteger(L
, fam_fnt(math_fam(*n
), 0));
473 static int lua_nodelib_fast_getfont(lua_State * L)
476 n = (halfword *) lua_touserdata(L, 1);
477 if (type(*n) != glyph_node) {
480 lua_pushinteger(L, font(*n));
487 /* node.direct.getfont */
491 static int lua_nodelib_direct_getfont(lua_State * L)
494 n = (halfword) lua_tointeger(L, 1);
495 if ((n == null) || (type(n) != glyph_node)) {
498 lua_pushinteger(L, font(n));
505 static int lua_nodelib_direct_getfont(lua_State
* L
) /* family_font is not yet in manual, what does arg 2 do */
507 halfword n
= lua_tointeger(L
, 1);
509 halfword t
= type(n
);
510 if (t
== glyph_node
) {
511 lua_pushinteger(L
, font(n
));
512 } else if ((t
== math_char_node
) || (t
== math_text_char_node
)) {
513 lua_pushinteger(L
, fam_fnt(math_fam(n
), 0));
525 static int lua_nodelib_getcharacter(lua_State
* L
)
527 halfword
*n
= lua_touserdata(L
, 1);
528 if ( (n
== NULL
) || (! lua_getmetatable(L
,1)) ) {
530 } else if (type(*n
) == glyph_node
) {
531 lua_pushinteger(L
, character(*n
));
532 } else if ((type(*n
) == math_char_node
) || (type(*n
) == math_text_char_node
)) {
533 lua_pushinteger(L
, math_character(*n
));
540 static int lua_nodelib_fast_getcharacter(lua_State * L)
543 n = (halfword *) lua_touserdata(L, 1);
544 if (type(*n) == glyph_node) {
545 lua_pushinteger(L, character(*n));
546 } else if ((type(*n) == math_char_node) || (type(*n) == math_text_char_node)) {
547 lua_pushinteger(L, math_character(*n));
556 /* node.direct.getchar */
558 static int lua_nodelib_direct_getcharacter(lua_State
* L
)
560 halfword n
= lua_tointeger(L
, 1);
563 } else if (type(n
) == glyph_node
) {
564 lua_pushinteger(L
, character(n
));
565 } else if ((type(n
) == math_char_node
) || (type(n
) == math_text_char_node
)) {
566 lua_pushinteger(L
, math_character(n
));
575 static int lua_nodelib_direct_getdiscretionary(lua_State
* L
)
577 halfword n
= lua_tointeger(L
, 1);
579 if (type(n
) == disc_node
) {
580 nodelib_pushdirect_or_nil(vlink(pre_break(n
)));
581 nodelib_pushdirect_or_nil(vlink(post_break(n
)));
582 nodelib_pushdirect_or_nil(vlink(no_break(n
)));
583 if (lua_isboolean(L
, 2)) {
584 if (lua_toboolean(L
, 2)) {
585 nodelib_pushdirect_or_nil(tlink(pre_break(n
)));
586 nodelib_pushdirect_or_nil(tlink(post_break(n
)));
587 nodelib_pushdirect_or_nil(tlink(no_break(n
)));
598 static int lua_nodelib_getdiscretionary(lua_State
* L
)
601 halfword
*n
= lua_touserdata(L
, 1);
603 if (type(*n
) == disc_node
) {
604 fast_metatable_or_nil(vlink(pre_break(*n
)));
605 fast_metatable_or_nil(vlink(post_break(*n
)));
606 fast_metatable_or_nil(vlink(no_break(*n
)));
607 if (lua_isboolean(L
, 2)) {
608 if (lua_toboolean(L
, 2)) {
609 fast_metatable_or_nil(tlink(pre_break(*n
)));
610 fast_metatable_or_nil(tlink(post_break(*n
)));
611 fast_metatable_or_nil(tlink(no_break(*n
)));
625 static int lua_nodelib_getlist(lua_State
* L
)
628 halfword
*n
= lua_touserdata(L
, 1);
629 if ((n
== NULL
) || (! lua_getmetatable(L
,1))) {
631 } else if ((type(*n
) == hlist_node
) || (type(*n
) == vlist_node
)) {
632 fast_metatable_or_nil_alink(list_ptr(*n
));
641 static int lua_nodelib_setlist(lua_State * L)
643 halfword *n = lua_touserdata(L, 1);
644 if ((n != null) && ((type(n) == hlist_node) || (type(n) == vlist_node))) {
645 if (lua_type(L,2) == LUA_TNIL) {
648 halfword *l = lua_touserdata(L, 2);
657 /* node.direct.getlist */
659 static int lua_nodelib_direct_getlist(lua_State
* L
)
661 halfword n
= lua_tointeger(L
, 1);
664 } else if ((type(n
) == hlist_node
) || (type(n
) == vlist_node
)) {
665 nodelib_pushdirect_or_nil_alink(list_ptr(n
));
672 static int lua_nodelib_direct_setlist(lua_State
* L
)
674 halfword n
= lua_tointeger(L
, 1);
675 if ((n
!= null
) && ((type(n
) == hlist_node
) || (type(n
) == vlist_node
))) {
676 if (lua_type(L
,2) == LUA_TNUMBER
) {
677 list_ptr(n
) = (halfword
) lua_tointeger(L
, 2);
687 static int lua_nodelib_getleader(lua_State
* L
)
690 halfword
*n
= lua_touserdata(L
, 1);
691 if ( (n
== NULL
) || (! lua_getmetatable(L
,1)) ) {
693 } else if (type(*n
) == glue_node
) {
694 fast_metatable_or_nil(leader_ptr(*n
));
701 /* node.direct.getleader */
703 static int lua_nodelib_direct_getleader(lua_State
* L
)
705 halfword n
= lua_tointeger(L
, 1);
708 } else if (type(n
) == glue_node
) {
709 nodelib_pushdirect_or_nil(leader_ptr(n
));
716 static int lua_nodelib_direct_setleader(lua_State
* L
)
718 halfword n
= lua_tointeger(L
, 1);
719 if ((n
!= null
) && (type(n
) == glue_node
)) {
720 if (lua_type(L
,2) == LUA_TNUMBER
) {
721 leader_ptr(n
) = (halfword
) lua_tointeger(L
, 2);
723 leader_ptr(n
) = null
;
731 static int lua_nodelib_getnext(lua_State
* L
)
734 /* [given-node] [...]*/
735 halfword
*p
= lua_touserdata(L
, 1);
736 if ( (p
== NULL
) || (! lua_getmetatable(L
,1)) ) {
739 /* [given-node] [mt-given-node]*/
740 lua_get_metatablelua(luatex_node
);
741 /* [given-node] [mt-given-node] [mt-node]*/
742 if (!lua_rawequal(L
, -1, -2)) {
745 fast_metatable_or_nil(vlink(*p
));
748 return 1; /* just one*/
753 static int lua_nodelib_fast_getnext(lua_State * L)
756 halfword *p = lua_touserdata(L, 1);
757 if ((p == NULL) || (!vlink(*p))){
761 lua_getmetatable(L,1);
762 a = lua_newuserdata(L, sizeof(halfword));
765 lua_setmetatable(L,1);
772 /* node.direct.getnext */
774 static int lua_nodelib_direct_getnext(lua_State
* L
)
776 halfword p
= lua_tointeger(L
, 1);
780 nodelib_pushdirect_or_nil(vlink(p
));
787 static int lua_nodelib_getprev(lua_State
* L
)
790 halfword
*p
= lua_touserdata(L
, 1);
791 if ( (p
== NULL
) || (! lua_getmetatable(L
,1)) ) {
794 lua_get_metatablelua(luatex_node
);
795 if (!lua_rawequal(L
, -1, -2)) {
798 fast_metatable_or_nil(alink(*p
));
804 static int lua_nodelib_getboth(lua_State
* L
)
807 halfword
*p
= lua_touserdata(L
, 1);
808 if ( (p
== NULL
) || (! lua_getmetatable(L
,1)) ) {
812 lua_get_metatablelua(luatex_node
);
813 if (!lua_rawequal(L
, -1, -2)) {
817 fast_metatable_or_nil(alink(*p
));
818 fast_metatable_or_nil(vlink(*p
));
826 static int lua_nodelib_fast_getprev(lua_State * L)
829 halfword *p = lua_touserdata(L, 1);
830 if ((p == NULL) || (!alink(*p))) {
834 lua_getmetatable(L,1);
835 a = lua_newuserdata(L, sizeof(halfword));
838 lua_setmetatable(L,1);
845 /* node.direct.getprev */
847 static int lua_nodelib_direct_getprev(lua_State
* L
)
849 halfword p
= lua_tointeger(L
, 1);
853 nodelib_pushdirect_or_nil(alink(p
));
858 /* node.direct.getboth */
860 static int lua_nodelib_direct_getboth(lua_State
* L
)
862 halfword p
= lua_tointeger(L
, 1);
867 nodelib_pushdirect_or_nil(alink(p
));
868 nodelib_pushdirect_or_nil(vlink(p
));
873 /* node.subtype (maybe also return them for other node types now) */
875 static int lua_nodelib_subtype(lua_State
* L
)
877 if (lua_type(L
,1) == LUA_TSTRING
) {
878 int i
= get_node_type_id_from_name(L
,1,whatsit_node_data
);
880 lua_pushinteger(L
, i
);
890 /* node.type (converts id numbers to type names) */
892 static int lua_nodelib_type(lua_State
* L
)
894 if (lua_type(L
,1) == LUA_TNUMBER
) {
895 int i
= lua_tointeger(L
, 1);
896 if (known_node_type(i
)) {
897 lua_pushstring(L
, node_data
[i
].name
);
900 } else if (maybe_isnode(L
, 1) != NULL
) {
901 lua_pushstring(L
,"node");
908 /* node.new (allocate a new node) */
910 static int lua_nodelib_new(lua_State
* L
)
914 int t
= lua_type(L
, 1);
915 if (t
== LUA_TNUMBER
) {
916 i
= lua_tointeger(L
,1);
917 if (! known_node_type(i
)) {
920 } else if (t
== LUA_TSTRING
) {
921 i
= get_node_type_id_from_name(L
,1,node_data
);
926 luaL_error(L
, "invalid node id for creating new node");
929 if (i
== whatsit_node
) {
930 if (t
== LUA_TNUMBER
) {
931 j
= lua_tointeger(L
,2);
932 if (! known_whatsit_type(j
)) {
935 } else if (t
== LUA_TSTRING
) {
936 j
= get_node_type_id_from_name(L
,2,whatsit_node_data
);
941 luaL_error(L
, "creating a whatsit requires the subtype number as a second argument");
943 } else if (t
== LUA_TNUMBER
) {
944 j
= (int) lua_tointeger(L
, 2);
949 lua_nodelib_push_fast(L
, n
);
953 /* node.direct.new (still with checking) */
955 static int lua_nodelib_direct_new(lua_State
* L
)
959 int i
= get_valid_node_type_id(L
, 1);
960 if (i
== whatsit_node
) {
962 if (lua_gettop(L
) > 1)
963 j
= get_valid_node_subtype_id(L
, 2);
965 luaL_error(L
, "Creating a whatsit requires the subtype number as a second argument");
968 if (lua_gettop(L
) > 1)
969 j
= (int) lua_tointeger(L
, 2);
972 lua_pushinteger(L
,n
);
976 /* node.free (this function returns the 'next' node, because that may be helpful) */
978 static int lua_nodelib_free(lua_State
* L
)
982 if (lua_gettop(L
) < 1) {
985 } else if (lua_isnil(L
, 1)) {
986 return 1; /* the nil itself */
988 n
= *(check_isnode(L
, 1));
991 /* can be: lua_nodelib_push_fast(L, p); */
992 lua_pushinteger(L
, p
);
997 /* node.direct.free */
999 static int lua_nodelib_direct_free(lua_State
* L
)
1001 halfword n
= lua_tointeger(L
,1);
1005 halfword p
= vlink(n
);
1010 lua_pushinteger(L
,p
);
1016 /* node.flush_node (no next returned) */
1018 static int lua_nodelib_flush_node(lua_State
* L
)
1020 if ((lua_gettop(L
) < 1) || lua_isnil(L
, 1)) {
1023 halfword n
= *(check_isnode(L
, 1));
1029 /* node.direct.flush_node */
1031 static int lua_nodelib_direct_flush_node(lua_State
* L
)
1033 halfword n
= lua_tointeger(L
,1);
1040 /* node.flush_list */
1042 static int lua_nodelib_flush_list(lua_State
* L
)
1044 if ((lua_gettop(L
) < 1) || lua_isnil(L
, 1)) {
1047 halfword n_ptr
= *check_isnode(L
, 1);
1048 flush_node_list(n_ptr
);
1053 /* node.direct.flush_list */
1055 static int lua_nodelib_direct_flush_list(lua_State
* L
)
1057 halfword n
= lua_tointeger(L
,1);
1064 /* remove a node from a list */
1068 static void show_node_links (halfword l
, const char * p
)
1072 fprintf(DEBUG_OUT
, "%s t = %d, prev = %d, next = %d\n", p
, (int)t
, (int)alink(t
), (int)vlink(t
));
1081 static int lua_nodelib_remove(lua_State
* L
)
1083 halfword head
, current
, t
;
1084 if (lua_gettop(L
) < 2)
1085 luaL_error(L
, "Not enough arguments for node.remove()");
1086 head
= *(check_isnode(L
, 1));
1087 if (lua_isnil(L
, 2))
1088 return 2; /* the arguments, as they are */
1089 current
= *(check_isnode(L
, 2));
1090 if (head
== current
) {
1091 if (alink(current
)){
1092 vlink(alink(current
)) = vlink(current
);
1094 if (vlink(current
)){
1095 alink( vlink(current
)) = alink(current
);
1098 head
= vlink(current
);
1099 current
= vlink(current
);
1102 if (t
== null
|| vlink(t
) != current
) {
1103 set_t_to_prev(head
, current
);
1104 if (t
== null
) /* error! */
1105 luaL_error(L
,"Attempt to node.remove() a non-existing node");
1107 /* t is now the previous node */
1108 vlink(t
) = vlink(current
);
1109 if (vlink(current
) != null
)
1110 alink(vlink(current
)) = t
;
1111 current
= vlink(current
);
1114 show_node_links(head
, "after");
1116 /* can be: lua_nodelib_push_fast(L, head); */
1117 lua_pushinteger(L
, head
);
1118 lua_nodelib_push(L
);
1119 /* can be: lua_nodelib_push_fast(L, current); */
1120 lua_pushinteger(L
, current
);
1121 lua_nodelib_push(L
);
1125 /* node.direct.remove */
1127 static int lua_nodelib_direct_remove(lua_State
* L
)
1129 halfword current
, t
;
1130 halfword head
= lua_tointeger(L
,1);
1136 current
= (halfword
) lua_tointeger(L
,2);
1137 if (current
== null
) {
1138 lua_pushinteger(L
, head
);
1142 if (head
== current
) {
1143 if (alink(current
)){
1144 vlink( alink(current
) ) = vlink(current
);
1146 if (vlink(current
)){
1147 alink( vlink(current
) ) = alink(current
);
1149 head
= vlink(current
);
1150 current
= vlink(current
);
1153 if (t
== null
|| vlink(t
) != current
) {
1154 set_t_to_prev(head
, current
);
1156 luaL_error(L
,"Attempt to node.direct.remove() a non-existing node");
1159 vlink(t
) = vlink(current
);
1160 if (vlink(current
) != null
)
1161 alink(vlink(current
)) = t
;
1162 current
= vlink(current
);
1167 lua_pushinteger(L
, head
);
1169 if (current
== null
) {
1172 lua_pushinteger(L
, current
);
1177 /* node.insert_before (insert a node in a list) */
1179 static int lua_nodelib_insert_before(lua_State
* L
)
1181 halfword head
, current
, n
, t
;
1182 if (lua_gettop(L
) < 3) {
1183 luaL_error(L
, "Not enough arguments for node.insert_before()");
1185 if (lua_isnil(L
, 3)) {
1189 n
= *(check_isnode(L
, 3));
1191 if (lua_isnil(L
, 1)) { /* no head */
1194 lua_nodelib_push_fast(L
, n
);
1195 lua_pushvalue(L
, -1);
1198 head
= *(check_isnode(L
, 1));
1200 if (lua_isnil(L
, 2)) {
1201 current
= tail_of_list(head
);
1203 current
= *(check_isnode(L
, 2));
1205 if (head
!= current
) {
1207 if (t
== null
|| vlink(t
) != current
) {
1208 set_t_to_prev(head
, current
);
1209 if (t
== null
) { /* error! */
1210 luaL_error(L
, "Attempt to node.insert_before() a non-existing node");
1215 couple_nodes(n
, current
);
1216 if (head
== current
) {
1217 lua_nodelib_push_fast(L
, n
);
1219 lua_nodelib_push_fast(L
, head
);
1221 lua_nodelib_push_fast(L
, n
);
1225 /* node.direct.insert_before */
1227 static int lua_nodelib_direct_insert_before(lua_State
* L
)
1229 halfword head
, current
;
1230 halfword n
= lua_tointeger(L
,3);
1236 head
= (halfword
) lua_tointeger(L
,1);
1237 current
= (halfword
) lua_tointeger(L
,2);
1238 /* no head, ignore current */
1242 lua_pushinteger(L
, n
);
1243 lua_pushvalue(L
, -1);
1248 if (current
== null
)
1249 current
= tail_of_list(head
);
1250 if (head
!= current
) {
1251 halfword t
= alink(current
);
1252 if (t
== null
|| vlink(t
) != current
)
1253 set_t_to_prev(head
, current
);
1256 couple_nodes(n
, current
);
1257 if (head
== current
) {
1258 lua_pushinteger(L
, n
);
1260 lua_pushinteger(L
, head
);
1262 lua_pushinteger(L
, n
);
1266 /* node.insert_after */
1268 static int lua_nodelib_insert_after(lua_State
* L
)
1270 halfword head
, current
, n
;
1271 if (lua_gettop(L
) < 3) {
1272 luaL_error(L
, "Not enough arguments for node.insert_after()");
1274 if (lua_isnil(L
, 3)) {
1278 n
= *(check_isnode(L
, 3));
1280 if (lua_isnil(L
, 1)) { /* no head */
1283 lua_nodelib_push_fast(L
, n
);
1284 lua_pushvalue(L
, -1);
1287 head
= *(check_isnode(L
, 1));
1289 if (lua_isnil(L
, 2)) {
1291 while (vlink(current
) != null
)
1292 current
= vlink(current
);
1294 current
= *(check_isnode(L
, 2));
1296 try_couple_nodes(n
, vlink(current
));
1297 couple_nodes(current
, n
);
1300 lua_nodelib_push_fast(L
, n
);
1304 /* node.direct.insert_after */
1306 static int lua_nodelib_direct_insert_after(lua_State
* L
)
1308 halfword head
, current
;
1309 /*[head][current][new]*/
1310 halfword n
= lua_tointeger(L
,3);
1315 head
= (halfword
) lua_tointeger(L
,1);
1316 current
= (halfword
) lua_tointeger(L
,2);
1318 /* no head, ignore current */
1321 lua_pushinteger(L
,n
);
1322 lua_pushvalue(L
, -1);
1326 if (current
== null
) {
1329 while (vlink(current
) != null
)
1330 current
= vlink(current
);
1332 try_couple_nodes(n
, vlink(current
));
1333 couple_nodes(current
, n
);
1335 lua_pushinteger(L
, n
);
1339 /* node.copy_list */
1342 we need to use an intermediate variable as otherwise target is used in the loop
1343 and subfields get overwritten (or something like that) which results in crashes
1344 and unexpected side effects
1347 static int lua_nodelib_copy_list(lua_State
* L
)
1349 halfword n
, s
= null
;
1351 if (lua_isnil(L
, 1))
1352 return 1; /* the nil itself */
1353 n
= *check_isnode(L
, 1);
1354 if ((lua_gettop(L
) > 1) && (!lua_isnil(L
,2)))
1355 s
= *check_isnode(L
, 2);
1356 m
= do_copy_node_list(n
, s
);
1357 lua_nodelib_push_fast(L
,m
);
1362 /* node.direct.copy_list */
1364 static int lua_nodelib_direct_copy_list(lua_State
* L
)
1366 halfword n
= lua_tointeger(L
,1);
1370 halfword s
= lua_tointeger(L
,2);
1373 m
= do_copy_node_list(n
,null
);
1375 m
= do_copy_node_list(n
,s
);
1377 lua_pushinteger(L
,m
);
1382 /* node.copy (deep copy) */
1384 static int lua_nodelib_copy(lua_State
* L
)
1387 if (lua_isnil(L
, 1))
1388 return 1; /* the nil itself */
1389 n
= *check_isnode(L
, 1);
1391 lua_nodelib_push_fast(L
, n
);
1395 /* node.direct.copy (deep copy) */
1397 static int lua_nodelib_direct_copy(lua_State
* L
)
1399 if (lua_isnil(L
, 1)) {
1400 return 1; /* the nil itself */
1402 /* beware, a glue node can have number 0 (zeropt) so we cannot test for null) */
1403 halfword n
= lua_tointeger(L
, 1);
1405 lua_pushinteger(L
, n
);
1411 /* node.write (output a node to tex's processor) */
1413 static int lua_nodelib_append(lua_State
* L
)
1417 int j
= lua_gettop(L
);
1418 for (i
= 1; i
<= j
; i
++) {
1419 n
= *check_isnode(L
, i
);
1421 while (vlink(n
) != null
) {
1429 /* node.direct.write */
1431 static int lua_nodelib_direct_append(lua_State
* L
)
1435 int j
= lua_gettop(L
);
1436 for (i
= 1; i
<= j
; i
++) {
1437 halfword n
= lua_tointeger(L
,i
); /*lua_getnumber(L, i);*/
1441 while (vlink(m
) != null
) {
1452 static int lua_nodelib_last_node(lua_State
* L
)
1454 halfword m
= pop_tail();
1455 /* can be: lua_nodelib_push_fast(L, m); */
1456 lua_pushinteger(L
, m
);
1457 lua_nodelib_push(L
);
1461 /* node.direct.last */
1463 static int lua_nodelib_direct_last_node(lua_State
* L
)
1465 halfword m
= pop_tail();
1466 lua_pushinteger(L
, m
);
1470 /* node.hpack (build a hbox) */
1472 static int lua_nodelib_hpack(lua_State
* L
)
1479 halfword n
= *(check_isnode(L
, 1));
1480 if (lua_gettop(L
) > 1) {
1481 w
= (int) lua_tointeger(L
, 2);
1482 if (lua_gettop(L
) > 2) {
1483 if (lua_type(L
, 3) == LUA_TSTRING
) {
1484 s
= lua_tostring(L
, 3);
1485 if (lua_key_eq(s
, exactly
)) {
1487 } else if (lua_key_eq(s
, additional
)) {
1489 } else if (lua_key_eq(s
, cal_expand_ratio
)) {
1491 } else if (lua_key_eq(s
, subst_ex_font
)) {
1494 } else if (lua_type(L
, 3) == LUA_TNUMBER
) {
1495 m
= (int) lua_tointeger(L
, 3);
1497 if ((m
<0) || (m
>3)) {
1498 luaL_error(L
, "wrong mode in hpack");
1500 if (lua_gettop(L
) > 3) {
1501 if (lua_type(L
, 4) == LUA_TSTRING
) {
1502 d
= nodelib_getdir(L
, 4, 1);
1504 lua_pushstring(L
, "incorrect 4th argument");
1509 p
= hpack(n
, w
, m
, d
);
1510 lua_nodelib_push_fast(L
, p
);
1511 lua_pushinteger(L
, last_badness
);
1515 /* node.direct.hpack */
1517 static int lua_nodelib_direct_hpack(lua_State
* L
)
1524 halfword n
= lua_tointeger(L
,1);
1525 /* could be macro */
1526 if (lua_gettop(L
) > 1) {
1527 w
= (int) lua_tointeger(L
, 2);
1528 if (lua_gettop(L
) > 2) {
1529 if (lua_type(L
, 3) == LUA_TSTRING
) {
1530 s
= lua_tostring(L
, 3);
1531 if (lua_key_eq(s
, additional
)) {
1533 } else if (lua_key_eq(s
, exactly
)) {
1535 } else if (lua_key_eq(s
, cal_expand_ratio
)) {
1537 } else if (lua_key_eq(s
, subst_ex_font
)) {
1540 luaL_error(L
, "3rd argument should be either additional or exactly");
1542 } else if (lua_type(L
, 3) == LUA_TNUMBER
) {
1543 m
= (int) lua_tointeger(L
, 3);
1545 lua_pushstring(L
, "incorrect 3rd argument");
1547 if (lua_gettop(L
) > 3) {
1548 if (lua_type(L
, 4) == LUA_TSTRING
) {
1549 d
= nodelib_getdir(L
, 4, 1);
1551 lua_pushstring(L
, "incorrect 4th argument");
1557 p
= hpack(n
, w
, m
, d
);
1558 lua_pushinteger(L
, p
);
1559 lua_pushinteger(L
, last_badness
);
1563 /* node.vpack (build a vbox) */
1565 static int lua_nodelib_vpack(lua_State
* L
)
1572 halfword n
= *(check_isnode(L
, 1));
1573 if (lua_gettop(L
) > 1) {
1574 w
= (int) lua_tointeger(L
, 2);
1575 if (lua_gettop(L
) > 2) {
1576 if (lua_type(L
, 3) == LUA_TSTRING
) {
1577 s
= lua_tostring(L
, 3);
1578 if (lua_key_eq(s
, additional
)) {
1580 } else if (lua_key_eq(s
, exactly
)) {
1583 luaL_error(L
, "3rd argument should be either additional or exactly");
1586 if (lua_gettop(L
) > 3) {
1587 if (lua_type(L
, 4) == LUA_TSTRING
) {
1588 d
= nodelib_getdir(L
, 4, 1);
1590 lua_pushstring(L
, "incorrect 4th argument");
1595 else if (lua_type(L
, 3) == LUA_TNUMBER
) {
1596 m
= (int) lua_tointeger(L
, 3);
1598 lua_pushstring(L
, "incorrect 3rd argument");
1602 p
= vpackage(n
, w
, m
, max_dimen
, d
);
1603 lua_nodelib_push_fast(L
, p
);
1604 lua_pushinteger(L
, last_badness
);
1608 /* node.direct.vpack */
1610 static int lua_nodelib_direct_vpack(lua_State
* L
)
1617 halfword n
= (halfword
) lua_tointeger(L
,1);
1618 if (lua_gettop(L
) > 1) {
1619 w
= (int) lua_tointeger(L
, 2);
1620 if (lua_gettop(L
) > 2) {
1621 if (lua_type(L
, 3) == LUA_TSTRING
) {
1622 s
= lua_tostring(L
, 3);
1623 if (lua_key_eq(s
, additional
)) {
1625 } else if (lua_key_eq(s
, exactly
)) {
1628 luaL_error(L
, "3rd argument should be either additional or exactly");
1631 if (lua_gettop(L
) > 3) {
1632 if (lua_type(L
, 4) == LUA_TSTRING
) {
1633 d
= nodelib_getdir(L
, 4, 1);
1635 lua_pushstring(L
, "incorrect 4th argument");
1640 else if (lua_type(L
, 3) == LUA_TNUMBER
) {
1641 m
= (int) lua_tointeger(L
, 3);
1643 lua_pushstring(L
, "incorrect 3rd argument");
1647 p
= vpackage(n
, w
, m
, max_dimen
, d
);
1648 lua_pushinteger(L
, p
);
1649 lua_pushinteger(L
, last_badness
);
1653 /* node.dimensions (of a hlist or vlist) */
1655 static int lua_nodelib_dimensions(lua_State
* L
)
1657 int top
= lua_gettop(L
);
1660 glue_ratio g_mult
= 1.0;
1661 int g_sign
= normal
;
1662 int g_order
= normal
;
1665 halfword n
= null
, p
= null
;
1666 if (lua_type(L
, 1) == LUA_TNUMBER
) {
1672 g_mult
= (glue_ratio
) lua_tonumber(L
, 1); /* integer or float */
1673 g_sign
= (int) lua_tointeger(L
, 2);
1674 g_order
= (int) lua_tointeger(L
, 3);
1676 n
= *(check_isnode(L
, i
));
1677 if (lua_gettop(L
) > i
&& !lua_isnil(L
, (i
+ 1))) {
1678 if (lua_type(L
, (i
+ 1)) == LUA_TSTRING
) {
1679 d
= nodelib_getdir(L
, (i
+ 1), 1);
1681 p
= *(check_isnode(L
, (i
+ 1)));
1684 if (lua_gettop(L
) > (i
+ 1) && lua_type(L
, (i
+ 2)) == LUA_TSTRING
) {
1685 d
= nodelib_getdir(L
, (i
+ 2), 1);
1687 siz
= natural_sizes(n
, p
, g_mult
, g_sign
, g_order
, d
);
1688 lua_pushinteger(L
, siz
.wd
);
1689 lua_pushinteger(L
, siz
.ht
);
1690 lua_pushinteger(L
, siz
.dp
);
1693 luaL_error(L
, "missing argument to 'dimensions' (node expected)");
1695 return 0; /* not reached */
1698 /* node.direct.dimensions*/
1700 static int lua_nodelib_direct_dimensions(lua_State
* L
)
1702 int top
= lua_gettop(L
);
1705 glue_ratio g_mult
= 1.0;
1706 int g_sign
= normal
;
1707 int g_order
= normal
;
1710 halfword n
= null
, p
= null
;
1713 g_mult
= (glue_ratio
) lua_tonumber(L
, 1); /* integer or float */
1714 g_sign
= (int) lua_tointeger(L
, 2);
1715 g_order
= (int) lua_tointeger(L
, 3);
1717 n
= (halfword
) lua_tointeger(L
,i
);
1718 if (lua_gettop(L
) > i
&& !lua_isnil(L
, (i
+ 1))) {
1719 if (lua_type(L
, (i
+ 1)) == LUA_TSTRING
) {
1720 d
= nodelib_getdir(L
, (i
+ 1), 1);
1722 p
= (halfword
) lua_tointeger(L
,i
+1);
1725 if (lua_gettop(L
) > (i
+ 1) && lua_type(L
, (i
+ 2)) == LUA_TSTRING
)
1726 d
= nodelib_getdir(L
, (i
+ 2), 1);
1727 siz
= natural_sizes(n
, p
, g_mult
, g_sign
, g_order
, d
);
1728 lua_pushinteger(L
, siz
.wd
);
1729 lua_pushinteger(L
, siz
.ht
);
1730 lua_pushinteger(L
, siz
.dp
);
1733 luaL_error(L
, "missing argument to 'dimensions' (node expected)");
1735 return 0; /* not reached */
1738 /* node.mlist_to_hlist (create a hlist from a formula) */
1740 static int lua_nodelib_mlist_to_hlist(lua_State
* L
)
1744 halfword n
= *(check_isnode(L
, 1));
1745 assign_math_style(L
,2,w
);
1746 luaL_checkany(L
, 3);
1747 m
= lua_toboolean(L
, 3);
1748 mlist_to_hlist(n
, m
, w
);
1749 alink(vlink(temp_head
)) = null
; /*hh-ls */
1750 lua_nodelib_push_fast(L
, vlink(temp_head
));
1754 /* node.family_font */
1756 static int lua_nodelib_mfont(lua_State
* L
)
1759 int f
= luaL_checkinteger(L
, 1);
1760 if (lua_gettop(L
) == 2)
1761 s
= lua_tointeger(L
, 2); /* this should be a multiple of 256 ! */
1764 lua_pushinteger(L
, fam_fnt(f
,s
));
1769 This function is similar to |get_node_type_id|, for field
1770 identifiers. It has to do some more work, because not all
1771 identifiers are valid for all types of nodes.
1773 If really needed we can optimize this one using a big if ..
1774 .. else like with the getter and setter.
1778 static int get_node_field_id(lua_State
* L
, int n
, int node
)
1781 const char *s
= lua_tostring(L
, n
);
1786 if (lua_key_eq(s
, next
)) {
1788 } else if (lua_key_eq(s
, id
)) {
1790 } else if (lua_key_eq(s
, subtype
)) {
1791 if (nodetype_has_subtype(t
)) {
1794 } else if (lua_key_eq(s
, attr
)) {
1795 if (nodetype_has_attributes(t
)) {
1798 } else if (lua_key_eq(s
, prev
)) {
1799 if (nodetype_has_prev(t
)) {
1804 const char **fields
= node_data
[t
].fields
;
1805 if (t
== whatsit_node
) {
1806 fields
= whatsit_node_data
[subtype(node
)].fields
;
1808 if (lua_key_eq(s
, list
)) {
1811 if (fields
!= NULL
) {
1812 for (j
= 0; fields
[j
] != NULL
; j
++) {
1813 if (strcmp(s
, fields
[j
]) == 0) {
1822 /* node.has_field */
1824 static int lua_nodelib_has_field(lua_State
* L
)
1827 if (!lua_isnil(L
, 1))
1828 i
= get_node_field_id(L
, 2, *(check_isnode(L
, 1)));
1829 lua_pushboolean(L
, (i
!= -2));
1833 /* node.is_char (node[,font]) */
1835 static int lua_nodelib_is_char(lua_State
* L
)
1837 halfword n
= *(check_isnode(L
, 1));
1838 if (type(n
) != glyph_node
) {
1839 lua_pushnil(L
); /* no glyph at all */
1840 lua_pushinteger(L
,type(n
)); /* can save a lookup call */
1842 } else if (subtype(n
) >= 256) {
1843 lua_pushboolean(L
,0); /* a done glyph */
1844 } else if (lua_type(L
,2) == LUA_TNUMBER
) {
1845 halfword f
= lua_tointeger(L
, 2);
1846 if (f
&& f
== font(n
)) {
1847 lua_pushinteger(L
,character(n
)); /* a todo glyph in the asked font */
1849 lua_pushboolean(L
,0); /* a todo glyph in another font */
1852 lua_pushinteger(L
,character(n
)); /* a todo glyph */
1857 static int lua_nodelib_is_glyph(lua_State
* L
)
1859 halfword n
= *(check_isnode(L
, 1));
1860 if (type(n
) != glyph_node
) {
1861 lua_pushboolean(L
,0);
1862 lua_pushinteger(L
,type(n
));
1864 lua_pushinteger(L
,character(n
));
1865 lua_pushinteger(L
,font(n
));
1870 /* node.direct.has_field */
1872 static int lua_nodelib_direct_has_field(lua_State
* L
)
1875 halfword n
= lua_tointeger(L
, 1);
1877 i
= get_node_field_id(L
, 2, n
);
1878 lua_pushboolean(L
, (i
!= -2));
1882 /* fetch the list of valid node types */
1884 static int do_lua_nodelib_types(lua_State
* L
, node_info
* data
)
1888 for (i
= 0; data
[i
].id
!= -1; i
++) {
1889 lua_pushstring(L
, data
[i
].name
);
1890 lua_rawseti(L
, -2, data
[i
].id
);
1897 static int lua_nodelib_types(lua_State
* L
)
1899 return do_lua_nodelib_types(L
, node_data
);
1904 static int lua_nodelib_whatsits(lua_State
* L
)
1906 return do_lua_nodelib_types(L
, whatsit_node_data
);
1909 /* node.fields (fetch the list of valid fields) */
1911 static int lua_nodelib_fields(lua_State
* L
)
1915 const char **fields
;
1916 int t
= get_valid_node_type_id(L
, 1);
1917 if (t
== whatsit_node
) {
1918 t
= get_valid_node_subtype_id(L
, 2);
1919 fields
= whatsit_node_data
[t
].fields
;
1921 fields
= node_data
[t
].fields
;
1923 lua_checkstack(L
, 2);
1925 lua_push_string_by_name(L
,next
);
1926 lua_rawseti(L
, -2, 0);
1927 lua_push_string_by_name(L
,id
);
1928 lua_rawseti(L
, -2, 1);
1929 if (nodetype_has_subtype(t
)) {
1930 lua_push_string_by_name(L
,subtype
);
1931 lua_rawseti(L
, -2, 2);
1934 if (nodetype_has_prev(t
)) {
1935 lua_push_string_by_name(L
,prev
);
1936 lua_rawseti(L
, -2, -1);
1938 if (fields
!= NULL
) {
1939 for (i
= 0; fields
[i
] != NULL
; i
++) {
1940 lua_pushstring(L
, fields
[i
]); /* todo */
1941 lua_rawseti(L
, -2, (i
+ offset
));
1947 static int lua_nodelib_subtypes(lua_State
* L
)
1951 const char **subtypes
= NULL
;
1953 int t
= lua_type(L
,1);
1954 if (t
== LUA_TSTRING
) {
1955 /* official accessors */
1956 s
= lua_tostring(L
,1);
1957 if (lua_key_eq(s
,glyph
)) subtypes
= node_subtypes_glyph
;
1958 else if (lua_key_eq(s
,glue
)) { subtypes
= node_subtypes_glue
; l
= 1; }
1959 else if (lua_key_eq(s
,boundary
)) subtypes
= node_subtypes_boundary
;
1960 else if (lua_key_eq(s
,penalty
)) subtypes
= node_subtypes_penalty
;
1961 else if (lua_key_eq(s
,kern
)) subtypes
= node_subtypes_kern
;
1962 else if (lua_key_eq(s
,rule
)) subtypes
= node_subtypes_rule
;
1963 else if (lua_key_eq(s
,list
)
1964 || lua_key_eq(s
,hlist
)
1965 || lua_key_eq(s
,vlist
)) subtypes
= node_subtypes_list
; /* too many but ok as reserved */
1966 else if (lua_key_eq(s
,adjust
)) subtypes
= node_subtypes_adjust
;
1967 else if (lua_key_eq(s
,disc
)) subtypes
= node_subtypes_disc
;
1968 else if (lua_key_eq(s
,fill
)) subtypes
= node_subtypes_fill
;
1969 else if (lua_key_eq(s
,leader
)) { subtypes
= node_subtypes_leader
; l
= 2; }
1970 else if (lua_key_eq(s
,marginkern
)) subtypes
= node_subtypes_marginkern
;
1971 else if (lua_key_eq(s
,math
)) subtypes
= node_subtypes_math
;
1972 else if (lua_key_eq(s
,noad
)) subtypes
= node_subtypes_noad
;
1973 else if (lua_key_eq(s
,radical
)) subtypes
= node_subtypes_radical
;
1974 else if (lua_key_eq(s
,accent
)) subtypes
= node_subtypes_accent
;
1975 else if (lua_key_eq(s
,fence
)) subtypes
= node_subtypes_fence
;
1977 else if (lua_key_eq(s
,pdf_destination
)) subtypes
= node_subtypes_pdf_destination
;
1978 else if (lua_key_eq(s
,pdf_literal
)) subtypes
= node_subtypes_pdf_literal
;
1979 } else if (t
== LUA_TNUMBER
) {
1981 t
= lua_tointeger(L
,1);
1982 if (t
== glyph_node
) subtypes
= node_subtypes_glyph
;
1983 else if (t
== glue_node
) { subtypes
= node_subtypes_glue
; l
= 1; }
1984 else if (t
== boundary_node
) subtypes
= node_subtypes_boundary
;
1985 else if (t
== penalty_node
) subtypes
= node_subtypes_penalty
;
1986 else if (t
== kern_node
) subtypes
= node_subtypes_kern
;
1987 else if (t
== rule_node
) subtypes
= node_subtypes_rule
;
1988 else if((t
== hlist_node
)
1989 || (t
== vlist_node
)) subtypes
= node_subtypes_list
;
1990 else if (t
== adjust_node
) subtypes
= node_subtypes_adjust
;
1991 else if (t
== disc_node
) subtypes
= node_subtypes_disc
;
1992 else if (t
== glue_spec_node
) subtypes
= node_subtypes_fill
;
1993 else if (t
== margin_kern_node
) subtypes
= node_subtypes_marginkern
;
1994 else if (t
== math_node
) subtypes
= node_subtypes_math
;
1995 else if (t
== simple_noad
) subtypes
= node_subtypes_noad
;
1996 else if (t
== radical_noad
) subtypes
= node_subtypes_radical
;
1997 else if (t
== accent_noad
) subtypes
= node_subtypes_accent
;
1998 else if (t
== fence_noad
) subtypes
= node_subtypes_fence
;
2000 else if (t
== pdf_dest_node
) subtypes
= node_subtypes_pdf_destination
;
2001 else if (t
== pdf_literal_node
) subtypes
= node_subtypes_pdf_literal
;
2003 if (subtypes
!= NULL
) {
2004 lua_checkstack(L
, 2);
2007 for (i
= 0; subtypes
[i
] != NULL
; i
++) {
2008 lua_pushstring(L
, subtypes
[i
]); /* todo */
2009 lua_rawseti(L
, -2, i
);
2013 /* add math states */
2014 for (i
= 0; node_subtypes_mathglue
[i
] != NULL
; i
++) {
2015 lua_pushstring(L
, node_subtypes_mathglue
[i
]); /* todo */
2016 lua_rawseti(L
, -2, 98 + i
);
2019 for (i
= 0; node_subtypes_leader
[i
] != NULL
; i
++) {
2020 lua_pushstring(L
, node_subtypes_leader
[i
]); /* todo */
2021 lua_rawseti(L
, -2, 100 + i
);
2030 /* node.slide (find the end of a list and add prev links) */
2032 static int lua_nodelib_slide(lua_State
* L
)
2035 if (lua_isnil(L
, 1))
2036 return 1; /* the nil itself */
2037 n
= *check_isnode(L
, 1);
2039 return 1; /* the old userdata */
2040 /* alink(t) = null; */ /* don't do this, |t|'s |alink| may be a valid pointer */
2041 while (vlink(n
) != null
) {
2042 alink(vlink(n
)) = n
;
2045 lua_nodelib_push_fast(L
, n
);
2049 /* node.direct.slide */
2051 static int lua_nodelib_direct_slide(lua_State
* L
)
2053 halfword n
= lua_tointeger(L
, 1);
2057 while (vlink(n
) != null
) {
2058 alink(vlink(n
)) = n
;
2061 lua_pushinteger(L
, n
);
2066 /* node.tail (find the end of a list) */
2068 static int lua_nodelib_tail(lua_State
* L
)
2071 if (lua_isnil(L
, 1))
2072 return 1; /* the nil itself */
2073 n
= *check_isnode(L
, 1);
2075 return 1; /* the old userdata */
2076 while (vlink(n
) != null
)
2078 lua_nodelib_push_fast(L
, n
);
2082 /* node.direct.tail */
2084 static int lua_nodelib_direct_tail(lua_State
* L
)
2086 halfword n
= lua_tointeger(L
, 1);
2090 while (vlink(n
) != null
)
2092 lua_pushinteger(L
, n
);
2097 /* node.end_of_math (skip over math and return last) */
2099 static int lua_nodelib_end_of_math(lua_State
* L
)
2102 if (lua_isnil(L
, 1))
2104 n
= *check_isnode(L
, 1);
2107 if (type(n
) == math_node
&& (subtype(n
) == 1)) {
2108 lua_nodelib_push_fast(L
, n
);
2111 while (vlink(n
) != null
) {
2113 if (n
&& (type(n
) == math_node
) && (subtype(n
) == 1)) {
2114 lua_nodelib_push_fast(L
, n
);
2121 /* node.direct.end_of_math */
2123 static int lua_nodelib_direct_end_of_math(lua_State
* L
)
2125 halfword n
= lua_tointeger(L
, 1);
2128 if ((type(n
)==math_node
&& (subtype(n
)==1))) {
2129 lua_pushinteger(L
, n
);
2132 while (vlink(n
) != null
) {
2134 if (n
&& (type(n
)==math_node
) && (subtype(n
)==1)) {
2135 lua_pushinteger(L
, n
);
2143 /* node.has_attribute (gets attribute) */
2145 static int lua_nodelib_has_attribute(lua_State
* L
)
2148 halfword n
= *check_isnode(L
, 1);
2150 i
= lua_tointeger(L
, 2);
2151 val
= luaL_optinteger(L
, 3, UNUSED_ATTRIBUTE
);
2152 if ((val
= has_attribute(n
, i
, val
)) > UNUSED_ATTRIBUTE
) {
2153 lua_pushinteger(L
, val
);
2161 /* node.direct.has_attribute */
2163 static int lua_nodelib_direct_has_attribute(lua_State
* L
)
2166 halfword n
= lua_tointeger(L
, 1);
2168 i
= lua_tointeger(L
, 2);
2169 val
= luaL_optinteger(L
, 3, UNUSED_ATTRIBUTE
);
2170 if ((val
= has_attribute(n
, i
, val
)) > UNUSED_ATTRIBUTE
) {
2171 lua_pushinteger(L
, val
);
2179 /* node.get_attribute */
2181 static int lua_nodelib_get_attribute(lua_State
* L
)
2184 p
= *check_isnode(L
, 1);
2185 if (nodetype_has_attributes(type(p
))) {
2190 int i
= lua_tointeger(L
, 2);
2192 if (attribute_id(p
) == i
) {
2193 int ret
= attribute_value(p
);
2194 if (ret
== UNUSED_ATTRIBUTE
) {
2197 lua_pushinteger(L
,ret
);
2200 } else if (attribute_id(p
) > i
) {
2212 /* node.direct.get_attribute */
2214 static int lua_nodelib_direct_get_attribute(lua_State
* L
)
2216 register halfword p
= lua_tointeger(L
, 1);
2217 if (nodetype_has_attributes(type(p
))) {
2222 int i
= lua_tointeger(L
, 2);
2224 if (attribute_id(p
) == i
) {
2225 int ret
= attribute_value(p
);
2226 if (ret
== UNUSED_ATTRIBUTE
) {
2229 lua_pushinteger(L
,ret
);
2232 } else if (attribute_id(p
) > i
) {
2244 /* node.set_attribute */
2246 static int lua_nodelib_set_attribute(lua_State
* L
)
2248 if (lua_gettop(L
) == 3) {
2249 int i
= lua_tointeger(L
, 2);
2250 int val
= lua_tointeger(L
, 3);
2251 halfword n
= *check_isnode(L
, 1);
2252 if (val
== UNUSED_ATTRIBUTE
) {
2253 (void) unset_attribute(n
, i
, val
);
2255 set_attribute(n
, i
, val
);
2258 luaL_error(L
, "incorrect number of arguments");
2263 /* node.direct.set_attribute */
2265 static int lua_nodelib_direct_set_attribute(lua_State
* L
)
2268 halfword n
= lua_tointeger(L
, 1);
2271 if (lua_gettop(L
) == 3) {
2272 i
= (int) lua_tointeger(L
, 2);
2273 val
= (int) lua_tointeger(L
, 3);
2274 if (val
== UNUSED_ATTRIBUTE
) {
2275 (void) unset_attribute(n
, i
, val
);
2277 set_attribute(n
, i
, val
);
2280 luaL_error(L
, "incorrect number of arguments");
2285 /* node.unset_attribute */
2287 static int lua_nodelib_unset_attribute(lua_State
* L
)
2289 if (lua_gettop(L
) <= 3) {
2290 int i
= luaL_checknumber(L
, 2);
2291 int val
= luaL_optnumber(L
, 3, UNUSED_ATTRIBUTE
);
2292 halfword n
= *check_isnode(L
, 1);
2293 int ret
= unset_attribute(n
, i
, val
);
2294 if (ret
> UNUSED_ATTRIBUTE
) {
2295 lua_pushinteger(L
, ret
);
2301 return luaL_error(L
, "incorrect number of arguments");
2305 /* node.direct.unset_attribute */
2307 static int lua_nodelib_direct_unset_attribute(lua_State
* L
)
2309 halfword n
= lua_tointeger(L
, 1);
2312 } else if (lua_gettop(L
) <= 3) { /* a useless test, we never test for that elsewhere */
2313 int i
= (int)luaL_checknumber(L
, 2);
2314 int val
= (int)luaL_optnumber(L
, 3, UNUSED_ATTRIBUTE
);
2315 int ret
= unset_attribute(n
, i
, val
);
2316 if (ret
> UNUSED_ATTRIBUTE
) {
2317 lua_pushinteger(L
, ret
);
2321 } else { /* can go */
2322 return luaL_error(L
, "incorrect number of arguments");
2329 static int lua_nodelib_set_glue(lua_State
* L
)
2331 halfword n
= *check_isnode(L
, 1);
2332 int top
= lua_gettop(L
) ;
2333 if ((n
!= null
) && (type(n
) == glue_node
|| type(n
) == glue_spec_node
)) {
2334 width(n
) = ((top
> 1 && lua_type(L
, 2) == LUA_TNUMBER
)) ? lua_tointeger(L
,2) : 0;
2335 stretch(n
) = ((top
> 2 && lua_type(L
, 3) == LUA_TNUMBER
)) ? lua_tointeger(L
,3) : 0;
2336 shrink(n
) = ((top
> 3 && lua_type(L
, 4) == LUA_TNUMBER
)) ? lua_tointeger(L
,4) : 0;
2337 stretch_order(n
) = ((top
> 4 && lua_type(L
, 5) == LUA_TNUMBER
)) ? lua_tointeger(L
,5) : 0;
2338 shrink_order(n
) = ((top
> 5 && lua_type(L
, 6) == LUA_TNUMBER
)) ? lua_tointeger(L
,6) : 0;
2341 return luaL_error(L
, "glue (spec) expected");
2345 static int lua_nodelib_direct_set_glue(lua_State
* L
)
2347 halfword n
= lua_tointeger(L
, 1);
2348 int top
= lua_gettop(L
) ;
2349 if ((n
!= null
) && (type(n
) == glue_node
|| type(n
) == glue_spec_node
)) {
2350 width(n
) = ((top
> 1 && lua_type(L
, 2) == LUA_TNUMBER
)) ? lua_tointeger(L
,2) : 0;
2351 stretch(n
) = ((top
> 2 && lua_type(L
, 3) == LUA_TNUMBER
)) ? lua_tointeger(L
,3) : 0;
2352 shrink(n
) = ((top
> 3 && lua_type(L
, 4) == LUA_TNUMBER
)) ? lua_tointeger(L
,4) : 0;
2353 stretch_order(n
) = ((top
> 4 && lua_type(L
, 5) == LUA_TNUMBER
)) ? lua_tointeger(L
,5) : 0;
2354 shrink_order(n
) = ((top
> 5 && lua_type(L
, 6) == LUA_TNUMBER
)) ? lua_tointeger(L
,6) : 0;
2357 return luaL_error(L
, "glue (spec) expected");
2361 static int lua_nodelib_get_glue(lua_State
* L
)
2363 halfword n
= *check_isnode(L
, 1);
2364 if ((n
!= null
) && (type(n
) == glue_node
|| type(n
) == glue_spec_node
)) {
2365 lua_pushinteger(L
,width(n
));
2366 lua_pushinteger(L
,stretch(n
));
2367 lua_pushinteger(L
,shrink(n
));
2368 lua_pushinteger(L
,stretch_order(n
));
2369 lua_pushinteger(L
,shrink_order(n
));
2372 return luaL_error(L
, "glue (spec) expected");
2376 static int lua_nodelib_direct_get_glue(lua_State
* L
)
2378 halfword n
= lua_tointeger(L
, 1);
2379 if ((n
!= null
) && (type(n
) == glue_node
|| type(n
) == glue_spec_node
)) {
2380 lua_pushinteger(L
,width(n
));
2381 lua_pushinteger(L
,stretch(n
));
2382 lua_pushinteger(L
,shrink(n
));
2383 lua_pushinteger(L
,stretch_order(n
));
2384 lua_pushinteger(L
,shrink_order(n
));
2387 return luaL_error(L
, "glue (spec) expected");
2391 static int lua_nodelib_is_zero_glue(lua_State
* L
)
2393 halfword n
= *check_isnode(L
, 1);
2394 if ((n
!= null
) && (type(n
) == glue_node
|| type(n
) == glue_spec_node
)) {
2395 lua_toboolean(L
,(width(n
) == 0 && stretch(n
) == 0 && shrink(n
) == 0));
2398 return luaL_error(L
, "glue (spec) expected");
2402 static int lua_nodelib_direct_is_zero_glue(lua_State
* L
)
2404 halfword n
= lua_tointeger(L
, 1);
2405 if ((n
!= null
) && (type(n
) == glue_node
|| type(n
) == glue_spec_node
)) {
2406 lua_toboolean(L
,(width(n
) == 0 && stretch(n
) == 0 && shrink(n
) == 0));
2409 return luaL_error(L
, "glue (spec) expected");
2415 static int nodelib_aux_nil(lua_State
* L
)
2421 /* node.traverse_id */
2423 static int nodelib_aux_next_filtered(lua_State
* L
)
2425 halfword t
; /* traverser */
2427 int i
= (int) lua_tointeger(L
, lua_upvalueindex(1));
2428 if (lua_isnil(L
, 2)) { /* first call */
2429 t
= *check_isnode(L
, 1);
2432 t
= *check_isnode(L
, 2);
2436 while (t
!= null
&& type(t
) != i
) {
2442 fast_metatable_top(t
);
2447 static int lua_nodelib_traverse_filtered(lua_State
* L
)
2450 if (lua_isnil(L
, 2)) {
2451 lua_pushcclosure(L
, nodelib_aux_nil
, 0);
2454 n
= *check_isnode(L
, 2);
2455 lua_pop(L
, 1); /* the node, integer remains */
2456 lua_pushcclosure(L
, nodelib_aux_next_filtered
, 1);
2457 lua_nodelib_push_fast(L
, n
);
2462 /* node.direct.traverse_id */
2464 static int nodelib_direct_aux_next_filtered(lua_State
* L
)
2466 halfword t
; /* traverser */
2467 int i
= (int) lua_tointeger(L
, lua_upvalueindex(1));
2468 if (lua_isnil(L
, 2)) { /* first call */
2469 t
= lua_tointeger(L
,1) ;
2472 t
= lua_tointeger(L
,2) ;
2479 } else if (type(t
) == i
) {
2480 lua_pushinteger(L
,t
);
2490 static int lua_nodelib_direct_traverse_filtered(lua_State
* L
)
2493 if (lua_isnil(L
, 2)) {
2494 lua_pushcclosure(L
, nodelib_aux_nil
, 0);
2497 n
= (halfword
) lua_tointeger(L
, 2);
2501 lua_pushcclosure(L
, nodelib_direct_aux_next_filtered
, 1);
2502 lua_pushinteger(L
,n
);
2507 /* node.direct.traverse_char */
2509 static int nodelib_direct_aux_next_char(lua_State
* L
)
2511 halfword t
; /* traverser */
2512 if (lua_isnil(L
, 2)) { /* first call */
2513 t
= lua_tointeger(L
,1) ;
2516 t
= lua_tointeger(L
,2) ;
2523 } else if ((type(t
) == glyph_node
) && (subtype(t
) < 256)){
2524 lua_pushinteger(L
,t
);
2534 static int lua_nodelib_direct_traverse_char(lua_State
* L
)
2537 if (lua_isnil(L
, 1)) {
2538 lua_pushcclosure(L
, nodelib_aux_nil
, 0);
2541 n
= (halfword
) lua_tointeger(L
, 1);
2543 lua_pushcclosure(L
, nodelib_aux_nil
, 0);
2546 lua_pushcclosure(L
, nodelib_direct_aux_next_char
, 0);
2547 lua_pushinteger(L
,n
);
2554 static int nodelib_aux_next(lua_State
* L
)
2556 halfword t
; /* traverser */
2557 halfword
*a
; /* a or *a */
2558 if (lua_isnil(L
, 2)) { /* first call */
2559 t
= *check_isnode(L
, 1);
2562 t
= *check_isnode(L
, 2);
2569 fast_metatable_top(t
);
2574 static int lua_nodelib_traverse(lua_State
* L
)
2577 if (lua_isnil(L
, 1)) {
2578 lua_pushcclosure(L
, nodelib_aux_nil
, 0);
2581 n
= *check_isnode(L
, 1);
2582 lua_pushcclosure(L
, nodelib_aux_next
, 0);
2583 lua_nodelib_push_fast(L
, n
);
2588 /* node.traverse_char */
2590 static int nodelib_aux_next_char(lua_State
* L
)
2592 halfword t
; /* traverser */
2594 if (lua_isnil(L
, 2)) { /* first call */
2595 t
= *check_isnode(L
, 1);
2598 t
= *check_isnode(L
, 2);
2605 } else if ((type(t
) == glyph_node
) && (subtype(t
) < 256)){
2606 fast_metatable_top(t
);
2615 static int lua_nodelib_traverse_char(lua_State
* L
)
2618 if (lua_isnil(L
, 1)) {
2619 lua_pushcclosure(L
, nodelib_aux_nil
, 0);
2622 n
= *check_isnode(L
, 1);
2623 lua_pushcclosure(L
, nodelib_aux_next_char
, 0);
2624 lua_nodelib_push_fast(L
, n
);
2629 /* node.direct.traverse */
2631 static int nodelib_direct_aux_next(lua_State
* L
)
2633 halfword t
; /* traverser */
2634 if (lua_isnil(L
, 2)) { /* first call */
2635 t
= lua_tointeger(L
,1) ;
2638 t
= lua_tointeger(L
,2) ;
2645 lua_pushinteger(L
,t
);
2650 static int lua_nodelib_direct_traverse(lua_State
* L
)
2653 if (lua_isnil(L
, 1)) {
2654 lua_pushcclosure(L
, nodelib_aux_nil
, 0);
2657 n
= (halfword
) lua_tointeger(L
, 1);
2659 lua_pushcclosure(L
, nodelib_aux_nil
, 0);
2662 lua_pushcclosure(L
, nodelib_direct_aux_next
, 0);
2663 lua_pushinteger(L
,n
);
2670 static int do_lua_nodelib_count(lua_State
* L
, halfword match
, int i
, halfword first1
)
2674 while (t
!= match
) {
2675 if (i
< 0 || type(t
) == i
)
2679 lua_pushinteger(L
, count
);
2685 static int lua_nodelib_length(lua_State
* L
)
2689 if (lua_isnil(L
, 1)) {
2690 lua_pushinteger(L
, 0);
2693 n
= *check_isnode(L
, 1);
2694 if (lua_gettop(L
) == 2)
2695 m
= *check_isnode(L
, 2);
2696 return do_lua_nodelib_count(L
, m
, -1, n
);
2699 /* node.direct.length */
2701 static int lua_nodelib_direct_length(lua_State
* L
)
2704 halfword n
= lua_tointeger(L
, 1);
2706 lua_pushinteger(L
, 0);
2709 m
= (halfword
) lua_tointeger(L
, 2);
2710 return do_lua_nodelib_count(L
, m
, -1, n
);
2715 static int lua_nodelib_count(lua_State
* L
)
2719 int i
= lua_tointeger(L
, 1);
2720 if (lua_isnil(L
, 2)) {
2721 lua_pushinteger(L
, 0);
2724 n
= *check_isnode(L
, 2);
2725 if (lua_gettop(L
) == 3)
2726 m
= *check_isnode(L
, 3);
2727 return do_lua_nodelib_count(L
, m
, i
, n
);
2730 /* node.direct.count */
2732 static int lua_nodelib_direct_count(lua_State
* L
)
2734 return do_lua_nodelib_count(L
,
2735 (halfword
) lua_tointeger(L
, 3), /* m */
2736 (int) lua_tointeger(L
, 1), /* i */
2737 (halfword
) lua_tointeger(L
, 2) /* n */
2741 /* getting and setting fields (helpers) */
2743 int nodelib_getlist(lua_State
* L
, int n
)
2745 if (lua_isuserdata(L
, n
)) {
2746 halfword m
= *check_isnode(L
, n
);
2753 int nodelib_getdir(lua_State
* L
, int n
, int absolute_only
)
2755 if (lua_type(L
, n
) == LUA_TSTRING
) {
2756 const char *s
= lua_tostring(L
, n
);
2757 RETURN_DIR_VALUES(TLT
);
2758 RETURN_DIR_VALUES(TRT
);
2759 RETURN_DIR_VALUES(LTL
);
2760 RETURN_DIR_VALUES(RTT
);
2761 luaL_error(L
, "Bad direction specifier %s", s
);
2763 luaL_error(L
, "Direction specifiers have to be strings");
2768 static str_number
nodelib_getstring(lua_State
* L
, int a
)
2771 const char *s
= lua_tolstring(L
, a
, &k
);
2772 return maketexlstring(s
, k
);
2775 static int nodelib_cantset(lua_State
* L
, int n
, const char *s
)
2777 luaL_error(L
,"You cannot set field %s in a node of type %s",s
,node_data
[type(n
)].name
);
2781 /* node.direct.getfield */
2783 static void lua_nodelib_getfield_whatsit(lua_State
* L
, int n
, const char *s
)
2786 if (t
== user_defined_node
) {
2787 if (lua_key_eq(s
, user_id
)) {
2788 lua_pushinteger(L
, user_node_id(n
));
2789 } else if (lua_key_eq(s
, type
)) {
2790 lua_pushinteger(L
, user_node_type(n
));
2791 } else if (lua_key_eq(s
, value
)) {
2792 switch (user_node_type(n
)) {
2794 nodelib_pushlist(L
, user_node_value(n
));
2797 lua_pushinteger(L
, user_node_value(n
));
2800 if (user_node_value(n
) != 0) {
2801 lua_rawgeti(L
, LUA_REGISTRYINDEX
, user_node_value(n
));
2807 nodelib_pushlist(L
, user_node_value(n
));
2810 nodelib_pushstring(L
, user_node_value(n
));
2813 tokenlist_to_lua(L
, user_node_value(n
));
2816 lua_pushinteger(L
, user_node_value(n
));
2822 } else if (t
== pdf_literal_node
) {
2823 if (lua_key_eq(s
, mode
)) {
2824 lua_pushinteger(L
, pdf_literal_mode(n
));
2825 } else if (lua_key_eq(s
, data
)) {
2826 if (pdf_literal_type(n
) == lua_refid_literal
) {
2827 lua_rawgeti(L
, LUA_REGISTRYINDEX
, pdf_literal_data(n
));
2829 tokenlist_to_luastring(L
, pdf_literal_data(n
));
2834 } else if (t
== late_lua_node
) {
2835 if (lua_key_eq(s
, string
) || lua_key_eq(s
, data
)) {
2836 if (late_lua_type(n
) == lua_refid_literal
) {
2837 lua_rawgeti(L
, LUA_REGISTRYINDEX
, late_lua_data(n
));
2839 tokenlist_to_luastring(L
, late_lua_data(n
));
2841 } else if (lua_key_eq(s
, name
)) {
2842 tokenlist_to_luastring(L
, late_lua_name(n
));
2846 } else if (t
== pdf_annot_node
) {
2847 if (lua_key_eq(s
, width
)) {
2848 lua_pushinteger(L
, width(n
));
2849 } else if (lua_key_eq(s
, depth
)) {
2850 lua_pushinteger(L
, depth(n
));
2851 } else if (lua_key_eq(s
, height
)) {
2852 lua_pushinteger(L
, height(n
));
2853 } else if (lua_key_eq(s
, objnum
)) {
2854 lua_pushinteger(L
, pdf_annot_objnum(n
));
2855 } else if (lua_key_eq(s
, data
)) {
2856 tokenlist_to_luastring(L
, pdf_annot_data(n
));
2860 } else if (t
== pdf_dest_node
) {
2861 if (lua_key_eq(s
, width
)) {
2862 lua_pushinteger(L
, width(n
));
2863 } else if (lua_key_eq(s
, depth
)) {
2864 lua_pushinteger(L
, depth(n
));
2865 } else if (lua_key_eq(s
, height
)) {
2866 lua_pushinteger(L
, height(n
));
2867 } else if (lua_key_eq(s
, named_id
)) {
2868 lua_pushinteger(L
, pdf_dest_named_id(n
));
2869 } else if (lua_key_eq(s
, dest_id
)) {
2870 if (pdf_dest_named_id(n
) == 1)
2871 tokenlist_to_luastring(L
, pdf_dest_id(n
));
2873 lua_pushinteger(L
, pdf_dest_id(n
));
2874 } else if (lua_key_eq(s
, dest_type
)) {
2875 lua_pushinteger(L
, pdf_dest_type(n
));
2876 } else if (lua_key_eq(s
, xyz_zoom
)) {
2877 lua_pushinteger(L
, pdf_dest_xyz_zoom(n
));
2878 } else if (lua_key_eq(s
, objnum
)) {
2879 lua_pushinteger(L
, pdf_dest_objnum(n
));
2883 } else if (t
== pdf_setmatrix_node
) {
2884 if (lua_key_eq(s
, data
)) {
2885 tokenlist_to_luastring(L
, pdf_setmatrix_data(n
));
2889 } else if (t
== pdf_colorstack_node
) {
2890 if (lua_key_eq(s
, stack
)) {
2891 lua_pushinteger(L
, pdf_colorstack_stack(n
));
2892 } else if (lua_key_eq(s
, command
)) {
2893 lua_pushinteger(L
, pdf_colorstack_cmd(n
));
2894 } else if (lua_key_eq(s
, data
)) {
2895 tokenlist_to_luastring(L
, pdf_colorstack_data(n
));
2899 } else if (t
== pdf_refobj_node
) {
2900 if (lua_key_eq(s
, objnum
)) {
2901 lua_pushinteger(L
, pdf_obj_objnum(n
));
2905 } else if (t
== write_node
) {
2906 if (lua_key_eq(s
, stream
)) {
2907 lua_pushinteger(L
, write_stream(n
));
2908 } else if (lua_key_eq(s
, data
)) {
2909 tokenlist_to_lua(L
, write_tokens(n
));
2913 } else if (t
== special_node
) {
2914 if (lua_key_eq(s
, data
)) {
2915 tokenlist_to_luastring(L
, write_tokens(n
));
2919 } else if (t
== pdf_start_link_node
) {
2920 if (lua_key_eq(s
, width
)) {
2921 lua_pushinteger(L
, width(n
));
2922 } else if (lua_key_eq(s
, depth
)) {
2923 lua_pushinteger(L
, depth(n
));
2924 } else if (lua_key_eq(s
, height
)) {
2925 lua_pushinteger(L
, height(n
));
2926 } else if (lua_key_eq(s
, objnum
)) {
2927 lua_pushinteger(L
, pdf_link_objnum(n
));
2928 } else if (lua_key_eq(s
, link_attr
)) {
2929 tokenlist_to_luastring(L
, pdf_link_attr(n
));
2930 } else if (lua_key_eq(s
, action
)) {
2931 nodelib_pushaction(L
, pdf_link_action(n
));
2935 } else if (t
== pdf_action_node
) {
2936 if (lua_key_eq(s
, action_type
)) {
2937 lua_pushinteger(L
, pdf_action_type(n
));
2938 } else if (lua_key_eq(s
, named_id
)) {
2939 lua_pushinteger(L
, pdf_action_named_id(n
));
2940 } else if (lua_key_eq(s
, action_id
)) {
2941 if (pdf_action_named_id(n
) == 1) {
2942 tokenlist_to_luastring(L
, pdf_action_id(n
));
2944 lua_pushinteger(L
, pdf_action_id(n
));
2946 } else if (lua_key_eq(s
, file
)) {
2947 tokenlist_to_luastring(L
, pdf_action_file(n
));
2948 } else if (lua_key_eq(s
, new_window
)) {
2949 lua_pushinteger(L
, pdf_action_new_window(n
));
2950 } else if (lua_key_eq(s
, data
)) {
2951 tokenlist_to_luastring(L
, pdf_action_tokens(n
));
2955 } else if ((t
== pdf_thread_node
) || (t
== pdf_start_thread_node
)) {
2956 if (lua_key_eq(s
, width
)) {
2957 lua_pushinteger(L
, width(n
));
2958 } else if (lua_key_eq(s
, depth
)) {
2959 lua_pushinteger(L
, depth(n
));
2960 } else if (lua_key_eq(s
, height
)) {
2961 lua_pushinteger(L
, height(n
));
2962 } else if (lua_key_eq(s
, named_id
)) {
2963 lua_pushinteger(L
, pdf_thread_named_id(n
));
2964 } else if (lua_key_eq(s
, thread_id
)) {
2965 if (pdf_thread_named_id(n
) == 1) {
2966 tokenlist_to_luastring(L
, pdf_thread_id(n
));
2968 lua_pushinteger(L
, pdf_thread_id(n
));
2970 } else if (lua_key_eq(s
, thread_attr
)) {
2971 tokenlist_to_luastring(L
, pdf_thread_attr(n
));
2975 } else if (t
== open_node
) {
2976 if (lua_key_eq(s
, stream
)) {
2977 lua_pushinteger(L
, write_stream(n
));
2978 } else if (lua_key_eq(s
, name
)) {
2979 nodelib_pushstring(L
, open_name(n
));
2980 } else if (lua_key_eq(s
, area
)) {
2981 nodelib_pushstring(L
, open_area(n
));
2982 } else if (lua_key_eq(s
, ext
)) {
2983 nodelib_pushstring(L
, open_ext(n
));
2987 } else if (t
== close_node
) {
2988 if (lua_key_eq(s
, stream
)) {
2989 lua_pushinteger(L
, write_stream(n
));
2998 static int lua_nodelib_fast_getfield(lua_State
* L
)
3001 the order is somewhat determined by the occurance of nodes and
3002 importance of fields
3008 halfword n
= *((halfword
*) lua_touserdata(L
, 1));
3013 somenode[9] as interface to attributes ... 30% faster than has_attribute
3014 (1) because there is no lua function overhead, and (2) because we already
3015 know that we deal with a node so no checking is needed. The fast typecheck
3016 is needed (lua_check... is a slow down actually).
3020 if (lua_type(L
, 2) == LUA_TNUMBER
) {
3025 if (! nodetype_has_attributes(t
)) {
3031 if (p
== null
|| vlink(p
) == null
) {
3035 i
= (int) lua_tointeger(L
, 2);
3038 if (attribute_id(p
) == i
) {
3039 if ((int) attribute_value(p
) > UNUSED_ATTRIBUTE
) {
3040 lua_pushinteger(L
, (int) attribute_value(p
));
3045 } else if (attribute_id(p
) > i
) {
3055 s
= lua_tostring(L
, 2);
3057 if (lua_key_eq(s
, id
)) {
3058 lua_pushinteger(L
, t
);
3059 } else if (lua_key_eq(s
, next
)) {
3060 fast_metatable_or_nil(vlink(n
));
3061 } else if (lua_key_eq(s
, prev
)) {
3062 fast_metatable_or_nil(alink(n
));
3063 } else if (lua_key_eq(s
, attr
)) {
3064 if (! nodetype_has_attributes(t
)) {
3067 nodelib_pushattr(L
, node_attr(n
));
3069 } else if (t
== glyph_node
) {
3070 /* candidates: fontchar (font,char) whd (width,height,depth) */
3071 if (lua_key_eq(s
, subtype
)) {
3072 lua_pushinteger(L
, subtype(n
));
3073 } else if (lua_key_eq(s
, font
)) {
3074 lua_pushinteger(L
, font(n
));
3075 } else if (lua_key_eq(s
, char)) {
3076 lua_pushinteger(L
, character(n
));
3077 } else if (lua_key_eq(s
, xoffset
)) {
3078 lua_pushinteger(L
, x_displace(n
));
3079 } else if (lua_key_eq(s
, yoffset
)) {
3080 lua_pushinteger(L
, y_displace(n
));
3081 } else if (lua_key_eq(s
, xadvance
)) {
3082 lua_pushinteger(L
, x_advance(n
));
3083 } else if (lua_key_eq(s
, width
)) {
3084 lua_pushinteger(L
, char_width(font(n
),character(n
)));
3085 } else if (lua_key_eq(s
, height
)) {
3086 lua_pushinteger(L
, char_height(font(n
),character(n
)));
3087 } else if (lua_key_eq(s
, depth
)) {
3088 lua_pushinteger(L
, char_depth(font(n
),character(n
)));
3089 } else if (lua_key_eq(s
, expansion_factor
)) {
3090 lua_pushinteger(L
, ex_glyph(n
));
3091 } else if (lua_key_eq(s
, components
)) {
3092 fast_metatable_or_nil(lig_ptr(n
));
3093 } else if (lua_key_eq(s
, lang
)) {
3094 lua_pushinteger(L
, char_lang(n
));
3095 } else if (lua_key_eq(s
, left
)) {
3096 lua_pushinteger(L
, char_lhmin(n
));
3097 } else if (lua_key_eq(s
, right
)) {
3098 lua_pushinteger(L
, char_rhmin(n
));
3099 } else if (lua_key_eq(s
, uchyph
)) {
3100 lua_pushinteger(L
, char_uchyph(n
));
3104 } else if ((t
== hlist_node
) || (t
== vlist_node
)) {
3105 /* candidates: whd (width,height,depth) */
3106 if (lua_key_eq(s
, subtype
)) {
3107 lua_pushinteger(L
, subtype(n
));
3108 } else if (lua_key_eq(s
, list
) || lua_key_eq(s
, head
)) {
3109 fast_metatable_or_nil_alink(list_ptr(n
));
3110 } else if (lua_key_eq(s
, width
)) {
3111 lua_pushinteger(L
, width(n
));
3112 } else if (lua_key_eq(s
, height
)) {
3113 lua_pushinteger(L
, height(n
));
3114 } else if (lua_key_eq(s
, depth
)) {
3115 lua_pushinteger(L
, depth(n
));
3116 } else if (lua_key_eq(s
, dir
)) {
3117 lua_push_dir_par(L
, box_dir(n
));
3118 } else if (lua_key_eq(s
, shift
)) {
3119 lua_pushinteger(L
, shift_amount(n
));
3120 } else if (lua_key_eq(s
, glue_order
)) {
3121 lua_pushinteger(L
, glue_order(n
));
3122 } else if (lua_key_eq(s
, glue_sign
)) {
3123 lua_pushinteger(L
, glue_sign(n
));
3124 } else if (lua_key_eq(s
, glue_set
)) {
3125 lua_pushnumber(L
, (double) glue_set(n
)); /* float */
3129 } else if (t
== disc_node
) {
3130 if (lua_key_eq(s
, subtype
)) {
3131 lua_pushinteger(L
, subtype(n
));
3132 } else if (lua_key_eq(s
, pre
)) {
3133 fast_metatable_or_nil(vlink(pre_break(n
)));
3134 } else if (lua_key_eq(s
, post
)) {
3135 fast_metatable_or_nil(vlink(post_break(n
)));
3136 } else if (lua_key_eq(s
, replace
)) {
3137 fast_metatable_or_nil(vlink(no_break(n
)));
3138 } else if (lua_key_eq(s
, penalty
)) {
3139 lua_pushinteger(L
, disc_penalty(n
));
3143 } else if (t
== glue_node
) {
3144 if (lua_key_eq(s
, subtype
)) {
3145 lua_pushinteger(L
, subtype(n
));
3146 } else if (lua_key_eq(s
, width
)) {
3147 lua_pushinteger(L
, width(n
));
3148 } else if (lua_key_eq(s
, stretch
)) {
3149 lua_pushinteger(L
, stretch(n
));
3150 } else if (lua_key_eq(s
, shrink
)) {
3151 lua_pushinteger(L
, shrink(n
));
3152 } else if (lua_key_eq(s
, stretch_order
)) {
3153 lua_pushinteger(L
, stretch_order(n
));
3154 } else if (lua_key_eq(s
, shrink_order
)) {
3155 lua_pushinteger(L
, shrink_order(n
));
3156 } else if (lua_key_eq(s
, leader
)) {
3157 fast_metatable_or_nil(leader_ptr(n
));
3161 } else if (t
== kern_node
) {
3162 if (lua_key_eq(s
, subtype
)) {
3163 lua_pushinteger(L
, subtype(n
));
3164 } else if (lua_key_eq(s
, kern
)) {
3165 lua_pushinteger(L
, width(n
));
3166 } else if (lua_key_eq(s
, expansion_factor
)) {
3167 lua_pushinteger(L
, ex_kern(n
));
3171 } else if (t
== penalty_node
) {
3172 if (lua_key_eq(s
, subtype
)) {
3173 lua_pushinteger(L
, subtype(n
));
3174 } else if (lua_key_eq(s
, penalty
)) {
3175 lua_pushinteger(L
, penalty(n
));
3179 } else if (t
== rule_node
) {
3180 /* candidates: whd (width,height,depth) */
3181 if (lua_key_eq(s
, subtype
)) {
3182 lua_pushinteger(L
, subtype(n
));
3183 } else if (lua_key_eq(s
, width
)) {
3184 lua_pushinteger(L
, width(n
));
3185 } else if (lua_key_eq(s
, height
)) {
3186 lua_pushinteger(L
, height(n
));
3187 } else if (lua_key_eq(s
, depth
)) {
3188 lua_pushinteger(L
, depth(n
));
3189 } else if (lua_key_eq(s
, dir
)) {
3190 lua_push_dir_par(L
, rule_dir(n
));
3191 } else if (lua_key_eq(s
, index
)) {
3192 lua_pushinteger(L
, rule_index(n
));
3193 } else if (lua_key_eq(s
, transform
)) {
3194 lua_pushinteger(L
,rule_transform(n
));
3198 } else if (t
== dir_node
) {
3199 if (lua_key_eq(s
, dir
)) {
3200 lua_push_dir_text(L
, dir_dir(n
));
3201 } else if (lua_key_eq(s
, level
)) {
3202 lua_pushinteger(L
, dir_level(n
));
3203 } else if (lua_key_eq(s
, subtype
)) { /* can be used for anything */
3204 lua_pushinteger(L
, subtype(n
));
3208 } else if (t
== local_par_node
) {
3209 if (lua_key_eq(s
, pen_inter
)) {
3210 lua_pushinteger(L
, local_pen_inter(n
));
3211 } else if (lua_key_eq(s
, pen_broken
)) {
3212 lua_pushinteger(L
, local_pen_broken(n
));
3213 } else if (lua_key_eq(s
, dir
)) {
3214 lua_push_dir_par(L
, local_par_dir(n
));
3215 } else if (lua_key_eq(s
, box_left
)) {
3216 /* can be: fast_metatable_or_nil(local_box_left(n)) */
3217 nodelib_pushlist(L
, local_box_left(n
));
3218 } else if (lua_key_eq(s
, box_left_width
)) {
3219 lua_pushinteger(L
, local_box_left_width(n
));
3220 } else if (lua_key_eq(s
, box_right
)) {
3221 /* can be: fast_metatable_or_nil(local_box_right(n)) */
3222 nodelib_pushlist(L
, local_box_right(n
));
3223 } else if (lua_key_eq(s
, box_right_width
)) {
3224 lua_pushinteger(L
, local_box_right_width(n
));
3228 } else if (t
== glue_spec_node
) {
3229 if (lua_key_eq(s
, width
)) {
3230 lua_pushinteger(L
, width(n
));
3231 } else if (lua_key_eq(s
, stretch
)) {
3232 lua_pushinteger(L
, stretch(n
));
3233 } else if (lua_key_eq(s
, shrink
)) {
3234 lua_pushinteger(L
, shrink(n
));
3235 } else if (lua_key_eq(s
, stretch_order
)) {
3236 lua_pushinteger(L
, stretch_order(n
));
3237 } else if (lua_key_eq(s
, shrink_order
)) {
3238 lua_pushinteger(L
, shrink_order(n
));
3242 } else if (t
== whatsit_node
) {
3243 if (lua_key_eq(s
, subtype
)) {
3244 lua_pushinteger(L
, subtype(n
));
3246 lua_nodelib_getfield_whatsit(L
, n
, s
);
3248 } else if (t
== simple_noad
) {
3249 if (lua_key_eq(s
, subtype
)) {
3250 lua_pushinteger(L
, subtype(n
));
3251 } else if (lua_key_eq(s
, nucleus
)) {
3252 fast_metatable_or_nil(nucleus(n
));
3253 } else if (lua_key_eq(s
, sub
)) {
3254 fast_metatable_or_nil(subscr(n
));
3255 } else if (lua_key_eq(s
, sup
)) {
3256 fast_metatable_or_nil(supscr(n
));
3260 } else if ((t
== math_char_node
) || (t
== math_text_char_node
)) {
3261 /* candidates: famchar (fam,char) */
3262 if (lua_key_eq(s
, subtype
)) {
3263 lua_pushinteger(L
, subtype(n
));
3264 } else if (lua_key_eq(s
, fam
)) {
3265 lua_pushinteger(L
, math_fam(n
));
3266 } else if (lua_key_eq(s
, char)) {
3267 lua_pushinteger(L
, math_character(n
));
3268 } else if (lua_key_eq(s
, font
)) {
3269 lua_pushinteger(L
, fam_fnt(math_fam(n
), 0));
3273 } else if (t
== mark_node
) {
3274 if (lua_key_eq(s
, subtype
)) {
3275 lua_pushinteger(L
, subtype(n
));
3276 } else if (lua_key_eq(s
, class)) {
3277 lua_pushinteger(L
, mark_class(n
));
3278 } else if (lua_key_eq(s
, mark
)) {
3279 tokenlist_to_lua(L
, mark_ptr(n
));
3283 } else if (t
== ins_node
) {
3284 if (lua_key_eq(s
, subtype
)) {
3285 lua_pushinteger(L
, subtype(n
));
3286 } else if (lua_key_eq(s
, cost
)) {
3287 lua_pushinteger(L
, float_cost(n
));
3288 } else if (lua_key_eq(s
, depth
)) {
3289 lua_pushinteger(L
, depth(n
));
3290 } else if (lua_key_eq(s
, height
)) {
3291 lua_pushinteger(L
, height(n
));
3292 } else if ((lua_key_eq(s
, list
)) || (lua_key_eq(s
, head
))) { /* already mapped */
3293 fast_metatable_or_nil_alink(ins_ptr(n
));
3294 /* glue parameters */
3295 } else if (lua_key_eq(s
, width
)) {
3296 lua_pushinteger(L
, width(n
));
3297 } else if (lua_key_eq(s
, stretch
)) {
3298 lua_pushinteger(L
, stretch(n
));
3299 } else if (lua_key_eq(s
, shrink
)) {
3300 lua_pushinteger(L
, shrink(n
));
3301 } else if (lua_key_eq(s
, stretch_order
)) {
3302 lua_pushinteger(L
, stretch_order(n
));
3303 } else if (lua_key_eq(s
, shrink_order
)) {
3304 lua_pushinteger(L
, shrink_order(n
));
3308 } else if (t
== math_node
) {
3309 if (lua_key_eq(s
, subtype
)) {
3310 lua_pushinteger(L
, subtype(n
));
3311 } else if (lua_key_eq(s
, surround
)) {
3312 lua_pushinteger(L
, surround(n
));
3313 /* glue parameters */
3314 } else if (lua_key_eq(s
, width
)) {
3315 lua_pushinteger(L
, width(n
));
3316 } else if (lua_key_eq(s
, stretch
)) {
3317 lua_pushinteger(L
, stretch(n
));
3318 } else if (lua_key_eq(s
, shrink
)) {
3319 lua_pushinteger(L
, shrink(n
));
3320 } else if (lua_key_eq(s
, stretch_order
)) {
3321 lua_pushinteger(L
, stretch_order(n
));
3322 } else if (lua_key_eq(s
, shrink_order
)) {
3323 lua_pushinteger(L
, shrink_order(n
));
3327 } else if (t
== fraction_noad
) {
3328 if (lua_key_eq(s
, subtype
)) {
3329 lua_pushinteger(L
, subtype(n
));
3330 } else if (lua_key_eq(s
, width
)) {
3331 lua_pushinteger(L
, thickness(n
));
3332 } else if (lua_key_eq(s
, num
)) {
3333 fast_metatable_or_nil(numerator(n
));
3334 } else if (lua_key_eq(s
, denom
)) {
3335 fast_metatable_or_nil(denominator(n
));
3336 } else if (lua_key_eq(s
, left
)) {
3337 fast_metatable_or_nil(left_delimiter(n
));
3338 } else if (lua_key_eq(s
, right
)) {
3339 fast_metatable_or_nil(right_delimiter(n
));
3343 } else if (t
== style_node
) {
3344 if (lua_key_eq(s
, subtype
)) {
3345 lua_pushinteger(L
, subtype(n
));
3346 } else if (lua_key_eq(s
, style
)) {
3347 lua_push_math_style_name(L
,subtype(n
));
3351 } else if (t
== accent_noad
) {
3352 if (lua_key_eq(s
, subtype
)) {
3353 lua_pushinteger(L
, subtype(n
));
3354 } else if (lua_key_eq(s
, nucleus
)) {
3355 fast_metatable_or_nil(nucleus(n
));
3356 } else if (lua_key_eq(s
, sub
)) {
3357 fast_metatable_or_nil(subscr(n
));
3358 } else if (lua_key_eq(s
, sup
)) {
3359 fast_metatable_or_nil(supscr(n
));
3360 } else if ((lua_key_eq(s
, top_accent
))||(lua_key_eq(s
, accent
))) {
3361 fast_metatable_or_nil(top_accent_chr(n
));
3362 } else if (lua_key_eq(s
, bot_accent
)) {
3363 fast_metatable_or_nil(bot_accent_chr(n
));
3364 } else if (lua_key_eq(s
, overlay_accent
)) {
3365 fast_metatable_or_nil(overlay_accent_chr(n
));
3369 } else if (t
== fence_noad
) {
3370 if (lua_key_eq(s
, subtype
)) {
3371 lua_pushinteger(L
, subtype(n
));
3372 } else if (lua_key_eq(s
, delim
)) {
3373 fast_metatable_or_nil(delimiter(n
));
3377 } else if (t
== delim_node
) {
3378 if (lua_key_eq(s
, subtype
)) {
3379 lua_pushinteger(L
, subtype(n
));
3380 } else if (lua_key_eq(s
, small_fam
)) {
3381 lua_pushinteger(L
, small_fam(n
));
3382 } else if (lua_key_eq(s
, small_char
)) {
3383 lua_pushinteger(L
, small_char(n
));
3384 } else if (lua_key_eq(s
, large_fam
)) {
3385 lua_pushinteger(L
, large_fam(n
));
3386 } else if (lua_key_eq(s
, large_char
)) {
3387 lua_pushinteger(L
, large_char(n
));
3391 } else if ((t
== sub_box_node
) || (t
== sub_mlist_node
)) {
3392 if (lua_key_eq(s
, subtype
)) {
3393 lua_pushinteger(L
, subtype(n
));
3394 } else if ((lua_key_eq(s
, list
)) || (lua_key_eq(s
, head
))){
3395 fast_metatable_or_nil_alink(math_list(n
));
3399 } else if (t
== radical_noad
) {
3400 if (lua_key_eq(s
, subtype
)) {
3401 lua_pushinteger(L
, subtype(n
));
3402 } else if (lua_key_eq(s
, nucleus
)) {
3403 fast_metatable_or_nil(nucleus(n
));
3404 } else if (lua_key_eq(s
, sub
)) {
3405 fast_metatable_or_nil(subscr(n
));
3406 } else if (lua_key_eq(s
, sup
)) {
3407 fast_metatable_or_nil(supscr(n
));
3408 } else if (lua_key_eq(s
, left
)) {
3409 fast_metatable_or_nil(left_delimiter(n
));
3410 } else if (lua_key_eq(s
, degree
)) {
3411 fast_metatable_or_nil(degree(n
));
3415 } else if (t
== margin_kern_node
) {
3416 if (lua_key_eq(s
, subtype
)) {
3417 lua_pushinteger(L
, subtype(n
));
3418 } else if (lua_key_eq(s
, width
)) {
3419 lua_pushinteger(L
, width(n
));
3420 } else if (lua_key_eq(s
, glyph
)) {
3421 fast_metatable_or_nil(margin_char(n
));
3425 } else if (t
== split_up_node
) {
3426 if (lua_key_eq(s
, subtype
)) {
3427 lua_pushinteger(L
, subtype(n
));
3428 } else if (lua_key_eq(s
, last_ins_ptr
)) {
3429 fast_metatable_or_nil(last_ins_ptr(n
));
3430 } else if (lua_key_eq(s
, best_ins_ptr
)) {
3431 fast_metatable_or_nil(best_ins_ptr(n
));
3432 } else if (lua_key_eq(s
, broken_ptr
)) {
3433 fast_metatable_or_nil(broken_ptr(n
));
3434 } else if (lua_key_eq(s
, broken_ins
)) {
3435 fast_metatable_or_nil(broken_ins(n
));
3439 } else if (t
== choice_node
) {
3440 if (lua_key_eq(s
, subtype
)) {
3441 lua_pushinteger(L
, subtype(n
));
3442 } else if (lua_key_eq(s
, display
)) {
3443 fast_metatable_or_nil(display_mlist(n
));
3444 } else if (lua_key_eq(s
, text
)) {
3445 fast_metatable_or_nil(text_mlist(n
));
3446 } else if (lua_key_eq(s
, script
)) {
3447 fast_metatable_or_nil(script_mlist(n
));
3448 } else if (lua_key_eq(s
, scriptscript
)) {
3449 fast_metatable_or_nil(script_script_mlist(n
));
3453 } else if (t
== inserting_node
) {
3454 if (lua_key_eq(s
, subtype
)) {
3455 lua_pushinteger(L
, subtype(n
));
3456 } else if (lua_key_eq(s
, last_ins_ptr
)) {
3457 fast_metatable_or_nil(last_ins_ptr(n
));
3458 } else if (lua_key_eq(s
, best_ins_ptr
)) {
3459 fast_metatable_or_nil(best_ins_ptr(n
));
3463 } else if (t
== attribute_node
) {
3464 if (lua_key_eq(s
, subtype
)) {
3465 lua_pushinteger(L
, subtype(n
));
3466 } else if (lua_key_eq(s
, number
)) {
3467 lua_pushinteger(L
, attribute_id(n
));
3468 } else if (lua_key_eq(s
, value
)) {
3469 lua_pushinteger(L
, attribute_value(n
));
3473 } else if (t
== adjust_node
) {
3474 if (lua_key_eq(s
, subtype
)) {
3475 lua_pushinteger(L
, subtype(n
));
3476 } else if ((lua_key_eq(s
, list
)) || (lua_key_eq(s
, head
))) {
3477 fast_metatable_or_nil_alink(adjust_ptr(n
));
3481 } else if (t
== unset_node
) {
3482 if (lua_key_eq(s
, subtype
)) {
3483 lua_pushinteger(L
, subtype(n
));
3484 } else if (lua_key_eq(s
, width
)) {
3485 lua_pushinteger(L
, width(n
));
3486 } else if (lua_key_eq(s
, height
)) {
3487 lua_pushinteger(L
, height(n
));
3488 } else if (lua_key_eq(s
, depth
)) {
3489 lua_pushinteger(L
, depth(n
));
3490 } else if (lua_key_eq(s
, dir
)) {
3491 lua_push_dir_par(L
, box_dir(n
));
3492 } else if (lua_key_eq(s
, shrink
)) {
3493 lua_pushinteger(L
, glue_shrink(n
));
3494 } else if (lua_key_eq(s
, glue_order
)) {
3495 lua_pushinteger(L
, glue_order(n
));
3496 } else if (lua_key_eq(s
, glue_sign
)) {
3497 lua_pushinteger(L
, glue_sign(n
));
3498 } else if (lua_key_eq(s
, stretch
)) {
3499 lua_pushinteger(L
, glue_stretch(n
));
3500 } else if (lua_key_eq(s
, count
)) {
3501 lua_pushinteger(L
, span_count(n
));
3502 } else if ((lua_key_eq(s
, list
)) || (lua_key_eq(s
, head
))){
3503 fast_metatable_or_nil_alink(list_ptr(n
));
3507 } else if (t
== attribute_list_node
) {
3508 if (lua_key_eq(s
, subtype
)) {
3509 lua_pushinteger(L
, subtype(n
));
3513 } else if (t
== boundary_node
) {
3514 if (lua_key_eq(s
, subtype
)) {
3515 lua_pushinteger(L
, subtype(n
));
3516 } else if (lua_key_eq(s
, value
)) {
3517 lua_pushinteger(L
, boundary_value(n
));
3527 static int lua_nodelib_getfield(lua_State
* L
)
3529 /* [given-node] [...]*/
3530 halfword
*p
= lua_touserdata(L
, 1);
3531 if ( (p
== NULL
) || (! lua_getmetatable(L
,1)) ) {
3535 /* [given-node] [mt-given-node]*/
3536 lua_get_metatablelua(luatex_node
);
3537 /* [given-node] [mt-given-node] [mt-node]*/
3538 if (!lua_rawequal(L
, -1, -2)) {
3542 /* prune stack and call getfield */
3544 return lua_nodelib_fast_getfield(L
);
3547 /* node.direct.getfield */
3549 static void lua_nodelib_direct_getfield_whatsit(lua_State
* L
, int n
, const char *s
)
3552 if (t
== user_defined_node
) {
3553 if (lua_key_eq(s
, user_id
)) {
3554 lua_pushinteger(L
, user_node_id(n
));
3555 } else if (lua_key_eq(s
, type
)) {
3556 lua_pushinteger(L
, user_node_type(n
));
3557 } else if (lua_key_eq(s
, value
)) {
3558 switch (user_node_type(n
)) {
3560 nodelib_pushdirect(user_node_value(n
));
3563 lua_pushinteger(L
, user_node_value(n
));
3566 if (user_node_value(n
) != 0) {
3567 lua_rawgeti(L
, LUA_REGISTRYINDEX
, user_node_value(n
));
3573 nodelib_pushdirect(user_node_value(n
));
3576 nodelib_pushstring(L
, user_node_value(n
));
3579 tokenlist_to_lua(L
, user_node_value(n
));
3582 lua_pushinteger(L
, user_node_value(n
));
3588 } else if (t
== pdf_literal_node
) {
3589 if (lua_key_eq(s
, mode
)) {
3590 lua_pushinteger(L
, pdf_literal_mode(n
));
3591 } else if (lua_key_eq(s
, data
)) {
3592 if (pdf_literal_type(n
) == lua_refid_literal
) {
3593 lua_rawgeti(L
, LUA_REGISTRYINDEX
, pdf_literal_data(n
));
3595 tokenlist_to_luastring(L
, pdf_literal_data(n
));
3600 } else if (t
== late_lua_node
) {
3601 if (lua_key_eq(s
, string
) || lua_key_eq(s
, data
)) {
3602 if (late_lua_type(n
) == lua_refid_literal
) {
3603 lua_rawgeti(L
, LUA_REGISTRYINDEX
, late_lua_data(n
));
3605 tokenlist_to_luastring(L
, late_lua_data(n
));
3607 } else if (lua_key_eq(s
, name
)) {
3608 tokenlist_to_luastring(L
, late_lua_name(n
));
3612 } else if (t
== pdf_annot_node
) {
3613 if (lua_key_eq(s
, width
)) {
3614 lua_pushinteger(L
, width(n
));
3615 } else if (lua_key_eq(s
, depth
)) {
3616 lua_pushinteger(L
, depth(n
));
3617 } else if (lua_key_eq(s
, height
)) {
3618 lua_pushinteger(L
, height(n
));
3619 } else if (lua_key_eq(s
, objnum
)) {
3620 lua_pushinteger(L
, pdf_annot_objnum(n
));
3621 } else if (lua_key_eq(s
, data
)) {
3622 tokenlist_to_luastring(L
, pdf_annot_data(n
));
3626 } else if (t
== pdf_dest_node
) {
3627 if (lua_key_eq(s
, width
)) {
3628 lua_pushinteger(L
, width(n
));
3629 } else if (lua_key_eq(s
, depth
)) {
3630 lua_pushinteger(L
, depth(n
));
3631 } else if (lua_key_eq(s
, height
)) {
3632 lua_pushinteger(L
, height(n
));
3633 } else if (lua_key_eq(s
, named_id
)) {
3634 lua_pushinteger(L
, pdf_dest_named_id(n
));
3635 } else if (lua_key_eq(s
, dest_id
)) {
3636 if (pdf_dest_named_id(n
) == 1)
3637 tokenlist_to_luastring(L
, pdf_dest_id(n
));
3639 lua_pushinteger(L
, pdf_dest_id(n
));
3640 } else if (lua_key_eq(s
, dest_type
)) {
3641 lua_pushinteger(L
, pdf_dest_type(n
));
3642 } else if (lua_key_eq(s
, xyz_zoom
)) {
3643 lua_pushinteger(L
, pdf_dest_xyz_zoom(n
));
3644 } else if (lua_key_eq(s
, objnum
)) {
3645 lua_pushinteger(L
, pdf_dest_objnum(n
));
3649 } else if (t
== pdf_setmatrix_node
) {
3650 if (lua_key_eq(s
, data
)) {
3651 tokenlist_to_luastring(L
, pdf_setmatrix_data(n
));
3655 } else if (t
== pdf_colorstack_node
) {
3656 if (lua_key_eq(s
, stack
)) {
3657 lua_pushinteger(L
, pdf_colorstack_stack(n
));
3658 } else if (lua_key_eq(s
, command
)) {
3659 lua_pushinteger(L
, pdf_colorstack_cmd(n
));
3660 } else if (lua_key_eq(s
, data
)) {
3661 tokenlist_to_luastring(L
, pdf_colorstack_data(n
));
3665 } else if (t
== pdf_refobj_node
) {
3666 if (lua_key_eq(s
, objnum
)) {
3667 lua_pushinteger(L
, pdf_obj_objnum(n
));
3671 } else if (t
== write_node
) {
3672 if (lua_key_eq(s
, stream
)) {
3673 lua_pushinteger(L
, write_stream(n
));
3674 } else if (lua_key_eq(s
, data
)) {
3675 tokenlist_to_lua(L
, write_tokens(n
));
3679 } else if (t
== special_node
) {
3680 if (lua_key_eq(s
, data
)) {
3681 tokenlist_to_luastring(L
, write_tokens(n
));
3685 } else if (t
== pdf_start_link_node
) {
3686 if (lua_key_eq(s
, width
)) {
3687 lua_pushinteger(L
, width(n
));
3688 } else if (lua_key_eq(s
, depth
)) {
3689 lua_pushinteger(L
, depth(n
));
3690 } else if (lua_key_eq(s
, height
)) {
3691 lua_pushinteger(L
, height(n
));
3692 } else if (lua_key_eq(s
, objnum
)) {
3693 lua_pushinteger(L
, pdf_link_objnum(n
));
3694 } else if (lua_key_eq(s
, link_attr
)) {
3695 tokenlist_to_luastring(L
, pdf_link_attr(n
));
3696 } else if (lua_key_eq(s
, action
)) {
3697 nodelib_pushaction(L
, pdf_link_action(n
));
3701 } else if (t
== pdf_action_node
) {
3702 if (lua_key_eq(s
, action_type
)) {
3703 lua_pushinteger(L
, pdf_action_type(n
));
3704 } else if (lua_key_eq(s
, named_id
)) {
3705 lua_pushinteger(L
, pdf_action_named_id(n
));
3706 } else if (lua_key_eq(s
, action_id
)) {
3707 if (pdf_action_named_id(n
) == 1) {
3708 tokenlist_to_luastring(L
, pdf_action_id(n
));
3710 lua_pushinteger(L
, pdf_action_id(n
));
3712 } else if (lua_key_eq(s
, file
)) {
3713 tokenlist_to_luastring(L
, pdf_action_file(n
));
3714 } else if (lua_key_eq(s
, new_window
)) {
3715 lua_pushinteger(L
, pdf_action_new_window(n
));
3716 } else if (lua_key_eq(s
, data
)) {
3717 tokenlist_to_luastring(L
, pdf_action_tokens(n
));
3721 } else if ((t
== pdf_thread_node
) || (t
== pdf_start_thread_node
)) {
3722 if (lua_key_eq(s
, width
)) {
3723 lua_pushinteger(L
, width(n
));
3724 } else if (lua_key_eq(s
, depth
)) {
3725 lua_pushinteger(L
, depth(n
));
3726 } else if (lua_key_eq(s
, height
)) {
3727 lua_pushinteger(L
, height(n
));
3728 } else if (lua_key_eq(s
, named_id
)) {
3729 lua_pushinteger(L
, pdf_thread_named_id(n
));
3730 } else if (lua_key_eq(s
, thread_id
)) {
3731 if (pdf_thread_named_id(n
) == 1) {
3732 tokenlist_to_luastring(L
, pdf_thread_id(n
));
3734 lua_pushinteger(L
, pdf_thread_id(n
));
3736 } else if (lua_key_eq(s
, thread_attr
)) {
3737 tokenlist_to_luastring(L
, pdf_thread_attr(n
));
3741 } else if (t
== open_node
) {
3742 if (lua_key_eq(s
, stream
)) {
3743 lua_pushinteger(L
, write_stream(n
));
3744 } else if (lua_key_eq(s
, name
)) {
3745 nodelib_pushstring(L
, open_name(n
));
3746 } else if (lua_key_eq(s
, area
)) {
3747 nodelib_pushstring(L
, open_area(n
));
3748 } else if (lua_key_eq(s
, ext
)) {
3749 nodelib_pushstring(L
, open_ext(n
));
3753 } else if (t
== close_node
) {
3754 if (lua_key_eq(s
, stream
)) {
3755 lua_pushinteger(L
, write_stream(n
));
3764 static int lua_nodelib_direct_getfield(lua_State
* L
)
3768 halfword n
= lua_tointeger(L
, 1);
3770 if (lua_type(L
, 2) == LUA_TNUMBER
) {
3773 if (! nodetype_has_attributes(t
)) {
3778 if (p
== null
|| vlink(p
) == null
) {
3782 i
= (int) lua_tointeger(L
, 2);
3785 if (attribute_id(p
) == i
) {
3786 if ((int) attribute_value(p
) > UNUSED_ATTRIBUTE
) {
3787 lua_pushinteger(L
, (int) attribute_value(p
));
3792 } else if (attribute_id(p
) > i
) {
3802 s
= lua_tostring(L
, 2);
3804 if (lua_key_eq(s
, id
)) {
3805 lua_pushinteger(L
, t
);
3806 } else if (lua_key_eq(s
, next
)) {
3807 nodelib_pushdirect_or_nil(vlink(n
));
3808 } else if (lua_key_eq(s
, prev
)) {
3809 nodelib_pushdirect_or_nil(alink(n
));
3810 } else if (lua_key_eq(s
, subtype
)) {
3811 if (t
== glue_spec_node
) {
3812 lua_pushinteger(L
, 0); /* dummy, the only one */
3814 lua_pushinteger(L
, subtype(n
));
3816 } else if (lua_key_eq(s
, attr
)) {
3817 if (! nodetype_has_attributes(t
)) {
3820 nodelib_pushattr(L
, node_attr(n
));
3822 } else if (t
== glyph_node
) {
3823 if (lua_key_eq(s
, font
)) {
3824 lua_pushinteger(L
, font(n
));
3825 } else if (lua_key_eq(s
, char)) {
3826 lua_pushinteger(L
, character(n
));
3827 } else if (lua_key_eq(s
, xoffset
)) {
3828 lua_pushinteger(L
, x_displace(n
));
3829 } else if (lua_key_eq(s
, yoffset
)) {
3830 lua_pushinteger(L
, y_displace(n
));
3831 } else if (lua_key_eq(s
, xadvance
)) {
3832 lua_pushinteger(L
, x_advance(n
));
3833 } else if (lua_key_eq(s
, width
)) {
3834 lua_pushinteger(L
, char_width(font(n
),character(n
)));
3835 } else if (lua_key_eq(s
, height
)) {
3836 lua_pushinteger(L
, char_height(font(n
),character(n
)));
3837 } else if (lua_key_eq(s
, depth
)) {
3838 lua_pushinteger(L
, char_depth(font(n
),character(n
)));
3839 } else if (lua_key_eq(s
, expansion_factor
)) {
3840 lua_pushinteger(L
, ex_glyph(n
));
3841 } else if (lua_key_eq(s
, components
)) {
3842 nodelib_pushdirect_or_nil(lig_ptr(n
));
3843 } else if (lua_key_eq(s
, lang
)) {
3844 lua_pushinteger(L
, char_lang(n
));
3845 } else if (lua_key_eq(s
, left
)) {
3846 lua_pushinteger(L
, char_lhmin(n
));
3847 } else if (lua_key_eq(s
, right
)) {
3848 lua_pushinteger(L
, char_rhmin(n
));
3849 } else if (lua_key_eq(s
, uchyph
)) {
3850 lua_pushinteger(L
, char_uchyph(n
));
3854 } else if ((t
== hlist_node
) || (t
== vlist_node
)) {
3855 /* candidates: whd (width,height,depth) */
3856 if (lua_key_eq(s
, list
) || lua_key_eq(s
, head
)) {
3857 nodelib_pushdirect_or_nil_alink(list_ptr(n
));
3858 } else if (lua_key_eq(s
, width
)) {
3859 lua_pushinteger(L
, width(n
));
3860 } else if (lua_key_eq(s
, height
)) {
3861 lua_pushinteger(L
, height(n
));
3862 } else if (lua_key_eq(s
, depth
)) {
3863 lua_pushinteger(L
, depth(n
));
3864 } else if (lua_key_eq(s
, dir
)) {
3865 lua_push_dir_par(L
, box_dir(n
));
3866 } else if (lua_key_eq(s
, shift
)) {
3867 lua_pushinteger(L
, shift_amount(n
));
3868 } else if (lua_key_eq(s
, glue_order
)) {
3869 lua_pushinteger(L
, glue_order(n
));
3870 } else if (lua_key_eq(s
, glue_sign
)) {
3871 lua_pushinteger(L
, glue_sign(n
));
3872 } else if (lua_key_eq(s
, glue_set
)) {
3873 lua_pushnumber(L
, (double) glue_set(n
)); /* float */
3877 } else if (t
== disc_node
) {
3878 if (lua_key_eq(s
, pre
)) {
3879 nodelib_pushdirect_or_nil(vlink(pre_break(n
)));
3880 } else if (lua_key_eq(s
, post
)) {
3881 nodelib_pushdirect_or_nil(vlink(post_break(n
)));
3882 } else if (lua_key_eq(s
, replace
)) {
3883 nodelib_pushdirect_or_nil(vlink(no_break(n
)));
3884 } else if (lua_key_eq(s
, penalty
)) {
3885 lua_pushinteger(L
, disc_penalty(n
));
3889 } else if (t
== glue_node
) {
3890 if (lua_key_eq(s
, width
)) {
3891 lua_pushinteger(L
, width(n
));
3892 } else if (lua_key_eq(s
, stretch
)) {
3893 lua_pushinteger(L
, stretch(n
));
3894 } else if (lua_key_eq(s
, shrink
)) {
3895 lua_pushinteger(L
, shrink(n
));
3896 } else if (lua_key_eq(s
, stretch_order
)) {
3897 lua_pushinteger(L
, stretch_order(n
));
3898 } else if (lua_key_eq(s
, shrink_order
)) {
3899 lua_pushinteger(L
, shrink_order(n
));
3900 } else if (lua_key_eq(s
, leader
)) {
3901 nodelib_pushdirect_or_nil(leader_ptr(n
));
3905 } else if (t
== kern_node
) {
3906 if (lua_key_eq(s
, kern
)) {
3907 lua_pushinteger(L
, width(n
));
3908 } else if (lua_key_eq(s
, expansion_factor
)) {
3909 lua_pushinteger(L
, ex_kern(n
));
3913 } else if (t
== penalty_node
) {
3914 if (lua_key_eq(s
, penalty
)) {
3915 lua_pushinteger(L
, penalty(n
));
3919 } else if (t
== rule_node
) {
3920 /* candidates: whd (width,height,depth) */
3921 if (lua_key_eq(s
, width
)) {
3922 lua_pushinteger(L
, width(n
));
3923 } else if (lua_key_eq(s
, height
)) {
3924 lua_pushinteger(L
, height(n
));
3925 } else if (lua_key_eq(s
, depth
)) {
3926 lua_pushinteger(L
, depth(n
));
3927 } else if (lua_key_eq(s
, dir
)) {
3928 lua_push_dir_par(L
, rule_dir(n
));
3929 } else if (lua_key_eq(s
, index
)) {
3930 lua_pushinteger(L
, rule_index(n
));
3931 } else if (lua_key_eq(s
, transform
)) {
3932 lua_pushinteger(L
,rule_transform(n
));
3936 } else if (t
== dir_node
) {
3937 if (lua_key_eq(s
, dir
)) {
3938 lua_push_dir_text(L
, dir_dir(n
));
3939 } else if (lua_key_eq(s
, level
)) {
3940 lua_pushinteger(L
, dir_level(n
));
3941 } else if (lua_key_eq(s
, subtype
)) { /* can be used for anything */
3942 lua_pushinteger(L
, subtype(n
));
3946 } else if (t
== local_par_node
) {
3947 if (lua_key_eq(s
, pen_inter
)) {
3948 lua_pushinteger(L
, local_pen_inter(n
));
3949 } else if (lua_key_eq(s
, pen_broken
)) {
3950 lua_pushinteger(L
, local_pen_broken(n
));
3951 } else if (lua_key_eq(s
, dir
)) {
3952 lua_push_dir_par(L
, local_par_dir(n
));
3953 } else if (lua_key_eq(s
, box_left
)) {
3954 nodelib_pushdirect_or_nil(local_box_left(n
));
3955 } else if (lua_key_eq(s
, box_left_width
)) {
3956 lua_pushinteger(L
, local_box_left_width(n
));
3957 } else if (lua_key_eq(s
, box_right
)) {
3958 nodelib_pushdirect_or_nil(local_box_right(n
));
3959 } else if (lua_key_eq(s
, box_right_width
)) {
3960 lua_pushinteger(L
, local_box_right_width(n
));
3964 } else if (t
== whatsit_node
) {
3965 lua_nodelib_direct_getfield_whatsit(L
, n
, s
);
3966 } else if (t
== simple_noad
) {
3967 if (lua_key_eq(s
, nucleus
)) {
3968 nodelib_pushdirect_or_nil(nucleus(n
));
3969 } else if (lua_key_eq(s
, sub
)) {
3970 nodelib_pushdirect_or_nil(subscr(n
));
3971 } else if (lua_key_eq(s
, sup
)) {
3972 nodelib_pushdirect_or_nil(supscr(n
));
3976 } else if ((t
== math_char_node
) || (t
== math_text_char_node
)) {
3977 if (lua_key_eq(s
, fam
)) {
3978 lua_pushinteger(L
, math_fam(n
));
3979 } else if (lua_key_eq(s
, char)) {
3980 lua_pushinteger(L
, math_character(n
));
3981 } else if (lua_key_eq(s
, font
)) {
3982 lua_pushinteger(L
, fam_fnt(math_fam(n
), 0));
3986 } else if (t
== mark_node
) {
3987 if (lua_key_eq(s
, class)) {
3988 lua_pushinteger(L
, mark_class(n
));
3989 } else if (lua_key_eq(s
, mark
)) {
3990 tokenlist_to_lua(L
, mark_ptr(n
));
3994 } else if (t
== ins_node
) {
3995 if (lua_key_eq(s
, cost
)) {
3996 lua_pushinteger(L
, float_cost(n
));
3997 } else if (lua_key_eq(s
, depth
)) {
3998 lua_pushinteger(L
, depth(n
));
3999 } else if (lua_key_eq(s
, height
)) {
4000 lua_pushinteger(L
, height(n
));
4001 } else if ((lua_key_eq(s
, list
)) || (lua_key_eq(s
, head
))) {
4002 nodelib_pushdirect_or_nil_alink(ins_ptr(n
));
4004 } else if (lua_key_eq(s
, width
)) {
4005 lua_pushinteger(L
, width(n
));
4006 } else if (lua_key_eq(s
, stretch
)) {
4007 lua_pushinteger(L
, stretch(n
));
4008 } else if (lua_key_eq(s
, shrink
)) {
4009 lua_pushinteger(L
, shrink(n
));
4010 } else if (lua_key_eq(s
, stretch_order
)) {
4011 lua_pushinteger(L
, stretch_order(n
));
4012 } else if (lua_key_eq(s
, shrink_order
)) {
4013 lua_pushinteger(L
, shrink_order(n
));
4017 } else if (t
== math_node
) {
4018 if (lua_key_eq(s
, surround
)) {
4019 lua_pushinteger(L
, surround(n
));
4021 } else if (lua_key_eq(s
, width
)) {
4022 lua_pushinteger(L
, width(n
));
4023 } else if (lua_key_eq(s
, stretch
)) {
4024 lua_pushinteger(L
, stretch(n
));
4025 } else if (lua_key_eq(s
, shrink
)) {
4026 lua_pushinteger(L
, shrink(n
));
4027 } else if (lua_key_eq(s
, stretch_order
)) {
4028 lua_pushinteger(L
, stretch_order(n
));
4029 } else if (lua_key_eq(s
, shrink_order
)) {
4030 lua_pushinteger(L
, shrink_order(n
));
4034 } else if (t
== fraction_noad
) {
4035 if (lua_key_eq(s
, width
)) {
4036 lua_pushinteger(L
, thickness(n
));
4037 } else if (lua_key_eq(s
, num
)) {
4038 nodelib_pushdirect_or_nil(numerator(n
));
4039 } else if (lua_key_eq(s
, denom
)) {
4040 nodelib_pushdirect_or_nil(denominator(n
));
4041 } else if (lua_key_eq(s
, left
)) {
4042 nodelib_pushdirect_or_nil(left_delimiter(n
));
4043 } else if (lua_key_eq(s
, right
)) {
4044 nodelib_pushdirect_or_nil(right_delimiter(n
));
4048 } else if (t
== style_node
) {
4049 if (lua_key_eq(s
, style
)) {
4050 lua_push_math_style_name(L
,subtype(n
));
4054 } else if (t
== accent_noad
) {
4055 if (lua_key_eq(s
, nucleus
)) {
4056 nodelib_pushdirect_or_nil(nucleus(n
));
4057 } else if (lua_key_eq(s
, sub
)) {
4058 nodelib_pushdirect_or_nil(subscr(n
));
4059 } else if (lua_key_eq(s
, sup
)) {
4060 nodelib_pushdirect_or_nil(supscr(n
));
4061 } else if ((lua_key_eq(s
, top_accent
))||(lua_key_eq(s
, accent
))) {
4062 nodelib_pushdirect_or_nil(top_accent_chr(n
));
4063 } else if (lua_key_eq(s
, bot_accent
)) {
4064 nodelib_pushdirect_or_nil(bot_accent_chr(n
));
4065 } else if (lua_key_eq(s
, overlay_accent
)) {
4066 nodelib_pushdirect_or_nil(overlay_accent_chr(n
));
4070 } else if (t
== fence_noad
) {
4071 if (lua_key_eq(s
, delim
)) {
4072 nodelib_pushdirect_or_nil(delimiter(n
));
4076 } else if (t
== delim_node
) {
4077 if (lua_key_eq(s
, small_fam
)) {
4078 lua_pushinteger(L
, small_fam(n
));
4079 } else if (lua_key_eq(s
, small_char
)) {
4080 lua_pushinteger(L
, small_char(n
));
4081 } else if (lua_key_eq(s
, large_fam
)) {
4082 lua_pushinteger(L
, large_fam(n
));
4083 } else if (lua_key_eq(s
, large_char
)) {
4084 lua_pushinteger(L
, large_char(n
));
4088 } else if ((t
== sub_box_node
) || (t
== sub_mlist_node
)) {
4089 if ((lua_key_eq(s
, list
)) || (lua_key_eq(s
, head
))){
4090 nodelib_pushdirect_or_nil_alink(math_list(n
));
4094 } else if (t
== radical_noad
) {
4095 if (lua_key_eq(s
, nucleus
)) {
4096 nodelib_pushdirect_or_nil(nucleus(n
));
4097 } else if (lua_key_eq(s
, sub
)) {
4098 nodelib_pushdirect_or_nil(subscr(n
));
4099 } else if (lua_key_eq(s
, sup
)) {
4100 nodelib_pushdirect_or_nil(supscr(n
));
4101 } else if (lua_key_eq(s
, left
)) {
4102 nodelib_pushdirect_or_nil(left_delimiter(n
));
4103 } else if (lua_key_eq(s
, degree
)) {
4104 nodelib_pushdirect_or_nil(degree(n
));
4108 } else if (t
== margin_kern_node
) {
4109 if (lua_key_eq(s
, width
)) {
4110 lua_pushinteger(L
, width(n
));
4111 } else if (lua_key_eq(s
, glyph
)) {
4112 nodelib_pushdirect_or_nil(margin_char(n
));
4116 } else if (t
== split_up_node
) {
4117 if (lua_key_eq(s
, last_ins_ptr
)) {
4118 nodelib_pushdirect_or_nil(last_ins_ptr(n
));
4119 } else if (lua_key_eq(s
, best_ins_ptr
)) {
4120 nodelib_pushdirect_or_nil(best_ins_ptr(n
));
4121 } else if (lua_key_eq(s
, broken_ptr
)) {
4122 nodelib_pushdirect_or_nil(broken_ptr(n
));
4123 } else if (lua_key_eq(s
, broken_ins
)) {
4124 nodelib_pushdirect_or_nil(broken_ins(n
));
4128 } else if (t
== choice_node
) {
4129 if (lua_key_eq(s
, display
)) {
4130 nodelib_pushdirect_or_nil(display_mlist(n
));
4131 } else if (lua_key_eq(s
, text
)) {
4132 nodelib_pushdirect_or_nil(text_mlist(n
));
4133 } else if (lua_key_eq(s
, script
)) {
4134 nodelib_pushdirect_or_nil(script_mlist(n
));
4135 } else if (lua_key_eq(s
, scriptscript
)) {
4136 nodelib_pushdirect_or_nil(script_script_mlist(n
));
4140 } else if (t
== inserting_node
) {
4141 if (lua_key_eq(s
, last_ins_ptr
)) {
4142 nodelib_pushdirect_or_nil(last_ins_ptr(n
));
4143 } else if (lua_key_eq(s
, best_ins_ptr
)) {
4144 nodelib_pushdirect_or_nil(best_ins_ptr(n
));
4148 } else if (t
== attribute_node
) {
4149 if (lua_key_eq(s
, number
)) {
4150 lua_pushinteger(L
, attribute_id(n
));
4151 } else if (lua_key_eq(s
, value
)) {
4152 lua_pushinteger(L
, attribute_value(n
));
4156 } else if (t
== adjust_node
) {
4157 if ((lua_key_eq(s
, list
)) || (lua_key_eq(s
, head
))) {
4158 nodelib_pushdirect_or_nil_alink(adjust_ptr(n
));
4162 } else if (t
== unset_node
) {
4163 if (lua_key_eq(s
, width
)) {
4164 lua_pushinteger(L
, width(n
));
4165 } else if (lua_key_eq(s
, height
)) {
4166 lua_pushinteger(L
, height(n
));
4167 } else if (lua_key_eq(s
, depth
)) {
4168 lua_pushinteger(L
, depth(n
));
4169 } else if (lua_key_eq(s
, dir
)) {
4170 lua_push_dir_par(L
, box_dir(n
));
4171 } else if (lua_key_eq(s
, shrink
)) {
4172 lua_pushinteger(L
, glue_shrink(n
));
4173 } else if (lua_key_eq(s
, glue_order
)) {
4174 lua_pushinteger(L
, glue_order(n
));
4175 } else if (lua_key_eq(s
, glue_sign
)) {
4176 lua_pushinteger(L
, glue_sign(n
));
4177 } else if (lua_key_eq(s
, stretch
)) {
4178 lua_pushinteger(L
, glue_stretch(n
));
4179 } else if (lua_key_eq(s
, count
)) {
4180 lua_pushinteger(L
, span_count(n
));
4181 } else if ((lua_key_eq(s
, list
)) || (lua_key_eq(s
, head
))){
4182 nodelib_pushdirect_or_nil_alink(list_ptr(n
));
4186 /* } else if (t == attribute_list_node) { */
4187 /* lua_pushnil(L); */
4188 } else if (t
== boundary_node
) {
4189 if (lua_key_eq(s
, subtype
)) {
4190 lua_pushinteger(L
, subtype(n
));
4191 } else if (lua_key_eq(s
, value
)) {
4192 lua_pushinteger(L
, boundary_value(n
));
4196 } else if (t
== glue_spec_node
) {
4197 if (lua_key_eq(s
, width
)) {
4198 lua_pushinteger(L
, width(n
));
4199 } else if (lua_key_eq(s
, stretch
)) {
4200 lua_pushinteger(L
, stretch(n
));
4201 } else if (lua_key_eq(s
, shrink
)) {
4202 lua_pushinteger(L
, shrink(n
));
4203 } else if (lua_key_eq(s
, stretch_order
)) {
4204 lua_pushinteger(L
, stretch_order(n
));
4205 } else if (lua_key_eq(s
, shrink_order
)) {
4206 lua_pushinteger(L
, shrink_order(n
));
4216 /* msg could be preallocated and shared */
4218 static void lua_nodelib_do_tostring(lua_State
* L
, halfword n
, const char *tag
)
4221 char a
[7] = { ' ', ' ', ' ', 'n', 'i', 'l', 0 };
4222 char v
[7] = { ' ', ' ', ' ', 'n', 'i', 'l', 0 };
4224 if ((alink(n
) != null
) && (type(n
) != attribute_node
))
4225 snprintf(a
, 7, "%6d", (int) alink(n
));
4226 if (vlink(n
) != null
)
4227 snprintf(v
, 7, "%6d", (int) vlink(n
));
4228 snprintf(msg
, 255, "<%s %s < %6d > %s : %s %d>", tag
, a
, (int) n
, v
, node_data
[type(n
)].name
, subtype(n
));
4229 lua_pushstring(L
, msg
);
4234 /* __tostring node.tostring */
4236 static int lua_nodelib_tostring(lua_State
* L
)
4238 halfword n
= *check_isnode(L
, 1);
4239 lua_nodelib_do_tostring(L
, n
, "node");
4243 /* node.direct.tostring */
4245 static int lua_nodelib_direct_tostring(lua_State
* L
)
4247 halfword n
= lua_tointeger(L
,1);
4251 lua_nodelib_do_tostring(L
, n
, "direct");
4258 static int lua_nodelib_equal(lua_State
* L
)
4260 halfword n
= *((halfword
*) lua_touserdata(L
, 1));
4261 halfword m
= *((halfword
*) lua_touserdata(L
, 2));
4262 lua_pushboolean(L
, (n
== m
));
4266 /* node.ligaturing */
4268 static int font_tex_ligaturing(lua_State
* L
)
4270 /* on the stack are two nodes and a direction */
4271 /* hh-ls: we need to deal with prev nodes when a range starts with a ligature */
4276 if (lua_gettop(L
) < 1) {
4278 lua_pushboolean(L
, 0);
4281 h
= *check_isnode(L
, 1);
4282 if (lua_gettop(L
) > 1) {
4283 t
= *check_isnode(L
, 2);
4285 tmp_head
= new_node(nesting_node
, 1);
4287 couple_nodes(tmp_head
, h
);
4288 tlink(tmp_head
) = t
;
4289 t
= handle_ligaturing(tmp_head
, t
);
4291 vlink(p
) = vlink(tmp_head
) ;
4293 alink(vlink(tmp_head
)) = p
;
4295 lua_pushinteger(L, vlink(tmp_head));
4296 lua_nodelib_push(L);
4298 lua_nodelib_push_fast(L
, vlink(tmp_head
));
4300 lua_pushinteger(L, t);
4301 lua_nodelib_push(L);
4303 lua_nodelib_push_fast(L
, t
);
4304 lua_pushboolean(L
, 1);
4305 flush_node(tmp_head
);
4309 static int font_tex_direct_ligaturing(lua_State
* L
)
4311 /* on the stack are two nodes and a direction */
4312 /* hh-ls: we need to deal with prev nodes when a range starts with a ligature */
4317 if (lua_gettop(L
) < 1) {
4319 lua_pushboolean(L
, 0);
4322 h
= lua_tointeger(L
, 1);
4323 if (lua_gettop(L
) > 1) {
4324 t
= lua_tointeger(L
, 2);
4326 tmp_head
= new_node(nesting_node
, 1);
4328 couple_nodes(tmp_head
, h
);
4329 tlink(tmp_head
) = t
;
4330 t
= handle_ligaturing(tmp_head
, t
);
4332 vlink(p
) = vlink(tmp_head
) ;
4334 alink(vlink(tmp_head
)) = p
;
4335 lua_pushinteger(L
, vlink(tmp_head
));
4336 lua_pushinteger(L
, t
);
4337 lua_pushboolean(L
, 1);
4338 flush_node(tmp_head
);
4344 static int font_tex_kerning(lua_State
* L
)
4346 /* on the stack are two nodes and a direction */
4352 if (lua_gettop(L
) < 1) {
4354 lua_pushboolean(L
, 0);
4357 h
= *check_isnode(L
, 1);
4358 if (lua_gettop(L
) > 1) {
4359 t
= *check_isnode(L
, 2);
4361 tmp_head
= new_node(nesting_node
, 1);
4363 couple_nodes(tmp_head
, h
);
4364 tlink(tmp_head
) = t
;
4365 t
= handle_kerning(tmp_head
, t
);
4367 vlink(p
) = vlink(tmp_head
) ;
4369 alink(vlink(tmp_head
)) = p
;
4371 lua_pushinteger(L, vlink(tmp_head));
4372 lua_nodelib_push(L);
4374 lua_nodelib_push_fast(L
, vlink(tmp_head
));
4376 lua_pushinteger(L, t);
4377 lua_nodelib_push(L);
4379 lua_nodelib_push_fast(L
, t
);
4380 lua_pushboolean(L
, 1);
4381 flush_node(tmp_head
);
4385 static int font_tex_direct_kerning(lua_State
* L
)
4387 /* on the stack are two nodes and a direction */
4393 if (lua_gettop(L
) < 1) {
4395 lua_pushboolean(L
, 0);
4398 h
= lua_tointeger(L
, 1);
4399 if (lua_gettop(L
) > 1) {
4400 t
= lua_tointeger(L
, 2);
4402 tmp_head
= new_node(nesting_node
, 1);
4404 couple_nodes(tmp_head
, h
);
4405 tlink(tmp_head
) = t
;
4406 t
= handle_kerning(tmp_head
, t
);
4408 vlink(p
) = vlink(tmp_head
) ;
4410 alink(vlink(tmp_head
)) = p
;
4411 lua_pushinteger(L
, vlink(tmp_head
));
4412 lua_pushinteger(L
, t
);
4413 lua_pushboolean(L
, 1);
4414 flush_node(tmp_head
);
4418 /* node.protect_glyphs (returns also boolean because that signals callback) */
4420 static int lua_nodelib_protect_glyphs(lua_State
* L
)
4423 halfword head
= *check_isnode(L
, 1);
4424 while (head
!= null
) {
4425 if (type(head
) == glyph_node
) {
4426 int s
= subtype(head
);
4429 subtype(head
) = (quarterword
) (s
== 1 ? 256 : 256 + s
);
4434 lua_pushboolean(L
, t
);
4435 lua_pushvalue(L
, 1);
4439 static int lua_nodelib_protect_glyph(lua_State
* L
)
4441 halfword n
= *check_isnode(L
, 1);
4442 if (type(n
) == glyph_node
) {
4445 subtype(n
) = (quarterword
) (s
== 1 ? 256 : 256 + s
);
4451 /* node.direct.protect_glyphs */
4453 static int lua_nodelib_direct_protect_glyphs(lua_State
* L
)
4456 halfword head
= (halfword
) lua_tointeger(L
,1);
4457 while (head
!= null
) {
4458 if (type(head
) == glyph_node
) {
4459 int s
= subtype(head
);
4462 subtype(head
) = (quarterword
) (s
== 1 ? 256 : 256 + s
);
4467 lua_pushboolean(L
, t
);
4468 lua_pushvalue(L
, 1);
4472 static int lua_nodelib_direct_protect_glyph(lua_State
* L
)
4474 halfword n
= (halfword
) lua_tointeger(L
,1);
4475 if ((n
!= null
) && (type(n
) == glyph_node
)) {
4478 subtype(n
) = (quarterword
) (s
== 1 ? 256 : 256 + s
);
4484 /* node.unprotect_glyphs (returns also boolean because that signals callback) */
4486 static int lua_nodelib_unprotect_glyphs(lua_State
* L
)
4489 halfword head
= *(check_isnode(L
, 1));
4490 while (head
!= null
) {
4491 if (type(head
) == glyph_node
) {
4492 int s
= subtype(head
);
4495 subtype(head
) = (quarterword
) (s
- 256);
4500 lua_pushboolean(L
, t
);
4501 lua_pushvalue(L
, 1);
4505 /* node.direct.unprotect_glyphs */
4507 static int lua_nodelib_direct_unprotect_glyphs(lua_State
* L
)
4510 halfword head
= (halfword
) lua_tointeger(L
,1);
4511 while (head
!= null
) {
4512 if (type(head
) == glyph_node
) {
4513 int s
= subtype(head
);
4516 subtype(head
) = (quarterword
) (s
- 256);
4521 lua_pushboolean(L
, t
);
4522 lua_pushvalue(L
, 1);
4526 /* node.first_glyph */
4528 static int lua_nodelib_first_glyph(lua_State
* L
)
4530 /* on the stack are two nodes and a direction */
4531 halfword h
, savetail
= null
, t
= null
;
4532 if (lua_gettop(L
) < 1) {
4534 lua_pushboolean(L
, 0);
4537 h
= *(check_isnode(L
, 1));
4538 if (lua_gettop(L
) > 1) {
4539 t
= *(check_isnode(L
, 2));
4540 savetail
= vlink(t
);
4543 while (h
!= null
&& (type(h
) != glyph_node
|| !is_simple_character(h
))) {
4546 if (savetail
!= null
) {
4547 vlink(t
) = savetail
;
4549 lua_pushinteger(L
, h
);
4550 lua_nodelib_push(L
);
4551 lua_pushboolean(L
, (h
== null
? 0 : 1));
4555 /* node.direct.first_glyph */
4557 static int lua_nodelib_direct_first_glyph(lua_State
* L
)
4559 halfword h
,savetail
,t
;
4562 h
= (halfword
) lua_tointeger(L
,1);
4567 t
= (halfword
) lua_tointeger(L
,2);
4569 savetail
= vlink(t
);
4572 while (h
!= null
&& (type(h
) != glyph_node
|| !is_simple_character(h
)))
4574 if (savetail
!= null
)
4575 vlink(t
) = savetail
;
4576 lua_pushinteger(L
, h
);
4577 return 1; /* no need to also push a boolean if we have nil */
4580 /* new, fast and dumb ones: only signals that something needs to be processed */
4582 /* node.has_glyph */
4584 static int lua_nodelib_has_glyph(lua_State
* L
)
4587 halfword h
= (halfword
) *(check_isnode(L
,1)) ;
4589 if ( (type(h
) == glyph_node
) || (type(h
) == disc_node
)) {
4600 /* node.direct.has_glyph */
4602 static int lua_nodelib_direct_has_glyph(lua_State
* L
)
4604 halfword h
= (halfword
) lua_tointeger(L
,1) ;
4606 if ((type(h
) == glyph_node
) || (type(h
) == disc_node
)) {
4607 nodelib_pushdirect(h
);
4617 /* this is too simplistic, but it helps Hans to get going */
4619 static halfword
do_ligature_n(halfword prev
, halfword stop
, halfword lig
)
4621 vlink(lig
) = vlink(stop
);
4623 lig_ptr(lig
) = vlink(prev
);
4628 /* node.do_ligature_n(node prev, node last, node lig) */
4630 static int lua_nodelib_do_ligature_n(lua_State
* L
)
4633 halfword n
= *check_isnode(L
, 1);
4634 halfword m
= *check_isnode(L
, 2);
4635 halfword o
= *check_isnode(L
, 3);
4636 if (alink(n
) == null
|| vlink(alink(n
)) != n
) {
4637 halfword tmp_head
= new_node(temp_node
, 0);
4638 couple_nodes(tmp_head
, n
);
4639 p
= do_ligature_n(tmp_head
, m
, o
);
4640 flush_node(tmp_head
);
4642 p
= do_ligature_n(alink(n
), m
, o
);
4644 lua_pushinteger(L
, p
);
4645 lua_nodelib_push(L
);
4649 /* node.direct.do_ligature_n(node prev, node last, node lig) */
4651 static int lua_nodelib_direct_do_ligature_n(lua_State
* L
)
4654 halfword n
= (halfword
) lua_tointeger(L
, 1);
4655 halfword m
= (halfword
) lua_tointeger(L
, 2);
4656 halfword o
= (halfword
) lua_tointeger(L
, 3);
4657 if ((n
== null
) || (m
== null
) || (o
== null
)) {
4660 if (alink(n
) == null
|| vlink(alink(n
)) != n
) {
4661 halfword tmp_head
= new_node(temp_node
, 0);
4662 couple_nodes(tmp_head
, n
);
4663 p
= do_ligature_n(tmp_head
, m
, o
);
4664 flush_node(tmp_head
);
4666 p
= do_ligature_n(alink(n
), m
, o
);
4668 lua_pushinteger(L
, p
);
4675 static int lua_nodelib_usedlist(lua_State
* L
)
4677 lua_pushinteger(L
, list_node_mem_usage());
4678 lua_nodelib_push(L
);
4682 /* node.direct.usedlist */
4684 static int lua_nodelib_direct_usedlist(lua_State
* L
)
4686 lua_pushinteger(L
, list_node_mem_usage());
4690 /* node.protrusion_skipable(node m) */
4692 static int lua_nodelib_cp_skipable(lua_State
* L
)
4694 halfword n
= *check_isnode(L
, 1);
4695 lua_pushboolean(L
, cp_skipable(n
));
4699 /* node.direct.protrusion_skipable(node m) */
4701 static int lua_nodelib_direct_cp_skipable(lua_State
* L
)
4703 halfword n
= lua_tointeger(L
, 1);
4707 lua_pushboolean(L
, cp_skipable(n
));
4713 /* node.currentattr(node m) */
4715 static int lua_nodelib_currentattr(lua_State
* L
)
4717 int u
= lua_gettop(L
);
4721 /* current_attribute_list() return attr_list_cache */
4722 /* or null (attr_list_cache can also be null) */
4723 n
= current_attribute_list();
4725 lua_pushinteger(L
, n
);
4726 lua_nodelib_push(L
);
4733 normal_warning("node lib","assignment via node.current_attr(<list>) is not supported (yet)");
4739 /* node.direct.currentattr(node m) */
4741 static int lua_nodelib_direct_currentattr(lua_State
* L
)
4743 /* current_attribute_list() return attr_list_cache */
4744 /* or null (attr_list_cache can also be null) */
4745 halfword n
= current_attribute_list();
4747 lua_pushinteger(L
, n
);
4754 /* node.direct.todirect */
4756 static int lua_nodelib_direct_todirect(lua_State
* L
)
4758 if (lua_type(L
,1) != LUA_TNUMBER
) {
4759 /* assume node, no further testing, used in known situations */
4761 n
= lua_touserdata(L
, 1);
4765 lua_pushinteger(L
, *((halfword
*)n
) );
4767 } /* else assume direct and returns argument */
4772 /* node.direct.tonode */
4774 static int lua_nodelib_direct_tonode(lua_State
* L
)
4777 halfword n
= lua_tointeger(L
, 1);
4779 a
= (halfword
*) lua_newuserdata(L
, sizeof(halfword
));
4781 lua_get_metatablelua(luatex_node
);
4782 lua_setmetatable(L
,-2);
4783 } /* else assume node and return argument */
4789 #define cleanup_late_lua(n) do { \
4790 if (late_lua_data(n) != 0) { \
4791 if (late_lua_type(n) == normal) { \
4792 delete_token_ref(late_lua_data(n)); \
4793 } else if (late_lua_type(n) == lua_refid_literal) { \
4794 luaL_unref(L, LUA_REGISTRYINDEX,late_lua_data(n)); \
4799 #define cleanup_late_lua_name(n) do { \
4800 if (late_lua_name(n) != 0) { \
4801 delete_token_ref(late_lua_name(n)); \
4805 static int lua_nodelib_setfield_whatsit(lua_State
* L
, int n
, const char *s
)
4809 if (t
== pdf_literal_node
) {
4810 if (lua_key_eq(s
, mode
)) {
4811 pdf_literal_mode(n
) = (quarterword
) lua_tointeger(L
, 3);
4812 } else if (lua_key_eq(s
, data
)) {
4814 pdf_literal_data(n
) = nodelib_gettoks(L
, 3);
4816 lua_pushvalue(L
, 3);
4817 pdf_literal_data(n
) = luaL_ref(L
, LUA_REGISTRYINDEX
);
4818 pdf_literal_type(n
) = lua_refid_literal
;
4821 return nodelib_cantset(L
, n
, s
);
4823 } else if (t
== late_lua_node
) {
4824 if (lua_key_eq(s
, string
)) {
4825 cleanup_late_lua(n
) ; /* ls-hh */
4827 late_lua_data(n
) = nodelib_gettoks(L
, 3);
4828 late_lua_type(n
) = normal
;
4830 lua_pushvalue(L
, 3);
4831 late_lua_data(n
) = luaL_ref(L
, LUA_REGISTRYINDEX
);
4832 late_lua_type(n
) = lua_refid_literal
;
4834 } else if (lua_key_eq(s
, data
)) {
4835 cleanup_late_lua(n
) ; /* ls-hh */
4836 late_lua_data(n
) = nodelib_gettoks(L
, 3);
4837 late_lua_type(n
) = normal
;
4838 } else if (lua_key_eq(s
, name
)) {
4839 cleanup_late_lua_name(n
) ; /* ls-hh */
4840 late_lua_name(n
) = nodelib_gettoks(L
, 3);
4842 return nodelib_cantset(L
, n
, s
);
4845 } else if (t
== user_defined_node
) {
4846 if (lua_key_eq(s
, user_id
)) {
4847 user_node_id(n
) = (halfword
) lua_tointeger(L
, 3);
4848 } else if (lua_key_eq(s
, type
)) {
4849 user_node_type(n
) = (halfword
) lua_tointeger(L
, 3);
4850 } else if (lua_key_eq(s
, value
)) {
4851 switch (user_node_type(n
)) {
4853 user_node_value(n
) = nodelib_getlist(L
, 3);
4856 user_node_value(n
) = (halfword
) lua_tointeger(L
, 3);
4859 lua_pushvalue(L
, 3);
4860 if (user_node_value(n
) != 0) {
4861 luaL_unref(L
, LUA_REGISTRYINDEX
,user_node_value(n
));
4863 user_node_value(n
) = luaL_ref(L
, LUA_REGISTRYINDEX
);
4866 user_node_value(n
) = nodelib_getlist(L
, 3);
4869 user_node_value(n
) = nodelib_getstring(L
, 3);
4872 user_node_value(n
) = nodelib_gettoks(L
, 3);
4875 user_node_value(n
) = (halfword
) lua_tointeger(L
, 3);
4879 return nodelib_cantset(L
, n
, s
);
4881 } else if (t
== pdf_annot_node
) {
4882 if (lua_key_eq(s
, width
)) {
4883 width(n
) = (halfword
) lua_tointeger(L
, 3);
4884 } else if (lua_key_eq(s
, depth
)) {
4885 depth(n
) = (halfword
) lua_tointeger(L
, 3);
4886 } else if (lua_key_eq(s
, height
)) {
4887 height(n
) = (halfword
) lua_tointeger(L
, 3);
4888 } else if (lua_key_eq(s
, objnum
)) {
4889 pdf_annot_objnum(n
) = (halfword
) lua_tointeger(L
, 3);
4890 } else if (lua_key_eq(s
, data
)) {
4891 pdf_annot_data(n
) = nodelib_gettoks(L
, 3);
4893 return nodelib_cantset(L
, n
, s
);
4895 } else if (t
== pdf_dest_node
) {
4896 if (lua_key_eq(s
, width
)) {
4897 width(n
) = (halfword
) lua_tointeger(L
, 3);
4898 } else if (lua_key_eq(s
, depth
)) {
4899 depth(n
) = (halfword
) lua_tointeger(L
, 3);
4900 } else if (lua_key_eq(s
, height
)) {
4901 height(n
) = (halfword
) lua_tointeger(L
, 3);
4902 } else if (lua_key_eq(s
, named_id
)) {
4903 pdf_dest_named_id(n
) = (quarterword
) lua_tointeger(L
, 3);
4904 } else if (lua_key_eq(s
, dest_id
)) {
4905 if (pdf_dest_named_id(n
) == 1) {
4906 pdf_dest_id(n
) = nodelib_gettoks(L
, 3);
4908 pdf_dest_id(n
) = (halfword
) lua_tointeger(L
, 3);
4910 } else if (lua_key_eq(s
, dest_type
)) {
4911 pdf_dest_type(n
) = (quarterword
) lua_tointeger(L
, 3);
4912 } else if (lua_key_eq(s
, xyz_zoom
)) {
4913 pdf_dest_xyz_zoom(n
) = (halfword
) lua_tointeger(L
, 3);
4914 } else if (lua_key_eq(s
, objnum
)) {
4915 pdf_dest_objnum(n
) = (halfword
) lua_tointeger(L
, 3);
4917 return nodelib_cantset(L
, n
, s
);
4919 } else if (t
== pdf_setmatrix_node
) {
4920 if (lua_key_eq(s
, data
)) {
4921 pdf_setmatrix_data(n
) = nodelib_gettoks(L
, 3);
4923 return nodelib_cantset(L
, n
, s
);
4925 } else if (t
== pdf_refobj_node
) {
4926 if (lua_key_eq(s
, objnum
)) {
4927 pdf_obj_objnum(n
) = (halfword
) lua_tointeger(L
, 3);
4929 return nodelib_cantset(L
, n
, s
);
4931 } else if (t
== pdf_start_link_node
) {
4932 if (lua_key_eq(s
, width
)) {
4933 width(n
) = (halfword
) lua_tointeger(L
, 3);
4934 } else if (lua_key_eq(s
, depth
)) {
4935 depth(n
) = (halfword
) lua_tointeger(L
, 3);
4936 } else if (lua_key_eq(s
, height
)) {
4937 height(n
) = (halfword
) lua_tointeger(L
, 3);
4938 } else if (lua_key_eq(s
, objnum
)) {
4939 pdf_link_objnum(n
) = (halfword
) lua_tointeger(L
, 3);
4940 } else if (lua_key_eq(s
, link_attr
)) {
4941 pdf_link_attr(n
) = nodelib_gettoks(L
, 3);
4942 } else if (lua_key_eq(s
, action
)) {
4943 pdf_link_action(n
) = nodelib_getaction(L
, 3);
4945 return nodelib_cantset(L
, n
, s
);
4947 } else if (t
== write_node
) {
4948 if (lua_key_eq(s
, stream
)) {
4949 write_stream(n
) = (halfword
) lua_tointeger(L
, 3);
4950 } else if (lua_key_eq(s
, data
)) {
4951 write_tokens(n
) = nodelib_gettoks(L
, 3);
4953 return nodelib_cantset(L
, n
, s
);
4955 } else if (t
== pdf_colorstack_node
) {
4956 if (lua_key_eq(s
, stack
)) {
4957 pdf_colorstack_stack(n
) = (halfword
) lua_tointeger(L
, 3);
4958 } else if (lua_key_eq(s
, command
)) {
4959 pdf_colorstack_cmd(n
) = (halfword
) lua_tointeger(L
, 3);
4960 } else if (lua_key_eq(s
, data
)) {
4961 pdf_colorstack_data(n
) = nodelib_gettoks(L
, 3);
4963 return nodelib_cantset(L
, n
, s
);
4965 } else if (t
== pdf_action_node
) {
4966 if (lua_key_eq(s
, action_type
)) {
4967 pdf_action_type(n
) = (quarterword
) lua_tointeger(L
, 3);
4968 } else if (lua_key_eq(s
, named_id
)) {
4969 pdf_action_named_id(n
) = (quarterword
) lua_tointeger(L
, 3);
4970 } else if (lua_key_eq(s
, action_id
)) {
4971 if (pdf_action_named_id(n
) == 1) {
4972 pdf_action_id(n
) = nodelib_gettoks(L
, 3);
4974 pdf_action_id(n
) = (halfword
) lua_tointeger(L
, 3);
4976 } else if (lua_key_eq(s
, file
)) {
4977 pdf_action_file(n
) = nodelib_gettoks(L
, 3);
4978 } else if (lua_key_eq(s
, new_window
)) {
4979 pdf_action_new_window(n
) = (halfword
) lua_tointeger(L
, 3);
4980 } else if (lua_key_eq(s
, data
)) {
4981 pdf_action_tokens(n
) = nodelib_gettoks(L
, 3);
4983 return nodelib_cantset(L
, n
, s
);
4985 } else if ((t
== pdf_thread_node
) || (t
== pdf_start_thread_node
)) {
4986 if (lua_key_eq(s
, width
)) {
4987 width(n
) = (halfword
) lua_tointeger(L
, 3);
4988 } else if (lua_key_eq(s
, depth
)) {
4989 depth(n
) = (halfword
) lua_tointeger(L
, 3);
4990 } else if (lua_key_eq(s
, height
)) {
4991 height(n
) = (halfword
) lua_tointeger(L
, 3);
4992 } else if (lua_key_eq(s
, named_id
)) {
4993 pdf_thread_named_id(n
) = (quarterword
) lua_tointeger(L
, 3);
4994 } else if (lua_key_eq(s
, thread_id
)) {
4995 if (pdf_thread_named_id(n
) == 1) {
4996 pdf_thread_id(n
) = nodelib_gettoks(L
, 3);
4998 pdf_thread_id(n
) = (halfword
) lua_tointeger(L
, 3);
5000 } else if (lua_key_eq(s
, thread_attr
)) {
5001 pdf_thread_attr(n
) = nodelib_gettoks(L
, 3);
5003 return nodelib_cantset(L
, n
, s
);
5005 } else if (t
== special_node
) {
5006 if (lua_key_eq(s
, data
)) {
5007 write_tokens(n
) = nodelib_gettoks(L
, 3);
5009 return nodelib_cantset(L
, n
, s
);
5011 } else if (t
== open_node
) {
5012 if (lua_key_eq(s
, stream
)) {
5013 write_stream(n
) = (halfword
) lua_tointeger(L
, 3);
5014 } else if (lua_key_eq(s
, name
)) {
5015 open_name(n
) = nodelib_getstring(L
, 3);
5016 } else if (lua_key_eq(s
, area
)) {
5017 open_area(n
) = nodelib_getstring(L
, 3);
5018 } else if (lua_key_eq(s
, ext
)) {
5019 open_ext(n
) = nodelib_getstring(L
, 3);
5021 return nodelib_cantset(L
, n
, s
);
5023 } else if (t
== close_node
) {
5024 if (lua_key_eq(s
, stream
)) {
5025 write_stream(n
) = (halfword
) lua_tointeger(L
, 3);
5027 return nodelib_cantset(L
, n
, s
);
5029 } else if ((t
== pdf_end_link_node
) || (t
== pdf_end_thread_node
) || (t
== save_pos_node
) ||
5030 (t
== pdf_save_node
) || (t
== pdf_restore_node
)) {
5031 return nodelib_cantset(L
, n
, s
);
5038 static int lua_nodelib_fast_setfield(lua_State
* L
)
5041 halfword n
= *((halfword
*) lua_touserdata(L
, 1));
5044 if (lua_type(L
, 2) == LUA_TNUMBER
) {
5045 if (lua_gettop(L
) == 3) {
5046 int i
= lua_tointeger(L
, 2);
5047 int val
= lua_tointeger(L
, 3);
5048 if (val
== UNUSED_ATTRIBUTE
) {
5049 (void) unset_attribute(n
, i
, val
);
5051 set_attribute(n
, i
, val
);
5054 luaL_error(L
, "incorrect number of arguments");
5059 s
= lua_tostring(L
, 2);
5061 /*if (lua_key_eq(s, id)) {
5062 type(n) = (quarteword) lua_tointeger(L, 3);
5064 if (lua_key_eq(s
, next
)) {
5065 halfword x
= nodelib_getlist(L
, 3);
5066 if (x
>0 && type(x
) == glue_spec_node
) {
5067 return luaL_error(L
, "You can't assign a %s node to a next field\n", node_data
[type(x
)].name
);
5070 } else if (lua_key_eq(s
, prev
)) {
5071 halfword x
= nodelib_getlist(L
, 3);
5072 if (x
>0 && type(x
) == glue_spec_node
) {
5073 return luaL_error(L
, "You can't assign a %s node to a prev field\n", node_data
[type(x
)].name
);
5076 } else if (lua_key_eq(s
, attr
)) {
5077 if (nodetype_has_attributes(type(n
))) {
5078 nodelib_setattr(L
, 3, n
);
5080 } else if (t
== glyph_node
) {
5081 if (lua_key_eq(s
, subtype
)) {
5082 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5083 } else if (lua_key_eq(s
, font
)) {
5084 font(n
) = (halfword
) lua_tointeger(L
, 3);
5085 } else if (lua_key_eq(s
, char)) {
5086 character(n
) = (halfword
) lua_tointeger(L
, 3);
5087 } else if (lua_key_eq(s
, xoffset
)) {
5088 x_displace(n
) = (halfword
) lua_tointeger(L
, 3);
5089 } else if (lua_key_eq(s
, yoffset
)) {
5090 y_displace(n
) = (halfword
) lua_tointeger(L
, 3);
5091 } else if (lua_key_eq(s
, xadvance
)) {
5092 x_advance(n
) = (halfword
) lua_tointeger(L
, 3);
5093 } else if (lua_key_eq(s
, width
)) {
5095 } else if (lua_key_eq(s
, height
)) {
5097 } else if (lua_key_eq(s
, depth
)) {
5099 } else if (lua_key_eq(s
, expansion_factor
)) {
5100 ex_glyph(n
) = (halfword
) lua_tointeger(L
, 3);
5101 } else if (lua_key_eq(s
, components
)) {
5102 lig_ptr(n
) = nodelib_getlist(L
, 3);
5103 } else if (lua_key_eq(s
, lang
)) {
5104 set_char_lang(n
, (halfword
) lua_tointeger(L
, 3));
5105 } else if (lua_key_eq(s
, left
)) {
5106 set_char_lhmin(n
, (halfword
) lua_tointeger(L
, 3));
5107 } else if (lua_key_eq(s
, right
)) {
5108 set_char_rhmin(n
, (halfword
) lua_tointeger(L
, 3));
5109 } else if (lua_key_eq(s
, uchyph
)) {
5110 set_char_uchyph(n
, (halfword
) lua_tointeger(L
, 3));
5112 return nodelib_cantset(L
, n
, s
);
5114 } else if ((t
== hlist_node
) || (t
== vlist_node
)) {
5115 if (lua_key_eq(s
, subtype
)) {
5116 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5117 } else if (lua_key_eq(s
, list
) || lua_key_eq(s
, head
)) {
5118 list_ptr(n
) = nodelib_getlist(L
, 3);
5119 } else if (lua_key_eq(s
, width
)) {
5120 width(n
) = (halfword
) lua_tointeger(L
, 3);
5121 } else if (lua_key_eq(s
, height
)) {
5122 height(n
) = (halfword
) lua_tointeger(L
, 3);
5123 } else if (lua_key_eq(s
, depth
)) {
5124 depth(n
) = (halfword
) lua_tointeger(L
, 3);
5125 } else if (lua_key_eq(s
, dir
)) {
5126 box_dir(n
) = nodelib_getdir(L
, 3, 1);
5127 } else if (lua_key_eq(s
, shift
)) {
5128 shift_amount(n
) = (halfword
) lua_tointeger(L
, 3);
5129 } else if (lua_key_eq(s
, glue_order
)) {
5130 glue_order(n
) = (quarterword
) lua_tointeger(L
, 3);
5131 } else if (lua_key_eq(s
, glue_sign
)) {
5132 glue_sign(n
) = (quarterword
) lua_tointeger(L
, 3);
5133 } else if (lua_key_eq(s
, glue_set
)) {
5134 glue_set(n
) = (glue_ratio
) lua_tonumber(L
, 3); /* integer or float */
5136 return nodelib_cantset(L
, n
, s
);
5138 } else if (t
== disc_node
) {
5139 if (lua_key_eq(s
, subtype
)) {
5140 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5141 } else if (lua_key_eq(s
, pre
)) {
5142 set_disc_field(pre_break(n
), nodelib_getlist(L
, 3));
5143 } else if (lua_key_eq(s
, post
)) {
5144 set_disc_field(post_break(n
), nodelib_getlist(L
, 3));
5145 } else if (lua_key_eq(s
, replace
)) {
5146 set_disc_field(no_break(n
), nodelib_getlist(L
, 3));
5147 } else if (lua_key_eq(s
, penalty
)) {
5148 disc_penalty(n
) = (quarterword
) lua_tointeger(L
, 3);
5150 return nodelib_cantset(L
, n
, s
);
5152 } else if (t
== glue_node
) {
5153 if (lua_key_eq(s
, subtype
)) {
5154 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5155 } else if (lua_key_eq(s
, width
)) {
5156 width(n
) = (halfword
) lua_tointeger(L
, 3);
5157 } else if (lua_key_eq(s
, stretch
)) {
5158 stretch(n
) = (halfword
) lua_tointeger(L
, 3);
5159 } else if (lua_key_eq(s
, shrink
)) {
5160 shrink(n
) = (halfword
) lua_tointeger(L
, 3);
5161 } else if (lua_key_eq(s
, stretch_order
)) {
5162 stretch_order(n
) = (quarterword
) lua_tointeger(L
, 3);
5163 } else if (lua_key_eq(s
, shrink_order
)) {
5164 shrink_order(n
) = (quarterword
) lua_tointeger(L
, 3);
5165 } else if (lua_key_eq(s
, leader
)) {
5166 leader_ptr(n
) = nodelib_getlist(L
, 3);
5168 return nodelib_cantset(L
, n
, s
);
5170 } else if (t
== kern_node
) {
5171 if (lua_key_eq(s
, subtype
)) {
5172 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5173 } else if (lua_key_eq(s
, kern
)) {
5174 width(n
) = (halfword
) lua_tointeger(L
, 3);
5175 } else if (lua_key_eq(s
, expansion_factor
)) {
5176 ex_kern(n
) = (halfword
) lua_tointeger(L
, 3);
5178 return nodelib_cantset(L
, n
, s
);
5180 } else if (t
== penalty_node
) {
5181 if (lua_key_eq(s
, subtype
)) {
5183 } else if (lua_key_eq(s
, penalty
)) {
5184 penalty(n
) = (halfword
) lua_tointeger(L
, 3);
5186 return nodelib_cantset(L
, n
, s
);
5188 } else if (t
== rule_node
) {
5189 if (lua_key_eq(s
, subtype
)) {
5190 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5191 } else if (lua_key_eq(s
, width
)) {
5192 width(n
) = (halfword
) lua_tointeger(L
, 3);
5193 } else if (lua_key_eq(s
, height
)) {
5194 height(n
) = (halfword
) lua_tointeger(L
, 3);
5195 } else if (lua_key_eq(s
, depth
)) {
5196 depth(n
) = (halfword
) lua_tointeger(L
, 3);
5197 } else if (lua_key_eq(s
, dir
)) {
5198 rule_dir(n
) = nodelib_getdir(L
, 3, 1);
5199 } else if (lua_key_eq(s
, index
)) {
5200 rule_index(n
) = (halfword
) lua_tointeger(L
, 3);
5201 } else if (lua_key_eq(s
, transform
)) {
5202 rule_transform(n
) = (halfword
) lua_tointeger(L
, 3);
5204 return nodelib_cantset(L
, n
, s
);
5206 } else if (t
== dir_node
) {
5207 if (lua_key_eq(s
, dir
)) {
5208 dir_dir(n
) = nodelib_getdir(L
, 3, 0);
5209 } else if (lua_key_eq(s
, level
)) {
5210 dir_level(n
) = (halfword
) lua_tointeger(L
, 3);
5211 } else if (lua_key_eq(s
, subtype
)) { /* can be used for anything */
5212 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5214 return nodelib_cantset(L
, n
, s
);
5216 } else if (t
== local_par_node
) {
5217 if (lua_key_eq(s
, pen_inter
)) {
5218 local_pen_inter(n
) = (halfword
) lua_tointeger(L
, 3);
5219 } else if (lua_key_eq(s
, pen_broken
)) {
5220 local_pen_broken(n
) = (halfword
) lua_tointeger(L
, 3);
5221 } else if (lua_key_eq(s
, dir
)) {
5222 local_par_dir(n
) = nodelib_getdir(L
, 3, 1);
5223 } else if (lua_key_eq(s
, box_left
)) {
5224 local_box_left(n
) = nodelib_getlist(L
, 3);
5225 } else if (lua_key_eq(s
, box_left_width
)) {
5226 local_box_left_width(n
) = (halfword
) lua_tointeger(L
, 3);
5227 } else if (lua_key_eq(s
, box_right
)) {
5228 local_box_right(n
) = nodelib_getlist(L
, 3);
5229 } else if (lua_key_eq(s
, box_right_width
)) {
5230 local_box_right_width(n
) = (halfword
) lua_tointeger(L
, 3);
5232 return nodelib_cantset(L
, n
, s
);
5234 } else if (t
== whatsit_node
) {
5235 if (lua_key_eq(s
, subtype
)) {
5236 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5238 lua_nodelib_setfield_whatsit(L
, n
, s
);
5240 } else if (t
== simple_noad
) {
5241 if (lua_key_eq(s
, subtype
)) {
5242 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5243 } else if (lua_key_eq(s
, nucleus
)) {
5244 nucleus(n
) = nodelib_getlist(L
, 3);
5245 } else if (lua_key_eq(s
, sub
)) {
5246 subscr(n
) = nodelib_getlist(L
, 3);
5247 } else if (lua_key_eq(s
, sup
)) {
5248 supscr(n
) = nodelib_getlist(L
, 3);
5250 return nodelib_cantset(L
, n
, s
);
5252 } else if ((t
== math_char_node
) || (t
== math_text_char_node
)) {
5253 if (lua_key_eq(s
, subtype
)) {
5254 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5255 } else if (lua_key_eq(s
, fam
)) {
5256 math_fam(n
) = (halfword
) lua_tointeger(L
, 3);
5257 } else if (lua_key_eq(s
, char)) {
5258 math_character(n
) = (halfword
) lua_tointeger(L
, 3);
5260 return nodelib_cantset(L
, n
, s
);
5262 } else if (t
== mark_node
) {
5263 if (lua_key_eq(s
, subtype
)) {
5264 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5265 } else if (lua_key_eq(s
, class)) {
5266 mark_class(n
) = (halfword
) lua_tointeger(L
, 3);
5267 } else if (lua_key_eq(s
, mark
)) {
5268 mark_ptr(n
) = nodelib_gettoks(L
, 3);
5270 return nodelib_cantset(L
, n
, s
);
5272 } else if (t
== ins_node
) {
5273 if (lua_key_eq(s
, subtype
)) {
5274 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5275 } else if (lua_key_eq(s
, cost
)) {
5276 float_cost(n
) = (halfword
) lua_tointeger(L
, 3);
5277 } else if (lua_key_eq(s
, depth
)) {
5278 depth(n
) = (halfword
) lua_tointeger(L
, 3);
5279 } else if (lua_key_eq(s
, height
)) {
5280 height(n
) = (halfword
) lua_tointeger(L
, 3);
5281 } else if ((lua_key_eq(s
, list
)) || (lua_key_eq(s
, head
))) {
5282 ins_ptr(n
) = nodelib_getlist(L
, 3);
5284 } else if (lua_key_eq(s
, width
)) {
5285 width(n
) = (halfword
) lua_tointeger(L
, 3);
5286 } else if (lua_key_eq(s
, stretch
)) {
5287 stretch(n
) = (halfword
) lua_tointeger(L
, 3);
5288 } else if (lua_key_eq(s
, shrink
)) {
5289 shrink(n
) = (halfword
) lua_tointeger(L
, 3);
5290 } else if (lua_key_eq(s
, stretch_order
)) {
5291 stretch_order(n
) = (quarterword
) lua_tointeger(L
, 3);
5292 } else if (lua_key_eq(s
, shrink_order
)) {
5293 shrink_order(n
) = (quarterword
) lua_tointeger(L
, 3);
5295 return nodelib_cantset(L
, n
, s
);
5297 } else if (t
== math_node
) {
5298 if (lua_key_eq(s
, subtype
)) {
5299 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5300 } else if (lua_key_eq(s
, surround
)) {
5301 surround(n
) = (halfword
) lua_tointeger(L
, 3);
5303 } else if (lua_key_eq(s
, width
)) {
5304 width(n
) = (halfword
) lua_tointeger(L
, 3);
5305 } else if (lua_key_eq(s
, stretch
)) {
5306 stretch(n
) = (halfword
) lua_tointeger(L
, 3);
5307 } else if (lua_key_eq(s
, shrink
)) {
5308 shrink(n
) = (halfword
) lua_tointeger(L
, 3);
5309 } else if (lua_key_eq(s
, stretch_order
)) {
5310 stretch_order(n
) = (quarterword
) lua_tointeger(L
, 3);
5311 } else if (lua_key_eq(s
, shrink_order
)) {
5312 shrink_order(n
) = (quarterword
) lua_tointeger(L
, 3);
5314 return nodelib_cantset(L
, n
, s
);
5316 } else if (t
== fraction_noad
) {
5317 if (lua_key_eq(s
, subtype
)) {
5318 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5319 } else if (lua_key_eq(s
, width
)) {
5320 thickness(n
) = (halfword
) lua_tointeger(L
, 3);
5321 } else if (lua_key_eq(s
, num
)) {
5322 numerator(n
) = nodelib_getlist(L
, 3);
5323 } else if (lua_key_eq(s
, denom
)) {
5324 denominator(n
) = nodelib_getlist(L
, 3);
5325 } else if (lua_key_eq(s
, left
)) {
5326 left_delimiter(n
) = nodelib_getlist(L
, 3);
5327 } else if (lua_key_eq(s
, right
)) {
5328 right_delimiter(n
) = nodelib_getlist(L
, 3);
5330 return nodelib_cantset(L
, n
, s
);
5332 } else if (t
== style_node
) {
5333 if (lua_key_eq(s
, subtype
)) {
5335 } else if (lua_key_eq(s
, style
)) {
5336 assign_math_style(L
,3,subtype(n
));
5338 /* return nodelib_cantset(L, n, s); */
5340 } else if (t
== accent_noad
) {
5341 if (lua_key_eq(s
, subtype
)) {
5342 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5343 } else if (lua_key_eq(s
, nucleus
)) {
5344 nucleus(n
) = nodelib_getlist(L
, 3);
5345 } else if (lua_key_eq(s
, sub
)) {
5346 subscr(n
) = nodelib_getlist(L
, 3);
5347 } else if (lua_key_eq(s
, sup
)) {
5348 supscr(n
) = nodelib_getlist(L
, 3);
5349 } else if ((lua_key_eq(s
, top_accent
))||(lua_key_eq(s
, accent
))) {
5350 top_accent_chr(n
) = nodelib_getlist(L
, 3);
5351 } else if (lua_key_eq(s
, bot_accent
)) {
5352 bot_accent_chr(n
) = nodelib_getlist(L
, 3);
5353 } else if (lua_key_eq(s
, overlay_accent
)) {
5354 overlay_accent_chr(n
) = nodelib_getlist(L
, 3);
5356 return nodelib_cantset(L
, n
, s
);
5358 } else if (t
== fence_noad
) {
5359 if (lua_key_eq(s
, subtype
)) {
5360 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5361 } else if (lua_key_eq(s
, delim
)) {
5362 delimiter(n
) = nodelib_getlist(L
, 3);
5364 return nodelib_cantset(L
, n
, s
);
5366 } else if (t
== delim_node
) {
5367 if (lua_key_eq(s
, subtype
)) {
5368 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5369 } else if (lua_key_eq(s
, small_fam
)) {
5370 small_fam(n
) = (halfword
) lua_tointeger(L
, 3);
5371 } else if (lua_key_eq(s
, small_char
)) {
5372 small_char(n
) = (halfword
) lua_tointeger(L
, 3);
5373 } else if (lua_key_eq(s
, large_fam
)) {
5374 large_fam(n
) = (halfword
) lua_tointeger(L
, 3);
5375 } else if (lua_key_eq(s
, large_char
)) {
5376 large_char(n
) = (halfword
) lua_tointeger(L
, 3);
5378 return nodelib_cantset(L
, n
, s
);
5380 } else if ((t
== sub_box_node
) || (t
== sub_mlist_node
)) {
5381 if (lua_key_eq(s
, subtype
)) {
5382 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5383 } else if ((lua_key_eq(s
, list
)) || (lua_key_eq(s
, head
))){
5384 math_list(n
) = nodelib_getlist(L
, 3);
5386 return nodelib_cantset(L
, n
, s
);
5388 } else if (t
== radical_noad
) {
5389 if (lua_key_eq(s
, subtype
)) {
5390 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5391 } else if (lua_key_eq(s
, nucleus
)) {
5392 nucleus(n
) = nodelib_getlist(L
, 3);
5393 } else if (lua_key_eq(s
, sub
)) {
5394 subscr(n
) = nodelib_getlist(L
, 3);
5395 } else if (lua_key_eq(s
, sup
)) {
5396 supscr(n
) = nodelib_getlist(L
, 3);
5397 } else if (lua_key_eq(s
, left
)) {
5398 left_delimiter(n
) = nodelib_getlist(L
, 3);
5399 } else if (lua_key_eq(s
, degree
)) {
5400 degree(n
) = nodelib_getlist(L
, 3);
5402 return nodelib_cantset(L
, n
, s
);
5404 } else if (t
== margin_kern_node
) {
5405 if (lua_key_eq(s
, subtype
)) {
5406 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5407 } else if (lua_key_eq(s
, width
)) {
5408 width(n
) = (halfword
) lua_tointeger(L
, 3);
5409 } else if (lua_key_eq(s
, glyph
)) {
5410 margin_char(n
) = nodelib_getlist(L
, 3);
5412 return nodelib_cantset(L
, n
, s
);
5414 } else if (t
== split_up_node
) {
5415 if (lua_key_eq(s
, subtype
)) {
5416 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5417 } else if (lua_key_eq(s
, last_ins_ptr
)) {
5418 last_ins_ptr(n
) = nodelib_getlist(L
, 3);
5419 } else if (lua_key_eq(s
, best_ins_ptr
)) {
5420 best_ins_ptr(n
) = nodelib_getlist(L
, 3);
5421 } else if (lua_key_eq(s
, broken_ptr
)) {
5422 broken_ptr(n
) = nodelib_getlist(L
, 3);
5423 } else if (lua_key_eq(s
, broken_ins
)) {
5424 broken_ins(n
) = nodelib_getlist(L
, 3);
5426 return nodelib_cantset(L
, n
, s
);
5428 } else if (t
== choice_node
) {
5429 if (lua_key_eq(s
, subtype
)) {
5430 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5431 } else if (lua_key_eq(s
, display
)) {
5432 display_mlist(n
) = nodelib_getlist(L
, 3);
5433 } else if (lua_key_eq(s
, text
)) {
5434 text_mlist(n
) = nodelib_getlist(L
, 3);
5435 } else if (lua_key_eq(s
, script
)) {
5436 script_mlist(n
) = nodelib_getlist(L
, 3);
5437 } else if (lua_key_eq(s
, scriptscript
)) {
5438 script_script_mlist(n
) = nodelib_getlist(L
, 3);
5440 return nodelib_cantset(L
, n
, s
);
5442 } else if (t
== inserting_node
) {
5443 if (lua_key_eq(s
, subtype
)) {
5444 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5445 } else if (lua_key_eq(s
, last_ins_ptr
)) {
5446 last_ins_ptr(n
) = nodelib_getlist(L
, 3);
5447 } else if (lua_key_eq(s
, best_ins_ptr
)) {
5448 best_ins_ptr(n
) = nodelib_getlist(L
, 3);
5450 return nodelib_cantset(L
, n
, s
);
5452 } else if (t
== attribute_node
) {
5453 if (lua_key_eq(s
, subtype
)) {
5455 } else if (lua_key_eq(s
, number
)) {
5456 attribute_id(n
) = (halfword
) lua_tointeger(L
, 3);
5457 } else if (lua_key_eq(s
, value
)) {
5458 attribute_value(n
) = (halfword
) lua_tointeger(L
, 3);
5460 return nodelib_cantset(L
, n
, s
);
5462 } else if (t
== adjust_node
) {
5463 if (lua_key_eq(s
, subtype
)) {
5464 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5465 } else if ((lua_key_eq(s
, list
)) || (lua_key_eq(s
, head
))) {
5466 adjust_ptr(n
) = nodelib_getlist(L
, 3);
5468 return nodelib_cantset(L
, n
, s
);
5470 } else if (t
== unset_node
) {
5471 if (lua_key_eq(s
, subtype
)) {
5473 } else if (lua_key_eq(s
, width
)) {
5474 width(n
) = (halfword
) lua_tointeger(L
, 3);
5475 } else if (lua_key_eq(s
, height
)) {
5476 height(n
) = (halfword
) lua_tointeger(L
, 3);
5477 } else if (lua_key_eq(s
, depth
)) {
5478 depth(n
) = (halfword
) lua_tointeger(L
, 3);
5479 } else if (lua_key_eq(s
, dir
)) {
5480 box_dir(n
) = nodelib_getdir(L
, 3, 1);
5481 } else if (lua_key_eq(s
, shrink
)) {
5482 glue_shrink(n
) = (halfword
) lua_tointeger(L
, 3);
5483 } else if (lua_key_eq(s
, glue_order
)) {
5484 glue_order(n
) = (quarterword
) lua_tointeger(L
, 3);
5485 } else if (lua_key_eq(s
, glue_sign
)) {
5486 glue_sign(n
) = (quarterword
) lua_tointeger(L
, 3);
5487 } else if (lua_key_eq(s
, stretch
)) {
5488 glue_stretch(n
) = (halfword
) lua_tointeger(L
, 3);
5489 } else if (lua_key_eq(s
, count
)) {
5490 span_count(n
) = (quarterword
) lua_tointeger(L
, 3);
5491 } else if ((lua_key_eq(s
, list
)) || (lua_key_eq(s
, head
))){
5492 list_ptr(n
) = nodelib_getlist(L
, 3);
5494 return nodelib_cantset(L
, n
, s
);
5496 } else if (t
== attribute_list_node
) {
5497 if (lua_key_eq(s
, subtype
)) {
5500 return nodelib_cantset(L
, n
, s
);
5502 } else if (t
== boundary_node
) {
5503 if (lua_key_eq(s
, subtype
)) {
5504 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5505 } else if (lua_key_eq(s
, value
)) {
5506 boundary_value(n
) = lua_tointeger(L
, 3);
5508 return nodelib_cantset(L
, n
, s
);
5510 } else if (t
== glue_spec_node
) {
5511 if (lua_key_eq(s
, width
)) {
5512 width(n
) = (halfword
) lua_tointeger(L
, 3);
5513 } else if (lua_key_eq(s
, stretch
)) {
5514 stretch(n
) = (halfword
) lua_tointeger(L
, 3);
5515 } else if (lua_key_eq(s
, shrink
)) {
5516 shrink(n
) = (halfword
) lua_tointeger(L
, 3);
5517 } else if (lua_key_eq(s
, stretch_order
)) {
5518 stretch_order(n
) = (quarterword
) lua_tointeger(L
, 3);
5519 } else if (lua_key_eq(s
, shrink_order
)) {
5520 shrink_order(n
) = (quarterword
) lua_tointeger(L
, 3);
5522 return nodelib_cantset(L
, n
, s
);
5525 return luaL_error(L
, "You can't assign to this %s node (%d)\n", node_data
[t
].name
, n
);
5530 static int lua_nodelib_setfield(lua_State
* L
)
5532 /* [given-node] [...]*/
5533 halfword
*p
= lua_touserdata(L
, 1);
5534 if ( (p
== NULL
) || (! lua_getmetatable(L
,1)) ) {
5537 /* [given-node] [mt-given-node]*/
5538 lua_get_metatablelua(luatex_node
);
5539 /* [given-node] [mt-given-node] [mt-node]*/
5540 if ( (!lua_rawequal(L
, -1, -2)) ) {
5543 /* prune stack and call getfield */
5545 return lua_nodelib_fast_setfield(L
);
5548 /* node.direct.setfield */
5550 static int lua_nodelib_direct_setfield_whatsit(lua_State
* L
, int n
, const char *s
)
5553 if (t
== pdf_literal_node
) {
5554 if (lua_key_eq(s
, mode
)) {
5555 pdf_literal_mode(n
) = (quarterword
) lua_tointeger(L
, 3);
5556 } else if (lua_key_eq(s
, data
)) {
5558 pdf_literal_data(n
) = nodelib_gettoks(L
, 3);
5560 lua_pushvalue(L
, 3);
5561 pdf_literal_data(n
) = luaL_ref(L
, LUA_REGISTRYINDEX
);
5562 pdf_literal_type(n
) = lua_refid_literal
;
5565 return nodelib_cantset(L
, n
, s
);
5567 } else if (t
== late_lua_node
) {
5568 if (lua_key_eq(s
, string
)) {
5569 cleanup_late_lua(n
) ; /* ls-hh */
5571 late_lua_data(n
) = nodelib_gettoks(L
, 3);
5572 late_lua_type(n
) = normal
;
5574 lua_pushvalue(L
, 3);
5575 late_lua_data(n
) = luaL_ref(L
, LUA_REGISTRYINDEX
);
5576 late_lua_type(n
) = lua_refid_literal
;
5578 } else if (lua_key_eq(s
, data
)) {
5579 cleanup_late_lua(n
) ; /* ls-hh */
5580 late_lua_data(n
) = nodelib_gettoks(L
, 3);
5581 late_lua_type(n
) = normal
;
5582 } else if (lua_key_eq(s
, name
)) {
5583 cleanup_late_lua_name(n
) ; /* ls-hh */
5584 late_lua_name(n
) = nodelib_gettoks(L
, 3);
5586 return nodelib_cantset(L
, n
, s
);
5588 } else if (t
== user_defined_node
) {
5589 if (lua_key_eq(s
, user_id
)) {
5590 user_node_id(n
) = (halfword
) lua_tointeger(L
, 3);
5591 } else if (lua_key_eq(s
, type
)) {
5592 user_node_type(n
) = (halfword
) lua_tointeger(L
, 3);
5593 } else if (lua_key_eq(s
, value
)) {
5594 switch (user_node_type(n
)) {
5596 user_node_value(n
) = nodelib_getlist(L
, 3);
5599 user_node_value(n
) = (halfword
) lua_tointeger(L
, 3);
5602 lua_pushvalue(L
, 3);
5603 if (user_node_value(n
) != 0) {
5604 luaL_unref(L
, LUA_REGISTRYINDEX
,user_node_value(n
));
5606 user_node_value(n
) = luaL_ref(L
, LUA_REGISTRYINDEX
);
5609 user_node_value(n
) = nodelib_getlist(L
, 3);
5612 user_node_value(n
) = nodelib_getstring(L
, 3);
5615 user_node_value(n
) = nodelib_gettoks(L
, 3);
5618 user_node_value(n
) = (halfword
) lua_tointeger(L
, 3);
5622 return nodelib_cantset(L
, n
, s
);
5624 } else if (t
== pdf_annot_node
) {
5625 if (lua_key_eq(s
, width
)) {
5626 width(n
) = (halfword
) lua_tointeger(L
, 3);
5627 } else if (lua_key_eq(s
, depth
)) {
5628 depth(n
) = (halfword
) lua_tointeger(L
, 3);
5629 } else if (lua_key_eq(s
, height
)) {
5630 height(n
) = (halfword
) lua_tointeger(L
, 3);
5631 } else if (lua_key_eq(s
, objnum
)) {
5632 pdf_annot_objnum(n
) = (halfword
) lua_tointeger(L
, 3);
5633 } else if (lua_key_eq(s
, data
)) {
5634 pdf_annot_data(n
) = nodelib_gettoks(L
, 3);
5636 return nodelib_cantset(L
, n
, s
);
5638 } else if (t
== pdf_dest_node
) {
5639 if (lua_key_eq(s
, width
)) {
5640 width(n
) = (halfword
) lua_tointeger(L
, 3);
5641 } else if (lua_key_eq(s
, depth
)) {
5642 depth(n
) = (halfword
) lua_tointeger(L
, 3);
5643 } else if (lua_key_eq(s
, height
)) {
5644 height(n
) = (halfword
) lua_tointeger(L
, 3);
5645 } else if (lua_key_eq(s
, named_id
)) {
5646 pdf_dest_named_id(n
) = (quarterword
) lua_tointeger(L
, 3);
5647 } else if (lua_key_eq(s
, dest_id
)) {
5648 if (pdf_dest_named_id(n
) == 1) {
5649 pdf_dest_id(n
) = nodelib_gettoks(L
, 3);
5651 pdf_dest_id(n
) = (halfword
) lua_tointeger(L
, 3);
5653 } else if (lua_key_eq(s
, dest_type
)) {
5654 pdf_dest_type(n
) = (quarterword
) lua_tointeger(L
, 3);
5655 } else if (lua_key_eq(s
, xyz_zoom
)) {
5656 pdf_dest_xyz_zoom(n
) = (halfword
) lua_tointeger(L
, 3);
5657 } else if (lua_key_eq(s
, objnum
)) {
5658 pdf_dest_objnum(n
) = (halfword
) lua_tointeger(L
, 3);
5660 return nodelib_cantset(L
, n
, s
);
5662 } else if (t
== pdf_setmatrix_node
) {
5663 if (lua_key_eq(s
, data
)) {
5664 pdf_setmatrix_data(n
) = nodelib_gettoks(L
, 3);
5666 return nodelib_cantset(L
, n
, s
);
5668 } else if (t
== pdf_refobj_node
) {
5669 if (lua_key_eq(s
, objnum
)) {
5670 pdf_obj_objnum(n
) = (halfword
) lua_tointeger(L
, 3);
5672 return nodelib_cantset(L
, n
, s
);
5674 } else if (t
== pdf_start_link_node
) {
5675 if (lua_key_eq(s
, width
)) {
5676 width(n
) = (halfword
) lua_tointeger(L
, 3);
5677 } else if (lua_key_eq(s
, depth
)) {
5678 depth(n
) = (halfword
) lua_tointeger(L
, 3);
5679 } else if (lua_key_eq(s
, height
)) {
5680 height(n
) = (halfword
) lua_tointeger(L
, 3);
5681 } else if (lua_key_eq(s
, objnum
)) {
5682 pdf_link_objnum(n
) = (halfword
) lua_tointeger(L
, 3);
5683 } else if (lua_key_eq(s
, link_attr
)) {
5684 pdf_link_attr(n
) = nodelib_gettoks(L
, 3);
5685 } else if (lua_key_eq(s
, action
)) {
5686 pdf_link_action(n
) = nodelib_popdirect(n
); /*nodelib_getaction(L, 3);*/
5688 return nodelib_cantset(L
, n
, s
);
5690 } else if (t
== write_node
) {
5691 if (lua_key_eq(s
, stream
)) {
5692 write_stream(n
) = (halfword
) lua_tointeger(L
, 3);
5693 } else if (lua_key_eq(s
, data
)) {
5694 write_tokens(n
) = nodelib_gettoks(L
, 3);
5696 return nodelib_cantset(L
, n
, s
);
5698 } else if (t
== pdf_colorstack_node
) {
5699 if (lua_key_eq(s
, stack
)) {
5700 pdf_colorstack_stack(n
) = (halfword
) lua_tointeger(L
, 3);
5701 } else if (lua_key_eq(s
, command
)) {
5702 pdf_colorstack_cmd(n
) = (halfword
) lua_tointeger(L
, 3);
5703 } else if (lua_key_eq(s
, data
)) {
5704 pdf_colorstack_data(n
) = nodelib_gettoks(L
, 3);
5706 return nodelib_cantset(L
, n
, s
);
5708 } else if (t
== pdf_action_node
) {
5709 if (lua_key_eq(s
, action_type
)) {
5710 pdf_action_type(n
) = (quarterword
) lua_tointeger(L
, 3);
5711 } else if (lua_key_eq(s
, named_id
)) {
5712 pdf_action_named_id(n
) = (quarterword
) lua_tointeger(L
, 3);
5713 } else if (lua_key_eq(s
, action_id
)) {
5714 if (pdf_action_named_id(n
) == 1) {
5715 pdf_action_id(n
) = nodelib_gettoks(L
, 3);
5717 pdf_action_id(n
) = (halfword
) lua_tointeger(L
, 3);
5719 } else if (lua_key_eq(s
, file
)) {
5720 pdf_action_file(n
) = nodelib_gettoks(L
, 3);
5721 } else if (lua_key_eq(s
, new_window
)) {
5722 pdf_action_new_window(n
) = (halfword
) lua_tointeger(L
, 3);
5723 } else if (lua_key_eq(s
, data
)) {
5724 pdf_action_tokens(n
) = nodelib_gettoks(L
, 3);
5726 return nodelib_cantset(L
, n
, s
);
5728 } else if ((t
== pdf_thread_node
) || (t
== pdf_start_thread_node
)) {
5729 if (lua_key_eq(s
, width
)) {
5730 width(n
) = (halfword
) lua_tointeger(L
, 3);
5731 } else if (lua_key_eq(s
, depth
)) {
5732 depth(n
) = (halfword
) lua_tointeger(L
, 3);
5733 } else if (lua_key_eq(s
, height
)) {
5734 height(n
) = (halfword
) lua_tointeger(L
, 3);
5735 } else if (lua_key_eq(s
, named_id
)) {
5736 pdf_thread_named_id(n
) = (quarterword
) lua_tointeger(L
, 3);
5737 } else if (lua_key_eq(s
, thread_id
)) {
5738 if (pdf_thread_named_id(n
) == 1) {
5739 pdf_thread_id(n
) = nodelib_gettoks(L
, 3);
5741 pdf_thread_id(n
) = (halfword
) lua_tointeger(L
, 3);
5743 } else if (lua_key_eq(s
, thread_attr
)) {
5744 pdf_thread_attr(n
) = nodelib_gettoks(L
, 3);
5746 return nodelib_cantset(L
, n
, s
);
5748 } else if (t
== special_node
) {
5749 if (lua_key_eq(s
, data
)) {
5750 write_tokens(n
) = nodelib_gettoks(L
, 3);
5752 return nodelib_cantset(L
, n
, s
);
5754 } else if (t
== open_node
) {
5755 if (lua_key_eq(s
, stream
)) {
5756 write_stream(n
) = (halfword
) lua_tointeger(L
, 3);
5757 } else if (lua_key_eq(s
, name
)) {
5758 open_name(n
) = nodelib_getstring(L
, 3);
5759 } else if (lua_key_eq(s
, area
)) {
5760 open_area(n
) = nodelib_getstring(L
, 3);
5761 } else if (lua_key_eq(s
, ext
)) {
5762 open_ext(n
) = nodelib_getstring(L
, 3);
5764 return nodelib_cantset(L
, n
, s
);
5766 } else if (t
== close_node
) {
5767 if (lua_key_eq(s
, stream
)) {
5768 write_stream(n
) = (halfword
) lua_tointeger(L
, 3);
5770 return nodelib_cantset(L
, n
, s
);
5772 } else if ((t
== pdf_end_link_node
) || (t
== pdf_end_thread_node
) || (t
== save_pos_node
) ||
5773 (t
== pdf_save_node
) || (t
== pdf_restore_node
)) {
5774 return nodelib_cantset(L
, n
, s
);
5781 static int lua_nodelib_direct_setcharacter(lua_State
* L
)
5783 halfword n
= lua_tointeger(L
, 1);
5784 if ((n
) && (lua_type(L
, 2) == LUA_TNUMBER
)) {
5785 if (type(n
) == glyph_node
) {
5786 character(n
) = (halfword
) lua_tointeger(L
, 2);
5787 } else if ((type(n
) == math_char_node
) || (type(n
) == math_text_char_node
)) {
5788 math_character(n
) = (halfword
) lua_tointeger(L
, 2);
5794 static int lua_nodelib_direct_setnext(lua_State
* L
)
5796 halfword n
= lua_tointeger(L
, 1);
5798 if (lua_type(L
, 2) == LUA_TNUMBER
) {
5799 vlink(n
) = (halfword
) lua_tointeger(L
, 2);
5807 static int lua_nodelib_direct_setprev(lua_State
* L
)
5809 halfword n
= lua_tointeger(L
, 1);
5811 if (lua_type(L
, 2) == LUA_TNUMBER
) {
5812 alink(n
) = (halfword
) lua_tointeger(L
, 2);
5820 static int lua_nodelib_direct_setboth(lua_State
* L
)
5822 halfword n
= lua_tointeger(L
, 1);
5824 if (lua_type(L
, 2) == LUA_TNUMBER
) {
5825 alink(n
) = (halfword
) lua_tointeger(L
, 2);
5829 if (lua_type(L
, 3) == LUA_TNUMBER
) {
5830 vlink(n
) = (halfword
) lua_tointeger(L
, 3);
5838 static int lua_nodelib_direct_setlink(lua_State
* L
)
5840 if (lua_type(L
, 1) == LUA_TNUMBER
) {
5841 halfword a
= lua_tointeger(L
, 1);
5842 if (lua_type(L
, 2) == LUA_TNUMBER
) {
5843 halfword b
= lua_tointeger(L
, 2);
5849 } else if (lua_type(L
, 2) == LUA_TNUMBER
) {
5850 halfword b
= lua_tointeger(L
, 2);
5856 static int lua_nodelib_direct_is_char(lua_State
* L
)
5858 halfword n
= lua_tointeger(L
, 1);
5859 if (type(n
) != glyph_node
) {
5860 lua_pushnil(L
); /* no glyph at all */
5861 lua_pushinteger(L
,type(n
)); /* can save a lookup call */
5863 } else if (subtype(n
) >= 256) {
5864 lua_pushboolean(L
,0); /* a done glyph */
5865 } else if (lua_type(L
,2) == LUA_TNUMBER
) {
5866 halfword f
= lua_tointeger(L
, 2);
5867 if (f
&& f
== font(n
)) {
5868 lua_pushinteger(L
,character(n
)); /* a todo glyph in the asked font */
5870 lua_pushboolean(L
,0); /* a todo glyph in another font */
5873 lua_pushinteger(L
,character(n
)); /* a todo glyph */
5878 static int lua_nodelib_direct_is_glyph(lua_State
* L
)
5880 halfword n
= lua_tointeger(L
, 1);
5881 if (type(n
) != glyph_node
) {
5882 lua_pushboolean(L
,0);
5883 lua_pushinteger(L
,type(n
));
5885 lua_pushinteger(L
,character(n
));
5886 lua_pushinteger(L
,font(n
));
5891 static int lua_nodelib_direct_setdiscretionary(lua_State
* L
)
5893 halfword n
= lua_tointeger(L
, 1);
5894 if (type(n
) == disc_node
) {
5895 int t
= lua_gettop(L
) ;
5897 set_disc_field(pre_break(n
), lua_tointeger(L
,2));
5899 set_disc_field(post_break(n
), lua_tointeger(L
,3));
5901 set_disc_field(no_break(n
), lua_tointeger(L
,4));
5903 subtype(n
) = (quarterword
) lua_tointeger(L
,5);
5905 disc_penalty(n
) = lua_tointeger(L
,6);
5909 set_disc_field(no_break(n
), null
);
5912 set_disc_field(post_break(n
), null
);
5913 set_disc_field(no_break(n
), null
);
5916 set_disc_field(pre_break(n
), null
);
5917 set_disc_field(post_break(n
), null
);
5918 set_disc_field(no_break(n
), null
);
5925 static int lua_nodelib_direct_setfield(lua_State
* L
)
5929 halfword n
= lua_tointeger(L
, 1);
5932 if (lua_type(L
, 2) == LUA_TNUMBER
) {
5933 if (lua_gettop(L
) == 3) {
5934 int i
= lua_tointeger(L
, 2);
5935 int val
= lua_tointeger(L
, 3);
5936 if (val
== UNUSED_ATTRIBUTE
) {
5937 (void) unset_attribute(n
, i
, val
);
5939 set_attribute(n
, i
, val
);
5942 luaL_error(L
, "incorrect number of arguments");
5947 s
= lua_tostring(L
, 2);
5949 /*if (lua_key_eq(s, id)) {
5950 type(n) = (quarteword) lua_tointeger(L, 3);
5952 if (lua_key_eq(s
, next
)) {
5953 halfword x
= nodelib_popdirect(3);
5954 if (x
>0 && type(x
) == glue_spec_node
) {
5955 return luaL_error(L
, "You can't assign a %s node to a next field\n", node_data
[type(x
)].name
);
5958 } else if (lua_key_eq(s
, prev
)) {
5959 halfword x
= nodelib_popdirect(3);
5960 if (x
>0 && type(x
) == glue_spec_node
) {
5961 return luaL_error(L
, "You can't assign a %s node to a prev field\n", node_data
[type(x
)].name
);
5964 } else if (lua_key_eq(s
, attr
)) {
5965 if (nodetype_has_attributes(type(n
))) {
5966 nodelib_setattr(L
, 3, n
);
5968 } else if (t
== glyph_node
) {
5969 if (lua_key_eq(s
, subtype
)) {
5970 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5971 } else if (lua_key_eq(s
, font
)) {
5972 font(n
) = (halfword
) lua_tointeger(L
, 3);
5973 } else if (lua_key_eq(s
, char)) {
5974 character(n
) = (halfword
) lua_tointeger(L
, 3);
5975 } else if (lua_key_eq(s
, xoffset
)) {
5976 x_displace(n
) = (halfword
) lua_tointeger(L
, 3);
5977 } else if (lua_key_eq(s
, yoffset
)) {
5978 y_displace(n
) = (halfword
) lua_tointeger(L
, 3);
5979 } else if (lua_key_eq(s
, xadvance
)) {
5980 x_advance(n
) = (halfword
) lua_tointeger(L
, 3);
5981 } else if (lua_key_eq(s
, expansion_factor
)) {
5982 ex_glyph(n
) = (halfword
) lua_tointeger(L
, 3);
5983 } else if (lua_key_eq(s
, components
)) {
5984 lig_ptr(n
) = nodelib_popdirect(3);
5985 } else if (lua_key_eq(s
, lang
)) {
5986 set_char_lang(n
, (halfword
) lua_tointeger(L
, 3));
5987 } else if (lua_key_eq(s
, left
)) {
5988 set_char_lhmin(n
, (halfword
) lua_tointeger(L
, 3));
5989 } else if (lua_key_eq(s
, right
)) {
5990 set_char_rhmin(n
, (halfword
) lua_tointeger(L
, 3));
5991 } else if (lua_key_eq(s
, uchyph
)) {
5992 set_char_uchyph(n
, (halfword
) lua_tointeger(L
, 3));
5993 } else if (lua_key_eq(s
, width
)) {
5995 } else if (lua_key_eq(s
, height
)) {
5997 } else if (lua_key_eq(s
, depth
)) {
6000 return nodelib_cantset(L
, n
, s
);
6002 } else if ((t
== hlist_node
) || (t
== vlist_node
)) {
6003 if (lua_key_eq(s
, subtype
)) {
6004 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
6005 } else if (lua_key_eq(s
, list
) || lua_key_eq(s
, head
)) {
6006 list_ptr(n
) = nodelib_popdirect(3);
6007 } else if (lua_key_eq(s
, width
)) {
6008 width(n
) = (halfword
) lua_tointeger(L
, 3);
6009 } else if (lua_key_eq(s
, height
)) {
6010 height(n
) = (halfword
) lua_tointeger(L
, 3);
6011 } else if (lua_key_eq(s
, depth
)) {
6012 depth(n
) = (halfword
) lua_tointeger(L
, 3);
6013 } else if (lua_key_eq(s
, dir
)) {
6014 box_dir(n
) = nodelib_getdir(L
, 3, 1);
6015 } else if (lua_key_eq(s
, shift
)) {
6016 shift_amount(n
) = (halfword
) lua_tointeger(L
, 3);
6017 } else if (lua_key_eq(s
, glue_order
)) {
6018 glue_order(n
) = (quarterword
) lua_tointeger(L
, 3);
6019 } else if (lua_key_eq(s
, glue_sign
)) {
6020 glue_sign(n
) = (quarterword
) lua_tointeger(L
, 3);
6021 } else if (lua_key_eq(s
, glue_set
)) {
6022 glue_set(n
) = (glue_ratio
) lua_tonumber(L
, 3); /* integer or float */
6024 return nodelib_cantset(L
, n
, s
);
6026 } else if (t
== disc_node
) {
6027 if (lua_key_eq(s
, subtype
)) {
6028 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
6029 } else if (lua_key_eq(s
, pre
)) {
6030 set_disc_field(pre_break(n
), nodelib_popdirect(3));
6031 } else if (lua_key_eq(s
, post
)) {
6032 set_disc_field(post_break(n
), nodelib_popdirect(3));
6033 } else if (lua_key_eq(s
, replace
)) {
6034 set_disc_field(no_break(n
), nodelib_popdirect(3));
6035 } else if (lua_key_eq(s
, penalty
)) {
6036 disc_penalty(n
) = (quarterword
) lua_tointeger(L
, 3);
6038 return nodelib_cantset(L
, n
, s
);
6040 } else if (t
== glue_node
) {
6041 if (lua_key_eq(s
, subtype
)) {
6042 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
6043 } else if (lua_key_eq(s
, width
)) {
6044 width(n
) = (halfword
) lua_tointeger(L
, 3);
6045 } else if (lua_key_eq(s
, stretch
)) {
6046 stretch(n
) = (halfword
) lua_tointeger(L
, 3);
6047 } else if (lua_key_eq(s
, shrink
)) {
6048 shrink(n
) = (halfword
) lua_tointeger(L
, 3);
6049 } else if (lua_key_eq(s
, stretch_order
)) {
6050 stretch_order(n
) = (quarterword
) lua_tointeger(L
, 3);
6051 } else if (lua_key_eq(s
, shrink_order
)) {
6052 shrink_order(n
) = (quarterword
) lua_tointeger(L
, 3);
6053 } else if (lua_key_eq(s
, leader
)) {
6054 leader_ptr(n
) = nodelib_popdirect(3);
6056 return nodelib_cantset(L
, n
, s
);
6058 } else if (t
== kern_node
) {
6059 if (lua_key_eq(s
, subtype
)) {
6060 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
6061 } else if (lua_key_eq(s
, kern
)) {
6062 width(n
) = (halfword
) lua_tointeger(L
, 3);
6063 } else if (lua_key_eq(s
, expansion_factor
)) {
6064 ex_kern(n
) = (halfword
) lua_tointeger(L
, 3);
6066 return nodelib_cantset(L
, n
, s
);
6068 } else if (t
== penalty_node
) {
6069 if (lua_key_eq(s
, subtype
)) {
6071 } else if (lua_key_eq(s
, penalty
)) {
6072 penalty(n
) = (halfword
) lua_tointeger(L
, 3);
6074 return nodelib_cantset(L
, n
, s
);
6076 } else if (t
== rule_node
) {
6077 if (lua_key_eq(s
, subtype
)) {
6078 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
6079 } else if (lua_key_eq(s
, width
)) {
6080 width(n
) = (halfword
) lua_tointeger(L
, 3);
6081 } else if (lua_key_eq(s
, height
)) {
6082 height(n
) = (halfword
) lua_tointeger(L
, 3);
6083 } else if (lua_key_eq(s
, depth
)) {
6084 depth(n
) = (halfword
) lua_tointeger(L
, 3);
6085 } else if (lua_key_eq(s
, dir
)) {
6086 rule_dir(n
) = nodelib_getdir(L
, 3, 1);
6087 } else if (lua_key_eq(s
, index
)) {
6088 rule_index(n
) = (halfword
) lua_tointeger(L
, 3);
6089 } else if (lua_key_eq(s
, transform
)) {
6090 rule_transform(n
) = (halfword
) lua_tointeger(L
, 3);
6092 return nodelib_cantset(L
, n
, s
);
6094 } else if (t
== dir_node
) {
6095 if (lua_key_eq(s
, dir
)) {
6096 dir_dir(n
) = nodelib_getdir(L
, 3, 0);
6097 } else if (lua_key_eq(s
, level
)) {
6098 dir_level(n
) = (halfword
) lua_tointeger(L
, 3);
6099 } else if (lua_key_eq(s
, subtype
)) { /* can be used for anything */
6100 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
6102 return nodelib_cantset(L
, n
, s
);
6104 } else if (t
== whatsit_node
) {
6105 if (lua_key_eq(s
, subtype
)) {
6106 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
6108 lua_nodelib_direct_setfield_whatsit(L
, n
, s
);
6110 } else if (t
== local_par_node
) {
6111 if (lua_key_eq(s
, pen_inter
)) {
6112 local_pen_inter(n
) = (halfword
) lua_tointeger(L
, 3);
6113 } else if (lua_key_eq(s
, pen_broken
)) {
6114 local_pen_broken(n
) = (halfword
) lua_tointeger(L
, 3);
6115 } else if (lua_key_eq(s
, dir
)) {
6116 local_par_dir(n
) = nodelib_getdir(L
, 3, 1);
6117 } else if (lua_key_eq(s
, box_left
)) {
6118 local_box_left(n
) = nodelib_getlist(L
, 3);
6119 } else if (lua_key_eq(s
, box_left_width
)) {
6120 local_box_left_width(n
) = (halfword
) lua_tointeger(L
, 3);
6121 } else if (lua_key_eq(s
, box_right
)) {
6122 local_box_right(n
) = nodelib_getlist(L
, 3);
6123 } else if (lua_key_eq(s
, box_right_width
)) {
6124 local_box_right_width(n
) = (halfword
) lua_tointeger(L
, 3);
6126 return nodelib_cantset(L
, n
, s
);
6128 } else if (t
== simple_noad
) {
6129 if (lua_key_eq(s
, subtype
)) {
6130 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
6131 } else if (lua_key_eq(s
, nucleus
)) {
6132 nucleus(n
) = nodelib_popdirect(3);
6133 } else if (lua_key_eq(s
, sub
)) {
6134 subscr(n
) = nodelib_popdirect(3);
6135 } else if (lua_key_eq(s
, sup
)) {
6136 supscr(n
) = nodelib_popdirect(3);
6138 return nodelib_cantset(L
, n
, s
);
6140 } else if ((t
== math_char_node
) || (t
== math_text_char_node
)) {
6141 if (lua_key_eq(s
, subtype
)) {
6142 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
6143 } else if (lua_key_eq(s
, fam
)) {
6144 math_fam(n
) = (halfword
) lua_tointeger(L
, 3);
6145 } else if (lua_key_eq(s
, char)) {
6146 math_character(n
) = (halfword
) lua_tointeger(L
, 3);
6148 return nodelib_cantset(L
, n
, s
);
6150 } else if (t
== mark_node
) {
6151 if (lua_key_eq(s
, subtype
)) {
6152 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
6153 } else if (lua_key_eq(s
, class)) {
6154 mark_class(n
) = (halfword
) lua_tointeger(L
, 3);
6155 } else if (lua_key_eq(s
, mark
)) {
6156 mark_ptr(n
) = nodelib_gettoks(L
, 3);
6158 return nodelib_cantset(L
, n
, s
);
6160 } else if (t
== ins_node
) {
6161 if (lua_key_eq(s
, subtype
)) {
6162 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
6163 } else if (lua_key_eq(s
, cost
)) {
6164 float_cost(n
) = (halfword
) lua_tointeger(L
, 3);
6165 } else if (lua_key_eq(s
, depth
)) {
6166 depth(n
) = (halfword
) lua_tointeger(L
, 3);
6167 } else if (lua_key_eq(s
, height
)) {
6168 height(n
) = (halfword
) lua_tointeger(L
, 3);
6169 } else if ((lua_key_eq(s
, list
)) || (lua_key_eq(s
, head
))) {
6170 ins_ptr(n
) = nodelib_popdirect(3);
6172 } else if (lua_key_eq(s
, width
)) {
6173 width(n
) = (halfword
) lua_tointeger(L
, 3);
6174 } else if (lua_key_eq(s
, stretch
)) {
6175 stretch(n
) = (halfword
) lua_tointeger(L
, 3);
6176 } else if (lua_key_eq(s
, shrink
)) {
6177 shrink(n
) = (halfword
) lua_tointeger(L
, 3);
6178 } else if (lua_key_eq(s
, stretch_order
)) {
6179 stretch_order(n
) = (quarterword
) lua_tointeger(L
, 3);
6180 } else if (lua_key_eq(s
, shrink_order
)) {
6181 shrink_order(n
) = (quarterword
) lua_tointeger(L
, 3);
6183 return nodelib_cantset(L
, n
, s
);
6185 } else if (t
== math_node
) {
6186 if (lua_key_eq(s
, subtype
)) {
6187 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
6188 } else if (lua_key_eq(s
, surround
)) {
6189 surround(n
) = (halfword
) lua_tointeger(L
, 3);
6191 } else if (lua_key_eq(s
, width
)) {
6192 width(n
) = (halfword
) lua_tointeger(L
, 3);
6193 } else if (lua_key_eq(s
, stretch
)) {
6194 stretch(n
) = (halfword
) lua_tointeger(L
, 3);
6195 } else if (lua_key_eq(s
, shrink
)) {
6196 shrink(n
) = (halfword
) lua_tointeger(L
, 3);
6197 } else if (lua_key_eq(s
, stretch_order
)) {
6198 stretch_order(n
) = (quarterword
) lua_tointeger(L
, 3);
6199 } else if (lua_key_eq(s
, shrink_order
)) {
6200 shrink_order(n
) = (quarterword
) lua_tointeger(L
, 3);
6202 return nodelib_cantset(L
, n
, s
);
6204 } else if (t
== fraction_noad
) {
6205 if (lua_key_eq(s
, subtype
)) {
6206 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
6207 } else if (lua_key_eq(s
, width
)) {
6208 thickness(n
) = (halfword
) lua_tointeger(L
, 3);
6209 } else if (lua_key_eq(s
, num
)) {
6210 numerator(n
) = nodelib_popdirect(3);
6211 } else if (lua_key_eq(s
, denom
)) {
6212 denominator(n
) = nodelib_popdirect(3);
6213 } else if (lua_key_eq(s
, left
)) {
6214 left_delimiter(n
) = nodelib_popdirect(3);
6215 } else if (lua_key_eq(s
, right
)) {
6216 right_delimiter(n
) = nodelib_popdirect(3);
6218 return nodelib_cantset(L
, n
, s
);
6220 } else if (t
== style_node
) {
6221 if (lua_key_eq(s
, subtype
)) {
6223 } else if (lua_key_eq(s
, style
)) {
6224 assign_math_style(L
,2,subtype(n
));
6226 /* return nodelib_cantset(L, n, s); */
6228 } else if (t
== accent_noad
) {
6229 if (lua_key_eq(s
, subtype
)) {
6230 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
6231 } else if (lua_key_eq(s
, nucleus
)) {
6232 nucleus(n
) = nodelib_popdirect(3);
6233 } else if (lua_key_eq(s
, sub
)) {
6234 subscr(n
) = nodelib_popdirect(3);
6235 } else if (lua_key_eq(s
, sup
)) {
6236 supscr(n
) = nodelib_popdirect(3);
6237 } else if ((lua_key_eq(s
, top_accent
))||(lua_key_eq(s
, accent
))) {
6238 top_accent_chr(n
) = nodelib_popdirect(3);
6239 } else if (lua_key_eq(s
, bot_accent
)) {
6240 bot_accent_chr(n
) = nodelib_popdirect(3);
6241 } else if (lua_key_eq(s
, overlay_accent
)) {
6242 overlay_accent_chr(n
) = nodelib_popdirect(3);
6244 return nodelib_cantset(L
, n
, s
);
6246 } else if (t
== fence_noad
) {
6247 if (lua_key_eq(s
, subtype
)) {
6248 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
6249 } else if (lua_key_eq(s
, delim
)) {
6250 delimiter(n
) = nodelib_popdirect(3);
6252 return nodelib_cantset(L
, n
, s
);
6254 } else if (t
== delim_node
) {
6255 if (lua_key_eq(s
, subtype
)) {
6256 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
6257 } else if (lua_key_eq(s
, small_fam
)) {
6258 small_fam(n
) = (halfword
) lua_tointeger(L
, 3);
6259 } else if (lua_key_eq(s
, small_char
)) {
6260 small_char(n
) = (halfword
) lua_tointeger(L
, 3);
6261 } else if (lua_key_eq(s
, large_fam
)) {
6262 large_fam(n
) = (halfword
) lua_tointeger(L
, 3);
6263 } else if (lua_key_eq(s
, large_char
)) {
6264 large_char(n
) = (halfword
) lua_tointeger(L
, 3);
6266 return nodelib_cantset(L
, n
, s
);
6268 } else if ((t
== sub_box_node
) || (t
== sub_mlist_node
)) {
6269 if (lua_key_eq(s
, subtype
)) {
6270 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
6271 } else if ((lua_key_eq(s
, list
)) || (lua_key_eq(s
, head
))){
6272 math_list(n
) = nodelib_popdirect(3);
6274 return nodelib_cantset(L
, n
, s
);
6276 } else if (t
== radical_noad
) {
6277 if (lua_key_eq(s
, subtype
)) {
6278 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
6279 } else if (lua_key_eq(s
, nucleus
)) {
6280 nucleus(n
) = nodelib_popdirect(3);
6281 } else if (lua_key_eq(s
, sub
)) {
6282 subscr(n
) = nodelib_popdirect(3);
6283 } else if (lua_key_eq(s
, sup
)) {
6284 supscr(n
) = nodelib_popdirect(3);
6285 } else if (lua_key_eq(s
, left
)) {
6286 left_delimiter(n
) = nodelib_popdirect(3);
6287 } else if (lua_key_eq(s
, degree
)) {
6288 degree(n
) = nodelib_popdirect(3);
6290 return nodelib_cantset(L
, n
, s
);
6292 } else if (t
== margin_kern_node
) {
6293 if (lua_key_eq(s
, subtype
)) {
6294 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
6295 } else if (lua_key_eq(s
, width
)) {
6296 width(n
) = (halfword
) lua_tointeger(L
, 3);
6297 } else if (lua_key_eq(s
, glyph
)) {
6298 margin_char(n
) = nodelib_popdirect(3);
6300 return nodelib_cantset(L
, n
, s
);
6302 } else if (t
== split_up_node
) {
6303 if (lua_key_eq(s
, subtype
)) {
6304 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
6305 } else if (lua_key_eq(s
, last_ins_ptr
)) {
6306 last_ins_ptr(n
) = nodelib_popdirect(3);
6307 } else if (lua_key_eq(s
, best_ins_ptr
)) {
6308 best_ins_ptr(n
) = nodelib_popdirect(3);
6309 } else if (lua_key_eq(s
, broken_ptr
)) {
6310 broken_ptr(n
) = nodelib_popdirect(3);
6311 } else if (lua_key_eq(s
, broken_ins
)) {
6312 broken_ins(n
) = nodelib_popdirect(3);
6314 return nodelib_cantset(L
, n
, s
);
6316 } else if (t
== choice_node
) {
6317 if (lua_key_eq(s
, subtype
)) {
6318 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
6319 } else if (lua_key_eq(s
, display
)) {
6320 display_mlist(n
) = nodelib_popdirect(3);
6321 } else if (lua_key_eq(s
, text
)) {
6322 text_mlist(n
) = nodelib_popdirect(3);
6323 } else if (lua_key_eq(s
, script
)) {
6324 script_mlist(n
) = nodelib_popdirect(3);
6325 } else if (lua_key_eq(s
, scriptscript
)) {
6326 script_script_mlist(n
) = nodelib_popdirect(3);
6328 return nodelib_cantset(L
, n
, s
);
6330 } else if (t
== inserting_node
) {
6331 if (lua_key_eq(s
, subtype
)) {
6332 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
6333 } else if (lua_key_eq(s
, last_ins_ptr
)) {
6334 last_ins_ptr(n
) = nodelib_popdirect(3);
6335 } else if (lua_key_eq(s
, best_ins_ptr
)) {
6336 best_ins_ptr(n
) = nodelib_popdirect(3);
6338 return nodelib_cantset(L
, n
, s
);
6340 } else if (t
== attribute_node
) {
6341 if (lua_key_eq(s
, subtype
)) {
6343 } else if (lua_key_eq(s
, number
)) {
6344 attribute_id(n
) = (halfword
) lua_tointeger(L
, 3);
6345 } else if (lua_key_eq(s
, value
)) {
6346 attribute_value(n
) = (halfword
) lua_tointeger(L
, 3);
6348 return nodelib_cantset(L
, n
, s
);
6350 } else if (t
== adjust_node
) {
6351 if (lua_key_eq(s
, subtype
)) {
6352 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
6353 } else if ((lua_key_eq(s
, list
)) || (lua_key_eq(s
, head
))) {
6354 adjust_ptr(n
) = nodelib_popdirect(3);
6356 return nodelib_cantset(L
, n
, s
);
6358 } else if (t
== unset_node
) {
6359 if (lua_key_eq(s
, subtype
)) {
6361 } else if (lua_key_eq(s
, width
)) {
6362 width(n
) = (halfword
) lua_tointeger(L
, 3);
6363 } else if (lua_key_eq(s
, height
)) {
6364 height(n
) = (halfword
) lua_tointeger(L
, 3);
6365 } else if (lua_key_eq(s
, depth
)) {
6366 depth(n
) = (halfword
) lua_tointeger(L
, 3);
6367 } else if (lua_key_eq(s
, dir
)) {
6368 box_dir(n
) = nodelib_getdir(L
, 3, 1);
6369 } else if (lua_key_eq(s
, shrink
)) {
6370 glue_shrink(n
) = (halfword
) lua_tointeger(L
, 3);
6371 } else if (lua_key_eq(s
, glue_order
)) {
6372 glue_order(n
) = (quarterword
) lua_tointeger(L
, 3);
6373 } else if (lua_key_eq(s
, glue_sign
)) {
6374 glue_sign(n
) = (quarterword
) lua_tointeger(L
, 3);
6375 } else if (lua_key_eq(s
, stretch
)) {
6376 glue_stretch(n
) = (halfword
) lua_tointeger(L
, 3);
6377 } else if (lua_key_eq(s
, count
)) {
6378 span_count(n
) = (quarterword
) lua_tointeger(L
, 3);
6379 } else if ((lua_key_eq(s
, list
)) || (lua_key_eq(s
, head
))){
6380 list_ptr(n
) = nodelib_popdirect(3);
6382 return nodelib_cantset(L
, n
, s
);
6384 } else if (t
== attribute_list_node
) {
6385 if (lua_key_eq(s
, subtype
)) {
6388 return nodelib_cantset(L
, n
, s
);
6390 } else if (t
== boundary_node
) {
6391 if (lua_key_eq(s
, subtype
)) {
6392 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
6393 } else if (lua_key_eq(s
, value
)) {
6394 boundary_value(n
) = lua_tointeger(L
, 3);
6396 return nodelib_cantset(L
, n
, s
);
6398 } else if (t
== glue_spec_node
) {
6399 if (lua_key_eq(s
, width
)) {
6400 width(n
) = (halfword
) lua_tointeger(L
, 3);
6401 } else if (lua_key_eq(s
, stretch
)) {
6402 stretch(n
) = (halfword
) lua_tointeger(L
, 3);
6403 } else if (lua_key_eq(s
, shrink
)) {
6404 shrink(n
) = (halfword
) lua_tointeger(L
, 3);
6405 } else if (lua_key_eq(s
, stretch_order
)) {
6406 stretch_order(n
) = (quarterword
) lua_tointeger(L
, 3);
6407 } else if (lua_key_eq(s
, shrink_order
)) {
6408 shrink_order(n
) = (quarterword
) lua_tointeger(L
, 3);
6410 return nodelib_cantset(L
, n
, s
);
6413 return luaL_error(L
, "You can't assign to this %s node (%d)\n", node_data
[t
].name
, n
);
6420 static int direct_get_box_id(lua_State
* L
, int i
)
6423 int cur_cs1
, cur_cmd1
;
6426 switch (lua_type(L
, i
)) {
6428 s
= lua_tolstring(L
, i
, &k
);
6429 cur_cs1
= string_lookup(s
, k
);
6430 cur_cmd1
= eq_type(cur_cs1
);
6431 if (cur_cmd1
== char_given_cmd
||
6432 cur_cmd1
== math_given_cmd
) {
6437 j
= lua_tointeger(L
, (i
));
6440 luaL_error(L
, "argument must be a string or a number");
6441 j
= -1; /* not a valid box id */
6446 /* node.getbox = tex.getbox */
6448 /* node.direct.getbox */
6450 static int lua_nodelib_direct_getbox(lua_State
* L
)
6453 int k
= direct_get_box_id(L
, -1);
6454 direct_check_index_range(k
, "getbox");
6455 t
= get_tex_box_register(k
);
6459 lua_pushinteger(L
, t
);
6464 /* node.setbox = tex.setbox */
6467 static int lua_nodelib_direct_setbox(lua_State
* L
)
6471 int save_global_defs
;
6472 int n
= lua_gettop(L
);
6473 if (n
== 3 && (lua_type(L
, 1) == LUA_TSTRING
)) {
6474 const char *s
= lua_tostring(L
, 1);
6475 if (lua_key_eq(s
, global
))
6478 t
= lua_type(L
, -1);
6479 k
= direct_get_box_id(L
, -2);
6480 direct_check_index_range(k
, "setbox");
6481 if (t
== LUA_TBOOLEAN
) {
6482 j
= lua_toboolean(L
, -1);
6488 } else if (t
== LUA_TNIL
) {
6491 j
= nodelib_popdirect(-1);
6492 if (j
!= null
&& type(j
) != hlist_node
&& type(j
) != vlist_node
) {
6493 luaL_error(L
, "setbox: incompatible node type (%s)\n",get_node_name(type(j
), subtype(j
)));
6498 save_global_defs
= int_par(global_defs_code
);
6500 int_par(global_defs_code
) = 1;
6502 err
= set_tex_box_register(k
, j
);
6503 int_par(global_defs_code
) = save_global_defs
;
6505 luaL_error(L
, "incorrect value");
6510 /* node.is_node(n) */
6512 static int lua_nodelib_is_node(lua_State
* L
)
6514 if (maybe_isnode(L
,1) == NULL
)
6515 lua_pushboolean(L
,0);
6517 lua_pushboolean(L
,1);
6521 /* node.direct.is_direct(n) (handy for mixed usage testing) */
6523 static int lua_nodelib_direct_is_direct(lua_State
* L
)
6525 quick and dirty and faster than not node.is_node, this helper
6526 returns false or <direct>
6529 if (lua_type(L,1) == LUA_TNUMBER)
6530 lua_pushboolean(L,1);
6532 lua_pushboolean(L,0);
6534 if (lua_type(L
,1) != LUA_TNUMBER
)
6535 lua_pushboolean(L
,0);
6536 /* else return direct */
6540 /* node.direct.is_node(n) (handy for mixed usage testing) */
6542 static int lua_nodelib_direct_is_node(lua_State
* L
)
6544 quick and dirty, only checks userdata, node.is_node is slower but
6545 more exact, this helper returns false or <node>
6548 halfword *n = lua_touserdata(L, 1);
6550 lua_pushboolean(L,1);
6552 lua_pushboolean(L,0);
6555 if (maybe_isnode(L
,1) == NULL
)
6556 lua_pushboolean(L
,0);
6557 /* else assume and return node */
6562 Beware, enabling and disabling can result in an inconsistent properties table
6563 but it might make sense sometimes. Of course by default we have disabled this
6564 mechanism. And, one can always sweep the table empty.
6567 static int lua_nodelib_properties_set_mode(lua_State
* L
) /* hh */
6569 if (lua_isboolean(L
,1)) {
6570 lua_properties_enabled
= lua_toboolean(L
,1);
6572 if (lua_isboolean(L
,2)) {
6573 lua_properties_use_metatable
= lua_toboolean(L
,2);
6578 /* We used to have variants in assigned defaults but they made no sense. */
6580 static int lua_nodelib_properties_flush_table(lua_State
* L
) /* hh */
6581 { /* <node|direct> <number> */
6582 lua_get_metatablelua(node_properties
);
6583 lua_pushnil(L
); /* initializes lua_next */
6584 while (lua_next(L
,-2) != 0) {
6585 lua_pushvalue(L
,-2);
6593 /* maybe we should allocate a proper index 0..var_mem_max but not now */
6595 static int lua_nodelib_get_property(lua_State
* L
) /* hh */
6597 halfword n
= *((halfword
*) lua_touserdata(L
, 1));
6601 lua_get_metatablelua(node_properties
);
6602 lua_rawgeti(L
,-1,n
);
6607 static int lua_nodelib_direct_get_property(lua_State
* L
) /* hh */
6609 halfword n
= lua_tointeger(L
, 1);
6613 lua_get_metatablelua(node_properties
);
6614 lua_rawgeti(L
,-1,n
);
6619 static int lua_nodelib_set_property(lua_State
* L
) /* hh */
6621 /* <node> <value> */
6622 halfword n
= *((halfword
*) lua_touserdata(L
, 1));
6625 lua_get_metatablelua(node_properties
);
6626 /* <node> <value> <propertytable> */
6628 /* <propertytable> <value> */
6629 lua_rawseti(L
,-2,n
);
6634 static int lua_nodelib_direct_set_property(lua_State
* L
) /* hh */
6636 /* <direct> <value> */
6637 halfword n
= lua_tointeger(L
, 1);
6640 lua_get_metatablelua(node_properties
);
6641 /* <node> <value> <propertytable> */
6643 /* <propertytable> <value> */
6649 static int lua_nodelib_direct_properties_get_table(lua_State
* L
) /* hh */
6650 { /* <node|direct> */
6651 lua_get_metatablelua(node_properties
);
6655 static int lua_nodelib_properties_get_table(lua_State
* L
) /* hh */
6656 { /* <node|direct> */
6657 lua_get_metatablelua(node_properties_indirect
);
6663 static int lua_nodelib_get_property_t(lua_State
* L
) /* hh */
6664 { /* <table> <node> */
6665 halfword n
= *((halfword
*) lua_touserdata(L
, 2));
6674 static int lua_nodelib_set_property_t(lua_State
* L
) /* hh */
6676 /* <table> <node> <value> */
6677 halfword n
= *((halfword
*) lua_touserdata(L
, 2));
6687 static int lua_nodelib_effective_glue(lua_State
* L
)
6691 glue
= lua_touserdata(L
, 1);
6692 if ((glue
== NULL
) || (type(*glue
) != glue_node
)) {
6695 int w
= width(*glue
) ;
6696 parent
= lua_touserdata(L
, 2);
6697 if ((parent
!= NULL
) && ((type(*parent
) == hlist_node
) || (type(*parent
) == vlist_node
))) {
6698 if ((int)glue_sign(*parent
) == 1) {
6699 if (stretch_order(*glue
) == glue_order(*parent
)) {
6700 w
+= stretch(*glue
) * glue_set(*parent
);
6702 } else if (glue_sign(*parent
) == 2) {
6703 if (shrink_order(*glue
) == glue_order(*parent
)) {
6704 w
-= shrink(*glue
) * glue_set(*parent
);
6708 lua_pushinteger(L
,w
);
6714 static int lua_nodelib_direct_effective_glue(lua_State
* L
)
6716 halfword glue
= lua_tointeger(L
, 1);
6717 if ((glue
== null
) || (type(glue
) != glue_node
)) {
6720 int w
= width(glue
) ;
6721 halfword parent
= lua_tointeger(L
, 2);
6722 if ((parent
!= null
) && ((type(parent
) == hlist_node
) || (type(parent
) == vlist_node
))) {
6723 if ((int)glue_sign(parent
) == 1) {
6724 if (stretch_order(glue
) == glue_order(parent
)) {
6725 w
+= stretch(glue
) * glue_set(parent
);
6727 } else if (glue_sign(parent
) == 2) {
6728 if (shrink_order(glue
) == glue_order(parent
)) {
6729 w
-= shrink(glue
) * glue_set(parent
);
6733 lua_pushinteger(L
,w
);
6739 static const struct luaL_Reg nodelib_p
[] = {
6740 {"__index", lua_nodelib_get_property_t
},
6741 {"__newindex", lua_nodelib_set_property_t
},
6742 {NULL
, NULL
} /* sentinel */
6745 static void lua_new_properties_table(lua_State
* L
)
6747 lua_pushstring(L
,"node.properties");
6749 lua_settable(L
,LUA_REGISTRYINDEX
);
6751 lua_pushstring(L
,"node.properties.indirect");
6753 luaL_newmetatable(L
,"node.properties.indirect.meta");
6754 luaL_register(L
, NULL
, nodelib_p
);
6755 lua_setmetatable(L
,-2);
6756 lua_settable(L
,LUA_REGISTRYINDEX
);
6761 static const struct luaL_Reg direct_nodelib_f
[] = {
6762 {"copy", lua_nodelib_direct_copy
},
6763 {"copy_list", lua_nodelib_direct_copy_list
},
6764 {"count", lua_nodelib_direct_count
},
6765 {"current_attr", lua_nodelib_direct_currentattr
},
6766 {"dimensions", lua_nodelib_direct_dimensions
},
6767 {"do_ligature_n", lua_nodelib_direct_do_ligature_n
},
6768 {"end_of_math", lua_nodelib_direct_end_of_math
},
6769 /* {"family_font", lua_nodelib_mfont}, */ /* no node argument */
6770 /* {"fields", lua_nodelib_fields}, */ /* no node argument */
6771 {"first_glyph", lua_nodelib_direct_first_glyph
},
6772 {"flush_list", lua_nodelib_direct_flush_list
},
6773 {"flush_node", lua_nodelib_direct_flush_node
},
6774 {"free", lua_nodelib_direct_free
},
6775 {"getbox", lua_nodelib_direct_getbox
},
6776 {"getchar", lua_nodelib_direct_getcharacter
},
6777 {"getdisc", lua_nodelib_direct_getdiscretionary
},
6778 {"getfield", lua_nodelib_direct_getfield
},
6779 {"getfont", lua_nodelib_direct_getfont
},
6780 {"getid", lua_nodelib_direct_getid
},
6781 {"getnext", lua_nodelib_direct_getnext
},
6782 {"getprev", lua_nodelib_direct_getprev
},
6783 {"getboth", lua_nodelib_direct_getboth
},
6784 {"getlist", lua_nodelib_direct_getlist
},
6785 {"getleader", lua_nodelib_direct_getleader
},
6786 {"getsubtype", lua_nodelib_direct_getsubtype
},
6787 {"has_glyph", lua_nodelib_direct_has_glyph
},
6788 {"has_attribute", lua_nodelib_direct_has_attribute
},
6789 {"get_attribute", lua_nodelib_direct_get_attribute
},
6790 {"has_field", lua_nodelib_direct_has_field
},
6791 {"is_char", lua_nodelib_direct_is_char
},
6792 {"is_glyph", lua_nodelib_direct_is_glyph
},
6793 {"hpack", lua_nodelib_direct_hpack
},
6794 /* {"id", lua_nodelib_id}, */ /* no node argument */
6795 {"insert_after", lua_nodelib_direct_insert_after
},
6796 {"insert_before", lua_nodelib_direct_insert_before
},
6797 {"is_direct", lua_nodelib_direct_is_direct
},
6798 {"is_node", lua_nodelib_direct_is_node
},
6799 {"kerning", font_tex_direct_kerning
},
6800 {"last_node", lua_nodelib_direct_last_node
},
6801 {"length", lua_nodelib_direct_length
},
6802 {"ligaturing", font_tex_direct_ligaturing
},
6803 /* {"mlist_to_hlist", lua_nodelib_mlist_to_hset_properties_modelist}, */
6804 {"new", lua_nodelib_direct_new
},
6805 {"tostring", lua_nodelib_direct_tostring
},
6806 {"protect_glyphs", lua_nodelib_direct_protect_glyphs
},
6807 {"protect_glyph", lua_nodelib_direct_protect_glyph
},
6808 {"protrusion_skippable", lua_nodelib_direct_cp_skipable
},
6809 {"remove", lua_nodelib_direct_remove
},
6810 {"set_attribute", lua_nodelib_direct_set_attribute
},
6811 {"setbox", lua_nodelib_direct_setbox
},
6812 {"setfield", lua_nodelib_direct_setfield
},
6813 {"setchar", lua_nodelib_direct_setcharacter
},
6814 {"setdisc", lua_nodelib_direct_setdiscretionary
},
6815 {"setnext", lua_nodelib_direct_setnext
},
6816 {"setprev", lua_nodelib_direct_setprev
},
6817 {"setboth", lua_nodelib_direct_setboth
},
6818 {"setlink", lua_nodelib_direct_setlink
},
6819 {"setlist", lua_nodelib_direct_setlist
},
6820 {"setleader", lua_nodelib_direct_setleader
},
6821 {"setsubtype", lua_nodelib_direct_setsubtype
},
6822 {"slide", lua_nodelib_direct_slide
},
6823 /* {"subtype", lua_nodelib_subtype}, */ /* no node argument */
6824 {"tail", lua_nodelib_direct_tail
},
6825 {"todirect", lua_nodelib_direct_todirect
},
6826 {"tonode", lua_nodelib_direct_tonode
},
6827 {"traverse", lua_nodelib_direct_traverse
},
6828 {"traverse_id", lua_nodelib_direct_traverse_filtered
},
6829 {"traverse_char", lua_nodelib_direct_traverse_char
},
6830 /* {"type", lua_nodelib_type}, */ /* no node argument */
6831 /* {"types", lua_nodelib_types}, */ /* no node argument */
6832 {"unprotect_glyphs", lua_nodelib_direct_unprotect_glyphs
},
6833 {"unset_attribute", lua_nodelib_direct_unset_attribute
},
6834 {"setglue",lua_nodelib_direct_set_glue
},
6835 {"getglue",lua_nodelib_direct_get_glue
},
6836 {"is_zero_glue",lua_nodelib_direct_is_zero_glue
},
6837 {"usedlist", lua_nodelib_direct_usedlist
},
6838 {"vpack", lua_nodelib_direct_vpack
},
6839 /* {"whatsits", lua_nodelib_whatsits}, */ /* no node argument */
6840 {"write", lua_nodelib_direct_append
},
6841 {"set_properties_mode",lua_nodelib_properties_set_mode
},
6842 {"flush_properties_table",lua_nodelib_properties_flush_table
}, /* hh experiment */
6843 {"get_properties_table",lua_nodelib_direct_properties_get_table
}, /* hh experiment */
6844 {"getproperty", lua_nodelib_direct_get_property
},
6845 {"setproperty", lua_nodelib_direct_set_property
},
6846 {"effective_glue", lua_nodelib_direct_effective_glue
},
6848 {NULL
, NULL
} /* sentinel */
6853 static const struct luaL_Reg nodelib_f
[] = {
6854 {"copy", lua_nodelib_copy
},
6855 {"copy_list", lua_nodelib_copy_list
},
6856 {"count", lua_nodelib_count
},
6857 {"current_attr", lua_nodelib_currentattr
},
6858 {"dimensions", lua_nodelib_dimensions
},
6859 {"do_ligature_n", lua_nodelib_do_ligature_n
},
6860 {"end_of_math", lua_nodelib_end_of_math
},
6861 {"family_font", lua_nodelib_mfont
},
6862 {"fields", lua_nodelib_fields
},
6863 {"subtypes", lua_nodelib_subtypes
},
6864 {"first_glyph", lua_nodelib_first_glyph
},
6865 {"flush_list", lua_nodelib_flush_list
},
6866 {"flush_node", lua_nodelib_flush_node
},
6867 {"free", lua_nodelib_free
},
6868 /* {"getbox", lua_nodelib_getbox}, */ /* tex.getbox */
6869 {"getnext", lua_nodelib_getnext
},
6870 {"getprev", lua_nodelib_getprev
},
6871 {"getboth", lua_nodelib_getboth
},
6872 {"getdisc", lua_nodelib_getdiscretionary
},
6873 {"getlist", lua_nodelib_getlist
},
6874 {"getleader", lua_nodelib_getleader
},
6875 {"getid", lua_nodelib_getid
},
6876 {"getsubtype", lua_nodelib_getsubtype
},
6877 {"getfont", lua_nodelib_getfont
},
6878 {"getchar", lua_nodelib_getcharacter
},
6879 {"getfield", lua_nodelib_getfield
},
6880 {"setfield", lua_nodelib_setfield
},
6881 {"has_glyph", lua_nodelib_has_glyph
},
6882 {"has_attribute", lua_nodelib_has_attribute
},
6883 {"get_attribute", lua_nodelib_get_attribute
},
6884 {"has_field", lua_nodelib_has_field
},
6885 {"is_char", lua_nodelib_is_char
},
6886 {"is_glyph", lua_nodelib_is_glyph
},
6887 {"hpack", lua_nodelib_hpack
},
6888 {"id", lua_nodelib_id
},
6889 {"insert_after", lua_nodelib_insert_after
},
6890 {"insert_before", lua_nodelib_insert_before
},
6891 {"is_node", lua_nodelib_is_node
},
6892 {"kerning", font_tex_kerning
},
6893 {"last_node", lua_nodelib_last_node
},
6894 {"length", lua_nodelib_length
},
6895 {"ligaturing", font_tex_ligaturing
},
6896 {"mlist_to_hlist", lua_nodelib_mlist_to_hlist
},
6897 {"new", lua_nodelib_new
},
6898 {"next", lua_nodelib_next
}, /* getnext is somewhat more efficient, and get* fits better in direct compatibility */
6899 {"prev", lua_nodelib_prev
}, /* getprev is somewhat more efficient, and get* fits better in direct compatibility */
6900 {"tostring", lua_nodelib_tostring
},
6901 {"protect_glyphs", lua_nodelib_protect_glyphs
},
6902 {"protect_glyph", lua_nodelib_protect_glyph
},
6903 {"protrusion_skippable", lua_nodelib_cp_skipable
},
6904 {"remove", lua_nodelib_remove
},
6905 /* {"setbox", lua_nodelib_setbox}, */ /* tex.setbox */
6906 {"set_attribute", lua_nodelib_set_attribute
},
6907 {"slide", lua_nodelib_slide
},
6908 {"subtype", lua_nodelib_subtype
},
6909 {"tail", lua_nodelib_tail
},
6910 {"traverse", lua_nodelib_traverse
},
6911 {"traverse_id", lua_nodelib_traverse_filtered
},
6912 {"traverse_char", lua_nodelib_traverse_char
},
6913 {"type", lua_nodelib_type
},
6914 {"types", lua_nodelib_types
},
6915 {"unprotect_glyphs", lua_nodelib_unprotect_glyphs
},
6916 {"unset_attribute", lua_nodelib_unset_attribute
},
6917 {"setglue",lua_nodelib_set_glue
},
6918 {"getglue",lua_nodelib_get_glue
},
6919 {"is_zero_glue",lua_nodelib_is_zero_glue
},
6920 {"usedlist", lua_nodelib_usedlist
},
6921 {"vpack", lua_nodelib_vpack
},
6922 {"whatsits", lua_nodelib_whatsits
},
6923 {"write", lua_nodelib_append
},
6925 /* {"attributes_to_table",lua_nodelib_attributes_to_table}, */ /* hh experiment */
6927 {"set_properties_mode",lua_nodelib_properties_set_mode
}, /* hh experiment */
6928 {"flush_properties_table",lua_nodelib_properties_flush_table
}, /* hh experiment */
6929 {"get_properties_table",lua_nodelib_properties_get_table
}, /* bonus */ /* hh experiment */
6930 {"getproperty", lua_nodelib_get_property
}, /* hh experiment */
6931 {"setproperty", lua_nodelib_set_property
}, /* hh experiment */
6932 {"effective_glue", lua_nodelib_effective_glue
},
6934 {NULL
, NULL
} /* sentinel */
6937 static const struct luaL_Reg nodelib_m
[] = {
6938 {"__index", lua_nodelib_fast_getfield
},
6939 {"__newindex", lua_nodelib_fast_setfield
},
6940 {"__tostring", lua_nodelib_tostring
},
6941 {"__eq", lua_nodelib_equal
},
6942 {NULL
, NULL
} /* sentinel */
6945 int luaopen_node(lua_State
* L
)
6948 lua_new_properties_table(L
);
6950 /* the main metatable of node userdata */
6951 luaL_newmetatable(L
, NODE_METATABLE
);
6953 luaL_register(L
, NULL
, nodelib_m
);
6954 luaL_register(L
, "node", nodelib_f
);
6956 lua_pushstring(L
,"direct");
6958 luaL_register(L
, NULL
, direct_nodelib_f
);
6963 void nodelist_to_lua(lua_State
* L
, int n
)
6965 lua_pushinteger(L
, n
);
6966 lua_nodelib_push(L
);
6969 int nodelist_from_lua(lua_State
* L
)
6971 if (lua_isnil(L
, -1)) {
6974 halfword n
= *check_isnode(L
, -1);
6975 return (n
? n
: null
);