Alinhar*, & e \futurelet

Alinhar*, & e \futurelet

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 \halignespecificado no caso de látex por c retc, então ele \ifxirá comparar os dois primeiros tokens do modelo (provavelmente \unskipe \hfilentã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:

  1. Digitalizar a entrada para tokenizar os caracteres para fornecer alimento para a "boca" do analisador de macro;

  2. Expandindo macros;

  3. Execução de tokens não expansíveis: diretivas de programação como \defou \hboxou comandos de composição tipográfica, como caracteres.

Sob este modelo, todos esperam que dentro de um alinhamento (as primitivas do TeX \halignou \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 " vparte" 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 \crtokens. Eu pensei que poderia simplesmente colocar &e \crdentro big_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 \ifnumproteçã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.

informação relacionada