LaTeX \newcommand default argument: is empty?

Viewed 37186

I'm trying to write a simple example command that prints nothing without an argument, but with an argument it surrounds it with something.

I've read that the default value should be \@empty and the simple \ifx\@empty#1 condition should do the job:

\newcommand{\optarg}[1][\@empty]{%
\ifx\@empty#1  {}  \else  {(((#1)))}  \fi
}

\optarg % (((empty)))
\optarg{} % (((empty)))
\optarg{test} % (((empty))) test

The latter three commands all print the empty word for some reason, and I want the first two to print nothing and the last to print (((test))).

I'm using TeXLive/Ubuntu. An ideas?

4 Answers

Try the following test:

\documentclass{article}

\usepackage{xifthen}% provides \isempty test

\newcommand{\optarg}[1][]{%
  \ifthenelse{\isempty{#1}}%
    {}% if #1 is empty
    {(((#1)))}% if #1 is not empty
}

\begin{document}

Testing \verb|\optarg|: \optarg% prints nothing

Testing \verb|\optarg[]|: \optarg[]% prints nothing

Testing \verb|\optarg[test]|: \optarg[test]% prints (((test)))

\end{document}

The xifthen package provides the \ifthenelse construct and the \isempty test.

Another option is to use the ifmtarg package (see the ifmtarg.sty file for the documentation).

Using the LaTeX3 xparse package:

\usepackage{xparse}
\NewDocumentCommand\optarg{g}{%
  \IfNoValueF{#1}{(((#1)))}%
}

In the underlying TeX engine with which LaTeX is written, the number of arguments a command can take is fixed. What you've done with the default [\@empty] is ask LaTeX to examine the next token to see if it is an open square bracket [. If so, LaTeX takes the contents of square brackets as the argument, if not, the next token is put back into the input stream and the default \@empty argument is used instead. So to get your idea to work, you have to use square brackets to delimit the optional argument when present:

\optarg
\optarg[]
\optarg[test]

You should have better luck with this notation.

It's annoying that you can't use the same brackets for an optional argument as you use for a required argument, but that's the way it is.

Related