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

40

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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