Hi,
the function node.get_properties_table returns a tabe which does not
contain the actual node properties and also doesn't allow setting the
node properties.
See for example
\directlua{
node.set_properties_mode(true, true)
}
\directlua{
local indirectprops = node.get_properties_table()
local directprops = node.direct.get_properties_table()
local n = node.new'glue' % Type doesn't really matter
local p = {}
node.setproperty(n, p)
assert(node.getproperty(n) == p, "Assert failed: getproperty after setproperty") % works fine
local directn = node.direct.todirect(n)
assert(node.direct.getproperty(directn) == p, "Assert failed: direct.getproperty after setproperty") % works fine
assert(directprops[directn] == p, "Assert failed: direct.get_properties_table after setproperty") % works fine
assert(indirectprops[n] == p, "Assert failed: get_properties_table after setproperty") % This breaks
node.free(n)
}
\bye
Here a property is set using node.setproperty and then we try to access
it through different methods. All of them work, except for
node.get_properties_table because this uses a different table which is
unrelated to the actual property table returned by e.g.
node.direct.get_properties_table. This issue appear because the
metatable __index and __newindex functions for node.get_properties_table
set the property in the table passed as first parameter, which is the
(non-direct) node.get_properties_table table instead of
node.direct.get_properties_table().
Here is a possible fix which passes the actual property table as upvalue
to the metafunctions:
---
source/texk/web2c/luatexdir/lua/lnodelib.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/source/texk/web2c/luatexdir/lua/lnodelib.c b/source/texk/web2c/luatexdir/lua/lnodelib.c
index d5ab00a55..4e713aaa2 100644
--- a/source/texk/web2c/luatexdir/lua/lnodelib.c
+++ b/source/texk/web2c/luatexdir/lua/lnodelib.c
@@ -8406,7 +8406,7 @@ static int lua_nodelib_get_property_t(lua_State * L)
if (n == null) {
lua_pushnil(L);
} else {
- lua_rawgeti(L,1,n);
+ lua_rawgeti(L,lua_upvalueindex(1),n);
}
return 1;
}
@@ -8417,7 +8417,7 @@ static int lua_nodelib_set_property_t(lua_State * L)
halfword n = *((halfword *) lua_touserdata(L, 2));
if (n != null) {
lua_settop(L,3);
- lua_rawseti(L,1,n);
+ lua_rawseti(L,lua_upvalueindex(1),n);
}
return 0;
}
@@ -8831,16 +8831,19 @@ static const struct luaL_Reg nodelib_p[] = {
static void lua_new_properties_table(lua_State * L)
{
- lua_pushstring(L,"node.properties");
lua_newtable(L);
+ lua_pushstring(L,"node.properties");
+ lua_pushvalue(L,-2);
lua_settable(L,LUA_REGISTRYINDEX);
lua_pushstring(L,"node.properties.indirect");
lua_newtable(L);
luaL_newmetatable(L,"node.properties.indirect.meta");
- luaL_openlib(L, NULL, nodelib_p, 0);
+ lua_pushvalue(L,-4);
+ luaL_openlib(L, NULL, nodelib_p, 1);
lua_setmetatable(L,-2);
lua_settable(L,LUA_REGISTRYINDEX);
+ lua_pop(L,1);
}
/* node.direct.* */
--
2.26.0
Best regards,
Marcel