3

SE, lately I'm playing around with expl3 and xparse a little and I encountered following problem: I want to create a command which creates a new command -- similar to this post. This is not as hard, as long the second command doesn't have any arguments; trying to create a command, which accepts arguments is a little more tricky.

What I got so far:

\documentclass{article}
\usepackage{xparse}

\NewDocumentCommand\test{ m}
{
    \NewDocumentCommand#1 {m}
        {My name is \string#1, king of kings}
}

\begin{document}
\test{\ozymandias}
\ozymandias{\manthano}
\end{document}

This outputs My name is ozymandias, king of kings, which gives the correct sonnet, but not what I wanted. I know where the problem is, I just don't know how to fix it atm :)

  • 1
    The \string#1 is unclear! What do you expect this to do? – user31729 Feb 4 '16 at 23:25
  • 1
    The argument in the inner definition should be referred to with ##1 – egreg Feb 4 '16 at 23:47
  • @ChristianHupfer The \string#1 was used as an example, basically I just intended to do more complicated stuff. – manthano Feb 5 '16 at 7:04
2

I wonder about the \string#1 inside.

The new command inside can be constructed with

\expandafter\NewDocumentCommand\csname #1\endcsname{...}{....}

i.e. the name of the new sequence must be constructed first with \expandafter (first the name is given, then \NewDocumentCommand comes into action). The same approach has to be taken for the traditional \newcommand or \renewcommand etc.

However, the \test command must be used as \test{ozymandias}, without \!

Please note, that it is necessary to use ##1 to access the first argument of the inner macro (if this is wanted at all), subsequent arguments are numbered with ##2 etc.

\documentclass{article}
\usepackage{xparse}

\NewDocumentCommand{\manthano}{}{Manthano}

\NewDocumentCommand\test{ m}
{%
  \expandafter\NewDocumentCommand\csname #1\endcsname{m}{%
   My name is ##1, king of kings%
   }
}

\begin{document}
\test{ozymandias}
\ozymandias{\manthano}
\end{document}

EDIT: To use \test with \, you have to adapt the command to

\makeatletter
\NewDocumentCommand\test{ m}
{%
  \expandafter\NewDocumentCommand\csname\expandafter\@gobble\string #1\endcsname{m}{%
   My name is ##1, king of kings%
   }
}
\makeatother
  • Thanks for the answer; the ##1 was indeed on misaing piece of the puzzle. Before I'm accepting you answer, is there a way to write \test, so that it processes an argument starting with an `? I already tested some combination of \csname\@gobble\string #1\endcsname` but neither did it work properly nor do I think this is the LaTex3 approach (Btw. this is the reason, why I used the unlucky \string #1 example here). – manthano Feb 5 '16 at 7:09
  • @manthano: Do you mean something like \test{?ozymandias} or using the ? as a delimiter, more like \test?ozymandias? ??? – user31729 Feb 5 '16 at 8:26
  • Merde, I misspelled it. Somehow I cannot correct my comment on a mobile device, I will come back to it later. What I meant: I want the argument to start with \ and I tested \csname\@gobble\string #1\endcsname – manthano Feb 5 '16 at 8:57
  • @manthano: Hm, unsure how to achieve this at the moment. Since xparse is involved already, expl3 might come into action! – user31729 Feb 5 '16 at 10:22
  • I already thought about explicit expl3 usage, but I'm not used to it very well. I'll give it a try. Thank you – manthano Feb 5 '16 at 10:33

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.