如何在 \edef 中放置条件构造

如何在 \edef 中放置条件构造

\ifthenelse正常工作,但在使用时\edef

\documentclass{article}
\usepackage{ifthen}
\newcommand\testing[1][]{%
    \edef\tmp{\ifthenelse{\equal{#1}{}}{Blank}{#1}}%
}
\begin{document}
    \testing
\end{document}

我得到:

! Undefined control sequence.
<argument> \equal 
                  {}{}
l.10 

\ifthenelse当我使用\putbib命令(来自bibunits包)时也收到此错误。

有办法解决这个问题吗?

答案1

放在\noexpand不应扩展的内部宏前面:

\documentclass{article}
\usepackage{ifthen}
\newcommand\testing[1][]{%
    \edef\tmp{\noexpand\ifthenelse{\noexpand\equal{#1}{}}{Blank}{#1}}%
}
\begin{document}
    \testing
\end{document}

如果你真的想扩展整个表达式,那么你只能使用完全可扩展的代码,而不要使用临时赋值等。你也可以\edef真的一个错误的条款来代替。

答案2

\ifthenelse在 中使用是不可能的\edef;马丁的方法只会推迟评估,因此\edef只会扩展#1(这可能是您想要的)。

为了测试一个参数是否为空,更安全的测试是

\if\relax\detokenize{#1}\relax
  <empty>
\else
  <not empty>
\fi

还可以定义“TF”变体:

\makeatletter
\newcommand{\ifEmptyTF}[1]{%
  \if\relax\detokenize{#1}\relax
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi}
\makeatother

然后你的代码就可以变成

\newcommand{\testing}[1][]{\ifEmptyTF{#1}{Blank}{#1}}

可以借助\pdfstrcmp(\strcmp在 XeTeX 中调用) 获得“扩展”版本:

\usepackage{pdftexcmds}
\makeatletter
\newcommand{\ifExpandedEmptyTF}[1]{%
  \ifnum\pdf@strcmp{#1}{}=\z@
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi}
\makeatother

pdftex命令定义\pdf@strcmp独立于所使用的排版引擎来做正确的事情)。

例如\ifEmpty{\empty}将计算结果为 false,而\ifExpandedEmptyTF{\empty}将计算结果为 true,因为\empty定义为

\def\empty{}

相关内容