Compreendendo \@firstofone

Compreendendo \@firstofone

Eu estava olhando essa resposta e tentando entender o código, sou um super novato (meu segundo dia) em LaTeX e fiquei preso na seguinte parte do código que não consegui fazê-lo funcionar em um ambiente que não fosse de tabela. Aqui está a forma mais simples do que não entendo.

\documentclass{article}
\begin{document}
    \newcommand*\f[3]{#1-#2-#3}
    \newcommand*\ex[1]{\f#1 - \expandafter\f\@firstofone}
     Try \ex{111}{221}
\end{document}

Por algum motivo, que não está claro para mim, no código vinculado, o último argumento não é consumido mas fica para ser consumido pela expandafter\f\...construção. Pelo que entendi \expandafterdeveria primeiro "executar" \@firstofone, pegando o {221}argumento, tirando os colchetes e alimentando-o \f. Isso não acontece e não consigo entender o porquê.

Responder1

Você precisa usar \makeatletterpara que isso funcione, mas é o mínimo.

A chamada \ex{111}{221}se expande primeiro para

\f 111 - \expandafter\f\@firstofone{221}

Now \fé expandido e procura três argumentos, encontrando 1e 1, 1porque o TeX usa um único token se uma chave estiver faltando.

Pela definição, \fisso é expandido e o texto de substituição é reinserido no fluxo de entrada:

1-1-1 - \expandafter\f\@firstofone{221}

Os tokens 1-1-1 -não são expansíveis e por isso são enviados para a próxima etapa. Agora resta

\expandafter\f\@firstofone{221}

Isso irá deixar \fde lado e expandir, \@firstofoneo que apenas retorna seu (argumento não apoiado), então obtemos

\f221

isso se torna 2-2-1. Assim, o efeito líquido do seu código é imprimir

1-1-1 - 2-2-1

o que não parece realmente útil. Onde quer que você o tenha encontrado, não confie nele.

Responder2

Como egreg apontou em sua resposta, o uso de \@firstofonenão é muito útil e não faz diferença neste caso específico. Contudo, há casos em queéútil. Para completar, gostaria de dar dois exemplos.

Macros expansíveis

EmPor que o \expandafter\@firstoftwoidioma?é fornecido um caso de uso típico para \@firstoftwoe em macros totalmente expansíveis. , uma espécie de "função de identidade" do LaTeX, é útil em contextos semelhantes onde apenas um único parâmetro deve ser tratado:\@secondoftwo\@firstofone

\def\gobbleIfZero#1{%
  \ifnum#1=0
    \expandafter\@gobble
  \else
    \expandafter\@firstofone
  \fi
}

foo\gobbleIfZero{0}{bar}

foo\gobbleIfZero{123}{bar}

darei

foo

foobar

\@gobble(como \@firstofone) recebe um único parâmetro, mas o descarta e expande para "nada".

Correção de catcodes

Um pouco mais complicado, mas também mais interessante, é o caso em que estão envolvidas alterações no código de gato. Quando o TeX está analisando argumentos para macros, ele corrige catcodes sempre que o texto do argumento está sendo lido. Isso não importa no seu caso, pois não há alterações nos códigos de gato aqui. Mas suponha que o seguinte exemplo, um tanto artificial, seja dado:

\begingroup
\catcode`4=\active
\gdef 4{four}
\endgroup

\newcommand*\f{\catcode`4=\active}
\newcommand*\exA{\f}
\newcommand*\exB{\expandafter\f\@firstofone}

{\exA{345}--{345}}

{\exB{345}--{345}}

Isto resulta em

3quatro5-3quatro5

345-3quatro5

As primeiras quatro linhas definem uma macro global 4que se expande para four. Geralmente 4tem catcode 12 (outro), então mudamos para 13 (ativo) para poder fazer dele uma macro. \faqui traz essas macros de volta ao escopo quando executadas.

Quando \exAé executado, o catcode 4é alterado para 13 que posteriormente faz 4ser expandido para fourambos os grupos seguintes. Não há parâmetros aqui, então isso é simples.

Por outro lado, na macro é processada \exBa primeira parte pela qual apenas retorna o mesmo texto,{345}\@firstofonemas corrige o catcodede 4a 12. Depois de corrigido, não poderá mais ser alterado! Mesmo que a mudança do catcode \fseja processadaanteso primeiro 345, não terá nenhum efeito sobre ele. Como os catcodes do segundo {345}ainda não foram corrigidos, as alterações ainda serão aplicadas a este grupo.

Este comportamento é bastante útil se você deseja injetar código extra em macros existentes que lidam com alterações de catcode, por exemplo \verb(inspirado poresta pérola TeX):

\begingroup
\catcode`\/\active
\catcode`\_\active
\@firstofone{%
  \verb|%
  \catcode`\/\active \def/{\par}%
  \catcode`\_\active \def_#1_{\textcolor{blue}{#1}}%
}_\documentclass_{article}/_\begin_{document}/  We all love _\LaTeX_!/_\end_{document}|
\endgroup

quais saídas

saída

Não sei onde você leu sobre \@firstofoneisso, mas pode ter sido em um desses contextos.

informação relacionada