¿Cómo detecta \ verb espacios que no deberían existir?
Considere el siguiente MWE:
\documentclass{article}
\usepackage{listings}
\lstset{basicstyle=\ttfamily}
\begin{document}
\lstinline |asdf|asdf asdfasdf
\verb |asdf|asdf asdfasdf
\end{document}
Mi comprensión de lo que se puede esperar aquí siempre ha sido la siguiente (supongamos \cmdque uno \verbo \lstinlinelo siguiente):
- Cuando TeX se tokeniza por primera vez
\cmd |, devora el espacio que le sigue, dejando solo el token\cmden su "boca" (y|detrás de él en el flujo de entrada). - Luego se expande
\cmd, lo que conduce a una serie de cambios en el código de categoría, básicamente haciendo cada carácter especialother, seguido de alguna macro que mira el siguiente token (en este caso,|). - Esta macro luego toma todo hasta la próxima aparición de ese token (siendo tokenizado en ese momento), aplica algún formato y cambia los códigos de categoría nuevamente.
En particular, el espacio que sigue \cmdse devora durante la tokenización de esa secuencia de control, es decir, antes de que se cambie cualquier código de categoría.
Con este entendimiento, esperaría que las dos líneas anteriores se componga
asdfasdf asdfasdf
Pero obtengo el siguiente resultado:
\lstinlinese comporta como se esperaba, pero de \verbalguna manera conoce el espacio que le sigue.
¿¿Cómo?? Que yo sepa, nunca debería haber habido una ficha de espacio detrás de la \verbficha.
Respuestas
Al principio dijiste:
Cuando TeX tokenizado por primera vez
\cmd |
pero eso está mal. TeX es un caballero de buen comportamiento y no se adelanta escaneando ay a |antes de saber qué \cmdse supone que debe hacer. En lo que respecta a TeX, el espacio y el |y cualquier otro carácter podrían significar lo mismo, y podrían cambiar de significado, por lo que el escaneo previo solo causaría confusión.
Cuando TeX ve \cmd, lo único "especial" que hace con los espacios en blanco es configurarlos state:=skip_blanks, de modo que cuando, digamos, componga, \TeX codeescriba
\def\test{\catcode`\ =12 \testx}
\def\testx{\futurelet\token\testy}
\def\testy{\show\token\afterassignment\testx\let\token = }
\test x
y verá que muestra 5 the character antes de mostrar the letter x.
Ahora volvamos al problema en cuestión: actualice su LaTeX :-)
El antiguo comportamiento de \verbera mirar el siguiente token, cualquiera que fuera, y usarlo como delimitador (dada la excepción de {). Esto ahora se ha corregido para la versión de LaTeX 2020-10-01 (de LaTeX News Issue 32 ):
Creo que lo que pasa es lo siguiente:
\verbse tokeniza primero (el carácter de espacio, que tiene catcode 10 justo antes de que\verbse tokenice, marca el final de esta palabra de control pero no se descarta).TeX pasará al estado S, ya que
\verbes una palabra de control (secuencia de control cuyo nombre está compuesto únicamente por “letras”), pero aún no omite los espacios en blanco.\verbse expande y se ejecuta el código de su expansión. Este código primero le da a los espacios el catcode 12 (vía\let\do\@makeother \dospecials), esto es importante.Hay
\verbun texto de reemplazo al final de\@ifstar\@sverb\@verb. Este\@ifstarvenideros miradas en la entrada, por lo tanto manda el estado S. Ya tienen espacios catcode 12 en este punto, el siguiente carácter de espacio\verbes no omitir. Se tokeniza con catcode 12.Dado que usamos la forma sin estrella de
\verby\@verbse define como\def\@verb{\@vobeyspaces \frenchspacing \@sverb}, los espacios ahora se activan y\@sverbse expanden (por lo tanto, el delimitador final será un espacio catcode-13, mientras que el delimitador de inicio fue un espacio catcode-12).\@sverbtoma el token de espacio catcode-12 como su único argumento y define los espacios activos para que sean\letiguales a\verb@egroup(si se\verb*hubiera usado, también\@sverblo habría hecho\@setupverbvisiblespace \@vobeyspaces; por lo tanto, los espacios terminan activos en todos los casos). Así es como el texto literal terminará en condiciones no erróneas:\verb@egroupcederá\egroup, que terminará el grupo iniciado por\verb(hay un texto de reemplazo de\bgroupin\verb). Dado que la configuración de catcode especial se ha realizado localmente dentro de este grupo, esto finaliza la configuración de catcode especial.
Por lo tanto, la oración de la pregunta "Esta macro luego toma todo hasta la próxima aparición de ese token" no es realmente correcta: no se toma el contenido literal como argumento. Los tokens entre los delimitadores inicial y final se procesan simplemente como tokens catcode-12, excepto los tokens de espacio que siempre están activos al final de \@sverb, como hemos visto.
Nota: como señaló Phelype Oleinik , el comportamiento de \verbse cambió en el formato LaTeX desde 2020-10-01. Mis comentarios aquí se basan en LaTeX2e <2020-02-02> patch level 5.