How to define a macro to create a new macro with a name passed as its argument?
Use \csname #1\endcsname
which must be expanded before \newcommand
using \expandafter
:
\newcommand\create[1]{%
\expandafter\newcommand\csname #1\endcsname{My name is #1}}
% usage: \create{foobar}
If you want to pass the macro as control sequence instead, i.e. \foobar
instead of foobar
then you need to turn it into a string and remove the backslash:
\makeatletter
\newcommand\create[1]{%
\expandafter\newcommand\csname\expandafter\@gobble\string#1\endcsname{My name is #1}}
\makeatother
% usage: \create{\foobar}
There is also the \@namedef
macro which is defined as \expandafter\def\csname #1\endcsname
, so you can use it as:
\newcommand\create[1]{\@namedef{My name is #1}}
The etoolbox
package also provides a basically identical, but robust macro called \csdef
. For both you can provide a parameter text, e.g. for arguments direct after the name argument: \csdef{name}#1#2{some code with two arguments #1 and #2}
(the #
have to be doubled inside another macro).
\documentclass{article}
\newcommand\create[1]{%
\expandafter\def\csname #1\endcsname{My name is #1}}
\begin{document}
\create{test}
\test
\end{document}
If you're going to be doing lots of this sort of thing, you can create a bunch of macros in one go from a comma separated list with some etoolbox
magic:
\usepackage{etoolbox}
\newcommand\create[1]{%
\expandafter\newcommand\csname #1\endcsname{My name is #1}}
\newcommand\createlist{%
\let\do\create
\docsvlist
}
The argument of \createlist
should be a list like: \createlist{foo,Foo,magic,jabberwocky}
and it will create \foo,\Foo,\magic,\jabberwocky