alguém pode explicar o futureletdentro deambientes de alinhamento?
Exemplo:
O comando \A deve dar um "A" se o próximo caractere for um {, um "B" se for & e "C" em qualquer outro caso.
\gdef\A{\futurelet\thesymbol\B}
\gdef\B#1{\ifx\bgroup\thesymbol A\else\ifx&\thesymbol B\else C\fi\fi}
e no caso de texto normal ou matemática embutida, funciona muito bem:
\A{a},\A&,\A a % -> "A,B,C"
$\A{a}$,$\A&$,$\A a$ % -> "A,B,C"
masno momento em que eu o uso em um ambiente de alinhamento * (amsmath), ocorre um erro "Incomplete \ifx":
\begin{align*} \A{a},\A&,\A a \end{align*}% --> error.
Alguém pode me explicar? THX!
Chris
PS: Há mais coisas sobre futurelet em um ambiente de alinhamento que não entendo: se definirmos
\gdef\A{\futurelet\thesymbol\alpha}
\gdef\D#1{\detokenize{#1}}
então
\begin{align*}
\D&,\A a % -> "&,alpha a" (okay)
\A a,\D{&} % -> "alpha a,&" (okay)
\A a,\D& % -> error: "Argument of D has an extra }." (???)
\end{align*}
Responder1
\gdef\B#1{\ifx\bgroup\thesymbol A\else\ifx&\thesymbol B\else C\fi\fi}
quando o TeX vê, &
ele troca o resto do modelo pelo \halign
especificado no caso de látex por c
r
etc, então ele \ifx
irá comparar os dois primeiros tokens do modelo (provavelmente \unskip
e \hfil
então a célula (e então o grupo) terminará, as coisas darão errado .
Se você quiser se esconder &
ao iniciar um grupo antes do futurelet e finalizá-lo após o teste, você precisa do
{\ifnum0=`}
...
\ifnum0=`{\fi}
formulário que aparece em qualquer código tabular.
Isso produz A, B, C, que acho que é o resultado pretendido.
\documentclass{article}
\usepackage{amsmath}
\gdef\A{{\ifnum0=`}\fi\futurelet\thesymbol\B}
\gdef\B#1{\ifx\bgroup\thesymbol A\else\ifx&\thesymbol B\else C\fi\fi \ifnum0=`{\fi}}
\begin{document}
\begin{align*} \A{a},\A&,\A a \end{align*}
\end{document}
Para o seu segundo exemplo, observe que &
termina um grupo assim
a,\D&
é parecido {\D}
e ambos dão o mesmo erro:
! Argument of \D has an extra }.
<inserted text>
\par
l.15 {\D}
Lá não está tão claro qual é a correção, pois não está claro o que você deseja {\D}
fazer.
Responder2
Não posso competir com o entendimento de David sobre o código TeX, então não tentarei consertar suas macros (embora minha opinião seja que o que você está fazendo é fundamentalmente imprudente). No entanto, seu comentário sobre “quando o TeX vê o &
” pode ser expandido da seguinte forma. Ao escanear um alinhamento, o TeX atua de uma maneira que está em desacordo com o modelo mental que a maioria dos usuários (mesmo usuários experientes e conhecedores) tem de sua execução. Ou seja, nósImagineque o TeX está sempre fazendo uma de três coisas:
Digitalizar a entrada para tokenizar os caracteres para fornecer alimento para a "boca" do analisador de macro;
Expandindo macros;
Execução de tokens não expansíveis: diretivas de programação como
\def
ou\hbox
ou comandos de composição tipográfica, como caracteres.
Sob este modelo, todos esperam que dentro de um alinhamento (as primitivas do TeX \halign
ou \valign
) o caractere de tabulação &
execute sua ação no ponto 3: execução. Contudo, este não é realmente o caso; na verdade, o TeX "avisa" os caracteres de tabulação no ponto 1! Se TeXjá leuum E comercial (ou categoria equivalente de caractere) encerrará imediatamente a célula atual, fechando um grupo, inserindo a " v
parte" do modelo e assim por diante.
(Editar:Eu estava apenas folheando errorlog.pdf
(ou seja, texdoc errorlog
) e encontrei o comentário relevante em uma sessão de depuração em 18 de março de 1978:
Faça a próxima rotina de interceptação
&
e\cr
tokens. Eu pensei que poderia simplesmente colocar&
e\cr
dentrobig_switch
[ou seja, no estômago do TeX, não nos olhos]; isso foi um grande erro.
Este é um insight parcial interessante sobre o que levou Knuth a fazer a escolha acima, aparentemente bizarra, de comportamento desses tokens de matriz, bem como a confirmação de que esse é realmente o comportamento.)
A exceção, é claro, é quando o TeX está dentro de um grupo de chaves inacabado (e devem ser caracteres de chaves reais, não implícitos ou \begingroup
, que iniciam este grupo), o que leva à construção }` de David {\ifnum0=
que é expansivelmente equivalente a uma chave aberta sem realmente criar colchetes desequilibrados dentro de uma definição de macro onde ela pode ser colocada.
O resultado dessa estranha regra de análise é que é preciso ter muito cuidado com o que é lido por uma macro em uma célula de tabela ou delimitado por um ambiente. Macros como a sua, que efetivamente leem seus argumentos por meio de atribuição, em vez de análise de macro-argumentos, são ainda mais precárias, pois sem os colchetes necessários, a guia que poderia ser lida serianãoestar protegido. Os ambientes compatíveis com tabelas incluem a \ifnum
proteção de quaisquer caracteres de tabulação que possam ocorrer neles; os mais ingênuos serão divididos entre as células e, portanto, provavelmente falharão.