Define a macro in terms of other macro names
With your present code
\def\expandafter\csname\a\b\endcsname{\c}
you are overwriting the TeX
primitive \expandafter
such that it must be followed by \csname\a\b\endcsname
. Then the construct
\expandafter\csname\a\b\endcsname
will expand to \c
. With an empty document nothing happens, but try to type something and you'll get a puzzling
! Use of \expandafter doesn't match its definition.
What you do want is to hold \def
for a while, so you must put the \expandafter
before it. The code
\documentclass{article}
\begin{document}
\def\a{A}
\def\b{B}
\def\c{CC}
\expandafter\def\csname\a\b\endcsname{\c}
\AB
\end{document}
will do what you expect.
My favourite reading about \expandafter
: A Tutorial on \expandafter
(TUGboat 9)
The control sequences \a
, \b
and \c
are already defined in the LaTeX 2ε-kernel.
\MYa
, \MYb
and \MYc
will be used instead.
For the sake of having fun playing around with (La)TeX's expansion-mechanisms, I offer the following approaches:
With this approach \csname
's triggering of expansion until finding a matching\endcsname
is used in combination with \expandafter
for tricking LaTeX into expanding things behind the \csname..\endcsname
-construct as well:
% Use LaTeX for compiling this:
\newcommand*\MYa{A}
\newcommand*\MYb{B}
\newcommand*\MYc{CC}
\expandafter\newcommand\csname\MYa\MYb\expandafter\endcsname\expandafter{\MYc}
\show\AB
\stop
You can also combine \expandafter
with \exchange
:
% Use LaTeX for compiling this:
\newcommand\exchange[2]{#2#1}
\newcommand*\MYa{A}
\newcommand*\MYb{B}
\newcommand*\MYc{CC}
\expandafter\exchange\expandafter{\expandafter{\MYc}}{\expandafter\newcommand\csname\MYa\MYb\endcsname}%
\show\AB
\stop
In many situations a variant of \exchange
is useful which adds curly braces:
% Use LaTeX for compiling this:
\newcommand\PassFirstToSecond[2]{#2{#1}}
\newcommand*\MYa{A}
\newcommand*\MYb{B}
\newcommand*\MYc{CC}
\expandafter\PassFirstToSecond\expandafter{\MYc}{\expandafter\newcommand\csname\MYa\MYb\endcsname}%
\show\AB
\stop
There is also the macro \name
which takes everything before the first pair of curly braces for one argument and everything within the first pair of curly braces for another argument and which returns things after having applied \csname..\endcsname
to the things within curly braces:
\name\newcommand{macro}...
→ \newcommand\macro...
\name\global\long\def{macro}...
→ \global\long\def\macro...
\name\string{macro}
→ \string\macro
\name{macro}
→ \macro
\name\name\let{macroA}={macroB}
→ \name\let\macroA={macroB}
→ \let\macroA=\macroB
% Use LaTeX for compiling this:
\newcommand*\MYa{A}
\newcommand*\MYb{B}
\newcommand*\MYc{CC}
\newcommand\exchange[2]{#2#1}%
\csname @ifdefinable\endcsname\name{%
\long\def\name#1#{\romannumeral0\innername{#1}}%
}%
\newcommand\innername[2]{%
\expandafter\exchange\expandafter{\csname#2\endcsname}{ #1}%
}%
\name\expandafter\newcommand\expandafter{\MYa\MYb}\expandafter{\MYc}%
% ->
% \romannumeral0\innername{\expandafter\newcommand\expandafter}{\MYa\MYb}\expandafter{\MYc}
% ->
% %\romannumeral0-expansion in progress
% \expandafter\exchange\expandafter{\csname\MYa\MYb\endcsname}{ \expandafter\newcommand\expandafter}\expandafter{\MYc}%
% -> ( \expandafter-chain "hits" \csname )
% %\romannumeral0-expansion in progress
% \exchange{\AB}{ \expandafter\newcommand\expandafter}\expandafter{\MYc}%
% ->
% %\romannumeral0-expansion in progress
% <space>\expandafter\newcommand\expandafter\AB\expandafter{\MYc}%
% ->
% %\romannumeral0-expansion terminated:
% \expandafter\newcommand\expandafter\AB\expandafter{\MYc}%
% -> ( \expandafter-chain "hits" \MYc )
% \newcommand\AB{CC}%
\show\AB
\stop
In case \PassFirstToSecond
is available:
% Use LaTeX for compiling this:
\newcommand*\MYa{A}
\newcommand*\MYb{B}
\newcommand*\MYc{CC}
\newcommand\PassFirstToSecond[2]{#2{#1}}%
\newcommand\exchange[2]{#2#1}%
\csname @ifdefinable\endcsname\name{%
\long\def\name#1#{\romannumeral0\innername{#1}}%
}%
\newcommand\innername[2]{%
\expandafter\exchange\expandafter{\csname#2\endcsname}{ #1}%
}%
\expandafter\PassFirstToSecond\expandafter{\MYc}{\name\newcommand*{\MYa\MYb}}%
\show\AB
\stop
My favourite reading about \expandafter
(and about how to keep the amount of \expandafter
short) is the thread "How can I know the number of expandafters when appending to a csname macro". ;-)