Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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.

share|improve this question

2 Answers 2

up vote 3 down vote accepted

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}
share|improve this answer
    
Thanks! This is exactly what I needed. Out of curiosity, if I want to define a newcommand within a newcommand within a newcommand... n levels deep does ##...#1 reference the argument (where there are n#s)? –  Nate Ackerman Jul 8 at 4:28
    
If you nest another level, you need to double the # again (####1). –  jon Jul 8 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.

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

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.