texlive[60193] Master/texmf-dist: readarray (8aug21)

commits+karl at tug.org commits+karl at tug.org
Sun Aug 8 22:55:00 CEST 2021

Revision: 60193
Author:   karl
Date:     2021-08-08 22:55:00 +0200 (Sun, 08 Aug 2021)
Log Message:
readarray (8aug21)

Modified Paths:

Modified: trunk/Master/texmf-dist/doc/latex/readarray/readarray.pdf
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/readarray/readarray.tex
--- trunk/Master/texmf-dist/doc/latex/readarray/readarray.tex	2021-08-08 07:22:24 UTC (rev 60192)
+++ trunk/Master/texmf-dist/doc/latex/readarray/readarray.tex	2021-08-08 20:55:00 UTC (rev 60193)
@@ -1,26 +1,5 @@
-%% Copyright 2013 Steven B. Segletes
-% 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.
-% Revisions:
-% 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).
@@ -32,8 +11,7 @@
 \def\cmd#1{\texttt{\string\ \unskip#1}}
 A111 A112 A113 A114
 A121 A122 A123 A124
 A131 A132 A133 A134
@@ -42,7 +20,7 @@
 A221 A222 A223 A224
 A231 A232 A233 A234
 A111 A112 A113 A114
 A121 A122 A123 A124
@@ -53,7 +31,7 @@
 A231 A232 A233 A234
 \textit{am} ,  \textit{are}, have \textit{been}, have \textit{been}
 \textit{are}, \textit{are} , have \textit{been}, have \textit{been}
 \textit{is} , \textit{are} , has \textit{been} , have \textit{been}
@@ -80,28 +58,44 @@
 \rule{0em}{.7em}\small Routines for inputting formatted array data and 
 recalling it on an element-by-element basis.\\
 \rule{0em}{2.7em}\large Steven B. Segletes\\
-steven.b.segletes.civ at mail.mil\\
+SSegletes at verizon.net\\
-\section*{Comments About Version 2.0}
+\subsection*{Comments About Version 3.0}
-Version 2.0 of the \rdar{} package has brought major changes,
+Version 3.0 of \rdar{} introduces several new features.
+Arrays can be initialized  with the \vb|\initarray| command,
+  rather than being read from a file.
+With \vb|\setvalue|, the tokens of individual
+  array cells can be revised on demand.
+The contents of one array can be merged into another
+  by way of the \vb|\mergearray| command.
+The \vb|\typesetarray| command allows for versatile ways
+  to format your array output, including by way
+  of \vb|tabular| environments.
+The way end-of-line characters can be handled on a data-read
+  is made more versatile with this package version.
+There are many new things here---check them out.\vspace{-10pt}
+\subsubsection*{Comments About Version 2.0}
+Version 2.0 of the \rdar{} package brought major changes,
   including a \textit{new and improved} syntax.
 Functionally, the data-reading/parsing code of the package
-  has been revised to use the powerful \loi{} package.
+  was revised to use the powerful \loi{} package.
 This has two primary advantages: 1) the data that is read is no
   longer expanded prior to the read, so that macros can be read
   and stored in the data arrays using their unexpanded tokens; and 2) 
   list separators other than a space may now be employed
   to parse the data into array cells.
-While a newer preferred syntax has been introduced for reading and
-  recalling arrays, the deprecated syntax is still supported.
 The user will also note other small changes, such as the fact that errors
   arising from array-boundary violations now appear in the log file
-  rather than the document itself.
+  rather than the document itself.\vspace{-10pt}
 \section{Description and Commands}
@@ -117,7 +111,6 @@
   to do this, without the help of this package.
 The commands included in this package help the user to input data, define
 it in terms of array elements, and recall those elements at will. Those
 commands are:
@@ -127,8 +120,9 @@
 \textup{To place file data into a data macro:}\\
 \textup{To place file data into a 1-D file-record array:}\\
-\textup{To parse a data macro and place the results into a 2-D or 3-D array:}\\
+ \hfill\textup{(1-D)}\\
+\textup{To parse a data macro and place the results into a new 2-D or 3-D array:}\\
@@ -138,18 +132,50 @@
-\textup{Recall data from indexed array cell:}\\
+\textup{To create a new array, each cell initialized to a default 
+  value:}\\
+  \hfill\textup{(2-D)}\\
+  \vb|]|\hfill\textup{(3-D)}\\
+\textup{To merge each cell of one array into another:}\\
+  column\vb|]|\hfill\textup{(2-D)}\\
+  row\vb|,|column\vb|]|\hfill\textup{(3-D)}\\
+\textup{To typeset an array:}\\
+\textup{Recall (typeset) data from indexed array cell:}\\
 \textup{To place the actual tokens of an array cell into a macro:}\\
-  \hfill\textup{(3-D)}\\
-\textup{To change the array-parsing separator character:}\\
+  \vb|]\|macro\hfill\textup{(3-D)}\\
+\textup{To manually (re)set the value of an existing array cell:}\\
+  value\vb|}|\hfill\textup{(2-D)}\\
+  value\vb|}|\hfill\textup{(3-D)}\\
+\textup{To change the array-parsing separator for}
+  \vb|\readdef| \textup{and/or} \vb|\readarray|\textup{:}\\
+\textup{To change the default (=9) end-of-line catcode for}
+  \vb|\readdef|\textup{:}\\
+\textup{To redefine default cell initialization for} \vb|\initarray|
+  \textup{:}\\
+\textup{To redefine default cell format in} \vb|\typesetarray|\textup{:}\\
+\textup{To redefine default plane, row, column separator formats for}
+  \vb|\typesetarray|\textup{:}\\
 \textup{To select the level of bounds checking on array cell recall:}\\
 \rl\vb|\nocheckbounds|\hfill OR\hfill%
 \vb|\checkbounds|\hfill OR\hfill%
@@ -156,10 +182,10 @@
-In these commands, \cmd{}\textit{data-macro} is a command sequence into
+In these commands, \cmd{}\textit{data-macro} is a control sequence into
   which the contents of \texttt{filename} are set into a \cmd{def}. 
