# Nested newcommand and expanding \@nil

I'm creating a command to generate a series of macros all with equivalent styling. i.e. something along the lines of 1

\newcustommacro{\macroA}{\textbf}

Now, I want my macro to have Special behavior if optional argument is not passed so I'm using David Carlisle's answer from that question.


\documentclass{standalone}

\makeatletter
\newcommand{\testA}[1][\@nil]{
\def\tmp{#1}%
\ifx\tmp\@nnil%
No arg: Hello%
\else
Yes arg: Bye(#1)%
\fi
}
\makeatother

\newcommand{\makeamacro}[2]{%
\makeatletter
\newcommand{#1}[1][\@nil]{
\def\tmp{##1}%
\ifx\tmp\@nnil%
No arg: Hello%
\else
Yes arg: #2(##1)
\fi
}
\makeatother
}

\makeamacro{\testB}{Bye}

\begin{document}

testA, no arg: \testA

testA, yes arg: \testA[arg]

testB, no arg: \testB

testB, yes arg: \testB[arg]

\end{document}

I doubled the #'s as required for passing arguments to nested newcommands. What do I need to do for the @'s? I'm stumped.

I have no averstion to xparse so if someone suggests a nested verison of egreg's answer to the same question linked above then that'd be ok too.

1: I know the example is just making a macro that is basically just \textbf{}

• Wrong position of \makeatletter and \makeatother – egreg Nov 26 '17 at 9:56

You're placing \makeatletter and \makeatother in the wrong place.

Whey you want to use macros with @ in their name, such as \@nnil, the whole code should be surrounded by \makeatletter and \makeatother:

\documentclass{article}

\makeatletter
\newcommand{\testA}[1][\@nil]{% <--- don't forget
\def\tmp{#1}%
\ifx\tmp\@nnil
No arg: Hello%
\else
Yes arg: Bye(#1)%
\fi
}

\newcommand{\makeamacro}[2]{%
\newcommand{#1}[1][\@nil]{% <--- don't forget
\def\tmp{##1}%
\ifx\tmp\@nnil
No arg: Hello%
\else
Yes arg: #2(##1)
\fi
}
}
\makeatother

\makeamacro{\testB}{Bye}

\begin{document}

testA, no arg: \testA

testA, yes arg: \testA[arg]

testB, no arg: \testB

testB, yes arg: \testB[arg]

\end{document}

This said, xparse is easier under this respect:

\usepackage{xparse}

\NewDocumentCommand{\testA}{o}{%
\IfNoValueTF{#1}
{No arg: Hello}%
{Yes arg: Bye(#1)}%
}

\NewDocumentCommand{\makeamacro}{mm}{%
\NewDocumentCommand{#1}{o}{%
\IfNoValueTF{##1}
{No arg: Hello}%
{Yes arg: #2(##1)}%
}%
}
• That was easy to fix. – tmgriffiths Nov 26 '17 at 22:54
• @tmgriffiths The concept of category codes is not so easy to grasp, but once one gets the hang of it, it becomes almost routine. ;-) – egreg Nov 26 '17 at 22:55

Do you search for something like that? (xparse)

\documentclass{article}
\usepackage{xparse}

\NewDocumentCommand{\testA}{o D(){Bye}}{
\IfNoValueTF {#1}
{No arg: Hello}
{Yes arg: #2(#1)}
}

\begin{document}

testA, no arg: \testA

testA, yes arg: \testA[arg]

testA, yes arg: \testA[arg](notbye)

\end{document}