# Testing for a “if not defined” boolean

How can I test for a not defined boolean?

I want to have

\usepackage{xr-hyper}
\usepackage{hyperref}

\providebool{is_single_book}
\booltrue{is_single_book}


in my main.tex and in each of the chapter TeX files.

if not defined is_single_book
\externaldocument{volume1}[http://mybook.com/volume1.pdf]
fi


So when I compile the entire book, \externaldocument{volume1}[http://mybook.com/volume1.pdf] isn't executed.

It doesn't have to be a boolean if something else is simpler or doesn't require an extra package.

• Why do you want "is not defined" rather than "true" and "false"? Does a package specify that boolean? – TeXnician Aug 16 '18 at 11:06
• So you essentially want a three-way switch: boolean undefined, boolean true and boolean false? Or can you simplify this to a simple two-valued logic with a true and false boolean? Since you use etoolbox commands you can use \ifcsundef{ifis_single_book}{<undef>}{<def>} to check if the boolean is_single_book is undefined. Note that \providebool makes sure the boolean is defined, so \ifcsundef{ifis_single_book} will execute the false branch. – moewe Aug 16 '18 at 11:06

While you could check if a bool is defined by using \ifcsundef{if...} (see comment from moewe), it looks as if you actually want a boolean which is always false if you are in a chapter tex file.

This can be archived by using \providebool, which defines the bool as false, iff is is not defined already:

Use

\newbool{is_single_book}
\booltrue{is_single_book}


\providebool{is_single_book}
\ifbool{is_single_book}{}{%
\externaldocument{volume1}[http://mybook.com/volume1.pdf]%
}


Even better would be to use toggles. They are almost the same but avoid name clashes and provide slightly better performance:

To use them, insert

\newtoggle{is_single_book}
\toggletrue{is_single_book}


\providetoggle{is_single_book}
\iftoggle{is_single_book}{}{%
\externaldocument{volume1}[http://mybook.com/volume1.pdf]%
}


in the chapters.

• +1 for toggles. – moewe Aug 16 '18 at 11:28
• Something seams to be wrong for the chapters part. \externaldocument{volume1}[http://mybook.com/volume1.pdf] isn't being executed. Is is_single_book true or fasle right after \providetoggle{is_single_book}? – Sandra Schlichting Aug 16 '18 at 12:34
• \externaldocument{volume1}[http://mybook.com/volume1.pdf] should be executed if is_single_book is false or undefined. – Sandra Schlichting Aug 16 '18 at 12:37

\providebool and \booltrue makes me think you are using etoolbox.

etoolbox booleans are just a thin wrapper around TeX's \newif.

That means that \newbool{<name>} defines \if<name>, so you can check if a boolean is defined by checking if \if<name> is defined.

\documentclass[british]{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{babel}
\usepackage{etoolbox}

\newcommand*{\ifboolundef}[1]{\ifcsundef{if#1}}

\newcommand*{\sabooleantest}[1]{%
bool \ttfamily{#1} is
\ifboolundef{#1}
{undefined}
{\ifbool{#1}
{true}
{false}}}

\begin{document}
\sabooleantest{flobbel}

\newbool{globbel}
\boolfalse{globbel}
\sabooleantest{globbel}

\newbool{hobbel}
\booltrue{hobbel}
\sabooleantest{hobbel}
\end{document}


bool flobbel is undefined

bool globbel is false

bool hobbel is true

The question is whether you really need something that comes down to a three-valued logic. Is a two-valued boolean not enough?

If you want to avoid problems in case the boolean is undefined, you could just check if a macro is undefined or defined. This also has two states, but unlike with booleans there are no errors if the thing is not defined.

\newcommand*{\mybool}{}
\ifcsundef{\mybool}
{not defined}
{defined}


You could also define 'permissive toggles' that are false if they don't exist

\documentclass[british]{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{babel}
\usepackage{etoolbox}

\newcommand*{\permissivetoggletrue}[1]{\csletcs{sa@ptogl@#1}{@empty}}
\newcommand*{\permissivetogglefalse}[1]{\csundef{sa@ptogl@#1}}
\newcommand*{\ifpermissivetoggle}[1]{\ifcsdef{sa@ptogl@#1}}

\begin{document}
flobbel
\ifpermissivetoggle{flobbel}
{true}
{false}

\permissivetoggletrue{globbel}
globbel
\ifpermissivetoggle{globbel}
{true}
{false}
\end{document}


This can also be done without etoolbox if you like those sort of things

\makeatletter
\newcommand*{\permissivetoggletrue}[1]{%
\expandafter\let\csname sa@ptogl@#1\endcsname\@empty}
\newcommand*{\permissivetogglefalse}[1]{%
\expandafter\let\csname sa@ptogl@#1\endcsname\@sa@undef}% this assumes \@sa@undef is undefined
\newcommand*{\ifpermissivetoggle}[1]{%
\ifcsname sa@ptogl@#1\endcsname
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi}
\makeatother

• I were only using etoolbox for this one thing, so if this package can be avoided, then it would be much appreciated. – Sandra Schlichting Aug 16 '18 at 11:34
• @SandraSchlichting Theoretically especially in my last two examples we could do away with etoolbox, but I would end up essentially copying (a bit of) code from that package, so why not load it? – moewe Aug 16 '18 at 11:38
• I see. Good point. – Sandra Schlichting Aug 16 '18 at 11:42

It doesn't have to be a boolean, if something else is simpler or doesn't require an extra package.

I think \ifdefined and \def provide what you're looking for. You don't need an extra package or any definition.

\def\isSingleBook{}


or, alternatively, \newcommand{\isSingleBook}{} or \providecommand{\isSingleBook}{}.

Then you can check with:

\ifdefined\isSingleBook
%% you're in the book
\else
%% you're not in the book
\fi