Recalculating tail of the list in ligaturing callback
Dear list, Running the following one-liner: \directlua{callback.register('ligaturing', node.ligaturing)}ffi\bye results in: ------------------------------------------- This is LuaTeX, Version 1.09.0 (TeX Live 2019/dev/Debian) restricted system commands enabled. **\directlua{callback.register('ligaturing', node.ligaturing)}ffi\bye ! error: (linebreak): invalid list tail, probably missing glue ! ==> Fatal error occurred, no output PDF file produced! ------------------------------------------- The problem seems to be that, when restoring the original ‘tail of the list’ after applying the ligaturing callback (in this case consisting of the parfillskip glue), it is appended to the tail of the /original/ list-to-be-ligatured. The latter, of course, has been lost if the paragraph ends in a ligature. According to the manual, the first node of the list passed to the callback is guaranteed not to be a glyph_node. Should the same not hold for the last one, too? The manual states that it ‘normally’ is a glue, but that is clearly not the case here. Best, Esger
On 11/14/2018 12:47 PM, Esger Renkema wrote:
Dear list,
Running the following one-liner:
\directlua{callback.register('ligaturing', node.ligaturing)}ffi\bye
results in:
------------------------------------------- This is LuaTeX, Version 1.09.0 (TeX Live 2019/dev/Debian) restricted system commands enabled. **\directlua{callback.register('ligaturing', node.ligaturing)}ffi\bye ! error: (linebreak): invalid list tail, probably missing glue ! ==> Fatal error occurred, no output PDF file produced! -------------------------------------------
The problem seems to be that, when restoring the original ‘tail of the list’ after applying the ligaturing callback (in this case consisting of the parfillskip glue), it is appended to the tail of the /original/ list-to-be-ligatured. The latter, of course, has been lost if the paragraph ends in a ligature.
the user of a callback is responsible for returning the right result you can locate the for your case proper end node and pass that one as second argument
According to the manual, the first node of the list passed to the callback is guaranteed not to be a glyph_node. Should the same not hold for the last one, too? The manual states that it ‘normally’ is a glue, but that is clearly not the case here. contextual ligature building can be influences by glue nodes (i.e. spaces) so the whole list gets passed
we're not going to add overhead for checking the result Hans ----------------------------------------------------------------- Hans Hagen | PRAGMA ADE Ridderstraat 27 | 8061 GH Hasselt | The Netherlands tel: 038 477 53 69 | www.pragma-ade.nl | www.pragma-pod.nl -----------------------------------------------------------------
---- On Wed, 14 Nov 2018 12:47:28 +0100 Esger Renkema
Dear list,
Running the following one-liner:
\directlua{callback.register('ligaturing', node.ligaturing)}ffi\bye
results in:
------------------------------------------- This is LuaTeX, Version 1.09.0 (TeX Live 2019/dev/Debian) restricted system commands enabled. **\directlua{callback.register('ligaturing', node.ligaturing)}ffi\bye ! error: (linebreak): invalid list tail, probably missing glue ! ==> Fatal error occurred, no output PDF file produced! -------------------------------------------
The problem seems to be that, when restoring the original ‘tail of the list’ after applying the ligaturing callback (in this case consisting of the parfillskip glue), it is appended to the tail of the /original/ list-to-be-ligatured. The latter, of course, has been lost if the paragraph ends in a ligature.
According to the manual, the first node of the list passed to the callback is guaranteed not to be a glyph_node. Should the same not hold for the last one, too? The manual states that it ‘normally’ is a glue, but that is clearly not the case here.
I do not think the tail should be required to be not a glyph, it would be enough if LuaTeX would just comply with the current documentation:
After the callback, the internal value of the ‘tail of the list’ will be recalculated.
Looking into the relevant code shows that the tail is only recalculated, if it was null: callback_id = callback_defined(ligaturing_callback); if (callback_id > 0) { tail = run_lua_ligkern_callback(head, tail, callback_id); if (tail == null) tail = tail_of_list(head); } else if (callback_id == 0) { tail = handle_ligaturing(head, tail); } callback_id = callback_defined(kerning_callback); if (callback_id > 0) { tail = run_lua_ligkern_callback(head, tail, callback_id); if (tail == null) { tail = tail_of_list(head); } Now `run_lua_ligkern_callback` always returns the tail parameter without change, so I am pretty sure `tail` is never `null`. The problem could be fixed by just deleting this conditions: diff --git a/source/texk/web2c/luatexdir/font/luafont.c b/source/texk/web2c/luatexdir/font/luafont.c index 7cb03521d..244587148 100644 --- a/source/texk/web2c/luatexdir/font/luafont.c +++ b/source/texk/web2c/luatexdir/font/luafont.c @@ -2425,17 +2425,14 @@ halfword new_ligkern(halfword head, halfword tail) callback_id = callback_defined(ligaturing_callback); if (callback_id > 0) { tail = run_lua_ligkern_callback(head, tail, callback_id); - if (tail == null) - tail = tail_of_list(head); + tail = tail_of_list(head); } else if (callback_id == 0) { tail = handle_ligaturing(head, tail); } callback_id = callback_defined(kerning_callback); if (callback_id > 0) { tail = run_lua_ligkern_callback(head, tail, callback_id); - if (tail == null) { - tail = tail_of_list(head); - } + tail = tail_of_list(head); } else if (callback_id == 0) { halfword nest1 = new_node(nesting_node, 1); halfword cur = vlink(head); Best regards, Marcel
On 11/14/2018 2:42 PM, Marcel Krüger wrote:
Now `run_lua_ligkern_callback` always returns the tail parameter without change, so I am pretty sure `tail` is never `null`.
not true ... the callback can be any function and there doesn't have to be a tail returned .... if you want to recalculate, just make sure you return only head \directlua{callback.register('ligaturing', function(...) return (node.ligaturing(...)) end }ffi\bye so no fundamental changes will happen (if only because something that works better for you might fail or have side effects (functional or performance) for others) Hans ----------------------------------------------------------------- Hans Hagen | PRAGMA ADE Ridderstraat 27 | 8061 GH Hasselt | The Netherlands tel: 038 477 53 69 | www.pragma-ade.nl | www.pragma-pod.nl -----------------------------------------------------------------
---- On Wed, 14 Nov 2018 15:26:43 +0100 Hans Hagen
On 11/14/2018 2:42 PM, Marcel Krüger wrote:
Now `run_lua_ligkern_callback` always returns the tail parameter without change, so I am pretty sure `tail` is never `null`.
not true ... the callback can be any function and there doesn't have to be a tail returned .... if you want to recalculate, just make sure you return only head
Are you sure? The actual callback which `run_lua_ligkern_callback` calls does not return anything (or at least it's return values are ignored), so how would you influence the `run_lua_ligkern_callback` return value?
\directlua{callback.register('ligaturing', function(...) return (node.ligaturing(...)) end }ffi\bye
This doesn't work on my system (neither with experimental nor with trunk).
so no fundamental changes will happen (if only because something that works better for you might fail or have side effects (functional or performance) for others)
Actually returning the tail (optionally) would work better for me than the suggested recalculating, but it does not seem to be implemented (or documented). Anyway, if the current behavior is kept, IMO the documentation should be updated to reflect this. Best regards Marcel
Hans
----------------------------------------------------------------- Hans Hagen | PRAGMA ADE Ridderstraat 27 | 8061 GH Hasselt | The Netherlands tel: 038 477 53 69 | www.pragma-ade.nl | www.pragma-pod.nl -----------------------------------------------------------------
On 11/16/2018 1:54 PM, Marcel Krüger wrote:
---- On Wed, 14 Nov 2018 15:26:43 +0100 Hans Hagen
wrote ---- On 11/14/2018 2:42 PM, Marcel Krüger wrote:
Now `run_lua_ligkern_callback` always returns the tail parameter without change, so I am pretty sure `tail` is never `null`.
not true ... the callback can be any function and there doesn't have to be a tail returned .... if you want to recalculate, just make sure you return only head
Are you sure? The actual callback which `run_lua_ligkern_callback` calls does not return anything (or at least it's return values are ignored), so how would you influence the `run_lua_ligkern_callback` return value? i'll put it on the to-be-checked list
Hans ----------------------------------------------------------------- Hans Hagen | PRAGMA ADE Ridderstraat 27 | 8061 GH Hasselt | The Netherlands tel: 038 477 53 69 | www.pragma-ade.nl | www.pragma-pod.nl -----------------------------------------------------------------
participants (3)
-
Esger Renkema
-
Hans Hagen
-
Marcel Krüger