% \iffalse
%
%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
%<package>\ProvidesPackage{coolstr}
%<package> [2023/05/03 v2.2 COntent Oriented LaTeX Strings]
%<package>\RequirePackage{ifthen}
%<package>\RequirePackage{amsmath}
%<package>\RequirePackage{amssymb}
%
% Update on 2023/05/03 purely to clarify the license; no code changes.
% This package is released under the GNU LGPL.
%
%<*driver>
\documentclass{ltxdoc}
\usepackage{coolstr}
\usepackage{url}
\usepackage{pdflscape}
\EnableCrossrefs
\CodelineIndex
\RecordChanges
\begin{document}
\DocInput{coolstr.dtx}
\end{document}
%</driver>
% \fi
%
%
% \CheckSum{314}
%
%
%% \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         \~}
%
% \changes{v1.0}{2006/09/17}{Initial Release}
% \changes{v2.0}{2006/12/29}{Added three new commands: \texttt{ifstrchareq}, \texttt{ifstrleneq}, \texttt{strlen}}
%
% \GetFileInfo{coolstr.sty}
%
% \DoNotIndex{\#,\$,\%,\&,\@,\\,\{,\},\^,\_,\~,\ ,\!,\(,\),\,}
% \DoNotIndex{\@ne,\expandafter}
% \DoNotIndex{\advance,\begingroup,\catcode,\closein}
% \DoNotIndex{\newcommand,\renewcommand,\providecommand}
% \DoNotIndex{\closeout,\day,\def,\edef,\gdef,\xdef,\let,\empty,\endgroup}
% \DoNotIndex{\newcounter,\providecounter,\addtocounter,\setcounter,\stepcounter,\value,\arabic}
% \DoNotIndex{\if,\fi,\ifthenelse,\else,\setboolean,\boolean,\newboolean,\provideboolean,\equal,\AND,\OR,\NOT,\whiledo}
% \DoNotIndex{\ifcase,\ifcat,\or,\else}
% \DoNotIndex{\par,\parbox,\mbox,\hbox,\begin,\end,\nabla,\partial}
% \DoNotIndex{\overline,\bar,\small,\tiny,\mathchoice,\scriptsize,\textrm,\texttt}
% \DoNotIndex{\alpha,\beta,\gamma,\epsilon,\varepsilon,\delta,\zeta,\eta,\theta,\vartheta,\iota,\kappa,\lambda,\mu,\nu}
% \DoNotIndex{\xi,\omicron,\pi,\varpi,\rho,\varrho,\sigma,\tau,\upsilon,\phi,\varphi,\chi,\psi,\omega}
% \DoNotIndex{\Delta,\Gamma,\Theta,\Lambda,\Xi,\Pi,\Sigma,\Phi,\Psi,\Omega}
% \DoNotIndex{\digamma,\lceil,\rceil,\lfloor,\rfloor,\left,\right,\inp,\inb,\inbr,\inap,\nop}
% \DoNotIndex{\sum,\prod,\int,\log,\ln,\exp,\sin,\cos,\tan,\csc,\sec,\cot,\arcsin,\arccos,\arctan,\det}
% \DoNotIndex{\sinh,\cosh,\tanh,\csch,\sech,\coth,\arcsinh,\arccosh,\arctanh}
% \DoNotIndex{\mod,\max,\min,\gcd,\lcm,\wp,\arg,\dots,\infty,}
% \DoNotIndex{\frac,\binom,\braket,\@@atop}
% \DoNotIndex{\cdot,\ldots,\tilde,\times,\dagger,\relax}
% \DoNotIndex{\mathbb,\roman,\bf,\mathord,\cal,\DeclareMathOperator,\PackageError,\PackageWarning}
% \DoNotIndex{\csname,\endcsname,\ifx,\ifnum}
% \DoNotIndex{\COOL@Hypergeometric@pq,\COOL@Hypergeometric@pq@ab@value,\hideOnSF,\COOL@decide@paren}
% \DoNotIndex{\COOL@decide@indicies}
% \DoNotIndex{\mod,\bmod,\pmod,\pod,\operatorname}
%
% \title{The \textsf{coolstr} package\thanks{This document
% corresponds to \textsf{cool}~\fileversion,
% dated~\filedate.}}
% \author{nsetzer}
%
% \maketitle
%
% \setcounter{IndexColumns}{2}
% \StopEventually{\PrintChanges\PrintIndex}
%
% The \textsf{coolstr} package is a ``sub" package of the \textsf{cool} package that seemed appropriate to publish
% independently since it may occur that one wishes to include the ability to check strings without having to accept 
% all the overhead of the \textsf{cool} package itself.
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%\section{Basics}
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Strings are defined as a sequence of characters (not \TeX{} tokens).  The main purpose behind treating strings as
% characters rather than tokens is that one can then do some text manipulation on them.
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%\section{Descriptions}
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% \DescribeMacro{\substr} |\substr|\marg{string}\marg{start index}\marg{num char} gives at most $\|$\meta{num char}$\|$ 
% characters from \meta{string}.
%
% if \meta{start index} is greater than zero, and \meta{num char} is greater than zero, |\substr| gives at most
% \meta{num char} starting with index \meta{start index} and going to the end of the string.
%
% if \meta{start index} is greater than zero, and \meta{num char} is less than zero, |\substr| gives at most 
% $-$\meta{num char} characters and going to the beginning of the string
%
% if \meta{start index} is less than zero, and \meta{num char} is greater than zero, |\substr| gives at most
% \meta{num char} characters starting at the $-$\meta{start index} character from the end of the string and going
% to the end of the string
%
% if \meta{start index} is less than zero, and \meta{num char} is less than zero, |\substr| gives at most
% $-$\meta{num char} characters starting at the $-$\meta{start index} character from the end of the string and going
% to the beginning of the string
%
% There are two special, non-numeric values that \meta{char num} may take.  They are |end| or |beg|, and they will always
% go to the end or begining of the string, respectively
%
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%\section{Test Cases}
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
%\subsection{\texttt{$\backslash$substr}}
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% \DescribeMacro{\substr}
%
% \begin{tabular}{ll}
% \hline
% |\substr{12345}{1}{2}|                & \substr{12345}{1}{2}                  \\
% |\substr{12345}{3}{5}|                & \substr{12345}{3}{5}                  \\
% |\substr{12345}{3}{end}|      & \substr{12345}{3}{end}                        \\
% |\substr{12345}{3}{beg}|      & \substr{12345}{3}{beg}                        \\
% |\substr{12345}{-2}{1}|       & \substr{12345}{-2}{1}                 \\
% |\substr{12345}{3}{-2}|       & \substr{12345}{3}{-2}                 \\
% |\substr{12345}{-2}{-2}|      & \substr{12345}{-2}{-2}                        \\
% |\substr{12345}{0}{5}|                & \substr{12345}{0}{5}  (the null string)               \\
% |\substr{12345}{2}{0}|                & \substr{12345}{2}{0}  (the null string)               \\
% \hline 
% \end{tabular}
%
%
% \newboolean{t}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
%\subsection{\texttt{$\backslash$isdecimal}}
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%
% \begin{tabular}{ll}
% (null str)            & \isdecimal{}{t} \ifthenelse{ \boolean{t} }{is decimal}{not a decimal}                 \\
% \textvisiblespace     & \isdecimal{ }{t} \ifthenelse{ \boolean{t} }{is decimal}{not a decimal}                        \\
% \textvisiblespace\textvisiblespace
%                       & \isdecimal{  }{t} \ifthenelse{ \boolean{t} }{is decimal}{not a decimal}               \\
% |2.345|               & \isdecimal{2.345}{t} \ifthenelse{ \boolean{t} }{is decimal}{not a decimal}            \\
% |2.4.5|               & \isdecimal{2.4.5}{t} \ifthenelse{ \boolean{t} }{is decimal}{not a decimal}            \\
% |+-2.45|              & \isdecimal{+-2.45}{t} \ifthenelse{ \boolean{t} }{is decimal}{not a decimal}           \\
% |+2.345|              & \isdecimal{+2.345}{t} \ifthenelse{ \boolean{t} }{is decimal}{not a decimal}           \\
% |-2.345|              & \isdecimal{-2.345}{t} \ifthenelse{ \boolean{t} }{is decimal}{not a decimal}           \\
% |2.345-|              & \isdecimal{2.345-}{t} \ifthenelse{ \boolean{t} }{is decimal}{not a decimal}           \\
% |2.4+4.|              & \isdecimal{2.4+4.5}{t} \ifthenelse{ \boolean{t} }{is decimal}{not a decimal}          \\
% |+4.|                 & \isdecimal{+4.}{t} \ifthenelse{ \boolean{t} }{is decimal}{not a decimal}              \\
% |4.|                  & \isdecimal{4.}{t} \ifthenelse{ \boolean{t} }{is decimal}{not a decimal}               \\
% |+.7|                 & \isdecimal{+.7}{t} \ifthenelse{ \boolean{t} }{is decimal}{not a decimal}              \\
% |.3|                  & \isdecimal{.3}{t} \ifthenelse{ \boolean{t} }{is decimal}{not a decimal}               \\
% |4|                   & \isdecimal{4}{t} \ifthenelse{ \boolean{t} }{is decimal}{not a decimal}                        \\
%                       & |\newcommand{\numberstore}{4.5}|                                                              \\
% |\numberstore|                & \newcommand{\numberstore}{4.5} \isdecimal{\numberstore}{t} \ifthenelse{ \boolean{t} }{is decimal}{not a decimal}      
% \end{tabular}
%
%
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
%\subsection{\texttt{$\backslash$isnumeric}}
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%
% \begin{tabular}{ll}
% (null str)            & \isnumeric{}{t} \ifthenelse{ \boolean{t} }{is numeric}{not numeric}                   \\
% \textvisiblespace     & \isnumeric{ }{t} \ifthenelse{ \boolean{t} }{is numeric}{not numeric}                  \\
% \textvisiblespace\textvisiblespace
%               & \isnumeric{  }{t} \ifthenelse{ \boolean{t} }{is numeric}{not numeric}                 \\
% |4.5|                 & \isnumeric{4.5}{t} \ifthenelse{ \boolean{t} }{is numeric}{not numeric}                        \\
% |4.5e5|               & \isnumeric{4.5e5}{t} \ifthenelse{ \boolean{t} }{is numeric}{not numeric}              \\
% |+4.5e5|              & \isnumeric{+4.5e5}{t} \ifthenelse{ \boolean{t} }{is numeric}{not numeric}             \\
% |4.5e+5|              & \isnumeric{4.5e+5}{t} \ifthenelse{ \boolean{t} }{is numeric}{not numeric}             \\
% |+4.5e+5|             & \isnumeric{+4.5e+5}{t} \ifthenelse{ \boolean{t} }{is numeric}{not numeric}            \\
% |4.5E5|               & \isnumeric{4.5E5}{t} \ifthenelse{ \boolean{t} }{is numeric}{not numeric}              \\
% |-4.5E5|              & \isnumeric{-4.5E5}{t} \ifthenelse{ \boolean{t} }{is numeric}{not numeric}             \\
% |4.5E-5|              & \isnumeric{4.5E-5}{t} \ifthenelse{ \boolean{t} }{is numeric}{not numeric}             \\
% |-4.5E-5|             & \isnumeric{-4.5E-5}{t} \ifthenelse{ \boolean{t} }{is numeric}{not numeric}            \\
% |4.5.E-5|             & \isnumeric{4.5.E-5}{t} \ifthenelse{ \boolean{t} }{is numeric}{not numeric}            \\
% |abcdefg|             & \isnumeric{abcdefg}{t} \ifthenelse{ \boolean{t} }{is numeric}{not numeric}            \\
% |abcE-5|              & \isnumeric{abcE-5}{t} \ifthenelse{ \boolean{t} }{is numeric}{not numeric}
% \end{tabular}
%
%
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
%\subsection{\texttt{$\backslash$isint}}
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%
% \begin{tabular}{ll}
% (null str)            & \isint{}{t} \ifthenelse{ \boolean{t} }{is integer}{not integer}               \\
% \textvisiblespace     & \isint{ }{t} \ifthenelse{ \boolean{t} }{is integer}{not integer}              \\
% \textvisiblespace\textvisiblespace
%                       & \isint{  }{t} \ifthenelse{ \boolean{t} }{is integer}{not integer}             \\
% |4|                   & \isint{4}{t} \ifthenelse{ \boolean{t} }{is integer}{not integer}              \\
% |+4|                  & \isint{+4}{t} \ifthenelse{ \boolean{t} }{is integer}{not integer}             \\
% |4.5|                 & \isint{4.5}{t} \ifthenelse{ \boolean{t} }{is integer}{not integer}            \\
% |4.5e5|               & \isint{4.5e5}{t} \ifthenelse{ \boolean{t} }{is integer}{not integer}          \\
% |+4.5e5|              & \isint{+4.5e5}{t} \ifthenelse{ \boolean{t} }{is integer}{not integer}         \\
% |4.5e+5|              & \isint{4.5e+5}{t} \ifthenelse{ \boolean{t} }{is integer}{not integer}         \\
% |+4.5e+5|             & \isint{+4.5e+5}{t} \ifthenelse{ \boolean{t} }{is integer}{not integer}                \\
% |4.5E5|               & \isint{4.5E5}{t} \ifthenelse{ \boolean{t} }{is integer}{not integer}          \\
% |-4.5E5|              & \isint{-4.5E5}{t} \ifthenelse{ \boolean{t} }{is integer}{not integer}         \\
% |4.5E-5|              & \isint{4.5E-5}{t} \ifthenelse{ \boolean{t} }{is integer}{not integer}         \\
% |-4.5E-5|             & \isint{-4.5E-5}{t} \ifthenelse{ \boolean{t} }{is integer}{not integer}                \\
% |4.5.E-5|             & \isint{4.5.E-5}{t} \ifthenelse{ \boolean{t} }{is integer}{not integer}                \\
% |abcdefg|             & \isint{abcdefg}{t} \ifthenelse{ \boolean{t} }{is integer}{not integer}                \\
% |abcE-5|              & \isint{abcE-5}{t} \ifthenelse{ \boolean{t} }{is integer}{not integer}         \\
%                       & |\renewcommand{\numberstore}{4}|                                              \\
% |\numberstore|                & \newcommand{\numberstore}{4} \isint{\numberstore}{t} \ifthenelse{ \boolean{t} }{is integer}{not integer}
% \end{tabular}
%
%
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%\section{Acknowledgments}
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 
% Thanks to J.~J.~Weimer for the comments and aid in coding.  
%
% \noindent Thanks goes to Abraham Weishaus for pointing out a bug in |\strlenstore|
%
% \noindent Thanks to Daniel Kucerovsky for pointing the `blank-space' bug of |\isnumeric| (and consequently |\isdecimal|).
%
% 
% \begin{landscape}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%\section{Implementation}
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% This is just an internal counter for dealing with the strings; most often used for the length
%
%    \begin{macrocode}
\newcounter{COOL@strlen}%
%    \end{macrocode}
%
% \begin{macro}{\setstrEnd}
%
% |\setstrEnd{|\meta{string}|}| allows the user to set the end of a string `character' 
% in the rare event that the default value actually appears in the string.
% The default value is
%
%    \begin{macrocode}
\newcommand{\COOL@strEnd}{\%\%\%}
\newcommand{\COOL@intEnd}{\%@\%@\%@}
\let\COOL@strStop=\relax
%    \end{macrocode}
%
% and may be changed by the following command (which utilizes the |\renewcommand|):
%
%    \begin{macrocode}
\newcommand{\setstrEnd}[1]{\renewcommand{\COOL@strEnd}{#1}}
%    \end{macrocode}
%
% \end{macro}
%
%
% This area defines the core technology behind the \textsf{coolstr} package: the string ``gobbler".
%
%    \begin{macrocode}
\newcounter{COOL@strpointer}
%    \end{macrocode}
%
% Now we come to ``the gobbler"---a recursive function that eats up a string.  
% It must be written in \TeX{} primatives.
%
% The idea behind this is that ``the gobbler" eats up everything before the desired character and everything 
% after the desired character.
%
%    \begin{macrocode}
\def\COOL@strgobble[#1]#2#3{%
\ifthenelse{\equal{#3}{\COOL@strEnd}}%
        {%
        \ifthenelse{\value{COOL@strpointer}=#1}%
                {%
                #2%
                }%
        % Else
                {%
                }%
        }%
% Else
        {%
        \ifthenelse{\value{COOL@strpointer}=#1}%
                {%
                #2%
                }%
        % Else
                {%
                }%
        \stepcounter{COOL@strpointer}%
        \COOL@strgobble[#1]#3%
        }%
}
%    \end{macrocode}
%
% \begin{macro}{\strchar}
% |\strchar|\marg{index} gives the \meta{index} character of the string.  Strings start indexing at $1$.
%
%    \begin{macrocode}
\newcommand{\strchar}[2]{%
\setcounter{COOL@strpointer}{1}%
\COOL@strgobble[#2]#1\COOL@strEnd%
}
%    \end{macrocode}
%
% \end{macro}
%
%
% \begin{macro}{\strlen}
% \changes{v2.0}{2006/12/29}{added to package}
% \changes{v2.1}{2007/01/08}{added ifthenelse to return $0$ for empty string}
% |\strlen|\marg{string} gives the length of the string.  It is better to use |\strlenstore| to record the length
%
% |\strlen{abc}| \strlen{abc}
%
%    \begin{macrocode}
\newcommand{\strlen}[1]{%
\ifthenelse{\equal{#1}{}}%
        {%
        0%
        }%
% Else
        {%
        \strchar{#1}{0}%
        \arabic{COOL@strpointer}%
        }%
}
%    \end{macrocode}
%
% \end{macro}
%
%
% \begin{macro}{\strlenstore}
% \changes{v2.0}{2006/12/29}{added to package}
% \changes{v2.1}{2007/01/08}{corrected error in setting counter}
% \changes{v2.1}{2007/01/08}{added ifthenelse to return $0$ for empty string}
% |\strlenstore|\marg{string}\marg{counter} stores the length of \meta{string} in \meta{counter}
%
%    \begin{macrocode}
\newcommand{\strlenstore}[2]{%
\ifthenelse{\equal{#1}{}}%
        {%
        \setcounter{#2}{0}%
        }%
% Else
        {%
        \strchar{#1}{0}%
        \setcounter{#2}{\value{COOL@strpointer}}%
        }%
}
%    \end{macrocode}
%
% \end{macro}
%
%
%
%
% \begin{macro}{\substr}
% \changes{v2.1}{2007/01/08}{added to package}
% |\substr|\marg{string}\marg{index}\marg{numchar}
%
% a special value of |end| for \meta{numchar} gives from \meta{index} to the end of the string; |beg| gives from \meta{index} to the beginning of the string
%
%    \begin{macrocode}
\newcounter{COOL@str@index}
\newcounter{COOL@str@start}
\newcounter{COOL@str@end}
\newcommand{\substr}[3]{%
\strlenstore{#1}{COOL@strlen}%
\ifthenelse{#2 < 0 \AND \NOT #2 < -\value{COOL@strlen}}%
        {%
%    \end{macrocode}
% The starting index is less than zero, so start that many characters back from the end.  This means mapping the index to \meta{index}${} + {}$\meta{string length}${} + 1$
%    \begin{macrocode}
        \setcounter{COOL@str@index}{\value{COOL@strlen}}%
        \addtocounter{COOL@str@index}{#2}%
        \addtocounter{COOL@str@index}{1}%
        }%
% ElseIf
{\ifthenelse{#2 > 0 \AND \NOT #2 > \value{COOL@strlen}}%
        {%
%    \end{macrocode}
% The starting index is greater than zero, and within the appropriate range; record it
%    \begin{macrocode}
        \setcounter{COOL@str@index}{#2}%
        }%
% Else
        {%
%    \end{macroccode}
% The \meta{index} value is invalid.  Set it to zero for returning the null string
%    \begin{macrocode}
        \setcounter{COOL@str@index}{0}%
        }}%
%    \end{macrocode}
% Now deal with the \meta{numchar} (which can also be negative)
%    \begin{macrocode}
\ifthenelse{\equal{#3}{beg}}%
        {%
        \setcounter{COOL@str@start}{1}%
        \setcounter{COOL@str@end}{\value{COOL@str@index}}%
        }%
% ElseIf
{\ifthenelse{\equal{#3}{end}}%
        {%
        \setcounter{COOL@str@start}{\value{COOL@str@index}}%
        \setcounter{COOL@str@end}{\value{COOL@strlen}}%
        }%
% ElseIf
{\ifthenelse{#3 < 0}%
        {%
%    \end{macrocode}
% This means to take that many characters to the \emph{left} of the starting index.
%    \begin{macrocode}
        \setcounter{COOL@str@start}{\value{COOL@str@index}}%
        \addtocounter{COOL@str@start}{#3}%
        \addtocounter{COOL@str@start}{1}%
        \ifthenelse{\NOT \value{COOL@str@start} > 0}{\setcounter{COOL@str@start}{1}}{}%
        \setcounter{COOL@str@end}{\value{COOL@str@index}}%
        }%
% ElseIf
{\ifthenelse{#3 > 0}%
        {%
        \setcounter{COOL@str@start}{\value{COOL@str@index}}%
        \setcounter{COOL@str@end}{\value{COOL@str@index}}%
        \addtocounter{COOL@str@end}{#3}%
        \addtocounter{COOL@str@end}{-1}%
        \ifthenelse{\value{COOL@str@end} > \value{COOL@strlen}}{\setcounter{COOL@str@end}{\value{COOL@strlen}}}{}%
        }%
% Else
        {%
%    \end{macrocode}
% nonsense submitted, so return the null string
%    \begin{macrocode}
        \setcounter{COOL@str@index}{0}%
        }}}}%
%    \end{macrocode}
% Now send back the appropriate thing
%    \begin{macrocode}
\ifthenelse{ \value{COOL@str@index} = 0 }%
        {%
        }%
% Else
        {%
        \setcounter{COOL@strpointer}{1}%
        \COOL@substrgobbler#1\COOL@strStop\COOL@strEnd%
        }%
}
%    \end{macrocode}
% Now define the ``gobbler"
%    \begin{macrocode}
\def\COOL@substrgobbler#1#2\COOL@strEnd{%
\ifthenelse{\equal{#2}{\COOL@strStop}}%
        {%
        \ifthenelse{ \value{COOL@strpointer} < \value{COOL@str@start} \OR \value{COOL@strpointer} > \value{COOL@str@end} }%
                {}%
        % Else
                {%
                #1%
                }%
        }%
% Else
        {%
        \ifthenelse{ \value{COOL@strpointer} < \value{COOL@str@start} \OR \value{COOL@strpointer} > \value{COOL@str@end} }%
                {}%
        % Else
                {%
                #1%
                }%
        \stepcounter{COOL@strpointer}%
        \COOL@substrgobbler#2\COOL@strEnd%
        }%
}
%    \end{macrocode}
%
% \end{macro}
%
%
% Define a new boolean for comparing characters
%
%    \begin{macrocode}
\newboolean{COOL@charmatch}
%    \end{macrocode}
%
% \begin{macro}{\COOL@strcomparegobble}
% This ``gobbler" does character comparison
% \changes{v2.0}{2006/12/29}{added to package for single character comparisons}
%
%    \begin{macrocode}
\def\COOL@strcomparegobble[#1]<#2>#3#4{%
\ifthenelse{\equal{#4}{\COOL@strEnd}}%
        {%
        \ifthenelse{\value{COOL@strpointer}=#1 \AND \equal{#2}{#3} }%
                {%
                \setboolean{COOL@charmatch}{true}%
                }%
        % Else
                {%
                }%
        }%
% Else
        {%
        \ifthenelse{\value{COOL@strpointer}=#1 \AND \equal{#2}{#3} }%
                {%
                \setboolean{COOL@charmatch}{true}%
                }%
        % Else
                {%
                }%
        \stepcounter{COOL@strpointer}%
        \COOL@strcomparegobble[#1]<#2>#4%
        }%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\ifstrchareq}
% |\ifstrchareq|\marg{string}\marg{char index}\marg{comparison char}\marg{do if true}\marg{do if false}
% \changes{v2.0}{2006/12/29}{added to package to do character comparing}
%
%    \begin{macrocode}
\newcommand{\ifstrchareq}[5]{%
\setboolean{COOL@charmatch}{false}%
\setcounter{COOL@strpointer}{1}%
\COOL@strcomparegobble[#2]<#3>#1\COOL@strEnd\relax%
\ifthenelse{ \boolean{COOL@charmatch} }%
        {%
        #4%
        }%
% Else
        {%
        #5%
        }%
}
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\ifstrleneq}
% |\ifstrleneq|\marg{string}\marg{number}\marg{do if true}\marg{do if false}
%
% \noindent |\ifstrleneq{abc}{3}{length is $3$}{length is not $3$}| \ifstrleneq{abc}{3}{length is $3$}{length is not $3$}
%
% \noindent |\ifstrleneq{abcde}{3}{length is $3$}{length is not $3$}| \ifstrleneq{abcde}{3}{length is $3$}{length is not $3$}
%
% \changes{v2.0}{2006/12/29}{added to package to do length comparison}
% \changes{v2.1}{2007/01/08}{altered function to use \texttt{strlenstore}}
%
%    \begin{macrocode}
\newcommand{\ifstrleneq}[4]{%
\strlenstore{#1}{COOL@strlen}%
\ifthenelse{ \value{COOL@strlen} = #2 }%
        {%
        #3%
        }%
% Else
        {%
        #4%
        }%
}
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\COOL@decimalgobbler}
%
% This ``gobbler" is used to determine if the submitted string is a rational number (satisfies $d_n d_{n-1} \cdots d_1 d_0 . d_{-1} d_{-2} \cdots d_{-m}$).  The idea behind the macro is that it assumes the string is rational until it encounters a non-numeric object 
% \changes{v2.0}{2006/12/29}{added this ``gobbler'' to complete \texttt{isnumeric}}
%
%    \begin{macrocode}
\newboolean{COOL@decimalfound}
\newboolean{COOL@decimal}
%    \end{macrocode}
%
% |COOL@decimalfound| is a boolean indicating if the first decimal point is found
%
% |COOL@decimal| is the flag that tells if the string contains numeric data
%
%    \begin{macrocode}
\def\COOL@decimalgobbler#1#2\COOL@strEnd{%
%    \end{macrocode}
% \changes{v2.2}{2009/09/09}{fixed blank space bug (blank space causes code to `crash')}
%    \begin{macrocode}
\ifthenelse{\equal{#1}{\COOL@strStop}}%
        {%
%    \end{macrocode}
%       user submitted a null string, which can not be numeric
%    \begin{macrocode}
        \setboolean{COOL@decimal}{false}%
        }%
{\ifthenelse{\equal{#2}{\COOL@strStop}}%
%    \end{macrocode}
% this indicates we are at the end of the string.  We only need to perform the check to see if the digit is a number or the first decimal point
%    \begin{macrocode}
        {%
        \ifthenelse{`#1 < `0 \OR `#1 > `9}%
                {%
                \ifthenelse{ `#1 = `.  \AND \NOT \value{COOL@strpointer} = 1 \AND \NOT \boolean{COOL@decimalfound} }%
                        {%
                        }%
                % Else
                        {%
                        \setboolean{COOL@decimal}{false}%
                        }%
                }%
        % Else
                {%
                }%
        }%
% Else
        {%
        \ifthenelse{ `#1 < `0 \OR `#1 > `9 }%
                {%
%    \end{macrocode}
% not at the end of a string, and have encountered a non-digit.  If it is a number, then this non digit must be the first decimal point or it may be the first character and a $+$ or $-$ sign
%    \begin{macrocode}
                \ifthenelse{ `#1 = `.  \AND \NOT \boolean{COOL@decimalfound} }%
                        {%
                        \setboolean{COOL@decimalfound}{true}%
                        }%
                {\ifthenelse{ \(`#1 = `+ \OR `#1 = `-\) \AND \value{COOL@strpointer} = 1 }%
                        {%
                        }%
                % Else
                        {%
                        \setboolean{COOL@decimal}{false}%
                        }}%
                }%
        % Else
                {}%
        \stepcounter{COOL@strpointer}%
        \COOL@decimalgobbler#2\COOL@strEnd%
        }}%
}
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\isdecimal}
% |isdecimal|\marg{string}\marg{boolean}
% \changes{v2.0}{2006/12/29}{added}
%
%    \begin{macrocode}
\newcommand{\isdecimal}[2]{%
\setcounter{COOL@strpointer}{1}%
\setboolean{COOL@decimalfound}{false}%
\setboolean{COOL@decimal}{true}%
\expandafter\COOL@decimalgobbler#1\COOL@strStop\COOL@strEnd%
\ifthenelse{ \boolean{COOL@decimal} }%
        {%
        \setboolean{#2}{true}%
        }%
% Else
        {%
        \setboolean{#2}{false}%
        }%
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\isnumeric}
% |\isnumeric|\marg{string}\marg{boolean} stores |true| in \meta{boolean} if \meta{string} is numeric
% \changes{v2.0}{2006/12/29}{added extra mandatory argument for storing return boolean}
%
%    \begin{macrocode}
\newboolean{COOL@numeric}%
\def\COOL@eparser#1e#2\COOL@strEnd{%
\xdef\COOL@num@magnitude{#1}%
\xdef\COOL@num@exponent{#2}%
}
\def\COOL@ecorrector#1e\COOL@strStop{%
\xdef\COOL@num@exponent{#1}%
}
\def\COOL@Eparser#1E#2\COOL@strEnd{%
\xdef\COOL@num@magnitude{#1}%
\xdef\COOL@num@exponent{#2}%
}
\def\COOL@Ecorrector#1E\COOL@strStop{%
\xdef\COOL@num@exponent{#1}%
}
\newcommand{\isnumeric}[2]{%
\COOL@eparser#1e\COOL@strStop\COOL@strEnd%
\ifthenelse{ \equal{\COOL@num@exponent}{\COOL@strStop} }%
        {%
        \COOL@Eparser#1E\COOL@strStop\COOL@strEnd%
        \ifthenelse{ \equal{\COOL@num@exponent}{\COOL@strStop} }%
                {%
                \gdef\COOL@num@exponent{0}%
                }%
        % Else
                {%
                \expandafter\COOL@Ecorrector\COOL@num@exponent%
                }%
        }
% Else
        {%
        \expandafter\COOL@ecorrector\COOL@num@exponent%
        }%
\isdecimal{\COOL@num@magnitude}{COOL@numeric}%
\ifthenelse{ \boolean{COOL@numeric} }%
        {%
        \isdecimal{\COOL@num@exponent}{COOL@numeric}%
        \ifthenelse{ \boolean{COOL@numeric} }%
                {%
                \setboolean{#2}{true}%
                }%
        % Else
                {%
                \setboolean{#2}{false}%
                }%
        }%
% Else
        {%
        \setboolean{#2}{false}%
        }%
}
%    \end{macrocode}
%
% \end{macro}
%
% In addition to identifying numeric data, it is useful to know if integers are present, thus another ``gobbler" is 
% needed
%
%    \begin{macrocode}
\newboolean{COOL@isint}
\def\COOL@intgobbler#1#2\COOL@strEnd{%
\ifcat#11%
\ifthenelse{\equal{#2}{\COOL@strStop}}%
        {%
        \ifthenelse{`#1 < `0 \OR `#1 > `9}%
                {%
                \setboolean{COOL@isint}{false}%
                }%
        % Else
                {%
                }%
        }%
% Else
        {%
        \ifthenelse{ `#1 < `0 \OR `#1 > `9 }%
                {%
                \ifthenelse{ `#1 = `+ \OR `#1 = `- \AND \value{COOL@strpointer} = 1 }%
                        {}%
                % Else
                        {%
                        \setboolean{COOL@isint}{false}%
                        }%
                }%
        % Else
                {%
                }%
        \stepcounter{COOL@strpointer}%
        \COOL@intgobbler#2\COOL@strEnd%
        }%
\else%
        \setboolean{COOL@isint}{false}%
\fi%
}
%    \end{macrocode}
%
% \begin{macro}{\isint}
% \changes{v2.0}{2006/12/29}{added extra mandatory argument for storing return boolean}
% \changes{v2.0a}{2006/12/30}{modified internals slightly to work with \textsf{cool} package}
% \changes{v2.1b}{2007/10/10}{added expandafter before COOL@intgobbler to expand macros before evaluating}
% |\isint|\marg{string}\marg{boolean} sets the \meta{boolean} to |true| if \meta{string} is an integer or |false| otherwise
%
%    \begin{macrocode}
\newcommand{\isint}[2]{%
\setcounter{COOL@strpointer}{1}%
\setboolean{COOL@isint}{true}%
\expandafter\COOL@intgobbler#1\COOL@strStop\COOL@strEnd%
\ifthenelse{ \boolean{COOL@isint} }%
        {%
        \setboolean{#2}{true}%
        }%
% Else
        {%
        \setboolean{#2}{false}%
        }%
}
%    \end{macrocode}
%
% \end{macro}
%
% \end{landscape}
%
%
%
% \Finale
\endinput
