[Dev-luatex] Recalculating tail of the list in ligaturing callback

Marcel Krüger tex at 2krueger.de
Wed Nov 14 14:42:01 CET 2018


 ---- On Wed, 14 Nov 2018 12:47:28 +0100 Esger Renkema <esgerrenkema at gmail.com> 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. 
 >  
 > 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



More information about the dev-luatex mailing list