Jonathan Sauer wrote:
Hello,
in the following PlainTeX example, I try to access all \hboxes created by TeX by using the hpack_filter callback:
--------------------------------------------------------------- [deleted] ---------------------------------------------------------------
Why does the filter not get called more often, namely once for every line in the output file?
It only gets called for explicit hboxing (that is an optimization, but it is really needed). The manual should be clearer on this, sorry about that. The hpack_filter is not the right callback, at least not for now. I could make a dedicated callback for line packaging, maybe? It is possible to get the "prepared paragraph" using the "post_linebreak_filter", but then you have a bit of work to do. Here is the code: \directlua0{ callback.register('post_linebreak_filter', function(head) % head is the alternating list of hboxes and glues etc. for i in node.traverse_id('hlist',head) do if i.next == nil then % last line has no next v = node.hpack(i.list,'natural') print (v.width / 65535) % next two lines prevent memory leaks v.list = nil node.free(v) end end return true end) } If you want to be 'perfect', you should copy i.list to and remove the last glue(s) from the copy before hpacking() it: the final glue(s) may have a non-zero natural width.
Which leads me to another question: When having a \hbox node list, how to I determine the horizontal (when typesetting horizontally) resp. vertical (when typesetting vertically) position of a node relative to the left/top edge of the \hbox? I would think that after line breaking, each node should know this position, but how do I access it?
Using the function above, you can calculate the position within a paragraph by adding up the various widths and heights and depths. Exact positions are trickier: Nothing is certain until after \output, so using the normal position primitives (\pdfsavepos, \pdflastxpos etc) or \latelua0 {print(pdf.h)} and a two-pass approach is probably easier to deal with. Best wishes, Taco