[Tex/LaTex] Using the compulsory argument for the optional argument

argumentsmacrosoptional arguments

I am trying to define a command that takes two arguments, where one is optional. If the optional argument isn't given I would like the compulsory argument to be used for the optional argument.

For example:

\necommand{\foo}[2][#2]{#1 foo(#2)}

which would return:

IN: \foo[hello]{hi}      OUT: hello foo(hi)
IN: \foo{hi}             OUT: hi foo(hi)

Ideally it would be nice to keep it simple and use standard LaTeX with no packages. Thanks in advance!

Best Answer

The classical approach for this is to use \@dblarg:

\documentclass{article}

\makeatletter
\newcommand{\foo}{\@dblarg\ah@foo}
\def\ah@foo[#1]#2{#1 foo(#2)}
\makeatother

\begin{document}

No optional argument: \foo{xyz}

Optional argument: \foo[abc]{xyz}

\end{document}

enter image description here

With xparse it's easier:

\documentclass{article}
\usepackage{xparse}

\NewDocumentCommand{\foo}{om}{%
  \IfNoValueTF{#1}{#2}{#1} foo(#2)%
}

\begin{document}

No optional argument: \foo{xyz}

Optional argument: \foo[abc]{xyz}

\end{document}

Wherever you need the optional argument, you type \IfNoValueTF{#1}{#2}{#1}.

There's a much slicker way if you have xparse released 2017/02/10 (or later): an optional argument O can take as default any of the mandatory argument:

\documentclass{article}
\usepackage{xparse}

\NewDocumentCommand{\foo}{ O{#2} m }{%
  #1 foo(#2)%
}

\begin{document}

No optional argument: \foo{xyz}

Optional argument: \foo[abc]{xyz}

\end{document}

So we're telling \foo that, if the optional argument is missing (first call), the mandatory argument #2 should be used also as value for #1. In the second call, the optional argument is given, so it's substituted for #1.