Bidi-Dokumentengruppierung, Listenumgebung und Anzeigemathematik-Interaktion

Bidi-Dokumentengruppierung, Listenumgebung und Anzeigemathematik-Interaktion

Ich versuche, einen Teil meines Codes zu debuggen, der funktioniert, wenn alles LTR ist, und der funktioniert, wenn alles RTL ist, aber fehlschlägt, wenn die Hauptdokumentrichtung von der Richtung innerhalb einer meiner Umgebungen abweicht.

Ich habe es geschafft, meinen Code auf etwas ziemlich Einfaches zu reduzieren, gebe aber zu, dass aus der Frage, warum um Himmels Willen ich das tun möchte, was ich tue, nicht klar wird … Außerdem unterscheidet sich das Verhalten leicht von meinem viel komplizierteren Code in der realen Welt, sodass ich vielleicht trotzdem noch etwas übersehen habe.

Das Problem

  • Im folgenden Code verwende ich, \predisplaysizeum die Länge der letzten Zeile eines Absatzes zu messen.
  • Wenn Sie dies tun, müssen Sie die \prevgrafMathematik aus der Anzeige heraus erfassen, um sie anschließend so zurückzusetzen, dass der Abstand erhalten bleibt.
  • Im folgenden Code \prevgrafwird am Ende jeder meiner Listenumgebungen 4 Mal zurückgesetzt. Der Wert ist jedoch unterschiedlich, je nachdem, ob ich die Sprache vor der ersten Listenumgebung oder am Anfang der Listenumgebung ändere. Im folgenden MWE \measurelineergibt jeder aufeinanderfolgende Aufruf von ein Ergebnis \prevgrafvon 1, 1, 1 und dann 0.

Warum ist das so? Und wie kann ich ein konsistentes Verhalten erreichen?

Ich weiß, das Beispiel ist bizarr, aber warum sollte es einen Unterschied machen, je nachdem, ob ich \setlanguage{ukenglish}vorher aufrufe listenvaoder als erstes darin listenva???

(Ich möchte das Verhalten des zweiten Beispiels im MWE unten. Das ist das Muster von \prevgraffür die vier Aufrufe von , das \measurelinelauten sollte: 1, 0, 1, 0. Sie können dies sehen, wenn Sie auskommentieren und \babelprovide[import, main]{persian}sicherstellen, dass die Sprache vor dem Beginn von listenvamit der in festgelegten übereinstimmt listenva.)

Was mir auffällt

  • \@noparlistfalseDer vorherige Aufruf \endlistin der \listenvbUmgebung stellt sicher, dass \prevgrafbeim zweiten Aufruf 0 ist. Mit anderen Worten, wenn ich diese Zeile auskommentiere, \prevgrafist für jeden der vier Aufrufe von 1 \measureline.

  • Dasselbe Problem tritt auf, wenn die Hauptdokumentsprache LTR ist und meine Umgebung die Sprache auf RTL-Sprache einstellt.

  • Auch die Gruppierung hat Auswirkungen auf:

    Das funktioniert:

    \listenva
      \begin{listenvb}
        Test.
      \end{listenvb}
    \endlistenva
    

    Aber das schlägt fehl:

    \begingroup
    \selectlanguage{ukenglish}
    \begin{listenva}
      \begin{listenvb}
        Test.
      \end{listenvb}
    \end{listenva}
    \endgroup
    

MWE

%! TeX Program = lualatex

