4

I have a command defined with xparse that looks like this:

\NewDocumentCommand{\ME}{sogd<>}{\added[id=ME,remark={#1}]{#2}}

(for the full code see Passing complicated argument patterns to a new command)

Now, I want this to be defined through another command, something like

\newcommand{\definerevision}[1]{
    \NewDocumentCommand{\#1}{gg}{\added[id=#1,remark={??#1}]{??#2}}
}

(?? means "what to put here?")

That is \definerevision{INITIAL} expands to define the command \NewDocumentCommand{\INITIAL}{gg}{\added[id=INITIAL,remark={#1}]{#2}} (e.g. in the header)

There are two potential problems, the first is to expand \#1 and the second is that the argument #1 has to be distinguished between the top level command or the nested command (how to distinguish).

Is there a way to define a command through another command using \newcommand or \xparse?

  • 1
    Yes, there is ... For the inner command you need ##1 instead #1, etc, and the definition requires some more to-do... I'll try to answer it – user31729 Jun 1 '15 at 0:31
  • I am sure, you meant remark=##2, since ##1 is the starred optional argument. – user31729 Jun 1 '15 at 0:38
  • I tried to simplify the code for this question so I put simply ...{gg}{ ... #1 ... #2}. Also I put ?? to know what to put there. – alfC Jun 1 '15 at 0:41
  • Changed my solution to your {gg} macro – user31729 Jun 1 '15 at 0:46
6

Defining a command within another command requires to use the \csname #1 \endcsname approach for the \NewDocumentCommand (or \newcommand as well) (assuming #1 is the name of the new command, as argument of the outer command), preceeded by \expandafter

If a command is defined within another one, all parameter arguments characters # have to be doubled, it i.e. ##1, ##2, etc.

\documentclass{article}
\usepackage{xparse}

\newcommand{\added}[1]{%
\Large%
\textbf{Arg was #1}%
}

\newcommand{\definerevision}[1]{%
  \expandafter\NewDocumentCommand\csname #1\endcsname{gg}{\added[id=#1,remark={##1}]{##2}}%
}


\definerevision{MOE}  

\definerevision{LARRY}  

\definerevision{CURLY}  
\begin{document}

\MOE{Added}{only this}

\LARRY{Added}{other more important stuff}

\CURLY{Screwed}{up the whole thing}


\end{document}
  • Awesome. It is important not to put {} around \csname #1\endcsname (I did that mistake first) – alfC Jun 1 '15 at 0:52
  • \expandafter\NewDocumentCommand{\csname....} would try to expand { which is useless here... and believe me, I did that mistake too (some months ago ;-)) – user31729 Jun 1 '15 at 0:53

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.