% \iffalse % %\NeedsTeXFormat{LaTeX2e}[1999/12/01] %\ProvidesPackage{coollist} % [2023/05/03 v1.4 COntent Oriented LaTeX Lists] %\RequirePackage{ifthen} %\RequirePackage{amsmath} %\RequirePackage{amssymb} %\RequirePackage{coolstr} %\RequirePackage{forloop} % % 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{coollist} \usepackage{url} \usepackage{pdflscape} \EnableCrossrefs \CodelineIndex \RecordChanges \begin{document} \DocInput{coollist.dtx} \end{document} % % \fi % % % \CheckSum{251} % % %% \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/08/14}{Initial Release} % \changes{v1.1}{2001/10/06}{Added documentation for commands in separate section.} % \changes{v1.1}{2001/10/06}{Added test cases/examples} % % \GetFileInfo{coollist.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} % \DoNotIndex{\forLoop,\forloop} % \DoNotIndex{\listval,\liststore,\isint,\isnumeric} % \DoNotIndex{ % \COOL@list@temp@i, % \COOL@list@temp@ii, % \COOL@list@temp@iii} % % \title{The \textsf{coollist} package\thanks{This document % corresponds to \textsf{coollist}~\fileversion, % dated~\filedate.}} % \author{nsetzer} % % \maketitle % % \setcounter{IndexColumns}{2} % \StopEventually{\PrintChanges\PrintIndex} % % The \textsf{coollist} 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 manipulate lists without having to accept % all the overhead of the \textsf{cool} package itself. % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %\section{Basics} % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Lists are defined as a sequence of tokens separated by a comma. The \textsf{coollist} package allows the user % to access certain elements of the list while neglecting others---essentially turning lists into a sort of % array. % % List elements are accessed by specifying the position of the object within the list (the index of the item) and % all lists start indexing at |1|. % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %\section{Commands \& Descriptions} % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % \DescribeMacro{\setlistStop} % \DescribeMacro{\setlistEnd} % |\setlistStop|\marg{string} and |\setlistEnd|\marg{string} allow the user to set the end of a list % `character' in the rare event that the default values actually appear in the list. % |listStop| is used to identify when the list actually terminates, while |listEnd| forces the reading macro to % take in the entire list (without both entities, errors would occur if macros were included in the list). % % The default values are % % \begin{tabular}{ll} % |listStop| & \makeatletter |@@| \makeatother \\ % |listEnd| & \makeatletter |@@@| \makeatother % \end{tabular} % % % % \DescribeMacro{\listval} % |\listval|\marg{list}\marg{index} returns the \meta{index} item of the comma delimited list \meta{list} % or nothing if \meta{index} is outside the number of elements of the list. % The first element of the list has index $1$. % % % % \DescribeMacro{\liststore} % |\liststore|\marg{list}\marg{macro\_base\_name} stores the elements of comma delimited list \meta{list} % in a set of macros having the first part of \meta{macro\_base\_name} and ending with the roman numermal % index of the list. % % For example, |\liststore{1,2,3}{list}| would define |\listi|, |\listii|, and |\listiii| each % holding |1|, |2|, |3|, respectively. % % % % \DescribeMacro{\listlen} % |\listlen|\marg{list} returns the length of the comma delimited list \meta{list}, though it is not useful for % storing this length. % If you need to record the list's length for later use, it is better to use the function |\listlenstore|. % % % % \DescribeMacro{\listlenstore} % |\listlenstore|\marg{counter}\marg{list} stores the length of the comma delimited list \meta{list} is the counter % \meta{counter}. % % % % \DescribeMacro{\listcopy} % |\listcopy|\marg{listtocopy}\marg{listcopybase} stores the elements of \meta{listtocopy} into the list % \meta{listtocopybase}. % % % % \DescribeMacro{\listsum} % |\listsum|\oarg{storedlist}\marg{list}\marg{macro} stores the sum of the comma delimited list \meta{list} % (if \meta{storedlist} is |storedlist=false| or |liststored=false|) or the sum of the stored list with base name \meta{list} % (if \meta{storedlist} is |storedlist=true| or |liststored=true|) in the macro \meta{macro}. % Integers are recognized and summed accordingly. All other tokens are summed as variables with some % integer coefficient as the end result. % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %\section{Test Cases} % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %\subsection{\texttt{$\backslash$listval}} % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % \DescribeMacro{\listval} % % \begin{tabular}{ll} % |\listval{1,2,3,4}{0}| & \listval{1,2,3,4}{0} (the null string) \\ % |$\listval{\alpha,\beta,\gamma}{2}$| & $\listval{\alpha,\beta,\gamma}{2}$ \\ % |\listval{a,b,c}{4}| & \listval{a,b,c}{4} (the null string) % \end{tabular} % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %\subsection{\texttt{$\backslash$liststore}} % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % \DescribeMacro{\liststore} % % \begin{tabular}{ll} % |\liststore{1,2,3,4}{temp}| % \\ % |\tempi;\tempii;\tempiii;\tempiv| & \liststore{1,2,3,4}{temp} \tempi;\tempii;\tempiii;\tempiv % \\[1cm] % |\liststore{a_1,a_2,a_3,a_4}{temp}| % \\ % |$\tempi;\tempii;\tempiii;\tempiv$| & \liststore{a_1,a_2,a_3,a_4}{temp} $\tempi;\tempii;\tempiii;\tempiv$ % \\[1cm] % |\liststore{a,b}{temp}| % \\ % |\tempi;\tempii| & \liststore{a,b,c}{temp} \tempi;\tempii % \end{tabular} % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %\subsection{\texttt{$\backslash$listlen}} % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % \DescribeMacro{\listlen} % % \begin{tabular}{ll} % |\listlen{1,2,3,4,5}| & \listlen{1,2,3,4,5} \\ % |\listlen{}| & \listlen{} \\ % |\listlen{1,2}| & \listlen{1,2} \\ % |\listlen{1}| & \listlen{1} % \end{tabular} % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %\subsection{\texttt{$\backslash$listlenstore}} % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % \DescribeMacro{\listlen} % |\newcounter{thelistlength}| \newcounter{thelistlength} % % \begin{tabular}{ll} % |\listlenstore{thelistlength}{1,2,3,4,5}| % \\ % |\arabic{thelistlength}| & \listlenstore{thelistlength}{1,2,3,4,5} \arabic{thelistlength} % \\[1cm] % |\listlenstore{thelistlength}{}| % \\ % |\arabic{thelistlength}| & \listlenstore{thelistlength}{} \arabic{thelistlength} % \\[1cm] % \end{tabular} % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %\subsection{\texttt{$\backslash$listcopy}} % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % \DescribeMacro{\listcopy} copy elements of a list % % \begin{tabular}{ll} % |\liststore{1,2,3}{temp}| \\ % |\listcopy{temp}{copiedlist}| \\ % |\copiedlisti;\copiedlistii;\copiedlistiii| & % \liststore{1,2,3}{temp}\listcopy{temp}{copiedlist}\copiedlisti;\copiedlistii;\copiedlistiii % \end{tabular} % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %\subsection{\texttt{$\backslash$listsum}} % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % \DescribeMacro{\listsum} Summing elements of lists % % \begin{tabular}{ll} % |\listsum{1,2,3,4,5}{\thelistsum}| \\ % |\thelistsum| & \listsum{1,2,3,4,5}{\thelistsum}\thelistsum \\[1cm] % |\listsum{1,2,3,a,b,a,a}{\thelistsum}| \\ % |\thelistsum| & \listsum{1,2,3,a,b,a,a}{\thelistsum}\thelistsum \\[1cm] % |\liststore{1,2,3,5,j,k,j}{temp}| \\ % |\listsum[liststored=true]{temp}{\thelistsum}| \\ % |\thelistsum| & % \liststore{1,2,3,5,j,k,j}{temp}\listsum[liststored=true]{temp}{\thelistsum}\thelistsum \\[1cm] % |\listsum{a,b,c,d}{\thelistsum}| \\ % |\thelistsum| & \listsum{a,b,c,d}{\thelistsum}\thelistsum % \end{tabular} % % % \begin{landscape} % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %\section{Implementation} % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % This is just an internal counter for dealing with the lists, most often used for the length of the list. % % \begin{macrocode} \newcounter{COOL@listlen}% % \end{macrocode} % % % \begin{macro}{\setlistEnd} % \begin{macro}{\setlistStop} % % |\setlistStop{|\meta{string}|}| and |\setlistEnd{|\meta{string}|}| allow the user to set the end of a list `character's % in the rare event that the default values actually appear in the list. % Both of these entities are required to properly deliminate the list and avoid errors when macros are included in the list. The default values are % % \begin{macrocode} \newcommand{\COOL@listEnd}{@@@}% \newcommand{\COOL@listStop}{@@}% % \end{macrocode} % % and they may be changed by the following commands (which utilize the |\renewcommand|): % % \begin{macrocode} \newcommand{\setlistStop}[1]{\renewcommand{\COOL@listStop}{#1}}% \newcommand{\setlistEnd}[1]{\renewcommand{\COOL@listEnd}{#1}}% % \end{macrocode} % % \end{macro} % \end{macro} % % % This area defines the core technology behind the \textsf{coollist} package: the list ``gobbler". % To properly eat a list a counter and a boolean need to be used. |listpointer| acts just like the name % implies, as the current ``position" of the list. |found| indicates that the position has been found % % \begin{macrocode} \newcounter{COOL@listpointer}% \newboolean{COOL@found}% % \end{macrocode} % % Now we come to ``the gobbler"---a recursive function that eats up a list and gives back the appropriate item. % This must be done in \TeX{} primatives. % % The idea behind this is that ``the gobbler" eats up everything before the desired item and everything % after the desired item. % % \begin{macrocode} \def\COOL@listgobble[#1]#2,#3,\COOL@listEnd{% \ifthenelse{\equal{#3}{\COOL@listStop}}% {% % \end{macrocode} % % we have reached the end of the list, just need to check if we need to output something % % \begin{macrocode} \ifthenelse{\value{COOL@listpointer}=#1}% {% \setboolean{COOL@found}{true}% #2% }% % Else {% }% }% % Else {% \ifthenelse{\value{COOL@listpointer}=#1}% {% \setboolean{COOL@found}{true}% #2% }% % Else {% }% \stepcounter{COOL@listpointer}% % \end{macrocode} % % We must eat up the whole list no matter what or else the stuff beyond |#1| will be displayed. so we need % to call ``the gobbler" again. % % \begin{macrocode} \COOL@listgobble[#1]#3,\COOL@listEnd% }% }% % \end{macrocode} % % % % % \begin{macro}{\listval} % \changes{v1.1}{2007/10/06}{alter behavior to do nothing for empty lists} % % |\listval|\marg{comma\_deliminated\_list}\marg{index} % % gives the \meta{index} value of \meta{comma\_deliminated\_list}---as in % % |\listval{1,2,3,4,5,6}{3}| = \listval{1,2,3,4,5,6}{3} % % |$\listval{\alpha,\beta,\gamma}{2}$| = $\listval{\alpha,\beta,\gamma}{2}$ % % \begin{macrocode} \newcommand{\listval}[2]{% % \end{macrocode} % % check to see if the submitted list is empty. if it is, do nothing % % \begin{macrocode} \ifthenelse{\equal{#1}{}}% {% % \end{macrocode} % % set the listpointer to zero because the list has no length % \begin{macrocode} \setcounter{COOL@listpointer}{0}% }% % \end{macrocode} % % Else % % \begin{macrocode} {% % \end{macrocode} % % start at the beginning of the list, so initialize |listpointer| % % \begin{macrocode} \setcounter{COOL@listpointer}{1}% % \end{macrocode} % % Assume that the target will not be found---it will be set to true by ``the gobbler" if it is % % \begin{macrocode} \setboolean{COOL@found}{false}% % \end{macrocode} % % Now call the gobbler---since the user shouldn't be forced to submit the end character (in fact % he or she shouldn't even need to worry that an end character exists nor what it is), we add it % on along with the `optional' parameter that tells us which element to retreive. To ensure that % the entire list is read in by |\COOL@listgobbler| we need the list stop `character' too. % % \begin{macrocode} \COOL@listgobble[#2]#1,\COOL@listStop,\COOL@listEnd% }% }% % \end{macrocode} % % \end{macro} % % % % \begin{macro}{\liststore} % \changes{v1.3}{2007/10/14}{added code to store the length of the list} % \begin{macro}{\COOL@liststore@gobbler} % The list may be stored in a macro of the user's choosing with the function. The syntax is % % |\liststore|\marg{csv\_list}\marg{macro\_base\_name} % % and the resulting list elements are stored in % % \meta{macro\_base\_name}\meta{list\_index\_roman} % % where \meta{list\_index\_roman} is the list index in roman numerals. % % Some examples will clarify: % % |\liststore{1,2,3,4}{temp}| \liststore{1,2,3,4}{temp} % % \noindent |\tempi;\tempii;\tempiii;\tempiv| yields \tempi;\tempii;\tempiii;\tempiv % % % \noindent |\liststore{a_1,a_2,a_3,a_4}{temp}| \liststore{a_1,a_2,a_3,a_4}{temp} % % \noindent |\tempi;\tempii;\tempiii;\tempiv| yields $\tempi;\tempii;\tempiii;\tempiv$ % \begin{macrocode} \def\COOL@liststore@gobbler[#1]#2,#3,\COOL@listEnd{% \ifthenelse{\equal{#3}{\COOL@listStop}}% {% \expandafter\gdef\csname #1\roman{COOL@listpointer}\endcsname{#2}% }% % Else {% \expandafter\gdef\csname #1\roman{COOL@listpointer}\endcsname{#2}% \stepcounter{COOL@listpointer}% \COOL@liststore@gobbler[#1]#3,\COOL@listEnd% }% } \newcommand{\liststore}[2]{% \setcounter{COOL@listpointer}{1}% \COOL@liststore@gobbler[#2]#1,\COOL@listStop,\COOL@listEnd% % \end{macrocode} % Now store the length % \begin{macrocode} \expandafter\xdef\csname #2length\endcsname{\arabic{COOL@listpointer}}% }% % \end{macrocode} % \end{macro} % \end{macro} % % % % % % \begin{macro}{\listlen} % % This returns the length of the list, though it is not useful for storing this length. If you need to record the % list's length for later use, it is better to use the next function |\listlenstore|. % % The format is |\listlen|\marg{comma deliminated list}. It works by recording % the value of |listpointer| after it has complete traversed the list. Since indexing starts at |1|, it uses the % index |0| which will never ever be an index of the list, so ``the gobbler" will not return any value. % % Example: |\listlen{1,2,3,4,5}| = \listlen{1,2,3,4,5} % % \begin{macrocode} \newcommand{\listlen}[1]{% \listval{#1}{0}% \arabic{COOL@listpointer} }%listlength % \end{macrocode} % % \end{macro} % % % % % \begin{macro}{\listlenstore} % % This store the length of the list. The format is |\listlenstore|\marg{counter}\marg{comma deliminated list}. % % \begin{macrocode} \newcommand{\listlenstore}[2]{% \listval{#2}{0}% \setcounter{#1}{\value{COOL@listpointer}} }%listlength % \end{macrocode} % % \end{macro} % % % % % % \begin{macro}{\listcopy} % \changes{v1.3}{2007/10/14}{added this function to the package} % % This copies one list into another element by element. % % \begin{macrocode} \newcommand{\listcopy}[2]{% % \end{macrocode} % Store the length of the list to be copied % \begin{macrocode} \setcounter{COOL@listlen}{\csname #1length\endcsname}% % \end{macrocode} % go through each element of the list and copy it to the new list % \begin{macrocode} \forloop{COOL@listpointer}{1}{\NOT \value{COOL@listpointer} > \value{COOL@listlen}}% {% \expandafter\xdef\csname #2\roman{COOL@listpointer}\endcsname{\csname #1\roman{COOL@listpointer}\endcsname}% }% \expandafter\xdef\csname #2length\endcsname{\csname #1length\endcsname}% } % \end{macrocode} % % \end{macro} % % % % % \begin{macro}{\listsum} % \changes{v1.2}{2007/10/10}{added this function to the package} % \changes{v1.3}{2007/10/14}{altered function to take optional argument for summing stored lists} % \changes{v1.4}{2009/09/20}{corrected optional argument to accept both `storedlist' and `liststored' due to original error in error message} % Sum the contents of the list. Integers are recognized and summed, tokens are treated as independent variables. % The function returns a string of the sum % % Counter for the coefficients % \begin{macrocode} \newcounter{COOL@intsum} % \end{macrocode} % Counter for the register index % \begin{macrocode} \newcounter{COOL@register@ct} \newcounter{COOL@register@len} % \end{macrocode} % boolean for identifying integers % \begin{macrocode} \newboolean{COOL@listsum@isint} % \end{macrocode} % % Now the function % % \begin{macrocode} \newcommand{\listsum}[3][liststored=false]{% % \end{macrocode} % Check to see if the list is already stored. If it is, copy it; otherwise store it % \begin{macrocode} \ifthenelse{ \equal{#1}{liststored=false} \OR \equal{#1}{storedlist=false} }% {% % \end{macrocode} % First store the entire list % \begin{macrocode} \liststore{#2}{COOL@listtosum@element@}% % \end{macrocode} % store the length of the list % \begin{macrocode} \listlenstore{COOL@listlen}{#2}% }% % \end{macrocode} % ElseIf % \begin{macrocode} { \ifthenelse{ \equal{#1}{liststored=true} \OR \equal{#1}{storedlist=true} }% {% \listcopy{#2}{COOL@listtosum@element@}% \setcounter{COOL@listlen}{\COOL@listtosum@element@length}% }% % \end{macrocode} % Else % \begin{macrocode} {% \PackageError{cool}{Invalid listsum optional argument}% {optional argument may only be `storedlist=true', `liststored=true', `storedlist=false', or `liststored=false'}% }}% % \end{macrocode} % check for the list having a non-zero length % \begin{macrocode} \ifthenelse{ \value{COOL@listlen} < 1 }% {% \PackageWarning{cool}{List is empty}% \xdef#3{0}% }% % \end{macrocode} % Else % \begin{macrocode} {% % \end{macrocode} % put the first list element into the register % \begin{macrocode} \isint{\COOL@listtosum@element@i}{COOL@listsum@isint}% \ifthenelse{ \boolean{COOL@listsum@isint} }% {% \xdef\COOL@listsum@register@integers{\COOL@listtosum@element@i}% \setcounter{COOL@register@len}{0}% }% % \end{macrocode} % Else % \begin{macrocode} {% % \end{macrocode} % Initialize the integers register to zero; store the character and its coefficient % \begin{macrocode} \gdef\COOL@listsum@register@integers{0}% \xdef\COOL@listsum@register@i{\COOL@listtosum@element@i}% \gdef\COOL@listsum@register@coef@i{1}% \setcounter{COOL@register@len}{1}% }% % \end{macrocode} % Now go through each additional element making an index of the symbols and summing identical ones % \begin{macrocode} \forloop{COOL@listpointer}{2}{\NOT \value{COOL@listpointer} > \value{COOL@listlen}}% {% % \end{macrocode} % Expand the element to a convenient storage macro % \begin{macrocode} \xdef\COOL@listsum@element{\csname COOL@listtosum@element@\roman{COOL@listpointer}\endcsname}% % \end{macrocode} % Check if this element is an integer % \begin{macrocode} \isint{\COOL@listsum@element}{COOL@listsum@isint}% \ifthenelse{ \boolean{COOL@listsum@isint} }% {% % \end{macrocode} % Grab the current value of the integers and store it in the register counter % \begin{macrocode} \setcounter{COOL@intsum}{\COOL@listsum@register@integers}% \addtocounter{COOL@intsum}{\COOL@listsum@element}% \xdef\COOL@listsum@register@integers{\arabic{COOL@intsum}}% }% % \end{macrocode} % Else, it's not an integer so search to see if it matches known elements % \begin{macrocode} {% \setboolean{COOL@found}{false}% \forloop{COOL@register@ct}{1}{\NOT \value{COOL@register@ct} > \value{COOL@register@len}}% {% \xdef\COOL@listsum@known@element{% \csname COOL@listsum@register@\roman{COOL@register@ct}\endcsname% }% \ifthenelse{ \equal{\COOL@listsum@element}{\COOL@listsum@known@element} }% {% % \end{macrocode} % found the element so increment the coefficient % (grab coefficient, store in ct, increment ct, store new ct) % \begin{macrocode} \xdef\COOL@listsum@known@element@coef{% \csname COOL@listsum@register@coef@\roman{COOL@register@ct}\endcsname% }% \setcounter{COOL@intsum}{\COOL@listsum@known@element@coef}% \addtocounter{COOL@intsum}{1}% \expandafter% \xdef\csname COOL@listsum@register@coef@\roman{COOL@register@ct}\endcsname% {\arabic{COOL@intsum}}% % \end{macrocode} % flag the element as found and set the counter to the length of the register $+1$ % \begin{macrocode} \setboolean{COOL@found}{true}% }% % \end{macrocode} % Else do nothing % \begin{macrocode} {% }% }% % \end{macrocode} % Check to see if the element is a known element. If not, add it to the register % \begin{macrocode} \ifthenelse{ \boolean{COOL@found} }% {}% % \end{macrocode} % Else % \begin{macrocode} {% \addtocounter{COOL@register@len}{1}% \expandafter% \xdef\csname COOL@listsum@register@\roman{COOL@register@len}\endcsname% {\COOL@listsum@element}% \expandafter% \xdef\csname COOL@listsum@register@coef@\roman{COOL@register@len}\endcsname{1}% }% }% }% % \end{macrocode} % Finally, create and store the sum % \begin{macrocode} \xdef\COOL@listsum@result{}% \ifthenelse{ \NOT \COOL@listsum@register@integers = 0 }% { \xdef\COOL@listsum@result{\COOL@listsum@result\COOL@listsum@register@integers}% \ifthenelse{ \NOT \value{COOL@register@len} = 0 }% {% \xdef\COOL@listsum@result{\COOL@listsum@result+}% }{}% }{}% \forloop{COOL@register@ct}{1}{ \NOT \value{COOL@register@ct} > \value{COOL@register@len} }% {% \edef\COOL@listsum@curcoef{\csname COOL@listsum@register@coef@\roman{COOL@register@ct}\endcsname}% \ifthenelse{ \NOT \COOL@listsum@curcoef = 1}% {% \xdef\COOL@listsum@result{\COOL@listsum@result\COOL@listsum@curcoef}% }{}% \xdef\COOL@listsum@result{\COOL@listsum@result\csname COOL@listsum@register@\roman{COOL@register@ct}\endcsname}% \ifthenelse{ \NOT \value{COOL@register@ct} = \value{COOL@register@len} }% {% \xdef\COOL@listsum@result{\COOL@listsum@result+}% }{}% }% \xdef#3{\COOL@listsum@result}% }% } % \end{macrocode} % % \end{macro} % % % \end{landscape} % % % \Finale \endinput