7

In a command with an optional argument, if I put a string beginning with TeX quotes (e.g., ``quote'') in the optional argument, something goes wrong. See the bottom entry in the example below.

The example is a bit more than minimal because I wanted to show clearly both the input and the output in the PDF.

\documentclass{article}
\usepackage{csquotes}

\newcommand{\optional}[2][\relax]{%
    \ifx#1\relax
        [\emph{no first arg}]
    \else
        [\emph{arg\#1:} #1]
    \fi
    \{\emph{arg\#2:} #2\}%
}

\begin{document}

\begin{tabular}{l}
%
\verb|\optional[first]{second}|\\
\optional[first]{second}\\[1ex]
%
\verb|\optional[]{second}|\\
\optional[]{second}\\[1ex]
%
\verb|\optional{only}|\\
\optional{only}\\[1ex]
%
\verb|\optional[\enquote{quote}]{second}|\\
\optional[\enquote{quote}]{second}\\[1ex]
%
\verb|\optional[``quote'']{second}|\\
\optional[``quote'']{second}  % why does this go wrong?
\end{tabular}

\end{document}

enter image description here

lockstep
  • 250,273
musarithmia
  • 12,463

1 Answers1

7

In your last test, when the macro is expanded TeX is doing

\ifx``quote''\relax

which of course returns true, because \ifx compares the two backquotes.

The code \ifx#1\relax can be relied upon only if #1 consists of just one token. You could do \ifx\relax#1; in this case the last test would do

\ifx\relax``quote''

and `quote'' would disappear as part of the false branch.

See What does \ifx\\#1\\ stand for? for other ways to test if an optional argument is absent.

The best way to write this macro is with xparse:

\usepackage{xparse}
\NewDocumentCommand{\optional}{om}{%
  \IfNoValueTF{#1}
    {[\emph{no first arg}]}
    {[\emph{arg\#1:} #1]}%
  \{\emph{arg\#2:} #2\}%
}

Example

\documentclass{article}
\usepackage{csquotes}
\usepackage{xparse}

\NewDocumentCommand{\optional}{om}{%
  \IfNoValueTF{#1}
    {[\emph{no first arg}]}
    {[\emph{arg\#1:} #1]}%
  \{\emph{arg\#2:} #2\}%
}

\begin{document}

\begin{tabular}{l}
%
\verb|\optional[first]{second}|\\
\optional[first]{second}\\[1ex]
%
\verb|\optional[]{second}|\\
\optional[]{second}\\[1ex]
%
\verb|\optional{only}|\\
\optional{only}\\[1ex]
%
\verb|\optional[\enquote{quote}]{second}|\\
\optional[\enquote{quote}]{second}\\[1ex]
%
\verb|\optional[``quote'']{second}|\\
\optional[``quote'']{second}  % why does this go wrong?
\end{tabular}

\end{document}

enter image description here

egreg
  • 1,121,712