
Eu tenho o seguinte código Tex simples:
\def\xx{ABC}
\def\temp #1 {\def\tempii{#1}}
\temp\xx a b c
\tempii\tempii
Espero ver o seguinte resultado:
a b c ABCABC
Mas eu realmente vejo isso:
b c ABCaABCa
Por que o 'a' está incluído na definição de \tempii?
Responder1
Ainda estou pensando por que isso acontece, mas esta revisão (abrangendo \xx
) oferece o que você deseja.
Acho que a resposta é que, no uso \temp\xx a b c
, o espaço depois \xx
é, na visão do analisador TeX, não um espaço, mas apenas significa o fim do nome da macro \xx
. Por exemplo, se você colocar \xx A
uma linha sozinha, verá que ela será impressa sem ABCA
espaço. Assim, o analisador suga o "A" final como conectado a \xx
. Também se pode usar \temp\xx{} a b c
, como forma de informar ao analisador que o espaço é um separador, e não apenas o próximo caractere seguinte \xx
.
\documentclass{article}
\begin{document}
\def\xx{ABC}
\def\temp #1 {\def\tempii{#1}}
\temp{\xx} a b c
\tempii\tempii
\end{document}
Responder2
Para maior clareza, denotarei os tokens de espaço por •
, pois eles são muito importantes na discussão; espaços nos exemplos de código a seguir devem ser ignorados.
O texto do parâmetro \temp
é
#1•
enquanto o texto de substituição é
\def\tempii{#1}
Sua chamada \temp
é
\temp\xx a•b•c•\tempii\tempii
Observe que depois \xx
existe um espaço apenas para delimitar a macro; isso énãoum token de espaço: não é nada, porque o TeX sempre ignora espaços seguindo o controlepalavras(não controlesímbolos). O espaço depois c
vem do final da linha do seu código.
Os tokens a seguir \temp
são varridos (sem expansão) para encontrar uma correspondência com o texto do parâmetro, onde o argumento é delimitado por um espaço, então #1
termina sendo \xx a
e o próximo estado do fluxo de entrada é
\def\tempii{\xx a}b•c•\tempii\tempii
Agora o TeX executa a definição e a remove do fluxo de entrada:
b•c•\tempii\tempii
e a peça b•c•
passa para a fase de composição tipográfica. Após a expansão das duas cópias de \tempii
, isso equivale a ter digitado
b•c•\xx a\xx a
ou
b•c•ABCaABCa
que é exatamente o que você conseguiu.
Se você tivesse usado \?
em vez das \xx
duas últimas linhas teria sido convertido em
\temp\?•a•b•c•\tempii\tempii
porque \?
é um símbolo de controle e o TeX não ignora espaços depois deles. Neste caso o resultado seria
a•b•c•ABCABC
Observe que
\expandafter\temp\xx a•b•c
\tempii\tempii
produziria o mesmo resultado, pois após a ação do \expandafter
TeX seria apresentado
\temp ABCa•b•c
(mesma convenção para espaços de antes, é claro). Você obteria o mesmo resultado que with \?
em vez de \xx
with
\expandafter\temp\expandafter\xx\space a•b•c
porque então o TeX seria apresentado com
\temp\xx•a•b•c
Na verdade, os espaços são ignorados após as palavras de controle apenas durante o processo de tokenização.