How do you define one macro with arguments inside another


\documentclass{article}
\begin{document}

\newcommand{\test}[1]
{
\newcommand{#1}[2]
{\#1 \#2}
}

\test{\you}
\you{3}{4}
\end{document}


I would like the output to be "3 4" not "#1 #2" as I want the #1 #2 to be interpreted in the internal \newcommand as arguments.

Something like this works. (It also works with xparse in the same way.)

\documentclass{article}

\newcommand{\test}[1]{%
\expandafter\newcommand\csname #1\endcsname[2]{%
##1 and ##2}}
\test{you}

\usepackage{xparse}
\NewDocumentCommand{\xtest} {m}
{%
\expandafter\NewDocumentCommand\csname #1\endcsname {mm}
{##1 and also ##2}%
}
\xtest{andher}

\begin{document}

\you{3}{4}

\test{me}
\me{5}{6}

\andher{7}{8}

\xtest{andhim}
\andhim{9}{10}

\end{document}

• If you nest another level, you need to double the # again (####1). – jon Jul 8 '14 at 4:29

The LaTeX2e kernel defined \@namedef{<csname>} that could be used exactly for this purpose, as it is defined as:

\def\@namedef#1{\expandafter\def\csname #1\endcsname}


It sets up the definition of its argument as a control sequence, awaiting the actual replacement text as part of the usual \def construction.

\documentclass{article}

\makeatletter
\newcommand{\test}[1]{\@namedef{#1}##1##2{##1 and ##2}}
\makeatother

\begin{document}

\test{you}\you{3}{4}

\end{document}


\namedef{<csname>} expands to \expandafter\def\csname <csname>\endcsname, which expands to \def\<csname>.