Closed poetaman closed 3 years ago
Thank you for your excellent bug report! I read your post on Stackoverflow and all answers very carefully. I’m afraid, but I will need some extra tutoring, how to access the properties of copied nodes using metatables __index ...
If you were to access each property one by one (by name), then you don't need to anything special. In your code you are trying to iterate over whole properties table (and rightly so) using pairs()
, thats where it doesn't really do anything if values are actually in metatable associated with properties table (instead of being in properties table itself). Replacing the definition of function template.table_inline(table)
in your nodetree.lua
with the following code will resolve the problem. The only change made to your current definition of template.table_inline(table)
is the addition of expression table = getAllData(table)
before you iterate over the key, value pairs of table
. As you can see in the definition of function getAllData
, all it does is merge the values of key, value pairs of table
with its metatable.
function template.table_inline(table)
local tex_escape = ''
if options.channel == 'tex' then
tex_escape = '\\'
end
if type(table) == 'table' then
table = getAllData(table)
local output = tex_escape .. '{'
local kv_list = ''
for key, value in pairs(table) do
if type(key) ~= 'numbers' then
key = '\'' ..
template.colored_string(key, 'cyan', 'dim') .. '\''
end
kv_list = kv_list .. '[' .. key .. '] = ' ..
template.table_inline(value) .. ', '
end
output = output .. kv_list:gsub(', $', '')
return output .. tex_escape .. '}'
else
return tostring(table)
end
end
--- Merge key-value pairs from metatable into table.
--
-- Source: https://stackoverflow.com/a/5639667
-- Works if __index returns table, which it should as per luatex manual
--
-- @tparam t table
-- @tparam prevData table
--
-- @treturn table. Merged table
function getAllData(t, prevData)
-- if prevData == nil, start empty, otherwise start with prevData
local data = prevData or {}
-- copy all the attributes from t
for k,v in pairs(t) do
data[k] = data[k] or v
end
-- get t's metatable, or exit if not existing
local mt = getmetatable(t)
if type(mt)~='table' then return data end
-- get the __index from mt, or exit if not table
local index = mt.__index
if type(index)~='table' then return data end
-- include the data from index into data, recursively, and return
return getAllData(index, data)
end
Thank you very much! Would you be so kind and review the latest master branch.
@Josef-Friedrich You are welcome :) Thanks for the fix. I confirm that the issue reported in this bug is now fixed with your last commit.
Hi Josef,
Nodetree doesn't print the node properties table if properties reside in metatable. Properties will reside in a metatable if nodes were copied using an operation like box copy: (
\copy
) . LuaTeX manual states this: "If the second argument of set_properties_mode is true then a metatable approach is chosen: the copy gets its own table with the original table as metatable. If you use the generic font loader the mode is enabled that way." As a minimal test example (to observe this issue), please run the following code twice (there are NOTEs to comment/uncomment some lines of code for 2nd run). I have posted this as a question on TeX.SE hereExcerpt from 1st run (properties for nodes from original box, this is fine):
Excerpt from 2st run (properties for nodes from copied box, this isn't most useful as properties are not listed):