agrupación de documentos bidi, entorno de lista y visualización de interacción matemática

agrupación de documentos bidi, entorno de lista y visualización de interacción matemática

Estoy intentando depurar parte de mi código que funciona cuando todo es LTR y funciona cuando todo es RTL, pero falla cuando la dirección del documento principal es diferente a la dirección dentro de uno de mis entornos.

Me las arreglé para reducir mi código a algo bastante simple, pero admito que no quedará claro a partir de la pregunta por qué querría hacer lo que estoy haciendo... Además, el comportamiento es ligeramente diferente al de mi Código del mundo real mucho más complicado, por lo que es posible que todavía me haya perdido algo.

El problema

  • En el siguiente código, utilizo \predisplaysizepara medir la longitud de la última línea de un párrafo.
  • Cuando haces esto, necesitas tomar las \prevgrafmatemáticas del interior de la pantalla para restablecerlas luego y mantener el espaciado.
  • En el código siguiente, \prevgrafse restablece 4 veces al final de cada uno de los entornos de mi lista. Pero su valor es diferente dependiendo de si cambio el idioma antes del primer entorno de lista o al comienzo del entorno de lista. En el MWE a continuación, cada llamada sucesiva \measurelineda un \prevgrafvalor de 1, 1, 1 y luego 0.

¿Por qué es esto? ¿Y cómo puedo conseguir un comportamiento coherente?

Sé que el ejemplo es extraño, pero ¿por qué debería haber una diferencia dependiendo de si llamo \setlanguage{ukenglish}antes listenvao lo primero que hace adentro listenva?

(Quiero el comportamiento del segundo ejemplo en el MWE a continuación. Ese es el patrón \prevgrafpara las cuatro llamadas de \measurelinedebería ser: 1, 0, 1, 0. Puede ver esto cuando comenta \babelprovide[import, main]{persian}, asegurándose de que el idioma antes del El inicio listenvaes el mismo que el que se establece en el interior listenva)

Cosas que noto

  • Llamar \@noparlistfalseantes \endlisten el \listenvbentorno es lo que garantiza que \prevgrafsea 0 en la segunda llamada. En otras palabras, si comento esta línea, \prevgrafes 1 para cada una de las cuatro llamadas a \measureline.

  • El mismo problema ocurre cuando el idioma del documento principal es LTR y mi entorno configura el idioma como RTL.

  • La agrupación también está afectando cosas:

    Esto funciona:

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

    Pero esto falla:

    \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}

Estoy obteniendo un resultado incorrecto

salida incorrecta

Salida deseada

salida deseada

Respuesta1

Considera lo siguiente

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

que da la salida

\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

mientras que si descomento \textdirection=0el resultado es

\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

Parece que cuando presionas explícitamente un nodo de directorio (usando \textdir) en un grupo, LuaTeX no descarta la línea vacía antes de la pantalla (tal vez no la considera vacía debido a los nodos de directorio alrededor de la penalización). No estoy seguro si eso debería considerarse un error o no.

No soy competente en el código de Babel, pero supongo que Babel no inserta nodos de directorio cuando no es necesario, por lo que cuando lo colocas \selectlanguage{ukenglish}en el nivel de agrupación superior, Babel no inyecta más nodos de directorio dentro del grupo de tu ambiente.

Probablemente puedas arreglártelas sin usar el truco de visualización para obtener la longitud de la última línea si estás dispuesto a usar algo de lua:

\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}

ingrese la descripción de la imagen aquí

información relacionada