The TeXbook explains a nice feature when it comes to defining macros: In the ⟨parameter text⟩
of a macro-definition you can use #{
-notation for a macro whose last argument will be delimited by a left curly brace {
which—unlike other argument-delimiters—will be re-inserted as if it had been left in place.
Thus I sometimes use a macro-mechanism \NameToCs
which processes an argument which is delimited by a left curly brace ({
) and another argument which is nested in curly braces.
The argument nested in curly braces is taken for the name of a ⟨control sequence token⟩
which is to be constructed via \csname
..\endcsname
.
\NameToCs
works as follows:
\NameToCs⟨stuff not in curly braces⟩{NameOfCs}
→
⟨stuff not in curly braces⟩\NameOfCs
(If you wish to obtain only the control-sequence-token \NameOfCs
, then you can leave ⟨stuff not in curly braces⟩
empty: \NameToCs{NameOfCs} → \NameOfCs
)
\makeatletter
\newcommand\exchange[2]{#2#1}%
\@ifdefinable\NameToCs{\long\def\NameToCs#1#{\romannumeral0\innerNameToCs{#1}}}%
\newcommand\innerNameToCs[2]{\expandafter\exchange\expandafter{\csname#2\endcsname}{ #1}}%
\makeatother
There are various uses for such a macro:
\NameToCs{foo}
→ \foo
\NameToCs\string{foo}
→ \string\foo
\NameToCs\meaning{foo}
→ \meaning\foo
\NameToCs\global\long\def{foo}...
→ \global\long\def\foo...
\NameToCs\newcommand*{foo}...
→ \newcommand*\foo...
\NameToCs\NameToCs\global\let{foo}={bar}
→ \NameToCs\global\let\foo={bar}
→ \global\let\foo=\bar
Usage-example 5 can be applied within the ⟨balanced text⟩
of the definition of a macro \csnewcommand
:
\newcommand*\csnewcommand{\NameToCs\newcommand}%
Putting the pieces together in a MWE:
\documentclass{article}
% Define the macro \NameToCs:
\makeatletter
\newcommand\exchange[2]{#2#1}%
\@ifdefinable\NameToCs{\long\def\NameToCs#1#{\romannumeral0\innerNameToCs{#1}}}%
\newcommand\innerNameToCs[2]{\expandafter\exchange\expandafter{\csname#2\endcsname}{ #1}}%
\makeatother
% Define \csnewcommand and \csrenewcommand and \csProvideCommand and \csDeclareRobustCommand
\newcommand*\csnewcommand{\NameToCs\newcommand}%
\newcommand*\csrenewcommand{\NameToCs\renewcommand}%
\newcommand*\csProvideCommand{\NameToCs\ProvideCommand}%
\newcommand*\csDeclareRobustCommand{\NameToCs\DeclareRobustCommand}%
\csnewcommand*{FooValue}{FooValue's First Value}
% This throws an error:
%\csnewcommand*{FooValue}{FooValue's Second Value}
% This does not throw an error.
%\csrenewcommand*{FooValue}{FooValue's Second Value}
\csnewcommand*{Some Macro}{Some Macro's First Value}
% This throws an error:
%\csnewcommand*{Some Macro}{Some Macro's Second Value}
% This does not throw an error.
%\csrenewcommand*{Some Macro}{Some Macro's Second Value}
\csnewcommand*{Some Other Macro}{Some Other Macro's First Value}
% This throws an error:
%\csnewcommand*{Some Other Macro}{Some Other Macro's Second Value}
% This does not throw an error.
\csrenewcommand*{Some Other Macro}{Some Other Macro's Second Value}
\begin{document}
\noindent
\texttt{\NameToCs\string{FooValue}} is defined as \texttt{\NameToCs\meaning{FooValue}}\\
Expanding \texttt{\NameToCs\string{FooValue}} yields: \NameToCs{FooValue}
\bigskip
\noindent
\texttt{\NameToCs\string{Some Macro}} is defined as \texttt{\NameToCs\meaning{Some Macro}}\\
Expanding \texttt{\NameToCs\string{Some Macro}} yields: \NameToCs{Some Macro}
\bigskip
\noindent
\texttt{\NameToCs\string{Some Other Macro}} is defined as \texttt{\NameToCs\meaning{Some Other Macro}}\\
Expanding \texttt{\NameToCs\string{Some Other Macro}} yields: \NameToCs{Some Other Macro}
\end{document}

csdef
but find it hard to belive that a similar macro is not already built in.