# How to check if optional argument has its default value?

Is it possible to check whether some macro's optional argument has its default value and generate different output based on this condition?

For instance, say I defined:

\documentclass{article}

\newcounter{item}[section]
\newcommand{\myitem}[1][the default]{\refstepcounter{item}Item{{~\theitem}}: This is #1.\newline}

\begin{document}

\section{Default Item}

\myitem

\section{Special Items}

\myitem[special case 1]
\myitem[special case 2]

\end{document}


How can I have the counter in double curly braces only be output if the argument is not its default value? Specifically, I would like to remove the counter only from the single item in the first section in this example.

You can use xparse:

\documentclass{article}
\usepackage{xparse}

\newcounter{item}[section]
\NewDocumentCommand{\myitem}{o}{%
\par\noindent
\refstepcounter{item}%
Item\IfValueT{#1}{~\theitem}: %
This is \IfNoValueTF{#1}{the default}{#1}.\par
}

\begin{document}

\section{Default Item}

\myitem

\section{Special Items}

\myitem[special case 1]
\myitem[special case 2]

\end{document}


Not the best way (unless jumping into latex.ltx and tracking the \@xargdef etc. definitions)

First define the default argument as macro outside of \myitem and inside of \myitem check by \ifx\@temp@\myitemdefault (say).

\documentclass{article}

\newcounter{item}[section]

\makeatletter
\def\myitemdefault{the default}

\newcommand{\myitem}[1][\myitemdefault]{%
\edef\@temp@{#1}
\ifx\myitemdefault\@temp@%
This is the default stuff!%
\else
\refstepcounter{item}Item{{~\theitem}}: This is #1.%

\fi
}
\makeatother

\begin{document}

\section{Default Item}

\myitem

\section{Special Items}

\myitem[special case 1]
\myitem[special case 2]

\end{document}

• Does this have any restrictions? Will it also work if the default is itself a macro? Aug 25, 2017 at 20:17
• It won't work with unexpandable content in a macro
– user31729
Aug 25, 2017 at 20:22
• I'm not quite sure I understand. In the case at hand, \myitemdefault is actually defined as \def\uclinebackspace{\vspace{-\dimexpr\parskip+\baselineskip}}. After reading this post I'm not certain I understand. Is there something I can do with \protected to still make this work? Aug 25, 2017 at 20:28