Hello, with the following I get an orphan enddir node ============================== run \linedirection=1 run \linedirection=0 run run \linedirection=1 run \bye ============================= This can confuse the par builder in some situations, and even worse it can confuse the code in pdflistout.c Another example, where the confusion is visible, is ================================= run \linedirection=1 run \linedirection=0 run run {\linedirection=1 run} run \linedirection=1 run \bye================================= Note how the last "run" (or nur with direction) is at the bottom left corner. In fact, anything in the problematic line that is after the problematic point is being shifted, and after the line break things are restored: ============================ run \linedirection=1 run \linedirection=0 run run {\linedirection=1 run} run \linedirection=1 run \linedirection=0 run Some more\hfill\break text \bye ============================ I think this is because when hlist_out() encounters the orphan enddir node the coordinate system gets corrupted because the orphan enddir causing it the be restored to bogus saved values. The enddir node is inserted in https://gitlab.lisn.upsaclay.fr/texlive/luatex/-/blob/master/source/texk/web... or (with \textdirection) in https://gitlab.lisn.upsaclay.fr/texlive/luatex/-/blob/master/source/texk/web... Udi
On Wednesday, February 18th, 2026 at 4:39 PM, Udi Fogiel
Hello,
with the following I get an orphan enddir node
============================== run \linedirection=1 run \linedirection=0 run run \linedirection=1 run
\bye =============================
The enddir node is inserted in https://gitlab.lisn.upsaclay.fr/texlive/luatex/-/blob/master/source/texk/web...
or (with \textdirection) in https://gitlab.lisn.upsaclay.fr/texlive/luatex/-/blob/master/source/texk/web...
The problem is that new_graf might not inject dir nodes even if no_local_dirs_par is positive, which break the synchronization between the open dir nodes and no_local_dirs_par. Like at the start of boxes, no_local_dirs_par should be reset, but then if dir nodes are injected it should be incremented. I attached a fix. thanks, Udi
On Thursday, March 5th, 2026 at 2:44 PM, Udi Fogiel
I attached a fix.
Note that if the paragraph is starting inside of a group then the fix won't work, as no_local_dirs_par is set locally =============== run \linedirection=1 run \linedirection=0 run % the next paragraph is starting inside a group {run} {\linedirection=1 run} run \linedirection=1 run \linedirection=0 run Some more\hfill\break text \bye ================== So the patch does not fix everything, but it certainly improves the situation. Udi
On Thursday, March 5th, 2026 at 3:10 PM, Udi Fogiel
On Thursday, March 5th, 2026 at 2:44 PM, Udi Fogiel
wrote: I attached a fix.
Note that if the paragraph is starting inside of a group then the fix won't work, as no_local_dirs_par is set locally
=============== run \linedirection=1 run \linedirection=0 run
% the next paragraph is starting inside a group {run} {\linedirection=1 run} run \linedirection=1 run \linedirection=0 run Some more\hfill\break text
\bye ==================
So the patch does not fix everything, but it certainly improves the situation.
Another solution which works even in this case is to always inject dir nodes from the stack, even if the direction is the same as pardirection. See the attached diff. Udi
On Thu, 5 Mar 2026 at 14:52, Udi Fogiel
On Thursday, March 5th, 2026 at 3:10 PM, Udi Fogiel
wrote: On Thursday, March 5th, 2026 at 2:44 PM, Udi Fogiel < udi.fogiel@proton.me> wrote:
I attached a fix.
Note that if the paragraph is starting inside of a group then the fix won't work, as no_local_dirs_par is set locally
=============== run \linedirection=1 run \linedirection=0 run
% the next paragraph is starting inside a group {run} {\linedirection=1 run} run \linedirection=1 run \linedirection=0 run Some more\hfill\break text
\bye ==================
So the patch does not fix everything, but it certainly improves the situation.
Another solution which works even in this case is to always inject dir nodes from the stack, even if the direction is the same as pardirection. See the attached diff.
Ok, I will check them later. -- luigi
On Thu, 5 Mar 2026 at 17:50, luigi scarso
On Thu, 5 Mar 2026 at 14:52, Udi Fogiel
wrote: On Thursday, March 5th, 2026 at 3:10 PM, Udi Fogiel
wrote: On Thursday, March 5th, 2026 at 2:44 PM, Udi Fogiel < udi.fogiel@proton.me> wrote:
I attached a fix.
Note that if the paragraph is starting inside of a group then the fix won't work, as no_local_dirs_par is set locally
=============== run \linedirection=1 run \linedirection=0 run
% the next paragraph is starting inside a group {run} {\linedirection=1 run} run \linedirection=1 run \linedirection=0 run Some more\hfill\break text
\bye ==================
So the patch does not fix everything, but it certainly improves the situation.
Another solution which works even in this case is to always inject dir nodes from the stack, even if the direction is the same as pardirection. See the attached diff.
Ok, I will check them later.
Sorry for the delay, I had already seen it but then I was busy with other things related to Luatex. Re-checking it now. -- luigi
On Wednesday, April 1st, 2026 at 7:13 PM, luigi scarso
Sorry for the delay, I had already seen it but then I was busy with other things related to Luatex. Re-checking it now.
Thanks luigi. After giving it some more thought, the first patch does not fix everything (as mentioned previously), and the second one is probably not backwards compatible as it creates direction nodes is situations where previously weren't any (and this for example can affect vertical spacing around display if \mathemptydisplamode is not set). There is a simple ad hoc solution, which can also be done from Lua: \directlua{ callback.register("pre_linebreak_filter", function(head) local stack = 0 for n, sb in node.traverse_id(node.id('dir'),head) do stack = stack + 1-2*sb if stack == -1 then head = node.remove(head,n) return head end end return head end) } Something similar can be done from C before the callback kicks in (so that callback order won't matter and the fix will be made in all formats). But maybe after looking into it you found a better solution (hopefully). Udi
participants (2)
-
luigi scarso -
Udi Fogiel