[luatex] The node returned by node.traverse().

Paul Isambert zappathustra at free.fr
Thu Feb 16 07:24:07 CET 2012


luigi scarso <luigi.scarso at gmail.com> a écrit:
> 
> On Wed, Feb 15, 2012 at 2:44 PM, Paul Isambert <zappathustra at free.fr> wrote:
> > luigi scarso <luigi.scarso at gmail.com> a écrit:
> >>
> >> On Wed, Feb 15, 2012 at 9:02 AM, Paul Isambert <zappathustra at free.fr> wrote:
> >> > Hello there,
> >> >
> >> > I have a problem with the identity, so to speak, of nodes returned by
> >> > node.traverse(); I don't know if I'm missing something (perhaps related
> >> > to Lua rather than LuaTeX) or what. The following code should illustrate
> >> > the problem (I do not bother with breaks since there is only one node in
> >> > the list and one entry in the table):
> >> >
> >> > %%%%%%%%%%%
> >> > \setbox0=\hbox{a}
> >> >
> >> > \directlua{
> >> >  local head = tex.box[0].head
> >> >  local t = { [head] = true }
> >> >  for n in node.traverse(head) do
> >> >    texio.write_nl(tostring(t[n]))
> >> >    texio.write_nl(tostring(n == head))
> >> >    for a in pairs(t) do
> >> >      if a == n then
> >> >        texio.write_nl("They match!")
> >> >      end
> >> >    end
> >> >  end
> >> > }
> >> The key of t is head,  and head is a userdata.
> >>
> >>  n==head is managed by __eq(n,head)  handler so can happen that
> >> __eq(n,head) is true based on some considerations of n and head.
> >>
> >> On the other side rawequal(n,head) gives false
> >> so n and head have not the same identity (can be a different address,
> >> but we don't have a
> >> way to print addresses in Lua).
> >> With
> >> local head_copy = head
> >> rawequal(head_copy,head)
> >> gives true , i.e head_copy and head have the same identity.
> >> (and of course head_copy == head  is true )
> >>
> >> As far I know, keys are based on  identities, so t[n] and t[head] differs.
> >
> > Thank you Luigi; I'd thought about metatable magic but I hadn't considered
> > rawequal to make sure.
> >
> > Now I should recast the question: why are "head" an "n" different? I
> > suppose the answer of course is: because node.traverse() doesn't really
> > return the node, but then what does it return and why?
> >
> > Best,
> > Paul
> >
> another pointer to the same object, but for  the key its address is
> used, not the content
> so we avoid collisions:

[...]

The C parlance eludes me, as you know, but reworded in Lua: "head" and
"head1" do not even point to the same userdata:

%%%%
\setbox0=\hbox{a}

\directlua{%
  local head = tex.box[0].head
  local head1 = tex.box[0].head
  getmetatable(head).__tostring = nil
  print(head, head1)
}

\bye
%%%%

This prints "userdata: 0x27521b8	userdata: 0x27520f8". Unfortunately,
there is no __WhenUsedAsIndex metamethod that would make "Table[head]"
equal to "Table[head1]". So I guess the only way to really get the
identity of a node (regardless of its prev and next) is something like

local function NodeNumber (n)
  return tostring(n):match("<%s+(%d+)%s+>")
end

which can then be used as an index, under the assumption that node
numbers are never reused.

Thank you Luigi,
Paul



More information about the luatex mailing list