0

For a package I'm writing, I would like to provide a customised way to create a new command. The idea is that the user will write something like

\DeclareFancyThing{\myfancything}{parameter1}{parameter2}

and then this will create a command \myfancything, which itself takes an argument or two.

I was pleased and surprised to find that the following MWE does actually work, and produces the words "fancy foo!" as expected:

\documentclass{article}

\newcommand{\mynewcommand}[2]{% \newcommand{#1}{fancy #2!}% }

\mynewcommand{\foo}{foo}

\begin{document} \foo \end{document}

However, I can't work out how to make it so that the generated command \foo itself takes an argument. Is there a way to do that?

The following might be expected to produce the words "fancy foo (bar)!", but it in fact gives the error "TeX capacity exceeded, sorry [input stack size=10000]."

\documentclass{article}

\newcommand{\mynewcommand}[2]{% \newcommand{#1}[1]{fancy #2 (#1)!}% }

\mynewcommand{\foo}{foo}

\begin{document} \foo{bar} \end{document}

I guess the issue is that the #1 refers to the first argument of \mynewcommand instead of the argument of \foo, but I don't know how to change that.

Edit: The question is rightly closed, so I can't post an answer - but in order to help future visitors, in case the comments get deleted, the following works fine and produces "fancy foo (bar)!".

\documentclass{article}

\newcommand{\mynewcommand}[2]{% \newcommand{#1}[1]{fancy #2 (##1)!}% }

\mynewcommand{\foo}{foo}

\begin{document} \foo{bar} \end{document}

N. Virgo
  • 4,289
  • 2
  • 26
  • 41
  • 3
    You need to double the #, i.e., ##1. For example \newcommand{\mynewcommand}[2]{ \newcommand{#1}[1]{fancy #2! ##1!} } works. But why would you want to do that when \newcommand already exists? – Marijn Aug 12 '22 at 06:39
  • @Marijn the reason is because I want my users (i.e. me) to be able to write \DeclareFancyThing{\foo}{1}{7}{14.2}{8}{hello} and then after that just write \foo{42}, instead of having to write \fancyThing{42}{1}{7}{14.2}{8}{hello} every time they use the command. Of course the user can write \newcommand{\foo}[1]{\fancyThing{#1}{1}{7}{14.2}{8}{hello}} themself, but since every document will contain several such lines I wanted to automate it. – N. Virgo Aug 12 '22 at 06:43
  • @Marijn it's not particularly easier, but it looks marginally more logical in the source code. It's all just aesthetics I guess. – N. Virgo Aug 12 '22 at 06:46
  • Of course it is your choice which interfaces you provide for users - however you could run into trouble trying to reinvent the wheel for only a small gain, so be careful what you wish for :) – Marijn Aug 12 '22 at 06:49
  • @Marijn fair enough, point well taken. If you want the points feel free to post your first comment as an answer and I'll accept it - it does answer the question as asked. – N. Virgo Aug 12 '22 at 06:51
  • 1
    Let me see if I can find a duplicate, it is a common technique for carrying over arguments in nested definitions (there is also ###1, ####1 etc. for deeper nesting). – Marijn Aug 12 '22 at 06:53
  • apart from needing ## you are missing % at ends of lines, your definition is creating multiple space tokens each time it is used – David Carlisle Aug 12 '22 at 08:02
  • @DavidCarlisle hopefully that's fixed now. – N. Virgo Aug 12 '22 at 08:14
  • 1
    @Marijn ###1 is nonsense. We have ##1 for first level of nesting, ####1 for second etc. We must to double all # in each next level. – wipet Aug 12 '22 at 08:16

0 Answers0