% 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