TeX 引号使用 \ifx 短路可选参数

TeX 引号使用 \ifx 短路可选参数

在带有可选参数的命令中,如果我在可选参数中放入以 TeX 引号开头的字符串(例如“quote”),就会出错。请参阅下面示例中的底部条目。

这个例子比最简单的例子要多一些,因为我想在 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}

在此处输入图片描述

答案1

在你的最后一个测试中,当宏扩展时,TeX 正在执行

\ifx``quote''\relax

它当然会返回 true,因为\ifx比较了两个反引号。

仅当代码仅包含一个标记\ifx#1\relax时,才可以依赖该代码。您可以执行;在这种情况下,最后一个测试将执行#1\ifx\relax#1

\ifx\relax``quote''

`quote''会作为假枝的一部分消失。

\ifx\\#1\\ 代表什么?寻找其他方法来测试可选参数是否缺失。

编写此宏的最佳方法是xparse

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

例子

\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}

在此处输入图片描述

相关内容