那么 \equal 怎样将 \relax 与另一个类似 \relax 的命令进行比较?

那么 \equal 怎样将 \relax 与另一个类似 \relax 的命令进行比较?

我正在实施特别指定LaTeX 中的列表数据结构,其中 \aaa扩展了 aaa 的值,\bbb扩展了 bbb 的值,为了显示 \bbb 在列表中位于 \aaa 的旁边,\NEXTaaa扩展为 bbb,并且我没有定义\NEXTbbb。这些定义是用 完成的\@namedef

使用 ifthen 宏来运行代码,我发现了一个(据说)错误。我无法将其\relax与类似宏进行比较\relax,例如扩展 后得到的宏\csname UndefinedCmd\endcsname

问题是:在 之后\let\abc\relax,如何使用 ifthen 宏成功进行比较\abc\relax我实际上得到的是\equal{\abc}{\relax}-> false!!! 这是 上的错误吗ifthen

梅威瑟:

\documentclass{article}
\usepackage{ifthen}

\begin{document}

\let\abc\relax

\ifthenelse{\equal{\abc}{\relax}}
  {Good!}
  {Bad :-(}

%% I read Bad :-( on PDF file.

\end{document}

答案1

您可能不应该使用ifthen。也许etoolbox\ifboolexpr或更强大的东西。但如果必须使用,这里有两个选项。

  1. 重新定义ifthen\isundefined未定义\relax

    \documentclass{article}
    \usepackage{ifthen}
    
    \makeatletter
    \def\TE@undef#1#2{%
      \TE@throw
      \noexpand\ifnum1=%
        \noexpand\ifx\noexpand\@undefined\noexpand#11\noexpand\fi
        \noexpand\ifx\relax\noexpand#11\noexpand\fi\space#2}
    \makeatother
    
    \begin{document}
    
    \let\abc\relax
    
    \ifthenelse{\isundefined{\abc}}
      {Good!}
      {Bad :-(}
    
    \end{document}
    
  2. 添加\isdefequal要执行的\ifx比较(参数必须是两个单独的标记):

    \documentclass{article}
    \usepackage{etoolbox}
    \usepackage{ifthen}
    
    \makeatletter
    \patchcmd\ifthenelse
      {\let\isundefined\TE@undef}
      {\let\isundefined\TE@undef
       \let\isdefequal\TE@isdefequal}
      {}{\FAILED}
    \long\def\TE@isdefequal#1#2#3{\TE@throw
      \noexpand\ifx\noexpand#1\noexpand#2#3}
    \makeatother
    
    \begin{document}
    
    \let\abc\relax
    
    \ifthenelse{\isdefequal{\abc}{\relax}}
      {Good!}
      {Bad :-(}
    
    \end{document}
    

答案2

虽然不是的直接替代品\ifthenelse,但功能更强大。

\documentclass{article}

\ExplSyntaxOn
\NewExpandableDocumentCommand{\xifthenelse}{mmm}
 {
  \bool_if:nTF { #1 } { #2 } { #3 }
 }

\cs_new_eq:NN \numtest     \int_compare_p:n
\cs_new_eq:NN \oddtest     \int_if_odd_p:n
\cs_new_eq:NN \fptest      \fp_compare_p:n
\cs_new_eq:NN \dimtest     \dim_compare_p:n
\cs_new_eq:NN \deftest     \cs_if_exist_p:N
\cs_new_eq:NN \namedeftest \cs_if_exist_p:c
\cs_new_eq:NN \eqdeftest   \token_if_eq_meaning_p:NN
\cs_new_eq:NN \streqtest   \str_if_eq_p:ee
\cs_new_eq:NN \emptytest   \tl_if_empty_p:n
\cs_new_eq:NN \blanktest   \tl_if_blank_p:n
\cs_new_eq:NN \boolean     \legacy_if_p:n
\cs_new:Npn \modetest #1
 {
  \str_case:nnF { #1 }
   {
    {h}{\mode_if_horizontal_p:}
    {v}{\mode_if_vertical_p:}
    {m}{\mode_if_math_p:}
    {i}{\mode_if_inner_p:}
   }
   {\c_false_bool}
 }
\cs_new:Npn \enginetest #1
 {
  \str_case:nnF { #1 }
   {
    {luatex}{\sys_if_engine_luatex_p:}
    {pdftex}{\sys_if_engine_pdftex_p:}
    {ptex}{\sys_if_engine_ptex_p:}
    {uptex}{\sys_if_engine_uptex_p:}
    {xetex}{\sys_if_engine_xetex_p:}
   }
   {\c_false_bool}
 }

\ExplSyntaxOff

\begin{document}

\let\abc\relax

\xifthenelse{\eqdeftest{\abc}{\relax}}{true}{false}

\xifthenelse{\eqdeftest{\abc}{\relax} && \numtest{0>1}}{true}{false}

\xifthenelse{\eqdeftest{\abc}{\relax} || \numtest{0>1}}{true}{false}

\xifthenelse{\enginetest{pdftex} || \enginetest{luatex}}{true}{false}

\end{document}

您可以使用括号&&来表示“与”、||表示“或”、!表示否定。

在此处输入图片描述

相关内容