-The \textit{array-identifier} is a sequence of  
-  (catcode 11) letters that identify the array.
+The \cmd{}\textit{array-identifier} is the array into which cell data is
+  inserted.
 The starred version of the commands are used if, during the array 
   creation, it is desired to automatically excise the array data of 
   leading and trailing spaces.
@@ -197,7 +223,7 @@
 In addition to the strings of fixed name created during the 
   \cmd{readdef}, there are various strings created during
   the \cmd{readarray} whose name is a function of the 
-  \textit{array-identifier}, such as
+  \cmd{}\textit{array-identifier}, such as
@@ -205,24 +231,11 @@
-where \textit{array-identifier} is the alphabetic-character string by which
+where \cmd{}\textit{array-identifier} is the name
 you have designated a particular array.  
 Their meaning will be discussed later in this document.
-Support routines which are generally not required directly by
-the user for the specification and recall of data arrays, but which are
-useful for debugging include
-the following:
-These macros print out the complete array, in either a structured or
-  unstructured form, respectively.
 \section{Data Structure}
 The first requirement is to lay out a format for the data interface to
@@ -229,7 +242,7 @@
   this package.  
 The {\rdar} package is set up to digest data separated by a user-defined 
   separator character.
-The default separator is a space character but, as of V2.0, the separator
+The default separator is a space character but the separator
   may be specified by way of \vb|\readarraysepchar{|\textit{separator}\vb|}|.
 The format for the data organization to be digested is as follows, 
   for 2-D arrays:
@@ -307,6 +320,41 @@
   into the data macro \cmd{dataA}; and 2) they are also placed into a 1-D
   file record array, \cmd{ArrayRecord}.
+Regarding the point that end-of-line characters are replaced
+  with a data separator, these are controlled by two separate
+  mechanisms, each with its own control.
+First, end-of-lines are, by default discarded---this is accomplished
+  internally with \rdar{} setting \vb|\endlinechar| equal to 9,
+  during the \vb|\readdef|.
+This is not the native \LaTeX{} behavior.
+In \LaTeX{}, end-of-lines are converted into spaces, unless 
+  preempted with a \vb|%| character or a line-ending control
+  sequence.
+To recover the \LaTeX{} way of treating end-of-lines, the 
+  count \vb|\readarrayendlinechar| is provided, which can
+  be set in the manner desired for subsequent invocations
+  of \vb|\readdef|.
+For example, \vb|\readarrayendlinechar=5 | will change 
+  subsequent treatment of end-of-line characters to the normal
+  \LaTeX{} treatment.
+The second aspect regarding end-of-lines is the data
+  separator inserted when the end-of-line is 
+  reached.  This is one of the functions of the
+  \vb|\readarraysepchar| macro, the argument to which
+  is the separator inserted into the read, when 
+  end-of-line is encountered during a \vb|\readdef|.
+If you don't want any record separators inserted during
+ the \vb|\readdef|, one may set \vb|\readarraysepchar{}|.
+Note, however, that an empty \rdar{} sepchar, while valid
+  during a \vb|\readdef|, is meaningless during a
+  \vb|\readarray| invocation, since it would like to
+  use the sepchar to parse the data.  
+Therefore, an empty sepchar should be redefined to
+  a meaningful value prior to invoking \vb|\readarray|.
+See section~\ref{s:sepchar} for more information on the
+  separator character.
 There is no
 \textit{requirement} that the input file be organized with structured rows
   of data corresponding to individual file records, nor that blank 
@@ -407,7 +455,7 @@
-\subsection{Creating 2-D and 3-D Arrays}
+\subsection{Creating 2-D and 3-D Arrays from Data}
 The \cmd{readarray}\margcmd{readarray} command, used to convert
   raw parsable data into data arrays,
@@ -424,10 +472,6 @@
 This option, is only relevant when the data separator is not already a
-If an array name is reutilized, its prior definitions are cleared,
-  so that ``old'' data is not inadvertantly retrieved following the
-  reutilization.
 \subsubsection{2-D Arrays}
@@ -489,21 +533,66 @@
 If, perchance, a row or plane is only partially defined by 
   \cmd{readarray}, the partial data is discarded from the array.
-\subsubsection{Array Parsing Separator}
+\subsubsection{Array Parsing Separator\label{s:sepchar}}
 While it may be easily envisioned that the array data is numerical, this
   need not be the case.  
 The array data may be text, and even formatted text.
-Furthermore, one may introduce space characters into the data of
-  individual cells simply by resetting the \rdar{} parsing separator
-  to something other than the default space, ``~''.
-This can be done, for example employing a comma as the separator,  
-  by way of \vb|\readarraysepchar{,}|.\margcmd{readarraysepchar}
+A key setting, either when inputting information from a file
+  by way of \vb|\readdef| or when parsing a \vb|\def|'ed
+  argument into an array by way of \vb|\readarray|, is the
+  macro \vb|\readarraysepchar|.\margcmd{readarraysepchar}
+The value of \vb|\readarraysepchar| is used in distinct
+  ways for \vb|\readdef| and \vb|\readarray|.
+For \vb|\readdef|, the separator is inserted into the 
+  \vb|\data-macro|
+  definition whenever an end-line-char (end of record)
+  is encountered.
+For the subsequent \vb|\readarray| (with or without a \vb|*|), the
+  \vb|\readarraysepchar| is used to separate the data
+  contained in the \vb|\data-macro| into individual cell
+  data that will be placed into the \vb|\array-identifier|.
+For example, if your data file is comma separated, but the
+  last item of data in each record is not followed by a 
+  trailing comma, setting \vb|\readarraysepchar{,}| will
+  assure that the comma gets inserted into the 
+  \vb|\data-macro| after each record, during the 
+  \vb|\readdef|.
+This will preclude confusion of the last item of 
+  each record with the first item of the subsequent 
+  record when the \vb|\readarray| is executed.
+If the trailing comma were present in the data file,
+  then \vb|\readarraysepchar{}| could be set for the
+  \vb|\readdef|, to avoid inserting an extra comma.
+However, it would have to be reset to a comma before
+  executing the \vb|\readarray|, in order to parse
+  the data using the comma to separate cell data.
+Finally, if one wished to employ lists rather than
+  arrays (wherein each row could have a variable
+  number of columns, for example), then one could
+  set \vb|\readarraysepchar{\\}| prior to the 
+  \vb|\readdef|, so as to insert a \vb|\\| macro
+  between each record.
+Then, if the file data were otherwise comma separated,
+  one could use the \loi{} tools rather than \rdar{}
+  to absorb the data as a list, rather than an array.
+In this case, \vb|\setsepchar{\\/,}| would set a
+  two-tier nested parsing for \loi{}.
+Then, \vb|\readlist\|\textit{listname}\vb|{\|%
+  \textit{data-macro}\vb|}| would read the data into
+  a list, with a variable column dimension for each row,
+  based on the number of commas in each file record.
 Note also, using the facilities of the underlying \loi{} package,
   that compound separators are possible.
