32

I wish to use \newcommand inside \newcommand. I can do a basic version of that, but the bit that I can't figure out is how to construct a nontrivial name for the inner \newcommand (i.e. by prepending a prefix to the argument of the outer \newcommand).

A minimal example to illustrate the problem:

\documentclass{report}

\newcommand{\defpill}[3]{
  \newcommand{\blue#1}{#2}
  \newcommand{\red#1}{#3}
}

\begin{document}

Let me define a pill (with apologies to chemists).
  \defpill{aspirin}{$A_2Sp_3$}{$A_2Sp_5$}
This should not print anything.

But I should now be able to use my new commands, for example the one
giving the formula of the red aspirin: \redaspirin. Or the blue one:
\blueaspirin.

\end{document}

The bit that doesn't work, I suspect, is the variable name of the inner commands (\blue#1 etc). A simpler example where the name of the inner command is just #1 works fine, but then I'd have to supply two names instead of having \defpill build them for me out of a single suffix.

How do I do that?

2

2 Answers 2

41

\csname is your friend:

\documentclass{report}

\newcommand{\defpill}[3]{%
  \expandafter\newcommand\csname blue#1\endcsname{#2}%
  \expandafter\newcommand\csname red#1\endcsname{#3}%
}

\begin{document}

Let me define a pill (with apologies to chemists).%
  \defpill{aspirin}{$A_2Sp_3$}{$A_2Sp_5$}
This should not print anything.

But I should now be able to use my new commands, for example the one
giving the formula of the red aspirin: \redaspirin. Or the blue one:
\blueaspirin.

\end{document}
4
  • 6
    It would be better to add % after the braces in the \newcommand to prevent additional spaces being inserted. Sep 16, 2011 at 20:44
  • 1
    Excellent, thanks knut, just what I needed! You taught me something new.
    – st01
    Sep 17, 2011 at 9:52
  • @PeterGrill What would happen if additional spaces were inserted? And actually, how would they be inserted, and where?
    – Rubens
    Jul 20, 2014 at 20:47
  • 1
    @Rubens: You can try experimenting and look carefully at the output. Also have a look at Tex Capacity Exceeded (if remove % after use of macro). Jul 21, 2014 at 2:59
12

Based on egreg's answer to my more-complicated issue here, you should also consider using \@namedef:

\documentclass{report}

\makeatletter
\newcommand{\defpill}[3]{%
  \@namedef{blue#1}{#2}%
  \@namedef{red#1}{#3}%
}
\makeatother

\begin{document}
Let me define a pill (with apologies to chemists).%
  \defpill{aspirin}{$A_2Sp_3$}{$A_2Sp_5$}
This should not print anything.

But I should now be able to use my new commands, for example the one
giving the formula of the red aspirin: \redaspirin. Or the blue one:
\blueaspirin.
\end{document}

You must log in to answer this question.

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