Non-letters in macro names

Novos usuários do LaTeX ficam surpresos ao perceberem que definições de macro contendo caracteres não alfabéticos, como, por exemplo,

\newcommand{\cul8r}{Goodbye!}
são incapazes de compilar. A razão é que a linguagem de macro do TeX, diferentemente da maioria das linguagens de programação, aceita exclusivamente letras em nomes de macros.

Existem várias técnicas para definir uma macro com um nome como \cul8r. Infelizmente, nenhuma das técnicas é particularmente boa:

  1. Use \csname\endcsname para definir e invocar a macro:
    \expandafter\newcommand\csname cul8r\endcsname{Goodbye!}
    Eu disse: ``\csname cul8r\endcsname''.
    
    Pro:
    Sem efeitos colaterais inesperados
    Con:
    Muito verborrágico para ser útil
  2. Defina um “gerador de comandos especiais” e use os comandos resultantes:
    \newcommand{\DefineRemark}[2]{%
      \expandafter\newcommand\csname rmk-#1\endcsname{#2}%
    }
    \newcommand{\Remark}[1]{\csname rmk-#1\endcsname}
    ...
    \DefineRemark{cul8r}{Goodbye!}
    ...
    \Remark{cul8r}
    
    Pro:
    Simples de usar, não muito desarrumado
    Con:
    Dificilmente faz o que planejamos (“experts” verão que você está definindo uma macro, mas outros provavelmente não o farão)
  3. Convença o TeX de que “8” é letra:
    \catcode`8 = 11 
    \newcommand{\cul8r}{Goodbye!}
    Eu disse: ``\cul8r''.
    
    Pro:
    \cul8r pode ser usado diretamente
    Con:
    É provável que interrompa outras utilizações do “8” (como números ou dimensões); assim, \setlength{\paperwidth}{8in} nos dirá:
    ! Número ausente, tratado como zero.
     
                       8
    
    Como regra geral, alterar códigos de categoria é algo para se usar in extremis, após exame detalhado das opções. É concebível que essa ação drástica possa ser útil para você, mas a maioria dos usuários comuns deve estar bem avisada a sequer tentar tal técnica.
  4. 4. Defina uma macro \cul que deve ser sempre seguida de “8r”:
    \def\cul8r{Goodbye!}
    Eu disse: ``\cul8r''.
    
    Pro:
    \cul8r pode ser usado diretamente
    Con #1:
    Dará problema se \cul for seguido de qualquer outra coisa além de “8r”, com um diagnóstico confuso — \cul99 produzirá:
    ! Uso de \cul não corresponde à definição dele.
    <*> \cul9
             9
    
    (o que confundiria alguém que sequer tenha percebido que havia uma definição de \cul no documento).
    Con #2:
    Silenciosamente, redefine o \cul existente, quando houver; consequentemente, a técnica não pode ser usada para definir duas macros, uma \cul8r e, digamos, uma \cul123 , no mesmo documento.
A técnica 3 é comumente usada — de forma limitada — na maioria dos pacotes LaTeX e no próprio LaTeX. A convenção é usar “@” nos nomes das macros internas para ocultá-las do usuário e, assim, evitar conflitos de nomes. Para esse fim, o LaTeX trata automaticamente “@” como letra ao processar classes e pacotes e como caractere especial quando processa o documento do usuário. A chave dessa técnica é a separação: internamente, um caractere não alfabético é usado para nomes de macro e o usuário não vê nada disso, enquanto o status permanece “congelado” em todas as definições criadas dentro da classe ou do pacote. Veja \@ e @ em nomes de macros para mais informações.

Note que o uso análogo da técnica 3 neste exemplo nos daria

\begingroup
  \catcode`8 = 11 
  \gdef\cul8r{Goodbye!}
  \gdef\later{\cul8r}
\endgroup
Eu disse: ``\later''.
que funciona, mas derruba o objeto do exercício. (\later tem o código de catálogo “congelado” para ‘8’, embora o valor volte ao normal no momento em que ele é usado; observe, ainda, o uso do comando primitivo \gdef, já que o \newcommand não pode criar uma macro que fique disponível fora do grupo.)

Recomendação: Escolha outro mecanismo (tal como \DefineRemark, acima) ou escolha outro nome para sua macro, um que contenha apenas letras comuns. Uma abordagem usual é utilizar algarismos romanos no lugar dos arábicos:

\newcommand{\culVIIIr}{Goodbye!}
o que estraga a intenção da piada implícita no exemplo \cul8r!

This answer last edited: 2009-06-03


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