-For example, \textit{either} a comma \textit{or} a period may be used
+For example, when employing \vb|\readarray|.
+  \textit{either} a comma \textit{or} a period may be used
   for the data parsing, by specifying a
   \textbf{logical-OR} (\vb+||+) separated list: \vb:\readarraysepchar{,||.}:.
 Similarly, a multicharacter separator is possible, so that setting
@@ -528,9 +617,18 @@
-will employ a comma separator to parse the file.
-It will then create a 3-D array using data from the file, placed into the 
-  array \cmd{tobeConjugation}.
+will read the file into \vb|\dataC|, adding a comma between
+  records.
+It will then employ a comma separator to parse the file.
+As a result, it will create a 3-D array using data from the
+  \vb|\dataC| macro, and create a parsed array by the name of
+  \cmd{tobeConjugation}.
+During the \vb|\readdef|, it will have been gleaned that the file
+  is arranged with 4 columns (stored in \vb|\ncols|) and
+  3 rows per plane (stored in \vb|\nrows|).
+These row \& column specifications could be manually overridden
+  merely by specifying actual numbers in the bracketed argument to
+  \vb|\readarray|.
 Leading/trailing spaces will be removed from the data, with the use of the
   star form of the \cmd{readarray} command.
 Data can then be directly accessed, so that, for example
@@ -545,9 +643,70 @@
+\section{Initializing an Array Structure}
-\section{Recalling Data from Array Structures}
+With the \vb|readarray| macro described above, data can be
+  introduced into an array structure that is specifically created
+  to receive the data.
+However, sometimes, an array placeholder must be defined before 
+  knowing exactly what will eventually reside there.
+For this purpose, that package provides \vb|\initarray|.
+  \margcmd{initarray}
+With a command like \vb|\initarray\z[3,4]|, a 2-D array identified
+  as \vb|\z| is created with 3 rows and 4 columns.
+Each cell is initialized with a standard value (default
+  \vb|-|).
+However, the standard initialization value may be changed,
+  for example, to a \vb|0| with an invocation of
+  \vb|\renewcommand\readarrayinitvalue{0}|.%
+  \margcmd{readarrayinitvalue}
+\section{Manually Setting Array-Cell Data}
+While \vb|\readarray| and \vb|\initarray| are used to create
+  new arrays and to populate their cells with content, we here
+  examine a way to update or change the content of a single existing
+  array cell.
+The command \vb|\setvalue|\margcmd{setvalue} is used to place
+  content into an existing array cell.
+Let us assume that the array \vb|\z| was created as a 
+  2-D array of size 3 rows by 4 columns.
+The command \vb|\setvalue\z[2,3]{xyz}| will replace the
+  existing content of the array's 2nd row and 3rd column
+  with the tokens \vb|xyz|.
+All other cells in the \vb|\z| array will remain as they
+  were; the pre-existing content of cell \vb|\z[2,3]|, once
+  replaced, will no longer be available.
+\section{Merging Data from Separate Arrays}
+The command \vb|\setvalue| was described as a way to replace
+  the contents of a single cell in an array.
+Here, we describe a way to replace the contents of multiple
+  cells at once, in the form of merging two arrays with the
+  macro \vb|\mergearray|\margcmd{mergearray}.
+This command sets up a loop of repeated invocations of 
+  \vb|\setarray|.
+Let's assume that we had created arrays 
+  \vb|\Q[10,10]| and \vb|\R[3,2]|.
+The command
+  \vb|\mergarray\R\Q[6,3]| will overlay the contents of 
+  \vb|\R|'s 3x2 cells into the \vb|\Q| cells, beginning with
+  \vb|\Q[6,3]|.
+The overlay will, therefore, include the cells: \vb|[6,3]|, \vb|[6,4]|, 
+  \vb|[7,3]|, \vb|[7,4]|, \vb|[8,3]|, and \vb|[8,4]|.
+If the overlay of the \textit{from-array} causes the bounds in 
+  the \textit{to-array} to be exceeded, no copy is made of those 
+  cells.
+However, a warning will be noted in the log file if error
+  checking is enabled.
+\section{Recalling Cell Data from Array Structures}
 While one must specify the number of columns and/or rows associated
 with the \vb|\readarray| invocation, those numbers may not yet
@@ -597,6 +756,74 @@
 which yields ``\tobeConjugation[3,2,4]''.
+\section{Typesetting Whole Arrays}
+Often, one wishes not just to recall the contents of a single
+  cell, but to recall a whole array for the purposes of typesetting.
+The command \vb|\typesetarray| does just that.
+Let us create an array \vb|\Q[2,2,2]| whose cell \vb|[i,j,k]| contains
+  the tokens ``($i,j,k$)'', where $i$, $j$ and $k$ denote a particular
+  plane, row and column of \vb|\Q|.
+If one invokes \vb|\typesetarray\Q|\margcmd{typesetarray}, the default 
+  dump of the array will be:
+The presentation of the array is governed by four defined macros,
+  whose definitions can be renewed:\\
+  \vb|\typesetplanesepchar| (default \vb|\\---\\|),\\
+  \vb|\typesetrowsepchar| (default \vb|\\|),\\
+  \vb|\typesetcolsepchar| (default \vb|,|) and\\
+  \vb|\typesetcell|,\\
+  the last of which takes 1 argument (the cell content) and, by
+  default, presents it unaltered.
+One can see that the default treatment separates columns with
+  a comma, performs a linefeed between each row, and
+  inserts an em-dash on a line by itself between each plane, which
+  is exactly how \vb|\Q| was presented above.
+However, these defaults can be renewed to produce a different
+  visual format, for example, that obtainable from a \vb|tabular|
+  environment.
+For example, upon issuing these renewals
+one may insert the \vb|\typesetarray| inside a \vb|\tabular|
+  and it will format according to those rules:
+yielding the following output:
 \section{Bounds Checking}
 While the user is developing his or her application involving the {\rdar}
