How to form "if ... or ... then" conditionals in TeX?
There are a number of approaches. Assuming you are looking for a purely primitive-based on, then something like
\ifnum\ifnum\x=1 1\else\ifnum\x=14 1\else0\fi\fi
=1 %
<do this>
\else
<do that>
\fi
Thus you use 'secondary' conditionals to convert the original problem into a simple TRUE/FALSE situation, where the 'outer' \ifnum
is simply testing for 0
or 1
. (This works as TeX keeps expanding until it finds a number when considering the outer \ifnum
.)
It's important to get the number-termination correct when using this approach. In the example, the spaces after \x=1
and \x=14
are required to get the correct outcome. With a bit more imagination, you can make more complex constructs using the same approach (for example, you can having combined OR and AND conditions in this way.)
An alternative method if the logic gets complex would be to include the 'payload' as separate macros:
\ifnum\x=1 %
\expandafter\myfirstcase
\else
\ifnum\x=14 %
\expandafter\expandafter\expandafter\myfirstcase
\else
\expandafter\expandafter\expandafter\mysecondcase
\fi
\fi
\def\myfirstcase{do this}
\def\mysecondcase{do that}
This is what you often see with larger 'to do' blocks. The \expandafter
use is 'good practice' but may not be needed depending on the exact nature of the code to insert.
\usepackage{etoolbox}
\newcommand{\mytest}[1]{%
\ifboolexpr{ test {\ifnumcomp{#1}{=}{1}} or test {\ifnumcomp{#1}{=}{14}} }
{do this}
{do that}}
\mytest{1} \mytest{14} \mytest{0}
There is also the xifthen package that provides for "composite" tests.
The package xintexpr implements boolean logic on arithmetic expressions. We can use therein the \pdfstrcmp
utility (if the engine makes it available) to compare strings.
\documentclass{article}
\usepackage{xintexpr}
\begin{document}
\def\x{14}
\xintifboolexpr { \x = 1 || \x = 14 }
{True}
{False}
\xintifboolexpr { even(\x) && \x < 24 }
{True}
{False}
\xintifboolexpr { \x = floor(sqrt(\x))^2 }
{True}
{False}
% \pdfstrcmp {text1}{text2} evaluates to 0 if text1 and text2 are equal
% to -1 if text1 comes first in lexicographic order, to +1 else
% To test if the strings are equal we thus use not(\pdfstrcmp {text1}{text2})
% (or we can use the ! as synonym of the "not" function)
\xintifboolexpr { 1=1 && (2=3 || 4<= 4 || not(\pdfstrcmp {abc}{def})) && !(2=4)}
{True}
{False}
\xintifboolexpr {\pdfstrcmp {abc}{def} = -1}
{True}
{False}
\end{document}
Compiled with PDFLaTeX:
The package can also be used with Plain TeX.
As seen above &&
is AND and ||
is OR. It is also possible to write 'and'
and respectively 'or'
(quotes mandatory).