etoolbox の \ifboolexpr ステートメントで \notblank を使用する

etoolbox の \ifboolexpr ステートメントで \notblank を使用する

タイトルにあるように、私は現在、etoolbox の条件\ifboolexprステートメントを使用しようとしています\notblankが、問題が発生しています。 関係するコードは次のようになります。

\ifboolexpr{%
  test {\notblank{\Temp@Temp@Text@a}} or %
  test {\notblank{\Temp@Temp@Text@b}} or %
  test {\notblank{\Temp@Temp@Text@c}}    %
}%
{}{}%

しかし、大量のエラーが発生します。次のようなことを試しても、あまり改善されないようです。

\ifboolexpr{%
  test {\notblank{}} or %
  test {\notblank{}} or %
  test {\notblank{}}    %
}%
{}{}%

問題なく使用できる最大値は次のとおりです (MWE として提供されます。問題を再現するには、ステートメントを置き換えるだけです\ifbookexpr)。

\documentclass[10pt,a4paper,titlepage,twoside,onecolumn]{report}
\RequirePackage{etoolbox}

\makeatletter
\def\Temp@Temp@Text@a{testa}
\def\Temp@Temp@Text@b{testb}
\def\Temp@Temp@Text@c{testc}

\makeatother

\begin{document}

\makeatletter

\ifboolexpr{%
  test {} or %
  test {} or %
  test {}    %
}%
{true}{false}%

\makeatother

\end{document}

私の質問は次のとおりです:

  • 何が間違っているのでしょうか?
  • どうすれば解決できますか?

答え1

の文書では、への議論とへのetoolbox議論は\ifblank\notblankない展開されます。したがって、\notblank{\xyz}の定義が何であっても、「true」を返します\xyz

完全な拡張が必要な​​場合は、明示的に要求する必要があります。たとえば、

\documentclass[10pt,a4paper,titlepage,twoside,onecolumn]{report}
\usepackage{etoolbox}

\begin{document}

\makeatletter

\def\Temp@Temp@Text@a{testa}
\def\Temp@Temp@Text@b{testb}
\def\Temp@Temp@Text@c{testc}

\begingroup\edef\x{\endgroup
  \noexpand\ifboolexpr{%
    test {\noexpand\notblank{\Temp@Temp@Text@a}} or 
    test {\noexpand\notblank{\Temp@Temp@Text@b}} or 
    test {\noexpand\notblank{\Temp@Temp@Text@c}}    
  }}\x{\typeout{true}}{\typeout{false}}%

\def\Temp@Temp@Text@a{}
\def\Temp@Temp@Text@b{}
\def\Temp@Temp@Text@c{}

\begingroup\edef\x{\endgroup
  \noexpand\ifboolexpr{%
    test {\noexpand\notblank{\Temp@Temp@Text@a}} or 
    test {\noexpand\notblank{\Temp@Temp@Text@b}} or 
    test {\noexpand\notblank{\Temp@Temp@Text@c}}    
  }}\x{\typeout{true}}{\typeout{false}}%

\makeatother

\end{document}

最初のインスタンスは を返しtrue、2 番目のインスタンスは を返しますfalse

答え2

パッケージにcatoptionsは、追加のコードなしで必要なものがすべて揃っています。\xifblankFT完全に展開され、空白ではない\oifblankFTという意味もあります1ステップ拡張、空白ではない

\documentclass{report}
\usepackage{catoptions}
\def\vgap{\par\bigskip}

\begin{document}
\def\tempa{testa}
\def\tempb{testb}
\def\tempc{testc}

First test (true):
\ifexprTF{%
  test {\xifblankFT{\tempa}} or
  test {\xifblankFT{\tempb}} or
  test {\xifblankFT{\tempc}}
}{
  true
}{
  false
}

\vgap
\def\tempa{}
\def\tempb{}
\def\tempc{}

Second test (false):
\ifexprTF{%
  test {\xifblankFT{\tempa}} or
  test {\xifblankFT{\tempb}} or
  test {\xifblankFT{\tempc}}
}{
  true
}{
  false
}

\def\tempd{x}

\vgap
Third test (false):
\ifexprTF{%
  ( test {\xifblankTF{\tempa}} or test {\xifblankTF{\tempb}} )
  and
  ( test {\xifblankFT{\tempc}} and test {\xifblankFT{\tempd}} )
}{
  true
}{
  false
}

\vgap
\def\tempe{00}
\newif\iftestbool

Fourth test (true):
\ifexprTF{%
  ( switch {tempe} or bool {testbool} )
  and
  (  ( test {\xifblankTF{\tempc}} and not test {\xifblankTF{\tempd}} )
     or
     ( test {\xifstrcmpTF\tempa\tempb} or not test {\ifxTF\tempc\tempd} )
  )
}{
  true
}{
  false
}
\end{document}

このタイプのブール計算はコストがかかります。このアサーションを確認するには、トレースログを見るだけで十分です。99 パーセントの確率で、はるかに簡単なテストで済みます。たとえば、は\xifstrcmpFT拡張可能なので、次のような経済的なテストがあります。

\def\do#1{\ifx\do#1\relax\else+\xifstrcmpFT{#1}{}01\expandafter\do\fi}
\ifnum0=\numexpr0\do\tempa\tempb\tempc\tempd\do
  true
\else
  false
\fi

関連情報