diff options
Diffstat (limited to 'macros/latex/contrib/ifallfalse/ifallfalse.dtx')
-rw-r--r-- | macros/latex/contrib/ifallfalse/ifallfalse.dtx | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/macros/latex/contrib/ifallfalse/ifallfalse.dtx b/macros/latex/contrib/ifallfalse/ifallfalse.dtx new file mode 100644 index 0000000000..23bbbedd0d --- /dev/null +++ b/macros/latex/contrib/ifallfalse/ifallfalse.dtx @@ -0,0 +1,143 @@ +% \iffalse meta-comment +% +% Copyright (C) 2021 Dennis Chen <proofprogram@gmail.com> +% +% This file may be distributed and/or modified under +% the conditions the LaTeX Project Public License (LPPL), +% either version 1.3 of this license or (at your option) +% any later version. The latest version of this license +% can be found in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +% \fi +% +% \iffalse +%<package> +%<package>\NeedsTeXFormat{LaTeX2e} +%<package>\ProvidesPackage{ifallfalse}[2021/07/01 v1.0.0 Compare string against set of other strings] + +%<*driver> +\documentclass{ltxdoc} +\usepackage{ifallfalse} +\EnableCrossrefs +\CodelineIndex +\RecordChanges +\begin{document} + \DocInput{ifallfalse.dtx} + \PrintIndex +\end{document} +%</driver> +% \fi +% +% \changes{v1.0.0}{2021/07/01}{Initial version} +% +% \GetFileInfo{ifallfalse.sty} +% +% \title{\textsf{ifallfalse} -- Compare string against set of strings} +% \author{Dennis Chen \\ proofprogram@gmail.com} +% \date{\fileversion, v. \filedate\thanks{\url{https://github.com/chennisden/ifallfalse}}} +% +% \maketitle +% +% \begin{abstract} +% The \textsf{ifallfalse} package is a package that allows you to check whether a string is contained within another set of strings, and perform an action if it is not. +% \end{abstract} +% +% \section{Usage} +% +% The package provides an \textsf{ifallfalse} environment and a macro |\orcheck| to be used inside the \textsf{ifallfalse} environment. +% +% \DescribeEnv{ifallfalse} +% To set up an ifallfalse environment, simply write +% \begin{verbatim} +%\begin{ifallfalse}{string}{action} +% +%\end{ifallfalse} +% \end{verbatim} +% \textsf{string} will be compared to the set of strings (which we will declare via |\orcheck|), and if \textsf{string} does not match the set of strings, \textsf{action} will be executed. +% +% \DescribeMacro{\orcheck} +% +% To add strings to the set that \textsf{string} will be compared to, we must write |\orcheck{setstring}| inside the corresponding \textsf{ifallfalse} environment. Then, \textsf{action} will not execute if \textsf{string} matches \textsf{setstring} or any arguments of previous |\orcheck| declarations. +% +% If no |\orcheck| declarations exist, then \textsf{action} will always be executed. +% +% \subsection{Error Checking} +% +% The package checks whether the macro |\orcheck| is used inside an \textsf{ifallfalse} environment. If it is not, the package throws an error. +% +% \section{Example} +% +% Here is a simple example to demonstrate how \textsf{ifallfalse} is used. +% \begin{verbatim} +%\documentclass{minimal} +% +%\begin{document} +% +%\begin{ifallfalse}{purple}{This color is not red, blue, or green!} +% \orcheck{red} +% \orcheck{blue} +% \orcheck{green} +%\end{ifallfalse} +% +%\end{document} +% \end{verbatim} +% +% In this case, because \textsf{purple} does not match \textsf{red}, \textsf{blue}, or \textsf{green}, the action --- which is printing \textsf{This color is not red, blue, or green!} --- will execute at that location inside the document. +% +% \section{Implementation} +% +% These are the implementation details of package \textsf{ifallfalse}. Because the package is so short, we can explain everything. +% +% \begin{environment}{ifallfalse} +% When setting up ifallfalse, we locally define the |\comparedstring| macro with the first argument that the environment takes in. This is what will be compared against all the strings passed in through the |\orcheck| declarations inside the environment. +% +% Then, we define our body of logic (which we will be adding onto through |\orcheck|) to just initially consist of the action we would like to perform if |\comparedstring| matches none of the strings passed in through |\orcheck|. +% \begin{macrocode} +\newenvironment{allfalse}[2] +{ + \def\comparedstring{#1} + \def\logicbody{#2} +} +{ + \logicbody +} +% \end{macrocode} +% \end{environment} +% +% \begin{macro}{\orcheck} +% We first save \textsf{allfalse} to a macro so we can use |\ifx| to compare the current environment name against it. If we can, then we add some following (somewhat convoluted) code to |\logicbody|. I will explain what each piece of it does, though not in the order the pieces of code appear. +% \begin{itemize} +% \item |\ifx\@currenvir\@allfalsename| evaluates to true if the current environment (whose name is saved to the macro |\@currenvir|) matches the name of |\@allfalsename|, or \textsf{allfalse}. +% \item If it evaluates to \textsf{false}, the package throws an error. +% \item The line |\pdfstrcmp{\comparedstring}{#1}=0| evaluates to true when put with |\ifnum| if the two arguments passed into |\pdfstrcmp| are equal, because |pdfstrcmp| compares their lexographical order and returns 0 if the two strings are lexographically equivalent. +% \item Thus, we can treat |\ifnum\pdfstrcmp{\comparedstring}{#1}=0| as an expression that evaluates to true if |\comparedstring| and |#1| match, and false otherwise. +% \item When all is said and done, the logic reduces to something of the form +% \begin{verbatim} +% \if\else +% \if\else +% \ldots action +% \fi\ldots \fi +% \end{verbatim} +% Logically, \textsf{action} will only execute if all the conditions are false; in other words, it will only execute if |\comparedstring| does not match any of the strings passed in via |\orcheck|. This is because each |\else| branch must execute. +% \end{itemize} +% \begin{macrocode} +\newcommand*\@allfalsename{allfalse} + +\newcommand{\orcheck}[1]{ + \ifx\@currenvir\@allfalsename + \protected@edef\logicbody{ + \ifnum\pdfstrcmp{\comparedstring}{#1}=0\else\logicbody\fi + } + \else + \PackageError{ifallfalse}{ + \protect\orcheck\space should be nested within the allfalse environment + }{} + \fi +} +% \end{macrocode} +% \end{macro} +% +% \Finale +\endinput
\ No newline at end of file |