%%
%% This is file `macrolist.sty',
%% generated with the docstrip utility.
%%
%% The original source files were:
%%
%% macrolist.dtx  (with options: `package')
%% This work 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.

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{macrolist}[2021/07/31 v2.1.0 Create lists of macros and perform operations on them]

\RequirePackage{pgffor}

\newcommand{\macronewlist}[1]{
    \ifcsname c@macrolist@list@#1\endcsname
        \PackageError{macrolist}{The list '#1' is already defined}{}
    \else
        \newcounter{macrolist@list@#1}
        \setcounter{macrolist@list@#1}{0}
    \fi
}
\newcommand{\macrolistexists}[3]{\ifcsname c@macrolist@list@#1\endcsname#2\else#3\fi}
\newcommand{\macrolistelement}[2]{%
    \macrolist@inbounds{#1}{#2}%
    \csname macrolist@list@#1\the\numexpr #2\relax\endcsname%
}
\newcommand{\macrolistindexof}[2]{%
    \def\macrolist@listindex{0}%
    \macrolist@exists{#1}%
    \ifnum\macrolistsize{#1}>0\relax
        \def\macrolist@el{#2}%
        \macrolistforeach{#1}{\macrolist@listindexel}[\macrolistsize{#1}][1]{%
            \ifx\macrolist@el\macrolist@listindexel
                \xdef\macrolist@listindex{\macrolist@index}%
            \fi
        }%
    \fi
    \macrolist@listindex%
    \let\macrolist@listindex\relax%
}
\newcommand{\macrolistcontains}[4]{%
    \def\macrolist@listindex{0}%
    \macrolist@exists{#1}%
    \ifnum\macrolistsize{#1}>0\relax
        \def\macrolist@el{#2}%
        \macrolistforeach{#1}{\macrolist@listindexel}[\macrolistsize{#1}][1]{%
            \ifx\macrolist@el\macrolist@listindexel
                \xdef\macrolist@listindex{\macrolist@index}%
            \fi
        }%
    \fi
    \ifnum\macrolist@listindex>0\relax
        #3%
    \else
        #4%
    \fi
}
\newcommand{\macrolistadd}[1]{
    \macrolist@exists{#1}
    \def\macrolist@currlist{#1}
    \macrolist@listadd
}
%% We write \macrolistadd this way such that the optional argument will be positioned correctly
\newcommand{\macrolist@listadd}[2][]{
    \stepcounter{macrolist@list@\macrolist@currlist}

    \if\relax\detokenize{#1}\relax
        \expandafter\gdef\csname macrolist@list@\macrolist@currlist\macrolistsize{\macrolist@currlist}\endcsname{#2}
    \else
        \expandafter\ifnum\csname themacrolist@list@\macrolist@currlist\endcsname=#1
            \expandafter\gdef\csname macrolist@list@\macrolist@currlist\macrolistsize{\macrolist@currlist}\endcsname{#2}
        \else
            \macrolist@inbounds{\macrolist@currlist}{#1}
            \foreach \macrolist@index in {\macrolistsize{\macrolist@currlist}, ...,\the\numexpr #1+1\relax} {
                \global\expandafter\let\csname macrolist@list@\macrolist@currlist\macrolist@index\expandafter\endcsname\csname macrolist@list@\macrolist@currlist\the\numexpr\macrolist@index-1\relax\endcsname
            }
            \expandafter\gdef\csname macrolist@list@\macrolist@currlist#1\endcsname{#2}
        \fi
    \fi
}
\newcommand{\macrolisteadd}[1]{
    \macrolist@exists{#1}
    \def\macrolist@currlist{#1}
    \macrolist@listeadd
}
\newcommand{\macrolist@listeadd}[2][]{
    \stepcounter{macrolist@list@\macrolist@currlist}

    \if\relax\detokenize{#1}\relax
        \expandafter\xdef\csname macrolist@list@\macrolist@currlist\macrolistsize{\macrolist@currlist}\endcsname{#2}
    \else
        \expandafter\ifnum\csname themacrolist@list@\macrolist@currlist\endcsname=#1
            \expandafter\gdef\csname macrolist@list@\macrolist@currlist\macrolistsize{\macrolist@currlist}\endcsname{#2}
        \else
            \macrolist@inbounds{\macrolist@currlist}{#1}
            \foreach \macrolist@index in {\macrolistsize{\macrolist@currlist}, ...,\the\numexpr #1+1\relax} {
                \global\expandafter\let\csname macrolist@list@\macrolist@currlist\macrolist@index\expandafter\endcsname\csname macrolist@list@\macrolist@currlist\the\numexpr\macrolist@index-1\relax\endcsname
            }
            \expandafter\xdef\csname macrolist@list@\macrolist@currlist#1\endcsname{#2}
        \fi
    \fi
}
\newcommand{\macrolistremove}[2]{
    \macrolist@inbounds{#1}{#2}

    \ifnum\numexpr#2\relax=\macrolistsize{#1}
    \else
        \foreach \macrolist@index in {#2, ..., \the\numexpr\macrolistsize{#1}-1\relax} {
            \global\expandafter\let\csname macrolist@list@#1\macrolist@index\expandafter\endcsname\csname macrolist@list@#1\the\numexpr\macrolist@index+1\endcsname
        }
    \fi

    \global\expandafter\let\csname macrolist@list@#1\macrolistsize{#1}\endcsname\relax
    \addtocounter{macrolist@list@#1}{-1}
}
\newcommand{\macrolistremovelast}[1]{
    \macrolist@exists{#1}
    \global\expandafter\let\csname macrolist@list@#1\macrolistsize{#1}\endcsname\relax
    \addtocounter{macrolist@list@#1}{-1}
}
\newcommand{\macrolistclear}[2]{
    \macrolist@inbounds{#1}{#2}

    \foreach \macrolist@index in {1, ..., \macrolistsize{#1}} {
        \global\expandafter\let\csname \macrolist@list@#1\macrolist@index\endcsname\relax
    }

    \setcounter{macrolist@list@#1}{0}
}
\newcommand*{\macrolistsize}[1]{%
    \macrolist@exists{#1}%
    \csname themacrolist@list@#1\endcsname
}
\newcommand{\macrolistforeach}[2]
{%
    \def\macrolist@foreachstart{0}% Reset
    % This is used to make optional arguments line up correctly
    \def\macrolist@start{1}%
    \def\macrolist@end{\macrolistsize{#1}}%
    \def\macrolist@listname{#1}%
    \def\macrolist@element{#2}%
    \macrolist@listforeachi
}

\newcommand{\macrolist@listforeachi}[1][]{%
    \if\relax\detokenize{#1}\relax
    \else
        \def\macrolist@start{#1}%
        \def\macrolist@foreachstart{1}%
    \fi
    \macrolist@listforeachii
}

\newcommand{\macrolist@listforeachii}[1][]{%
    \if\relax\detokenize{#1}\relax
        \ifnum\macrolist@foreachstart=1
            \PackageError{macrolist}{You must either pass in both a starting and ending position or neither}{}
        \fi
    \else
        \def\macrolist@end{#1}%
    \fi
    \macrolist@listforeachaction
}

\newcommand{\macrolist@listforeachaction}[1]{%
    \macrolist@exists{\macrolist@listname}%
    \ifnum\numexpr\macrolist@start\relax>\macrolistsize{\macrolist@listname}%
        \PackageError{macrolist}{The starting index of the loop is out of the bounds of list '\macrolist@listname'}{}
    \fi
    \ifnum\numexpr\macrolist@end\relax>\macrolistsize{\macrolist@listname}
        \PackageError{macrolist}{The ending index of the loop is out of the bounds of list '\macrolist@listname'}{}
    \fi
    \foreach \macrolist@index in {\the\numexpr\macrolist@start\relax, ..., \the\numexpr\macrolist@end\relax} {%
        \expandafter\expandafter\expandafter\let\expandafter\expandafter\macrolist@element\csname macrolist@list@\macrolist@listname\macrolist@index\endcsname
        #1%
    }%
}
\newcommand{\macrolistjoin}[2]{%
    \ifnum\macrolistsize{#1}>1
        \macrolistforeach{#1}{\macrolist@joinelement}[1][\macrolistsize{#1}-1]{\macrolist@joinelement#2}%
    \fi
    \ifnum\macrolistsize{#1}>0
        \macrolistelement{#1}{\macrolistsize{#1}}%
    \fi
}
%% List: Some text
%% List: Some text, \macro
%% Prints out "Some text"
%% List: Element inserted into beginning, Some text, \macro
%% List: Some text, \macro
%% We're printing out \textbf{Some text}. We're printing out \textbf{\macro}.
%% Some text, \macro
\newcommand*{\macrolist@exists}[1]{%
    \ifcsname c@macrolist@list@#1\endcsname
    \else
        \PackageError{macrolist}
        {The first argument is not a defined list}
        {Make sure you have defined the list before trying to operate on it.}
    \fi
}
\newcommand*{\macrolist@inbounds}[2]{%
    \macrolist@exists{#1}%
    %
    \if\relax\detokenize{#2}
        \PackageError{macrolist}
        {No number has been passed into the second argument of your command
        }{Pass in a number to the second argument of your command.}
    \fi
    %
    \ifnum\numexpr#2 \relax>\macrolistsize{#1}
        \PackageError{macrolist}
        {Index out of bounds}
        {The number you have passed in to the second argument of your command\MessageBreak
        is out of the bounds of list '#1'.}
    \fi
}
\endinput
%%
%% End of file `macrolist.sty'.