@@ -637,7 +864,7 @@
 However, with \cmd{hypercheckbounds} set, full
   expansion of array cells is no longer possible.
-\section{Accessing Array Cells if No Expansion is Required}
+\section{Transfer Array Cell Tokens to Macro}
 With the normal use of \cmd{\rmfamily\itshape array-identifier} syntax
   for accessing array cells,
@@ -652,69 +879,28 @@
 So, for example \vb|\arraytomacro\tobeConjugation[2,2,3]\thiscell| will
   place the cell's original tokens in the macro \cmd{thiscell}.
-Upon detokenization, \cmd{thiscell} contains
+Upon detokenization, the macro \cmd{thiscell} contains
-\section{Support Routines}
-The package provides two commands that can help one understand how a
-  data set has been parsed into an array.
-Both of these commands dump the specified array to the document.
-In the case of \cmd{arraydump}\margcmd{arraydump}, the array is formatted
-  in the structure of the array, broken up by columns, rows, and planes.
-In the case of \cmd{scalardump}\margcmd{scalardump}, however, the elements 
-  of the array are dumped sequentially, without reference to the array's
-  heirarchy.
+\section{Deprecated and Defunct Features}
-For the case of 1-D record array \cmd{oneD} employed in prior sections, for 
-  example, the invocations of
+The following commands are supplied, but are no longer the preferred
+embodiment of package syntax.
-results in
+To replace the function of these, \vb|\typesetarray| is
+  the preferred embodiment.
-The \cmd{twoD} equivalent, resulting from parsing the same data file as
-  a 2-D, rather than a 1-D record array, is
+The following macros are no longer supported.
-For the case of the 3-D array (earlier read as \cmd{threeD}), 
-the \cmd{arraydump} would appear as
-Note that the \cmd{scalardump} of \cmd{threeD} is indistinguishable from
-  that of \cmd{twoD}, since both arrays are comprised of the same data 
-  cells, though arrayed into different plane/row/column structures.
-For comparison, the \cmd{arraydump} of \cmd{tobeConjugation} is
-\section{Deprecated, Vestigial, and Defunct Features}
-The following commands are supplied, but are no longer the preferred
-embodiment of package syntax.
@@ -733,44 +919,16 @@
-The following support macros are provided but no longer recommended.  
-Their capability is more fully served by way of the \loi{} package.
 \rl\vb|\getargsC{\|macro {\upshape or} string\vb|}|\\
-Note that whereas \cmd{getargs} could previously (pre-V2.0 \rdar) employ 
-  only a space as the parsing separator, \cmd{getargs} now respects the
-  currently set value of separator, as (re)defined by \cmd{readarraysepchar}.
-The following macros are no longer supported.
-Since the package now supports arbitrary parsing separators,
-  there is no need for the function of \cmd{converttilde}.
-However, were one desiring to parse, while treating hard spaces as spaces,
-  this can be simply achieved under V2.0 \rdar{} by setting the 
-  parsing character as either a space or a hard space, using
-  \vb:readarraysepchar{ ||~}:.
-Likewise, the indirect addressing (using a romannumeral \textit{index})
-  provided by the internal command \cmd{record}\textit{index} is fully 
-  superceded by the ability to directly address any record of \rdar's
-  1-D record arrays. 
 I am profoundly thankful to Christian Tellechea for using

