% 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