How to define a macro to create a new macro with a name passed as its argument?

I want to define a macro \create that accept a single mandatory argument from which another new macro is created and named.

The following code snippet may speak clearer what I want to achieve. But the following code cannot be compiled because it is wrong. :-)

\documentclass{article}

\newcommand\create[1]{%
\newcommand\#1{My name is #1}}

\begin{document}
\create{test}
\test
\end{document}


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).

• Unbelievable. You beat me to it by 49 seconds! – Ian Thompson Aug 11 '11 at 8:59
• I guess that the fact you're using \newcommand (with the benefits that that brings) is why you didn't mention \@namedef. – Loop Space Aug 11 '11 at 9:01
• @Andrew: Yes, also \@namedef requires \makeatletter ... \makeatother, which is a little annoying. However, for packaged code without optional arguments \@namedef{#1}{My name is #1} would also be an easy option. – Martin Scharrer Aug 11 '11 at 9:05
• @xport: In this case you must define the macro globally, i.e. either use \global\@namdef{#1}{<content>} or, if you need \newcommand, \global\expandafter\let\csname #1\expandafter\endcsname\csname #1\endcsname. – Martin Scharrer Aug 11 '11 at 9:55
• @xport: You didn't provide the real example to explain why grouping is necessary. There are many tricks to define a macro in group, e.g. {\def\x{\def\foo{bar}}\expandafter}\x. But you should firstly persuade us (and yourself) to believe that it is necessary to use these tricks. – Leo Liu Aug 11 '11 at 10:22
\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

• With etoolbox, you can use \csdef, \csgdef then. – Leo Liu Aug 11 '11 at 10:28
• @Leo but then you don't have the protection from overwriting definitions that \newcommand gives you... – Seamus Aug 11 '11 at 11:17
• With the help of a simple shell script, you can use this to get a list of all the filenames of images in a directory, and create a command that includes each one... (That's what I used it for.) – Seamus Aug 11 '11 at 12:26

If you want to pass the macro name as a macro name:

\documentclass{article}

\newcommand{\create}[1]% #1 = macro name
{\bgroup
\def\foo{Hello World!}% local definition
\global\let#1=\foo
\egroup}

\begin{document}
\create{\mymacro}%
\mymacro
\end{document}

• What's the difference between this and \newcommand\create[1]{\def#1{Hello World!}}? Sorry, I don't know much about tex subtleties. – coldfix Sep 20 '17 at 21:34
• @coldfix - I knew \let would work. I wasn't sure about \def, especially if the macro itself has arguments: – John Kormylo Sep 21 '17 at 3:30