Modified: trunk/Master/texmf-dist/tex/latex/readarray/readarray.sty
--- trunk/Master/texmf-dist/tex/latex/readarray/readarray.sty	2021-08-08 07:22:24 UTC (rev 60192)
+++ trunk/Master/texmf-dist/tex/latex/readarray/readarray.sty	2021-08-08 20:55:00 UTC (rev 60193)
@@ -1,5 +1,5 @@
 [\readarrayPackageDate\ \readarrayPackageVersion\ %
 Routines for inputting 2D and 3D array data and recalling it on an 
@@ -33,7 +33,10 @@
 %       -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
@@ -42,13 +45,12 @@
 \newcounter{use at args}
-\newcounter{arg at index}
-\newcounter{break at count}
 \newcounter{index at count}
-\newcounter{loop at count}
 \newtoks\Arg at toks
 \newtoks\@arrayident at toks
 \newread\rdar at file
@@ -59,62 +61,58 @@
   \expandafter\ra at TermB\expandafter{\@arrayident}%
-\newcommand\readarray{\@ifstar{\read at array@newsyntax[*]}{\read at array@newsyntax[]}}
+    {\read at array@newsyntax[*]}{\read at array@newsyntax[]}}
-  \edef\@arrayident{\rdar at macroname#1[#2]}%
-  \@arrayident at toks=\expandafter\expandafter\expandafter{\csname\@arrayident\endcsname}%
+  \@arrayident at toks=\expandafter\expandafter\expandafter
+    {\csname\rdar at macroname#1[#2]\endcsname}%
   \expandafter\def\expandafter#3\expandafter{\the\@arrayident at toks}%
 \newcommand\readarraysepchar[1]{\def\read at array@sepchar{#1}}
-\def\nocheckbounds{\def\rootmacro at aux##1##2##3{##1%
+\def\nocheckbounds{\def\rootmacro at aux##1##2{\csname##1[##2]\endcsname%
  }\typeout{readarray: bounds checking OFF}%
-\def\checkbounds{\def\rootmacro at aux##1##2##3{##1%
-  \expandafter\ifx##1\relax\readarrayboundfailmsg%
-  \setbox0=\hbox{\typeout{readarray Warning: ##1 out of bounds.}}%
+\def\checkbounds{\def\rootmacro at aux##1##2{%
+  \ifcsname##1[##2]\endcsname\csname##1[##2]\endcsname\else%
+  \readarrayboundfailmsg%
+  \typeout{readarray Warning: \readarraybackslash##1[##2] undefined.}%
  }\typeout{readarray: bounds checking ON}%
-\def\hypercheckbounds{\def\rootmacro at aux##1##2##3{##1%
-  \expandafter\ifx##1\relax\readarrayboundfailmsg%
-    \typeout{readarray Warning: ##1 out of bounds:}%
+\def\hypercheckbounds{\def\rootmacro at aux##1##2{%
+  \ifcsname##1[##2]\endcsname\csname##1[##2]\endcsname\else
+    \readarrayboundfailmsg%
+    \typeout{readarray Warning: \readarraybackslash##1[##2] undefined:}%
+    \setcounter{index at count}{0}%
+    \parse at index##2,\relax%
+    \forloop{@index}{1}{\value{@index}<\numexpr\theindex at count+1}{%
+      \ifnum\parsed at index[\the at index]<1%
+        \relax\typeout{ \nonpos at message{##1}{##2}}\fi%
+    }%
+    \ifnum \value{index at count}=1\relax%
+      \ifnum\parsed at index[1]>\csname##1CELLS\endcsname\relax
+        \typeout{ \record at message{##1}{##2}}\fi%
+    \fi
+    \ifnum \value{index at count}=2\relax%
+      \ifnum\parsed at index[1]>\csname##1ROWS\endcsname\relax
+        \typeout{ \row at message{##1}{\parsed at index[1]}}\fi%
+      \ifnum\parsed at index[2]>\csname##1COLS\endcsname\relax
+        \typeout{ \col at message{##1}{\parsed at index[2]}}\fi%
+    \fi
+    \ifnum \value{index at count}=3\relax%
+      \ifnum\parsed at index[1]>\csname##1PLANES\endcsname\relax
+        \typeout{ \plane at message{##1}{\parsed at index[1]}}\fi%
+      \ifnum\parsed at index[2]>\csname##1ROWS\endcsname\relax
+        \typeout{ \row at message{##1}{\parsed at index[2]}}\fi%
+      \ifnum\parsed at index[3]>\csname##1COLS\endcsname\relax
+        \typeout{ \col at message{##1}{\parsed at index[3]}}\fi%
+    \fi%
-  \setcounter{index at count}{0}%
-  \parse at index##3,\relax%
-  \setcounter{loop at count}{0}%
-  \whiledo{\value{loop at count}<\value{index at count}}{%
-    \stepcounter{loop at count}%
-    \ifnum\csname parsed at index[\theloop at count]\endcsname<0%
-      \relax\typeout{\nonposmessage{##2}{##3}}\fi%
-  }%
-  \ifnum \value{index at count}=1\relax%
-    \ifnum\csname parsed at index[1]\endcsname>%
-      \csname##2CELLS\endcsname\relax\typeout{\recordmessage{##2}{##3}}\fi%
-  \fi
-  \ifnum \value{index at count}=2\relax%
-    \ifnum\csname parsed at index[1]\endcsname>%
-      \csname##2ROWS\endcsname\relax\typeout{\rowmessage{##2}{%
-        \csname parsed at index[1]\endcsname}}\fi%
-    \ifnum\csname parsed at index[2]\endcsname>%
-      \csname##2COLS\endcsname\relax\typeout{\colmessage{##2}{%
-        \csname parsed at index[2]\endcsname}}\fi%
-  \fi
-  \ifnum \value{index at count}=3\relax%
-    \ifnum\csname parsed at index[1]\endcsname>%
-      \csname##2PLANES\endcsname\relax\typeout{\planemessage{##2}{%
-        \csname parsed at index[1]\endcsname}}\fi%
-    \ifnum\csname parsed at index[2]\endcsname>%
-      \csname##2ROWS\endcsname\relax\typeout{\rowmessage{##2}{%
-        \csname parsed at index[2]\endcsname}}\fi%
-    \ifnum\csname parsed at index[2]\endcsname>%
-      \csname##2COLS\endcsname\relax\typeout{\colmessage{##2}{%
-        \csname parsed at index[3]\endcsname}}\fi%
-  \fi%
  }\typeout{readarray: bounds hyperchecking ON}%
@@ -122,30 +120,30 @@
 \def\getArg at toks[#1]{\Arg at toks\expandafter\expandafter\expandafter{\Arg at list[#1]}}
   \clear at array{#3}%
   \edef\former at recordcount{\csname #3CELLS\endcsname}%
   \def\first at row{T}%
   \def\first at plane{T}%
-  \catcode\endlinechar=9 %
+  \catcode\endlinechar=\readarrayendlinechar\relax %
   \openin\rdar at file=#1%
   \loop\unless\ifeof\rdar at file%
-    \read\rdar at file to\rdar at fileline % Reads a line of the file into \rdar at fileline%
+    \read\rdar at file to\rdar at fileline % Reads file line into \rdar at fileline%
     \expandafter\g at addto@macro\expandafter#2\expandafter{\rdar at fileline}%
-    \ifthenelse{\equal{\rdar at fileline}{}}{}{\expandafter\g at addto@macro%
-      \expandafter#2\expandafter{\read at array@sepchar}}%
+    \ifx\rdar at fileline\empty\else\expandafter\g at addto@macro%
+      \expandafter#2\expandafter{\read at array@sepchar}\fi%
     \if T\first at row\read at array{#2}\setcounter{@col}{\numexpr(\Arg at listlen-1)}%
       \edef\ncols{\arabic{@col}}\def\first at row{F}\setcounter{@row}{1}%
       \if T\first at plane%
-        \ifthenelse{\equal{\rdar at fileline}{}}{%
+        \ifx\rdar at fileline\empty
           \edef\nrows{\arabic{@row}}\def\first at plane{F}%
-        }{%
+        \else
-        }%
+        \fi
     \def\record at name{\csname #3[\the at record]\endcsname}%
@@ -163,18 +161,17 @@
 \def\read at array@newsyntax[#1]#2#3[#4,#5]{%
-  \edef\@arrayident{\rdar at macroname#3}%
   \setcounter{index at count}{0}%
   \parse at index#5,\relax%
   \ifnum\value{index at count}=1\relax%
-     \def\ra at TermA{\readArrayij#1{#2}}%
-     \edef\ra at TermB{{\@arrayident}{\csname parsed at index[1]\endcsname}}%
+     \def\ra at TermA{\read at Arrayij[#1]{#2}}%
+     \edef\ra at TermB{{\rdar at macroname#3}{\parsed at index[1]}}%
      \expandafter\ra at TermA\ra at TermB%
   \ifnum\value{index at count}=2\relax%
-     \def\ra at TermA{\readArrayijk#1{#2}}%
-     \edef\ra at TermB{{\@arrayident}{\csname parsed at index[1]\endcsname}%
-      {\csname parsed at index[2]\endcsname}}%
+     \def\ra at TermA{\read at Arrayijk[#1]{#2}}%
+     \edef\ra at TermB{{\rdar at macroname#3}{\parsed at index[1]}%
+      {\parsed at index[2]}}%
      \expandafter\ra at TermA\ra at TermB%
@@ -184,29 +181,27 @@
   \read at array[#1]{#2}%
   \setcounter{@plane}{\numexpr(\Arg at listlen/#5/#4)}%
   \setcounter{use at args}{\numexpr\arabic{@plane}*#4*#5}%
-  \ifthenelse{\arabic{use at args} > \Arg at listlen}{%
+  \ifnum\arabic{use at args} > \Arg at listlen\relax
     \setcounter{use at args}{\numexpr\arabic{@plane}*#4*#5}%
-  }{}%
+  \fi%
   \expandafter\edef\csname#3CELLS\endcsname{\arabic{use at args}}%
-  \setcounter{@index}{0}%
-  \whiledo{\value{@index} < \value{use at args}}{%
-    \addtocounter{@index}{1}%
+  \forloop{@index}{1}{\value{@index} < \numexpr\value{use at args}+1}{%
-    \ifthenelse{\value{@col} > #5}%
-      {\addtocounter{@row}{1}%
-       \addtocounter{@col}{-#5}}%
-      {}%
-    \ifthenelse{\value{@row} > #4}%
-      {\addtocounter{@plane}{1}%
-       \addtocounter{@row}{-#4}}%
-      {}%
+    \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 at name{\csname#3[\the at plane,\the at row,\the at col]\endcsname}%
     \getArg at toks[\the at index]%
@@ -220,24 +215,22 @@
   \read at array[#1]{#2}%
   \setcounter{@row}{\numexpr(\Arg at listlen/#4)}%
   \setcounter{use at args}{\numexpr\arabic{@row}*#4}%
-  \ifthenelse{\arabic{use at args} > \Arg at listlen}{%
+  \ifnum\arabic{use at args} > \Arg at listlen\relax
     \setcounter{use at args}{\numexpr\arabic{@row}*#4}%
-  }{}%
+  \fi
   \expandafter\edef\csname#3CELLS\endcsname{\arabic{use at args}}%
-  \setcounter{@index}{0}%
-  \whiledo{\value{@index} < \value{use at args}}{%
-    \addtocounter{@index}{1}%
+  \forloop{@index}{1}{\value{@index} < \numexpr\value{use at args}+1}{%
-    \ifthenelse{\value{@col} > #4}%
-      {\addtocounter{@row}{1}%
-       \addtocounter{@col}{-#4}}%
-      {}%
+    \ifnum\value{@col} > #4\relax
+      \addtocounter{@row}{1}%
+      \addtocounter{@col}{-#4}%
+    \fi
     \def\arg at name{\csname#3[\the at row,\the at col]\endcsname}%
     \getArg at toks[\the at index]%
@@ -246,44 +239,163 @@
   \define at rootmacro{#3}%
-\newcommand\clear at array[1]{%
-  \expandafter\ifx\csname #1\endcsname\relax\else%
-    \setcounter{@row}{0}%
-    \whiledo{\value{@row}<\csname #1ROWS\endcsname}{%
-      \stepcounter{@row}%
+\newcommand\read at array[2][]{%
+  \bgroup%
+  \ifx\empty\read at array@sepchar
+    \setsepchar{\empty}%
+  \else
+    \expandafter\setsepchar\expandafter{\read at array@sepchar}%
+  \fi
+  \greadlist#1\Arg at list{#2}%
+  \egroup%
+  \edef\Arg at listCELLS{\Arg at listlen}%
+\def\clear at array#1{%
+  \ifcsname #1\endcsname%
+    \forloop{@row}{1}{\value{@row}<\numexpr\csname #1ROWS\endcsname+1}{%
       \ifnum\csname #1COLS\endcsname=0\relax%
-        \expandafter\let\csname #1[\the at row]\endcsname\relax%
+        \expandafter\let\csname #1[\the at row]\endcsname\undefined%
-        \setcounter{@col}{0}%
-        \whiledo{\value{@col}<\csname #1COLS\endcsname}{%
-          \stepcounter{@col}%
+        \forloop{@col}{1}{\value{@col}<\numexpr\csname #1COLS\endcsname+1}{%
           \ifnum\csname #1PLANES\endcsname=0\relax%
-            \expandafter\let\csname #1[\the at row,\the at col]\endcsname\relax%
+            \expandafter\let\csname #1[\the at row,\the at col]\endcsname
+              \undefined%
-            \setcounter{@plane}{0}%
-            \whiledo{\value{@plane}<\csname #1PLANES\endcsname}{%
-              \stepcounter{@plane}%
+            \forloop{@plane}{1}{\value{@plane}<\numexpr\csname #1PLANES\endcsname+1}{%
-                \let\csname #1[\the at plane,\the at row,\the at col]\endcsname\relax%
+                \let\csname #1[\the at plane,\the at row,\the at col]\endcsname
+                  \undefined%
+    \expandafter\let\csname #1PLANES\endcsname\undefined
+    \expandafter\let\csname #1ROWS\endcsname\undefined
+    \expandafter\let\csname #1PLANES\endcsname\undefined
+    \expandafter\let\csname #1\endcsname\undefined
-\newcommand\read at array[2][]{%
-  \bgroup%
-  \expandafter\setsepchar\expandafter{\read at array@sepchar}%
-  \greadlist#1\Arg at list{#2}%
-  \egroup%
-  \edef\Arg at listCELLS{\Arg at listlen}%
+  \ifcsname\rdar at macroname#1[#2]\endcsname
+    \expandafter\def\csname\rdar at macroname#1[#2]\endcsname{#3}%
+  \else
+    \typeout{readarray Warning (setvalue = #3): 
+      \readarraybackslash\rdar at macroname#1[#2] undefined.}%
+  \fi%
+\def\readarray at initializedata#1[#2]#3{%
+  \expandafter\def\csname
+    \rdar at macroname#1[#2]\expandafter\endcsname\expandafter{#3}%
+  \edef\@tmp{\rdar at macroname#1}%
+  \expandafter\clear at array\expandafter{\@tmp}%
+  \expandafter\define at rootmacro\expandafter{\@tmp}%
+  \setcounter{index at count}{0}%
+  \parse at index#2,\relax
+  \ifnum\value{index at count}=2\relax
+    \setcounter{use at args}{\numexpr\parsed at index[1]*\parsed at index[2]}
+    \expandafter\def\csname\@tmp PLANES\endcsname{0}
+    \expandafter\edef\csname\@tmp ROWS\endcsname{\parsed at index[1]}
+    \expandafter\edef\csname\@tmp COLS\endcsname{\parsed at index[2]}
+    \expandafter\edef\csname\@tmp CELLS\endcsname{\theuse at args}
+    \forloop{@row}{1}{\value{@row}<\numexpr\parsed at index[1]+1}{%
+      \forloop{@col}{1}{\value{@col}<\numexpr\parsed at index[2]+1}{%
+        \readarray at initializedata#1[\the at row,\the at col]{\readarrayinitvalue}}}
+  \else
+    \ifnum\value{index at count}=3\relax
+      \setcounter{use at args}{\numexpr\parsed at index[1]*
+        \parsed at index[2]*\parsed at index[3]}
+      \expandafter\edef\csname\@tmp PLANES\endcsname{\parsed at index[1]}
+      \expandafter\edef\csname\@tmp ROWS\endcsname{\parsed at index[2]}
+      \expandafter\edef\csname\@tmp COLS\endcsname{\parsed at index[3]}
+      \expandafter\edef\csname\@tmp CELLS\endcsname{\theuse at args}
+      \forloop{@plane}{1}{\value{@plane}<\numexpr\parsed at index[1]+1}{%
+        \forloop{@row}{1}{\value{@row}<\numexpr\parsed at index[2]+1}{%
+          \forloop{@col}{1}{\value{@col}<\numexpr\parsed at index[3]+1}{%
+            \readarray at initializedata#1[\the at plane,\the at row,\the at col]{%
+                                               \readarrayinitvalue}}}}
+    \else
+      [initarray ERROR: 2-D or 3-D arrays only]
+    \fi
+  \fi
+  \setcounter{index at count}{0}%
+  \parse at index#3,\relax
+  \ifnum\value{index at count}=2\relax 
+    \forloop{@row}{1}{\value{@row}<
+                  \numexpr\csname\rdar at macroname#1ROWS\endcsname+1}{%
+      \forloop{@col}{1}{\value{@col}<
+                  \numexpr\csname\rdar at macroname#1COLS\endcsname+1}{%
+        \edef\tmpA{\the\numexpr\the at row+\parsed at index[1]-1,%
+                  \the\numexpr\the at col+\parsed at index[2]-1}%
+        \edef\tmpB{\csname\rdar at macroname#1[\the at row,\the at col]\endcsname}%
+        \def\tmpC{\setvalue#2[\tmpA]}%
+        \expandafter\tmpC\expandafter{\tmpB}}}%
+  \else
+    \ifnum\value{index at count}=3\relax 
+      \forloop{@plane}{1}{\value{@plane}<
+                    \numexpr\csname\rdar at macroname#1PLANES\endcsname+1}{%
+        \forloop{@row}{1}{\value{@row}<
+                    \numexpr\csname\rdar at macroname#1ROWS\endcsname+1}{%
+          \forloop{@col}{1}{\value{@col}<
+                    \numexpr\csname\rdar at macroname#1COLS\endcsname+1}{%
+            \edef\tmpA{\the\numexpr\the at plane+\parsed at index[1]-1,%
+                       \the\numexpr\the at row+\parsed at index[2]-1,%
+                       \the\numexpr\the at col+\parsed at index[3]-1}%
+            \edef\tmpB{\csname\rdar at macroname#1%
+                         [\the at plane,\the at row,\the at 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 at toks#1{\Arg at toks\expandafter{\the\Arg at toks#1}}
+\def\xaddtoArg at toks#1{\expandafter\addtoArg at toks\expandafter{#1}}
+\def\xxaddtoArg at toks#1{\expandafter\xaddtoArg at toks\expandafter{#1}}
+\def\typesetarray#1{\noindent\Arg at toks{}%
+  \ifnum\csname\rdar at macroname#1PLANES\endcsname>0\relax
+    \forloop{@plane}{1}{\value{@plane}<
+               \numexpr\csname\rdar at macroname#1PLANES\endcsname+1}{%
+      \ifnum\the at plane=1 \else\xaddtoArg at toks{\typesetplanesepchar}\fi%
+      \forloop{@row}{1}{\value{@row}<
+               \numexpr\csname\rdar at macroname#1ROWS\endcsname+1}{%
+        \ifnum\the at row=1 \else\xaddtoArg at toks{\typesetrowsepchar}\fi%
+        \forloop{@col}{1}{\value{@col}<
+               \numexpr\csname\rdar at macroname#1COLS\endcsname+1}{%
+          \ifnum\the at col=1 \else\xaddtoArg at toks{\typesetcolsepchar}\fi%
+          \xaddtoArg at toks{\expandafter\typesetcell\expandafter
+            {\csname\rdar at macroname#1[\the at plane,\the at row,\the at col]\endcsname}}}%
+      }%
+    }%
+  \else
+    \forloop{@row}{1}{\value{@row}<
+               \numexpr\csname\rdar at macroname#1ROWS\endcsname+1}{%
+      \ifnum\the at row=1 \else\xaddtoArg at toks{\typesetrowsepchar}\fi%
+      \forloop{@col}{1}{\value{@col}<
+               \numexpr\csname\rdar at macroname#1COLS\endcsname+1}{%
+        \ifnum\the at col=1 \else\xaddtoArg at toks{\typesetcolsepchar}\fi%
+        \xaddtoArg at toks{\expandafter\typesetcell\expandafter
+          {\csname\rdar at macroname#1[\the at row,\the at col]\endcsname}}%
+      }%
+    }%
+  \fi
+  \the\Arg at toks
 \def\define at rootmacro#1{%
-  \expandafter\def\csname#1\endcsname[##1]{%
-    \expandafter\rootmacro at aux\csname #1[##1]\endcsname{#1}{##1}}%
+  \expandafter\def\csname#1\endcsname[##1]{\rootmacro at aux{#1}{##1}}%
 \def\parse at index#1,#2\relax{%
@@ -291,21 +403,43 @@
   \expandafter\gdef\csname parsed at index[\theindex at count]\endcsname{#1}%
   \ifx\relax#2\relax\else\parse at index#2\relax\fi%
+\def\parsed at index[#1]{\csname parsed at index[#1]\endcsname}
 \readarraysepchar{ }
-\def\nonposmessage#1#2{Negative index [#2] impermissable for #1.}
-\def\recordmessage#1#2{RECORD=#2 exceeds bounds(=\csname#1CELLS\endcsname) for #1.}
-\def\planemessage#1#2{PLANE=#2 exceeds bounds(=\csname#1PLANES\endcsname) for #1.}
-\def\rowmessage#1#2{ROW=#2 exceeds bounds(=\csname#1ROWS\endcsname) for #1.}
-\def\colmessage#1#2{COL=#2 exceeds bounds(=\csname#1COLS\endcsname) for #1.}
-\def\the at showargs@rule{\kern.2pt\rule{.8ex}{1.6ex}\hspace{.2pt}}%
-\def\readarrayboundfailmsg{?}% DISPLAYED WHEN ARRAY CALL OUT OF BOUNDS
+\def\nonpos at message#1#2{Nonpositive index [#2] prohibited for \ra at nm#1.}
+\def\record at message#1#2{%
+  RECORD=#2 exceeds bounds(=\csname#1CELLS\endcsname) for \ra at nm#1.}
+\def\plane at message#1#2{%
+  PLANE=#2 exceeds bounds(=\csname#1PLANES\endcsname) for \ra at nm#1.}
+\def\row at message#1#2{%
+  ROW=#2 exceeds bounds(=\csname#1ROWS\endcsname) for \ra at nm#1.}
+\def\col at message#1#2{%
+  COL=#2 exceeds bounds(=\csname#1COLS\endcsname) for \ra at nm#1.}
+\def\readarrayboundfailmsg{?}% WHEN ARRAY CALL OUT OF BOUNDS, IF BOUNDS CHECKING ON
+\def\ra at nm#1.{\readarraybackslash#1.}
+\def\the at showargs@rule{\kern.2pt\rule{.8ex}{1.6ex}\hspace{.2pt}}%
 \def\row at spacer{\\}
 \def\row at msg{\the at showargs@rule\hfill{\scriptsize\scshape$<$\row at sign~\arabic{@row}$>$}}
@@ -315,10 +449,9 @@
 \def\close at out{}
-  \edef\@arrayident{\rdar at macroname#1}%
-  \expandafter\ifx\csname\@arrayident\endcsname\relax\else%
-    \edef\ra at TmpA{\csname\@arrayident PLANES\endcsname}%
-    \edef\ra at TmpB{\csname\@arrayident COLS\endcsname}%
+  \expandafter\ifx\csname\rdar at macroname#1\endcsname\relax\else%
+    \edef\ra at TmpA{\csname\rdar at macroname#1PLANES\endcsname}%
+    \edef\ra at TmpB{\csname\rdar at macroname#1COLS\endcsname}%
     \def\ra at rank{3-D}%
     \ifnum\ra at TmpA=0\relax\def\ra at TmpA{1}\def\plane at sign{\mbox{}}\def\ra at rank{2-D}%
       \else\def\plane at sign{{\scriptsize\scshape Plane \arabic{@plane}}}\fi%
@@ -325,22 +458,18 @@
     \ifnum\ra at TmpB=0\relax\def\ra at TmpB{1}\def\row at sign{Record}\def\ra at rank{1-D}%
       \else\def\row at sign{Row}\fi%
     \par\noindent\header at msg%
-    \setcounter{@plane}{0}%
-    \whiledo{\value{@plane}<\ra at TmpA}{%
-      \stepcounter{@plane}%
+    \forloop{@plane}{1}{\value{@plane}<\numexpr\ra at TmpA+1}{%
       \plane at msg%
-      \setcounter{@row}{0}%
-      \whiledo{\value{@row}<\csname\@arrayident ROWS\endcsname}{%
-        \ifnum\value{@row}=0\relax\else\row at spacer\fi%
-        \stepcounter{@row}%
-        \setcounter{@col}{0}%
-        \whiledo{\value{@col}<\ra at TmpB}{%
+      \forloop{@row}{1}{\value{@row}<
+              \numexpr\csname\rdar at macroname#1ROWS\endcsname+1}{%
+        \ifnum\value{@row}=1\relax\else\row at spacer\fi%
+        \forloop{@col}{1}{\value{@col}<
+              \numexpr\ra at TmpB+1}{%
           \the at showargs@rule%
-          \stepcounter{@col}%
-          \ifnum\csname\@arrayident COLS\endcsname=0\relax%
+          \ifnum\csname\rdar at macroname#1COLS\endcsname=0\relax%
             #1[\the at row]%
-            \ifnum\csname\@arrayident PLANES\endcsname=0\relax%
+            \ifnum\csname\rdar at macroname#1PLANES\endcsname=0\relax%
               #1[\the at row,\the at col]%
               #1[\the at plane,\the at row,\the at col]%
@@ -355,7 +484,7 @@
   \def\row at spacer{}%
   \def\row at msg{}%
-  \def\header at msg{{\bfseries\csname\@arrayident CELLS\endcsname\ ELEMENTS:}%
+  \def\header at msg{{\bfseries\csname\rdar at macroname####1CELLS\endcsname\ ELEMENTS:}%
   \def\last at row{}%
   \def\plane at msg{}%
@@ -362,6 +491,28 @@
   \def\close at out{\the at showargs@rule\\}%
@@ -422,6 +573,4 @@
       \Arg at list[\value{@index}]}%

More information about the tex-live-commits mailing list.