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.

Paul Gaborit's answer to How to detect if option provided via \tikzset uses

  • \newbool to define a new boolean
  • \booltrue to set a boolean, and
  • \ifbool to perform a conditional operation

all from the etoolbox package. Well, I have been using

  • \newtoggle to define a new toggle
  • \toggletrue to set a toggle, and
  • \iftoggle to perform a conditional operation

also from the same package.

Is there a difference between the two? Is one preferable over the other?


Code:

\documentclass{article}
\usepackage{etoolbox}

\newtoggle{ToggleCondition}
\newbool{BooleanCondition}

\newcommand*{\CheckBoolean}{\ifbool{BooleanCondition}{true}{false}}
\newcommand*{\CheckToggle}{\iftoggle{ToggleCondition}{true}{false}}

\begin{document}

\toggletrue{ToggleCondition}
ToggleCondition is \CheckToggle.

\togglefalse{ToggleCondition}
ToggleCondition is \CheckToggle.

\medskip
\booltrue{BooleanCondition}
BooleanCondition is now \CheckBoolean.

\boolfalse{BooleanCondition}
BooleanCondition is now \CheckBoolean.
\end{document}
share|improve this question
add comment

2 Answers

up vote 15 down vote accepted

\newbool{mybool} is almost the same as \newif, but it checks whether \ifmybool is already defined, which LaTeX doesn't:

\newrobustcmd*{\newbool}[1]{%
  \expandafter\@ifdefinable\csname if#1\endcsname{%
    \expandafter\newif\csname if#1\endcsname}}

There's also \providebool which does nothing if the conditional is already defined.

Similarly, \ifbool is a wrapper around the usual construction

\if...
  \expandafter\@firstoftwo
\else
  \expandafter\@secondoftwo
\fi

with a preliminary check whether the conditional is defined. So it can be used also for primitive conditionals:

\ifbool{hmode}{<something for horizontal mode>}{<something else>}

Instead \newtoggle{mytoggle} is defined by

\newrobustcmd*{\newtoggle}[1]{%
  \ifcsdef{etb@tgl@#1}
    {\etb@error{Toggle '#1' already defined}\@eha}
    {\cslet{etb@tgl@#1}\@secondoftwo}}

so it checks whether the toggle is already defined and, if not, it sets it to "false". The constructed macro \etb@tgl@mytoggle is either \@firstoftwo (corresponding to "true") or \@secondoftwo (corresponding to "false"). When one says

\iftoggle{mytoggle}{<true>}{<false>}

etoolbox simply checks whether the toggle is defined and, if it is, just puts \etb@tgl@mytoggle in the input stream, thus doing "the right thing", because it chooses either <true> or <false> depending if it is \@firstoftwo or \@secondoftwo.

Note that \toggletrue is defined as

\newrobustcmd*{\toggletrue}[1]{%
  \ifcsdef{etb@tgl@#1}
    {\cslet{etb@tgl@#1}\etb@toggletrue}
    {\etb@noglobal\etb@err@notoggle{#1}}}

so it can be preceded by \global: indeed \ifcsdef is expandable, so if the toggle foo is not defined, after \global\toggletrue{foo} we'd remain with

\global\etb@noglobal\etb@err@notoggle{#1}}

which becomes

\global\let\relax\relax\etb@err@notoggle{#1}

that effectively removes the \global by doing a harmless \let (almost harmless, because it can impact on the stack memory, but since there's an error raised anyway, the user will correct it). If instead the toggle \foo is defined, we remain with

\global\cslet{etb@tgl@foo}\etb@toggletrue

so, again,

\global\expandafter\let\csname etb@tgl@foo\endcsname\etb@toggletrue

where \etb@toggletrue is the same as \@firstoftwo. The same holds, of course, for \togglefalse.

Which one to prefer? If you plan to use also the traditional \if... syntax, then \newbool is needed. Otherwise it's just a matter of personal preference.

Both booleans and toggles can be used in boolean expression (\ifboolexpr), so there's no difference for that usage either. Note that \global\booltrue and \global\boolfalse are legal too.

share|improve this answer
add comment

The answer to this is specified in the etoolbox documentation under section 3.5 Boolean Flags (p 12 onward):

3.5.1 TeX Flags
Since the tools in this section are based on \newif internally, they may be used to test and alter the state of flags previously defined with \newif. They are also compatible with the boolean tests of the ifthen package and may serve as a LaTeX interface for querying TeX primitives such as \ifmmode. The \newif approach requires a total of three macros per flag.

This means that using \newbool{cs} is similar to \newif\ifcs which creates 3 macros: \ifcs, \cstrue and \csfalse.

3.5.2 LaTeX Flags
In contrast to the flags from section 3.5.1, the tools in this section require only one macro per flag. They also use a separate namespace to avoid name clashes with regular macros.

This uses a single macro for each flag. The reference to "namespace" implies that you can use

\newbool{mybool}
\newtoggle{mybool}

without running into problems.

Preference? User-specific, in my opinion. Back in the 80's, when memory availability was a concern, perhaps \newtoggle would have been preferred... but we live in the present, which doesn't have that restriction.


Some technical details from etoolbox.sty:

  • \newbool is equivalent to \newif, apart from making sure that the condition can be defined via \@ifdefinable:

    \newrobustcmd*{\newbool}[1]{%
      \expandafter\@ifdefinable\csname if#1\endcsname{%
        \expandafter\newif\csname if#1\endcsname}}
    
  • \newtoggle{cs} creates \etb@tgl@cs:

    \newrobustcmd*{\newtoggle}[1]{%
      \ifcsdef{etb@tgl@#1}
        {\etb@error{Toggle '#1' already defined}\@eha}
        {\cslet{etb@tgl@#1}\@secondoftwo}}
    
share|improve this answer
    
So basically, "no difference". :-) –  Peter Grill Mar 6 '13 at 0:13
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.