\documentclass{article}
\pagestyle{empty}
\usepackage[bidi=basic, layout=lists]{babel}
\babelprovide[import, main]{persian}
\babelprovide[import]{ukenglish}
\newdimen\linelen
\newcommand{\measureline}{%
  \abovedisplayshortskip -\baselineskip
  \abovedisplayskip\abovedisplayshortskip
  \belowdisplayshortskip 0pt
  \belowdisplayskip\belowdisplayshortskip
  $$
    \ifdim\predisplaysize>0pt
      \global\linelen\dimexpr\predisplaysize-2em
    \fi
    \global\def\resetspacing{%
      \predisplaysize\the\predisplaysize
      \prevgraf\the\prevgraf
    }%
  $$
  \resetspacing
  \ifdim\linelen>0pt
    \vskip-\baselineskip
  \fi
}
\newcommand{\nolistspaces}{%
  \leftmargin 0pt
  \rightmargin 0pt
  \itemindent 0pt
  \partopsep 0pt
  \parsep 0pt
  \topsep 0pt
}
\newenvironment{listenva}{%
  \selectlanguage{ukenglish}%
  \list{}{\nolistspaces}%
  \item\relax
}{%
  \measureline
  \strut\hskip\linelen+++%
  \csname @noparlistfalse\endcsname
  \endlist
}
\newenvironment{listenvb}{%
  \list{}{\nolistspaces}%
  \item\relax
}{%
  \measureline
  \csname @noparlistfalse\endcsname
  \endlist
}
\begin{document}
\begin{listenva}
  \begin{listenvb}
    Test.
  \end{listenvb}
\end{listenva}

\selectlanguage{ukenglish}

\begin{listenva}
  \begin{listenvb}
    Test.
  \end{listenvb}
\end{listenva}
\end{document}

Ich erhalte die falsche Ausgabe

falsche Ausgabe

Gewünschte Ausgabe

gewünschte Ausgabe

Antwort1

Folgendes berücksichtigen

\showboxdepth\maxdimen\showboxbreadth\maxdimen
\tracingonline1\tracingoutput1
\everypar{\setbox0=\lastbox}
{%\textdirection=0
$$
$$\par}
\bye

was die Ausgabe ergibt

\vbox(667.20255+0.0)x469.75499, direction TLT
.\vbox(0.0+0.0)x469.75499, glue set 14.0fil, direction TLT
..\glue -22.5
..\hbox(8.5+0.0)x469.75499, glue set 469.755fil, direction TLT
...\vbox(8.5+0.0)x0.0, direction TLT
...\glue 0.0 plus 1.0fil
..\glue 0.0 plus 1.0fil minus 1.0fil
.\vbox(643.20255+0.0)x234.8775, glue set 626.20251fill, direction TLT
..\glue(\topskip) 10.0
..\hbox(0.0+0.0)x0.0, shifted 234.8775, direction TLT
..\penalty 0
..\glue(\belowdisplayshortskip) 7.0 plus 3.0 minus 4.0
..\glue 0.0 plus 1.0fill
.\glue(\baselineskip) 17.55556
.\hbox(6.44444+0.0)x469.75499, glue set 232.37749fil, direction TLT
..\glue 0.0 plus 1.0fil minus 1.0fil
..\tenrm 1
..\glue 0.0 plus 1.0fil minus 1.0fil

Wenn ich das Kommentarzeichen entferne, \textdirection=0ist die Ausgabe

\vbox(667.20255+0.0)x469.75499, direction TLT
.\vbox(0.0+0.0)x469.75499, glue set 14.0fil, direction TLT
..\glue -22.5
..\hbox(8.5+0.0)x469.75499, glue set 469.755fil, direction TLT
...\vbox(8.5+0.0)x0.0, direction TLT
...\glue 0.0 plus 1.0fil
..\glue 0.0 plus 1.0fil minus 1.0fil
.\vbox(643.20255+0.0)x469.75499, glue set 614.20251fill, direction TLT
..\glue(\topskip) 10.0
..\hbox(0.0+0.0)x469.75499, glue set 469.755fil, direction TLT
...\localpar
....\localinterlinepenalty=0
....\localbrokenpenalty=0
....\localleftbox=null
....\localrightbox=null
...\begindir TLT
...\penalty 10000
...\enddir TLT
...\glue(\parfillskip) 0.0 plus 1.0fil
...\glue(\rightskip) 0.0
..\penalty 10000
..\glue(\abovedisplayshortskip) 0.0 plus 3.0
..\glue(\baselineskip) 12.0
..\hbox(0.0+0.0)x0.0, shifted 234.8775, direction TLT
..\penalty 0
..\glue(\belowdisplayshortskip) 7.0 plus 3.0 minus 4.0
..\glue 0.0 plus 1.0fill
.\glue(\baselineskip) 17.55556
.\hbox(6.44444+0.0)x469.75499, glue set 232.37749fil, direction TLT
..\glue 0.0 plus 1.0fil minus 1.0fil
..\tenrm 1
..\glue 0.0 plus 1.0fil minus 1.0fil

