\def\readarrayPackageVersion{3.1} \def\readarrayPackageDate{2021/09/17} \ProvidesPackage{readarray} [\readarrayPackageDate\ \readarrayPackageVersion\ % Routines for inputting 2D and 3D array data and recalling it on an element-by-element basis.] % % This work may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.3 % of this license or (at your option) any later version. % The latest version of this license is in % http://www.latex-project.org/lppl.txt % and version 1.3c or later is part of all distributions of LaTeX % version 2005/12/01 or later. % % This work has the LPPL maintenance status `maintained'. % % The Current Maintainer of this work is Steven B. Segletes. % \RequirePackage{forloop} \RequirePackage{listofitems}[2016-10-22] % \newcounter{@index} \newcounter{@plane} \newcounter{@row} \newcounter{@col} \newcounter{use@args} \newcounter{@record} \newcounter{index@count} \newtoks\Arg@toks \newtoks\@arrayident@toks \newread\rdar@file \newcount\readarrayendlinechar \newif\ifignoreblankreadarrayrecords \ignoreblankreadarrayrecordsfalse \edef\readarraybackslash{\expandafter\@firstoftwo\string\\} % \newcommand\readdef[2]{\@readdef{#1}{#2}{ArrayRecord}} % \newcommand\readrecordarray[2]{% \edef\@arrayident{\rdar@macroname#2}% \def\ra@TermA{\@readdef{#1}}% \def\ra@TermB{\expandafter\ra@TermA\csname\@arrayident def\endcsname}% \expandafter\ra@TermB\expandafter{\@arrayident}% } % \newcommand\readarray{\@ifstar {\read@array@newsyntax[*]}{\read@array@newsyntax[]}} % \def\arraytomacro#1[#2]#3{% \@arrayident@toks=\expandafter\expandafter\expandafter {\csname\rdar@macroname#1[#2]\endcsname}% \expandafter\def\expandafter#3\expandafter{\the\@arrayident@toks}% } % \newcommand\readarraysepchar[1]{\def\read@array@sepchar{#1}} % \def\nocheckbounds{\def\rootmacro@aux##1##2{\csname##1[##2]\endcsname% }\typeout{readarray: bounds checking OFF}% } % \def\checkbounds{\def\rootmacro@aux##1##2{% \ifcsname##1[##2]\endcsname\csname##1[##2]\endcsname\else% \readarrayboundfailmsg% \typeout{readarray Warning: \readarraybackslash##1[##2] undefined.}% \fi% }\typeout{readarray: bounds checking ON}% } % \def\hypercheckbounds{\def\rootmacro@aux##1##2{% \ifcsname##1[##2]\endcsname\csname##1[##2]\endcsname\else \readarrayboundfailmsg% \typeout{readarray Warning: \readarraybackslash##1[##2] undefined:}% \setcounter{index@count}{0}% \parse@index##2,\relax% \forloop{@index}{1}{\value{@index}<\numexpr\theindex@count+1}{% \ifnum\parsed@index[\the@index]<1% \relax\typeout{ \nonpos@message{##1}{##2}}\fi% }% \ifnum \value{index@count}=1\relax% \ifnum\parsed@index[1]>\csname##1CELLS\endcsname\relax \typeout{ \record@message{##1}{##2}}\fi% \fi \ifnum \value{index@count}=2\relax% \ifnum\parsed@index[1]>\csname##1ROWS\endcsname\relax \typeout{ \row@message{##1}{\parsed@index[1]}}\fi% \ifnum\parsed@index[2]>\csname##1COLS\endcsname\relax \typeout{ \col@message{##1}{\parsed@index[2]}}\fi% \fi \ifnum \value{index@count}=3\relax% \ifnum\parsed@index[1]>\csname##1PLANES\endcsname\relax \typeout{ \plane@message{##1}{\parsed@index[1]}}\fi% \ifnum\parsed@index[2]>\csname##1ROWS\endcsname\relax \typeout{ \row@message{##1}{\parsed@index[2]}}\fi% \ifnum\parsed@index[3]>\csname##1COLS\endcsname\relax \typeout{ \col@message{##1}{\parsed@index[3]}}\fi% \fi% \fi% }\typeout{readarray: bounds hyperchecking ON}% } % \def\rdar@macroname{\expandafter\@gobble\string} % \def\getArg@toks[#1]{\Arg@toks\expandafter\expandafter\expandafter{\Arg@list[#1]}} % \def\@readdef#1#2#3{% \clear@array{#3}% \edef\former@recordcount{\csname #3CELLS\endcsname}% \def\nrows{0}% \def\first@row{T}% \def\first@plane{F}% \catcode\endlinechar=\readarrayendlinechar\relax % \def#2{}% \setcounter{@record}{0}% \openin\rdar@file=#1% \ifignoreblankreadarrayrecords \def\rdar@iftest{\rdar@record\empty}\else\def\rdar@iftest{01}\fi \loop\unless\ifeof\rdar@file% \read\rdar@file to\rdar@record % Reads record into \rdar@record% \expandafter\ifx\rdar@iftest\else \stepcounter{@record}% \expandafter\g@addto@macro\expandafter#2\expandafter{\rdar@record}% \ifx\rdar@record\empty\else\expandafter \g@addto@macro\expandafter#2\expandafter{\read@array@sepchar}% \if T\first@row \read@array{#2}% \setcounter{@col}{\numexpr(\Arg@listlen-1)}% \edef\ncols{\arabic{@col}}% \def\first@row{F}% \setcounter{@row}{0}% \def\first@plane{T}% \fi \fi \if T\first@plane \ifx\rdar@record\empty \edef\nrows{\arabic{@row}}% \def\first@plane{F}% \else \stepcounter{@row}% \fi \fi \def\record@name{\csname #3[\the@record]\endcsname}% \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter \expandafter\def\expandafter\record@name\expandafter{\rdar@record}% \fi \repeat \ifnum\nrows=0 \edef\nrows{\arabic{@row}}\fi \edef\nrecords{\arabic{@record}}% \expandafter\edef\csname #3PLANES\endcsname{0}% \expandafter\edef\csname #3ROWS\endcsname{\nrecords}% \expandafter\edef\csname #3COLS\endcsname{0}% \expandafter\edef\csname #3CELLS\endcsname{\nrecords}% \closein\rdar@file \catcode\endlinechar=5 % \define@rootmacro{#3}% } % \def\read@array@newsyntax[#1]#2#3[#4,#5]{% \setcounter{index@count}{0}% \parse@index#5,\relax% \ifnum\value{index@count}=1\relax% \def\ra@TermA{\read@Arrayij[#1]{#2}}% \edef\ra@TermB{{\rdar@macroname#3}{\parsed@index[1]}}% \expandafter\ra@TermA\ra@TermB% \else \ifnum\value{index@count}=2\relax% \def\ra@TermA{\read@Arrayijk[#1]{#2}}% \edef\ra@TermB{{\rdar@macroname#3}{\parsed@index[1]}% {\parsed@index[2]}}% \expandafter\ra@TermA\ra@TermB% \fi\fi } % \newcommand\read@Arrayijk[5][]{% \clear@array{#3}% \read@array[#1]{#2}% \setcounter{@plane}{\numexpr(\Arg@listlen/#5/#4)}% \setcounter{use@args}{\numexpr\arabic{@plane}*#4*#5}% \ifnum\arabic{use@args} > \Arg@listlen\relax \addtocounter{@plane}{-1}% \setcounter{use@args}{\numexpr\arabic{@plane}*#4*#5}% \fi% \expandafter\edef\csname#3PLANES\endcsname{\arabic{@plane}}% \expandafter\edef\csname#3ROWS\endcsname{#4}% \expandafter\edef\csname#3COLS\endcsname{#5}% \expandafter\edef\csname#3CELLS\endcsname{\arabic{use@args}}% \setcounter{@plane}{1}% \setcounter{@row}{1}% \setcounter{@col}{0}% \forloop{@index}{1}{\value{@index} < \numexpr\value{use@args}+1}{% \addtocounter{@col}{1}% \ifnum\value{@col} > #5\relax \addtocounter{@row}{1}% \addtocounter{@col}{-#5}% \fi \ifnum\value{@row} > #4\relax \addtocounter{@plane}{1}% \addtocounter{@row}{-#4}% \fi \def\arg@name{\csname#3[\the@plane,\the@row,\the@col]\endcsname}% \getArg@toks[\the@index]% \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter% \expandafter\def\expandafter\arg@name\expandafter{\the\Arg@toks}% }% \define@rootmacro{#3}% } % \newcommand\read@Arrayij[4][]{% \clear@array{#3}% \read@array[#1]{#2}% \setcounter{@row}{\numexpr(\Arg@listlen/#4)}% \setcounter{use@args}{\numexpr\arabic{@row}*#4}% \ifnum\arabic{use@args} > \Arg@listlen\relax \addtocounter{@row}{-1}% \setcounter{use@args}{\numexpr\arabic{@row}*#4}% \fi \expandafter\edef\csname#3PLANES\endcsname{0}% \expandafter\edef\csname#3ROWS\endcsname{\arabic{@row}}% \expandafter\edef\csname#3COLS\endcsname{#4}% \expandafter\edef\csname#3CELLS\endcsname{\arabic{use@args}}% \setcounter{@row}{1}% \setcounter{@col}{0}% \forloop{@index}{1}{\value{@index} < \numexpr\value{use@args}+1}{% \addtocounter{@col}{1}% \ifnum\value{@col} > #4\relax \addtocounter{@row}{1}% \addtocounter{@col}{-#4}% \fi \def\arg@name{\csname#3[\the@row,\the@col]\endcsname}% \getArg@toks[\the@index]% \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter% \expandafter\def\expandafter\arg@name\expandafter{\the\Arg@toks}% }% \define@rootmacro{#3}% } % \newcommand\read@array[2][]{% \bgroup% \ifx\empty\read@array@sepchar \setsepchar{\empty}% \else \expandafter\setsepchar\expandafter{\read@array@sepchar}% \fi \greadlist#1\Arg@list{#2}% \egroup% \edef\Arg@listCELLS{\Arg@listlen}% } % \def\clear@array#1{% \ifcsname #1ROWS\endcsname% \forloop{@row}{1}{\value{@row}<\numexpr\csname #1ROWS\endcsname+1}{% \ifnum\csname #1COLS\endcsname=0\relax% \expandafter\let\csname #1[\the@row]\endcsname\undefined% \else \forloop{@col}{1}{\value{@col}<\numexpr\csname #1COLS\endcsname+1}{% \ifnum\csname #1PLANES\endcsname=0\relax% \expandafter\let\csname #1[\the@row,\the@col]\endcsname \undefined% \else \forloop{@plane}{1}{\value{@plane}<\numexpr\csname #1PLANES\endcsname+1}{% \expandafter% \let\csname #1[\the@plane,\the@row,\the@col]\endcsname \undefined% }% \fi% }% \fi% }% \expandafter\let\csname #1PLANES\endcsname\undefined \expandafter\let\csname #1ROWS\endcsname\undefined \expandafter\let\csname #1PLANES\endcsname\undefined \expandafter\let\csname #1\endcsname\undefined \fi% } % \def\setvalue#1[#2]#3{% \ifcsname\rdar@macroname#1[#2]\endcsname \expandafter\def\csname\rdar@macroname#1[#2]\endcsname{#3}% \else \typeout{readarray Warning (setvalue = #3): \readarraybackslash\rdar@macroname#1[#2] undefined.}% \fi% } % \def\readarray@initializedata#1[#2]#3{% \expandafter\def\csname \rdar@macroname#1[#2]\expandafter\endcsname\expandafter{#3}% } % \def\initarray#1[#2]{% \edef\@tmp{\rdar@macroname#1}% \expandafter\clear@array\expandafter{\@tmp}% \expandafter\define@rootmacro\expandafter{\@tmp}% \setcounter{index@count}{0}% \parse@index#2,\relax \ifnum\value{index@count}=2\relax \setcounter{use@args}{\numexpr\parsed@index[1]*\parsed@index[2]} \expandafter\def\csname\@tmp PLANES\endcsname{0} \expandafter\edef\csname\@tmp ROWS\endcsname{\parsed@index[1]} \expandafter\edef\csname\@tmp COLS\endcsname{\parsed@index[2]} \expandafter\edef\csname\@tmp CELLS\endcsname{\theuse@args} \forloop{@row}{1}{\value{@row}<\numexpr\parsed@index[1]+1}{% \forloop{@col}{1}{\value{@col}<\numexpr\parsed@index[2]+1}{% \readarray@initializedata#1[\the@row,\the@col]{\readarrayinitvalue}}} \else \ifnum\value{index@count}=3\relax \setcounter{use@args}{\numexpr\parsed@index[1]* \parsed@index[2]*\parsed@index[3]} \expandafter\edef\csname\@tmp PLANES\endcsname{\parsed@index[1]} \expandafter\edef\csname\@tmp ROWS\endcsname{\parsed@index[2]} \expandafter\edef\csname\@tmp COLS\endcsname{\parsed@index[3]} \expandafter\edef\csname\@tmp CELLS\endcsname{\theuse@args} \forloop{@plane}{1}{\value{@plane}<\numexpr\parsed@index[1]+1}{% \forloop{@row}{1}{\value{@row}<\numexpr\parsed@index[2]+1}{% \forloop{@col}{1}{\value{@col}<\numexpr\parsed@index[3]+1}{% \readarray@initializedata#1[\the@plane,\the@row,\the@col]{% \readarrayinitvalue}}}} \else [initarray ERROR: 2-D or 3-D arrays only] \fi \fi } % \def\mergearray#1#2[#3]{% \setcounter{index@count}{0}% \parse@index#3,\relax \ifnum\value{index@count}=2\relax \forloop{@row}{1}{\value{@row}< \numexpr\csname\rdar@macroname#1ROWS\endcsname+1}{% \forloop{@col}{1}{\value{@col}< \numexpr\csname\rdar@macroname#1COLS\endcsname+1}{% \edef\tmpA{\the\numexpr\the@row+\parsed@index[1]-1,% \the\numexpr\the@col+\parsed@index[2]-1}% \edef\tmpB{\csname\rdar@macroname#1[\the@row,\the@col]\endcsname}% \def\tmpC{\setvalue#2[\tmpA]}% \expandafter\tmpC\expandafter{\tmpB}}}% \else \ifnum\value{index@count}=3\relax \forloop{@plane}{1}{\value{@plane}< \numexpr\csname\rdar@macroname#1PLANES\endcsname+1}{% \forloop{@row}{1}{\value{@row}< \numexpr\csname\rdar@macroname#1ROWS\endcsname+1}{% \forloop{@col}{1}{\value{@col}< \numexpr\csname\rdar@macroname#1COLS\endcsname+1}{% \edef\tmpA{\the\numexpr\the@plane+\parsed@index[1]-1,% \the\numexpr\the@row+\parsed@index[2]-1,% \the\numexpr\the@col+\parsed@index[3]-1}% \edef\tmpB{\csname\rdar@macroname#1% [\the@plane,\the@row,\the@col]\endcsname}% \def\tmpC{\setvalue#2[\tmpA]}% \expandafter\tmpC\expandafter{\tmpB}}}}% \else [mergearray ERROR: 2-D or 3-D arrays only] \fi \fi } % \def\addtoArg@toks#1{\Arg@toks\expandafter{\the\Arg@toks#1}} \def\xaddtoArg@toks#1{\expandafter\addtoArg@toks\expandafter{#1}} \def\xxaddtoArg@toks#1{\expandafter\xaddtoArg@toks\expandafter{#1}} % \def\typesetarray#1{\noindent\Arg@toks{}% \ifnum\csname\rdar@macroname#1PLANES\endcsname>0\relax \forloop{@plane}{1}{\value{@plane}< \numexpr\csname\rdar@macroname#1PLANES\endcsname+1}{% \ifnum\the@plane=1 \else\xaddtoArg@toks{\typesetplanesepchar}\fi% \forloop{@row}{1}{\value{@row}< \numexpr\csname\rdar@macroname#1ROWS\endcsname+1}{% \ifnum\the@row=1 \else\xaddtoArg@toks{\typesetrowsepchar}\fi% \forloop{@col}{1}{\value{@col}< \numexpr\csname\rdar@macroname#1COLS\endcsname+1}{% \ifnum\the@col=1 \else\xaddtoArg@toks{\typesetcolsepchar}\fi% \xaddtoArg@toks{\expandafter\typesetcell\expandafter {\csname\rdar@macroname#1[\the@plane,\the@row,\the@col]\endcsname}}}% }% }% \else \forloop{@row}{1}{\value{@row}< \numexpr\csname\rdar@macroname#1ROWS\endcsname+1}{% \ifnum\the@row=1 \else\xaddtoArg@toks{\typesetrowsepchar}\fi% \forloop{@col}{1}{\value{@col}< \numexpr\csname\rdar@macroname#1COLS\endcsname+1}{% \ifnum\the@col=1 \else\xaddtoArg@toks{\typesetcolsepchar}\fi% \xaddtoArg@toks{\expandafter\typesetcell\expandafter {\csname\rdar@macroname#1[\the@row,\the@col]\endcsname}}% }% }% \fi \the\Arg@toks } % \def\define@rootmacro#1{% \expandafter\def\csname#1\endcsname[##1]{\rootmacro@aux{#1}{##1}}% } % \def\parse@index#1,#2\relax{% \stepcounter{index@count}% \expandafter\gdef\csname parsed@index[\theindex@count]\endcsname{#1}% \ifx\relax#2\relax\else\parse@index#2\relax\fi% } % \def\parsed@index[#1]{\csname parsed@index[#1]\endcsname} % % INITIALIZATION % ON \readdef, SEP CHAR INSERTED AFTER EACH RECORD; % ON \readarray, SEP CHAR SERVES AS DATA-FIELD SEPARATOR \readarraysepchar{ } % ON \readdef, IGNORE END-LINE CHARS BY DEFAULT (NORMAL LaTeX MODE = 5) \readarrayendlinechar=9 % DEFAULT CELL DATA FOR \initarray \def\readarrayinitvalue{-} % DEFAULT FIELD SEPARATORS FOR \typesetarray \def\typesetplanesepchar{\\---\\} \def\typesetrowsepchar{\\} \def\typesetcolsepchar{,} % DEFAULT CELL FORMATTING ON \typesetarray \def\typesetcell#1{#1} % \nocheckbounds% DEFAULT IS NO BOUNDS CHECKING % \def\nonpos@message#1#2{Nonpositive index [#2] prohibited for \ra@nm#1.} \def\record@message#1#2{% RECORD=#2 exceeds bounds(=\csname#1CELLS\endcsname) for \ra@nm#1.} \def\plane@message#1#2{% PLANE=#2 exceeds bounds(=\csname#1PLANES\endcsname) for \ra@nm#1.} \def\row@message#1#2{% ROW=#2 exceeds bounds(=\csname#1ROWS\endcsname) for \ra@nm#1.} \def\col@message#1#2{% COL=#2 exceeds bounds(=\csname#1COLS\endcsname) for \ra@nm#1.} % \def\readarrayboundfailmsg{?}% WHEN ARRAY CALL OUT OF BOUNDS, IF BOUNDS CHECKING ON \def\ra@nm#1.{\readarraybackslash#1.} % % SUPPORT/DEBUG ROUTINES % (THESE ARE DEPRECATED...CONSIDER USING \typesetarray AS AN ALTERNATIVE) % \def\the@showargs@rule{\kern.2pt\rule{.8ex}{1.6ex}\hspace{.2pt}}% % \arraydump INITIALIZATIONS \def\row@spacer{\\} \def\row@msg{\the@showargs@rule\hfill{\scriptsize\scshape$<$\row@sign~\arabic{@row}$>$}} \def\header@msg{{\bfseries\ra@rank:}~} \def\last@row{\\} \def\plane@msg{\plane@sign\hrulefill\mbox{}\\} \def\close@out{} % \newcommand\arraydump[1]{% \expandafter\ifx\csname\rdar@macroname#1\endcsname\relax\else% \edef\ra@TmpA{\csname\rdar@macroname#1PLANES\endcsname}% \edef\ra@TmpB{\csname\rdar@macroname#1COLS\endcsname}% \def\ra@rank{3-D}% \ifnum\ra@TmpA=0\relax\def\ra@TmpA{1}\def\plane@sign{\mbox{}}\def\ra@rank{2-D}% \else\def\plane@sign{{\scriptsize\scshape Plane \arabic{@plane}}}\fi% \ifnum\ra@TmpB=0\relax\def\ra@TmpB{1}\def\row@sign{Record}\def\ra@rank{1-D}% \else\def\row@sign{Row}\fi% \par\noindent\header@msg% \forloop{@plane}{1}{\value{@plane}<\numexpr\ra@TmpA+1}{% \plane@msg% \forloop{@row}{1}{\value{@row}< \numexpr\csname\rdar@macroname#1ROWS\endcsname+1}{% \ifnum\value{@row}=1\relax\else\row@spacer\fi% \forloop{@col}{1}{\value{@col}< \numexpr\ra@TmpB+1}{% \the@showargs@rule% \ifnum\csname\rdar@macroname#1COLS\endcsname=0\relax% #1[\the@row]% \else% \ifnum\csname\rdar@macroname#1PLANES\endcsname=0\relax% #1[\the@row,\the@col]% \else% #1[\the@plane,\the@row,\the@col]% \fi% \fi% }\row@msg% }\last@row% }\close@out\mbox{}\hrulefill\mbox{}\par% \fi% } % \newcommand\scalardump[1]{\bgroup% \def\row@spacer{}% \def\row@msg{}% \def\header@msg{{\bfseries\csname\rdar@macroname####1CELLS\endcsname\ ELEMENTS:}% ~\hrulefill\mbox{}\\}% \def\last@row{}% \def\plane@msg{}% \def\close@out{\the@showargs@rule\\}% \arraydump#1\egroup% } \endinput % Revisions: % v1.0 -Initial release. % v1.01 -Documentation revision. % v1.1 -Added \csname record\roman{@row}\endcsname to \readdef. % v1.2 -Corrected the [truncated] LPPL license info. % -Added \arrayij and \arrayijk, which can be put into \edef. % -Used \romannumeral in preference to \roman{}, when possible, % to avoid unnecessary use of counters. % v1.3 -Moved \newread outside of \readdef, so as not to exhaust the % 16 allotted file streams (Thanks to Ken Kubota for the tip). % v2.0 -Converted parsing to listofitems package. This allows for % ANY parsing character or combination of characters (via logical OR). % -Replaced all \protected@edef's with appropriately expanded \def's. % -Use listofitems package in preference to \getargsC. % -Deprecated \Arrayijk, \arrayijk, \Arrayij, & \arrayij. Direct % access now preferred, e.g., \xyz[2,3,1]. % -Deprecated most other commands in favor of a more natural syntax. % v3.0 (2021-08-05) % -Added features: \setvalue, \initarray, \mergearray, \typesetarray. % -Allowed for \readarrayendlinechar to be set other than 9. % v3.1 (2021-09-17) % -Bug fix to not break if first line of file subject to \readdef % is blank/comment line. % -Introduce \ifignoreblankreadarrayrecords % -Bug fix in \clear@array, if selected array name is defined, % but not defined as an array. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% COMMANDS THAT WERE DEPRECATED IN v2.0 (2016-11-10), NOT BEING IN THE PREFERRED PACKAGE SYNTAX, THAT HAVE BEEN ELIMINATED in v3.0 (2021) CODE PROVIDED BELOW AS A COPY/PASTE LAST RESORT FOR STRAGGLERS \usepackage{ifthen} % % DEPRECATED COMMANDS (NOT PREFERRED EMBODIMENT OF PACKAGE SYNTAX) % \newcommand\readArrayijk{\@ifstar{\read@Arrayijk[*]}{\read@Arrayijk}} \newcommand\readArrayij{\@ifstar{\read@Arrayij[*]}{\read@Arrayij}} \newcommand\arrayijk[4]{\csname#1[#2,#3,#4]\endcsname} \newcommand\arrayij[3]{\csname#1[#2,#3]\endcsname} \newcommand\Arrayijk[5][\relax]{% \bgroup% \ifx\relax#1\else\def\readarrayboundfailmsg{#1}\fi\csname#2\endcsname[#3,#4,#5]% \egroup% } \newcommand\Arrayij[4][\relax]{% \bgroup% \ifx\relax#1\else\def\readarrayboundfailmsg{#1}\fi\csname#2\endcsname[#3,#4]% \egroup% } \newcommand\copyrecords[1]{% \clear@array{#1}% \edef\former@recordcount{\csname #1CELLS\endcsname}% \setcounter{@record}{0}% \whiledo{\value{@record} < \nrecords}{% \addtocounter{@record}{1}% \def\arg@name{\csname#1[\the@record]\endcsname}% \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter% \expandafter\def\expandafter\arg@name\expandafter{% \csname ArrayRecord[\the@record]\endcsname}% }% \expandafter\edef\csname#1PLANES\endcsname{0}% \expandafter\edef\csname#1ROWS\endcsname{\nrecords}% \expandafter\edef\csname#1COLS\endcsname{0}% \expandafter\edef\csname#1CELLS\endcsname{\nrecords}% \define@rootmacro{#1}% } \newcommand\showargs[1][0]{\bgroup% \def\Arg@listPLANES{0}% \def\Arg@listCOLS{0}% \let\Arg@listROWS\Arg@listCELLS% \scalardump\Arg@list\egroup% } \newcommand\showrecord[2][\relax]{% \bgroup\ifx\relax#1\else\def\readarrayboundfailmsg{#1}\fi\ArrayRecord[#2]\egroup% } % The support routine \getargs{} is provided for backward compatibility. % It is preferable to directly use facilities of the % listofitems package to accomplish these tasks. \def\getargsC#1{% \bgroup% \expandafter\setsepchar\expandafter{\read@array@sepchar}% \greadlist\Arg@list{#1}% \egroup% \edef\narg{\Arg@listlen}% \let\Arg@listCELLS\narg% \setcounter{@index}{0}% \whiledo{\value{@index}<\narg}{% \stepcounter{@index}% \expandafter\edef\csname arg\romannumeral\value{@index}\endcsname{% \Arg@list[\value{@index}]}% }% }