Hi list,
I've been playing around with some of the Lua callbacks in LuaMetaTeX,
and I have a few questions/comments.
Context: I'm writing a Plain/LaTeX/ConTeXt module called
"lua-widow-control" that uses Lua callbacks to automatically remove
widows and orphans from documents. The relevant Lua code is at:
https://github.com/gucci-on-fleek/lua-widow-control/blob/master/source/lua-widow-control.lua
in case you're curious about how I'm using these callbacks, but you
shouldn't need to look there since this email is self-contained.
1. In LMTX, calling "tex.linebreak" produces a
luatex warning > tex: left parfill skip is gone
warning. I don't get this warning in Plain LuaTeX, LuaLaTeX, or MkIV,
so I think that it's specific to LuaMetaTeX. The LuaMetaTeX manual
hardly mentions "left parfill skip"/"parfillleftskip", so I'm not too
sure what to do to avoid this warning.
You can reproduce the warning with this code (but any call to
"tex.linebreak" also works):
\startluacode
function test(head)
tex.linebreak(node.copylist(head))
return head
end
nodes.tasks.appendaction("processors", "after", "test")
\stopluacode
\starttext
Hello!
\stoptext
2. The LuaMetaTeX manual says that "pre_linebreak_filter" is called
after the parfillskip glue has been added, but this doesn't seem to
be the case. With LuaLaTeX/Plain LuaTeX, this is true, but the node
list passed to the callback in MkXL is missing the parfillskip. (I
don't have an MkIV installation to test here.)
This MkXL code:
\startluacode
function test(head)
local last = node.slide(head)
print "START"
for i=1,3 do
print(last)
print(
node.type(last.id),
node.subtypes(last.id)[last.subtype],
last.width,
last.stretchorder,
last.stretch
)
last = last.prev
end
print "STOP"
return head
end
nodes.tasks.appendaction("processors", "after", "test")
\stopluacode
\starttext
Hello!
\stoptext
produces:
START
<node : 2521 <= 2258 => nil : glue spaceskip>
glue spaceskip 341648 0 384354
<node : 2509 <= 2521 => 2258 : glyph unset>
glyph nil 213792 nil nil
<node : 2497 <= 2509 => 2521 : glyph unset>
glyph nil 385140 nil nil
STOP
START
<node : 2611 <= 2357 => nil : glue userskip>
glue userskip 0 2 65536
<node : 2274 <= 2611 => 2357 : glyph unset>
glyph nil 385140 nil nil
<node : 2239 <= 2274 => 2611 : rule strut>
rule strut 0 nil nil
STOP
while this (presumably) equivalent Plain LuaTeX code:
\directlua{
function test(head)
local last = node.slide(head)
print "START"
for i=1,3 do
print(last)
print(
node.type(last.id),
node.subtypes(last.id)[last.subtype],
last.width,
last.stretch_order,
last.stretch
)
last = last.prev
end
print "STOP"
return head
end
callback.register("pre_linebreak_filter", test)
}
Hello!
\bye
produces:
START
<node 82 < 298 > nil : glue 15>
glue parfillskip 0 2 65536
<node 291 < 82 > 298 : penalty 2>
penalty linepenalty nil nil nil
<node 284 < 291 > 82 : glyph 0>
glyph unset 182045 nil nil
STOP
I'm not sure if this is a doc bug, an engine bug, or if I'm just
doing something wrong.
3. The LuaTeX/LuaMetaTeX engine manuals say that for node callbacks, you
can return "true" if you don't need to replace the passed node list.
This works fine with raw LuaTeX callbacks and the luatexbase
wrappers, but it doesn't work with the ConTeXt "nodes.tasks" wrapper
functions.
This Plain example works:
\directlua{
callback.register("pre_linebreak_filter", function ()
return true
end)
}
Hello!
\bye
But this MkXL example doesn't:
\startluacode
function test(head)
return true
end
nodes.tasks.appendaction("processors", "after", "test")
\stopluacode
\starttext
Hello!
\stoptext
I'm not sure if this behaviour is expected or not. Saving the node
passed to the callback then returning it at the end works just fine,
but being able to just return "true" would be slightly more
convenient sometimes.
4. Would it be possible to add a ConTeXt-level interface ("nodes.tasks")
to the "pre_output_filter" callback? Right now I'm using the
low-level engine interface ("callback.register"), but this is pretty
fragile since any format update could block this. Plus, it would be
more convenient for me if I could register all of the callbacks the
same way. The way I'm doing it right now seems to work well enough
though, so this doesn't matter too much.
5. Off-topic, but is there a good way to trace node memory leaks?
Documents larger than ~1600 pages run out of node memory when I load
lua-widow-control, so I know that I'm leaking nodes somewhere, but
it's pretty tricky to trace. Are there any "tricks" to find leaked
nodes, or do I just need to watch my allocations very carefully?
Sorry if any of these points don't make much sense or have already been
answered elsewhere.
Thanks in advance.
-- Max
Versions used for test documents:
ConTeXt ver: 2022.04.20 19:18 LMTX fmt: 2022.5.1 int: english/english
This is LuaTeX, Version 1.13.2 (TeX Live 2021/W32TeX)
___________________________________________________________________________________
If your question is of interest to others as well, please add an entry to the
Wiki!
maillist : ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context
webpage : http://www.pragma-ade.nl / http://context.aanhet.net
archive : https://bitbucket.org/phg/context-mirror/commits/
wiki : http://contextgarden.net
___________________________________________________________________________________