Transcrever definições de comandos do LaTeX

Em vários lugares desta FAQ, perguntas são respondidas em termos de como programar uma macro LaTeX. Às vezes, essas macros também podem ajudar usuários do Plain TeX ou de outros pacotes; esta resposta tenta fornecer um guia rudimentar para transcrição de tais definições de macro para utilização em outros pacotes.

A razão pela qual o LaTeX tem comandos que substituem o \def é que existe uma filosofia geral dentro do LaTeX de que o usuário deve ser protegido de si mesmo: o usuário possui comandos diferentes conforme o comando a ser definido exista ( (\renewcommand) ou não (\newcommand), e se seu status não for o esperado pelo usuário, um erro é relatado. Um terceiro comando de definição, o \providecommand, apenas define se o comando resultante já não está definido; O LaTeX não tem um equivalente direto ao \def, que ignora o estado presente do comando. O comando final desse tipo é o \DeclareRobustCommand, que cria um comando “robusto” (isto é, que não se expandirá se estiver sujeito à “expansão protegida” do LaTeX); do ponto de vista do usuário do Plain TeX, o \DeclareRobustCommand eve ser tratado como uma versão sem verificação do \newcommand.

Comandos LaTeX são, por padrão, definidos \long; um * opcional entre o \newcommand e seus (outros) argumentos especifica que o comando não deve ser definido \long. O * é detectado por um comando \@ifstar que usa o \futurelet para alternar entre dois ramos e engole o *: usuários do LaTeX são encorajados a pensar no * como parte do nome do comando.

As verificações do LaTeX para comandos desconhecidos são feitas pelo \ifx, comparando uma construção \csname com \relax; como o argumento do nome do comando é o nome da sequência de controle desejado, isso acaba sendo um pouco cansativo. Já que #1 é o argumento necessário, temos:

\expandafter\ifx
  \csname\expandafter\@gobble\string#1\endcsname
  \relax
    ...
(\@gobble simplesmente joga fora seu argumento).

Os argumentos de um comando LaTeX são especificados por dois argumentos opcionais do comando de definição: uma contagem de argumentos (0–9: se a contagem for 0, o argumento opcional de contagem pode ser omitido) e um valor padrão para o primeiro argumento, se o primeiro argumento do comando definido for opcional. Então:

\newcommand\foo{...}
\newcommand\foo[0]{...}
\newcommand\foo[1]{...#1...}
\newcommand\foo[2][boo]{...#1...#2...}
No último caso, \foo pode ser chamado como \foo{goodbye}, o que equivale a \foo[boo]{goodbye} (usando o valor padrão atribuído ao primeiro argumento), ou como \foo[hello]{goodbye} (com um primeiro argumento explícito). A codificação de comandos com argumentos opcionais é exemplificada pela codificação do último \foo acima:
\def\foo{\futurelet\next\@r@foo}
\def\@r@foo{\ifx\next[%
    \let\next\@x@foo
  \else
    \def\next{\@x@foo[boo]}%
  \fi
  \next
}
\def\@x@foo[#1]#2{...#1...#2...}


Do you have any question? Ask on: latex.net.br - we love qood questions!