Es sieht so aus, als ob LuaTeX die leere Zeile vor der Anzeige nicht verwirft, wenn Sie explizit einen Verzeichnisknoten (mit \textdir) in eine Gruppe einfügen (vielleicht betrachtet es sie aufgrund der Verzeichnisknoten um die Strafe herum nicht als leer). Ich bin nicht sicher, ob das als Fehler angesehen werden sollte oder nicht.

Ich bin mit dem Babel-Code nicht vertraut, aber ich vermute, dass Babel keine Verzeichnisknoten einfügt, wenn es nicht nötig ist, und dass \selectlanguage{ukenglish}Babel daher, wenn Sie sie auf die oberste Gruppierungsebene setzen, keine weiteren Verzeichnisknoten in die Gruppe Ihrer Umgebung einfügt.

Sie können wahrscheinlich auf den Anzeigetrick verzichten, um die Länge der letzten Zeile zu erhalten, wenn Sie bereit sind, etwas Lua zu verwenden:

\documentclass{article}
\pagestyle{empty}
\usepackage[bidi=basic, layout=lists]{babel}
\babelprovide[import, main]{persian}
\babelprovide[import]{ukenglish}
\newdimen\linelen
\directlua{
 local disabled = true
 local function lastline_length(head,c)
    if disabled then 
        return head
    end
    local last_line = node.tail(head)
    local parfill_node
    for n in node.traverse_id(node.id('glue'),last_line.list) do
        if n.subtype == 15 then parfill_node = n end 
    end
    local length, _, _ = node.rangedimensions(last_line,last_line.head,parfill_node)
    tex.setdimen('global', 'linelen',length)
    return head
 end
 local getlastlinelength = luatexbase.new_luafunction"getlastlinelength"
 lua.get_functions_table()[getlastlinelength] = function() disabled = false end
 token.set_lua("getlastlinelength", getlastlinelength, "protected")
 local dontgetlastlinelength = luatexbase.new_luafunction"dontgetlastlinelength"
 lua.get_functions_table()[dontgetlastlinelength] = function() disabled = true end
 token.set_lua("dontgetlastlinelength", dontgetlastlinelength, "protected")
 luatexbase.add_to_callback('post_linebreak_filter',lastline_length,'lastline')
}
\newcommand{\nolistspaces}{%
  \leftmargin 0pt
  \rightmargin 0pt
  \itemindent 0pt
  \partopsep 0pt
  \parsep 0pt
  \topsep 0pt
}
\newenvironment{listenva}{%
  \selectlanguage{ukenglish}%
  \list{}{\nolistspaces}%
  \item\relax
}{%
  \ifdim\linelen>0pt
    \vskip-\baselineskip
  \fi
  \strut\hskip\linelen+++%
  \csname @noparlistfalse\endcsname
  \endlist
}
\newenvironment{listenvb}{%
  \global\linelen=0pt
  \getlastlinelength
  \list{}{\nolistspaces}%
  \item\relax
}{%
  \csname @noparlistfalse\endcsname
  \endlist
  \dontgetlastlinelength
}
\begin{document}
\begin{listenva}
  \begin{listenvb}
    Test.
  \end{listenvb}
\end{listenva}

\selectlanguage{ukenglish}

\begin{listenva}
  \begin{listenvb}
    Test.
  \end{listenvb}
\end{listenva}
\end{document}

Bildbeschreibung hier eingeben

verwandte Informationen