Como definir um comando que copia outro comando com um nome diferente?

Como definir um comando que copia outro comando com um nome diferente?

Espero criar um comando que automatize esse processo abaixo

\let\oldhat\hat

com algo neste formato:

\let\old(ARGUMENT)\(ARGUMENT)

tentei

\newcommand{\makeold}[1]{
    \expandafter\let\csname old#1\endcsname\csname#1\endcsname}
\makeold{hat} %This should rename \hat to \oldhat

mas isso me dá um erro de que tenho muitos \endcsname's. Estou entendendo mal o propósito de \csname?

Editar: eu tinha esquecido \letna minha tentativa.

Responder1

Está faltando um \lete um extra \expandafter. Esta definição funciona:

\newcommand{\makeold}[1]{%
   \expandafter\let
       \csname old#1\expandafter\endcsname
       \csname#1\endcsname
}

A execução de um comando como este é um pouco confusa, então deixe-me descrever como esse comando funciona:

\makeold{hat}expande para

\expandafter\let\csname oldhat\expandafter\endcsname\csname#1\endcsname

Em seguida, o primeiro \expandaftersalta sobre \lete expande o \csname. Expandir \csnamerecursivamente expande qualquer macro até atingir \endcsnamee formar uma macro a partir dos tokens encontrados dessa maneira. Em particular, expande o segundo \expandafterque salta para \endcsnameexpandir o segundo \csname, que se transforma \csname hat\endcsnameem \hat. O que sobra são os tokens, \let\oldhat\hatque é o que você queria fazer.

Responder2

É mais simples com etoolbox:

\usepackage{etoolbox}

\newcommand{\makeold}[1]{\csletcs{old#1}{#1}}

informação relacionada