Como o \ verb detecta espaços que não deveriam existir
Considere o seguinte MWE:
\documentclass{article}
\usepackage{listings}
\lstset{basicstyle=\ttfamily}
\begin{document}
\lstinline |asdf|asdf asdfasdf
\verb |asdf|asdf asdfasdf
\end{document}
Meu entendimento do que é esperado aqui sempre foi o seguinte (vamos \cmdrepresentar um \verbou \lstinlineo seguinte):
- Quando o TeX é tokenizado pela primeira vez
\cmd |, ele engole o espaço que o segue, deixando apenas o token\cmdem sua "boca" (e|atrás dele no fluxo de entrada). - Em seguida
\cmd, ele se expande , o que leva a uma série de alterações no código de categoria, basicamente criando todos os caracteres especiaisother, seguidos por alguma macro que examina o próximo token (neste caso,|). - Essa macro então pega tudo até a próxima ocorrência desse token (sendo então tokenizado), aplica alguma formatação e altera os códigos de categoria de volta.
Notavelmente, o espaço a seguir \cmdé engolido durante a tokenização dessa sequência de controle, ou seja, antes de quaisquer códigos de categoria serem alterados.
Com esse entendimento, eu esperaria que ambas as linhas acima fossem compostas
asdfasdf asdfasdf
Mas obtenho a seguinte saída:
\lstinlinese comporta conforme o esperado, mas de \verbalguma forma sabe sobre o espaço que o segue.
Quão?? Que eu saiba, nunca deveria haver um token de espaço atrás do \verbtoken.
Respostas
No começo você disse:
Quando o TeX foi tokenizado pela primeira vez
\cmd |
mas isso está errado. TeX é um cavalheiro bem comportado e não se adianta examinando um e um |antes de saber o que \cmddeve fazer. No que diz respeito ao TeX, o espaço e |qualquer outro caractere podem significar a mesma coisa, e podem mudar de significado, portanto, a pré-varredura só causaria confusão.
Quando o TeX vê \cmd, a única coisa “especial” que ele faz com os espaços em branco é definir state:=skip_blanks, de modo que, quando, digamos, a composição, \TeX codeescreva
\def\test{\catcode`\ =12 \testx}
\def\testx{\futurelet\token\testy}
\def\testy{\show\token\afterassignment\testx\let\token = }
\test x
e você verá que mostra 5 the character antes de mostrar the letter x.
Agora, de volta ao problema em questão: atualize seu LaTeX :-)
O comportamento antigo de \verbera olhar para o próximo token, qualquer que fosse, e usá-lo como um delimitador (com exceção de {). Isso agora foi corrigido para o lançamento do LaTeX 2020-10-01 (do LaTeX News Issue 32 ):
Acredito que o que acontece é o seguinte:
\verbé primeiro tokenizado (o caractere de espaço, que tem catcode 10 logo antes de\verbser tokenizado, marca o final desta palavra de controle, mas não é descartado).O TeX irá para o estado S, já que
\verbé uma palavra de controle (sequência de controle cujo nome é feito de “letras” apenas), mas ainda não pula os espaços em branco.\verbé expandido e o código de sua expansão é executado. Este código primeiro dá aos espaços o catcode 12 (via\let\do\@makeother \dospecials), isso é importante.É o fim do
\verbtexto de substituição de\@ifstar\@sverb\@verb. Isso\@ifstarolha para a frente na entrada, portanto, o estado S é ativado. Como os espaços têm catcode 12 neste ponto, o caractere de espaço seguinte não\verbé ignorado. Ele é tokenizado com catcode 12.Como usamos a forma sem estrela de
\verbe\@verbé definida como\def\@verb{\@vobeyspaces \frenchspacing \@sverb}, os espaços agora são ativados e\@sverbexpandidos (portanto, o delimitador final será um espaço catcode-13, enquanto o delimitador inicial era um espaço catcode-12).\@sverbpega o token de espaço catcode-12 como seu único argumento e define os espaços ativos como\letiguais a\verb@egroup(se\verb*tivessem sido usados, também\@sverbteriam sido usados\@setupverbvisiblespace \@vobeyspaces; assim, os espaços acabariam ativos em todos os casos). Esta é a forma como o texto integral vai terminar em condições não erróneos:\verb@egroupvai produzir\egroup, que vai terminar o grupo iniciado por\verb(há um\bgroupem\verb's texto de substituição). Como a configuração especial do catcode foi feita localmente dentro desse grupo, isso encerra a configuração especial do catcode.
Assim, a frase da pergunta “Esta macro então agarra tudo até a próxima ocorrência daquele token” não é realmente correta: não há captura do conteúdo literal como um argumento. Os tokens entre os delimitadores de início e fim são simplesmente processados como tokens catcode-12, exceto tokens de espaço que estão sempre ativos no final de \@sverb, como vimos.
Nota: como Phelype Oleinik apontou , o comportamento do \verbfoi alterado no formato LaTeX de 2020-10-01. Meus comentários aqui são baseados em LaTeX2e <2020-02-02> patch level 5.