2

How do I define a \newcommand (or in LaTeX 3 a \NewDocumentCommand) which itself defines a \newcommand with arguments. For example in

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

2 Answers 2

5

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}
3
3

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.

enter image description here

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .