# Variable persist outside environment

I am using the ifthen package for some conditional formatting. I am storing state in some booleans, but it seems that there is an issue with lexical scope. In particular, when a boolean is set within an environment, the value does not persist outside the environment.

Here is an example:

\documentclass{article}
\usepackage{ifthen}  % or xifthen
\newboolean{bool}
\setboolean{bool}{true}

\begin{document}
Start: \ifthenelse{\boolean{bool}}{T}{F}

\begin{itemize}
\item{item} \ifthenelse{\boolean{bool}}{T}{F}
\setboolean{bool}{false}
\item{item 2} \ifthenelse{\boolean{bool}}{T}{F}
\end{itemize}

End: \ifthenelse{\boolean{bool}}{T}{F}  \textit{(should be false)}
\end{document}


The output of this is:

   Start: T
* item T
* item F
End: T (should be false)


How might one preserve the value of the boolean set inside an environment so that it is accessible outside?

• ifthen and xifthen don't allow globally setting a boolean. You'll be luckier with etoolbox provided macros, that are much more powerful. – egreg Jul 5 '13 at 15:33
• Besides, if you use etoolbox toggles, internally you will only use one macro per toggle (booleans use three). – daleif Jul 5 '13 at 15:34

The package ifthen (and also xifthen) doesn't allow for globally setting booleans. You could define global booleans, by adding something like

\makeatletter
\def\newglobalboolean#1{%
\expandafter\@ifdefinable\csname if#1\endcsname{%
\expandafter\let\csname if#1\endcsname\iffalse
\expandafter\def\csname #1true\endcsname{%
\global\expandafter\let\csname if#1\endcsname\iftrue
}%
\expandafter\def\csname #1false\endcsname{%
\global\expandafter\let\csname if#1\endcsname\iffalse
}%
}}
\makeatother


After \newglobalboolean{foo}, acting with \setboolean{foo}{true} or \setboolean{foo}{false} will set the boolean globally. Example:

\documentclass{article}
\usepackage{ifthen}  % or xifthen

\makeatletter
\def\newglobalboolean#1{%
\expandafter\@ifdefinable\csname if#1\endcsname{%
\expandafter\let\csname if#1\endcsname\iffalse
\expandafter\def\csname #1true\endcsname{%
\global\expandafter\let\csname if#1\endcsname\iftrue
}%
\expandafter\def\csname #1false\endcsname{%
\global\expandafter\let\csname if#1\endcsname\iffalse
}%
}}
\makeatother

\newglobalboolean{bool}
\setboolean{bool}{true}

\begin{document}
Start: \ifthenelse{\boolean{bool}}{T}{F}

\begin{itemize}
\item{item} \ifthenelse{\boolean{bool}}{T}{F}
\setboolean{bool}{false}
\item{item 2} \ifthenelse{\boolean{bool}}{T}{F}
\end{itemize}

End: \ifthenelse{\boolean{bool}}{T}{F}  \textit{(should be false)}
\end{document}


However, the package etoolbox provides many more functions. You get the same output with

\documentclass{article}
\usepackage{etoolbox}

\newbool{foo}
\setbool{foo}{true}

\begin{document}
Start: \ifbool{foo}{T}{F}

\begin{itemize}
\item{item} \ifbool{foo}{T}{F}
\global\setbool{foo}{false}
\item{item 2} \ifbool{foo}{T}{F}
\end{itemize}

End: \ifbool{foo}{T}{F}  \textit{(should be false)}
\end{document}


Note that you can't say \newbool{bool}

Please comment the package \usepackage{ifthen} and put the below given code:

\def\boolean#1{#1}
\def\newboolean#1{\expandafter\newif\csname if#1\expandafter\endcsname\csname  #1false\endcsname}
\def\setboolean#1#2{\expandafter\global\csname #1#2\endcsname}
\def\ifthenelse#1#2#3{\csname if#1\endcsname#2\else#3\fi}


See the output.

• Sorry but I think that's a bad solution. Specially your definition of ifthenelse. If you do such things you should work with \expandafter\@firstoftwo – Marco Daniel Jul 5 '13 at 16:22
• One loses all the the features of ifthen, in this way. Not that I recommend to use it, but I can't recommend this solution either. – egreg Jul 5 '13 at 16:32
• Yea! That is why I told to comment that package and use the definition (for this particular situation). – Jagath Jul 5 '13 at 17:04