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 The node getter and setter are adapted a bit by Hans and Luigi so blame
25 them! On the agenda: check all keys, maybe hide some fields that are not
26 supposed to be seen and set (scratch fields for the backend and par
29 After doing lots of tests with luatex and luajittex, with and without jit,
30 and with and without ffi, we came to the conclusion that userdata prevents
31 a speedup. We also found that the checking of metatables as well as assignment
32 comes with overhead that can't be neglected. This is normally not really a
33 problem but when processing fonts for more complex scripts it's quite some
36 Because the userdata approach has some benefits, we stick to this. We did
37 some experiments with fast access (assuming nodes) and kept some of the code
38 commented here, but eventually settled for the direct approach. For code that
39 is proven to be okay, one can use the direct variants and operate on nodes
40 more directly. Currently these are numbers, but that might become light
41 userdata at one point, so *never* rely on that property. An important aspect
42 is that one cannot mix both methods, although with node.direct.tonode and
43 node.direct.todirect one can cast both representations.
45 So the advice is: use the indexed approach when possible and investigate the
46 direct one when speed might be an issue. For that reason we also provide the
47 get* and set* functions in the top level node namespace. There is a limited set
50 getnext : parsing nodelist always involves this one
51 getprev : used less but is logical companion to getnext
52 getid : consulted a lot
53 getsubtype : consulted less but also a topper
54 getfont : used a lot in otf handling (glyph nodes are consulted a lot)
55 getchar : idem and also in other places
56 getlist : we often parse nested lists so this is a convenient one too (only hlist/vlist !)
57 getleader : comparable to list, seldom used in tex (but needs consulting
59 getfield : generic getter, sufficient for the rest (other field names are
60 often shared so a specific getter makes no sense then)
62 Keep in mind that these only make sense when we're calling them millions of
63 times (which happens in font processing for instance). Setters are less important
64 as documents have not that many content related nodes (and setting many thousands
65 of properties is hardly a burden contrary to millions of consultations.)
67 Another change is that __index and __newindex are (as expected) exposed to
68 users but do no checking. The getfield and setfield functions do check. In
69 fact, fast mode can be simulated by fast_getfield = __index but the (measured)
70 benefit on average runs is not that large (some 5% when we also use the other
71 fast ones) which is easily nilled by inefficient coding. The direct variants
72 on the other hand can be significantly faster but with the drawback of lack
73 of userdata features. With respect to speed: keep in mind that measuring
74 a speedup on these functions is not representative for a normal run, where
77 maybe : setnext setprev setfont setchar (only makes sense for some scripts)
79 todo : check and optimize the direct function when possible
81 todo : once the direct ones are proven we can redefine some of the less
82 critical normal ones to call the direct ones after checking for
83 a first argument being a node (like protect/unprotect)
85 The code below has quite some duplicated code but this is also a prelude
86 to light userdata for diretc nodes so we prefer this method. Some userdata
87 variants could call the direct functions but not now (also because we don't
88 want to touch the originals too much). As usual: blame Luigi and Hans for
89 issues with this code. You can blame HH for weird or inaccurate comments.
91 Todo: as a prelude to lua 5.3 we should use integer instead of number when
92 possible. A boring job. We can use the direct variants for testing this.
94 Hans Hagen, Luigi Scarso (2011-2013)
98 static const char _svn_version
[] =
103 #include "lua/luatex-api.h"
104 #include "lua/lauxlib_bridge.h"
108 These macros create and access pointers (indices) to keys which is faster. The
109 shortcuts are created as part of the initialization.
116 When the first argument to an accessor is a node, we can use it's metatable
117 entry when we are returning nodes, which saves a lookup.
121 #define fast_metatable(n) do { \
122 a = (halfword *) lua_newuserdata(L, sizeof(halfword)); \
124 lua_getmetatable(L,1); \
125 lua_setmetatable(L,-2); \
128 #define fast_metatable_or_nil(n) do { \
130 a = (halfword *) lua_newuserdata(L, sizeof(halfword)); \
132 lua_getmetatable(L,1); \
133 lua_setmetatable(L,-2); \
139 #define fast_metatable_or_nil_alink(n) do { \
142 a = (halfword *) lua_newuserdata(L, sizeof(halfword)); \
144 lua_getmetatable(L,1); \
145 lua_setmetatable(L,-2); \
151 #define fast_metatable_top(n) do { \
152 a = (halfword *) lua_newuserdata(L, sizeof(halfword)); \
154 lua_getmetatable(L,-2); \
155 lua_setmetatable(L,-2); \
158 #define lua_push_node_metatablelua do { \
159 lua_rawgeti(L, LUA_REGISTRYINDEX, luaS_index(luatex_node)); \
160 lua_gettable(L, LUA_REGISTRYINDEX); \
165 This is a first step towards abstract direct nodes. When we have Lua 5.3 we
166 need to check all returned values for being integers. This might be another
171 #define nodelib_pushdirect(n) lua_pushnumber(L,n)
172 #define nodelib_popdirect(n) lua_tointeger(L,n)
174 #define nodelib_pushdirect_or_nil(n) do { \
178 lua_pushnumber(L,n); \
182 #define nodelib_pushdirect_or_nil_alink(n) do { \
187 lua_pushnumber(L,n); \
191 /* handy sometimes: */
193 /* static void stackDump (lua_State * L) { */
195 /* int top = lua_gettop(L); */
196 /* for (i = top; i >= 1; i--) { */
197 /* int t = lua_type(L, i); */
199 /* case LUA_TSTRING: */
200 /* printf("[%d] '%s'\n", i, lua_tostring(L, i)); */
202 /* case LUA_TBOOLEAN: */
203 /* printf("[%d] %s\n",i, lua_toboolean(L, i) ? "true" : "false"); */
205 /* case LUA_TNUMBER: */
206 /* printf("[%d] %g\n", i, lua_tonumber(L, i)); */
209 /* printf("[%d][%d] %s &d=0x%x *d=%d\n",i-top-1, i, lua_typename(L, t), lua_touserdata(L,i), *((int *)lua_touserdata(L,i))); */
216 #define nodelib_gettoks(L,a) tokenlist_from_lua(L)
218 #define nodelib_getspec nodelib_getlist
219 #define nodelib_getaction nodelib_getlist
221 /* a quick helper for dir nodes; there is only a small set of possible values */
223 #define RETURN_DIR_VALUES(a) \
224 if (s==luaS_##a##_ptr) { \
226 } else if (!absolute_only) { \
227 if (s==luaS_p##a##_ptr) \
229 else if (s==luaS_m##a##_ptr) \
230 return ((dir_##a)-64); \
233 /* fetching a field from a node .. we can often use the reuse bot-of-stack metatable */
235 #define nodelib_pushlist(L,n) { lua_pushnumber(L,n); lua_nodelib_push(L); } /* can be: fast_metatable_or_nil(n) */
236 #define nodelib_pushattr(L,n) { lua_pushnumber(L,n); lua_nodelib_push(L); } /* can be: fast_metatable_or_nil(n) */
237 #define nodelib_pushspec(L,n) { lua_pushnumber(L,n); lua_nodelib_push_spec(L); } /* can be: fast_metatable_or_nil(n) - different criterium? */
238 #define nodelib_pushaction(L,n) { lua_pushnumber(L,n); lua_nodelib_push(L); } /* can be: fast_metatable_or_nil(n) */
239 #define nodelib_pushstring(L,n) { char *ss=makecstring(n); lua_pushstring(L,ss); free(ss); }
241 /* find prev, and fix backlinks .. can be a macro instead (only used a few times) */
243 #define set_t_to_prev(head,current) \
245 while (vlink(t)!=current && t != null) { \
246 if (vlink(t)!=null) \
247 alink(vlink(t)) = t; \
251 #define get_node_type_id(L,n) do_get_node_type_id(L,n,node_data)
252 #define get_node_subtype_id(L,n) do_get_node_type_id(L,n,whatsit_node_data)
254 #define box(A) eqtb[box_base+(A)].hh.rh
255 #define direct_check_index_range(j,s) \
256 if (j<0 || j > 65535) { \
257 luaL_error(L, "incorrect index value %d for tex.%s()", (int)j, s); \
260 #define NODE_METATABLE "luatex.node"
263 #define DEBUG_OUT stdout
265 /* maybe these qualify as macros, not functions */
267 static halfword
*maybe_isnode(lua_State
* L
, int ud
)
269 halfword
*p
= lua_touserdata(L
, ud
);
271 if (lua_getmetatable(L
, ud
)) {
272 lua_rawgeti(L
, LUA_REGISTRYINDEX
, luaS_index(luatex_node
));
273 lua_gettable(L
, LUA_REGISTRYINDEX
);
274 if (!lua_rawequal(L
, -1, -2))
282 /* we could make the message a function and just inline the rest (via a macro) */
284 halfword
*check_isnode(lua_State
* L
, int ud
)
286 halfword
*p
= maybe_isnode(L
, ud
);
289 luatex_fail("There should have been a lua <node> here, not an object with type %s!", luaL_typename(L
, ud
));
295 This routine finds the numerical value of a string (or number) at
296 lua stack index |n|. If it is not a valid node type, returns -1
298 Todo: create a lua table instead at initialization time and then
299 use that hash, so that we don't need to loop for each lookup.
301 HH: can crash on noad 9
305 static int do_get_node_type_id(lua_State
* L
, int n
, node_info
* data
)
308 /* switch (lua_type(L, n)) { */
310 /* printf("LUA_TNIL\n"); */
312 /* case LUA_TNUMBER: */
313 /* printf("LUA_TNUMBER\n"); */
315 /* case LUA_TBOOLEAN: */
316 /* printf("LUA_TBOOLEAN\n"); */
318 /* case LUA_TSTRING: */
319 /* printf("LUA_TSTRING\n"); */
321 /* case LUA_TTABLE: */
322 /* printf("LUA_TTABLE\n"); */
324 /* case LUA_TFUNCTION: */
325 /* printf("LUA_TFUNCTION\n"); */
327 /* case LUA_TUSERDATA: */
328 /* printf("LUA_TUSERDATA\n"); */
330 /* case LUA_TTHREAD: */
331 /* printf("LUA_TTHREAD\n"); */
333 /* case LUA_TLIGHTUSERDATA: */
334 /* printf("LUA_TLIGHTUSERDATA\n"); */
337 if (lua_type(L
, n
) == LUA_TSTRING
) {
338 const char *s
= lua_tostring(L
, n
);
339 for (j
= 0; data
[j
].id
!= -1; j
++) {
340 if (strcmp(s
, data
[j
].name
) == 0)
343 } else if (lua_type(L
, n
) == LUA_TNUMBER
) {
344 int i
= (int) lua_tointeger(L
, n
);
345 for (j
= 0; data
[j
].id
!= -1; j
++) {
353 static int get_valid_node_type_id(lua_State
* L
, int n
)
355 int i
= get_node_type_id(L
, n
);
357 if (lua_type(L
, n
) == LUA_TSTRING
) {
358 luaL_error(L
, "Invalid node type id: %s", lua_tostring(L
, n
));
360 luaL_error(L
, "Invalid node type id: %d", lua_tonumber(L
, n
));
366 static int get_valid_node_subtype_id(lua_State
* L
, int n
)
368 int i
= get_node_subtype_id(L
, n
);
370 if (lua_type(L
, n
) == LUA_TSTRING
) {
371 luaL_error(L
, "Invalid whatsit node id: %s", lua_tostring(L
, n
));
373 luaL_error(L
, "Invalid whatsit node id: %d", lua_tonumber(L
, n
));
379 /* two simple helpers to speed up and simplify lua code (replaced by getnext and getprev) */
381 static int lua_nodelib_next(lua_State
* L
)
383 halfword
*p
= maybe_isnode(L
,1);
384 if (p
!= NULL
&& *p
&& vlink(*p
)) {
385 lua_nodelib_push_fast(L
,vlink(*p
));
392 static int lua_nodelib_prev(lua_State
* L
)
394 halfword
*p
= maybe_isnode(L
,1);
395 if (p
!= NULL
&& *p
&& alink(*p
)) {
396 lua_nodelib_push_fast(L
,alink(*p
));
405 static void lua_nodelib_push_simple(lua_State * L, halfword p)
408 a = (halfword *) lua_newuserdata(L, sizeof(halfword));
410 lua_rawgeti(L, LUA_REGISTRYINDEX, luaS_index(luatex_node));
411 lua_gettable(L, LUA_REGISTRYINDEX);
412 lua_setmetatable(L, -2);
419 Creates a userdata object for a number found at the stack top, if it is
420 representing a node (i.e. an pointer into |varmem|). It replaces the
421 stack entry with the new userdata, or pushes |nil| if the number is |null|,
422 or if the index is definately out of range. This test could be improved.
426 void lua_nodelib_push(lua_State
* L
)
431 if (lua_isnumber(L
, -1))
432 n
= (int) lua_tointeger(L
, -1);
434 if ((n
== null
) || (n
< 0) || (n
> var_mem_max
)) {
437 a
= lua_newuserdata(L
, sizeof(halfword
));
439 lua_rawgeti(L
, LUA_REGISTRYINDEX
, luaS_index(luatex_node
));
440 lua_gettable(L
, LUA_REGISTRYINDEX
);
441 lua_setmetatable(L
, -2);
446 /* |spec_ptr| fields can legally be zero, which is why there is a special function. */
448 static void lua_nodelib_push_spec(lua_State
* L
)
453 if (lua_isnumber(L
, -1))
454 n
= (halfword
) lua_tointeger(L
, -1);
456 if ((n
< 0) || (n
> var_mem_max
)) {
459 a
= lua_newuserdata(L
, sizeof(halfword
));
461 lua_rawgeti(L
, LUA_REGISTRYINDEX
, luaS_index(luatex_node
));
462 lua_gettable(L
, LUA_REGISTRYINDEX
);
463 lua_setmetatable(L
, -2);
468 void lua_nodelib_push_fast(lua_State
* L
, halfword n
)
471 a
= lua_newuserdata(L
, sizeof(halfword
));
473 lua_rawgeti(L
, LUA_REGISTRYINDEX
, luaS_index(luatex_node
));
474 lua_gettable(L
, LUA_REGISTRYINDEX
);
475 lua_setmetatable(L
, -2);
479 /* converts type strings to type ids */
481 static int lua_nodelib_id(lua_State
* L
)
483 int i
= get_node_type_id(L
, 1);
485 lua_pushnumber(L
, i
);
494 static int lua_nodelib_getid(lua_State
* L
)
496 /* [given-node] [...] */
497 halfword
*p
= lua_touserdata(L
, 1);
498 if ( (p
== NULL
) || (! lua_getmetatable(L
,1)) ) {
502 /* [given-node] [mt-given-node] */
503 lua_rawgeti(L
, LUA_REGISTRYINDEX
, luaS_index(luatex_node
));
504 lua_gettable(L
, LUA_REGISTRYINDEX
);
505 /* [given-node] [mt-given-node] [mt-node] */
506 if (!lua_rawequal(L
, -1, -2)) {
509 lua_pushnumber(L
, type(*p
));
516 static int lua_nodelib_fast_getid(lua_State * L)
519 n = (halfword *) lua_touserdata(L, 1);
520 lua_pushnumber(L, type(*n));
526 /* node.direct.getid */
528 static int lua_nodelib_direct_getid(lua_State
* L
)
531 n
= (halfword
) lua_tonumber(L
, 1);
535 lua_pushnumber(L
, type(n
));
540 /* node.getsubtype */
542 static int lua_nodelib_getsubtype(lua_State
* L
)
544 halfword
*p
= lua_touserdata(L
, 1);
545 if ( (p
== NULL
) || (! lua_getmetatable(L
,1)) ) {
548 lua_push_node_metatablelua
;
549 if ( (!lua_rawequal(L
, -1, -2)) || (! nodetype_has_subtype(*p
))) {
552 lua_pushnumber(L
, subtype(*p
));
558 /* node.fast.getsubtype
560 static int lua_nodelib_fast_getsubtype(lua_State * L)
563 n = (halfword *) lua_touserdata(L, 1);
564 lua_pushnumber(L, subtype(*n));
570 /* node.direct.getsubtype */
572 static int lua_nodelib_direct_getsubtype(lua_State
* L
)
575 n
= (halfword
) lua_tonumber(L
, 1);
576 if (n
== null
) { /* no check, we assume sane use */
579 lua_pushnumber(L
, subtype(n
));
586 static int lua_nodelib_getfont(lua_State
* L
)
588 halfword
*p
= lua_touserdata(L
, 1);
589 if ( (p
== NULL
) || (! lua_getmetatable(L
,1)) ) {
592 lua_push_node_metatablelua
;
593 if ( (!lua_rawequal(L
, -1, -2)) || (type(*p
) != glyph_node
) ) {
596 lua_pushnumber(L
, font(*p
));
604 static int lua_nodelib_fast_getfont(lua_State * L)
607 n = (halfword *) lua_touserdata(L, 1);
608 if (type(*n) != glyph_node) {
611 lua_pushnumber(L, font(*n));
618 /* node.direct.getfont */
620 static int lua_nodelib_direct_getfont(lua_State
* L
)
623 n
= (halfword
) lua_tonumber(L
, 1);
624 if ((n
== null
) || (type(n
) != glyph_node
)) {
627 lua_pushnumber(L
, font(n
));
634 static int lua_nodelib_getcharacter(lua_State
* L
)
636 halfword
*n
= lua_touserdata(L
, 1);
637 if ( (n
== NULL
) || (! lua_getmetatable(L
,1)) ) {
639 } else if (type(*n
) == glyph_node
) {
640 lua_pushnumber(L
, character(*n
));
641 } else if ((type(*n
) == math_char_node
) || (type(*n
) == math_text_char_node
)) {
642 lua_pushnumber(L
, math_character(*n
));
649 static int lua_nodelib_fast_getcharacter(lua_State * L)
652 n = (halfword *) lua_touserdata(L, 1);
653 if (type(*n) == glyph_node) {
654 lua_pushnumber(L, character(*n));
655 } else if ((type(*n) == math_char_node) || (type(*n) == math_text_char_node)) {
656 lua_pushnumber(L, math_character(*n));
665 /* node.direct.getchar */
667 static int lua_nodelib_direct_getcharacter(lua_State
* L
)
670 n
= (halfword
) lua_tonumber(L
, 1);
673 } else if (type(n
) == glyph_node
) {
674 lua_pushnumber(L
, character(n
));
675 } else if ((type(n
) == math_char_node
) || (type(n
) == math_text_char_node
)) {
676 lua_pushnumber(L
, math_character(n
));
685 static int lua_nodelib_getlist(lua_State
* L
)
688 halfword
*n
= lua_touserdata(L
, 1);
689 if ( (n
== NULL
) || (! lua_getmetatable(L
,1)) ) {
691 } else if ((type(*n
) == hlist_node
) || (type(*n
) == vlist_node
)) {
692 fast_metatable_or_nil_alink(list_ptr(*n
));
699 /* node.direct.getlist */
701 static int lua_nodelib_direct_getlist(lua_State
* L
)
704 n
= (halfword
) lua_tonumber(L
, 1);
707 } else if ((type(n
) == hlist_node
) || (type(n
) == vlist_node
)) {
708 nodelib_pushdirect_or_nil_alink(list_ptr(n
));
717 static int lua_nodelib_getleader(lua_State
* L
)
720 halfword
*n
= lua_touserdata(L
, 1);
721 if ( (n
== NULL
) || (! lua_getmetatable(L
,1)) ) {
723 } else if (type(*n
) == glue_node
) {
724 fast_metatable_or_nil(leader_ptr(*n
));
731 /* node.direct.getleader */
733 static int lua_nodelib_direct_getleader(lua_State
* L
)
736 n
= (halfword
) lua_tonumber(L
, 1);
739 } else if (type(n
) == glue_node
) {
740 nodelib_pushdirect_or_nil(leader_ptr(n
));
749 static int lua_nodelib_getnext(lua_State
* L
)
752 /* [given-node] [...]*/
753 halfword
*p
= lua_touserdata(L
, 1);
754 if ( (p
== NULL
) || (! lua_getmetatable(L
,1)) ) {
757 /* [given-node] [mt-given-node]*/
758 lua_rawgeti(L
, LUA_REGISTRYINDEX
, luaS_index(luatex_node
));
759 lua_gettable(L
, LUA_REGISTRYINDEX
);
760 /* [given-node] [mt-given-node] [mt-node]*/
761 if (!lua_rawequal(L
, -1, -2)) {
764 fast_metatable_or_nil(vlink(*p
));
767 return 1; /* just one*/
772 static int lua_nodelib_fast_getnext(lua_State * L)
775 // [given-node] [...]
776 halfword *p = lua_touserdata(L, 1);
777 if ((p == NULL) || (!vlink(*p))){
782 lua_getmetatable(L,1);
783 // [given-node] [mt-node]
784 a = lua_newuserdata(L, sizeof(halfword));
785 // [given-node] [mt-node] [next-node]
788 // [next-node] [mt-node]
789 lua_setmetatable(L,1);
790 // [next-node-with-mt]
797 /* node.direct.getnext */
799 static int lua_nodelib_direct_getnext(lua_State
* L
)
802 p
= (halfword
) lua_tonumber(L
, 1);
806 nodelib_pushdirect_or_nil(vlink(p
));
813 static int lua_nodelib_getprev(lua_State
* L
)
816 halfword
*p
= lua_touserdata(L
, 1);
817 if ( (p
== NULL
) || (! lua_getmetatable(L
,1)) ) {
820 lua_rawgeti(L
, LUA_REGISTRYINDEX
, luaS_index(luatex_node
));
821 lua_gettable(L
, LUA_REGISTRYINDEX
);
822 if (!lua_rawequal(L
, -1, -2)) {
825 fast_metatable_or_nil(alink(*p
));
834 static int lua_nodelib_fast_getprev(lua_State * L)
837 // [given-node] [...]
838 halfword *p = lua_touserdata(L, 1);
839 if ((p == NULL) || (!alink(*p))) {
844 lua_getmetatable(L,1);
845 // [given-node] [mt-node]
846 a = lua_newuserdata(L, sizeof(halfword));
847 // [given-node] [mt-node] [next-node]
850 // [next-node] [mt-node]
851 lua_setmetatable(L,1);
852 // [next-node-with-mt]
859 /* node.direct.getprev */
861 static int lua_nodelib_direct_getprev(lua_State
* L
)
864 p
= (halfword
) lua_tonumber(L
, 1);
868 nodelib_pushdirect_or_nil(alink(p
));
875 static int lua_nodelib_subtype(lua_State
* L
)
877 int i
= get_node_subtype_id(L
, 1);
879 lua_pushnumber(L
, i
);
881 lua_pushnil(L
); /* return 0; */
886 /* node.type (converts id numbers to type names) */
888 static int lua_nodelib_type(lua_State
* L
)
890 if (lua_type(L
,1) == LUA_TNUMBER
) {
891 int i
= get_node_type_id(L
, 1);
893 lua_pushstring(L
, node_data
[i
].name
);
896 } else if (maybe_isnode(L
, 1) != NULL
) {
897 lua_pushstring(L
,"node");
904 /* node.new (allocate a new node) */
906 static int lua_nodelib_new(lua_State
* L
)
910 i
= get_valid_node_type_id(L
, 1);
911 if (i
== whatsit_node
) {
913 if (lua_gettop(L
) > 1)
914 j
= get_valid_node_subtype_id(L
, 2);
916 luaL_error(L
, "Creating a whatsit requires the subtype number as a second argument");
919 if (lua_gettop(L
) > 1)
920 j
= (int) lua_tointeger(L
, 2);
923 lua_nodelib_push_fast(L
, n
);
927 /* node.direct.new (still with checking) */
929 static int lua_nodelib_direct_new(lua_State
* L
)
933 i
= get_valid_node_type_id(L
, 1);
934 if (i
== whatsit_node
) {
936 if (lua_gettop(L
) > 1)
937 j
= get_valid_node_subtype_id(L
, 2);
939 luaL_error(L
, "Creating a whatsit requires the subtype number as a second argument");
942 if (lua_gettop(L
) > 1)
943 j
= (int) lua_tointeger(L
, 2);
950 /* node.free (this function returns the 'next' node, because that may be helpful) */
952 static int lua_nodelib_free(lua_State
* L
)
956 if (lua_gettop(L
) < 1) {
959 } else if (lua_isnil(L
, 1)) {
960 return 1; /* the nil itself */
962 n
= check_isnode(L
, 1);
965 /* can be: lua_nodelib_push_fast(L, p); */
966 lua_pushnumber(L
, p
);
971 /* node.direct.free */
973 static int lua_nodelib_direct_free(lua_State
* L
)
977 n
= (halfword
) lua_tonumber(L
,1);
992 /* node.flush_node (no next returned) */
994 static int lua_nodelib_flush_node(lua_State
* L
)
997 if ((lua_gettop(L
) < 1) || lua_isnil(L
, 1))
999 n
= check_isnode(L
, 1);
1005 /* node.direct.flush_node */
1007 static int lua_nodelib_direct_flush_node(lua_State
* L
)
1010 n
= (halfword
) lua_tonumber(L
,1);
1017 /* node.flush_list */
1019 static int lua_nodelib_flush_list(lua_State
* L
)
1022 if ((lua_gettop(L
) < 1) || lua_isnil(L
, 1))
1024 n_ptr
= check_isnode(L
, 1);
1025 flush_node_list(*n_ptr
);
1029 /* node.direct.flush_list */
1031 static int lua_nodelib_direct_flush_list(lua_State
* L
)
1034 n
= (halfword
) lua_tonumber(L
,1);
1041 /* remove a node from a list */
1045 static void show_node_links (halfword l
, const char * p
)
1049 fprintf(DEBUG_OUT
, "%s t = %d, prev = %d, next = %d\n", p
, (int)t
, (int)alink(t
), (int)vlink(t
));
1058 static int lua_nodelib_remove(lua_State
* L
)
1060 halfword head
, current
, t
;
1061 if (lua_gettop(L
) < 2)
1062 luaL_error(L
, "Not enough arguments for node.remove()");
1063 head
= *(check_isnode(L
, 1));
1065 show_node_links(head
, "before");
1067 if (lua_isnil(L
, 2))
1068 return 2; /* the arguments, as they are */
1069 current
= *(check_isnode(L
, 2));
1070 if (head
== current
) {
1071 if (alink(current
)){
1072 vlink(alink(current
)) = vlink(current
); // vlink(prev) = next
1074 if (vlink(current
)){
1075 alink( vlink(current
)) = alink(current
); // alink(next) = prev
1078 head
= vlink(current
); //head = next
1079 current
= vlink(current
); //current = next
1080 } else { /* head != current */
1082 if (t
== null
|| vlink(t
) != current
) {
1083 set_t_to_prev(head
, current
);
1084 if (t
== null
) /* error! */
1085 luaL_error(L
,"Attempt to node.remove() a non-existing node");
1087 /* t is now the previous node */
1088 vlink(t
) = vlink(current
);
1089 if (vlink(current
) != null
)
1090 alink(vlink(current
)) = t
;
1091 current
= vlink(current
);
1094 show_node_links(head
, "after");
1096 /* can be: lua_nodelib_push_fast(L, head); */
1097 lua_pushnumber(L
, head
);
1098 lua_nodelib_push(L
);
1099 /* can be: lua_nodelib_push_fast(L, current); */
1100 lua_pushnumber(L
, current
);
1101 lua_nodelib_push(L
);
1105 /* node.direct.remove */
1107 static int lua_nodelib_direct_remove(lua_State
* L
)
1109 halfword head
, current
, t
;
1110 head
= (halfword
) lua_tonumber(L
,1);
1116 current
= (halfword
) lua_tonumber(L
,2);
1117 if (current
== null
) {
1118 lua_pushnumber(L
, head
);
1122 if (head
== current
) {
1123 if (alink(current
)){
1124 vlink( alink(current
) ) = vlink(current
); // vlink(prev) = next
1126 if (vlink(current
)){
1127 alink( vlink(current
) ) = alink(current
); // alink(next) = prev
1129 head
= vlink(current
); //head = next
1130 current
= vlink(current
); //current = next
1133 if (t
== null
|| vlink(t
) != current
) {
1134 set_t_to_prev(head
, current
);
1136 luaL_error(L
,"Attempt to node.direct.remove() a non-existing node");
1139 vlink(t
) = vlink(current
);
1140 if (vlink(current
) != null
)
1141 alink(vlink(current
)) = t
;
1142 current
= vlink(current
);
1147 lua_pushnumber(L
, head
);
1149 if (current
== null
) {
1152 lua_pushnumber(L
, current
);
1157 /* node.insert_before (insert a node in a list) */
1159 static int lua_nodelib_insert_before(lua_State
* L
)
1161 halfword head
, current
, n
, t
;
1162 if (lua_gettop(L
) < 3) {
1163 luaL_error(L
, "Not enough arguments for node.insert_before()");
1165 if (lua_isnil(L
, 3)) {
1169 n
= *(check_isnode(L
, 3));
1171 if (lua_isnil(L
, 1)) { /* no head */
1174 lua_nodelib_push_fast(L
, n
);
1175 lua_pushvalue(L
, -1);
1178 head
= *(check_isnode(L
, 1));
1180 if (lua_isnil(L
, 2)) {
1181 current
= tail_of_list(head
);
1183 current
= *(check_isnode(L
, 2));
1185 if (head
!= current
) {
1187 if (t
== null
|| vlink(t
) != current
) {
1188 set_t_to_prev(head
, current
);
1189 if (t
== null
) { /* error! */
1190 luaL_error(L
, "Attempt to node.insert_before() a non-existing node");
1195 couple_nodes(n
, current
);
1196 if (head
== current
) {
1197 lua_nodelib_push_fast(L
, n
);
1199 lua_nodelib_push_fast(L
, head
);
1201 lua_nodelib_push_fast(L
, n
);
1205 /* node.direct.insert_before */
1207 static int lua_nodelib_direct_insert_before(lua_State
* L
)
1209 halfword head
, current
, n
, t
;
1210 n
= (halfword
) lua_tonumber(L
,3);
1216 head
= (halfword
) lua_tonumber(L
,1);
1217 current
= (halfword
) lua_tonumber(L
,2);
1218 /* no head, ignore current */
1222 lua_pushnumber(L
, n
);
1223 lua_pushvalue(L
, -1);
1228 if (current
== null
)
1229 current
= tail_of_list(head
);
1230 if (head
!= current
) {
1232 if (t
== null
|| vlink(t
) != current
)
1233 set_t_to_prev(head
, current
);
1236 couple_nodes(n
, current
);
1237 if (head
== current
) {
1238 lua_pushnumber(L
, n
);
1240 lua_pushnumber(L
, head
);
1242 lua_pushnumber(L
, n
);
1246 /* node.insert_after */
1248 static int lua_nodelib_insert_after(lua_State
* L
)
1250 halfword head
, current
, n
;
1251 if (lua_gettop(L
) < 3) {
1252 luaL_error(L
, "Not enough arguments for node.insert_after()");
1254 if (lua_isnil(L
, 3)) {
1258 n
= *(check_isnode(L
, 3));
1260 if (lua_isnil(L
, 1)) { /* no head */
1263 lua_nodelib_push_fast(L
, n
);
1264 lua_pushvalue(L
, -1);
1267 head
= *(check_isnode(L
, 1));
1269 if (lua_isnil(L
, 2)) {
1271 while (vlink(current
) != null
)
1272 current
= vlink(current
);
1274 current
= *(check_isnode(L
, 2));
1276 try_couple_nodes(n
, vlink(current
));
1277 couple_nodes(current
, n
);
1280 lua_nodelib_push_fast(L
, n
);
1284 /* node.direct.insert_after */
1286 static int lua_nodelib_direct_insert_after(lua_State
* L
)
1288 halfword head
, current
, n
;
1289 /*[head][current][new]*/
1290 n
= (halfword
) lua_tonumber(L
,3);
1295 head
= (halfword
) lua_tonumber(L
,1);
1296 current
= (halfword
) lua_tonumber(L
,2);
1298 /* no head, ignore current */
1301 lua_pushnumber(L
,n
);
1302 lua_pushvalue(L
, -1);
1306 if (current
== null
) {
1309 while (vlink(current
) != null
)
1310 current
= vlink(current
);
1312 try_couple_nodes(n
, vlink(current
));
1313 couple_nodes(current
, n
);
1315 lua_pushnumber(L
, n
);
1319 /* node.copy_list */
1320 /* hh-ls: we need to use an intermediate variable as otherwise target is used in the loop
1321 and subfields get overwritten (or something like that) which results in crashes and
1322 unexpected side effects */
1323 static int lua_nodelib_copy_list(lua_State
* L
)
1325 halfword n
, s
= null
;
1327 if (lua_isnil(L
, 1))
1328 return 1; /* the nil itself */
1329 n
= *check_isnode(L
, 1);
1330 if ((lua_gettop(L
) > 1) && (!lua_isnil(L
,2)))
1331 s
= *check_isnode(L
, 2);
1332 m
= do_copy_node_list(n
, s
);
1333 // lua_pushnumber(L, m);
1334 // lua_nodelib_push(L);
1335 lua_nodelib_push_fast(L
,m
);
1341 /* node.direct.copy_list */
1343 static int lua_nodelib_direct_copy_list(lua_State
* L
)
1346 n
= (halfword
) lua_tonumber(L
,1);
1350 s
= (halfword
) lua_tonumber(L
,2);
1352 m
= do_copy_node_list(n
,null
);
1354 m
= do_copy_node_list(n
,s
);
1356 lua_pushnumber(L
,m
);
1361 /* node.copy (deep copy) */
1363 static int lua_nodelib_copy(lua_State
* L
)
1367 if (lua_isnil(L
, 1))
1368 return 1; /* the nil itself */
1369 n
= check_isnode(L
, 1);
1371 lua_nodelib_push_fast(L
, m
);
1375 /* node.direct.copy (deep copy) */
1377 static int lua_nodelib_direct_copy(lua_State
* L
)
1381 if (lua_isnil(L
, 1))
1382 return 1; /* the nil itself */
1383 /* beware, a glue node can have number 0 (zeropt) so we cannot test for null) */
1384 n
= (halfword
) lua_tonumber(L
, 1);
1386 lua_pushnumber(L
, m
);
1391 /* node.write (output a node to tex's processor) */
1393 static int lua_nodelib_append(lua_State
* L
)
1399 for (i
= 1; i
<= j
; i
++) {
1400 n
= check_isnode(L
, i
);
1403 while (vlink(m
) != null
) {
1411 /* node.direct.write */
1413 static int lua_nodelib_direct_append(lua_State
* L
)
1419 for (i
= 1; i
<= j
; i
++) {
1420 n
= (halfword
) lua_tonumber(L
,i
); /*lua_getnumber(L, i);*/
1424 while (vlink(m
) != null
) {
1435 static int lua_nodelib_last_node(lua_State
* L
)
1439 /* can be: lua_nodelib_push_fast(L, m); */
1440 lua_pushnumber(L
, m
);
1441 lua_nodelib_push(L
);
1445 /* node.direct.last */
1447 static int lua_nodelib_direct_last_node(lua_State
* L
)
1451 lua_pushnumber(L
, m
);
1455 /* node.hpack (build a hbox) */
1457 static int lua_nodelib_hpack(lua_State
* L
)
1464 n
= *(check_isnode(L
, 1));
1465 if (lua_gettop(L
) > 1) {
1466 w
= (int) lua_tointeger(L
, 2);
1467 if (lua_gettop(L
) > 2) {
1468 if (lua_type(L
, 3) == LUA_TSTRING
) {
1469 s
= lua_tostring(L
, 3);
1470 if (lua_key_eq(s
, exactly
)) {
1472 } else if (lua_key_eq(s
, additional
)) {
1474 } else if (lua_key_eq(s
, cal_expand_ratio
)) {
1476 } else if (lua_key_eq(s
, subst_ex_font
)) {
1479 luaL_error(L
, "3rd argument should be either additional or exactly");
1481 } else if (lua_type(L
, 3) == LUA_TNUMBER
) {
1482 m
=(int)lua_tonumber(L
, 3);
1484 lua_pushstring(L
, "incorrect 3rd argument");
1486 if (lua_gettop(L
) > 3) {
1487 if (lua_type(L
, 4) == LUA_TSTRING
) {
1488 d
= nodelib_getdir(L
, 4, 1);
1490 lua_pushstring(L
, "incorrect 4th argument");
1495 p
= hpack(n
, w
, m
, d
);
1496 lua_nodelib_push_fast(L
, p
);
1497 lua_pushnumber(L
, last_badness
);
1501 /* node.direct.hpack */
1503 static int lua_nodelib_direct_hpack(lua_State
* L
)
1510 n
= (halfword
) lua_tonumber(L
,1);
1511 /* could be macro */
1512 if (lua_gettop(L
) > 1) {
1513 w
= (int) lua_tointeger(L
, 2);
1514 if (lua_gettop(L
) > 2) {
1515 if (lua_type(L
, 3) == LUA_TSTRING
) {
1516 s
= lua_tostring(L
, 3);
1517 if (lua_key_eq(s
, additional
)) {
1519 } else if (lua_key_eq(s
, exactly
)) {
1521 } else if (lua_key_eq(s
, cal_expand_ratio
)) {
1523 } else if (lua_key_eq(s
, subst_ex_font
)) {
1526 luaL_error(L
, "3rd argument should be either additional or exactly");
1528 } else if (lua_type(L
, 3) == LUA_TNUMBER
) {
1529 m
=(int)lua_tonumber(L
, 3);
1531 lua_pushstring(L
, "incorrect 3rd argument");
1533 if (lua_gettop(L
) > 3) {
1534 if (lua_type(L
, 4) == LUA_TSTRING
) {
1535 d
= nodelib_getdir(L
, 4, 1);
1537 lua_pushstring(L
, "incorrect 4th argument");
1543 p
= hpack(n
, w
, m
, d
);
1544 lua_pushnumber(L
, p
);
1545 lua_pushnumber(L
, last_badness
);
1549 /* node.vpack (build a vbox) */
1551 static int lua_nodelib_vpack(lua_State
* L
)
1558 n
= *(check_isnode(L
, 1));
1559 if (lua_gettop(L
) > 1) {
1560 w
= (int) lua_tointeger(L
, 2);
1561 if (lua_gettop(L
) > 2) {
1562 if (lua_type(L
, 3) == LUA_TSTRING
) {
1563 s
= lua_tostring(L
, 3);
1564 if (lua_key_eq(s
, additional
)) {
1566 } else if (lua_key_eq(s
, exactly
)) {
1569 luaL_error(L
, "3rd argument should be either additional or exactly");
1572 if (lua_gettop(L
) > 3) {
1573 if (lua_type(L
, 4) == LUA_TSTRING
) {
1574 d
= nodelib_getdir(L
, 4, 1);
1576 lua_pushstring(L
, "incorrect 4th argument");
1581 else if (lua_type(L
, 3) == LUA_TNUMBER
) {
1582 m
=(int)lua_tonumber(L
, 3);
1584 lua_pushstring(L
, "incorrect 3rd argument");
1588 p
= vpackage(n
, w
, m
, max_dimen
, d
);
1589 lua_nodelib_push_fast(L
, p
);
1590 lua_pushnumber(L
, last_badness
);
1594 /* node.direct.vpack */
1596 static int lua_nodelib_direct_vpack(lua_State
* L
)
1603 n
= (halfword
) lua_tonumber(L
,1);
1604 if (lua_gettop(L
) > 1) {
1605 w
= (int) lua_tointeger(L
, 2);
1606 if (lua_gettop(L
) > 2) {
1607 if (lua_type(L
, 3) == LUA_TSTRING
) {
1608 s
= lua_tostring(L
, 3);
1609 if (lua_key_eq(s
, additional
)) {
1611 } else if (lua_key_eq(s
, exactly
)) {
1614 luaL_error(L
, "3rd argument should be either additional or exactly");
1617 if (lua_gettop(L
) > 3) {
1618 if (lua_type(L
, 4) == LUA_TSTRING
) {
1619 d
= nodelib_getdir(L
, 4, 1);
1621 lua_pushstring(L
, "incorrect 4th argument");
1626 else if (lua_type(L
, 3) == LUA_TNUMBER
) {
1627 m
=(int)lua_tonumber(L
, 3);
1629 lua_pushstring(L
, "incorrect 3rd argument");
1633 p
= vpackage(n
, w
, m
, max_dimen
, d
);
1634 lua_pushnumber(L
, p
);
1635 lua_pushnumber(L
, last_badness
);
1639 /* node.dimensions (of a hlist or vlist) */
1641 static int lua_nodelib_dimensions(lua_State
* L
)
1644 top
= lua_gettop(L
);
1647 glue_ratio g_mult
= 1.0;
1648 int g_sign
= normal
;
1649 int g_order
= normal
;
1652 halfword n
= null
, p
= null
;
1653 /* maybe be more restrictive: LUA_TNUMBER i.e. it's not good to mix numbers and strings with digits */
1654 if (lua_isnumber(L
, 1)) {
1660 g_mult
= (glue_ratio
) lua_tonumber(L
, 1);
1661 g_sign
=(int)lua_tonumber(L
, 2);
1662 g_order
=(int)lua_tonumber(L
, 3);
1664 n
= *(check_isnode(L
, i
));
1665 if (lua_gettop(L
) > i
&& !lua_isnil(L
, (i
+ 1))) {
1666 if (lua_type(L
, (i
+ 1)) == LUA_TSTRING
) {
1667 d
= nodelib_getdir(L
, (i
+ 1), 1);
1669 p
= *(check_isnode(L
, (i
+ 1)));
1672 if (lua_gettop(L
) > (i
+ 1) && lua_type(L
, (i
+ 2)) == LUA_TSTRING
) {
1673 d
= nodelib_getdir(L
, (i
+ 2), 1);
1675 siz
= natural_sizes(n
, p
, g_mult
, g_sign
, g_order
, d
);
1676 lua_pushnumber(L
, siz
.wd
);
1677 lua_pushnumber(L
, siz
.ht
);
1678 lua_pushnumber(L
, siz
.dp
);
1681 luaL_error(L
, "missing argument to 'dimensions' (node expected)");
1683 return 0; /* not reached */
1686 /* node.direct.dimensions*/
1688 static int lua_nodelib_direct_dimensions(lua_State
* L
)
1691 top
= lua_gettop(L
);
1694 glue_ratio g_mult
= 1.0;
1695 int g_sign
= normal
;
1696 int g_order
= normal
;
1699 halfword n
= null
, p
= null
;
1702 g_mult
= (glue_ratio
) lua_tonumber(L
, 1);
1703 g_sign
=(int)lua_tonumber(L
, 2);
1704 g_order
=(int)lua_tonumber(L
, 3);
1706 n
= (halfword
) lua_tonumber(L
,i
);
1707 if (lua_gettop(L
) > i
&& !lua_isnil(L
, (i
+ 1))) {
1708 if (lua_type(L
, (i
+ 1)) == LUA_TSTRING
) {
1709 d
= nodelib_getdir(L
, (i
+ 1), 1);
1711 p
= (halfword
) lua_tonumber(L
,i
+1);
1714 if (lua_gettop(L
) > (i
+ 1) && lua_type(L
, (i
+ 2)) == LUA_TSTRING
)
1715 d
= nodelib_getdir(L
, (i
+ 2), 1);
1716 siz
= natural_sizes(n
, p
, g_mult
, g_sign
, g_order
, d
);
1717 lua_pushnumber(L
, siz
.wd
);
1718 lua_pushnumber(L
, siz
.ht
);
1719 lua_pushnumber(L
, siz
.dp
);
1722 luaL_error(L
, "missing argument to 'dimensions' (node expected)");
1724 return 0; /* not reached */
1727 /* node.mlist_to_hlist (create a hlist from a formula) */
1729 static int lua_nodelib_mlist_to_hlist(lua_State
* L
)
1734 n
= *(check_isnode(L
, 1));
1735 //w = luaL_checkoption(L, 2, "text", math_style_names);
1736 assign_math_style(L
,2,w
);
1737 luaL_checkany(L
, 3);
1738 m
= lua_toboolean(L
, 3);
1739 mlist_to_hlist_args(n
, w
, m
);
1740 alink(vlink(temp_head
)) = null
; /*hh-ls */
1741 lua_nodelib_push_fast(L
, vlink(temp_head
));
1745 /* node.family_font */
1747 static int lua_nodelib_mfont(lua_State
* L
)
1750 f
= (int) luaL_checkinteger(L
, 1);
1751 if (lua_gettop(L
) == 2)
1752 s
= (int) lua_tointeger(L
, 2); /* this should be a multiple of 256 ! */
1755 lua_pushnumber(L
, fam_fnt(f
, s
));
1760 This function is similar to |get_node_type_id|, for field
1761 identifiers. It has to do some more work, because not all
1762 identifiers are valid for all types of nodes.
1764 If really needed we can optimize this one using a big if ..
1765 .. else like with the getter and setter.
1769 static int get_node_field_id(lua_State
* L
, int n
, int node
)
1772 const char *s
= lua_tostring(L
, n
);
1777 if (lua_key_eq(s
, next
)) {
1779 } else if (lua_key_eq(s
, id
)) {
1781 } else if (lua_key_eq(s
, subtype
)) {
1782 if (nodetype_has_subtype(t
)) {
1785 } else if (lua_key_eq(s
, attr
)) {
1786 if (nodetype_has_attributes(t
)) {
1789 } else if (lua_key_eq(s
, prev
)) {
1790 if (nodetype_has_prev(t
)) {
1795 const char **fields
= node_data
[t
].fields
;
1796 if (t
== whatsit_node
) {
1797 fields
= whatsit_node_data
[subtype(node
)].fields
;
1799 if (lua_key_eq(s
, list
)) {
1800 /* head and list are equivalent; we don't catch extra virtual fields */
1803 if (fields
!= NULL
) {
1804 for (j
= 0; fields
[j
] != NULL
; j
++) {
1805 if (strcmp(s
, fields
[j
]) == 0) {
1814 /* node.has_field */
1816 static int lua_nodelib_has_field(lua_State
* L
)
1819 if (!lua_isnil(L
, 1))
1820 i
= get_node_field_id(L
, 2, *(check_isnode(L
, 1)));
1821 lua_pushboolean(L
, (i
!= -2));
1825 /* node.direct.has_field */
1827 static int lua_nodelib_direct_has_field(lua_State
* L
)
1831 n
= (halfword
) lua_tonumber(L
, 1);
1833 i
= get_node_field_id(L
, 2, n
);
1834 lua_pushboolean(L
, (i
!= -2));
1838 /* fetch the list of valid node types */
1840 static int do_lua_nodelib_types(lua_State
* L
, node_info
* data
)
1844 for (i
= 0; data
[i
].id
!= -1; i
++) {
1845 lua_pushstring(L
, data
[i
].name
);
1846 lua_rawseti(L
, -2, data
[i
].id
);
1853 static int lua_nodelib_types(lua_State
* L
)
1855 return do_lua_nodelib_types(L
, node_data
);
1860 static int lua_nodelib_whatsits(lua_State
* L
)
1862 return do_lua_nodelib_types(L
, whatsit_node_data
);
1865 /* node.fields (fetch the list of valid fields) */
1867 static int lua_nodelib_fields(lua_State
* L
)
1871 const char **fields
;
1872 int t
= get_valid_node_type_id(L
, 1);
1873 if (t
== whatsit_node
) {
1874 t
= get_valid_node_subtype_id(L
, 2);
1875 fields
= whatsit_node_data
[t
].fields
;
1877 fields
= node_data
[t
].fields
;
1879 lua_checkstack(L
, 2);
1881 // lua_pushstring(L, "next");
1882 lua_push_string_by_name(L
,next
);
1883 lua_rawseti(L
, -2, 0);
1884 // lua_pushstring(L, "id");
1885 lua_push_string_by_name(L
,id
);
1886 lua_rawseti(L
, -2, 1);
1887 if (nodetype_has_subtype(t
)) {
1888 // lua_pushstring(L, "subtype");
1889 lua_push_string_by_name(L
,subtype
);
1890 lua_rawseti(L
, -2, 2);
1893 if (fields
!= NULL
) {
1894 if (nodetype_has_prev(t
)) {
1895 // lua_pushstring(L, "prev");
1896 lua_push_string_by_name(L
,prev
);
1897 lua_rawseti(L
, -2, -1);
1899 for (i
= 0; fields
[i
] != NULL
; i
++) {
1900 lua_pushstring(L
, fields
[i
]); /* todo */
1901 lua_rawseti(L
, -2, (i
+ offset
));
1907 /* node.slide (find the end of a list and add prev links) */
1909 static int lua_nodelib_slide(lua_State
* L
)
1913 if (lua_isnil(L
, 1))
1914 return 1; /* the nil itself */
1915 n
= check_isnode(L
, 1);
1918 return 1; /* the old userdata */
1919 /* alink(t) = null; */ /* don't do this, |t|'s |alink| may be a valid pointer */
1920 while (vlink(t
) != null
) {
1921 alink(vlink(t
)) = t
;
1924 lua_nodelib_push_fast(L
, t
);
1928 /* node.direct.slide */
1930 static int lua_nodelib_direct_slide(lua_State
* L
)
1933 n
= (halfword
) lua_tonumber(L
, 1);
1937 while (vlink(n
) != null
) {
1938 alink(vlink(n
)) = n
;
1941 lua_pushnumber(L
, n
);
1946 /* node.tail (find the end of a list) */
1948 static int lua_nodelib_tail(lua_State
* L
)
1952 if (lua_isnil(L
, 1))
1953 return 1; /* the nil itself */
1954 n
= check_isnode(L
, 1);
1957 return 1; /* the old userdata */
1958 while (vlink(t
) != null
)
1960 lua_nodelib_push_fast(L
, t
);
1964 /* node.direct.tail */
1966 static int lua_nodelib_direct_tail(lua_State
* L
)
1969 n
= (halfword
) lua_tonumber(L
, 1);
1973 while (vlink(n
) != null
)
1975 lua_pushnumber(L
, n
);
1980 /* node.end_of_math (skip over math and return last) */
1982 static int lua_nodelib_end_of_math(lua_State
* L
)
1986 if (lua_isnil(L
, 1))
1987 return 1; /* the nil itself */
1988 n
= check_isnode(L
, 1);
1991 return 1; /* the old userdata */
1992 while (vlink(t
) != null
) {
1993 t
= vlink(t
); /* skip first node */
1994 if (t
&& type(t
)==math_node
) {
1995 lua_nodelib_push_fast(L
, t
);
2002 /* node.direct.end_of_math */
2004 static int lua_nodelib_direct_end_of_math(lua_State
* L
)
2007 n
= (halfword
) lua_tonumber(L
, 1);
2009 while (vlink(n
) != null
) {
2010 n
= vlink(n
); /* skip first node */
2011 if (n
&& type(n
)==math_node
) {
2012 lua_pushnumber(L
, n
);
2021 /* node.has_attribute (gets attribute) */
2023 static int lua_nodelib_has_attribute(lua_State
* L
)
2027 n
= check_isnode(L
, 1);
2029 i
= (int) lua_tointeger(L
, 2);
2030 val
= (int) luaL_optinteger(L
, 3, UNUSED_ATTRIBUTE
);
2031 if ((val
= has_attribute(*n
, i
, val
)) > UNUSED_ATTRIBUTE
) {
2032 lua_pushnumber(L
, val
);
2040 /* node.direct.has_attribute */
2042 static int lua_nodelib_direct_has_attribute(lua_State
* L
)
2046 n
= (halfword
) lua_tonumber(L
, 1);
2048 i
= (int) lua_tointeger(L
, 2);
2049 val
= (int) luaL_optinteger(L
, 3, UNUSED_ATTRIBUTE
);
2050 if ((val
= has_attribute(n
, i
, val
)) > UNUSED_ATTRIBUTE
) {
2051 lua_pushnumber(L
, val
);
2059 /* node.set_attribute */
2061 static int lua_nodelib_set_attribute(lua_State
* L
)
2065 if (lua_gettop(L
) == 3) {
2066 i
= (int) lua_tointeger(L
, 2);
2067 val
= (int) lua_tointeger(L
, 3);
2068 n
= check_isnode(L
, 1);
2069 if (val
== UNUSED_ATTRIBUTE
) {
2070 (void) unset_attribute(*n
, i
, val
);
2072 set_attribute(*n
, i
, val
);
2075 luaL_error(L
, "incorrect number of arguments");
2080 /* node.direct.set_attribute */
2082 static int lua_nodelib_direct_set_attribute(lua_State
* L
)
2086 n
= (halfword
) lua_tonumber(L
, 1);
2089 if (lua_gettop(L
) == 3) {
2090 i
= (int) lua_tointeger(L
, 2);
2091 val
= (int) lua_tointeger(L
, 3);
2092 if (val
== UNUSED_ATTRIBUTE
) {
2093 (void) unset_attribute(n
, i
, val
);
2095 set_attribute(n
, i
, val
);
2098 luaL_error(L
, "incorrect number of arguments");
2103 /* node.unset_attribute */
2105 static int lua_nodelib_unset_attribute(lua_State
* L
)
2109 if (lua_gettop(L
) <= 3) {
2110 i
=(int)luaL_checknumber(L
, 2);
2111 val
=(int)luaL_optnumber(L
, 3, UNUSED_ATTRIBUTE
);
2112 n
= check_isnode(L
, 1);
2113 ret
= unset_attribute(*n
, i
, val
);
2114 if (ret
> UNUSED_ATTRIBUTE
) {
2115 lua_pushnumber(L
, ret
);
2121 return luaL_error(L
, "incorrect number of arguments");
2125 /* node.direct.unset_attribute */
2127 static int lua_nodelib_direct_unset_attribute(lua_State
* L
)
2131 n
= (halfword
) lua_tonumber(L
, 1);
2134 } else if (lua_gettop(L
) <= 3) { /* a useless test, we never test for that elsewhere */
2135 i
=(int)luaL_checknumber(L
, 2);
2136 val
=(int)luaL_optnumber(L
, 3, UNUSED_ATTRIBUTE
);
2137 ret
= unset_attribute(n
, i
, val
);
2138 if (ret
> UNUSED_ATTRIBUTE
) {
2139 lua_pushnumber(L
, ret
);
2143 } else { /* can go */
2144 return luaL_error(L
, "incorrect number of arguments");
2151 static int nodelib_aux_nil(lua_State
* L
)
2157 /* node.traverse_id */
2159 static int nodelib_aux_next_filtered(lua_State
* L
)
2161 halfword t
; /* traverser */
2163 int i
= (int) lua_tointeger(L
, lua_upvalueindex(1));
2164 if (lua_isnil(L
, 2)) { /* first call */
2165 t
= *check_isnode(L
, 1);
2168 t
= *check_isnode(L
, 2);
2172 while (t
!= null
&& type(t
) != i
) {
2178 fast_metatable_top(t
);
2183 static int lua_nodelib_traverse_filtered(lua_State
* L
)
2186 if (lua_isnil(L
, 2)) {
2187 lua_pushcclosure(L
, nodelib_aux_nil
, 0);
2190 n
= *(check_isnode(L
, 2));
2191 lua_pop(L
, 1); /* the node, integer remains */
2192 lua_pushcclosure(L
, nodelib_aux_next_filtered
, 1);
2193 lua_nodelib_push_fast(L
, n
);
2198 /* node.direct.traverse_id */
2200 static int nodelib_direct_aux_next_filtered(lua_State
* L
)
2202 halfword t
; /* traverser */
2203 int i
= (int) lua_tointeger(L
, lua_upvalueindex(1));
2204 if (lua_isnil(L
, 2)) { /* first call */
2205 t
= lua_tonumber(L
,1) ;
2208 t
= lua_tonumber(L
,2) ;
2212 while (t
!= null
&& type(t
) != i
) {
2218 lua_pushnumber(L
,t
);
2223 static int lua_nodelib_direct_traverse_filtered(lua_State
* L
)
2226 if (lua_isnil(L
, 2)) {
2227 lua_pushcclosure(L
, nodelib_aux_nil
, 0);
2230 n
= (halfword
) lua_tonumber(L
, 2);
2233 n
= (halfword
) lua_tonumber(L
, 2);
2235 lua_pushcclosure(L
, nodelib_direct_aux_next_filtered
, 1);
2236 lua_pushnumber(L
,n
);
2243 static int nodelib_aux_next(lua_State
* L
)
2245 halfword t
; /* traverser */
2246 halfword
*a
; /* a or *a */
2247 if (lua_isnil(L
, 2)) { /* first call */
2248 t
= *check_isnode(L
, 1);
2251 t
= *check_isnode(L
, 2);
2258 fast_metatable_top(t
);
2263 static int lua_nodelib_traverse(lua_State
* L
)
2266 if (lua_isnil(L
, 1)) {
2267 lua_pushcclosure(L
, nodelib_aux_nil
, 0);
2270 n
= *(check_isnode(L
, 1));
2271 lua_pushcclosure(L
, nodelib_aux_next
, 0);
2272 lua_nodelib_push_fast(L
, n
);
2277 /* node.direct.traverse */
2279 static int nodelib_direct_aux_next(lua_State
* L
)
2281 halfword t
; /* traverser */
2282 /*int i = (int) lua_tointeger(L, lua_upvalueindex(1));*/
2283 if (lua_isnil(L
, 2)) { /* first call */
2284 t
= lua_tonumber(L
,1) ;
2287 t
= lua_tonumber(L
,2) ;
2294 lua_pushnumber(L
,t
);
2299 static int lua_nodelib_direct_traverse(lua_State
* L
)
2302 if (lua_isnil(L
, 1)) {
2303 lua_pushcclosure(L
, nodelib_aux_nil
, 0);
2306 n
= (halfword
) lua_tonumber(L
, 1);
2308 lua_pushcclosure(L
, nodelib_aux_nil
, 0);
2311 lua_pushcclosure(L
, nodelib_direct_aux_next
, 0);
2312 lua_pushnumber(L
,n
);
2320 static int do_lua_nodelib_count(lua_State
* L
, halfword match
, int i
, halfword first1
)
2324 while (t
!= match
) {
2325 if (i
< 0 || type(t
) == i
)
2329 lua_pushnumber(L
, count
);
2335 static int lua_nodelib_length(lua_State
* L
)
2339 if (lua_isnil(L
, 1)) {
2340 lua_pushnumber(L
, 0);
2343 n
= *(check_isnode(L
, 1));
2344 if (lua_gettop(L
) == 2)
2345 m
= *(check_isnode(L
, 2));
2346 return do_lua_nodelib_count(L
, m
, -1, n
);
2349 /* node.direct.length */
2351 static int lua_nodelib_direct_length(lua_State
* L
)
2354 n
= (halfword
) lua_tonumber(L
, 1);
2356 lua_pushnumber(L
, 0);
2359 m
= (halfword
) lua_tonumber(L
, 2);
2360 return do_lua_nodelib_count(L
, m
, -1, n
);
2365 static int lua_nodelib_count(lua_State
* L
)
2370 i
= (int) lua_tointeger(L
, 1);
2371 if (lua_isnil(L
, 2)) {
2372 lua_pushnumber(L
, 0);
2375 n
= *(check_isnode(L
, 2));
2376 if (lua_gettop(L
) == 3)
2377 m
= *(check_isnode(L
, 3));
2378 return do_lua_nodelib_count(L
, m
, i
, n
);
2381 /* node.direct.count */
2383 static int lua_nodelib_direct_count(lua_State
* L
)
2385 return do_lua_nodelib_count(L
,
2386 (halfword
) lua_tonumber(L
, 3), /* m */
2387 (int) lua_tointeger(L
, 1), /* i */
2388 (halfword
) lua_tonumber(L
, 2) /* n */
2392 /* directions (could be a macro) */
2394 // static void nodelib_pushdir(lua_State * L, int n, boolean dirnode)
2397 // lua_pushstring(L, dir_strings[n+64]);
2399 // lua_pushstring(L, dir_strings[n+64]+1);
2403 /* getting and setting fields (helpers) */
2405 static int nodelib_getlist(lua_State
* L
, int n
)
2408 if (lua_isuserdata(L
, n
)) {
2409 m
= check_isnode(L
, n
);
2416 int nodelib_getdir(lua_State
* L
, int n
, int absolute_only
)
2418 if (lua_type(L
, n
) == LUA_TSTRING
) {
2419 const char *s
= lua_tostring(L
, n
);
2420 RETURN_DIR_VALUES(TLT
);
2421 RETURN_DIR_VALUES(TRT
);
2422 RETURN_DIR_VALUES(LTL
);
2423 RETURN_DIR_VALUES(RTT
);
2424 luaL_error(L
, "Bad direction specifier %s", s
);
2426 luaL_error(L
, "Direction specifiers have to be strings");
2431 static str_number
nodelib_getstring(lua_State
* L
, int a
)
2434 const char *s
= lua_tolstring(L
, a
, &k
);
2435 return maketexlstring(s
, k
);
2438 static void nodelib_setattr(lua_State
* L
, int stackindex
, halfword n
)
2441 p
= nodelib_getlist(L
, stackindex
);
2442 if (node_attr(n
) != p
) {
2443 if (node_attr(n
) != null
)
2444 delete_attribute_ref(node_attr(n
));
2451 static int nodelib_cantset(lua_State
* L
, int n
, const char *s
)
2453 luaL_error(L
,"You cannot set field %s in a node of type %s",s
,node_data
[type(n
)].name
);
2457 /* node.direct.getfield */
2459 static void lua_nodelib_getfield_whatsit(lua_State
* L
, int n
, const char *s
)
2464 if (t
== dir_node
) {
2465 if (lua_key_eq(s
, dir
)) {
2466 // nodelib_pushdir(L, dir_dir(n), true);
2467 lua_push_dir_text(L
, dir_dir(n
));
2468 } else if (lua_key_eq(s
, level
)) {
2469 lua_pushnumber(L
, dir_level(n
));
2470 } else if (lua_key_eq(s
, dvi_ptr
)) {
2471 lua_pushnumber(L
, dir_dvi_ptr(n
));
2472 } else if (lua_key_eq(s
, dir_h
)) {
2473 lua_pushnumber(L
, dir_dvi_h(n
));
2477 } else if (t
== user_defined_node
) {
2478 if (lua_key_eq(s
, user_id
)) {
2479 lua_pushnumber(L
, user_node_id(n
));
2480 } else if (lua_key_eq(s
, type
)) {
2481 lua_pushnumber(L
, user_node_type(n
));
2482 } else if (lua_key_eq(s
, value
)) {
2483 switch (user_node_type(n
)) {
2485 nodelib_pushlist(L
, user_node_value(n
));
2488 lua_pushnumber(L
, user_node_value(n
));
2491 if (user_node_value(n
) != 0) {
2492 lua_rawgeti(L
, LUA_REGISTRYINDEX
, user_node_value(n
));
2498 nodelib_pushlist(L
, user_node_value(n
));
2501 nodelib_pushstring(L
, user_node_value(n
));
2504 tokenlist_to_lua(L
, user_node_value(n
));
2507 lua_pushnumber(L
, user_node_value(n
));
2513 } else if (t
== local_par_node
) {
2514 if (lua_key_eq(s
, pen_inter
)) {
2515 lua_pushnumber(L
, local_pen_inter(n
));
2516 } else if (lua_key_eq(s
, pen_broken
)) {
2517 lua_pushnumber(L
, local_pen_broken(n
));
2518 } else if (lua_key_eq(s
, dir
)) {
2519 // nodelib_pushdir(L, local_par_dir(n), false);
2520 lua_push_dir_par(L
, local_par_dir(n
));
2521 } else if (lua_key_eq(s
, box_left
)) {
2522 /* can be: fast_metatable_or_nil(local_box_left(n)) */
2523 nodelib_pushlist(L
, local_box_left(n
));
2524 } else if (lua_key_eq(s
, box_left_width
)) {
2525 lua_pushnumber(L
, local_box_left_width(n
));
2526 } else if (lua_key_eq(s
, box_right
)) {
2527 /* can be: fast_metatable_or_nil(local_box_right(n)) */
2528 nodelib_pushlist(L
, local_box_right(n
));
2529 } else if (lua_key_eq(s
, box_right_width
)) {
2530 lua_pushnumber(L
, local_box_right_width(n
));
2534 } else if (t
== pdf_literal_node
) {
2535 if (lua_key_eq(s
, mode
)) {
2536 lua_pushnumber(L
, pdf_literal_mode(n
));
2537 } else if (lua_key_eq(s
, data
)) {
2538 if (pdf_literal_type(n
) == lua_refid_literal
) {
2539 lua_rawgeti(L
, LUA_REGISTRYINDEX
, pdf_literal_data(n
));
2541 tokenlist_to_luastring(L
, pdf_literal_data(n
));
2546 } else if (t
== late_lua_node
) {
2547 if (lua_key_eq(s
, string
) || lua_key_eq(s
, data
)) {
2548 if (late_lua_type(n
) == lua_refid_literal
) {
2549 lua_rawgeti(L
, LUA_REGISTRYINDEX
, late_lua_data(n
));
2551 tokenlist_to_luastring(L
, late_lua_data(n
));
2553 } else if (lua_key_eq(s
, name
)) {
2554 tokenlist_to_luastring(L
, late_lua_name(n
));
2558 } else if (t
== pdf_annot_node
) {
2559 if (lua_key_eq(s
, width
)) {
2560 lua_pushnumber(L
, width(n
));
2561 } else if (lua_key_eq(s
, depth
)) {
2562 lua_pushnumber(L
, depth(n
));
2563 } else if (lua_key_eq(s
, height
)) {
2564 lua_pushnumber(L
, height(n
));
2565 } else if (lua_key_eq(s
, objnum
)) {
2566 lua_pushnumber(L
, pdf_annot_objnum(n
));
2567 } else if (lua_key_eq(s
, data
)) {
2568 tokenlist_to_luastring(L
, pdf_annot_data(n
));
2572 } else if (t
== pdf_dest_node
) {
2573 if (lua_key_eq(s
, width
)) {
2574 lua_pushnumber(L
, width(n
));
2575 } else if (lua_key_eq(s
, depth
)) {
2576 lua_pushnumber(L
, depth(n
));
2577 } else if (lua_key_eq(s
, height
)) {
2578 lua_pushnumber(L
, height(n
));
2579 } else if (lua_key_eq(s
, named_id
)) {
2580 lua_pushnumber(L
, pdf_dest_named_id(n
));
2581 } else if (lua_key_eq(s
, dest_id
)) {
2582 if (pdf_dest_named_id(n
) == 1)
2583 tokenlist_to_luastring(L
, pdf_dest_id(n
));
2585 lua_pushnumber(L
, pdf_dest_id(n
));
2586 } else if (lua_key_eq(s
, dest_type
)) {
2587 lua_pushnumber(L
, pdf_dest_type(n
));
2588 } else if (lua_key_eq(s
, xyz_zoom
)) {
2589 lua_pushnumber(L
, pdf_dest_xyz_zoom(n
));
2590 } else if (lua_key_eq(s
, objnum
)) {
2591 lua_pushnumber(L
, pdf_dest_objnum(n
));
2595 } else if (t
== pdf_setmatrix_node
) {
2596 if (lua_key_eq(s
, data
)) {
2597 tokenlist_to_luastring(L
, pdf_setmatrix_data(n
));
2601 } else if (t
== pdf_colorstack_node
) {
2602 if (lua_key_eq(s
, stack
)) {
2603 lua_pushnumber(L
, pdf_colorstack_stack(n
));
2604 } else if (lua_key_eq(s
, command
)) {
2605 lua_pushnumber(L
, pdf_colorstack_cmd(n
));
2606 } else if (lua_key_eq(s
, data
)) {
2607 tokenlist_to_luastring(L
, pdf_colorstack_data(n
));
2611 } else if (t
== pdf_refobj_node
) {
2612 if (lua_key_eq(s
, objnum
)) {
2613 lua_pushnumber(L
, pdf_obj_objnum(n
));
2617 } else if (t
== pdf_refxform_node
) {
2618 if (lua_key_eq(s
, width
)) {
2619 lua_pushnumber(L
, width(n
));
2620 } else if (lua_key_eq(s
, depth
)) {
2621 lua_pushnumber(L
, depth(n
));
2622 } else if (lua_key_eq(s
, height
)) {
2623 lua_pushnumber(L
, height(n
));
2624 } else if (lua_key_eq(s
, objnum
)) {
2625 lua_pushnumber(L
, pdf_xform_objnum(n
));
2629 } else if (t
== pdf_refximage_node
) {
2630 if (lua_key_eq(s
, width
)) {
2631 lua_pushnumber(L
, width(n
));
2632 } else if (lua_key_eq(s
, depth
)) {
2633 lua_pushnumber(L
, depth(n
));
2634 } else if (lua_key_eq(s
, height
)) {
2635 lua_pushnumber(L
, height(n
));
2636 } else if (lua_key_eq(s
, transform
)) {
2637 lua_pushnumber(L
, pdf_ximage_transform(n
));
2638 } else if (lua_key_eq(s
, index
)) {
2639 lua_pushnumber(L
, pdf_ximage_index(n
));
2643 } else if (t
== write_node
) {
2644 if (lua_key_eq(s
, stream
)) {
2645 lua_pushnumber(L
, write_stream(n
));
2646 } else if (lua_key_eq(s
, data
)) {
2647 tokenlist_to_lua(L
, write_tokens(n
));
2651 } else if (t
== special_node
) {
2652 if (lua_key_eq(s
, data
)) {
2653 tokenlist_to_luastring(L
, write_tokens(n
));
2657 } else if (t
== pdf_start_link_node
) {
2658 if (lua_key_eq(s
, width
)) {
2659 lua_pushnumber(L
, width(n
));
2660 } else if (lua_key_eq(s
, depth
)) {
2661 lua_pushnumber(L
, depth(n
));
2662 } else if (lua_key_eq(s
, height
)) {
2663 lua_pushnumber(L
, height(n
));
2664 } else if (lua_key_eq(s
, objnum
)) {
2665 lua_pushnumber(L
, pdf_link_objnum(n
));
2666 } else if (lua_key_eq(s
, link_attr
)) {
2667 tokenlist_to_luastring(L
, pdf_link_attr(n
));
2668 } else if (lua_key_eq(s
, action
)) {
2669 nodelib_pushaction(L
, pdf_link_action(n
));
2673 } else if ((t
== pdf_thread_node
) || (t
== pdf_start_thread_node
)) {
2674 if (lua_key_eq(s
, width
)) {
2675 lua_pushnumber(L
, width(n
));
2676 } else if (lua_key_eq(s
, depth
)) {
2677 lua_pushnumber(L
, depth(n
));
2678 } else if (lua_key_eq(s
, height
)) {
2679 lua_pushnumber(L
, height(n
));
2680 } else if (lua_key_eq(s
, named_id
)) {
2681 lua_pushnumber(L
, pdf_thread_named_id(n
));
2682 } else if (lua_key_eq(s
, thread_id
)) {
2683 if (pdf_thread_named_id(n
) == 1) {
2684 tokenlist_to_luastring(L
, pdf_thread_id(n
));
2686 lua_pushnumber(L
, pdf_thread_id(n
));
2688 } else if (lua_key_eq(s
, thread_attr
)) {
2689 tokenlist_to_luastring(L
, pdf_thread_attr(n
));
2693 } else if (t
== open_node
) {
2694 if (lua_key_eq(s
, stream
)) {
2695 lua_pushnumber(L
, write_stream(n
));
2696 } else if (lua_key_eq(s
, name
)) {
2697 nodelib_pushstring(L
, open_name(n
));
2698 } else if (lua_key_eq(s
, area
)) {
2699 nodelib_pushstring(L
, open_area(n
));
2700 } else if (lua_key_eq(s
, ext
)) {
2701 nodelib_pushstring(L
, open_ext(n
));
2705 } else if (t
== close_node
) {
2706 if (lua_key_eq(s
, stream
)) {
2707 lua_pushnumber(L
, write_stream(n
));
2716 static int lua_nodelib_fast_getfield(lua_State
* L
)
2719 the order is somewhat determined by the occurance of nodes and
2720 importance of fields
2728 n
= *((halfword
*) lua_touserdata(L
, 1));
2733 somenode[9] as interface to attributes ... 30% faster than has_attribute
2734 (1) because there is no lua function overhead, and (2) because we already
2735 know that we deal with a node so no checking is needed. The fast typecheck
2736 is needed (lua_check... is a slow down actually).
2740 if (lua_type(L
, 2) == LUA_TNUMBER
) {
2745 if (! nodetype_has_attributes(t
)) {
2751 if (p
== null
|| vlink(p
) == null
) {
2755 i
= (int) lua_tointeger(L
, 2);
2758 if (attribute_id(p
) == i
) {
2759 if ((int) attribute_value(p
) > UNUSED_ATTRIBUTE
) {
2760 lua_pushnumber(L
, (int) attribute_value(p
));
2765 } else if (attribute_id(p
) > i
) {
2775 s
= lua_tostring(L
, 2);
2777 if (lua_key_eq(s
, id
)) {
2778 lua_pushnumber(L
, t
);
2779 } else if (lua_key_eq(s
, next
)) {
2780 fast_metatable_or_nil(vlink(n
));
2781 } else if (lua_key_eq(s
, prev
)) {
2782 fast_metatable_or_nil(alink(n
));
2783 } else if (lua_key_eq(s
, attr
)) {
2784 if (! nodetype_has_attributes(t
)) {
2787 nodelib_pushattr(L
, node_attr(n
));
2789 } else if (t
== glyph_node
) {
2790 /* candidates: fontchar (font,char) whd (width,height,depth) */
2791 if (lua_key_eq(s
, subtype
)) {
2792 lua_pushnumber(L
, subtype(n
));
2793 } else if (lua_key_eq(s
, font
)) {
2794 lua_pushnumber(L
, font(n
));
2795 } else if (lua_key_eq(s
, char)) {
2796 lua_pushnumber(L
, character(n
));
2797 } else if (lua_key_eq(s
, xoffset
)) {
2798 lua_pushnumber(L
, x_displace(n
));
2799 } else if (lua_key_eq(s
, yoffset
)) {
2800 lua_pushnumber(L
, y_displace(n
));
2801 } else if (lua_key_eq(s
, width
)) {
2802 lua_pushnumber(L
, char_width(font(n
),character(n
)));
2803 } else if (lua_key_eq(s
, height
)) {
2804 lua_pushnumber(L
, char_height(font(n
),character(n
)));
2805 } else if (lua_key_eq(s
, depth
)) {
2806 lua_pushnumber(L
, char_depth(font(n
),character(n
)));
2807 } else if (lua_key_eq(s
, expansion_factor
)) {
2808 lua_pushnumber(L
, ex_glyph(n
));
2809 } else if (lua_key_eq(s
, components
)) {
2810 fast_metatable_or_nil(lig_ptr(n
));
2811 } else if (lua_key_eq(s
, lang
)) {
2812 lua_pushnumber(L
, char_lang(n
));
2813 } else if (lua_key_eq(s
, left
)) {
2814 lua_pushnumber(L
, char_lhmin(n
));
2815 } else if (lua_key_eq(s
, right
)) {
2816 lua_pushnumber(L
, char_rhmin(n
));
2817 } else if (lua_key_eq(s
, uchyph
)) {
2818 lua_pushnumber(L
, char_uchyph(n
));
2822 } else if ((t
== hlist_node
) || (t
== vlist_node
)) {
2823 /* candidates: whd (width,height,depth) */
2824 if (lua_key_eq(s
, subtype
)) {
2825 lua_pushnumber(L
, subtype(n
));
2826 } else if (lua_key_eq(s
, list
) || lua_key_eq(s
, head
)) {
2827 fast_metatable_or_nil_alink(list_ptr(n
));
2828 } else if (lua_key_eq(s
, width
)) {
2829 lua_pushnumber(L
, width(n
));
2830 } else if (lua_key_eq(s
, height
)) {
2831 lua_pushnumber(L
, height(n
));
2832 } else if (lua_key_eq(s
, depth
)) {
2833 lua_pushnumber(L
, depth(n
));
2834 } else if (lua_key_eq(s
, dir
)) {
2835 // nodelib_pushdir(L, box_dir(n), false);
2836 lua_push_dir_par(L
, box_dir(n
));
2837 } else if (lua_key_eq(s
, shift
)) {
2838 lua_pushnumber(L
, shift_amount(n
));
2839 } else if (lua_key_eq(s
, glue_order
)) {
2840 lua_pushnumber(L
, glue_order(n
));
2841 } else if (lua_key_eq(s
, glue_sign
)) {
2842 lua_pushnumber(L
, glue_sign(n
));
2843 } else if (lua_key_eq(s
, glue_set
)) {
2844 lua_pushnumber(L
, (double) glue_set(n
));
2848 } else if (t
== disc_node
) {
2849 if (lua_key_eq(s
, subtype
)) {
2850 lua_pushnumber(L
, subtype(n
));
2851 } else if (lua_key_eq(s
, pre
)) {
2852 fast_metatable_or_nil(vlink(pre_break(n
)));
2853 } else if (lua_key_eq(s
, post
)) {
2854 fast_metatable_or_nil(vlink(post_break(n
)));
2855 } else if (lua_key_eq(s
, replace
)) {
2856 fast_metatable_or_nil(vlink(no_break(n
)));
2860 } else if (t
== glue_node
) {
2861 if (lua_key_eq(s
, subtype
)) {
2862 lua_pushnumber(L
, subtype(n
));
2863 } else if (lua_key_eq(s
, spec
)) {
2864 nodelib_pushspec(L
, glue_ptr(n
));
2865 } else if (lua_key_eq(s
, leader
)) {
2866 fast_metatable_or_nil(leader_ptr(n
));
2870 } else if (t
== glue_spec_node
) {
2871 if (lua_key_eq(s
, subtype
)) {
2872 lua_pushnumber(L
, 0); /* dummy, the only one that prevents move up */
2873 } else if (lua_key_eq(s
, width
)) {
2874 lua_pushnumber(L
, width(n
));
2875 } else if (lua_key_eq(s
, stretch
)) {
2876 lua_pushnumber(L
, stretch(n
));
2877 } else if (lua_key_eq(s
, shrink
)) {
2878 lua_pushnumber(L
, shrink(n
));
2879 } else if (lua_key_eq(s
, stretch_order
)) {
2880 lua_pushnumber(L
, stretch_order(n
));
2881 } else if (lua_key_eq(s
, shrink_order
)) {
2882 lua_pushnumber(L
, shrink_order(n
));
2883 } else if (lua_key_eq(s
, ref_count
)) {
2884 lua_pushnumber(L
, glue_ref_count(n
));
2885 } else if (lua_key_eq(s
, writable
)) {
2886 lua_pushboolean(L
, valid_node(n
));
2890 } else if (t
== kern_node
) {
2891 if (lua_key_eq(s
, subtype
)) {
2892 lua_pushnumber(L
, subtype(n
));
2893 } else if (lua_key_eq(s
, kern
)) {
2894 lua_pushnumber(L
, width(n
));
2895 } else if (lua_key_eq(s
, expansion_factor
)) {
2896 lua_pushnumber(L
, ex_kern(n
));
2900 } else if (t
== penalty_node
) {
2901 if (lua_key_eq(s
, subtype
)) {
2902 lua_pushnumber(L
, subtype(n
));
2903 } else if (lua_key_eq(s
, penalty
)) {
2904 lua_pushnumber(L
, penalty(n
));
2908 } else if (t
== rule_node
) {
2909 /* candidates: whd (width,height,depth) */
2910 if (lua_key_eq(s
, subtype
)) {
2911 lua_pushnumber(L
, subtype(n
));
2912 } else if (lua_key_eq(s
, width
)) {
2913 lua_pushnumber(L
, width(n
));
2914 } else if (lua_key_eq(s
, height
)) {
2915 lua_pushnumber(L
, height(n
));
2916 } else if (lua_key_eq(s
, depth
)) {
2917 lua_pushnumber(L
, depth(n
));
2918 } else if (lua_key_eq(s
, dir
)) {
2919 // nodelib_pushdir(L, rule_dir(n), false);
2920 lua_push_dir_par(L
, rule_dir(n
));
2924 } else if (t
== whatsit_node
) {
2925 if (lua_key_eq(s
, subtype
)) {
2926 lua_pushnumber(L
, subtype(n
));
2928 lua_nodelib_getfield_whatsit(L
, n
, s
);
2930 } else if (t
== simple_noad
) {
2931 if (lua_key_eq(s
, subtype
)) {
2932 lua_pushnumber(L
, subtype(n
));
2933 } else if (lua_key_eq(s
, nucleus
)) {
2934 fast_metatable_or_nil(nucleus(n
));
2935 } else if (lua_key_eq(s
, sub
)) {
2936 fast_metatable_or_nil(subscr(n
));
2937 } else if (lua_key_eq(s
, sup
)) {
2938 fast_metatable_or_nil(supscr(n
));
2942 } else if ((t
== math_char_node
) || (t
== math_text_char_node
)) {
2943 /* candidates: famchar (fam,char) */
2944 if (lua_key_eq(s
, subtype
)) {
2945 lua_pushnumber(L
, subtype(n
));
2946 } else if (lua_key_eq(s
, fam
)) {
2947 lua_pushnumber(L
, math_fam(n
));
2948 } else if (lua_key_eq(s
, char)) {
2949 lua_pushnumber(L
, math_character(n
));
2953 } else if (t
== mark_node
) {
2954 if (lua_key_eq(s
, subtype
)) {
2955 lua_pushnumber(L
, subtype(n
));
2956 } else if (lua_key_eq(s
, class)) {
2957 lua_pushnumber(L
, mark_class(n
));
2958 } else if (lua_key_eq(s
, mark
)) {
2959 tokenlist_to_lua(L
, mark_ptr(n
));
2963 } else if (t
== ins_node
) {
2964 if (lua_key_eq(s
, subtype
)) {
2965 lua_pushnumber(L
, subtype(n
));
2966 } else if (lua_key_eq(s
, cost
)) {
2967 lua_pushnumber(L
, float_cost(n
));
2968 } else if (lua_key_eq(s
, depth
)) {
2969 lua_pushnumber(L
, depth(n
));
2970 } else if (lua_key_eq(s
, height
)) {
2971 lua_pushnumber(L
, height(n
));
2972 } else if (lua_key_eq(s
, spec
)) {
2973 nodelib_pushspec(L
, split_top_ptr(n
));
2974 } else if ((lua_key_eq(s
, list
)) || (lua_key_eq(s
, head
))) {
2975 fast_metatable_or_nil_alink(ins_ptr(n
));
2979 } else if (t
== math_node
) {
2980 if (lua_key_eq(s
, subtype
)) {
2981 lua_pushnumber(L
, subtype(n
));
2982 } else if (lua_key_eq(s
, surround
)) {
2983 lua_pushnumber(L
, surround(n
));
2987 } else if (t
== fraction_noad
) {
2988 if (lua_key_eq(s
, subtype
)) {
2989 lua_pushnumber(L
, subtype(n
));
2990 } else if (lua_key_eq(s
, width
)) {
2991 lua_pushnumber(L
, thickness(n
));
2992 } else if (lua_key_eq(s
, num
)) {
2993 fast_metatable_or_nil(numerator(n
));
2994 } else if (lua_key_eq(s
, denom
)) {
2995 fast_metatable_or_nil(denominator(n
));
2996 } else if (lua_key_eq(s
, left
)) {
2997 fast_metatable_or_nil(left_delimiter(n
));
2998 } else if (lua_key_eq(s
, right
)) {
2999 fast_metatable_or_nil(right_delimiter(n
));
3003 } else if (t
== style_node
) {
3004 if (lua_key_eq(s
, subtype
)) {
3005 lua_pushnumber(L
, subtype(n
));
3006 } else if (lua_key_eq(s
, style
)) {
3007 lua_push_math_style_name(L
,subtype(n
));
3011 } else if (t
== accent_noad
) {
3012 if (lua_key_eq(s
, subtype
)) {
3013 lua_pushnumber(L
, subtype(n
));
3014 } else if (lua_key_eq(s
, nucleus
)) {
3015 fast_metatable_or_nil(nucleus(n
));
3016 } else if (lua_key_eq(s
, sub
)) {
3017 fast_metatable_or_nil(subscr(n
));
3018 } else if (lua_key_eq(s
, sup
)) {
3019 fast_metatable_or_nil(supscr(n
));
3020 } else if (lua_key_eq(s
, accent
)) {
3021 fast_metatable_or_nil(accent_chr(n
));
3022 } else if (lua_key_eq(s
, bot_accent
)) {
3023 fast_metatable_or_nil(bot_accent_chr(n
));
3027 } else if (t
== fence_noad
) {
3028 if (lua_key_eq(s
, subtype
)) {
3029 lua_pushnumber(L
, subtype(n
));
3030 } else if (lua_key_eq(s
, delim
)) {
3031 fast_metatable_or_nil(delimiter(n
));
3035 } else if (t
== delim_node
) {
3036 if (lua_key_eq(s
, subtype
)) {
3037 lua_pushnumber(L
, subtype(n
));
3038 } else if (lua_key_eq(s
, small_fam
)) {
3039 lua_pushnumber(L
, small_fam(n
));
3040 } else if (lua_key_eq(s
, small_char
)) {
3041 lua_pushnumber(L
, small_char(n
));
3042 } else if (lua_key_eq(s
, large_fam
)) {
3043 lua_pushnumber(L
, large_fam(n
));
3044 } else if (lua_key_eq(s
, large_char
)) {
3045 lua_pushnumber(L
, large_char(n
));
3049 } else if ((t
== sub_box_node
) || (t
== sub_mlist_node
)) {
3050 if (lua_key_eq(s
, subtype
)) {
3051 lua_pushnumber(L
, subtype(n
));
3052 } else if ((lua_key_eq(s
, list
)) || (lua_key_eq(s
, head
))){
3053 fast_metatable_or_nil_alink(math_list(n
));
3057 } else if (t
== radical_noad
) {
3058 if (lua_key_eq(s
, subtype
)) {
3059 lua_pushnumber(L
, subtype(n
));
3060 } else if (lua_key_eq(s
, nucleus
)) {
3061 fast_metatable_or_nil(nucleus(n
));
3062 } else if (lua_key_eq(s
, sub
)) {
3063 fast_metatable_or_nil(subscr(n
));
3064 } else if (lua_key_eq(s
, sup
)) {
3065 fast_metatable_or_nil(supscr(n
));
3066 } else if (lua_key_eq(s
, left
)) {
3067 fast_metatable_or_nil(left_delimiter(n
));
3068 } else if (lua_key_eq(s
, degree
)) {
3069 fast_metatable_or_nil(degree(n
));
3073 } else if (t
== margin_kern_node
) {
3074 if (lua_key_eq(s
, subtype
)) {
3075 lua_pushnumber(L
, subtype(n
));
3076 } else if (lua_key_eq(s
, width
)) {
3077 lua_pushnumber(L
, width(n
));
3078 } else if (lua_key_eq(s
, glyph
)) {
3079 fast_metatable_or_nil(margin_char(n
));
3083 } else if (t
== split_up_node
) {
3084 if (lua_key_eq(s
, subtype
)) {
3085 lua_pushnumber(L
, subtype(n
));
3086 } else if (lua_key_eq(s
, last_ins_ptr
)) {
3087 fast_metatable_or_nil(last_ins_ptr(n
));
3088 } else if (lua_key_eq(s
, best_ins_ptr
)) {
3089 fast_metatable_or_nil(best_ins_ptr(n
));
3090 } else if (lua_key_eq(s
, broken_ptr
)) {
3091 fast_metatable_or_nil(broken_ptr(n
));
3092 } else if (lua_key_eq(s
, broken_ins
)) {
3093 fast_metatable_or_nil(broken_ins(n
));
3097 } else if (t
== choice_node
) {
3098 if (lua_key_eq(s
, subtype
)) {
3099 lua_pushnumber(L
, subtype(n
));
3100 } else if (lua_key_eq(s
, display
)) {
3101 fast_metatable_or_nil(display_mlist(n
));
3102 } else if (lua_key_eq(s
, text
)) {
3103 fast_metatable_or_nil(text_mlist(n
));
3104 } else if (lua_key_eq(s
, script
)) {
3105 fast_metatable_or_nil(script_mlist(n
));
3106 } else if (lua_key_eq(s
, scriptscript
)) {
3107 fast_metatable_or_nil(script_script_mlist(n
));
3111 } else if (t
== inserting_node
) {
3112 if (lua_key_eq(s
, subtype
)) {
3113 lua_pushnumber(L
, subtype(n
));
3114 } else if (lua_key_eq(s
, last_ins_ptr
)) {
3115 fast_metatable_or_nil(last_ins_ptr(n
));
3116 } else if (lua_key_eq(s
, best_ins_ptr
)) {
3117 fast_metatable_or_nil(best_ins_ptr(n
));
3121 } else if (t
== attribute_node
) {
3122 if (lua_key_eq(s
, subtype
)) {
3123 lua_pushnumber(L
, subtype(n
));
3124 } else if (lua_key_eq(s
, number
)) {
3125 lua_pushnumber(L
, attribute_id(n
));
3126 } else if (lua_key_eq(s
, value
)) {
3127 lua_pushnumber(L
, attribute_value(n
));
3131 } else if (t
== adjust_node
) {
3132 if (lua_key_eq(s
, subtype
)) {
3133 lua_pushnumber(L
, subtype(n
));
3134 } else if ((lua_key_eq(s
, list
)) || (lua_key_eq(s
, head
))) {
3135 fast_metatable_or_nil_alink(adjust_ptr(n
));
3139 } else if (t
== action_node
) {
3140 if (lua_key_eq(s
, subtype
)) {
3141 lua_pushnumber(L
, subtype(n
));/* dummy subtype */
3142 } else if (lua_key_eq(s
, action_type
)) {
3143 lua_pushnumber(L
, pdf_action_type(n
));
3144 } else if (lua_key_eq(s
, named_id
)) {
3145 lua_pushnumber(L
, pdf_action_named_id(n
));
3146 } else if (lua_key_eq(s
, action_id
)) {
3147 if (pdf_action_named_id(n
) == 1) {
3148 tokenlist_to_luastring(L
, pdf_action_id(n
));
3150 lua_pushnumber(L
, pdf_action_id(n
));
3152 } else if (lua_key_eq(s
, file
)) {
3153 tokenlist_to_luastring(L
, pdf_action_file(n
));
3154 } else if (lua_key_eq(s
, new_window
)) {
3155 lua_pushnumber(L
, pdf_action_new_window(n
));
3156 } else if (lua_key_eq(s
, data
)) {
3157 tokenlist_to_luastring(L
, pdf_action_tokens(n
));
3158 } else if (lua_key_eq(s
, ref_count
)) {
3159 lua_pushnumber(L
, pdf_action_refcount(n
));
3163 } else if (t
== unset_node
) {
3164 if (lua_key_eq(s
, subtype
)) {
3165 lua_pushnumber(L
, subtype(n
));
3166 } else if (lua_key_eq(s
, width
)) {
3167 lua_pushnumber(L
, width(n
));
3168 } else if (lua_key_eq(s
, height
)) {
3169 lua_pushnumber(L
, height(n
));
3170 } else if (lua_key_eq(s
, depth
)) {
3171 lua_pushnumber(L
, depth(n
));
3172 } else if (lua_key_eq(s
, dir
)) {
3173 // nodelib_pushdir(L, box_dir(n), false);
3174 lua_push_dir_par(L
, box_dir(n
));
3175 } else if (lua_key_eq(s
, shrink
)) {
3176 lua_pushnumber(L
, glue_shrink(n
));
3177 } else if (lua_key_eq(s
, glue_order
)) {
3178 lua_pushnumber(L
, glue_order(n
));
3179 } else if (lua_key_eq(s
, glue_sign
)) {
3180 lua_pushnumber(L
, glue_sign(n
));
3181 } else if (lua_key_eq(s
, stretch
)) {
3182 lua_pushnumber(L
, glue_stretch(n
));
3183 } else if (lua_key_eq(s
, count
)) {
3184 lua_pushnumber(L
, span_count(n
));
3185 } else if ((lua_key_eq(s
, list
)) || (lua_key_eq(s
, head
))){
3186 fast_metatable_or_nil_alink(list_ptr(n
));
3190 } else if (t
== attribute_list_node
) {
3191 if (lua_key_eq(s
, subtype
)) {
3192 lua_pushnumber(L
, subtype(n
));
3202 static int lua_nodelib_getfield(lua_State
* L
)
3204 /* [given-node] [...]*/
3205 halfword
*p
= lua_touserdata(L
, 1);
3206 if ( (p
== NULL
) || (! lua_getmetatable(L
,1)) ) {
3210 /* [given-node] [mt-given-node]*/
3211 lua_rawgeti(L
, LUA_REGISTRYINDEX
, luaS_index(luatex_node
));
3212 lua_gettable(L
, LUA_REGISTRYINDEX
);
3213 /* [given-node] [mt-given-node] [mt-node]*/
3214 if (!lua_rawequal(L
, -1, -2)) {
3218 /* prune stack and call getfield */
3220 return lua_nodelib_fast_getfield(L
);
3223 /* node.direct.getfield */
3225 static void lua_nodelib_direct_getfield_whatsit(lua_State
* L
, int n
, const char *s
)
3230 if (t
== dir_node
) {
3231 if (lua_key_eq(s
, dir
)) {
3232 // nodelib_pushdir(L, dir_dir(n), true);
3233 lua_push_dir_text(L
, dir_dir(n
));
3234 } else if (lua_key_eq(s
, level
)) {
3235 lua_pushnumber(L
, dir_level(n
));
3236 } else if (lua_key_eq(s
, dvi_ptr
)) {
3237 lua_pushnumber(L
, dir_dvi_ptr(n
));
3238 } else if (lua_key_eq(s
, dir_h
)) {
3239 lua_pushnumber(L
, dir_dvi_h(n
));
3243 } else if (t
== user_defined_node
) {
3244 if (lua_key_eq(s
, user_id
)) {
3245 lua_pushnumber(L
, user_node_id(n
));
3246 } else if (lua_key_eq(s
, type
)) {
3247 lua_pushnumber(L
, user_node_type(n
));
3248 } else if (lua_key_eq(s
, value
)) {
3249 switch (user_node_type(n
)) {
3251 nodelib_pushdirect(user_node_value(n
));
3254 lua_pushnumber(L
, user_node_value(n
));
3257 if (user_node_value(n
) != 0) {
3258 lua_rawgeti(L
, LUA_REGISTRYINDEX
, user_node_value(n
));
3264 nodelib_pushdirect(user_node_value(n
));
3267 nodelib_pushstring(L
, user_node_value(n
));
3270 tokenlist_to_lua(L
, user_node_value(n
));
3273 lua_pushnumber(L
, user_node_value(n
));
3279 } else if (t
== local_par_node
) {
3280 if (lua_key_eq(s
, pen_inter
)) {
3281 lua_pushnumber(L
, local_pen_inter(n
));
3282 } else if (lua_key_eq(s
, pen_broken
)) {
3283 lua_pushnumber(L
, local_pen_broken(n
));
3284 } else if (lua_key_eq(s
, dir
)) {
3285 // nodelib_pushdir(L, local_par_dir(n), false);
3286 lua_push_dir_par(L
, local_par_dir(n
));
3287 } else if (lua_key_eq(s
, box_left
)) {
3288 nodelib_pushdirect_or_nil(local_box_left(n
));
3289 } else if (lua_key_eq(s
, box_left_width
)) {
3290 lua_pushnumber(L
, local_box_left_width(n
));
3291 } else if (lua_key_eq(s
, box_right
)) {
3292 nodelib_pushdirect_or_nil(local_box_right(n
));
3293 } else if (lua_key_eq(s
, box_right_width
)) {
3294 lua_pushnumber(L
, local_box_right_width(n
));
3298 } else if (t
== pdf_literal_node
) {
3299 if (lua_key_eq(s
, mode
)) {
3300 lua_pushnumber(L
, pdf_literal_mode(n
));
3301 } else if (lua_key_eq(s
, data
)) {
3302 if (pdf_literal_type(n
) == lua_refid_literal
) {
3303 lua_rawgeti(L
, LUA_REGISTRYINDEX
, pdf_literal_data(n
));
3305 tokenlist_to_luastring(L
, pdf_literal_data(n
));
3310 } else if (t
== late_lua_node
) {
3311 if (lua_key_eq(s
, string
) || lua_key_eq(s
, data
)) {
3312 if (late_lua_type(n
) == lua_refid_literal
) {
3313 lua_rawgeti(L
, LUA_REGISTRYINDEX
, late_lua_data(n
));
3315 tokenlist_to_luastring(L
, late_lua_data(n
));
3317 } else if (lua_key_eq(s
, name
)) {
3318 tokenlist_to_luastring(L
, late_lua_name(n
));
3322 } else if (t
== pdf_annot_node
) {
3323 if (lua_key_eq(s
, width
)) {
3324 lua_pushnumber(L
, width(n
));
3325 } else if (lua_key_eq(s
, depth
)) {
3326 lua_pushnumber(L
, depth(n
));
3327 } else if (lua_key_eq(s
, height
)) {
3328 lua_pushnumber(L
, height(n
));
3329 } else if (lua_key_eq(s
, objnum
)) {
3330 lua_pushnumber(L
, pdf_annot_objnum(n
));
3331 } else if (lua_key_eq(s
, data
)) {
3332 tokenlist_to_luastring(L
, pdf_annot_data(n
));
3336 } else if (t
== pdf_dest_node
) {
3337 if (lua_key_eq(s
, width
)) {
3338 lua_pushnumber(L
, width(n
));
3339 } else if (lua_key_eq(s
, depth
)) {
3340 lua_pushnumber(L
, depth(n
));
3341 } else if (lua_key_eq(s
, height
)) {
3342 lua_pushnumber(L
, height(n
));
3343 } else if (lua_key_eq(s
, named_id
)) {
3344 lua_pushnumber(L
, pdf_dest_named_id(n
));
3345 } else if (lua_key_eq(s
, dest_id
)) {
3346 if (pdf_dest_named_id(n
) == 1)
3347 tokenlist_to_luastring(L
, pdf_dest_id(n
));
3349 lua_pushnumber(L
, pdf_dest_id(n
));
3350 } else if (lua_key_eq(s
, dest_type
)) {
3351 lua_pushnumber(L
, pdf_dest_type(n
));
3352 } else if (lua_key_eq(s
, xyz_zoom
)) {
3353 lua_pushnumber(L
, pdf_dest_xyz_zoom(n
));
3354 } else if (lua_key_eq(s
, objnum
)) {
3355 lua_pushnumber(L
, pdf_dest_objnum(n
));
3359 } else if (t
== pdf_setmatrix_node
) {
3360 if (lua_key_eq(s
, data
)) {
3361 tokenlist_to_luastring(L
, pdf_setmatrix_data(n
));
3365 } else if (t
== pdf_colorstack_node
) {
3366 if (lua_key_eq(s
, stack
)) {
3367 lua_pushnumber(L
, pdf_colorstack_stack(n
));
3368 } else if (lua_key_eq(s
, command
)) {
3369 lua_pushnumber(L
, pdf_colorstack_cmd(n
));
3370 } else if (lua_key_eq(s
, data
)) {
3371 tokenlist_to_luastring(L
, pdf_colorstack_data(n
));
3375 } else if (t
== pdf_refobj_node
) {
3376 if (lua_key_eq(s
, objnum
)) {
3377 lua_pushnumber(L
, pdf_obj_objnum(n
));
3381 } else if (t
== pdf_refxform_node
) {
3382 if (lua_key_eq(s
, width
)) {
3383 lua_pushnumber(L
, width(n
));
3384 } else if (lua_key_eq(s
, depth
)) {
3385 lua_pushnumber(L
, depth(n
));
3386 } else if (lua_key_eq(s
, height
)) {
3387 lua_pushnumber(L
, height(n
));
3388 } else if (lua_key_eq(s
, objnum
)) {
3389 lua_pushnumber(L
, pdf_xform_objnum(n
));
3393 } else if (t
== pdf_refximage_node
) {
3394 if (lua_key_eq(s
, width
)) {
3395 lua_pushnumber(L
, width(n
));
3396 } else if (lua_key_eq(s
, depth
)) {
3397 lua_pushnumber(L
, depth(n
));
3398 } else if (lua_key_eq(s
, height
)) {
3399 lua_pushnumber(L
, height(n
));
3400 } else if (lua_key_eq(s
, transform
)) {
3401 lua_pushnumber(L
, pdf_ximage_transform(n
));
3402 } else if (lua_key_eq(s
, index
)) {
3403 lua_pushnumber(L
, pdf_ximage_index(n
));
3407 } else if (t
== write_node
) {
3408 if (lua_key_eq(s
, stream
)) {
3409 lua_pushnumber(L
, write_stream(n
));
3410 } else if (lua_key_eq(s
, data
)) {
3411 tokenlist_to_lua(L
, write_tokens(n
));
3415 } else if (t
== special_node
) {
3416 if (lua_key_eq(s
, data
)) {
3417 tokenlist_to_luastring(L
, write_tokens(n
));
3421 } else if (t
== pdf_start_link_node
) {
3422 if (lua_key_eq(s
, width
)) {
3423 lua_pushnumber(L
, width(n
));
3424 } else if (lua_key_eq(s
, depth
)) {
3425 lua_pushnumber(L
, depth(n
));
3426 } else if (lua_key_eq(s
, height
)) {
3427 lua_pushnumber(L
, height(n
));
3428 } else if (lua_key_eq(s
, objnum
)) {
3429 lua_pushnumber(L
, pdf_link_objnum(n
));
3430 } else if (lua_key_eq(s
, link_attr
)) {
3431 tokenlist_to_luastring(L
, pdf_link_attr(n
));
3432 } else if (lua_key_eq(s
, action
)) {
3433 nodelib_pushaction(L
, pdf_link_action(n
));
3437 } else if ((t
== pdf_thread_node
) || (t
== pdf_start_thread_node
)) {
3438 if (lua_key_eq(s
, width
)) {
3439 lua_pushnumber(L
, width(n
));
3440 } else if (lua_key_eq(s
, depth
)) {
3441 lua_pushnumber(L
, depth(n
));
3442 } else if (lua_key_eq(s
, height
)) {
3443 lua_pushnumber(L
, height(n
));
3444 } else if (lua_key_eq(s
, named_id
)) {
3445 lua_pushnumber(L
, pdf_thread_named_id(n
));
3446 } else if (lua_key_eq(s
, thread_id
)) {
3447 if (pdf_thread_named_id(n
) == 1) {
3448 tokenlist_to_luastring(L
, pdf_thread_id(n
));
3450 lua_pushnumber(L
, pdf_thread_id(n
));
3452 } else if (lua_key_eq(s
, thread_attr
)) {
3453 tokenlist_to_luastring(L
, pdf_thread_attr(n
));
3457 } else if (t
== open_node
) {
3458 if (lua_key_eq(s
, stream
)) {
3459 lua_pushnumber(L
, write_stream(n
));
3460 } else if (lua_key_eq(s
, name
)) {
3461 nodelib_pushstring(L
, open_name(n
));
3462 } else if (lua_key_eq(s
, area
)) {
3463 nodelib_pushstring(L
, open_area(n
));
3464 } else if (lua_key_eq(s
, ext
)) {
3465 nodelib_pushstring(L
, open_ext(n
));
3469 } else if (t
== close_node
) {
3470 if (lua_key_eq(s
, stream
)) {
3471 lua_pushnumber(L
, write_stream(n
));
3480 static int lua_nodelib_direct_getfield(lua_State
* L
)
3487 n
= (halfword
) lua_tonumber(L
, 1);
3491 if (lua_type(L
, 2) == LUA_TNUMBER
) {
3496 if (! nodetype_has_attributes(t
)) {
3502 if (p
== null
|| vlink(p
) == null
) {
3506 i
= (int) lua_tointeger(L
, 2);
3509 if (attribute_id(p
) == i
) {
3510 if ((int) attribute_value(p
) > UNUSED_ATTRIBUTE
) {
3511 lua_pushnumber(L
, (int) attribute_value(p
));
3516 } else if (attribute_id(p
) > i
) {
3526 s
= lua_tostring(L
, 2);
3528 if (lua_key_eq(s
, id
)) {
3529 lua_pushnumber(L
, t
);
3530 } else if (lua_key_eq(s
, next
)) {
3531 nodelib_pushdirect_or_nil(vlink(n
));
3532 } else if (lua_key_eq(s
, prev
)) {
3533 nodelib_pushdirect_or_nil(alink(n
));
3534 } else if (lua_key_eq(s
, attr
)) {
3535 if (! nodetype_has_attributes(t
)) {
3538 nodelib_pushattr(L
, node_attr(n
));
3540 } else if (lua_key_eq(s
, subtype
)) {
3541 if (t
== glue_spec_node
) {
3542 lua_pushnumber(L
, 0); /* dummy, the only one */
3544 lua_pushnumber(L
, subtype(n
));
3546 } else if (t
== glyph_node
) {
3547 if (lua_key_eq(s
, font
)) {
3548 lua_pushnumber(L
, font(n
));
3549 } else if (lua_key_eq(s
, char)) {
3550 lua_pushnumber(L
, character(n
));
3551 } else if (lua_key_eq(s
, xoffset
)) {
3552 lua_pushnumber(L
, x_displace(n
));
3553 } else if (lua_key_eq(s
, yoffset
)) {
3554 lua_pushnumber(L
, y_displace(n
));
3555 } else if (lua_key_eq(s
, width
)) {
3556 lua_pushnumber(L
, char_width(font(n
),character(n
)));
3557 } else if (lua_key_eq(s
, height
)) {
3558 lua_pushnumber(L
, char_height(font(n
),character(n
)));
3559 } else if (lua_key_eq(s
, depth
)) {
3560 lua_pushnumber(L
, char_depth(font(n
),character(n
)));
3561 } else if (lua_key_eq(s
, expansion_factor
)) {
3562 lua_pushnumber(L
, ex_glyph(n
));
3563 } else if (lua_key_eq(s
, components
)) {
3564 nodelib_pushdirect_or_nil(lig_ptr(n
));
3565 } else if (lua_key_eq(s
, lang
)) {
3566 lua_pushnumber(L
, char_lang(n
));
3567 } else if (lua_key_eq(s
, left
)) {
3568 lua_pushnumber(L
, char_lhmin(n
));
3569 } else if (lua_key_eq(s
, right
)) {
3570 lua_pushnumber(L
, char_rhmin(n
));
3571 } else if (lua_key_eq(s
, uchyph
)) {
3572 lua_pushnumber(L
, char_uchyph(n
));
3576 } else if ((t
== hlist_node
) || (t
== vlist_node
)) {
3577 /* candidates: whd (width,height,depth) */
3578 if (lua_key_eq(s
, list
) || lua_key_eq(s
, head
)) {
3579 nodelib_pushdirect_or_nil_alink(list_ptr(n
));
3580 } else if (lua_key_eq(s
, width
)) {
3581 lua_pushnumber(L
, width(n
));
3582 } else if (lua_key_eq(s
, height
)) {
3583 lua_pushnumber(L
, height(n
));
3584 } else if (lua_key_eq(s
, depth
)) {
3585 lua_pushnumber(L
, depth(n
));
3586 } else if (lua_key_eq(s
, dir
)) {
3587 // nodelib_pushdir(L, box_dir(n), false);
3588 lua_push_dir_par(L
, box_dir(n
));
3589 } else if (lua_key_eq(s
, shift
)) {
3590 lua_pushnumber(L
, shift_amount(n
));
3591 } else if (lua_key_eq(s
, glue_order
)) {
3592 lua_pushnumber(L
, glue_order(n
));
3593 } else if (lua_key_eq(s
, glue_sign
)) {
3594 lua_pushnumber(L
, glue_sign(n
));
3595 } else if (lua_key_eq(s
, glue_set
)) {
3596 lua_pushnumber(L
, (double) glue_set(n
));
3600 } else if (t
== disc_node
) {
3601 if (lua_key_eq(s
, pre
)) {
3602 nodelib_pushdirect_or_nil(vlink(pre_break(n
)));
3603 } else if (lua_key_eq(s
, post
)) {
3604 nodelib_pushdirect_or_nil(vlink(post_break(n
)));
3605 } else if (lua_key_eq(s
, replace
)) {
3606 nodelib_pushdirect_or_nil(vlink(no_break(n
)));
3610 } else if (t
== glue_node
) {
3611 if (lua_key_eq(s
, spec
)) {
3612 nodelib_pushdirect(glue_ptr(n
));
3613 } else if (lua_key_eq(s
, leader
)) {
3614 nodelib_pushdirect_or_nil(leader_ptr(n
));
3618 } else if (t
== glue_spec_node
) {
3619 if (lua_key_eq(s
, width
)) {
3620 lua_pushnumber(L
, width(n
));
3621 } else if (lua_key_eq(s
, stretch
)) {
3622 lua_pushnumber(L
, stretch(n
));
3623 } else if (lua_key_eq(s
, shrink
)) {
3624 lua_pushnumber(L
, shrink(n
));
3625 } else if (lua_key_eq(s
, stretch_order
)) {
3626 lua_pushnumber(L
, stretch_order(n
));
3627 } else if (lua_key_eq(s
, shrink_order
)) {
3628 lua_pushnumber(L
, shrink_order(n
));
3629 } else if (lua_key_eq(s
, ref_count
)) {
3630 lua_pushnumber(L
, glue_ref_count(n
));
3631 } else if (lua_key_eq(s
, writable
)) {
3632 lua_pushboolean(L
, valid_node(n
));
3636 } else if (t
== kern_node
) {
3637 if (lua_key_eq(s
, kern
)) {
3638 lua_pushnumber(L
, width(n
));
3639 } else if (lua_key_eq(s
, expansion_factor
)) {
3640 lua_pushnumber(L
, ex_kern(n
));
3644 } else if (t
== penalty_node
) {
3645 if (lua_key_eq(s
, penalty
)) {
3646 lua_pushnumber(L
, penalty(n
));
3650 } else if (t
== rule_node
) {
3651 /* candidates: whd (width,height,depth) */
3652 if (lua_key_eq(s
, width
)) {
3653 lua_pushnumber(L
, width(n
));
3654 } else if (lua_key_eq(s
, height
)) {
3655 lua_pushnumber(L
, height(n
));
3656 } else if (lua_key_eq(s
, depth
)) {
3657 lua_pushnumber(L
, depth(n
));
3658 } else if (lua_key_eq(s
, dir
)) {
3659 // nodelib_pushdir(L, rule_dir(n), false);
3660 lua_push_dir_par(L
, rule_dir(n
));
3664 } else if (t
== whatsit_node
) {
3665 lua_nodelib_direct_getfield_whatsit(L
, n
, s
);
3666 } else if (t
== simple_noad
) {
3667 if (lua_key_eq(s
, nucleus
)) {
3668 nodelib_pushdirect_or_nil(nucleus(n
));
3669 } else if (lua_key_eq(s
, sub
)) {
3670 nodelib_pushdirect_or_nil(subscr(n
));
3671 } else if (lua_key_eq(s
, sup
)) {
3672 nodelib_pushdirect_or_nil(supscr(n
));
3676 } else if ((t
== math_char_node
) || (t
== math_text_char_node
)) {
3677 if (lua_key_eq(s
, fam
)) {
3678 lua_pushnumber(L
, math_fam(n
));
3679 } else if (lua_key_eq(s
, char)) {
3680 lua_pushnumber(L
, math_character(n
));
3684 } else if (t
== mark_node
) {
3685 if (lua_key_eq(s
, class)) {
3686 lua_pushnumber(L
, mark_class(n
));
3687 } else if (lua_key_eq(s
, mark
)) {
3688 tokenlist_to_lua(L
, mark_ptr(n
));
3692 } else if (t
== ins_node
) {
3693 if (lua_key_eq(s
, cost
)) {
3694 lua_pushnumber(L
, float_cost(n
));
3695 } else if (lua_key_eq(s
, depth
)) {
3696 lua_pushnumber(L
, depth(n
));
3697 } else if (lua_key_eq(s
, height
)) {
3698 lua_pushnumber(L
, height(n
));
3699 } else if (lua_key_eq(s
, spec
)) {
3700 nodelib_pushdirect_or_nil(split_top_ptr(n
));
3701 } else if ((lua_key_eq(s
, list
)) || (lua_key_eq(s
, head
))) {
3702 nodelib_pushdirect_or_nil_alink(ins_ptr(n
));
3706 } else if (t
== math_node
) {
3707 if (lua_key_eq(s
, surround
)) {
3708 lua_pushnumber(L
, surround(n
));
3712 } else if (t
== fraction_noad
) {
3713 if (lua_key_eq(s
, width
)) {
3714 lua_pushnumber(L
, thickness(n
));
3715 } else if (lua_key_eq(s
, num
)) {
3716 nodelib_pushdirect_or_nil(numerator(n
));
3717 } else if (lua_key_eq(s
, denom
)) {
3718 nodelib_pushdirect_or_nil(denominator(n
));
3719 } else if (lua_key_eq(s
, left
)) {
3720 nodelib_pushdirect_or_nil(left_delimiter(n
));
3721 } else if (lua_key_eq(s
, right
)) {
3722 nodelib_pushdirect_or_nil(right_delimiter(n
));
3726 } else if (t
== style_node
) {
3727 if (lua_key_eq(s
, style
)) {
3728 lua_push_math_style_name(L
,subtype(n
));
3732 } else if (t
== accent_noad
) {
3733 if (lua_key_eq(s
, nucleus
)) {
3734 nodelib_pushdirect_or_nil(nucleus(n
));
3735 } else if (lua_key_eq(s
, sub
)) {
3736 nodelib_pushdirect_or_nil(subscr(n
));
3737 } else if (lua_key_eq(s
, sup
)) {
3738 nodelib_pushdirect_or_nil(supscr(n
));
3739 } else if (lua_key_eq(s
, accent
)) {
3740 nodelib_pushdirect_or_nil(accent_chr(n
));
3741 } else if (lua_key_eq(s
, bot_accent
)) {
3742 nodelib_pushdirect_or_nil(bot_accent_chr(n
));
3746 } else if (t
== fence_noad
) {
3747 if (lua_key_eq(s
, delim
)) {
3748 nodelib_pushdirect_or_nil(delimiter(n
));
3752 } else if (t
== delim_node
) {
3753 if (lua_key_eq(s
, small_fam
)) {
3754 lua_pushnumber(L
, small_fam(n
));
3755 } else if (lua_key_eq(s
, small_char
)) {
3756 lua_pushnumber(L
, small_char(n
));
3757 } else if (lua_key_eq(s
, large_fam
)) {
3758 lua_pushnumber(L
, large_fam(n
));
3759 } else if (lua_key_eq(s
, large_char
)) {
3760 lua_pushnumber(L
, large_char(n
));
3764 } else if ((t
== sub_box_node
) || (t
== sub_mlist_node
)) {
3765 if ((lua_key_eq(s
, list
)) || (lua_key_eq(s
, head
))){
3766 nodelib_pushdirect_or_nil_alink(math_list(n
));
3770 } else if (t
== radical_noad
) {
3771 if (lua_key_eq(s
, nucleus
)) {
3772 nodelib_pushdirect_or_nil(nucleus(n
));
3773 } else if (lua_key_eq(s
, sub
)) {
3774 nodelib_pushdirect_or_nil(subscr(n
));
3775 } else if (lua_key_eq(s
, sup
)) {
3776 nodelib_pushdirect_or_nil(supscr(n
));
3777 } else if (lua_key_eq(s
, left
)) {
3778 nodelib_pushdirect_or_nil(left_delimiter(n
));
3779 } else if (lua_key_eq(s
, degree
)) {
3780 nodelib_pushdirect_or_nil(degree(n
));
3784 } else if (t
== margin_kern_node
) {
3785 if (lua_key_eq(s
, width
)) {
3786 lua_pushnumber(L
, width(n
));
3787 } else if (lua_key_eq(s
, glyph
)) {
3788 nodelib_pushdirect_or_nil(margin_char(n
));
3792 } else if (t
== split_up_node
) {
3793 if (lua_key_eq(s
, last_ins_ptr
)) {
3794 nodelib_pushdirect_or_nil(last_ins_ptr(n
));
3795 } else if (lua_key_eq(s
, best_ins_ptr
)) {
3796 nodelib_pushdirect_or_nil(best_ins_ptr(n
));
3797 } else if (lua_key_eq(s
, broken_ptr
)) {
3798 nodelib_pushdirect_or_nil(broken_ptr(n
));
3799 } else if (lua_key_eq(s
, broken_ins
)) {
3800 nodelib_pushdirect_or_nil(broken_ins(n
));
3804 } else if (t
== choice_node
) {
3805 if (lua_key_eq(s
, display
)) {
3806 nodelib_pushdirect_or_nil(display_mlist(n
));
3807 } else if (lua_key_eq(s
, text
)) {
3808 nodelib_pushdirect_or_nil(text_mlist(n
));
3809 } else if (lua_key_eq(s
, script
)) {
3810 nodelib_pushdirect_or_nil(script_mlist(n
));
3811 } else if (lua_key_eq(s
, scriptscript
)) {
3812 nodelib_pushdirect_or_nil(script_script_mlist(n
));
3816 } else if (t
== inserting_node
) {
3817 if (lua_key_eq(s
, last_ins_ptr
)) {
3818 nodelib_pushdirect_or_nil(last_ins_ptr(n
));
3819 } else if (lua_key_eq(s
, best_ins_ptr
)) {
3820 nodelib_pushdirect_or_nil(best_ins_ptr(n
));
3824 } else if (t
== attribute_node
) {
3825 if (lua_key_eq(s
, number
)) {
3826 lua_pushnumber(L
, attribute_id(n
));
3827 } else if (lua_key_eq(s
, value
)) {
3828 lua_pushnumber(L
, attribute_value(n
));
3832 } else if (t
== adjust_node
) {
3833 if ((lua_key_eq(s
, list
)) || (lua_key_eq(s
, head
))) {
3834 nodelib_pushdirect_or_nil_alink(adjust_ptr(n
));
3838 } else if (t
== action_node
) {
3839 if (lua_key_eq(s
, action_type
)) {
3840 lua_pushnumber(L
, pdf_action_type(n
));
3841 } else if (lua_key_eq(s
, named_id
)) {
3842 lua_pushnumber(L
, pdf_action_named_id(n
));
3843 } else if (lua_key_eq(s
, action_id
)) {
3844 if (pdf_action_named_id(n
) == 1) {
3845 tokenlist_to_luastring(L
, pdf_action_id(n
));
3847 lua_pushnumber(L
, pdf_action_id(n
));
3849 } else if (lua_key_eq(s
, file
)) {
3850 tokenlist_to_luastring(L
, pdf_action_file(n
));
3851 } else if (lua_key_eq(s
, new_window
)) {
3852 lua_pushnumber(L
, pdf_action_new_window(n
));
3853 } else if (lua_key_eq(s
, data
)) {
3854 tokenlist_to_luastring(L
, pdf_action_tokens(n
));
3855 } else if (lua_key_eq(s
, ref_count
)) {
3856 lua_pushnumber(L
, pdf_action_refcount(n
));
3860 } else if (t
== unset_node
) {
3861 if (lua_key_eq(s
, width
)) {
3862 lua_pushnumber(L
, width(n
));
3863 } else if (lua_key_eq(s
, height
)) {
3864 lua_pushnumber(L
, height(n
));
3865 } else if (lua_key_eq(s
, depth
)) {
3866 lua_pushnumber(L
, depth(n
));
3867 } else if (lua_key_eq(s
, dir
)) {
3868 // nodelib_pushdir(L, box_dir(n), false);
3869 lua_push_dir_par(L
, box_dir(n
));
3870 } else if (lua_key_eq(s
, shrink
)) {
3871 lua_pushnumber(L
, glue_shrink(n
));
3872 } else if (lua_key_eq(s
, glue_order
)) {
3873 lua_pushnumber(L
, glue_order(n
));
3874 } else if (lua_key_eq(s
, glue_sign
)) {
3875 lua_pushnumber(L
, glue_sign(n
));
3876 } else if (lua_key_eq(s
, stretch
)) {
3877 lua_pushnumber(L
, glue_stretch(n
));
3878 } else if (lua_key_eq(s
, count
)) {
3879 lua_pushnumber(L
, span_count(n
));
3880 } else if ((lua_key_eq(s
, list
)) || (lua_key_eq(s
, head
))){
3881 nodelib_pushdirect_or_nil_alink(list_ptr(n
));
3885 /* } else if (t == attribute_list_node) { */
3886 /* lua_pushnil(L); */
3893 /* msg could be preallocated and shared */
3895 static void lua_nodelib_do_tostring(lua_State
* L
, halfword n
, const char *tag
)
3898 char a
[7] = { ' ', ' ', ' ', 'n', 'i', 'l', 0 };
3899 char v
[7] = { ' ', ' ', ' ', 'n', 'i', 'l', 0 };
3901 if (alink(n
) != null
)
3902 snprintf(a
, 7, "%6d", (int) alink(n
));
3903 if (vlink(n
) != null
)
3904 snprintf(v
, 7, "%6d", (int) vlink(n
));
3905 snprintf(msg
, 255, "<%s %s < %6d > %s : %s %d>", tag
, a
, (int) n
, v
, node_data
[type(n
)].name
, subtype(n
));
3906 lua_pushstring(L
, msg
);
3911 /* __tostring node.tostring */
3913 static int lua_nodelib_tostring(lua_State
* L
)
3916 n
= check_isnode(L
, 1);
3917 lua_nodelib_do_tostring(L
, *n
, "node");
3921 /* node.direct.tostring */
3923 static int lua_nodelib_direct_tostring(lua_State
* L
)
3925 halfword n
= (halfword
) lua_tonumber(L
,1);
3929 lua_nodelib_do_tostring(L
, n
, "direct");
3936 static int lua_nodelib_equal(lua_State
* L
)
3939 n
= *((halfword
*) lua_touserdata(L
, 1));
3940 m
= *((halfword
*) lua_touserdata(L
, 2));
3941 lua_pushboolean(L
, (n
== m
));
3945 /* node.ligaturing */
3947 static int font_tex_ligaturing(lua_State
* L
)
3949 /* on the stack are two nodes and a direction */
3953 if (lua_gettop(L
) < 1) {
3955 lua_pushboolean(L
, 0);
3958 h
= check_isnode(L
, 1);
3959 if (lua_gettop(L
) > 1) {
3960 t
= *(check_isnode(L
, 2));
3962 tmp_head
= new_node(nesting_node
, 1);
3963 couple_nodes(tmp_head
, *h
);
3964 tlink(tmp_head
) = t
;
3965 t
= handle_ligaturing(tmp_head
, t
);
3966 alink(vlink(tmp_head
)) = null
; /* hh-ls */
3967 lua_pushnumber(L
, vlink(tmp_head
));
3968 /* can be: lua_nodelib_push_fast(L, head); */
3969 flush_node(tmp_head
);
3970 lua_nodelib_push(L
);
3971 /* can be: lua_nodelib_push_fast(L, t); */
3972 lua_pushnumber(L
, t
);
3973 lua_nodelib_push(L
);
3974 lua_pushboolean(L
, 1);
3980 static int font_tex_kerning(lua_State
* L
)
3982 /* on the stack are two nodes and a direction */
3987 if (lua_gettop(L
) < 1) {
3989 lua_pushboolean(L
, 0);
3992 h
= check_isnode(L
, 1);
3993 if (lua_gettop(L
) > 1) {
3994 t
= *(check_isnode(L
, 2));
3996 tmp_head
= new_node(nesting_node
, 1);
3997 couple_nodes(tmp_head
, *h
);
3998 tlink(tmp_head
) = t
;
3999 t
= handle_kerning(tmp_head
, t
);
4000 alink(vlink(tmp_head
)) = null
; /* hh-ls */
4001 lua_pushnumber(L
, vlink(tmp_head
));
4002 /* can be: lua_nodelib_push_fast(L, head); */
4003 flush_node(tmp_head
);
4004 lua_nodelib_push(L
);
4005 /* can be: lua_nodelib_push_fast(L, t); */
4006 lua_pushnumber(L
, t
);
4007 lua_nodelib_push(L
);
4008 lua_pushboolean(L
, 1);
4013 /* node.protect_glyphs (returns also boolean because that signals callback) */
4015 static int lua_nodelib_protect_glyphs(lua_State
* L
)
4018 halfword head
= *(check_isnode(L
, 1));
4019 while (head
!= null
) {
4020 if (type(head
) == glyph_node
) {
4021 int s
= subtype(head
);
4024 subtype(head
) = (quarterword
) (s
== 1 ? 256 : 256 + s
);
4029 lua_pushboolean(L
, t
);
4030 lua_pushvalue(L
, 1);
4034 /* node.direct.protect_glyphs */
4036 static int lua_nodelib_direct_protect_glyphs(lua_State
* L
)
4039 halfword head
= (halfword
) lua_tonumber(L
,1);
4040 while (head
!= null
) {
4041 if (type(head
) == glyph_node
) {
4042 int s
= subtype(head
);
4045 subtype(head
) = (quarterword
) (s
== 1 ? 256 : 256 + s
);
4050 lua_pushboolean(L
, t
);
4051 lua_pushvalue(L
, 1);
4055 /* node.unprotect_glyphs (returns also boolean because that signals callback) */
4057 static int lua_nodelib_unprotect_glyphs(lua_State
* L
)
4060 halfword head
= *(check_isnode(L
, 1));
4061 while (head
!= null
) {
4062 if (type(head
) == glyph_node
) {
4063 int s
= subtype(head
);
4066 subtype(head
) = (quarterword
) (s
- 256);
4071 lua_pushboolean(L
, t
);
4072 lua_pushvalue(L
, 1);
4076 /* node.direct.unprotect_glyphs */
4078 static int lua_nodelib_direct_unprotect_glyphs(lua_State
* L
)
4081 halfword head
= (halfword
) lua_tonumber(L
,1);
4082 while (head
!= null
) {
4083 if (type(head
) == glyph_node
) {
4084 int s
= subtype(head
);
4087 subtype(head
) = (quarterword
) (s
- 256);
4092 lua_pushboolean(L
, t
);
4093 lua_pushvalue(L
, 1);
4097 /* node.first_glyph */
4099 static int lua_nodelib_first_glyph(lua_State
* L
)
4101 /* on the stack are two nodes and a direction */
4102 halfword h
, savetail
= null
, t
= null
;
4103 if (lua_gettop(L
) < 1) {
4105 lua_pushboolean(L
, 0);
4108 h
= *(check_isnode(L
, 1));
4109 if (lua_gettop(L
) > 1) {
4110 t
= *(check_isnode(L
, 2));
4111 savetail
= vlink(t
);
4114 while (h
!= null
&& (type(h
) != glyph_node
|| !is_simple_character(h
))) {
4117 if (savetail
!= null
) {
4118 vlink(t
) = savetail
;
4120 lua_pushnumber(L
, h
);
4121 lua_nodelib_push(L
);
4122 lua_pushboolean(L
, (h
== null
? 0 : 1));
4126 /* node.direct.first_glyph */
4128 static int lua_nodelib_direct_first_glyph(lua_State
* L
)
4130 halfword h
,savetail
,t
;
4133 h
= (halfword
) lua_tonumber(L
,1);
4138 t
= (halfword
) lua_tonumber(L
,2);
4140 savetail
= vlink(t
);
4143 while (h
!= null
&& (type(h
) != glyph_node
|| !is_simple_character(h
)))
4145 if (savetail
!= null
)
4146 vlink(t
) = savetail
;
4147 lua_pushnumber(L
, h
);
4148 return 1; /* no need to also push a boolean if we have nil */
4151 /* new, fast and dumb ones: only signals that something needs to be processed */
4153 /* #define do_has_glyph(h) do { \ */
4154 /* while (h != null) { \ */
4155 /* if (type(h) == glyph_node) { \ */
4158 /* h = vlink(h); \ */
4161 /* return null; \ */
4167 /* node.has_glyph */
4169 static int lua_nodelib_has_glyph(lua_State
* L
)
4172 halfword h
= (halfword
) *(check_isnode(L
,1)) ;
4174 if (type(h
) == glyph_node
) {
4185 /* node.direct.has_glyph */
4187 static int lua_nodelib_direct_has_glyph(lua_State
* L
)
4189 halfword h
= (halfword
) lua_tonumber(L
,1) ;
4191 if (type(h
) == glyph_node
) {
4192 nodelib_pushdirect(h
);
4205 static int lua_nodelib_first_character(lua_State
* L
)
4207 luatex_warn("node.first_character() is deprecated, please update to node.first_glyph()");
4208 return lua_nodelib_first_glyph(L
);
4211 /* this is too simplistic, but it helps Hans to get going */
4213 static halfword
do_ligature_n(halfword prev
, halfword stop
, halfword lig
)
4215 vlink(lig
) = vlink(stop
);
4217 lig_ptr(lig
) = vlink(prev
);
4222 /* node.do_ligature_n(node prev, node last, node lig) */
4224 static int lua_nodelib_do_ligature_n(lua_State
* L
)
4226 halfword n
, m
, o
, p
, tmp_head
;
4227 n
= *(check_isnode(L
, 1));
4228 m
= *(check_isnode(L
, 2));
4229 o
= *(check_isnode(L
, 3));
4230 if (alink(n
) == null
|| vlink(alink(n
)) != n
) {
4231 tmp_head
= new_node(temp_node
, 0);
4232 couple_nodes(tmp_head
, n
);
4233 p
= do_ligature_n(tmp_head
, m
, o
);
4234 flush_node(tmp_head
);
4236 p
= do_ligature_n(alink(n
), m
, o
);
4238 lua_pushnumber(L
, p
);
4239 lua_nodelib_push(L
);
4243 /* node.direct.do_ligature_n(node prev, node last, node lig) */
4245 static int lua_nodelib_direct_do_ligature_n(lua_State
* L
)
4247 halfword n
, m
, o
, p
, tmp_head
;
4248 n
= (halfword
) lua_tonumber(L
, 1);
4249 m
= (halfword
) lua_tonumber(L
, 2);
4250 o
= (halfword
) lua_tonumber(L
, 3);
4251 if ((n
== null
) || (m
== null
) || (o
== null
)) {
4254 if (alink(n
) == null
|| vlink(alink(n
)) != n
) {
4255 tmp_head
= new_node(temp_node
, 0);
4256 couple_nodes(tmp_head
, n
);
4257 p
= do_ligature_n(tmp_head
, m
, o
);
4258 flush_node(tmp_head
);
4260 p
= do_ligature_n(alink(n
), m
, o
);
4262 lua_pushnumber(L
, p
);
4269 static int lua_nodelib_usedlist(lua_State
* L
)
4271 lua_pushnumber(L
, list_node_mem_usage());
4272 lua_nodelib_push(L
);
4276 /* node.direct.usedlist */
4278 static int lua_nodelib_direct_usedlist(lua_State
* L
)
4280 lua_pushnumber(L
, list_node_mem_usage());
4284 /* node.protrusion_skipable(node m) */
4286 static int lua_nodelib_cp_skipable(lua_State
* L
)
4289 n
= *(check_isnode(L
, 1));
4290 lua_pushboolean(L
, cp_skipable(n
));
4294 /* node.direct.protrusion_skipable(node m) */
4296 static int lua_nodelib_direct_cp_skipable(lua_State
* L
)
4299 n
= (halfword
) lua_tonumber(L
, 1);
4303 lua_pushboolean(L
, cp_skipable(n
));
4308 /* node.currentattr(node m) */
4310 static int lua_nodelib_currentattr(lua_State
* L
)
4312 int n
= lua_gettop(L
);
4315 if (max_used_attr
>= 0) {
4316 if (attr_list_cache
== cache_disabled
) {
4317 update_attribute_cache();
4318 if (attr_list_cache
== null
) {
4323 attr_list_ref(attr_list_cache
)++;
4324 lua_pushnumber(L
, attr_list_cache
);
4325 lua_nodelib_push(L
);
4332 luatex_warn("Assignment via node.current_attr(<list>) is not supported (yet)");
4337 /* node.direct.currentattr(node m) */
4339 static int lua_nodelib_direct_currentattr(lua_State
* L
)
4341 if (max_used_attr
>= 0) {
4342 if (attr_list_cache
== cache_disabled
) {
4343 update_attribute_cache();
4344 if (attr_list_cache
== null
) {
4349 attr_list_ref(attr_list_cache
)++;
4350 lua_pushnumber(L
, attr_list_cache
);
4357 /* node.direct.todirect */
4359 static int lua_nodelib_direct_todirect(lua_State
* L
)
4361 if (lua_type(L
,1) != LUA_TNUMBER
) {
4362 /* assume node, no further testing, used in known situations */
4364 n
= lua_touserdata(L
, 1);
4368 lua_pushnumber(L
, *((halfword
*)n
) );
4370 } /* else assume direct and returns argument */
4375 /* node.direct.tonode */
4377 static int lua_nodelib_direct_tonode(lua_State
* L
)
4381 n
= (halfword
) lua_tonumber(L
, 1);
4383 a
= (halfword
*) lua_newuserdata(L
, sizeof(halfword
));
4385 lua_push_node_metatablelua
;
4386 lua_setmetatable(L
,-2);
4387 } /* else assume node and return argument */
4393 /* ls-hh: normally a value will not be reassigned */
4395 #define cleanup_late_lua(n) do { \
4396 if (late_lua_data(n) != 0) { \
4397 if (late_lua_type(n) == normal) { \
4398 delete_token_ref(late_lua_data(n)); \
4399 } else if (late_lua_type(n) == lua_refid_literal) { \
4400 luaL_unref(L, LUA_REGISTRYINDEX,late_lua_data(n)); \
4405 #define cleanup_late_lua_name(n) do { \
4406 if (late_lua_name(n) != 0) { \
4407 delete_token_ref(late_lua_name(n)); \
4411 static int lua_nodelib_setfield_whatsit(lua_State
* L
, int n
, const char *s
)
4416 if (t
== dir_node
) {
4417 if (lua_key_eq(s
, dir
)) {
4418 dir_dir(n
) = nodelib_getdir(L
, 3, 0);
4419 } else if (lua_key_eq(s
, level
)) {
4420 dir_level(n
) = (halfword
) lua_tointeger(L
, 3);
4421 } else if (lua_key_eq(s
, dvi_ptr
)) {
4422 dir_dvi_ptr(n
) = (halfword
) lua_tointeger(L
, 3);
4423 } else if (lua_key_eq(s
, dir_h
)) {
4424 dir_dvi_h(n
) = (halfword
) lua_tointeger(L
, 3);
4426 return nodelib_cantset(L
, n
, s
);
4428 } else if (t
== pdf_literal_node
) {
4429 if (lua_key_eq(s
, mode
)) {
4430 pdf_literal_mode(n
) = (quarterword
) lua_tointeger(L
, 3);
4431 } else if (lua_key_eq(s
, data
)) {
4433 pdf_literal_data(n
) = nodelib_gettoks(L
, 3);
4435 lua_pushvalue(L
, 3);
4436 pdf_literal_data(n
) = luaL_ref(L
, LUA_REGISTRYINDEX
);
4437 pdf_literal_type(n
) = lua_refid_literal
;
4440 return nodelib_cantset(L
, n
, s
);
4442 } else if (t
== late_lua_node
) {
4443 if (lua_key_eq(s
, string
)) {
4444 cleanup_late_lua(n
) ; /* ls-hh */
4446 late_lua_data(n
) = nodelib_gettoks(L
, 3);
4447 late_lua_type(n
) = normal
;
4449 lua_pushvalue(L
, 3);
4450 late_lua_data(n
) = luaL_ref(L
, LUA_REGISTRYINDEX
);
4451 late_lua_type(n
) = lua_refid_literal
;
4453 } else if (lua_key_eq(s
, data
)) {
4454 cleanup_late_lua(n
) ; /* ls-hh */
4455 late_lua_data(n
) = nodelib_gettoks(L
, 3);
4456 late_lua_type(n
) = normal
;
4457 } else if (lua_key_eq(s
, name
)) {
4458 cleanup_late_lua_name(n
) ; /* ls-hh */
4459 late_lua_name(n
) = nodelib_gettoks(L
, 3);
4461 return nodelib_cantset(L
, n
, s
);
4464 } else if (t
== user_defined_node
) {
4465 if (lua_key_eq(s
, user_id
)) {
4466 user_node_id(n
) = (halfword
) lua_tointeger(L
, 3);
4467 } else if (lua_key_eq(s
, type
)) {
4468 user_node_type(n
) = (halfword
) lua_tointeger(L
, 3);
4469 } else if (lua_key_eq(s
, value
)) {
4470 switch (user_node_type(n
)) {
4472 user_node_value(n
) = nodelib_getlist(L
, 3);
4475 user_node_value(n
) = (halfword
) lua_tointeger(L
, 3);
4478 lua_pushvalue(L
, 3);
4479 if (user_node_value(n
) != 0) {
4480 luaL_unref(L
, LUA_REGISTRYINDEX
,user_node_value(n
));
4482 user_node_value(n
) = luaL_ref(L
, LUA_REGISTRYINDEX
);
4485 user_node_value(n
) = nodelib_getlist(L
, 3);
4488 user_node_value(n
) = nodelib_getstring(L
, 3);
4491 user_node_value(n
) = nodelib_gettoks(L
, 3);
4494 user_node_value(n
) = (halfword
) lua_tointeger(L
, 3);
4498 return nodelib_cantset(L
, n
, s
);
4500 } else if (t
== pdf_annot_node
) {
4501 if (lua_key_eq(s
, width
)) {
4502 width(n
) = (halfword
) lua_tointeger(L
, 3);
4503 } else if (lua_key_eq(s
, depth
)) {
4504 depth(n
) = (halfword
) lua_tointeger(L
, 3);
4505 } else if (lua_key_eq(s
, height
)) {
4506 height(n
) = (halfword
) lua_tointeger(L
, 3);
4507 } else if (lua_key_eq(s
, objnum
)) {
4508 pdf_annot_objnum(n
) = (halfword
) lua_tointeger(L
, 3);
4509 } else if (lua_key_eq(s
, data
)) {
4510 pdf_annot_data(n
) = nodelib_gettoks(L
, 3);
4512 return nodelib_cantset(L
, n
, s
);
4514 } else if (t
== pdf_dest_node
) {
4515 if (lua_key_eq(s
, width
)) {
4516 width(n
) = (halfword
) lua_tointeger(L
, 3);
4517 } else if (lua_key_eq(s
, depth
)) {
4518 depth(n
) = (halfword
) lua_tointeger(L
, 3);
4519 } else if (lua_key_eq(s
, height
)) {
4520 height(n
) = (halfword
) lua_tointeger(L
, 3);
4521 } else if (lua_key_eq(s
, named_id
)) {
4522 pdf_dest_named_id(n
) = (quarterword
) lua_tointeger(L
, 3);
4523 } else if (lua_key_eq(s
, dest_id
)) {
4524 if (pdf_dest_named_id(n
) == 1) {
4525 pdf_dest_id(n
) = nodelib_gettoks(L
, 3);
4527 pdf_dest_id(n
) = (halfword
) lua_tointeger(L
, 3);
4529 } else if (lua_key_eq(s
, dest_type
)) {
4530 pdf_dest_type(n
) = (quarterword
) lua_tointeger(L
, 3);
4531 } else if (lua_key_eq(s
, xyz_zoom
)) {
4532 pdf_dest_xyz_zoom(n
) = (halfword
) lua_tointeger(L
, 3);
4533 } else if (lua_key_eq(s
, objnum
)) {
4534 pdf_dest_objnum(n
) = (halfword
) lua_tointeger(L
, 3);
4536 return nodelib_cantset(L
, n
, s
);
4538 } else if (t
== pdf_setmatrix_node
) {
4539 if (lua_key_eq(s
, data
)) {
4540 pdf_setmatrix_data(n
) = nodelib_gettoks(L
, 3);
4542 return nodelib_cantset(L
, n
, s
);
4544 } else if (t
== pdf_refobj_node
) {
4545 if (lua_key_eq(s
, objnum
)) {
4546 pdf_obj_objnum(n
) = (halfword
) lua_tointeger(L
, 3);
4548 return nodelib_cantset(L
, n
, s
);
4550 } else if (t
== pdf_refxform_node
) {
4551 if (lua_key_eq(s
, width
)) {
4552 width(n
) = (halfword
) lua_tointeger(L
, 3);
4553 } else if (lua_key_eq(s
, depth
)) {
4554 depth(n
) = (halfword
) lua_tointeger(L
, 3);
4555 } else if (lua_key_eq(s
, height
)) {
4556 height(n
) = (halfword
) lua_tointeger(L
, 3);
4557 } else if (lua_key_eq(s
, objnum
)) {
4558 pdf_xform_objnum(n
) = (halfword
) lua_tointeger(L
, 3);
4560 return nodelib_cantset(L
, n
, s
);
4562 } else if (t
== pdf_refximage_node
) {
4563 if (lua_key_eq(s
, width
)) {
4564 width(n
) = (halfword
) lua_tointeger(L
, 3);
4565 } else if (lua_key_eq(s
, depth
)) {
4566 depth(n
) = (halfword
) lua_tointeger(L
, 3);
4567 } else if (lua_key_eq(s
, height
)) {
4568 height(n
) = (halfword
) lua_tointeger(L
, 3);
4569 } else if (lua_key_eq(s
, transform
)) {
4570 pdf_ximage_transform(n
) = (halfword
) lua_tointeger(L
, 3);
4571 } else if (lua_key_eq(s
, index
)) {
4572 pdf_ximage_index(n
) = (halfword
) lua_tointeger(L
, 3);
4574 return nodelib_cantset(L
, n
, s
);
4576 } else if (t
== local_par_node
) {
4577 if (lua_key_eq(s
, pen_inter
)) {
4578 local_pen_inter(n
) = (halfword
) lua_tointeger(L
, 3);
4579 } else if (lua_key_eq(s
, pen_broken
)) {
4580 local_pen_broken(n
) = (halfword
) lua_tointeger(L
, 3);
4581 } else if (lua_key_eq(s
, dir
)) {
4582 local_par_dir(n
) = nodelib_getdir(L
, 3, 1);
4583 } else if (lua_key_eq(s
, box_left
)) {
4584 local_box_left(n
) = nodelib_getlist(L
, 3);
4585 } else if (lua_key_eq(s
, box_left_width
)) {
4586 local_box_left_width(n
) = (halfword
) lua_tointeger(L
, 3);
4587 } else if (lua_key_eq(s
, box_right
)) {
4588 local_box_right(n
) = nodelib_getlist(L
, 3);
4589 } else if (lua_key_eq(s
, box_right_width
)) {
4590 local_box_right_width(n
) = (halfword
) lua_tointeger(L
, 3);
4592 return nodelib_cantset(L
, n
, s
);
4594 } else if (t
== pdf_start_link_node
) {
4595 if (lua_key_eq(s
, width
)) {
4596 width(n
) = (halfword
) lua_tointeger(L
, 3);
4597 } else if (lua_key_eq(s
, depth
)) {
4598 depth(n
) = (halfword
) lua_tointeger(L
, 3);
4599 } else if (lua_key_eq(s
, height
)) {
4600 height(n
) = (halfword
) lua_tointeger(L
, 3);
4601 } else if (lua_key_eq(s
, objnum
)) {
4602 pdf_link_objnum(n
) = (halfword
) lua_tointeger(L
, 3);
4603 } else if (lua_key_eq(s
, link_attr
)) {
4604 pdf_link_attr(n
) = nodelib_gettoks(L
, 3);
4605 } else if (lua_key_eq(s
, action
)) {
4606 pdf_link_action(n
) = nodelib_getaction(L
, 3);
4608 return nodelib_cantset(L
, n
, s
);
4610 } else if (t
== write_node
) {
4611 if (lua_key_eq(s
, stream
)) {
4612 write_stream(n
) = (halfword
) lua_tointeger(L
, 3);
4613 } else if (lua_key_eq(s
, data
)) {
4614 write_tokens(n
) = nodelib_gettoks(L
, 3);
4616 return nodelib_cantset(L
, n
, s
);
4618 } else if (t
== pdf_colorstack_node
) {
4619 if (lua_key_eq(s
, stack
)) {
4620 pdf_colorstack_stack(n
) = (halfword
) lua_tointeger(L
, 3);
4621 } else if (lua_key_eq(s
, command
)) {
4622 pdf_colorstack_cmd(n
) = (halfword
) lua_tointeger(L
, 3);
4623 } else if (lua_key_eq(s
, data
)) {
4624 pdf_colorstack_data(n
) = nodelib_gettoks(L
, 3);
4626 return nodelib_cantset(L
, n
, s
);
4628 } else if ((t
== pdf_thread_node
) || (t
== pdf_start_thread_node
)) {
4629 if (lua_key_eq(s
, width
)) {
4630 width(n
) = (halfword
) lua_tointeger(L
, 3);
4631 } else if (lua_key_eq(s
, depth
)) {
4632 depth(n
) = (halfword
) lua_tointeger(L
, 3);
4633 } else if (lua_key_eq(s
, height
)) {
4634 height(n
) = (halfword
) lua_tointeger(L
, 3);
4635 } else if (lua_key_eq(s
, named_id
)) {
4636 pdf_thread_named_id(n
) = (quarterword
) lua_tointeger(L
, 3);
4637 } else if (lua_key_eq(s
, thread_id
)) {
4638 if (pdf_thread_named_id(n
) == 1) {
4639 pdf_thread_id(n
) = nodelib_gettoks(L
, 3);
4641 pdf_thread_id(n
) = (halfword
) lua_tointeger(L
, 3);
4643 } else if (lua_key_eq(s
, thread_attr
)) {
4644 pdf_thread_attr(n
) = nodelib_gettoks(L
, 3);
4646 return nodelib_cantset(L
, n
, s
);
4648 } else if (t
== special_node
) {
4649 if (lua_key_eq(s
, data
)) {
4650 write_tokens(n
) = nodelib_gettoks(L
, 3);
4652 return nodelib_cantset(L
, n
, s
);
4654 } else if (t
== open_node
) {
4655 if (lua_key_eq(s
, stream
)) {
4656 write_stream(n
) = (halfword
) lua_tointeger(L
, 3);
4657 } else if (lua_key_eq(s
, name
)) {
4658 open_name(n
) = nodelib_getstring(L
, 3);
4659 } else if (lua_key_eq(s
, area
)) {
4660 open_area(n
) = nodelib_getstring(L
, 3);
4661 } else if (lua_key_eq(s
, ext
)) {
4662 open_ext(n
) = nodelib_getstring(L
, 3);
4664 return nodelib_cantset(L
, n
, s
);
4666 } else if (t
== close_node
) {
4667 if (lua_key_eq(s
, stream
)) {
4668 write_stream(n
) = (halfword
) lua_tointeger(L
, 3);
4670 return nodelib_cantset(L
, n
, s
);
4672 } else if ((t
== pdf_end_link_node
) || (t
== pdf_end_thread_node
) || (t
== pdf_save_pos_node
) ||
4673 (t
== pdf_save_node
) || (t
== pdf_restore_node
) || (t
== cancel_boundary_node
)) {
4674 return nodelib_cantset(L
, n
, s
);
4681 static int lua_nodelib_fast_setfield(lua_State
* L
)
4687 n
= *((halfword
*) lua_touserdata(L
, 1));
4690 if (lua_type(L
, 2) == LUA_TNUMBER
) {
4694 if (lua_gettop(L
) == 3) {
4695 i
= (int) lua_tointeger(L
, 2);
4696 val
= (int) lua_tointeger(L
, 3);
4697 if (val
== UNUSED_ATTRIBUTE
) {
4698 (void) unset_attribute(n
, i
, val
);
4700 set_attribute(n
, i
, val
);
4703 luaL_error(L
, "incorrect number of arguments");
4708 s
= lua_tostring(L
, 2);
4710 /*if (lua_key_eq(s, id)) {
4711 type(n) = (quarteword) lua_tointeger(L, 3);
4713 if (lua_key_eq(s
, next
)) {
4714 halfword x
= nodelib_getlist(L
, 3);
4715 if (x
>0 && type(x
) == glue_spec_node
) {
4716 return luaL_error(L
, "You can't assign a %s node to a next field\n", node_data
[type(x
)].name
);
4719 } else if (lua_key_eq(s
, prev
)) {
4720 halfword x
= nodelib_getlist(L
, 3);
4721 if (x
>0 && type(x
) == glue_spec_node
) {
4722 return luaL_error(L
, "You can't assign a %s node to a prev field\n", node_data
[type(x
)].name
);
4725 } else if (lua_key_eq(s
, attr
)) {
4726 if (nodetype_has_attributes(type(n
))) {
4727 nodelib_setattr(L
, 3, n
);
4729 } else if (t
== glyph_node
) {
4730 if (lua_key_eq(s
, subtype
)) {
4731 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
4732 } else if (lua_key_eq(s
, font
)) {
4733 font(n
) = (halfword
) lua_tointeger(L
, 3);
4734 } else if (lua_key_eq(s
, char)) {
4735 character(n
) = (halfword
) lua_tointeger(L
, 3);
4736 } else if (lua_key_eq(s
, xoffset
)) {
4737 x_displace(n
) = (halfword
) lua_tointeger(L
, 3);
4738 } else if (lua_key_eq(s
, yoffset
)) {
4739 y_displace(n
) = (halfword
) lua_tointeger(L
, 3);
4740 } else if (lua_key_eq(s
, width
)) {
4742 } else if (lua_key_eq(s
, height
)) {
4744 } else if (lua_key_eq(s
, depth
)) {
4746 } else if (lua_key_eq(s
, expansion_factor
)) {
4747 ex_glyph(n
) = (halfword
) lua_tointeger(L
, 3);
4748 } else if (lua_key_eq(s
, components
)) {
4749 lig_ptr(n
) = nodelib_getlist(L
, 3);
4750 } else if (lua_key_eq(s
, lang
)) {
4751 set_char_lang(n
, (halfword
) lua_tointeger(L
, 3));
4752 } else if (lua_key_eq(s
, left
)) {
4753 set_char_lhmin(n
, (halfword
) lua_tointeger(L
, 3));
4754 } else if (lua_key_eq(s
, right
)) {
4755 set_char_rhmin(n
, (halfword
) lua_tointeger(L
, 3));
4756 } else if (lua_key_eq(s
, uchyph
)) {
4757 set_char_uchyph(n
, (halfword
) lua_tointeger(L
, 3));
4759 return nodelib_cantset(L
, n
, s
);
4761 } else if ((t
== hlist_node
) || (t
== vlist_node
)) {
4762 if (lua_key_eq(s
, subtype
)) {
4763 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
4764 } else if (lua_key_eq(s
, list
) || lua_key_eq(s
, head
)) {
4765 list_ptr(n
) = nodelib_getlist(L
, 3);
4766 } else if (lua_key_eq(s
, width
)) {
4767 width(n
) = (halfword
) lua_tointeger(L
, 3);
4768 } else if (lua_key_eq(s
, height
)) {
4769 height(n
) = (halfword
) lua_tointeger(L
, 3);
4770 } else if (lua_key_eq(s
, depth
)) {
4771 depth(n
) = (halfword
) lua_tointeger(L
, 3);
4772 } else if (lua_key_eq(s
, dir
)) {
4773 box_dir(n
) = nodelib_getdir(L
, 3, 1);
4774 } else if (lua_key_eq(s
, shift
)) {
4775 shift_amount(n
) = (halfword
) lua_tointeger(L
, 3);
4776 } else if (lua_key_eq(s
, glue_order
)) {
4777 glue_order(n
) = (quarterword
) lua_tointeger(L
, 3);
4778 } else if (lua_key_eq(s
, glue_sign
)) {
4779 glue_sign(n
) = (quarterword
) lua_tointeger(L
, 3);
4780 } else if (lua_key_eq(s
, glue_set
)) {
4781 glue_set(n
) = (glue_ratio
) lua_tonumber(L
, 3);
4783 return nodelib_cantset(L
, n
, s
);
4785 } else if (t
== disc_node
) {
4786 if (lua_key_eq(s
, subtype
)) {
4787 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
4788 } else if (lua_key_eq(s
, pre
)) {
4789 set_disc_field(pre_break(n
), nodelib_getlist(L
, 3));
4790 } else if (lua_key_eq(s
, post
)) {
4791 set_disc_field(post_break(n
), nodelib_getlist(L
, 3));
4792 } else if (lua_key_eq(s
, replace
)) {
4793 set_disc_field(no_break(n
), nodelib_getlist(L
, 3));
4795 return nodelib_cantset(L
, n
, s
);
4797 } else if (t
== glue_node
) {
4798 if (lua_key_eq(s
, subtype
)) {
4799 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
4800 } else if (lua_key_eq(s
, spec
)) {
4801 glue_ptr(n
) = nodelib_getspec(L
, 3);
4802 } else if (lua_key_eq(s
, leader
)) {
4803 leader_ptr(n
) = nodelib_getlist(L
, 3);
4805 return nodelib_cantset(L
, n
, s
);
4807 } else if (t
== glue_spec_node
) {
4808 if (lua_key_eq(s
, subtype
)) {
4809 subtype(n
) = (quarterword
) lua_tointeger(L
, 3); /* dummy, the only one that prevents move up */
4810 } else if (lua_key_eq(s
, width
)) {
4811 width(n
) = (halfword
) lua_tointeger(L
, 3);
4812 } else if (lua_key_eq(s
, stretch
)) {
4813 stretch(n
) = (halfword
) lua_tointeger(L
, 3);
4814 } else if (lua_key_eq(s
, shrink
)) {
4815 shrink(n
) = (halfword
) lua_tointeger(L
, 3);
4816 } else if (lua_key_eq(s
, stretch_order
)) {
4817 stretch_order(n
) = (quarterword
) lua_tointeger(L
, 3);
4818 } else if (lua_key_eq(s
, shrink_order
)) {
4819 shrink_order(n
) = (quarterword
) lua_tointeger(L
, 3);
4820 /* } else if (lua_key_eq(s, ref_count)) {
4821 glue_ref_count(n) = (halfword) lua_tointeger(L, 3);
4822 } else if (lua_key_eq(s, writable)) {
4826 return nodelib_cantset(L
, n
, s
);
4828 } else if (t
== kern_node
) {
4829 if (lua_key_eq(s
, subtype
)) {
4830 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
4831 } else if (lua_key_eq(s
, kern
)) {
4832 width(n
) = (halfword
) lua_tointeger(L
, 3);
4833 } else if (lua_key_eq(s
, expansion_factor
)) {
4834 ex_kern(n
) = (halfword
) lua_tointeger(L
, 3);
4836 return nodelib_cantset(L
, n
, s
);
4838 } else if (t
== penalty_node
) {
4839 if (lua_key_eq(s
, subtype
)) {
4841 } else if (lua_key_eq(s
, penalty
)) {
4842 penalty(n
) = (halfword
) lua_tointeger(L
, 3);
4844 return nodelib_cantset(L
, n
, s
);
4846 } else if (t
== rule_node
) {
4847 if (lua_key_eq(s
, subtype
)) {
4848 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
4849 } else if (lua_key_eq(s
, width
)) {
4850 width(n
) = (halfword
) lua_tointeger(L
, 3);
4851 } else if (lua_key_eq(s
, height
)) {
4852 height(n
) = (halfword
) lua_tointeger(L
, 3);
4853 } else if (lua_key_eq(s
, depth
)) {
4854 depth(n
) = (halfword
) lua_tointeger(L
, 3);
4855 } else if (lua_key_eq(s
, dir
)) {
4856 rule_dir(n
) = nodelib_getdir(L
, 3, 1);
4858 return nodelib_cantset(L
, n
, s
);
4860 } else if (t
== whatsit_node
) {
4861 if (lua_key_eq(s
, subtype
)) {
4862 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
4864 lua_nodelib_setfield_whatsit(L
, n
, s
);
4866 } else if (t
== simple_noad
) {
4867 if (lua_key_eq(s
, subtype
)) {
4868 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
4869 } else if (lua_key_eq(s
, nucleus
)) {
4870 nucleus(n
) = nodelib_getlist(L
, 3);
4871 } else if (lua_key_eq(s
, sub
)) {
4872 subscr(n
) = nodelib_getlist(L
, 3);
4873 } else if (lua_key_eq(s
, sup
)) {
4874 supscr(n
) = nodelib_getlist(L
, 3);
4876 return nodelib_cantset(L
, n
, s
);
4878 } else if ((t
== math_char_node
) || (t
== math_text_char_node
)) {
4879 if (lua_key_eq(s
, subtype
)) {
4880 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
4881 } else if (lua_key_eq(s
, fam
)) {
4882 math_fam(n
) = (halfword
) lua_tointeger(L
, 3);
4883 } else if (lua_key_eq(s
, char)) {
4884 math_character(n
) = (halfword
) lua_tointeger(L
, 3);
4886 return nodelib_cantset(L
, n
, s
);
4888 } else if (t
== mark_node
) {
4889 if (lua_key_eq(s
, subtype
)) {
4890 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
4891 } else if (lua_key_eq(s
, class)) {
4892 mark_class(n
) = (halfword
) lua_tointeger(L
, 3);
4893 } else if (lua_key_eq(s
, mark
)) {
4894 mark_ptr(n
) = nodelib_gettoks(L
, 3);
4896 return nodelib_cantset(L
, n
, s
);
4898 } else if (t
== ins_node
) {
4899 if (lua_key_eq(s
, subtype
)) {
4900 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
4901 } else if (lua_key_eq(s
, cost
)) {
4902 float_cost(n
) = (halfword
) lua_tointeger(L
, 3);
4903 } else if (lua_key_eq(s
, depth
)) {
4904 depth(n
) = (halfword
) lua_tointeger(L
, 3);
4905 } else if (lua_key_eq(s
, height
)) {
4906 height(n
) = (halfword
) lua_tointeger(L
, 3);
4907 } else if (lua_key_eq(s
, spec
)) {
4908 split_top_ptr(n
) = nodelib_getspec(L
, 3);
4909 } else if ((lua_key_eq(s
, list
)) || (lua_key_eq(s
, head
))) {
4910 ins_ptr(n
) = nodelib_getlist(L
, 3);
4912 return nodelib_cantset(L
, n
, s
);
4914 } else if (t
== math_node
) {
4915 if (lua_key_eq(s
, subtype
)) {
4916 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
4917 } else if (lua_key_eq(s
, surround
)) {
4918 surround(n
) = (halfword
) lua_tointeger(L
, 3);
4920 return nodelib_cantset(L
, n
, s
);
4922 } else if (t
== fraction_noad
) {
4923 if (lua_key_eq(s
, subtype
)) {
4924 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
4925 } else if (lua_key_eq(s
, width
)) {
4926 thickness(n
) = (halfword
) lua_tointeger(L
, 3);
4927 } else if (lua_key_eq(s
, num
)) {
4928 numerator(n
) = nodelib_getlist(L
, 3);
4929 } else if (lua_key_eq(s
, denom
)) {
4930 denominator(n
) = nodelib_getlist(L
, 3);
4931 } else if (lua_key_eq(s
, left
)) {
4932 left_delimiter(n
) = nodelib_getlist(L
, 3);
4933 } else if (lua_key_eq(s
, right
)) {
4934 right_delimiter(n
) = nodelib_getlist(L
, 3);
4936 return nodelib_cantset(L
, n
, s
);
4938 } else if (t
== style_node
) {
4939 if (lua_key_eq(s
, subtype
)) {
4941 } else if (lua_key_eq(s
, style
)) {
4942 assign_math_style(L
,3,subtype(n
));
4943 //subtype(n) = (quarterword) luaL_checkoption(L, 3, "text", math_style_names); /* not 2? */
4945 /* return nodelib_cantset(L, n, s); */
4947 } else if (t
== accent_noad
) {
4948 if (lua_key_eq(s
, subtype
)) {
4949 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
4950 } else if (lua_key_eq(s
, nucleus
)) {
4951 nucleus(n
) = nodelib_getlist(L
, 3);
4952 } else if (lua_key_eq(s
, sub
)) {
4953 subscr(n
) = nodelib_getlist(L
, 3);
4954 } else if (lua_key_eq(s
, sup
)) {
4955 supscr(n
) = nodelib_getlist(L
, 3);
4956 } else if (lua_key_eq(s
, accent
)) {
4957 accent_chr(n
) = nodelib_getlist(L
, 3);
4958 } else if (lua_key_eq(s
, bot_accent
)) {
4959 bot_accent_chr(n
) = nodelib_getlist(L
, 3);
4961 return nodelib_cantset(L
, n
, s
);
4963 } else if (t
== fence_noad
) {
4964 if (lua_key_eq(s
, subtype
)) {
4965 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
4966 } else if (lua_key_eq(s
, delim
)) {
4967 delimiter(n
) = nodelib_getlist(L
, 3);
4969 return nodelib_cantset(L
, n
, s
);
4971 } else if (t
== delim_node
) {
4972 if (lua_key_eq(s
, subtype
)) {
4973 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
4974 } else if (lua_key_eq(s
, small_fam
)) {
4975 small_fam(n
) = (halfword
) lua_tointeger(L
, 3);
4976 } else if (lua_key_eq(s
, small_char
)) {
4977 small_char(n
) = (halfword
) lua_tointeger(L
, 3);
4978 } else if (lua_key_eq(s
, large_fam
)) {
4979 large_fam(n
) = (halfword
) lua_tointeger(L
, 3);
4980 } else if (lua_key_eq(s
, large_char
)) {
4981 large_char(n
) = (halfword
) lua_tointeger(L
, 3);
4983 return nodelib_cantset(L
, n
, s
);
4985 } else if ((t
== sub_box_node
) || (t
== sub_mlist_node
)) {
4986 if (lua_key_eq(s
, subtype
)) {
4987 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
4988 } else if ((lua_key_eq(s
, list
)) || (lua_key_eq(s
, head
))){
4989 math_list(n
) = nodelib_getlist(L
, 3);
4991 return nodelib_cantset(L
, n
, s
);
4993 } else if (t
== radical_noad
) {
4994 if (lua_key_eq(s
, subtype
)) {
4995 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
4996 } else if (lua_key_eq(s
, nucleus
)) {
4997 nucleus(n
) = nodelib_getlist(L
, 3);
4998 } else if (lua_key_eq(s
, sub
)) {
4999 subscr(n
) = nodelib_getlist(L
, 3);
5000 } else if (lua_key_eq(s
, sup
)) {
5001 supscr(n
) = nodelib_getlist(L
, 3);
5002 } else if (lua_key_eq(s
, left
)) {
5003 left_delimiter(n
) = nodelib_getlist(L
, 3);
5004 } else if (lua_key_eq(s
, degree
)) {
5005 degree(n
) = nodelib_getlist(L
, 3);
5007 return nodelib_cantset(L
, n
, s
);
5009 } else if (t
== margin_kern_node
) {
5010 if (lua_key_eq(s
, subtype
)) {
5011 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5012 } else if (lua_key_eq(s
, width
)) {
5013 width(n
) = (halfword
) lua_tointeger(L
, 3);
5014 } else if (lua_key_eq(s
, glyph
)) {
5015 margin_char(n
) = nodelib_getlist(L
, 3);
5017 return nodelib_cantset(L
, n
, s
);
5019 } else if (t
== split_up_node
) {
5020 if (lua_key_eq(s
, subtype
)) {
5021 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5022 } else if (lua_key_eq(s
, last_ins_ptr
)) {
5023 last_ins_ptr(n
) = nodelib_getlist(L
, 3);
5024 } else if (lua_key_eq(s
, best_ins_ptr
)) {
5025 best_ins_ptr(n
) = nodelib_getlist(L
, 3);
5026 } else if (lua_key_eq(s
, broken_ptr
)) {
5027 broken_ptr(n
) = nodelib_getlist(L
, 3);
5028 } else if (lua_key_eq(s
, broken_ins
)) {
5029 broken_ins(n
) = nodelib_getlist(L
, 3);
5031 return nodelib_cantset(L
, n
, s
);
5033 } else if (t
== choice_node
) {
5034 if (lua_key_eq(s
, subtype
)) {
5035 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5036 } else if (lua_key_eq(s
, display
)) {
5037 display_mlist(n
) = nodelib_getlist(L
, 3);
5038 } else if (lua_key_eq(s
, text
)) {
5039 text_mlist(n
) = nodelib_getlist(L
, 3);
5040 } else if (lua_key_eq(s
, script
)) {
5041 script_mlist(n
) = nodelib_getlist(L
, 3);
5042 } else if (lua_key_eq(s
, scriptscript
)) {
5043 script_script_mlist(n
) = nodelib_getlist(L
, 3);
5045 return nodelib_cantset(L
, n
, s
);
5047 } else if (t
== inserting_node
) {
5048 if (lua_key_eq(s
, subtype
)) {
5049 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5050 } else if (lua_key_eq(s
, last_ins_ptr
)) {
5051 last_ins_ptr(n
) = nodelib_getlist(L
, 3);
5052 } else if (lua_key_eq(s
, best_ins_ptr
)) {
5053 best_ins_ptr(n
) = nodelib_getlist(L
, 3);
5055 return nodelib_cantset(L
, n
, s
);
5057 } else if (t
== attribute_node
) {
5058 if (lua_key_eq(s
, subtype
)) {
5060 } else if (lua_key_eq(s
, number
)) {
5061 attribute_id(n
) = (halfword
) lua_tointeger(L
, 3);
5062 } else if (lua_key_eq(s
, value
)) {
5063 attribute_value(n
) = (halfword
) lua_tointeger(L
, 3);
5065 return nodelib_cantset(L
, n
, s
);
5067 } else if (t
== adjust_node
) {
5068 if (lua_key_eq(s
, subtype
)) {
5069 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5070 } else if ((lua_key_eq(s
, list
)) || (lua_key_eq(s
, head
))) {
5071 adjust_ptr(n
) = nodelib_getlist(L
, 3);
5073 return nodelib_cantset(L
, n
, s
);
5075 } else if (t
== action_node
) {
5076 if (lua_key_eq(s
, subtype
)) {
5078 } else if (lua_key_eq(s
, action_type
)) {
5079 pdf_action_type(n
) = (quarterword
) lua_tointeger(L
, 3);
5080 } else if (lua_key_eq(s
, named_id
)) {
5081 pdf_action_named_id(n
) = (quarterword
) lua_tointeger(L
, 3);
5082 } else if (lua_key_eq(s
, action_id
)) {
5083 if (pdf_action_named_id(n
) == 1) {
5084 pdf_action_id(n
) = nodelib_gettoks(L
, 3);
5086 pdf_action_id(n
) = (halfword
) lua_tointeger(L
, 3);
5088 } else if (lua_key_eq(s
, file
)) {
5089 pdf_action_file(n
) = nodelib_gettoks(L
, 3);
5090 } else if (lua_key_eq(s
, new_window
)) {
5091 pdf_action_new_window(n
) = (halfword
) lua_tointeger(L
, 3);
5092 } else if (lua_key_eq(s
, data
)) {
5093 pdf_action_tokens(n
) = nodelib_gettoks(L
, 3);
5094 /* } else if (lua_key_eq(s, ref_count)) {
5095 pdf_action_refcount(n) = (halfword) lua_tointeger(L, 3); */
5097 return nodelib_cantset(L
, n
, s
);
5099 } else if (t
== unset_node
) {
5100 if (lua_key_eq(s
, subtype
)) {
5102 } else if (lua_key_eq(s
, width
)) {
5103 width(n
) = (halfword
) lua_tointeger(L
, 3);
5104 } else if (lua_key_eq(s
, height
)) {
5105 height(n
) = (halfword
) lua_tointeger(L
, 3);
5106 } else if (lua_key_eq(s
, depth
)) {
5107 depth(n
) = (halfword
) lua_tointeger(L
, 3);
5108 } else if (lua_key_eq(s
, dir
)) {
5109 box_dir(n
) = nodelib_getdir(L
, 3, 1);
5110 } else if (lua_key_eq(s
, shrink
)) {
5111 glue_shrink(n
) = (halfword
) lua_tointeger(L
, 3);
5112 } else if (lua_key_eq(s
, glue_order
)) {
5113 glue_order(n
) = (quarterword
) lua_tointeger(L
, 3);
5114 } else if (lua_key_eq(s
, glue_sign
)) {
5115 glue_sign(n
) = (quarterword
) lua_tointeger(L
, 3);
5116 } else if (lua_key_eq(s
, stretch
)) {
5117 glue_stretch(n
) = (halfword
) lua_tointeger(L
, 3);
5118 } else if (lua_key_eq(s
, count
)) {
5119 span_count(n
) = (quarterword
) lua_tointeger(L
, 3);
5120 } else if ((lua_key_eq(s
, list
)) || (lua_key_eq(s
, head
))){
5121 list_ptr(n
) = nodelib_getlist(L
, 3);
5123 return nodelib_cantset(L
, n
, s
);
5125 } else if (t
== attribute_list_node
) {
5126 if (lua_key_eq(s
, subtype
)) {
5129 return nodelib_cantset(L
, n
, s
);
5132 return luaL_error(L
, "You can't assign to this %s node (%d)\n", node_data
[t
].name
, n
);
5137 static int lua_nodelib_setfield(lua_State
* L
)
5139 /* [given-node] [...]*/
5140 halfword
*p
= lua_touserdata(L
, 1);
5141 if ( (p
== NULL
) || (! lua_getmetatable(L
,1)) ) {
5144 /* [given-node] [mt-given-node]*/
5145 lua_rawgeti(L
, LUA_REGISTRYINDEX
, luaS_index(luatex_node
));
5146 lua_gettable(L
, LUA_REGISTRYINDEX
);
5147 /* [given-node] [mt-given-node] [mt-node]*/
5148 if ( (!lua_rawequal(L
, -1, -2)) ) {
5151 /* prune stack and call getfield */
5153 return lua_nodelib_fast_setfield(L
);
5156 /* node.direct.setfield */
5158 static int lua_nodelib_direct_setfield_whatsit(lua_State
* L
, int n
, const char *s
)
5163 if (t
== dir_node
) {
5164 if (lua_key_eq(s
, dir
)) {
5165 dir_dir(n
) = nodelib_getdir(L
, 3, 0);
5166 } else if (lua_key_eq(s
, level
)) {
5167 dir_level(n
) = (halfword
) lua_tointeger(L
, 3);
5168 } else if (lua_key_eq(s
, dvi_ptr
)) {
5169 dir_dvi_ptr(n
) = (halfword
) lua_tointeger(L
, 3);
5170 } else if (lua_key_eq(s
, dir_h
)) {
5171 dir_dvi_h(n
) = (halfword
) lua_tointeger(L
, 3);
5173 return nodelib_cantset(L
, n
, s
);
5175 } else if (t
== pdf_literal_node
) {
5176 if (lua_key_eq(s
, mode
)) {
5177 pdf_literal_mode(n
) = (quarterword
) lua_tointeger(L
, 3);
5178 } else if (lua_key_eq(s
, data
)) {
5180 pdf_literal_data(n
) = nodelib_gettoks(L
, 3);
5182 lua_pushvalue(L
, 3);
5183 pdf_literal_data(n
) = luaL_ref(L
, LUA_REGISTRYINDEX
);
5184 pdf_literal_type(n
) = lua_refid_literal
;
5187 return nodelib_cantset(L
, n
, s
);
5189 } else if (t
== late_lua_node
) {
5190 if (lua_key_eq(s
, string
)) {
5191 cleanup_late_lua(n
) ; /* ls-hh */
5193 late_lua_data(n
) = nodelib_gettoks(L
, 3);
5194 late_lua_type(n
) = normal
;
5196 lua_pushvalue(L
, 3);
5197 late_lua_data(n
) = luaL_ref(L
, LUA_REGISTRYINDEX
);
5198 late_lua_type(n
) = lua_refid_literal
;
5200 } else if (lua_key_eq(s
, data
)) {
5201 cleanup_late_lua(n
) ; /* ls-hh */
5202 late_lua_data(n
) = nodelib_gettoks(L
, 3);
5203 late_lua_type(n
) = normal
;
5204 } else if (lua_key_eq(s
, name
)) {
5205 cleanup_late_lua_name(n
) ; /* ls-hh */
5206 late_lua_name(n
) = nodelib_gettoks(L
, 3);
5208 return nodelib_cantset(L
, n
, s
);
5210 } else if (t
== user_defined_node
) {
5211 if (lua_key_eq(s
, user_id
)) {
5212 user_node_id(n
) = (halfword
) lua_tointeger(L
, 3);
5213 } else if (lua_key_eq(s
, type
)) {
5214 user_node_type(n
) = (halfword
) lua_tointeger(L
, 3);
5215 } else if (lua_key_eq(s
, value
)) {
5216 switch (user_node_type(n
)) {
5218 user_node_value(n
) = nodelib_getlist(L
, 3);
5221 user_node_value(n
) = (halfword
) lua_tointeger(L
, 3);
5224 lua_pushvalue(L
, 3);
5225 if (user_node_value(n
) != 0) {
5226 luaL_unref(L
, LUA_REGISTRYINDEX
,user_node_value(n
));
5228 user_node_value(n
) = luaL_ref(L
, LUA_REGISTRYINDEX
);
5231 user_node_value(n
) = nodelib_getlist(L
, 3);
5234 user_node_value(n
) = nodelib_getstring(L
, 3);
5237 user_node_value(n
) = nodelib_gettoks(L
, 3);
5240 user_node_value(n
) = (halfword
) lua_tointeger(L
, 3);
5244 return nodelib_cantset(L
, n
, s
);
5246 } else if (t
== pdf_annot_node
) {
5247 if (lua_key_eq(s
, width
)) {
5248 width(n
) = (halfword
) lua_tointeger(L
, 3);
5249 } else if (lua_key_eq(s
, depth
)) {
5250 depth(n
) = (halfword
) lua_tointeger(L
, 3);
5251 } else if (lua_key_eq(s
, height
)) {
5252 height(n
) = (halfword
) lua_tointeger(L
, 3);
5253 } else if (lua_key_eq(s
, objnum
)) {
5254 pdf_annot_objnum(n
) = (halfword
) lua_tointeger(L
, 3);
5255 } else if (lua_key_eq(s
, data
)) {
5256 pdf_annot_data(n
) = nodelib_gettoks(L
, 3);
5258 return nodelib_cantset(L
, n
, s
);
5260 } else if (t
== pdf_dest_node
) {
5261 if (lua_key_eq(s
, width
)) {
5262 width(n
) = (halfword
) lua_tointeger(L
, 3);
5263 } else if (lua_key_eq(s
, depth
)) {
5264 depth(n
) = (halfword
) lua_tointeger(L
, 3);
5265 } else if (lua_key_eq(s
, height
)) {
5266 height(n
) = (halfword
) lua_tointeger(L
, 3);
5267 } else if (lua_key_eq(s
, named_id
)) {
5268 pdf_dest_named_id(n
) = (quarterword
) lua_tointeger(L
, 3);
5269 } else if (lua_key_eq(s
, dest_id
)) {
5270 if (pdf_dest_named_id(n
) == 1) {
5271 pdf_dest_id(n
) = nodelib_gettoks(L
, 3);
5273 pdf_dest_id(n
) = (halfword
) lua_tointeger(L
, 3);
5275 } else if (lua_key_eq(s
, dest_type
)) {
5276 pdf_dest_type(n
) = (quarterword
) lua_tointeger(L
, 3);
5277 } else if (lua_key_eq(s
, xyz_zoom
)) {
5278 pdf_dest_xyz_zoom(n
) = (halfword
) lua_tointeger(L
, 3);
5279 } else if (lua_key_eq(s
, objnum
)) {
5280 pdf_dest_objnum(n
) = (halfword
) lua_tointeger(L
, 3);
5282 return nodelib_cantset(L
, n
, s
);
5284 } else if (t
== pdf_setmatrix_node
) {
5285 if (lua_key_eq(s
, data
)) {
5286 pdf_setmatrix_data(n
) = nodelib_gettoks(L
, 3);
5288 return nodelib_cantset(L
, n
, s
);
5290 } else if (t
== pdf_refobj_node
) {
5291 if (lua_key_eq(s
, objnum
)) {
5292 pdf_obj_objnum(n
) = (halfword
) lua_tointeger(L
, 3);
5294 return nodelib_cantset(L
, n
, s
);
5296 } else if (t
== pdf_refxform_node
) {
5297 if (lua_key_eq(s
, width
)) {
5298 width(n
) = (halfword
) lua_tointeger(L
, 3);
5299 } else if (lua_key_eq(s
, depth
)) {
5300 depth(n
) = (halfword
) lua_tointeger(L
, 3);
5301 } else if (lua_key_eq(s
, height
)) {
5302 height(n
) = (halfword
) lua_tointeger(L
, 3);
5303 } else if (lua_key_eq(s
, objnum
)) {
5304 pdf_xform_objnum(n
) = (halfword
) lua_tointeger(L
, 3);
5306 return nodelib_cantset(L
, n
, s
);
5308 } else if (t
== pdf_refximage_node
) {
5309 if (lua_key_eq(s
, width
)) {
5310 width(n
) = (halfword
) lua_tointeger(L
, 3);
5311 } else if (lua_key_eq(s
, depth
)) {
5312 depth(n
) = (halfword
) lua_tointeger(L
, 3);
5313 } else if (lua_key_eq(s
, height
)) {
5314 height(n
) = (halfword
) lua_tointeger(L
, 3);
5315 } else if (lua_key_eq(s
, transform
)) {
5316 pdf_ximage_transform(n
) = (halfword
) lua_tointeger(L
, 3);
5317 } else if (lua_key_eq(s
, index
)) {
5318 pdf_ximage_index(n
) = (halfword
) lua_tointeger(L
, 3);
5320 return nodelib_cantset(L
, n
, s
);
5322 } else if (t
== local_par_node
) {
5323 if (lua_key_eq(s
, pen_inter
)) {
5324 local_pen_inter(n
) = (halfword
) lua_tointeger(L
, 3);
5325 } else if (lua_key_eq(s
, pen_broken
)) {
5326 local_pen_broken(n
) = (halfword
) lua_tointeger(L
, 3);
5327 } else if (lua_key_eq(s
, dir
)) {
5328 local_par_dir(n
) = nodelib_getdir(L
, 3, 1);
5329 } else if (lua_key_eq(s
, box_left
)) {
5330 local_box_left(n
) = nodelib_getlist(L
, 3);
5331 } else if (lua_key_eq(s
, box_left_width
)) {
5332 local_box_left_width(n
) = (halfword
) lua_tointeger(L
, 3);
5333 } else if (lua_key_eq(s
, box_right
)) {
5334 local_box_right(n
) = nodelib_getlist(L
, 3);
5335 } else if (lua_key_eq(s
, box_right_width
)) {
5336 local_box_right_width(n
) = (halfword
) lua_tointeger(L
, 3);
5338 return nodelib_cantset(L
, n
, s
);
5340 } else if (t
== pdf_start_link_node
) {
5341 if (lua_key_eq(s
, width
)) {
5342 width(n
) = (halfword
) lua_tointeger(L
, 3);
5343 } else if (lua_key_eq(s
, depth
)) {
5344 depth(n
) = (halfword
) lua_tointeger(L
, 3);
5345 } else if (lua_key_eq(s
, height
)) {
5346 height(n
) = (halfword
) lua_tointeger(L
, 3);
5347 } else if (lua_key_eq(s
, objnum
)) {
5348 pdf_link_objnum(n
) = (halfword
) lua_tointeger(L
, 3);
5349 } else if (lua_key_eq(s
, link_attr
)) {
5350 pdf_link_attr(n
) = nodelib_gettoks(L
, 3);
5351 } else if (lua_key_eq(s
, action
)) {
5352 pdf_link_action(n
) = nodelib_popdirect(n
); /*nodelib_getaction(L, 3);*/
5354 return nodelib_cantset(L
, n
, s
);
5356 } else if (t
== write_node
) {
5357 if (lua_key_eq(s
, stream
)) {
5358 write_stream(n
) = (halfword
) lua_tointeger(L
, 3);
5359 } else if (lua_key_eq(s
, data
)) {
5360 write_tokens(n
) = nodelib_gettoks(L
, 3);
5362 return nodelib_cantset(L
, n
, s
);
5364 } else if (t
== pdf_colorstack_node
) {
5365 if (lua_key_eq(s
, stack
)) {
5366 pdf_colorstack_stack(n
) = (halfword
) lua_tointeger(L
, 3);
5367 } else if (lua_key_eq(s
, command
)) {
5368 pdf_colorstack_cmd(n
) = (halfword
) lua_tointeger(L
, 3);
5369 } else if (lua_key_eq(s
, data
)) {
5370 pdf_colorstack_data(n
) = nodelib_gettoks(L
, 3);
5372 return nodelib_cantset(L
, n
, s
);
5374 } else if ((t
== pdf_thread_node
) || (t
== pdf_start_thread_node
)) {
5375 if (lua_key_eq(s
, width
)) {
5376 width(n
) = (halfword
) lua_tointeger(L
, 3);
5377 } else if (lua_key_eq(s
, depth
)) {
5378 depth(n
) = (halfword
) lua_tointeger(L
, 3);
5379 } else if (lua_key_eq(s
, height
)) {
5380 height(n
) = (halfword
) lua_tointeger(L
, 3);
5381 } else if (lua_key_eq(s
, named_id
)) {
5382 pdf_thread_named_id(n
) = (quarterword
) lua_tointeger(L
, 3);
5383 } else if (lua_key_eq(s
, thread_id
)) {
5384 if (pdf_thread_named_id(n
) == 1) {
5385 pdf_thread_id(n
) = nodelib_gettoks(L
, 3);
5387 pdf_thread_id(n
) = (halfword
) lua_tointeger(L
, 3);
5389 } else if (lua_key_eq(s
, thread_attr
)) {
5390 pdf_thread_attr(n
) = nodelib_gettoks(L
, 3);
5392 return nodelib_cantset(L
, n
, s
);
5394 } else if (t
== special_node
) {
5395 if (lua_key_eq(s
, data
)) {
5396 write_tokens(n
) = nodelib_gettoks(L
, 3);
5398 return nodelib_cantset(L
, n
, s
);
5400 } else if (t
== open_node
) {
5401 if (lua_key_eq(s
, stream
)) {
5402 write_stream(n
) = (halfword
) lua_tointeger(L
, 3);
5403 } else if (lua_key_eq(s
, name
)) {
5404 open_name(n
) = nodelib_getstring(L
, 3);
5405 } else if (lua_key_eq(s
, area
)) {
5406 open_area(n
) = nodelib_getstring(L
, 3);
5407 } else if (lua_key_eq(s
, ext
)) {
5408 open_ext(n
) = nodelib_getstring(L
, 3);
5410 return nodelib_cantset(L
, n
, s
);
5412 } else if (t
== close_node
) {
5413 if (lua_key_eq(s
, stream
)) {
5414 write_stream(n
) = (halfword
) lua_tointeger(L
, 3);
5416 return nodelib_cantset(L
, n
, s
);
5418 } else if ((t
== pdf_end_link_node
) || (t
== pdf_end_thread_node
) || (t
== pdf_save_pos_node
) ||
5419 (t
== pdf_save_node
) || (t
== pdf_restore_node
) || (t
== cancel_boundary_node
)) {
5420 return nodelib_cantset(L
, n
, s
);
5427 static int lua_nodelib_direct_setfield(lua_State
* L
)
5433 n
= (halfword
) lua_tonumber(L
, 1);
5436 if (lua_type(L
, 2) == LUA_TNUMBER
) {
5440 if (lua_gettop(L
) == 3) {
5441 i
= (int) lua_tointeger(L
, 2);
5442 val
= (int) lua_tointeger(L
, 3);
5443 if (val
== UNUSED_ATTRIBUTE
) {
5444 (void) unset_attribute(n
, i
, val
);
5446 set_attribute(n
, i
, val
);
5449 luaL_error(L
, "incorrect number of arguments");
5454 s
= lua_tostring(L
, 2);
5456 /*if (lua_key_eq(s, id)) {
5457 type(n) = (quarteword) lua_tointeger(L, 3);
5459 if (lua_key_eq(s
, next
)) {
5460 halfword x
= nodelib_popdirect(3);
5461 if (x
>0 && type(x
) == glue_spec_node
) {
5462 return luaL_error(L
, "You can't assign a %s node to a next field\n", node_data
[type(x
)].name
);
5465 } else if (lua_key_eq(s
, prev
)) {
5466 halfword x
= nodelib_popdirect(3);
5467 if (x
>0 && type(x
) == glue_spec_node
) {
5468 return luaL_error(L
, "You can't assign a %s node to a prev field\n", node_data
[type(x
)].name
);
5471 } else if (lua_key_eq(s
, attr
)) {
5472 if (nodetype_has_attributes(type(n
))) {
5473 nodelib_setattr(L
, 3, n
);
5475 } else if (t
== glyph_node
) {
5476 if (lua_key_eq(s
, subtype
)) {
5477 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5478 } else if (lua_key_eq(s
, font
)) {
5479 font(n
) = (halfword
) lua_tointeger(L
, 3);
5480 } else if (lua_key_eq(s
, char)) {
5481 character(n
) = (halfword
) lua_tointeger(L
, 3);
5482 } else if (lua_key_eq(s
, xoffset
)) {
5483 x_displace(n
) = (halfword
) lua_tointeger(L
, 3);
5484 } else if (lua_key_eq(s
, yoffset
)) {
5485 y_displace(n
) = (halfword
) lua_tointeger(L
, 3);
5486 } else if (lua_key_eq(s
, width
)) {
5488 } else if (lua_key_eq(s
, height
)) {
5490 } else if (lua_key_eq(s
, depth
)) {
5492 } else if (lua_key_eq(s
, expansion_factor
)) {
5493 ex_glyph(n
) = (halfword
) lua_tointeger(L
, 3);
5494 } else if (lua_key_eq(s
, components
)) {
5495 lig_ptr(n
) = nodelib_popdirect(3);
5496 } else if (lua_key_eq(s
, lang
)) {
5497 set_char_lang(n
, (halfword
) lua_tointeger(L
, 3));
5498 } else if (lua_key_eq(s
, left
)) {
5499 set_char_lhmin(n
, (halfword
) lua_tointeger(L
, 3));
5500 } else if (lua_key_eq(s
, right
)) {
5501 set_char_rhmin(n
, (halfword
) lua_tointeger(L
, 3));
5502 } else if (lua_key_eq(s
, uchyph
)) {
5503 set_char_uchyph(n
, (halfword
) lua_tointeger(L
, 3));
5505 return nodelib_cantset(L
, n
, s
);
5507 } else if ((t
== hlist_node
) || (t
== vlist_node
)) {
5508 if (lua_key_eq(s
, subtype
)) {
5509 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5510 } else if (lua_key_eq(s
, list
) || lua_key_eq(s
, head
)) {
5511 list_ptr(n
) = nodelib_popdirect(3);
5512 } else if (lua_key_eq(s
, width
)) {
5513 width(n
) = (halfword
) lua_tointeger(L
, 3);
5514 } else if (lua_key_eq(s
, height
)) {
5515 height(n
) = (halfword
) lua_tointeger(L
, 3);
5516 } else if (lua_key_eq(s
, depth
)) {
5517 depth(n
) = (halfword
) lua_tointeger(L
, 3);
5518 } else if (lua_key_eq(s
, dir
)) {
5519 box_dir(n
) = nodelib_getdir(L
, 3, 1);
5520 } else if (lua_key_eq(s
, shift
)) {
5521 shift_amount(n
) = (halfword
) lua_tointeger(L
, 3);
5522 } else if (lua_key_eq(s
, glue_order
)) {
5523 glue_order(n
) = (quarterword
) lua_tointeger(L
, 3);
5524 } else if (lua_key_eq(s
, glue_sign
)) {
5525 glue_sign(n
) = (quarterword
) lua_tointeger(L
, 3);
5526 } else if (lua_key_eq(s
, glue_set
)) {
5527 glue_set(n
) = (glue_ratio
) lua_tonumber(L
, 3);
5529 return nodelib_cantset(L
, n
, s
);
5531 } else if (t
== disc_node
) {
5532 if (lua_key_eq(s
, subtype
)) {
5533 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5534 } else if (lua_key_eq(s
, pre
)) {
5535 set_disc_field(pre_break(n
), nodelib_popdirect(3));
5536 } else if (lua_key_eq(s
, post
)) {
5537 set_disc_field(post_break(n
), nodelib_popdirect(3));
5538 } else if (lua_key_eq(s
, replace
)) {
5539 set_disc_field(no_break(n
), nodelib_popdirect(3));
5541 return nodelib_cantset(L
, n
, s
);
5543 } else if (t
== glue_node
) {
5544 if (lua_key_eq(s
, subtype
)) {
5545 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5546 } else if (lua_key_eq(s
, spec
)) {
5547 glue_ptr(n
) = nodelib_popdirect(3);
5548 } else if (lua_key_eq(s
, leader
)) {
5549 leader_ptr(n
) = nodelib_popdirect(3);
5551 return nodelib_cantset(L
, n
, s
);
5553 } else if (t
== glue_spec_node
) {
5554 if (lua_key_eq(s
, subtype
)) {
5555 subtype(n
) = (quarterword
) lua_tointeger(L
, 3); /* dummy, the only one that prevents move up */
5556 } else if (lua_key_eq(s
, width
)) {
5557 width(n
) = (halfword
) lua_tointeger(L
, 3);
5558 } else if (lua_key_eq(s
, stretch
)) {
5559 stretch(n
) = (halfword
) lua_tointeger(L
, 3);
5560 } else if (lua_key_eq(s
, shrink
)) {
5561 shrink(n
) = (halfword
) lua_tointeger(L
, 3);
5562 } else if (lua_key_eq(s
, stretch_order
)) {
5563 stretch_order(n
) = (quarterword
) lua_tointeger(L
, 3);
5564 } else if (lua_key_eq(s
, shrink_order
)) {
5565 shrink_order(n
) = (quarterword
) lua_tointeger(L
, 3);
5566 /* } else if (lua_key_eq(s, ref_count)) {
5567 glue_ref_count(n) = (halfword) lua_tointeger(L, 3);
5568 } else if (lua_key_eq(s, writable)) {
5571 return nodelib_cantset(L
, n
, s
);
5573 } else if (t
== kern_node
) {
5574 if (lua_key_eq(s
, subtype
)) {
5575 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5576 } else if (lua_key_eq(s
, kern
)) {
5577 width(n
) = (halfword
) lua_tointeger(L
, 3);
5578 } else if (lua_key_eq(s
, expansion_factor
)) {
5579 ex_kern(n
) = (halfword
) lua_tointeger(L
, 3);
5581 return nodelib_cantset(L
, n
, s
);
5583 } else if (t
== penalty_node
) {
5584 if (lua_key_eq(s
, subtype
)) {
5586 } else if (lua_key_eq(s
, penalty
)) {
5587 penalty(n
) = (halfword
) lua_tointeger(L
, 3);
5589 return nodelib_cantset(L
, n
, s
);
5591 } else if (t
== rule_node
) {
5592 if (lua_key_eq(s
, subtype
)) {
5593 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5594 } else if (lua_key_eq(s
, width
)) {
5595 width(n
) = (halfword
) lua_tointeger(L
, 3);
5596 } else if (lua_key_eq(s
, height
)) {
5597 height(n
) = (halfword
) lua_tointeger(L
, 3);
5598 } else if (lua_key_eq(s
, depth
)) {
5599 depth(n
) = (halfword
) lua_tointeger(L
, 3);
5600 } else if (lua_key_eq(s
, dir
)) {
5601 rule_dir(n
) = nodelib_getdir(L
, 3, 1);
5603 return nodelib_cantset(L
, n
, s
);
5605 } else if (t
== whatsit_node
) {
5606 if (lua_key_eq(s
, subtype
)) {
5607 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5609 lua_nodelib_direct_setfield_whatsit(L
, n
, s
);
5611 } else if (t
== simple_noad
) {
5612 if (lua_key_eq(s
, subtype
)) {
5613 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5614 } else if (lua_key_eq(s
, nucleus
)) {
5615 nucleus(n
) = nodelib_popdirect(3);
5616 } else if (lua_key_eq(s
, sub
)) {
5617 subscr(n
) = nodelib_popdirect(3);
5618 } else if (lua_key_eq(s
, sup
)) {
5619 supscr(n
) = nodelib_popdirect(3);
5621 return nodelib_cantset(L
, n
, s
);
5623 } else if ((t
== math_char_node
) || (t
== math_text_char_node
)) {
5624 if (lua_key_eq(s
, subtype
)) {
5625 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5626 } else if (lua_key_eq(s
, fam
)) {
5627 math_fam(n
) = (halfword
) lua_tointeger(L
, 3);
5628 } else if (lua_key_eq(s
, char)) {
5629 math_character(n
) = (halfword
) lua_tointeger(L
, 3);
5631 return nodelib_cantset(L
, n
, s
);
5633 } else if (t
== mark_node
) {
5634 if (lua_key_eq(s
, subtype
)) {
5635 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5636 } else if (lua_key_eq(s
, class)) {
5637 mark_class(n
) = (halfword
) lua_tointeger(L
, 3);
5638 } else if (lua_key_eq(s
, mark
)) {
5639 mark_ptr(n
) = nodelib_gettoks(L
, 3);
5641 return nodelib_cantset(L
, n
, s
);
5643 } else if (t
== ins_node
) {
5644 if (lua_key_eq(s
, subtype
)) {
5645 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5646 } else if (lua_key_eq(s
, cost
)) {
5647 float_cost(n
) = (halfword
) lua_tointeger(L
, 3);
5648 } else if (lua_key_eq(s
, depth
)) {
5649 depth(n
) = (halfword
) lua_tointeger(L
, 3);
5650 } else if (lua_key_eq(s
, height
)) {
5651 height(n
) = (halfword
) lua_tointeger(L
, 3);
5652 } else if (lua_key_eq(s
, spec
)) {
5653 split_top_ptr(n
) = nodelib_popdirect(3);
5654 } else if ((lua_key_eq(s
, list
)) || (lua_key_eq(s
, head
))) {
5655 ins_ptr(n
) = nodelib_popdirect(3);
5657 return nodelib_cantset(L
, n
, s
);
5659 } else if (t
== math_node
) {
5660 if (lua_key_eq(s
, subtype
)) {
5661 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5662 } else if (lua_key_eq(s
, surround
)) {
5663 surround(n
) = (halfword
) lua_tointeger(L
, 3);
5665 return nodelib_cantset(L
, n
, s
);
5667 } else if (t
== fraction_noad
) {
5668 if (lua_key_eq(s
, subtype
)) {
5669 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5670 } else if (lua_key_eq(s
, width
)) {
5671 thickness(n
) = (halfword
) lua_tointeger(L
, 3);
5672 } else if (lua_key_eq(s
, num
)) {
5673 numerator(n
) = nodelib_popdirect(3);
5674 } else if (lua_key_eq(s
, denom
)) {
5675 denominator(n
) = nodelib_popdirect(3);
5676 } else if (lua_key_eq(s
, left
)) {
5677 left_delimiter(n
) = nodelib_popdirect(3);
5678 } else if (lua_key_eq(s
, right
)) {
5679 right_delimiter(n
) = nodelib_popdirect(3);
5681 return nodelib_cantset(L
, n
, s
);
5683 } else if (t
== style_node
) {
5684 if (lua_key_eq(s
, subtype
)) {
5686 } else if (lua_key_eq(s
, style
)) {
5687 assign_math_style(L
,2,subtype(n
));
5688 //subtype(n) = (quarterword) luaL_checkoption(L, 2, "text", math_style_names); /* was 3 */
5690 /* return nodelib_cantset(L, n, s); */
5692 } else if (t
== accent_noad
) {
5693 if (lua_key_eq(s
, subtype
)) {
5694 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5695 } else if (lua_key_eq(s
, nucleus
)) {
5696 nucleus(n
) = nodelib_popdirect(3);
5697 } else if (lua_key_eq(s
, sub
)) {
5698 subscr(n
) = nodelib_popdirect(3);
5699 } else if (lua_key_eq(s
, sup
)) {
5700 supscr(n
) = nodelib_popdirect(3);
5701 } else if (lua_key_eq(s
, accent
)) {
5702 accent_chr(n
) = nodelib_popdirect(3);
5703 } else if (lua_key_eq(s
, bot_accent
)) {
5704 bot_accent_chr(n
) = nodelib_popdirect(3);
5706 return nodelib_cantset(L
, n
, s
);
5708 } else if (t
== fence_noad
) {
5709 if (lua_key_eq(s
, subtype
)) {
5710 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5711 } else if (lua_key_eq(s
, delim
)) {
5712 delimiter(n
) = nodelib_popdirect(3);
5714 return nodelib_cantset(L
, n
, s
);
5716 } else if (t
== delim_node
) {
5717 if (lua_key_eq(s
, subtype
)) {
5718 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5719 } else if (lua_key_eq(s
, small_fam
)) {
5720 small_fam(n
) = (halfword
) lua_tointeger(L
, 3);
5721 } else if (lua_key_eq(s
, small_char
)) {
5722 small_char(n
) = (halfword
) lua_tointeger(L
, 3);
5723 } else if (lua_key_eq(s
, large_fam
)) {
5724 large_fam(n
) = (halfword
) lua_tointeger(L
, 3);
5725 } else if (lua_key_eq(s
, large_char
)) {
5726 large_char(n
) = (halfword
) lua_tointeger(L
, 3);
5728 return nodelib_cantset(L
, n
, s
);
5730 } else if ((t
== sub_box_node
) || (t
== sub_mlist_node
)) {
5731 if (lua_key_eq(s
, subtype
)) {
5732 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5733 } else if ((lua_key_eq(s
, list
)) || (lua_key_eq(s
, head
))){
5734 math_list(n
) = nodelib_popdirect(3);
5736 return nodelib_cantset(L
, n
, s
);
5738 } else if (t
== radical_noad
) {
5739 if (lua_key_eq(s
, subtype
)) {
5740 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5741 } else if (lua_key_eq(s
, nucleus
)) {
5742 nucleus(n
) = nodelib_popdirect(3);
5743 } else if (lua_key_eq(s
, sub
)) {
5744 subscr(n
) = nodelib_popdirect(3);
5745 } else if (lua_key_eq(s
, sup
)) {
5746 supscr(n
) = nodelib_popdirect(3);
5747 } else if (lua_key_eq(s
, left
)) {
5748 left_delimiter(n
) = nodelib_popdirect(3);
5749 } else if (lua_key_eq(s
, degree
)) {
5750 degree(n
) = nodelib_popdirect(3);
5752 return nodelib_cantset(L
, n
, s
);
5754 } else if (t
== margin_kern_node
) {
5755 if (lua_key_eq(s
, subtype
)) {
5756 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5757 } else if (lua_key_eq(s
, width
)) {
5758 width(n
) = (halfword
) lua_tointeger(L
, 3);
5759 } else if (lua_key_eq(s
, glyph
)) {
5760 margin_char(n
) = nodelib_popdirect(3);
5762 return nodelib_cantset(L
, n
, s
);
5764 } else if (t
== split_up_node
) {
5765 if (lua_key_eq(s
, subtype
)) {
5766 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5767 } else if (lua_key_eq(s
, last_ins_ptr
)) {
5768 last_ins_ptr(n
) = nodelib_popdirect(3);
5769 } else if (lua_key_eq(s
, best_ins_ptr
)) {
5770 best_ins_ptr(n
) = nodelib_popdirect(3);
5771 } else if (lua_key_eq(s
, broken_ptr
)) {
5772 broken_ptr(n
) = nodelib_popdirect(3);
5773 } else if (lua_key_eq(s
, broken_ins
)) {
5774 broken_ins(n
) = nodelib_popdirect(3);
5776 return nodelib_cantset(L
, n
, s
);
5778 } else if (t
== choice_node
) {
5779 if (lua_key_eq(s
, subtype
)) {
5780 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5781 } else if (lua_key_eq(s
, display
)) {
5782 display_mlist(n
) = nodelib_popdirect(3);
5783 } else if (lua_key_eq(s
, text
)) {
5784 text_mlist(n
) = nodelib_popdirect(3);
5785 } else if (lua_key_eq(s
, script
)) {
5786 script_mlist(n
) = nodelib_popdirect(3);
5787 } else if (lua_key_eq(s
, scriptscript
)) {
5788 script_script_mlist(n
) = nodelib_popdirect(3);
5790 return nodelib_cantset(L
, n
, s
);
5792 } else if (t
== inserting_node
) {
5793 if (lua_key_eq(s
, subtype
)) {
5794 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5795 } else if (lua_key_eq(s
, last_ins_ptr
)) {
5796 last_ins_ptr(n
) = nodelib_popdirect(3);
5797 } else if (lua_key_eq(s
, best_ins_ptr
)) {
5798 best_ins_ptr(n
) = nodelib_popdirect(3);
5800 return nodelib_cantset(L
, n
, s
);
5802 } else if (t
== attribute_node
) {
5803 if (lua_key_eq(s
, subtype
)) {
5805 } else if (lua_key_eq(s
, number
)) {
5806 attribute_id(n
) = (halfword
) lua_tointeger(L
, 3);
5807 } else if (lua_key_eq(s
, value
)) {
5808 attribute_value(n
) = (halfword
) lua_tointeger(L
, 3);
5810 return nodelib_cantset(L
, n
, s
);
5812 } else if (t
== adjust_node
) {
5813 if (lua_key_eq(s
, subtype
)) {
5814 subtype(n
) = (quarterword
) lua_tointeger(L
, 3);
5815 } else if ((lua_key_eq(s
, list
)) || (lua_key_eq(s
, head
))) {
5816 adjust_ptr(n
) = nodelib_popdirect(3);
5818 return nodelib_cantset(L
, n
, s
);
5820 } else if (t
== action_node
) {
5821 if (lua_key_eq(s
, subtype
)) {
5823 } else if (lua_key_eq(s
, action_type
)) {
5824 pdf_action_type(n
) = (quarterword
) lua_tointeger(L
, 3);
5825 } else if (lua_key_eq(s
, named_id
)) {
5826 pdf_action_named_id(n
) = (quarterword
) lua_tointeger(L
, 3);
5827 } else if (lua_key_eq(s
, action_id
)) {
5828 if (pdf_action_named_id(n
) == 1) {
5829 pdf_action_id(n
) = nodelib_gettoks(L
, 3);
5831 pdf_action_id(n
) = (halfword
) lua_tointeger(L
, 3);
5833 } else if (lua_key_eq(s
, file
)) {
5834 pdf_action_file(n
) = nodelib_gettoks(L
, 3);
5835 } else if (lua_key_eq(s
, new_window
)) {
5836 pdf_action_new_window(n
) = (halfword
) lua_tointeger(L
, 3);
5837 } else if (lua_key_eq(s
, data
)) {
5838 pdf_action_tokens(n
) = nodelib_gettoks(L
, 3);
5839 /* } else if (lua_key_eq(s, ref_count)) {
5840 pdf_action_refcount(n) = (halfword) lua_tointeger(L, 3); */
5842 return nodelib_cantset(L
, n
, s
);
5844 } else if (t
== unset_node
) {
5845 if (lua_key_eq(s
, subtype
)) {
5847 } else if (lua_key_eq(s
, width
)) {
5848 width(n
) = (halfword
) lua_tointeger(L
, 3);
5849 } else if (lua_key_eq(s
, height
)) {
5850 height(n
) = (halfword
) lua_tointeger(L
, 3);
5851 } else if (lua_key_eq(s
, depth
)) {
5852 depth(n
) = (halfword
) lua_tointeger(L
, 3);
5853 } else if (lua_key_eq(s
, dir
)) {
5854 box_dir(n
) = nodelib_getdir(L
, 3, 1);
5855 } else if (lua_key_eq(s
, shrink
)) {
5856 glue_shrink(n
) = (halfword
) lua_tointeger(L
, 3);
5857 } else if (lua_key_eq(s
, glue_order
)) {
5858 glue_order(n
) = (quarterword
) lua_tointeger(L
, 3);
5859 } else if (lua_key_eq(s
, glue_sign
)) {
5860 glue_sign(n
) = (quarterword
) lua_tointeger(L
, 3);
5861 } else if (lua_key_eq(s
, stretch
)) {
5862 glue_stretch(n
) = (halfword
) lua_tointeger(L
, 3);
5863 } else if (lua_key_eq(s
, count
)) {
5864 span_count(n
) = (quarterword
) lua_tointeger(L
, 3);
5865 } else if ((lua_key_eq(s
, list
)) || (lua_key_eq(s
, head
))){
5866 list_ptr(n
) = nodelib_popdirect(3);
5868 return nodelib_cantset(L
, n
, s
);
5870 } else if (t
== attribute_list_node
) {
5871 if (lua_key_eq(s
, subtype
)) {
5874 return nodelib_cantset(L
, n
, s
);
5877 return luaL_error(L
, "You can't assign to this %s node (%d)\n", node_data
[t
].name
, n
);
5884 static int direct_get_box_id(lua_State
* L
, int i
)
5887 int cur_cs1
, cur_cmd1
;
5890 switch (lua_type(L
, i
)) {
5892 s
= lua_tolstring(L
, i
, &k
);
5893 cur_cs1
= string_lookup(s
, k
);
5894 cur_cmd1
= eq_type(cur_cs1
);
5895 if (cur_cmd1
== char_given_cmd
||
5896 cur_cmd1
== math_given_cmd
) {
5901 j
=(int)lua_tonumber(L
, (i
));
5904 luaL_error(L
, "argument must be a string or a number");
5905 j
= -1; /* not a valid box id */
5910 /* node.getbox = tex.getbox */
5912 /* node.direct.getbox */
5914 static int lua_nodelib_direct_getbox(lua_State
* L
)
5917 k
= direct_get_box_id(L
, -1);
5918 direct_check_index_range(k
, "getbox");
5919 t
= get_tex_box_register(k
);
5920 lua_pushnumber(L
, t
);
5924 static int direct_vsetbox(lua_State
* L
, int is_global
)
5927 int save_global_defs
= int_par(global_defs_code
);
5929 int_par(global_defs_code
) = 1;
5930 k
= direct_get_box_id(L
, -2);
5931 direct_check_index_range(k
, "setbox");
5932 if (lua_isboolean(L
, -1)) {
5933 j
= lua_toboolean(L
, -1);
5939 j
=nodelib_popdirect(-1);
5940 if (j
!= null
&& type(j
) != hlist_node
&& type(j
) != vlist_node
) {
5941 luaL_error(L
, "setbox: incompatible node type (%s)\n",get_node_name(type(j
), subtype(j
)));
5946 err
= set_tex_box_register(k
, j
);
5947 int_par(global_defs_code
) = save_global_defs
;
5949 luaL_error(L
, "incorrect value");
5954 /* node.setbox = tex.setbox */
5957 static int lua_nodelib_direct_setbox(lua_State
* L
)
5960 int n
= lua_gettop(L
);
5961 if (n
== 3 && lua_isstring(L
, 1)) {
5962 const char *s
= lua_tostring(L
, 1);
5963 if (lua_key_eq(s
, global
))
5966 return direct_vsetbox(L
, isglobal
);
5969 /* node.is_node(n) */
5971 static int lua_nodelib_is_node(lua_State
* L
)
5973 if (maybe_isnode(L
,1) == NULL
)
5974 lua_pushboolean(L
,0);
5976 lua_pushboolean(L
,1);
5980 /* node.direct.is_direct(n) (handy for mixed usage testing) */
5982 static int lua_nodelib_direct_is_direct(lua_State
* L
)
5984 quick and dirty and faster than not node.is_node, this helper
5985 returns false or <direct>
5988 if (lua_type(L,1) == LUA_TNUMBER)
5989 lua_pushboolean(L,1);
5991 lua_pushboolean(L,0);
5993 if (lua_type(L
,1) != LUA_TNUMBER
)
5994 lua_pushboolean(L
,0);
5995 /* else return direct */
5999 /* node.direct.is_node(n) (handy for mixed usage testing) */
6001 static int lua_nodelib_direct_is_node(lua_State
* L
)
6003 quick and dirty, only checks userdata, node.is_node is slower but
6004 more exact, this helper returns false or <node>
6007 halfword *n = lua_touserdata(L, 1);
6009 lua_pushboolean(L,1);
6011 lua_pushboolean(L,0);
6014 if (maybe_isnode(L
,1) == NULL
)
6015 lua_pushboolean(L
,0);
6016 /* else assume and return node */
6022 static const struct luaL_Reg fast_nodelib_f[] = {
6023 {"getid", lua_nodelib_fast_getid},
6024 {"getsubtype", lua_nodelib_fast_getsubtype},
6025 {"getfont", lua_nodelib_fast_getfont},
6026 {"getchar", lua_nodelib_fast_getcharacter},
6027 {"getnext", lua_nodelib_fast_getnext},
6028 {"getprev", lua_nodelib_fast_getprev},
6029 {"getfield", lua_nodelib_fast_getfield},
6030 {"setfield", lua_nodelib_fast_setfield},
6036 /* if really needed we can provide this:
6038 static int lua_nodelib_attributes_to_table(lua_State * L) // hh
6041 register halfword attribute;
6042 if (lua_isnumber(L,1)) {
6043 n = lua_tonumber(L,1);
6045 n = *((halfword *) lua_touserdata(L, 1));
6047 if ((n == null) || (! nodetype_has_attributes(type(n)))) {
6050 attribute = node_attr(n);
6051 if (attribute == null || (attribute == cache_disabled)) {
6054 if (! lua_istable(L,2)) {
6057 while (attribute != null) {
6058 lua_pushnumber(L,(int)attribute_id(attribute));
6059 lua_pushnumber(L,(int)attribute_value(attribute));
6061 attribute = vlink(attribute) ;
6070 /* There is no gain here but let's keep it around:
6072 static int lua_nodelib_attributes_to_properties(lua_State * L)
6075 register halfword attribute;
6076 if (lua_isnumber(L,1)) {
6077 n = lua_tonumber(L,1);
6079 n = *((halfword *) lua_touserdata(L, 1));
6085 lua_rawgeti(L, LUA_REGISTRYINDEX, luaS_index(node_properties));
6086 lua_gettable(L, LUA_REGISTRYINDEX);
6088 lua_rawseti(L, -1, luaS_index(attributes));
6090 if (! nodetype_has_attributes(type(n))) {
6093 attribute = node_attr(n);
6094 if (attribute == null || (attribute == cache_disabled)) {
6097 while (attribute != null) {
6098 lua_pushnumber(L,(int)attribute_id(attribute));
6099 lua_pushnumber(L,(int)attribute_value(attribute));
6101 attribute = vlink(attribute) ;
6113 /* Beware, enabling and disabling can result in an inconsistent properties table
6114 but it might make sense sometimes. Of course by default we have disabled this
6115 mechanism. And, one can always sweep the table empty. */
6117 static int lua_nodelib_properties_set_mode(lua_State
* L
) /* hh */
6119 if (lua_isboolean(L
,1)) {
6120 lua_properties_enabled
= lua_toboolean(L
,1);
6122 if (lua_isboolean(L
,2)) {
6123 lua_properties_use_metatable
= lua_toboolean(L
,2);
6128 /* We used to have variants in assigned defaults but they made no sense. */
6130 static int lua_nodelib_properties_flush_table(lua_State
* L
) /* hh */
6131 { /* <node|direct> <number> */
6132 lua_rawgeti(L
, LUA_REGISTRYINDEX
, lua_key_index(node_properties
));
6133 lua_gettable(L
, LUA_REGISTRYINDEX
);
6134 lua_pushnil(L
); /* initializes lua_next */
6135 while (lua_next(L
,-2) != 0) {
6136 lua_pushvalue(L
,-2);
6144 /* maybe we should allocate a proper index 0..var_mem_max but not now */
6146 static int lua_nodelib_get_property(lua_State
* L
) /* hh */
6149 n
= *((halfword
*) lua_touserdata(L
, 1));
6153 lua_rawgeti(L
, LUA_REGISTRYINDEX
, lua_key_index(node_properties
));
6154 lua_gettable(L
, LUA_REGISTRYINDEX
);
6155 lua_rawgeti(L
,-1,n
);
6160 static int lua_nodelib_direct_get_property(lua_State
* L
) /* hh */
6162 halfword n
= lua_tonumber(L
, 1);
6166 lua_rawgeti(L
, LUA_REGISTRYINDEX
, lua_key_index(node_properties
));
6167 lua_gettable(L
, LUA_REGISTRYINDEX
);
6168 lua_rawgeti(L
,-1,n
);
6173 static int lua_nodelib_set_property(lua_State
* L
) /* hh */
6175 /* <node> <value> */
6177 n
= *((halfword
*) lua_touserdata(L
, 1));
6180 lua_rawgeti(L
, LUA_REGISTRYINDEX
, lua_key_index(node_properties
));
6181 lua_gettable(L
, LUA_REGISTRYINDEX
);
6182 /* <node> <value> <propertytable> */
6184 /* <propertytable> <value> */
6185 lua_rawseti(L
,-2,n
);
6190 static int lua_nodelib_direct_set_property(lua_State
* L
) /* hh */
6192 /* <direct> <value> */
6193 halfword n
= lua_tonumber(L
, 1);
6194 if (n
!= null
) { // we could store in node instead */
6196 lua_rawgeti(L
, LUA_REGISTRYINDEX
, lua_key_index(node_properties
));
6197 lua_gettable(L
, LUA_REGISTRYINDEX
);
6198 /* <node> <value> <propertytable> */
6200 /* <propertytable> <value> */
6206 static int lua_nodelib_direct_properties_get_table(lua_State
* L
) /* hh */
6207 { /* <node|direct> */
6208 lua_rawgeti(L
, LUA_REGISTRYINDEX
, lua_key_index(node_properties
));
6209 lua_gettable(L
, LUA_REGISTRYINDEX
);
6213 static int lua_nodelib_properties_get_table(lua_State
* L
) /* hh */
6214 { /* <node|direct> */
6215 lua_rawgeti(L
, LUA_REGISTRYINDEX
, lua_key_index(node_properties_indirect
));
6216 lua_gettable(L
, LUA_REGISTRYINDEX
);
6222 static int lua_nodelib_get_property_t(lua_State
* L
) /* hh */
6223 { /* <table> <node> */
6225 n
= *((halfword
*) lua_touserdata(L
, 2));
6234 static int lua_nodelib_set_property_t(lua_State
* L
) /* hh */
6236 /* <table> <node> <value> */
6238 n
= *((halfword
*) lua_touserdata(L
, 2));
6246 static const struct luaL_Reg nodelib_p
[] = {
6247 {"__index", lua_nodelib_get_property_t
},
6248 {"__newindex", lua_nodelib_set_property_t
},
6249 {NULL
, NULL
} /* sentinel */
6252 static void lua_new_properties_table(lua_State
* L
) /* hh */
6254 lua_pushstring(L
,"node.properties");
6256 lua_settable(L
,LUA_REGISTRYINDEX
);
6258 lua_pushstring(L
,"node.properties.indirect");
6260 luaL_newmetatable(L
,"node.properties.indirect.meta");
6261 luaL_register(L
, NULL
, nodelib_p
);
6262 lua_setmetatable(L
,-2);
6263 lua_settable(L
,LUA_REGISTRYINDEX
);
6266 /* end of properties experiment */
6270 static const struct luaL_Reg direct_nodelib_f
[] = {
6271 {"copy", lua_nodelib_direct_copy
},
6272 {"copy_list", lua_nodelib_direct_copy_list
},
6273 {"count", lua_nodelib_direct_count
},
6274 {"current_attr", lua_nodelib_direct_currentattr
},
6275 {"dimensions", lua_nodelib_direct_dimensions
},
6276 {"do_ligature_n", lua_nodelib_direct_do_ligature_n
},
6277 {"end_of_math", lua_nodelib_direct_end_of_math
},
6278 /* {"family_font", lua_nodelib_mfont}, */ /* no node argument */
6279 /* {"fields", lua_nodelib_fields}, */ /* no node argument */
6280 /* {"first_character", lua_nodelib_first_character}, */ /* obsolete */
6281 {"first_glyph", lua_nodelib_direct_first_glyph
},
6282 {"flush_list", lua_nodelib_direct_flush_list
},
6283 {"flush_node", lua_nodelib_direct_flush_node
},
6284 {"free", lua_nodelib_direct_free
},
6285 {"getbox", lua_nodelib_direct_getbox
},
6286 {"getchar", lua_nodelib_direct_getcharacter
},
6287 {"getfield", lua_nodelib_direct_getfield
},
6288 {"getfont", lua_nodelib_direct_getfont
},
6289 {"getid", lua_nodelib_direct_getid
},
6290 {"getnext", lua_nodelib_direct_getnext
},
6291 {"getprev", lua_nodelib_direct_getprev
},
6292 {"getlist", lua_nodelib_direct_getlist
},
6293 {"getleader", lua_nodelib_direct_getleader
},
6294 {"getsubtype", lua_nodelib_direct_getsubtype
},
6295 {"has_glyph", lua_nodelib_direct_has_glyph
},
6296 {"has_attribute", lua_nodelib_direct_has_attribute
},
6297 {"has_field", lua_nodelib_direct_has_field
},
6298 {"hpack", lua_nodelib_direct_hpack
},
6299 /* {"id", lua_nodelib_id}, */ /* no node argument */
6300 {"insert_after", lua_nodelib_direct_insert_after
},
6301 {"insert_before", lua_nodelib_direct_insert_before
},
6302 {"is_direct", lua_nodelib_direct_is_direct
},
6303 {"is_node", lua_nodelib_direct_is_node
},
6304 /* {"kerning", font_tex_kerning}, */ /* maybe direct too (rather basic callback exposure) */
6305 {"last_node", lua_nodelib_direct_last_node
},
6306 {"length", lua_nodelib_direct_length
},
6307 /* {"ligaturing", font_tex_ligaturing}, */ /* maybe direct too (rather basic callback exposure) */
6308 /* {"mlist_to_hlist", lua_nodelib_mlist_to_hset_properties_modelist}, */ /* maybe direct too (rather basic callback exposure) */
6309 {"new", lua_nodelib_direct_new
},
6310 /* {"next", lua_nodelib_next}, */ /* replaced by getnext */
6311 /* {"prev", lua_nodelib_prev}, */ /* replaced by getprev */
6312 {"tostring", lua_nodelib_direct_tostring
},
6313 {"protect_glyphs", lua_nodelib_direct_protect_glyphs
},
6314 {"protrusion_skippable", lua_nodelib_direct_cp_skipable
},
6315 {"remove", lua_nodelib_direct_remove
},
6316 {"set_attribute", lua_nodelib_direct_set_attribute
},
6317 {"setbox", lua_nodelib_direct_setbox
},
6318 {"setfield", lua_nodelib_direct_setfield
},
6319 {"slide", lua_nodelib_direct_slide
},
6320 /* {"subtype", lua_nodelib_subtype}, */ /* no node argument */
6321 {"tail", lua_nodelib_direct_tail
},
6322 {"todirect", lua_nodelib_direct_todirect
}, /* not in node.* */
6323 {"tonode", lua_nodelib_direct_tonode
}, /* similar to node.* */
6324 {"traverse", lua_nodelib_direct_traverse
},
6325 {"traverse_id", lua_nodelib_direct_traverse_filtered
},
6326 /* {"type", lua_nodelib_type}, */ /* no node argument */
6327 /* {"types", lua_nodelib_types}, */ /* no node argument */
6328 {"unprotect_glyphs", lua_nodelib_direct_unprotect_glyphs
},
6329 {"unset_attribute", lua_nodelib_direct_unset_attribute
},
6330 {"usedlist", lua_nodelib_direct_usedlist
},
6331 {"vpack", lua_nodelib_direct_vpack
},
6332 /* {"whatsits", lua_nodelib_whatsits}, */ /* no node argument */
6333 {"write", lua_nodelib_direct_append
},
6335 /* {"attributes_to_table",lua_nodelib_attributes_to_table}, */ /* hh experiment */
6337 {"set_properties_mode",lua_nodelib_properties_set_mode
}, /* hh experiment */
6338 {"flush_properties_table",lua_nodelib_properties_flush_table
}, /* hh experiment */
6339 {"get_properties_table",lua_nodelib_direct_properties_get_table
}, /* hh experiment */
6340 {"getproperty", lua_nodelib_direct_get_property
}, /* bonus */ /* hh experiment */
6341 {"setproperty", lua_nodelib_direct_set_property
}, /* bonus */ /* hh experiment */
6343 {NULL
, NULL
} /* sentinel */
6348 static const struct luaL_Reg nodelib_f
[] = {
6349 {"copy", lua_nodelib_copy
},
6350 {"copy_list", lua_nodelib_copy_list
},
6351 {"count", lua_nodelib_count
},
6352 {"current_attr", lua_nodelib_currentattr
},
6353 {"dimensions", lua_nodelib_dimensions
},
6354 {"do_ligature_n", lua_nodelib_do_ligature_n
},
6355 {"end_of_math", lua_nodelib_end_of_math
},
6356 {"family_font", lua_nodelib_mfont
},
6357 {"fields", lua_nodelib_fields
},
6358 {"first_character", lua_nodelib_first_character
},
6359 {"first_glyph", lua_nodelib_first_glyph
},
6360 {"flush_list", lua_nodelib_flush_list
},
6361 {"flush_node", lua_nodelib_flush_node
},
6362 {"free", lua_nodelib_free
},
6363 /* {"getbox", lua_nodelib_getbox}, */ /* tex.getbox */
6364 {"getnext", lua_nodelib_getnext
},
6365 {"getprev", lua_nodelib_getprev
},
6366 {"getlist", lua_nodelib_getlist
},
6367 {"getleader", lua_nodelib_getleader
},
6368 {"getid", lua_nodelib_getid
},
6369 {"getfield", lua_nodelib_getfield
},
6370 {"setfield", lua_nodelib_setfield
},
6371 {"getsubtype", lua_nodelib_getsubtype
},
6372 {"getfont", lua_nodelib_getfont
},
6373 {"getchar", lua_nodelib_getcharacter
},
6374 {"has_glyph", lua_nodelib_has_glyph
},
6375 {"has_attribute", lua_nodelib_has_attribute
},
6376 {"has_field", lua_nodelib_has_field
},
6377 {"hpack", lua_nodelib_hpack
},
6378 {"id", lua_nodelib_id
},
6379 {"insert_after", lua_nodelib_insert_after
},
6380 {"insert_before", lua_nodelib_insert_before
},
6381 {"is_node", lua_nodelib_is_node
},
6382 {"kerning", font_tex_kerning
},
6383 {"last_node", lua_nodelib_last_node
},
6384 {"length", lua_nodelib_length
},
6385 {"ligaturing", font_tex_ligaturing
},
6386 {"mlist_to_hlist", lua_nodelib_mlist_to_hlist
},
6387 {"new", lua_nodelib_new
},
6388 {"next", lua_nodelib_next
}, /* getnext is somewhat more efficient, and get* fits better in direct compatibility */
6389 {"prev", lua_nodelib_prev
}, /* getprev is somewhat more efficient, and get* fits better in direct compatibility */
6390 {"tostring", lua_nodelib_tostring
},
6391 {"protect_glyphs", lua_nodelib_protect_glyphs
},
6392 {"protrusion_skippable", lua_nodelib_cp_skipable
},
6393 {"remove", lua_nodelib_remove
},
6394 /* {"setbox", lua_nodelib_setbox}, */ /* tex.setbox */
6395 {"set_attribute", lua_nodelib_set_attribute
},
6396 {"slide", lua_nodelib_slide
},
6397 {"subtype", lua_nodelib_subtype
},
6398 {"tail", lua_nodelib_tail
},
6399 {"traverse", lua_nodelib_traverse
},
6400 {"traverse_id", lua_nodelib_traverse_filtered
},
6401 {"type", lua_nodelib_type
},
6402 {"types", lua_nodelib_types
},
6403 {"unprotect_glyphs", lua_nodelib_unprotect_glyphs
},
6404 {"unset_attribute", lua_nodelib_unset_attribute
},
6405 {"usedlist", lua_nodelib_usedlist
},
6406 {"vpack", lua_nodelib_vpack
},
6407 {"whatsits", lua_nodelib_whatsits
},
6408 {"write", lua_nodelib_append
},
6410 /* {"attributes_to_table",lua_nodelib_attributes_to_table}, */ /* hh experiment */
6412 {"set_properties_mode",lua_nodelib_properties_set_mode
}, /* hh experiment */
6413 {"flush_properties_table",lua_nodelib_properties_flush_table
}, /* hh experiment */
6414 {"get_properties_table",lua_nodelib_properties_get_table
}, /* bonus */ /* hh experiment */
6415 {"getproperty", lua_nodelib_get_property
}, /* hh experiment */
6416 {"setproperty", lua_nodelib_set_property
}, /* hh experiment */
6418 {NULL
, NULL
} /* sentinel */
6421 static const struct luaL_Reg nodelib_m
[] = {
6422 {"__index", lua_nodelib_fast_getfield
},
6423 {"__newindex", lua_nodelib_fast_setfield
},
6424 {"__tostring", lua_nodelib_tostring
},
6425 {"__eq", lua_nodelib_equal
},
6426 {NULL
, NULL
} /* sentinel */
6429 int luaopen_node(lua_State
* L
)
6432 lua_new_properties_table(L
);
6434 /* the main metatable of node userdata */
6435 luaL_newmetatable(L
, NODE_METATABLE
);
6437 luaL_register(L
, NULL
, nodelib_m
);
6438 luaL_register(L
, "node", nodelib_f
);
6439 /* node.fast (experimental code)
6440 lua_pushstring(L,"fast");
6442 luaL_register(L, NULL, fast_nodelib_f);
6446 lua_pushstring(L
,"direct");
6448 luaL_register(L
, NULL
, direct_nodelib_f
);
6450 /* initialization of keywords */
6451 /*initialize_luaS_indexes(L);*/
6455 void nodelist_to_lua(lua_State
* L
, int n
)
6457 lua_pushnumber(L
, n
);
6458 lua_nodelib_push(L
);
6461 int nodelist_from_lua(lua_State
* L
)
6464 if (lua_isnil(L
, -1))
6466 n
= check_isnode(L
, -1);
6467 return (n
? *n
: null
);