Definir uma macro a partir de um argumento

É comum querer um comando para criar outro comando: geralmente, alguém quer que o nome do novo comando seja derivado de um argumento. O LaTeX faz isso o tempo todo: por exemplo, \newenvironment cria comandos para iniciar e terminar ambiente, cujos nomes são derivados do nome do comando do ambiente.

A abordagem (aparentemente) óbvia:

\def\relay#1#2{\def\#1{#2}}
não funciona (o mecanismo TeX interpreta isso como uma estranha redefinição de \#). ). O macete é usar \csname, que é uma primitiva do TeX para gerar nomes de comandos a partir de texto aleatório, junto com \expandafter. A definição acima deve ser:
\def\relay#1#2{%
  \expandafter\def\csname #1\endcsname{#2}%
}
Com essa definição, \relay{blah}{bleah} é equivalente a \def\blah{bleah}.

Note que a definição de \relay omite as chaves em volta do ‘nome do comando’ no \newcommand que ele executa. Isso é porque elas não são necessários (na verdade, elas raramente o são) e, nessa circunstância, elas tornam o código da macro um pouco mais entediante.

O nome criado não precisa (é claro) ser [[[emph]]][[[LBRACE]]]apenas [[[RBRACE]]] o argumento:

\def\newrace#1#2#3{%
  \expandafter\def\csname start#1\endcsname{%
    #2%
  }%
  \expandafter\def\csname finish#1\endcsname{%
    #3%
  }%
}
Com os comandos
\def\start#1{\csname start#1\endcsname}
\def\finish#1{\csname finish#1\endcsname}
essas ‘raças’ poderiam se comportar um pouco como ambientes do LaTeX.


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