From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Mon, 2 Sep 2019 13:46:59 +0900 Subject: Initial commit --- macros/latex/contrib/boolexpr/README | 64 ++ macros/latex/contrib/boolexpr/boolexpr.dtx | 1170 ++++++++++++++++++++++++++++ macros/latex/contrib/boolexpr/boolexpr.ins | 81 ++ macros/latex/contrib/boolexpr/boolexpr.pdf | Bin 0 -> 221162 bytes macros/latex/contrib/boolexpr/boolexpr.sty | 176 +++++ 5 files changed, 1491 insertions(+) create mode 100644 macros/latex/contrib/boolexpr/README create mode 100644 macros/latex/contrib/boolexpr/boolexpr.dtx create mode 100644 macros/latex/contrib/boolexpr/boolexpr.ins create mode 100644 macros/latex/contrib/boolexpr/boolexpr.pdf create mode 100644 macros/latex/contrib/boolexpr/boolexpr.sty (limited to 'macros/latex/contrib/boolexpr') diff --git a/macros/latex/contrib/boolexpr/README b/macros/latex/contrib/boolexpr/README new file mode 100644 index 0000000000..aefb3b73bd --- /dev/null +++ b/macros/latex/contrib/boolexpr/README @@ -0,0 +1,64 @@ +% boolexpr : Purely expandable boolean expressions and switch (eTeX - v3.1 2009/09/30) +% +% The \boolexpr macro evaluate boolean expressions in a *purely expandable way*. +% +% \boolexpr{ A \OR B \AND C } expands to 0 if the logical expression is TRUE. +% +% A, B, C may be : +% - numeric expressions such as: x = y, x <> y, x > y or: x < y +% - boolean switches: \iftrue 0\else 1\fi +% - conditionals: \ifcsname whatsit\endcsname 0\else 1\fi +% - another \boolexpr: \boolexpr{ D \OR E \AND F } +% +% \boolexpr may be used with \ifcase: +% \ifcase\boolexpr{ A \OR B \AND C } +% What to do if true +% \else +% What to do if false +% \fi +% +% \switch remains *purely expandable* (it may be used inside \csname...\endcsname f.ex.) +% +% \switch +% \case{ boolean expression} to do in first case +% \case{ boolean expression} to do in second case +% \otherwise to do if no case were true +% \endswitch +% +% \switch may have an optional argument to repeat in each \case evaluation, e.g. : +% +% \switch[\value{myCounter}] +% %|--| ---------------------------------------------------> |--| +% \case{>=12}It's $>=12$% => \case will expand to : \case{\value{myCounter}>=12} +% \case{=1}It's $1$% => \case will expand to : \case{\value{myCounter}=1} +% \otherwise ... +% \endswitch +% +% or : *(NB the double curly braces)* +% \switch[\pdfstrcmp{dummy}}] +% %|-----| ------------------------------------------------> |-----| +% \case{{first}}It's "FiRsT"% => \case{\lowercase{\ifstrequal{dummy}}{first}} +% \case{{second}}It"s "SeCoNd"%=> \case{\lowercase{\ifstrequal{dummy}}{second} +% \endswitch +% +% ********************************************************************************* +% This work consists of the main source file boolexpr.dtx and the derived +% files : boolexpr.sty, boolexpr.pdf, boolexpr.ins +% +% Some examples are included in the documentation: it is preferable (albeit +% not necessary) to install boolexpr.sty before compiling the documentation. +% +% Unpacking: +% (a) If boolexpr.ins is present: +% etex boolexpr.ins +% (b) Without boolexpr.ins: +% etex boolexpr.dtx +% (c) If you insist on using LaTeX +% latex \let\install=y\input{boolexpr.dtx} +% (quote the arguments according to the demands of your shell) +% +% Documentation: +% (pdf)latex boolexpr.dtx +% makeindex -s gind.ist boolexpr.idx +% +% F Chervet - Jul-Sep 2009 \ No newline at end of file diff --git a/macros/latex/contrib/boolexpr/boolexpr.dtx b/macros/latex/contrib/boolexpr/boolexpr.dtx new file mode 100644 index 0000000000..c217b4ea29 --- /dev/null +++ b/macros/latex/contrib/boolexpr/boolexpr.dtx @@ -0,0 +1,1170 @@ +% \iffalse meta-comment +% boolexpr : purely expandable boolean expressions and switch (eTeX) [v3.14 2010/04/15] +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either +% version 1.3 of this license or (at your option) any later +% version. The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% +% Copyright (C) 2009 by Florent Chervet +% +% This work consists of the main source file boolexpr.dtx +% and the derived files +% boolexpr.sty, boolexpr.pdf, boolexpr.ins, +% +% Unpacking: +% (a) If boolexpr.ins is present: +% etex boolexpr.ins +% (b) Without boolexpr.ins: +% etex boolexpr.dtx +% (c) If you insist on using LaTeX +% latex \let\install=y\input{boolexpr.dtx} +% (quote the arguments according to the demands of your shell) +% +% Documentation: +% (pdf)latex boolexpr.dtx +% +%<*ignore> +\begingroup + \def\x{LaTeX2e}% +\expandafter\endgroup +\ifcase 0\ifx\install y1\fi\expandafter + \ifx\csname processbatchFile\endcsname\relax\else1\fi + \ifx\fmtname\x\else 1\fi\relax +\else\csname fi\endcsname +% +%<*install> +\input docstrip.tex +\Msg{************************************************************************} +\Msg{* Installation} +\Msg{* Package: boolexpr 2010/04/15 v3.14 provides purely expandable boolean expressions and switch (eTeX)} +\Msg{************************************************************************} + +\keepsilent +\askforoverwritefalse + +\let\MetaPrefix\relax +\preamble + +This is a generated file. + +boolexpr : a purely expandable boolean expressions and switch (eTeX) + +This work may be distributed and/or modified under the +conditions of the LaTeX Project Public License, either +version 1.3 of this license or (at your option) any later +version. The latest version of this license is in + http://www.latex-project.org/lppl.txt + +Copyright (C) 2009 by Florent Chervet + +This work consists of the main source file boolexpr.dtx +and the derived files + boolexpr.sty, boolexpr.pdf, boolexpr.ins, + +boolexpr : a purely expandable boolean expressions and switch (eTeX) +\endpreamble +\let\MetaPrefix\DoubleperCent + +\generate{% + \file{boolexpr.ins}{\from{boolexpr.dtx}{install}}% + \file{boolexpr.sty}{\from{boolexpr.dtx}{package}}% +} + +\obeyspaces +\Msg{************************************************************************} +\Msg{*} +\Msg{* To finish the installation you have to move the following} +\Msg{* file into a directory searched by TeX:} +\Msg{*} +\Msg{* boolexpr.sty} +\Msg{*} +\Msg{* To produce the documentation run the file `boolexpr.dtx'} +\Msg{* through LaTeX.} +\Msg{*} +\Msg{* Happy TeXing!} +\Msg{*} +\Msg{************************************************************************} + +\endbatchfile +% +%<*ignore> +\fi +% +%<*driver> +\listfiles +\edef\thisfile{\jobname} +\def\thisinfo{Purely expandable boolean expressions and switch (\eTeX).} +\def\thisversion{v3.14} +\def\thisdate{2010/04/15} +\let\loadclass\LoadClass +\def\LoadClass#1{\loadclass[abstracton]{scrartcl}\let\scrmaketitle\maketitle\AtEndOfClass{\let\maketitle\scrmaketitle}} +\documentclass[a4paper,oneside]{ltxdoc} +\usepackage[latin9]{inputenc} +\usepackage[american]{babel} +\usepackage{etex,holtxdoc,etextools,xspace,geometry,tocloft,fancyhdr,color,bbding,makecell,enumitem,framed,txfonts,relsize}\CodelineNumbered +\usepackage{fancyvrb,ifpdf} +\IfFileExists{\thisfile.sty} + {\RequirePackage{\thisfile}} + \relax +\ifpdf\usepackage{embedfile}\embedfile{\thisfile.dtx}\fi +\geometry{top=2cm,headheight=1cm,headsep=.3cm,bottom=1.4cm,footskip=.5cm,left=4cm,right=2cm} +\hypersetup{% + pdftitle={The boolexpr package}, + pdfsubject={An e-TeX package for more useful tools for LaTeX package writers}, + pdfauthor={Florent CHERVET}, + colorlinks,linkcolor=reflink,urlcolor=refurl, + pdfstartview={FitH}, + pdfkeywords={tex, e-tex, latex, package, boolexpr, boolean, ifthen, ifthenelse, conditionals}, + bookmarksopen=true,bookmarksopenlevel=2} +\begin{document} + \DocInput{\thisfile.dtx} +\end{document} +% +% \fi +% +% \CheckSum{396} +% +% \CharacterTable +% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z +% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z +% Digits \0\1\2\3\4\5\6\7\8\9 +% Exclamation \! Double quote \" Hash (number) \# +% Dollar \$ Percent \% Ampersand \& +% Acute accent \' Left paren \( Right paren \) +% Asterisk \* Plus \+ Comma \, +% Minus \- Point \. Solidus \/ +% Colon \: Semicolon \; Less than \< +% Equals \= Greater than \> Question mark \? +% Commercial at \@ Left bracket \[ Backslash \\ +% Right bracket \] Circumflex \^ Underscore \_ +% Grave accent \` Left brace \{ Vertical bar \| +% Right brace \} Tilde \~} +% +% \DoNotIndex{\begin,\CodelineIndex,\CodelineNumbered,\def,\DisableCrossrefs} +% \DoNotIndex{\DocInput,\documentclass,\EnableCrossrefs,\end,\GetFileInfo} +% \DoNotIndex{\NeedsTeXFormat,\OnlyDescription,\RecordChanges,\usepackage} +% \DoNotIndex{\ProvidesClass,\ProvidesPackage,\ProvidesFile,\RequirePackage} +% \DoNotIndex{\filename,\fileversion,\filedate,\let} +% \DoNotIndex{\@listctr,\@nameuse,\csname,\else,\endcsname,\expandafter,\@ehd,\@nil,\bex,\case,\endcase} +% \DoNotIndex{\gdef,\global,\if,\item,\newcommand,\nobibliography} +% \DoNotIndex{\par,\providecommand,\relax,\renewcommand,\renewenvironment} +% \DoNotIndex{\stepcounter,\usecounter,\nocite,\fi} +% \DoNotIndex{\@fileswfalse,\@gobble,\@ifstar,\@unexpandable@protect} +% \DoNotIndex{\AtBeginDocument,\AtEndDocument} +% \DoNotIndex{\frenchspacing,\MessageBreak,\newif,\PackageWarningNoLine} +% \DoNotIndex{\protect,\string,\xdef,\ifx,\texttt,\@biblabel,\bibitem} +% \DoNotIndex{\z@,\wd,\vrule,\voidb@x,\verb,\bibitem} +% \DoNotIndex{\hskip,\hfil,\hfill,\hsize,\hspace,\hss,\hbox,\hb@xt@,\escapechar} +% \DoNotIndex{\date,\ifdefined,\ifhmode,\ifmmode,\cr} +% \DoNotIndex{\box,\author,\advance,\multiply,\Command,\outer,\kern,\title,\tt} +% \DoNotIndex{\the,\space,\section,\subsection,\textwidth} +% \DoNotIndex{\",\@empty,\@latex@error,\makeatletter,\makeatother} +% \DoNotIndex{\maketitle,\parindent,\setbox} +% +% +% \makeatletter +% \lastlinefit999 +% \newif\ifboolexprLoaded +% \ifdefined\boolexpr\boolexprLoadedtrue\else\boolexprLoadedfalse\fi +% \newcommand\macrocodecolor{\color{macrocode}}\definecolor{macrocode}{rgb}{0.18,0.00,0.45} +% \newcommand\reflinkcolor{\color{reflink}}\definecolor{reflink}{rgb}{0.49,0.00,0.00} +% \newcommand\refurlcolor{\color{refurl}}\definecolor{refurl}{rgb}{0.00,0.00,1.00} +% \newcommand\cmdref[1]{\hyperref[#1]{\underline{\reflinkcolor\CS{#1}}}} +% \newcommand\cmdlabel[1]{\label{#1}\hyperdef{cmdlabel}{#1}{}} +% \definecolor{dg}{rgb}{0.02,0.37,0.00} +% \def\ThisPackage{\Xpackage{\thisfile}\xspace}\def\thispackage{\xpackage{\thisfile}\xspace} +% \fancyhf{}\fancyhead[L]{\thispackage\ -- \thisinfo} +% \fancyfoot[L]{\color[gray]{.35}\scriptsize\thispackage\quad\copyright\oldstylenums{2009}\,\lower.3ex\hbox{\NibRight}\,Florent Chervet} +% \fancyfoot[R]{\oldstylenums{\thepage} / \oldstylenums{\pageref{LastPage}}} +% \pagestyle{fancy} +% \fancypagestyle{plain}{\fancyhf{}\let\headrulewidth\z@\fancyfoot[R]{\oldstylenums{\thepage} / \oldstylenums{\pageref{LastPage}}}} +% +% \catcode`\§\active\def§{\par\nobreak\vskip-\parskip} +% \newlength\saveparskip\saveparskip.4\baselineskip +% \newcommand\restoreparskip{\parskip\saveparskip} +% \parindent\z@\parskip\saveparskip\topsep\z@\partopsep\z@ +% \g@addto@macro\macro@font{\macrocodecolor\let\AltMacroFont\macro@font} +% \def\smex{\leavevmode\hb@xt@2em{\hfil$\longrightarrow$\hfil}} +% \def\csred#1{\textcolor{red}{\cs{#1}}} +% \def\CSif\bgroup\ignorespaces#1{\bgroup\ignorespaces\ifx#1\unskip\else \CS{#1}\fi} +% \def\CSbf#1{\textbf{\CS{#1}}} +% \def\Repeat#1#2{\ifnum\numexpr#1\relax>0\relax #2\relax\Repeat{#1-1}{#2}\fi} +% \def\Xpackage{\@dblarg\X@package} +% \def\X@package[#1]#2{% +% \xpackage{#2\footnote{\noindent\xpackage{#2}: \href{http://www.ctan.org/tex-archive/macros/latex/contrib/#1}{\nolinkurl{CTAN:macros/latex/contrib/#1}}}}} +% \deffootnote{1em}{0pt}{\rlap{\textsuperscript{\thefootnotemark}}\kern1em} +% \def\nq{\,!\!=} +% \def\nq{<>} +% \def\ie{\textsl{ie.\,}} +% \newbox\Sharpbox\setbox\Sharpbox=\hbox{|#|} +% \newcommand\Sharp[1]{\usebox\Sharpbox|#1|} +% \newcommand\myfbox[2][3em]{\fbox{\hbox to#1{\hss#2\hss}}} +% \newbox\boxedb@x +% \newcommand\boxedbox[1]{\setbox\boxedb@x\vbox{#1}\fbox{\box\boxedb@x}} +% \DefineVerbatimEnvironment{VerbEx}{Verbatim}{gobble=1,commandchars=![],fontfamily=tt,fontseries=tt,fontshape=tt} +% \newcommand\evaluated{\textcolor{blue}} +% \newcommand\notevaluated{\textcolor{black}} +% \newcommand\stripmeaning{\expandafter\strip@prefix\meaning} +% +% \makeatother +% +% \title{\vskip-2.3cm\mdseries The {\bfseries \ThisPackage}\kern.6em package} +% \author{\small\xemail{florent.chervet@free.fr}} +% \date{\thisdate -- \thisversion} +% \subtitle{\thisinfo} +% +% +% \maketitle \vskip-2\baselineskip\strut +% +% \makeatletter\begingroup\let\@thefnmark\@empty\let\@makefntext\@firstofone +% \footnotetext{\noindent +% This documentation is produced with the |DocStrip| utility. +% \begin{tabbing} +% \qquad\=\smex\=To get the documentation, \= run (thrice):\quad\= \texttt{pdflatex \thisfile.dtx} \\ +% \>\>for the index:\>\>\texttt{makeindex -s gind.ist \thisfile.idx} \\ +% \>\smex\>To get the package, \> run:\> \texttt{etex \thisfile.dtx} +% \end{tabbing}§ +% The \xext{dtx} file is embedded into this pdf file thank to \xpackage{embedfile} by H. Oberdiek.} +% \endgroup\makeatother +% +% \deffootnote{1em}{0pt}{\rlap{\thefootnotemark.}\kern1em} +% +% \begin{abstract}\parindent0pt\noindent\parskip\medskipamount\small\abovedisplayskip=0pt\belowdisplayskip=0pt +% \vskip-\baselineskip +% \thispackage provides a purely expandable way to evaluate boolean expressions of the form: +% +% \hfil\framebox[.618\linewidth][c]{$\alpha\quad\cs{AND}\quad\beta\quad\cs{OR}\quad\gamma\quad\dots$}\hfil +% +% where $\alpha$\,,\, $\beta$\, and $\gamma$ are \textit{atomic expressions} of one of those 8 valid forms: +% \begin{center} +% \begin{tabular}{*{6}{>{\hskip4pt}c<{\hskip4pt}}} +% \myfbox{$x=y$} & \myfbox{$x\nq y$}\footnotemark & \myfbox{$xy$} & \myfbox{$x>=y$} \\[12pt] +% \multicolumn{3}{c}{\myfbox[4.5cm]{\cs{if}\meta{test}\ $0$\cs{else} $1$\cs{fi}}} & +% \multicolumn{3}{c}{\myfbox[4.5cm]{another \cs{boolexpr} evaluation}} +% \end{tabular}\end{center} +% \footnotetext{The choice of $\nq$ rather than $\char33\!=$ is due to \nameref{catcodes}.} +% +% where $x$ and $y$ are either numeric expressions (or dimensions, glue, muglue to test using |\dimexpr|, |\glueexpr| +% or |\muexpr| -- please refer to the \nameref{examples}) and \meta{test} may be a switch (\cs{iftrue} / \cs{iffalse} +% or a conditional\footnote{\cs{if}, \cs{ifcase}, \cs{ifcat}, \cs{ifcsname}, \cs{ifdefined}, \cs{ifdim}, \cs{ifeof}, +% \cs{iffontchar}, \cs{ifhmode}, \cs{ifinner}, \cs{ifmmode}, \cs{ifnum}, \cs{ifodd}, \cs{ifvmode}, \cs{ifvoid}, \cs{ifx}}). +% \thispackage abide by the precedence of |\AND| on |\OR|, +% and the whole expression is evaluated until the result is known (in other words, |\AND| and |\OR| are \textit{shortcut} +% boolean operators). +% +% \cmdref{boolexpr} will expand to \textbf{0} if the expression is \textbf{true}, making it proper to work with |\ifcase| +% Furthermore, \thispackage defines a \cmdref{switch} syntax which remains purely expandable. +% +% \textbf{Be aware that \cs{boolexpr} (a little like \cs{numexpr}) works only if its argument is purely expandable}; +% the same for \cs{switch}. If you wish a more general \cs{CASE} syntax refer to this excellent paper: +% \url{http://www.tug.org/TUGboat/Articles/tb14-1/tb38fine.pdf}. +% +% The \thispackage package is designed to work with an \eTeX{} distribution of \LaTeX{}: +% it is based on the \eTeX{} |\numexpr| primitive and requires no other package. +% +% \end{abstract}\vskip-.5\baselineskip +% +% \cftbeforesecskip=5pt plus2pt minus4pt +% \smallskip\setcounter{tocdepth}{2}\enlargethispage{\baselineskip} +% \renewcommand\contentsname{Contents\vskip-5pt} +% {\smaller\tableofcontents} +% +% \def\B#1{\texttt{[}\meta{#1}\texttt{]}} +% +% \catcode95 11^^A% _ +% \section{Introduction -- Using \thispackage : \cs{boolexpr} and \cs{switch}} +% +% \begin{declcs}{boolexpr}\,\M{boolean expression} +% \end{declcs}\cmdlabel{boolexpr} +% \cs{boolexpr} is a macro that takes for unique argument a series of \textit{atomic expressions} of the form:\par +% \hskip2em\begin{tabular}{r>{$}c<{$}l} +% numeric expr. & = & numeric expr. \\ +% numeric expr. & \nq & numeric expr. \\ +% numeric expr. & < & numeric expr \\ +% numeric expr. & <= & numeric expr \\ +% numeric expr. & > & numeric expr. \\ +% numeric expr. & >= & numeric expr. \\ +% \cs{if}& \meta{test}& 0\ \cs{else}\ 1\cs{fi}\\ +% \multicolumn{3}{c}{\cs{boolexpr}\{\meta{boolean expression}\}} +% \end{tabular}\par\noindent +% related by \CSbf{AND} or \CSbf{OR} (with the usual logical precedence). +% +% \textbf{\cs{boolexpr} expands to \textbf{0} if the whole expression is \textbf{true}} +% and to a non nul number if the whole expression is false. +% +% \cs{boolexpr} is \textbf{purely expandable}. +% +% \begin{framed} +% Therefore, testing may be used as follow:§ +% \begin{Verbatim}[gobble=1] +% \ifcase\boolexpr{ boolean expression } +% what to do if true +% \else +% what to do if false +% \fi +% \end{Verbatim} +% \end{framed} +% +% It is possible to use \texttt{switches} as boolean quantities into a \cs{boolexpr} expression +% with the syntax:§ +% \qquad|\ifswitch 0\else 1\fi| +% +% It is also possible to use |\ifdim|, |\ifnum| etc. (although it is not necessary because other forms +% of atomic expression can perform those tests more easily) and |\ifdefined|, |\ifcsname| etc. with +% the same syntax, f.ex.:§ +% \qquad|\ifcsname| \meta{cs-name} |\endcsname 0\else 1\fi| +% +% It means that if the conditional is \texttt{true} then the \textit{atomic expression} is \texttt{true} +% (expands to |0|), otherwise the \textit{atomic expression} is |false| (expands to non |0|). +% +% It is possible to test |dimensions| (or |glue| or |muglue|) by writing |\dimexpr| +% (or |\glueexpr| or |\muexpr|) in front of the \textit{atomic expression}; therefore, the following are valid atomic expressions:§ +% \hskip2em\begin{tabular}{rr>{$}c<{$}l} +% \cs{dimexpr} & dimen expr. & < & dimen expr \\ +% \cs{glueexpr} & glue expr. & \nq & glue expr. \\ +% \cs{muexpr} & mu expr. & = & mu expr. +% \end{tabular} +% +% It is allowed to group expressions inside the argument of |\boolexpr| by inserting another |\boolexpr| evaluation, f.ex.:§ +% \qquad|\boolexpr{ \boolexpr{ |$\alpha$ | \OR | $\beta$ |} \AND | $\gamma$ | }| +% +% The logical \textbf{NOT} operator can be achieved by writing for example:§ +% \qquad|\ifcase\boolexpr{|\meta{boolean expression}|} 1\else 0\fi| +% +% Finally, if the \meta{boolean expression} is missing:§ +%\qquad|\boolexpr{ }| expands to |1| (\ie |false|). +% +% \begin{declcs}{ifboolexpr}\,\M{boolean expression}\,\M{true part}\,\M{false part} +% \end{declcs} +% \cs{ifboolexpr} is the \LaTeX{} form of a |\boolexpr| test.\enlargethispage{\baselineskip} +% +% \cs{ifboolexpr} is purely expandable (provided \meta{true part} and \meta{false part} are so). +% +% +% \clearpage +% \subsection*{\CSbf{boolexpr} examples}\label{examples}\addcontentsline{toc}{subsection}{\cs{boolexpr} Examples} +% \vskip-\baselineskip The part of the expression that is evaluated \textcolor{blue}{is in blue} (the remainder is not evaluated). +% +% \begin{tabular}{m{9.5cm}>{\color{dg}\smex\tt}m{5.6cm}}\hline +% \begin{VerbEx} +% \ifcase\boolexpr{ !evaluated[45 > 80 \OR 5<>5 \AND] 5<4 } +% boolexpr is true +% \else boolexpr is false +% \fi +% \end{VerbEx} +% & +% \ifboolexprLoaded +% \ifcase\boolexpr{ 45 > 80 \OR 5<>5 \AND 5<4 } +% boolexpr is true +% \else boolexpr is false +% \fi +% \else +% boolexpr is false +% \fi +% \\ \hline +% \begin{VerbEx} +% \ifcase\boolexpr{ !evaluated[45 < 80 \OR] 5 = 5 \AND 0<>0 } +% boolexpr is true +% \else boolexpr is false +% \fi +% \end{VerbEx} +% & +% \ifboolexprLoaded +% \ifcase\boolexpr{ 45 < 80 \OR 5 = 5 \AND 0<>0 } +% boolexpr is true +% \else boolexpr is false +% \fi +% \else +% boolexpr is true +% \fi +% \\ \hline +% \begin{VerbEx} +% \ifcase\boolexpr{ !evaluated[\boolexpr{ 45 < 80 \OR !notevaluated[5 = 5] } \AND 0<>0] } +% boolexpr is true +% \else boolexpr is false +% \fi +% \end{VerbEx} +% & +% \ifboolexprLoaded +% \ifnum\boolexpr{ \boolexpr{ 45 < 80 \OR 5 = 5 } \AND 0<>0 }=0 +% boolexpr is true +% \else boolexpr is false +% \fi +% \else +% boolexpr is false +% \fi +% \\ \hline +% \begin{VerbEx} +% \ifcase\boolexpr{ !evaluated[12>0 \AND (4+3)*5 > 20] } +% boolexpr is true +% \else boolexpr is false +% \fi +% \end{VerbEx} +% & +% \ifboolexprLoaded +% \ifcase\boolexpr{ 12>0 \AND (4+3)*5 > 20} +% boolexpr is true +% \else boolexpr is false +% \fi +% \else +% boolexpr is true +% \fi +% \\ \hline +% \begin{VerbEx} +% \makeatletter +% \number\boolexpr{ !evaluated[\the\catcode`\@=11] } +% \end{VerbEx} +% & +% \ifboolexprLoaded +% \makeatletter +% $\number\boolexpr{\the\catcode`\@=11}$ §{\small(catcode of character @ is 11)} +% \else +% $0$ §{\small(catcode of character @ is 11)} +% \fi +% \\ \hline +% \begin{VerbEx} +% \makeatother +% \number\boolexpr{ !evaluated[\the\catcode`\@=11] \AND \ifdefined\@undefined 0\else 1\fi } +% \end{VerbEx} +% &\omit \\[-2ex] & \omit +% \ifboolexprLoaded {\color{dg}\smex +% $\number\boolexpr{\catcode`\@=11 \AND \ifdefined\@undefined 0\else 1\fi}$} \\ &\omit {\color{dg}\tt\small(catcode of character @ is 12)} +% \else {\color{dg}\smex +% $1$ {\small(catcode of character @ is 12)} } +% \fi +% \\ \hline +% \begin{VerbEx} +% \makeatletter +% \number\boolexpr{ !evaluated[3<4 \AND \@ifundefined{iftest}{1}]{\iftest 0\else 1\fi} } +% \end{VerbEx} +% & \omit\\[-2ex] & \omit +% \ifboolexprLoaded {\color{dg}\smex +% \makeatletter +% \number\boolexpr{ 3<4 \AND \@ifundefined{iftest}{1}{\iftest 0\else 1\fi} }: |\iftest| not defined \hfil} +% \else {\color{bg} \smex 1: |\iftest| not defined\hfil} +% \fi +% \\ \hline +% \begin{VerbEx} +% \makeatletter \newif\iftest \testtrue +% \number\boolexpr{ !evaluated[3<4 \AND \@ifundefined{iftest}]{1}!evaluated[{\iftest 0\else 1\fi}] } +% \end{VerbEx} +% & \omit\\[-2ex] & \omit +% \ifboolexprLoaded {\color{dg}\smex +% \makeatletter\newif\iftest\testtrue +% \number\boolexpr{ 3<4 \AND \@ifundefined{iftest}{1}{\iftest 0\else 1\fi} }: |\iftest| is true \hfil} +% \else {\color{bg} \smex 0: |\iftest| is true \hfil} +% \fi +% \\ \hline +% \begin{VerbEx} +% \ifcase\boolexpr{ !evaluated[\dimexpr 12pt + 1in > 8mm * 2 \AND \iftest 0\else 1\fi] } +% boolexpr is true +% \else boolexpr is false +% \fi +% \end{VerbEx} +% & +% \ifboolexprLoaded +% \newif\iftest \testtrue +% \ifcase\boolexpr{ \dimexpr 12pt + 1in > 8mm * 2 \AND \iftest 0\else 1\fi } +% boolexpr is true +% \else boolexpr is false +% \fi +% \else boolexpr is true +% \fi +% \\ \hline +% \begin{VerbEx} +% \ifcase\boolexpr{ !evaluated[0=0 \AND \ifcase\boolexpr{1=1 \AND 5<=5} 1\else 0\fi] } +% boolexpr is true +% \else boolexpr is false +% \fi +% \end{VerbEx} +% & +% \ifboolexprLoaded +% \ifcase\boolexpr{ 0=0 \AND \ifcase\boolexpr{ 1=1 \AND 5<=5 } 1\else 0\fi } +% boolexpr is true +% \else boolexpr is false +% \fi +% \else boolexpr is false +% \fi \footnotesize +% § $\alpha$ |\AND NOT( |$\beta$| \AND |$\gamma$| )| +% § $\!\!\!\!\!\!=\alpha$| \AND NOT |$\beta$| \OR |$\alpha$| \AND NOT |$\gamma$ +% \\ \hline +% \end{tabular} +% +% \ifboolexprLoaded Results in \textcolor{green}{green} were evaluated by \thispackage at compilation time. +% \else Results in \textcolor{green}{green} were not evaluated at compilation time: \thispackage was not found. +% \fi +% +% \clearpage +% \subsection*{The \CSbf{switch} syntax}\label{switchsyntax}\addcontentsline{toc}{subsection}{The \cs{switch} syntax} +% +% \begin{declcs}{switch}\\ +% \CSbf{case}\,\M{boolean expression}\quad... \\ +% \CSbf{case}\,\M{boolean expression}\quad... \\ +% \CSbf{otherwise}\quad... \\ +% \CS{endswitch} +% \end{declcs}\cmdlabel{switch} +% +% \thispackage defines a syntax for \cs{switch} conditionals which remains purely expandable: +% \iffalse +% \begin{VerbEx} +% \switch +% !textbf[\case]{ !meta[bool expr] } ... +% !textbf[\case]{ !meta[bool expr] } ... +% !textbf[\case]{ !meta[bool expr] } ... +% !textbf[\otherwise] ... +% \endswitch +% \end{VerbEx} +% \fi +% +% \textbf{Each part of the switch is optional.} That means: +% \begin{center} +% \begin{tabular}{m{.4\textwidth}m{.4\textwidth}} +% \begin{VerbEx}[frame=single] +% \switch +% !textbf[\case]{ !meta[bool expr] } ... +% !textbf[\case]{ !meta[beel expr] } ... +% !textbf[\case]{ !meta[bool expr] } ... +% !textbf[\otherwise] ... +% \endswitch +% \end{VerbEx} +% & +% \begin{VerbEx}[frame=single] +% \switch +% !textbf[\case]{ !meta[bool expr] } ... +% !textbf[\case]{ !meta[beel expr] } ... +% !textbf[\case]{ !meta[bool expr] } ... +% \endswitch +% \end{VerbEx} +% \\ +% \begin{VerbEx}[frame=single] +% \switch +% !textbf[\otherwise] ... +% \endswitch +% \end{VerbEx} +% & +% \begin{VerbEx}[frame=single] +% \switch +% \endswitch +% \end{VerbEx} +% \end{tabular}\\ +% are allowed by \thispackage. +% \end{center} +% +% +% +% \subsection*{\CSbf{switch} examples}\label{switchexamples}\addcontentsline{toc}{subsection}{switch examples} +% +% The part of the expression that is evaluated \textcolor{blue}{is in blue} (the remainder is not evaluated). +% +% \begin{tabular}{m{9.5cm}>{\color{dg}\smex\tt}m{5.6cm}}\hline +% \begin{VerbEx} +% !evaluated[\switch] +% !evaluated[\case{6>1 \AND 6<=5}$\geq 1$ and $\leq 5$%] +% !evaluated[\case{3<10}$> 5$ and $< 10$%] +% \case{3>10}$\geq 10$% +% !evaluated[\endswitch] +% \end{VerbEx} +% & +% \ifboolexprLoaded +% \switch +% \case{6>1 \AND 6<=5}$\geq 1$ and $\leq 5$% +% \case{3<10}$>5$ and $< 10$% +% \case{3>10}$\geq 10$% +% \endswitch +% \else +% $>5$ and $< 10$% +% \fi +% \\ \hline +% \begin{VerbEx} +% \edef\result{% +% !evaluated[\switch] +% !evaluated[\case{6>1 \AND 6<=5}$\geq 1$ and $\leq 5$%] +% !evaluated[\case{3<10}$> 5$ and $< 10$%] +% \case{3>10}$\geq 10$% +% !evaluated[\endswitch]} +% \end{VerbEx} +% & +% \ifboolexprLoaded +% \edef\result{% +% \switch +% \case{6>1 \AND 6<=5}$\geq 1$ and $\leq 5$% +% \case{3<10}$>5$ and $< 10$% +% \case{3>10}$\geq 10$% +% \endswitch} +% \else +% \def\result{$>5$ and $< 10$} +% \fi +% result:\par\stripmeaning\result +% \\ \hline +% \begin{VerbEx}[commandchars=!()] +% \newcounter{myCounter} \setcounter{myCounter}{2} +% \edef\result{% +% !evaluated(\switch)[\value{myCounter}=] +% !evaluated(\case{1}one)% +% | ----------------------------> | +% !evaluated(\case{2}two)% <=> \case{value{myCounter}=2} +% \case{3}three% +% \case{2}vartwo%(never found)% +% \otherwise something else% +% !evaluated(\endswitch)} +% +% \end{VerbEx} +% & +% \ifboolexprLoaded +% \newcounter{myCounter} \setcounter{myCounter}{2} +% \edef\result{% +% \switch[\value{myCounter}=] +% \case{2}two% +% \case{3}three% +% \case{2}vartwo% +% \otherwise something else% +% \endswitch} +% \else +% \edef\result{two} +% \fi +% result:\stripmeaning\result +% \\ \hline +% \begin{VerbEx}[commandchars=!()] +% !evaluated(switch)[\value{myCounter}] +% !evaluated(\case{=1})It's $1$% +% !evaluated(\case{=-1})It's $-1$% +% |-| -------------------------> |-| +% !evaluated(\case{>=0})It's $>=0$% <=> \case{\value{myCounter}>=0} +% \otherwise something else% +% !evaluated(\endswitch) +% \end{VerbEx} +% & +% \ifboolexprLoaded \loggingall +% \vspace*{2cm}% +% \switch[\value{myCounter}] +% \case{=1}It's $1$% +% \case{=-1}It's $-1$% +% \case{>=0}It's $>=0$% +% \otherwise something else% +% \endswitch +% \else It's $>=0$% +% \fi +% \\\hline +% \begin{VerbEx}[commandchars=!()] +% !evaluated(switch)[\pdfstrcmp{DuMmY}] +% !evaluated(\case{{First}})It's "First"% +% |-| -------------------------> |-| +% !evaluated(\case{{DuMmY})It's DuMmY% +% \otherwise something else% +% !evaluated(\endswitch) +% \end{VerbEx} +% & +% \ifboolexprLoaded +% \ifdefined\pdfstrcmp +% \vspace*{2cm}% +% \switch[\pdfstrcmp{DuMmY}] +% \case{{First}}It's "First"% +% \case{{DuMmY}}It's "DuMmY"% +% \otherwise something else% +% \endswitch +% \else It's It's "DuMmY"% +% \fi +% \else It's "DuMmY"% +% \fi +% \\\hline +% \end{tabular} +% +% \ifboolexprLoaded Results in \textcolor{green}{green} were evaluated by \xpackage{boolexpr.sty} at compilation time. +% \else Results in \textcolor{green}{green} were not evaluated at compilation time: \thispackage was not found. +% \fi +% +% \subsection{Purely expandable macros for tests with \xpackage{boolexpr}} +% +% Please refer to the \xpackage{etextools} package documentation at :§ +% \url{http://www.ctan.org/tex-archive/macros/latex/contrib/etextools/etextools.pdf} +% +% +% +% +% +% \StopEventually{ +% } +% +% \clearpage +% \section{Implementation} +% +% \subsection{The algorithm} \enlargethispage{2\baselineskip} +% +% The \emph{string} is the suite of \textit{atomic expressions} connected by |\AND| or |\OR|.§ +% The \emph{result} must be $0$ if the \emph{string} is true, and non zero if the \emph{string} is false.§ +% ``\emph{go to} |some macro|'' means: ``\emph{now expand} |some macro|''. +% +% \def\orbuffer{\textsc{or}-buffer} +% \begin{enumerate}[label=\fbox{\Alph*},itemsep=12pt] +% \item |\bex@OR| +% \begin{enumerate}[label=\arabic*)] +% \item Split the \emph{string} into two parts:\\ +% |#1| = before the first |\OR| (|#1| does not contain any |\OR|) \\ +% |#2| = after the first |\OR| +% \item If |#2| is blank: the \emph{string} contains no |\OR|\\ +% \hspace*{2em} then go to |\bex@AND| to test |\AND| relations in |#1| \\ +% Otherwise: test the |\AND| relations in |#1| and keep |#2| in a so called ``\orbuffer'' for further testing. +% \end{enumerate} +% \item |\bex@AND| \\ +% |#1| = \orbuffer\ for further testing if needed +% \begin{enumerate}[label=\arabic*)] +% \item Split the string ``before the first |\OR|'' (\ie the |#1| of A.1) into two parts:\\ +% |#2| = before the first |\AND| (|#2| is an \textit{atomic expression}) \\ +% |#3| = after the first |\AND| (|#3| does not contain any |\OR|) +% \item Then test |#2| (the \textit{atomic expression}): +% \begin{enumerate}[label=\textbullet\:] +% \item[TRUE:] \underline{If \Sharp3 is blank} then |#2| is either: +% \begin{enumerate}[label=\textbullet,topsep=0pt,partopsep=0pt,itemsep=0pt,parsep=0pt] +% \item an atomic expression alone +% \item the last atomic expression in \emph{string}, preceded by |\OR| +% \item an atomic expression preceded by |\OR| and followed by |\OR| +% \end{enumerate} +% In each of these 3 cases, the whole expression (\ie the \textit{string}) is true +% because |#2| is true (otherwise, we had known the result of the whole \textit{string} earlier, and +% were not into testing |#2|) \\ +% \underline{Now if \Sharp3 is not blank} then |#2| is followed by |\AND|:\\ +% \hspace*{2em} go to |\bex@ANDAND| to test the series of |\AND| +% \item[FALSE:] \underline{if the \orbuffer\ \Sharp1 is blank} then |#2| is either: +% \begin{enumerate}[label=\textbullet,topsep=0pt,partopsep=0pt,itemsep=0pt,parsep=0pt] +% \item an atomic expression alone +% \item an atomic expression followed a series of |\AND| (and no |\OR|) +% \item the last atomic expression of the \emph{string} +% \end{enumerate} +% In each or these 3 cases, the whole expression (\ie the \emph{string}) is false +% because |#2| is false (otherwise, the result would have been known earlier) \\ +% \underline{Now if the \orbuffer\ \Sharp1 is not blank,} then we have to do more tests to get the result:\\ +% \hspace*{2em} go to |\bex@OR| to split the \orbuffer\ (|#1| here) and continue testing... +% \end{enumerate} +% \end{enumerate} +% \item |\bex@ANDAND| \\ +% |#1| is the \orbuffer\ for further testing if needed +% \begin{enumerate}[label=\arabic*)] +% \item Split the string (\ie |#3| in B.2.\textsc{true}) into two parts:\\ +% |#2| : before the first |\AND| (|#2| is an \textit{atomic expression}) \\ +% |#3| : after the first |\AND| \\ \clearpage +% \item Test the \textit{atomic expression} |#2|: +% \begin{enumerate}[label=\textbullet\:] +% \item [TRUE:] \underline{If \Sharp3 is blank} then |#2| is the last atomic expression of a series of |\AND| +% (possibly followed by |\OR|). \\ +% Conclusion: the whole \emph{string} is true (otherwise, we would have concluded earlier +% that it was false and were not into testing |#2|... think about it) \\ +% \underline{Now if \Sharp3 is not blank} then |#2| is followed by |\AND| and we have to test further:\\ +% \hspace*{2em} go to |\bex@ANDAND| to test |#3|. +% +% \item [FALSE:] we do not have to test the following |\AND|: the |\AND|-connected series is false.\\ +% \underline{If the \orbuffer\ \Sharp1 is blank} then the whole \emph{string} is false. \\ +% \underline{Now if the \orbuffer\ \Sharp1 is not blank}: continue testing into this \orbuffer\ :\\ +% \hspace*{2em} go to |\bex@OR|. +% \end{enumerate} +% \end{enumerate} +% +% \end{enumerate} +% +% \subsection{Category codes considerations}\label{catcodes} +% +% At first glance, the author of this package wanted to test inequality with the operator $\char33\!=$. A problem arose +% because some languages make the character \char33\ active (f.ex. french). As far as babel changes the catcodes +% |\AtBeginDocument|, the category code of \char33\ is different in the preamble (12) than in the document (13). +% +% After all, it was possible to change the definitions after begin document but... if you try to make the = character +% active, you will (surprisingly) observe that a test like:§ +% \qquad|\ifnum 4=4 ok\fi|§ +% leads you to one of the following error messages:\parskip=0pt§ +% \begin{tabbing} +%\qquad\=|undefined control sequence =|\qquad\= if |=| is undefined \\ +%\>|missing = inserted for \ifnum|\> if |=| is defined. +% \end{tabbing}\restoreparskip +% +% The same apply for |<| or |>|. Therefore: such conditionals are possible for \TeX{} only if |=|\,,\,|<| and |>| +% have a category code of 12 (11 is forbidden too). +% +% Thus the choice of |<>| is far easier and more reliable than the c-like $\char33\!=$. +% +% \subsection{Identification} +% +% This package is intended to use with a \LaTeX{} distribution of \eTeX{}. +% +% \begin{macrocode} +%<*package> +\ProvidesPackage{boolexpr} + [2010/04/15 v3.14 Purely expandable boolean expressions and switch (eTeX)] +% \end{macrocode} +% \iffalse +% +% \fi +% +% \subsection{Special catcode} +% The colon (/) will be used as a delimiter. We give it a category code of 8 (as in \xpackage{etextools}): +% \iffalse +%% Make a colon (:) of catcode 4 (used as delimiter) +% \fi +% \begin{macrocode} +\let\bex@AtEnd\@empty +\def\TMP@EnsureCode#1#2{% + \edef\bex@AtEnd{% + \bex@AtEnd + \catcode#1 \the\catcode#1\relax + }% + \catcode#1 #2\relax +} +\TMP@EnsureCode{95}{11}% _ +\TMP@EnsureCode{47}{8}% / etextool delimiter +\TMP@EnsureCode{60}{12}% < +\TMP@EnsureCode{61}{12}% = +\TMP@EnsureCode{62}{12}% > +\TMP@EnsureCode{43}{12}% - +\TMP@EnsureCode{45}{12}% + +\TMP@EnsureCode{58}{8}% : delimitor +% \end{macrocode} +% \iffalse +% +% \fi +% +% \subsection{Tree helper macros} +% +% While reading the \texttt{log} file it is preferable to read |\@firstoftwo|/|\@secondoftwo| +% when the algorithm is making a choice (|\ifblank|) and |\bex@truepart|/|bex@falsepart| +% when the algorithm has just determined the result of an atomic expression. +% \iffalse +%% Three helper macros +% \fi +% \begin{macrocode} +\let\bex@truepart\@firstoftwo +\let\bex@falsepart\@secondoftwo +% \end{macrocode} +% \iffalse +% +% \fi +% +% +% \begin{macro}{\bex@nbk} +% The following macro is purely expandable and its code is most probably due to D. Arseneau (\xpackage{url.sty}). +% \cs{bex@nbk} means if \textbf{n}ot \textbf{b}lan\textbf{k}. +% \begin{macrocode} +\long\def\bex@nbk#1#2/#3#4#5//{#4} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\bex@ifoptchar} +% \cs{bex@ifoptchar} checks if a character is a single opening bracket `\,\textbf{[}\,`. +% \begin{macrocode} +\long\def\bex@ifoptchar#1[#2/#3#{\csname @\if @\detokenize{#1#2}@% + first\else second\fi oftwo\endcsname} +% \end{macrocode} +% \end{macro} +% +% \iffalse +% +% \fi +% +% \subsection{Atomic expression evaluation} +% +% The six possible numeric atomic expressions\, $x < y$\,, $x<=y$\,, $x > y$\,, $x>=y$\,, $x<>y$\, and $x=y$ are first +% transformed to their zero-form:§ +% |\numexpr| $x-y<0$\,,|\numexpr| $x-y>0$\,,|\numexpr| $x-y<>0$\,, |\numexpr| $x-y=0$\, etc. +% +% Before all, we need to know which relation is used in the atomic expression: +% +% \begin{macro}{\bex@rel} +% |\bex@rel| tests an \textit{atomic expression}: first determine its type +% (inferior to, superior to, equality, inequality, other |\boolexpr|) and then +% use the appropriate evaluation macro: +% \iffalse +%% \bex@rel tests each atomic expression: choose which evaluation macro to use first +% \fi +% \begin{macrocode} +\long\def\bex@rel#1{% + \bex@test_eval#1/{\bex@eval{#1}} + {\bex@test_neq#1<>//{\bex@neq #1/} + {\bex@test_infeq#1<=//{\bex@infeq #1/} + {\bex@test_inf#1=//{\bex@supeq #1/} + {\bex@test_sup#1>//{\bex@sup #1/} + {\bex@test_eq#1=//{\bex@eq #1/} + {\@latex@error{Unknown relation found while scanning + \noexpand\boolexpr!}\@ehd}//}//}//}//}//}//}} +% \end{macrocode} +% \end{macro} +% \iffalse +% +% \fi +% +% \begin{macro}{The test macros} +% They test each \textit{atomic expression} in order to determine its type: +% \iffalse +%% Tests macros to determine the type of each atomic expression +% \fi +% \begin{macrocode} +\def\bex@test_neq#1<>#2/{\bex@nbk#2/} +\def\bex@test_eq#1=#2/{\bex@nbk #2/} +\def\bex@test_infeq#1<=#2/{\bex@nbk #2/} +\def\bex@test_inf#1<#2/{\bex@nbk #2/} +\def\bex@test_supeq#1>=#2/{\bex@nbk #2/} +\def\bex@test_sup#1>#2/{\bex@nbk #2/} +\long\def\bex@test_eval#1#2/{% + \ifcat\noexpand#1\relax% #1 is a control sequence + \bex@test_Eval{#1} + \else \expandafter\@secondoftwo + \fi} +\long\def\bex@test_Eval#1#2\fi{\fi\csname @% + \ifx#1\the second% + \else\ifx#1\numexpr second% + \else\ifx #1\number second% + \else\ifx #1\dimexpr second% + \else\ifx #1\glueexpr second% + \else\ifx #1\muexpr second% + \else\ifx #1\value second% + \else first% + \fi\fi\fi\fi\fi\fi\fi oftwo\endcsname} +% \end{macrocode} +% \end{macro} +% \iffalse +% +% \fi +% +% \begin{macro}{Evaluation macros} +% They evaluate each \textit{atomic expression} according to its type: +% \iffalse +%% Evaluation macro that evaluates an atomic expression depending on its type: +% \fi +% \begin{macrocode} +\long\def\bex@true_or_false#1{\csname bex@% + \ifnum\numexpr#1 true\else false\fi part\endcsname} +\long\def\bex@false_or_true#1{\csname bex@% + \ifnum\numexpr#1 false\else true\fi part\endcsname} +% \end{macrocode} +% +% \iffalse +% +% \fi +% \begin{macrocode} +\def\bex@eq#1=#2/{\bex@true_or_false{#1-(#2)=0}} +\def\bex@neq#1<>#2/{\bex@false_or_true{#1-(#2)=0}} +\def\bex@infeq#1<=#2/{\bex@false_or_true{#1-(#2)>0}} +\def\bex@inf#1<#2/{\bex@true_or_false{#1-(#2)<0}} +\def\bex@supeq#1>=#2/{\bex@false_or_true{#1-(#2)<0}} +\def\bex@sup#1>#2/{\bex@true_or_false{#1-(#2)>0}} +\long\def\bex@eval#1{\bex@true_or_false{#1=0}} +% \end{macrocode} +% \end{macro} +% \iffalse +% +% \fi +% +% \subsection{\texttt{\textbf{\textbackslash AND}} and \texttt{\textbf{\textbackslash OR}} management} +% +% \begin{macro}{\bex@OR} +% |\bex@OR| splits the string to evaluate into two parts: before the first |\OR| and after: +% \iffalse +%% \bex@OR splits the string to evaluate into two parts: before the first \OR and after +% \fi +% \begin{macrocode} +\long\def\bex@OR#1\OR#2:{\bex@AND{#2}#1\AND:} +% \end{macrocode} +% \end{macro} +% \iffalse +% +% \fi +% +% \begin{macro}{\bex@AND} +% |\bex@AND| splits the string to evaluate into two parts: before the first |\AND| and after: +% \iffalse +%% \bex@AND splits the string to evaluate into two parts: before the first \AND and after: +% \fi +% \begin{macrocode} +\long\def\bex@AND#1#2\AND#3:{% + \bex@rel{#2} + {\bex@nbk #3//{\bex@ANDAND{#1}#3:}{+0}//} + {\bex@nbk #1//{\bex@OR#1:}{+1}//}} +% \end{macrocode} +% \end{macro} +% \iffalse +% +% \fi +% +% \begin{macro}{\bex@ANDAND} +% |\bex@ANDAND| evaluate successive \textit{atomic expressions} related by |\AND| until +% false is found or until the end if every expression is true: +% \iffalse +%% \bex@ANDAND evaluate successive atomic expressions related by \AND: +% \fi +% \begin{macrocode} +\long\def\bex@ANDAND#1#2\AND#3:{% + \bex@rel{#2} + {\bex@nbk #3//{\bex@ANDAND{#1}#3:}{+0}//} + {\bex@nbk #1//{\bex@OR#1:}{+1}//}} +% \end{macrocode} +% \end{macro} +% \iffalse +% +% \fi +% +% \begin{macro}{\boolexpr} +% |\boolexpr| is the entry point for evaluating boolean expressions: +% \iffalse +%% \boolexpr: the entry point for evaluating boolean expressions +% \fi +% \begin{macrocode} +\newcommand\boolexpr[1]{\bex@nbk #1//{\numexpr\bex@OR#1\OR:}{+1}//} +% \end{macrocode} +% \end{macro} +% \iffalse +% +% \fi +% +% \begin{macro}{\ifboolexpr} +% |\ifboolexpr| is the \LaTeX{} form of |\boolexpr| tests: +% \iffalse +%% \ifboolexpr: the LaTeX form of \boolexpr tests +% \fi +% \begin{macrocode} +\ifdefined\ifboolexpr% etoolbox defines ifboolexpr... +\PackageWarning{boolexpr}{\string\ifboolexpr\space has been defined before\MessageBreak + by etoolbox (I suppose) - Overwritting} +\renewcommand\ifboolexpr[1]{\bex@true_or_false{\boolexpr{#1}=0}} +\else +\newcommand\ifboolexpr[1]{\bex@true_or_false{\boolexpr{#1}=0}} +\fi +% \end{macrocode} +% \end{macro} +% \iffalse +% +% \fi +% +% \begin{macro}{\switch} +% \cs{switch} is not long to implement... see: +% \begin{macrocode} +\long\def \switch#1\endswitch {\bex@nbk#1//{\bex@switch_opt#1\endswitch}{}//} +\long\def \bex@switch_opt#1#2\endswitch{\bex@ifoptchar#1/[/ + {\bex@switch_opti#1#2\endswitch}{\bex@switch_opti[]#1#2\endswitch}}%] +\def \bex@switch_opti[#1]#2\endswitch {\bex@switch_otherwise[{#1}]#2\otherwise\endswitch} + +\def\bex@switch_otherwise[#1]#2\otherwise#3\endswitch{% + \bex@switch_case[{#1}]#2\case\endswitch + {\bex@nbk#3//{\bex@otherwise#3\endswitch}{}//} + \endswitch} + +\def\bex@switch_case[#1]#2\case#3\endswitch{\bex@nbk#2//% + {\bex@case[{#1}]#2\endcase% + {\bex@nbk#3//{\bex@switch_case[{#1}]#3\endswitch}\@firstoftwo//}}% + {\bex@nbk#3//{\bex@switch_case[{#1}]#3\endswitch}\@firstoftwo//}//} + +\long\def\bex@case[#1]#2#3\endcase{\ifboolexpr{#1#2}{\bex@after_endswitch{#3}}} + +\long\def\bex@after_endswitch#1#2\endswitch{#1} +\long\def\bex@otherwise#1\otherwise#2\endswitch{#1} +% \end{macrocode} +% \end{macro} +% +% \subsubsection{Purely expandable macros for tests with \xpackage{boolexpr}} +% +%\begin{macro}{\bex@pdfmatch} +% \begin{macrocode} +\long\def\bex@pdfmatch#1#2{\ifnum\pdfmatch{#2}{#1}=0 1\else0\fi} +% \end{macrocode} +%\end{macro} +% +% \begin{macro}{\bex@ifempty} +% \begin{macrocode} +\long\def\bex@ifempty#1{\if\relax\detokenize{#1}\relax0\else1\fi} +\long\def\bex_ifempty#1{\csname @\if\relax\detokenize{#1}\relax first\else second\fi oftwo\endcsname} +% \end{macrocode} +% \end{macro} +% +%\begin{macro}{\bex@ifblank} +% \begin{macrocode} +\long\def\bex@ifblank#1{\bex@nbk#1//10//} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\bex@ifx} +% \begin{macrocode} +\long\def\bex@ifx#1#2{\bex__ifx#1#2//} +\long\def\bex_ifx#1#2#3/#4#5#6//{\bex@nbk#6//{\ifx#1#2\bex_else#5\else\bex_fi#6\fi}{#5}//} +\long\def\bex_else#1\else#2\fi{\fi#1} +\long\def\bex_fi#1\fi{\fi#1} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\bex@comp} +% \begin{macrocode} +\long\def\bex@comp#1{\bex@ifoptchar#1/[/\bex@c@mp{\bex@c@mp@[\numexpr]}} +\long\def\bex@c@mp[#1#2]#3#4#5{% + \bex_ifempty{#2}{% + \ifx #1\dimexpr \bex@c@mp@\ifdim\dimexpr{#3}{#4}{#5}% + \else\ifx #1\numexpr \bex@c@mp@\ifnum\numexpr{#3}{#4}{#5}% + \else\ifx #1\glueexpr \bex@c@mp@\ifdim\glueexpr{#3}{#4}{#5}% + \else\ifx #1\muexpr \bex@c@mp@\ifdim\muexpr{#3}{#4}{#5}% + \else\ifx #1\number \bex@c@mp@\ifnum\numexpr{#3}{#4}{#5}% + \else\PackageError{boolexpr}{% + Invalid comparison test while scanning \string\bex@comp\MessageBreak + found: \detokenize{#1}}% + \fi\fi\fi\fi\fi}% + {\PackageError{boolexpr}{Invalid comparison test while scanning \string\bex@comp\MessageBreak + found: \detokenize{#1}}}} +\long\def\bex@c@mp@#1#2#3#4#5{#1#2#3#4#5 0\else 1\fi} +% \end{macrocode} +%\end{macro} +% +% \begin{macrocode} +\bex@AtEnd\let\bex@AtEnd\@undefined +% +% \end{macrocode} +% +% \subsection{Future developments : to do} +% +% \thispackage should work either with \eTeX{} or \eTeX-\LaTeX{}... +% +% May be build a ``real'' |\NOT| operator. +% +% \begin{History} +% \begin{Version}{2010/04/15 v3.14} +% \item \xpackage{etoolbox} now defines a \cs{ifboolexpr} macro (not purely expandable). \\ +% Fix has been done (with a warning) to be able to use \cs{ifboolexpr} from \thispackage. +% \end{Version} +% +% \begin{Version}{2009/09/30 v3.1} +% \item Support of |\pdfmatch| added (|\bex@pdfmatch|) \\ +% \end{Version} +% +% \begin{Version}{2009/09/03 v3.0 -- \eTeX{}- and Xe\TeX{}- stable} +% \item +% Many bug fixed in \cmdref{switch}. Tested on \LaTeX, pdf\LaTeX{} and Xe\LaTeX. +% \item +% Revision of this pdf documentation. +% \end{Version} +% +% \begin{Version}{2009/08/31 v2.9} +% \item +% Added |\value| in the ``list of exceptions'' (\cs{bex@test_Eval}) +% Enhancement of |\switch| with the optional first argument (refer to the examples). +% \end{Version} +% +% \begin{Version}{2009/08/13 v2.2} +% \item +% Small optimisation in \cs{bex@OR} +% \end{Version} +% +% \begin{Version}{2009/08/12 v2.1} +% \item +% Added the \cs{switch} syntax +% \item +% Small bug (|\numexpr| forgotten in the ``list of exceptions'' (\cs{bex@test_Eval}) +% \item +% Redesigned tests for better compilation +% \end{Version} +% +% \begin{Version}{2009/07/22 v1.0} +% \item +% First version. +% \end{Version} +% +% \end{History} +% +% \clearpage +% \PrintIndex +% +% \label{LastPage} +% \Finale \ No newline at end of file diff --git a/macros/latex/contrib/boolexpr/boolexpr.ins b/macros/latex/contrib/boolexpr/boolexpr.ins new file mode 100644 index 0000000000..12b391e4a3 --- /dev/null +++ b/macros/latex/contrib/boolexpr/boolexpr.ins @@ -0,0 +1,81 @@ +%% +%% This is file `boolexpr.ins', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% boolexpr.dtx (with options: `install') +%% +%% This is a generated file. +%% +%% boolexpr : a purely expandable boolean expressions and switch (eTeX) +%% +%% This work may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either +%% version 1.3 of this license or (at your option) any later +%% version. The latest version of this license is in +%% http://www.latex-project.org/lppl.txt +%% +%% Copyright (C) 2009 by Florent Chervet +%% +%% This work consists of the main source file boolexpr.dtx +%% and the derived files +%% boolexpr.sty, boolexpr.pdf, boolexpr.ins, +%% +%% boolexpr : a purely expandable boolean expressions and switch (eTeX) +\input docstrip.tex +\Msg{************************************************************************} +\Msg{* Installation} +\Msg{* Package: boolexpr 2010/04/15 v3.14 provides purely expandable boolean expressions and switch (eTeX)} +\Msg{************************************************************************} + +\keepsilent +\askforoverwritefalse + +\let\MetaPrefix\relax +\preamble + +This is a generated file. + +boolexpr : a purely expandable boolean expressions and switch (eTeX) + +This work may be distributed and/or modified under the +conditions of the LaTeX Project Public License, either +version 1.3 of this license or (at your option) any later +version. The latest version of this license is in + http://www.latex-project.org/lppl.txt + +Copyright (C) 2009 by Florent Chervet + +This work consists of the main source file boolexpr.dtx +and the derived files + boolexpr.sty, boolexpr.pdf, boolexpr.ins, + +boolexpr : a purely expandable boolean expressions and switch (eTeX) +\endpreamble +\let\MetaPrefix\DoubleperCent + +\generate{% + \file{boolexpr.ins}{\from{boolexpr.dtx}{install}}% + \file{boolexpr.sty}{\from{boolexpr.dtx}{package}}% +} + +\obeyspaces +\Msg{************************************************************************} +\Msg{*} +\Msg{* To finish the installation you have to move the following} +\Msg{* file into a directory searched by TeX:} +\Msg{*} +\Msg{* boolexpr.sty} +\Msg{*} +\Msg{* To produce the documentation run the file `boolexpr.dtx'} +\Msg{* through LaTeX.} +\Msg{*} +\Msg{* Happy TeXing!} +\Msg{*} +\Msg{************************************************************************} + +\endbatchfile +\endinput +%% +%% End of file `boolexpr.ins'. diff --git a/macros/latex/contrib/boolexpr/boolexpr.pdf b/macros/latex/contrib/boolexpr/boolexpr.pdf new file mode 100644 index 0000000000..aa821e5d56 Binary files /dev/null and b/macros/latex/contrib/boolexpr/boolexpr.pdf differ diff --git a/macros/latex/contrib/boolexpr/boolexpr.sty b/macros/latex/contrib/boolexpr/boolexpr.sty new file mode 100644 index 0000000000..7836e6d25e --- /dev/null +++ b/macros/latex/contrib/boolexpr/boolexpr.sty @@ -0,0 +1,176 @@ +%% +%% This is file `boolexpr.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% boolexpr.dtx (with options: `package') +%% +%% This is a generated file. +%% +%% boolexpr : a purely expandable boolean expressions and switch (eTeX) +%% +%% This work may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either +%% version 1.3 of this license or (at your option) any later +%% version. The latest version of this license is in +%% http://www.latex-project.org/lppl.txt +%% +%% Copyright (C) 2009 by Florent Chervet +%% +%% This work consists of the main source file boolexpr.dtx +%% and the derived files +%% boolexpr.sty, boolexpr.pdf, boolexpr.ins, +%% +%% boolexpr : a purely expandable boolean expressions and switch (eTeX) +\ProvidesPackage{boolexpr} + [2010/04/15 v3.14 Purely expandable boolean expressions and switch (eTeX)] + +% Make a colon (:) of catcode 4 (used as delimiter) +\let\bex@AtEnd\@empty +\def\TMP@EnsureCode#1#2{% + \edef\bex@AtEnd{% + \bex@AtEnd + \catcode#1 \the\catcode#1\relax + }% + \catcode#1 #2\relax +} +\TMP@EnsureCode{95}{11}% _ +\TMP@EnsureCode{47}{8}% / etextool delimiter +\TMP@EnsureCode{60}{12}% < +\TMP@EnsureCode{61}{12}% = +\TMP@EnsureCode{62}{12}% > +\TMP@EnsureCode{43}{12}% - +\TMP@EnsureCode{45}{12}% + +\TMP@EnsureCode{58}{8}% : delimitor + +% Three helper macros +\let\bex@truepart\@firstoftwo +\let\bex@falsepart\@secondoftwo + +\long\def\bex@nbk#1#2/#3#4#5//{#4} +\long\def\bex@ifoptchar#1[#2/#3#{\csname @\if @\detokenize{#1#2}@% + first\else second\fi oftwo\endcsname} + +% \bex@rel tests each atomic expression: choose which evaluation macro to use first +\long\def\bex@rel#1{% + \bex@test_eval#1/{\bex@eval{#1}} + {\bex@test_neq#1<>//{\bex@neq #1/} + {\bex@test_infeq#1<=//{\bex@infeq #1/} + {\bex@test_inf#1=//{\bex@supeq #1/} + {\bex@test_sup#1>//{\bex@sup #1/} + {\bex@test_eq#1=//{\bex@eq #1/} + {\@latex@error{Unknown relation found while scanning + \noexpand\boolexpr!}\@ehd}//}//}//}//}//}//}} + +% Tests macros to determine the type of each atomic expression +\def\bex@test_neq#1<>#2/{\bex@nbk#2/} +\def\bex@test_eq#1=#2/{\bex@nbk #2/} +\def\bex@test_infeq#1<=#2/{\bex@nbk #2/} +\def\bex@test_inf#1<#2/{\bex@nbk #2/} +\def\bex@test_supeq#1>=#2/{\bex@nbk #2/} +\def\bex@test_sup#1>#2/{\bex@nbk #2/} +\long\def\bex@test_eval#1#2/{% + \ifcat\noexpand#1\relax% #1 is a control sequence + \bex@test_Eval{#1} + \else \expandafter\@secondoftwo + \fi} +\long\def\bex@test_Eval#1#2\fi{\fi\csname @% + \ifx#1\the second% + \else\ifx#1\numexpr second% + \else\ifx #1\number second% + \else\ifx #1\dimexpr second% + \else\ifx #1\glueexpr second% + \else\ifx #1\muexpr second% + \else\ifx #1\value second% + \else first% + \fi\fi\fi\fi\fi\fi\fi oftwo\endcsname} + +% Evaluation macro that evaluates an atomic expression depending on its type: +\long\def\bex@true_or_false#1{\csname bex@% + \ifnum\numexpr#1 true\else false\fi part\endcsname} +\long\def\bex@false_or_true#1{\csname bex@% + \ifnum\numexpr#1 false\else true\fi part\endcsname} + +\def\bex@eq#1=#2/{\bex@true_or_false{#1-(#2)=0}} +\def\bex@neq#1<>#2/{\bex@false_or_true{#1-(#2)=0}} +\def\bex@infeq#1<=#2/{\bex@false_or_true{#1-(#2)>0}} +\def\bex@inf#1<#2/{\bex@true_or_false{#1-(#2)<0}} +\def\bex@supeq#1>=#2/{\bex@false_or_true{#1-(#2)<0}} +\def\bex@sup#1>#2/{\bex@true_or_false{#1-(#2)>0}} +\long\def\bex@eval#1{\bex@true_or_false{#1=0}} + +% \bex@OR splits the string to evaluate into two parts: before the first \OR and after +\long\def\bex@OR#1\OR#2:{\bex@AND{#2}#1\AND:} + +% \bex@AND splits the string to evaluate into two parts: before the first \AND and after: +\long\def\bex@AND#1#2\AND#3:{% + \bex@rel{#2} + {\bex@nbk #3//{\bex@ANDAND{#1}#3:}{+0}//} + {\bex@nbk #1//{\bex@OR#1:}{+1}//}} + +% \bex@ANDAND evaluate successive atomic expressions related by \AND: +\long\def\bex@ANDAND#1#2\AND#3:{% + \bex@rel{#2} + {\bex@nbk #3//{\bex@ANDAND{#1}#3:}{+0}//} + {\bex@nbk #1//{\bex@OR#1:}{+1}//}} + +% \boolexpr: the entry point for evaluating boolean expressions +\newcommand\boolexpr[1]{\bex@nbk #1//{\numexpr\bex@OR#1\OR:}{+1}//} + +% \ifboolexpr: the LaTeX form of \boolexpr tests +\ifdefined\ifboolexpr% etoolbox defines ifboolexpr... +\PackageWarning{boolexpr}{\string\ifboolexpr\space has been defined before\MessageBreak + by etoolbox (I suppose) - Overwritting} +\renewcommand\ifboolexpr[1]{\bex@true_or_false{\boolexpr{#1}=0}} +\else +\newcommand\ifboolexpr[1]{\bex@true_or_false{\boolexpr{#1}=0}} +\fi + +\long\def \switch#1\endswitch {\bex@nbk#1//{\bex@switch_opt#1\endswitch}{}//} +\long\def \bex@switch_opt#1#2\endswitch{\bex@ifoptchar#1/[/ + {\bex@switch_opti#1#2\endswitch}{\bex@switch_opti[]#1#2\endswitch}}%] +\def \bex@switch_opti[#1]#2\endswitch {\bex@switch_otherwise[{#1}]#2\otherwise\endswitch} + +\def\bex@switch_otherwise[#1]#2\otherwise#3\endswitch{% + \bex@switch_case[{#1}]#2\case\endswitch + {\bex@nbk#3//{\bex@otherwise#3\endswitch}{}//} + \endswitch} + +\def\bex@switch_case[#1]#2\case#3\endswitch{\bex@nbk#2//% + {\bex@case[{#1}]#2\endcase% + {\bex@nbk#3//{\bex@switch_case[{#1}]#3\endswitch}\@firstoftwo//}}% + {\bex@nbk#3//{\bex@switch_case[{#1}]#3\endswitch}\@firstoftwo//}//} + +\long\def\bex@case[#1]#2#3\endcase{\ifboolexpr{#1#2}{\bex@after_endswitch{#3}}} + +\long\def\bex@after_endswitch#1#2\endswitch{#1} +\long\def\bex@otherwise#1\otherwise#2\endswitch{#1} +\long\def\bex@pdfmatch#1#2{\ifnum\pdfmatch{#2}{#1}=0 1\else0\fi} +\long\def\bex@ifempty#1{\if\relax\detokenize{#1}\relax0\else1\fi} +\long\def\bex_ifempty#1{\csname @\if\relax\detokenize{#1}\relax first\else second\fi oftwo\endcsname} +\long\def\bex@ifblank#1{\bex@nbk#1//10//} +\long\def\bex@ifx#1#2{\bex__ifx#1#2//} +\long\def\bex_ifx#1#2#3/#4#5#6//{\bex@nbk#6//{\ifx#1#2\bex_else#5\else\bex_fi#6\fi}{#5}//} +\long\def\bex_else#1\else#2\fi{\fi#1} +\long\def\bex_fi#1\fi{\fi#1} +\long\def\bex@comp#1{\bex@ifoptchar#1/[/\bex@c@mp{\bex@c@mp@[\numexpr]}} +\long\def\bex@c@mp[#1#2]#3#4#5{% + \bex_ifempty{#2}{% + \ifx #1\dimexpr \bex@c@mp@\ifdim\dimexpr{#3}{#4}{#5}% + \else\ifx #1\numexpr \bex@c@mp@\ifnum\numexpr{#3}{#4}{#5}% + \else\ifx #1\glueexpr \bex@c@mp@\ifdim\glueexpr{#3}{#4}{#5}% + \else\ifx #1\muexpr \bex@c@mp@\ifdim\muexpr{#3}{#4}{#5}% + \else\ifx #1\number \bex@c@mp@\ifnum\numexpr{#3}{#4}{#5}% + \else\PackageError{boolexpr}{% + Invalid comparison test while scanning \string\bex@comp\MessageBreak + found: \detokenize{#1}}% + \fi\fi\fi\fi\fi}% + {\PackageError{boolexpr}{Invalid comparison test while scanning \string\bex@comp\MessageBreak + found: \detokenize{#1}}}} +\long\def\bex@c@mp@#1#2#3#4#5{#1#2#3#4#5 0\else 1\fi} +\bex@AtEnd\let\bex@AtEnd\@undefined +\endinput +%% +%% End of file `boolexpr.sty'. -- cgit v1.2.3