% This macro source file is from the four volume series
% "TeX in Practice" by Stephan von Bechtolsheim, published
% 1993 by Springer-Verlag, New York.
% Copyright 1993 Stephan von Bechtolsheim.
% No warranty or liability is assumed.
% This macro may be copied freely if no fees other than
% media cost or shipping charges are charged and as long
% as this copyright and the following source code itself
% is not changed. Please see the series for further information.
%
% Version: 1.0
% Date: May 1, 1993
%
%
% This source code is documented in 20.3, p. III-136.
% Original source in file "tokens3.TEX", starting line 1017.
\wlog{L: "arraymac.tip" ["tokens3.TEX," l. 1017, p. III-136]}%
% This file DOES belong to format "texip."
\InputD{list-mac.tip}
\InputD{rangetst.tip}
\InputD{doloop.tip}
\catcode`\@ = 11
\def\IndexLastElement #1#2{%
    \NumberOfListElements{#1}{#2}%
    \advance #2 by -1
}
\newcount\@ArrayIndexCheckCount
\def\ArrayIndexCheck #1#2{%
    \IndexLastElement{#1}{\@ArrayIndexCheckCount}%
    \ifnum\@ArrayIndexCheckCount = -1
        \errmessage{\string\ArrayIndexCheck: array \string#2
            is empty.}%
    \else
        \CheckRange{#2}{0}{\@ArrayIndexCheckCount}%
            {\string\ArrayIndexCheck: index \number#2 out
                of range in list \string#1}%
    \fi
}
\newcount\@AccessArrayElementLimit
\newcount\@AccessArrayElementCount
\def\AccessArrayElement #1#2#3{%
    \ArrayIndexCheck{#1}{#2}%
    \let\@AccessArrayElementList = #1%
    \@AccessArrayElementLimit = #2\relax
    \DoLoop{\@AccessArrayElementCount}% 
        {1}{1}{\@AccessArrayElementLimit}%
        {\DropFirstElementOfList{\@AccessArrayElementList}}%
    \CarOfList{\@AccessArrayElementList}{#3}%
}
\newcount\@ModifyArrayElementCount
\newcount\@ModifyArrayElementLimit
\def\ModifyArrayElement #1#2#3{%
    \ArrayIndexCheck{#1}{2}%
    \IndexLastElement{#1}{\@ModifyArrayElementLimit}%
    \let\@ModifyArrayList = #1%
    \def\@ModifyArrayRet{}%
    \DoLoop{\@ModifyArrayElementCount}% 
        {0}{1}{\@ModifyArrayElementLimit}%
        {%
            \CarOfList{\@ModifyArrayList}%
                {\@ModifyArrayElement}%
            \DropFirstElementOfList{\@ModifyArrayList}%
            \ifnum\@ModifyArrayElementCount = #2\relax
                \RightAppendElement{\@ModifyArrayRet}{#3}%
            \else
                \RightAppendElement
                    {\@ModifyArrayRet}%
                    {\@ModifyArrayElement}%
            \fi
        }%
    \let #1 = \@ModifyArrayRet
}
\newcount\@InsertArrayElementCount
\newcount\@InsertArrayElementCountTwo
\def\InsertArrayElement #1#2#3{%
    \ifnum\NumberOfListElementsNumConditional{#1}=0
        \errmessage{\string\InsertArrayElement: empty array}%
    \fi
    \ifnum\NumberOfListElementsNumConditional{#1}=#2
    \else
            \ArrayIndexCheck{#1}{#2}%
    \fi
    \def\@InsertArrayElementListPre{}%
    \ifnum #2>0
        \@InsertArrayElementCount = #2\relax
        \advance\@InsertArrayElementCount by -1
        \ExtractSubArray{#1}{0}{\@InsertArrayElementCount}%
            {\@InsertArrayElementListPre}%
    \fi
    \def\@InsertArrayElementListPost{}%
    \IndexLastElement{#1}{\@InsertArrayElementCount}%
    \ifnum #2 > \@InsertArrayElementCount
    \else
        \ExtractSubArray{#1}{#2}{\@InsertArrayElementCount}%
            {\@InsertArrayElementListPost}%
    \fi
    \RightAppendElement{\@InsertArrayElementListPre}{#3}%
    \CombineTwoLists
        {\@InsertArrayElementListPre}%
        {\@InsertArrayElementListPost}%
        {\@InsertArrayElementListPre}%
    \let #1 = \@InsertArrayElementListPre
}
\newcount\@DeleteArrayElementCount
\newcount\@DeleteArrayElementLimit
\def\DeleteArrayElement #1#2{%
    \ArrayIndexCheck{#1}{#2}%
    \let\@DeleteArrayElementList = #1%
    \IndexLastElement{#1}{\@DeleteArrayElementLimit}%
    \ifnum\@DeleteArrayElementLimit = -1
        \errmessage{\string\DeleteArrayElement: empty array.}%
    \fi
    \def\@DeleteArrayElementResultList{}%
    \DoLoop{\@DeleteArrayElementCount}% 
        {0}{1}{\@DeleteArrayElementLimit}%
        {%
            \CarOfList{\@DeleteArrayElementList}%
                {\@DeleteArrayElement}%
            \DropFirstElementOfList{\@DeleteArrayElementList}%
            \ifnum\@DeleteArrayElementCount = #2\relax
            \else
                \RightAppendElement
                    {\@DeleteArrayElementResultList}%
                    {\@DeleteArrayElement}%
            \fi
        }%
    \let #1=\@DeleteArrayElementResultList
}
\newcount\@DeleteArrayElementRangeCount
\newcount\@DeleteArrayElementRangeLimit
\def\DeleteArrayElementRange #1#2#3{%
    \ArrayIndexCheck{#1}{#2}%
    \ArrayIndexCheck{#1}{#3}%
    \ifnum #2>#3
        \errmessage{\string\DeleteArrayElementRange:
            first index larger than second. Makes no
            sense}%
    \fi
    \@DeleteArrayElementRangeLimit = #3\relax
    \advance\@DeleteArrayElementRangeLimit by -#2%
    \advance\@DeleteArrayElementRangeLimit by 1
    \DoLoop{\@DeleteArrayElementRangeCount}{1}{1}%
        {\@DeleteArrayElementRangeLimit}%
        {\DropArrayElement{#1}{#2}}%
}
\newcount\@ShowArrayCount
\newcount\@ShowArrayLimit
\def\ShowArray #1{%
    \wlog{\string\ShowArray: begin}%
    \IndexLastElement{#1}{\@ShowArrayLimit}%
    \ifnum\@ShowArrayLimit = -1
        \wlog{** empty array **}%
    \else
        \DoLoop{\@ShowArrayCount}{0}{1}{\@ShowArrayLimit}{%
            \AccessArrayElement{#1}{\@ShowArrayCount}%
                {\@ShowArrayElement}%
            \wlog{Index \the\@ShowArrayCount:
                "\@ShowArrayElement"}%
        }%
    \fi
    \wlog{\string\ShowArray: end}%
    \wlog{}%
}
\def\@TokenToListDoneMacro{\@TokensToListDone}%
\def\TokensToTeXList #1#2{%
    \def#1{}%
    \def\@TokensToListName{#1}%
    \@TokensToList #2\@TokensToListDone
}
\def\@TokensToList #1{%
    \def\@TokensToListMacArgOne{#1}%
    \ifx\@TokensToListMacArgOne\@TokenToListDoneMacro
        \let\@TokensToListNext = \relax
    \else
        \expandafter\RightAppendElement\@TokensToListName{#1}%
        \let\@TokensToListNext = \@TokensToList
    \fi     
    \@TokensToListNext
}
\newcount\@ExtractArrayCount
\newcount\@ExtractArrayLimit
\newif\if@ExtractCopy
\def\ExtractSubArray #1#2#3#4{%
    \ArrayIndexCheck{#1}{#2}%
    \ArrayIndexCheck{#1}{#3}%
    \ifnum #3<#2
        \errmessage{\string\ExtractSubArray: first index >
            second index, error}%
    \fi
    \def\@ExtractSubArrayResult{}%
    \IndexLastElement{#1}{\@ExtractArrayLimit}%
    \DoLoop{\@ExtractArrayCount}{0}{1}{\@ExtractArrayLimit}%
        {%
            \@ExtractCopytrue
            \ifnum\@ExtractArrayCount < #2\relax
                \@ExtractCopyfalse
            \fi
            \ifnum\@ExtractArrayCount > #3\relax
                \@ExtractCopyfalse
            \fi
            \if@ExtractCopy
                \AccessArrayElement
                    {#1}%
                    {\@ExtractArrayCount}%
                    {\@SubArrayElement}%
                \RightAppendElement
                    {\@ExtractSubArrayResult}%
                    {\@SubArrayElement}%
            \fi
        }%
    \let #4 = \@ExtractSubArrayResult
}
\catcode`\@ = 12