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 :)

manthano
  • 1,040
  • 6
  • 19

1 Answers1

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
manthano
  • 1,040
  • 6
  • 19
  • 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 05 '16 at 07:09
  • @manthano: Do you mean something like \test{?ozymandias} or using the ? as a delimiter, more like \test?ozymandias? ??? –  Feb 05 '16 at 08: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 05 '16 at 08:57
  • @manthano: Hm, unsure how to achieve this at the moment. Since xparse is involved already, expl3 might come into action! –  Feb 05 '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 05 '16 at 10:33
  • @manthano: The problem with \test{\foo} is, that TeX tries to expand foo first, before it does anything with the inner \NewDocumentCommand –  Feb 05 '16 at 10:34
  • I managed to fix this and took the liberty to expand your answer. – manthano Feb 05 '16 at 13:19
  • @manthano: Ok, I've never thought about this way ;-) –  Feb 05 '16 at 13:23