Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

As the title says, I am currently trying to use etoolbox's \ifboolexpr statment on \notblank conditions but I am having issues with it. The code concerned looks like this :

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

It however generates a bunch of errors. Even trying something like this does not quite seem to work any better :

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

The maximum I am able to use without issues is (given as a MWE. To reproduce my issues, just substitute the \ifbookexpr statment) :

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

So my question is :

  • What am I doing wrong ?
  • How to solve it ?
share|improve this question
    
Please provide a minimal example! –  Marco Daniel Sep 1 '12 at 21:12
    
I edited it to give an MWE. The issues can be reproduced just by replacing the right bit of code. –  Samuel Albert Sep 1 '12 at 21:20
add comment

2 Answers

up vote 6 down vote accepted

The documentation of etoolbox states that the argument to \ifblank and to \notblank is not expanded. Therefore \notblank{\xyz} will return "true" no matter what's the definition of \xyz.

If you want complete expansion you have to ask for it explicitly, for example

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

The first instance returns true, while the second one returns false.

share|improve this answer
    
As I pointed out in my second exemple, my main problem here is that the code does not compile even without anything in the \notblank. Therefore, the expansion problem is in fact secondary for now. –  Samuel Albert Sep 1 '12 at 21:52
    
Well, nevermind, the real problem in my code was that I was apparently trying to use all of this an a piece of code that appears in an expend-only context, so using a robust way of expanding the storage macros first and using \ifboolexpe solved it. Therefore, your answer is good enough for me. –  Samuel Albert Sep 1 '12 at 22:08
add comment

The catoptions package has exactly what you need without further code. \xifblankFT means fully expanded not blank. There is also \oifblankFT, meaning one-step expanded not blank.

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

This type of boolean calculus is expensive. You only need to look at the tracelog to confirm this assertion. 99 percent of the time you can do with a much simpler test. For example, since \xifstrcmpFT is expandable, we have an economical test:

\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
share|improve this answer
    
This seems very nice but I cannot find documentation in the catoptions package about this kind of mechanics. Are you sure it is provided by this package and not another one that this one would load ? –  Samuel Albert Sep 2 '12 at 17:00
    
It is surely provided by catoptions package, not by any dependency. Unfortunately, official work hasn't allowed me to fully document catoptions package. You can email your needs to me and I will reply with a solution, if available. –  Ahmed Musa Sep 4 '12 at 2:00
    
ok, I will probably need to look further into it, along with the solution provided by etextools and try to really understand what's going on with the different packages I found allowing me to do this to try to determine if I really prefer one of these solutions. For now, I will stick with the solution of having \ifblank used only by the frontend and then to use only expandable \ifdefvoid statments in the internal mechanics. –  Samuel Albert Sep 4 '12 at 22:48
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.