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
          http://tug.org/svn/texlive?view=revision&revision=60193
Author:   karl
Date:     2021-08-08 22:55:00 +0200 (Sun, 08 Aug 2021)
Log Message:
-----------
readarray (8aug21)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/latex/readarray/readarray.pdf
    trunk/Master/texmf-dist/doc/latex/readarray/readarray.tex
    trunk/Master/texmf-dist/tex/latex/readarray/readarray.sty

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 @@
 \documentclass{article}
-%% 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).
+
 \usepackage{tabstackengine}[2016-10-04]
 \usepackage{lmodern}
 \usepackage[T1]{fontenc}
@@ -32,8 +11,7 @@
 \def\cmd#1{\texttt{\string\ \unskip#1}}
 \usepackage{readarray}
 \usepackage{verbatimbox}
-\usepackage{filecontents}
-\begin{filecontents*}{file1data.txt}
+\begin{filecontents*}[overwrite]{file1data.txt}
 A111 A112 A113 A114
 A121 A122 A123 A124
 A131 A132 A133 A134
@@ -42,7 +20,7 @@
 A221 A222 A223 A224
 A231 A232 A233 A234
 \end{filecontents*}
-\begin{filecontents*}{file2data.txt}
+\begin{filecontents*}[overwrite]{file2data.txt}
 \def{\dataA}{%
 A111 A112 A113 A114
 A121 A122 A123 A124
@@ -53,7 +31,7 @@
 A231 A232 A233 A234
 }
 \end{filecontents*}
-\begin{filecontents*}{file3data.txt}
+\begin{filecontents*}[overwrite]{file3data.txt}
 \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\\
 \rule{0em}{1.7em}\readarrayPackageDate\\
 V\readarrayPackageVersion
 \end{center}
 
-\section*{Comments About Version 2.0}
+\subsection*{Comments About Version 3.0}
 
-Version 2.0 of the \rdar{} package has brought major changes,
+\vspace{-5pt}
+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}
+
+\vspace{-5pt}
+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.
 }
 
-\clearpage
 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:}\\
 \rl\vb|\readdef{|filename\vb|}\|data-macro\\
 \textup{To place file data into a 1-D file-record array:}\\
-\rl\vb|\readrecordarray{|filename\vb|}\|array-identifier\\
-\textup{To parse a data macro and place the results into a 2-D or 3-D array:}\\
+\rl\vb|\readrecordarray{|filename\vb|}\|array-identifier%
+ \hfill\textup{(1-D)}\\
+\textup{To parse a data macro and place the results into a new 2-D or 3-D array:}\\
 \rl\vb|\readarray\|data-macro\vb|\|array-identifier\vb|[-,|columns\vb|]|%
   \hfill\textup{(2-D)}\\
 \rl\vb|\readarray\|data-macro\vb|\|array-identifier\vb|[-,|rows\vb|,|columns\vb|]|%
@@ -138,18 +132,50 @@
   \hfill\textup{(2-D)}\\
 \rl\vb|\readarray*\|data-macro\vb|\|array-identifier\vb|[-,|rows\vb|,|columns\vb|]|%
   \hfill\textup{(3-D)}\\
-\textup{Recall data from indexed array cell:}\\
+\textup{To create a new array, each cell initialized to a default 
+  value:}\\
+\rl\vb|\initarray\|array-identifier\vb|[|rows\vb|,|columns\vb|]|%
+  \hfill\textup{(2-D)}\\
+\rl\vb|\initarray\|array-identifier\vb|[|planes\vb|,|rows\vb|,|columns%
+  \vb|]|\hfill\textup{(3-D)}\\
+\textup{To merge each cell of one array into another:}\\
+\rl\vb|\mergearray\|from-array-id\vb|\|to-array-id\vb|[|row\vb|,|%
+  column\vb|]|\hfill\textup{(2-D)}\\
+\rl\vb|\mergearray\|from-array-id\vb|\|to-array-id\vb|[|plane\vb|,|%
+  row\vb|,|column\vb|]|\hfill\textup{(3-D)}\\
+\textup{To typeset an array:}\\
+\rl\vb|\typesetarray\|array-identifier\hfill\textup{(2-D/3-D)}\\
+\textup{Recall (typeset) data from indexed array cell:}\\
 \rl\vb|\|array-identifier\vb|[|row\vb|,|column\vb|]|%
   \hfill\textup{(2-D)}\\
 \rl\vb|\|array-identifier\vb|[|plane\vb|,|row\vb|,|column\vb|]|%
   \hfill\textup{(3-D)}\\
 \textup{To place the actual tokens of an array cell into a macro:}\\
-\rl\vb|\arraytomacro\|array-identifier\vb|[-,|columns\vb|]\|macro%
+\rl\vb|\arraytomacro\|array-identifier\vb|[|row\vb|,|column\vb|]\|macro%
   \hfill\textup{(2-D)}\\
-\rl\vb|\arraytomacro\|array-identifier\vb|[-,|rows\vb|,|columns\vb|]\|macro%
-  \hfill\textup{(3-D)}\\
-\textup{To change the array-parsing separator character:}\\
+\rl\vb|\arraytomacro\|array-identifier\vb|[|plane\vb|,|row\vb|,|column%
+  \vb|]\|macro\hfill\textup{(3-D)}\\
+\textup{To manually (re)set the value of an existing array cell:}\\
+\rl\vb|\setvalue\|array-identifier\vb|[|row\vb|,|column\vb|]{|%
+  value\vb|}|\hfill\textup{(2-D)}\\
+\rl\vb|\setvalue\|array-identifier\vb|[|plane\vb|,|row\vb|,|column\vb|]{|%
+  value\vb|}|\hfill\textup{(3-D)}\\
+\textup{To change the array-parsing separator for}
+  \vb|\readdef| \textup{and/or} \vb|\readarray|\textup{:}\\
 \rl\vb|\readarraysepchar{|parsing-separator-char\vb|}|\\
+\textup{To change the default (=9) end-of-line catcode for}
+  \vb|\readdef|\textup{:}\\
+\rl\vb|\readarrayendlinechar=|end-of-line-catcode\\
+\textup{To redefine default cell initialization for} \vb|\initarray|
+  \textup{:}\\
+\rl\vb|\renewcommand\readarrayinitvalue{|value\vb|}|\\
+\textup{To redefine default cell format in} \vb|\typesetarray|\textup{:}\\
+\rl\vb|\renewcommand\typesetcell[1]{|format-for-\#1\vb|}|\\
+\textup{To redefine default plane, row, column separator formats for}
+  \vb|\typesetarray|\textup{:}\\
+\rl\vb|\renewcommand\typesetplanesepchar{|format\vb|}|\\
+\rl\vb|\renewcommand\typesetrowsepchar{|format\vb|}|\\
+\rl\vb|\renewcommand\typesetcolsepchar{|format\vb|}|\\
 \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 @@
 \vb|\hypercheckbounds|
 \upshape 
 
-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
 
 \itshape
 \rl\vb|\|array-identifier\vb|CELLS|\\
@@ -205,24 +231,11 @@
 \rl\vb|\|array-identifier\vb|ROWS|\\
 \rl\vb|\|array-identifier\vb|COLS|\upshape
 
-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:
 
-\itshape
-
-\rl\vb|\arraydump\|array-identifier\\%
-\rl\vb|\scalardump\|array-identifier%
-\upshape
-
-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 @@
   reutilization.
 
 
-\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
   space.
 
-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}
 
 \begin{sloppypar}
@@ -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 @@
 \readdef{file3data.txt}\dataC
 \readarray*\dataC\tobeConjugation[-,\nrows,\ncols]
 
-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 @@
   \tobeConjugationCELLS.
   respectively.
 
+\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}
+
 \begin{sloppypar}
 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:
+
+\initarray\Q[2,2,2]
+\setvalue\Q[1,1,1]{(1,1,1)}
+\setvalue\Q[1,2,1]{(1,2,1)}
+\setvalue\Q[1,1,2]{(1,1,2)}
+\setvalue\Q[1,2,2]{(1,2,2)}
+\setvalue\Q[2,1,1]{(2,1,1)}
+\setvalue\Q[2,2,1]{(2,2,1)}
+\setvalue\Q[2,1,2]{(2,1,2)}
+\setvalue\Q[2,2,2]{(2,2,2)}
+\typesetarray\Q
+
+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
+\begin{verbatim}
+\renewcommand\typesetplanesepchar{\\\hline}
+\renewcommand\typesetrowsepchar{\\}
+\renewcommand\typesetcolsepchar{&}
+\renewcommand\typesetcell[1]{\scriptsize\textbf{#1}}
+\end{verbatim}
+one may insert the \vb|\typesetarray| inside a \vb|\tabular|
+  and it will format according to those rules:
+\begin{verbatim}
+\begin{tabular}{cc}
+\hline
+\typesetarray\Q\\
+\hline
+\end{tabular}
+\end{verbatim}
+yielding the following output:
+\renewcommand\typesetplanesepchar{\\\hline}
+\renewcommand\typesetrowsepchar{\\}
+\renewcommand\typesetcolsepchar{&}
+\renewcommand\typesetcell[1]{\scriptsize\textbf{#1}}
+\begin{tabular}{cc}
+\hline
+\typesetarray\Q\\
+\hline
+\end{tabular}
+.
+
+%@@@
+
 \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
 \arraytomacro\tobeConjugation[2,2,3]\thiscell
 ``\texttt{\detokenize\expandafter{\thiscell}}''.
 
-\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
+\textbf{Deprecated}
 
-\rl\vb|\arraydump\oneD|\\
-\rl\vb|\scalardump\oneD|
+The following commands are supplied, but are no longer the preferred
+embodiment of package syntax.
 
-results in
+\rl\vb|\arraydump|\\
+\rl\vb|\scalardump|
 
-\arraydump\oneD
-\scalardump\oneD
+To replace the function of these, \vb|\typesetarray| is
+  the preferred embodiment.
 
-\clearpage
+\textbf{Defunct}
 
-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.
 
-\rl\vb|\arraydump\twoD|\\
-\rl\vb|\scalardump\twoD|
-
-\arraydump\twoD
-\scalardump\twoD
-
-For the case of the 3-D array (earlier read as \cmd{threeD}), 
-the \cmd{arraydump} would appear as
-
-\rl\vb|\arraydump\threeD|\\
-\rl\vb|\scalardump\threeD|
-
-\arraydump\threeD
-\scalardump\threeD
-
-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.
-
-\clearpage
-For comparison, the \cmd{arraydump} of \cmd{tobeConjugation} is
-
-\arraydump\tobeConjugation
-
-
-\section{Deprecated, Vestigial, and Defunct Features}
-
-\textbf{Deprecated}
-
-The following commands are supplied, but are no longer the preferred
-embodiment of package syntax.
-
 \itshape
 \rl\vb|\copyrecords{|array-identifier\vb|}|%
 \\
@@ -733,44 +919,16 @@
 \rl\vb|\arrayij{|array-identifier\vb|}{|row\vb|}{|column\vb|}|\\
 \rl\vb|\arrayijk{|array-identifier\vb|}{|plane\vb|}{|row\vb|}{|%
      column\vb|}|\upshape
-
-\textbf{Vestigial}
-
-The following support macros are provided but no longer recommended.  
-Their capability is more fully served by way of the \loi{} package.
-
 \itshape
 \rl\vb|\getargsC{\|macro {\upshape or} string\vb|}|\\
 \rl\vb|\arg|index\\
 \rl\vb|\narg|\\
 \rl\vb|\showargs|%
-\upshape
-
-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}.
-
-\textbf{Defunct}
-
-The following macros are no longer supported.
-
-\itshape
 \rl\vb|\converttilde|\\
 \rl\vb|\record|index
 \upshape
 
-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. 
 
-
 \section{Acknowledgements}
 
 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 @@
-\def\readarrayPackageVersion{2.0}
-\def\readarrayPackageDate{2016/11/07}
+\def\readarrayPackageVersion{3.0}
+\def\readarrayPackageDate{2021/08/08}
 \ProvidesPackage{readarray}
 [\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.
-\RequirePackage{ifthen}
+% v3.0  (2021-08-05)
+%       -Added features: \setvalue, \initarray, \mergearray, \typesetarray
+%       -Allowed for \readarrayendlinechar to be set other than 9
+\RequirePackage{forloop}
 \RequirePackage{listofitems}[2016-10-22]
 %
 \newcounter{@index}
@@ -42,13 +45,12 @@
 \newcounter{@col}
 \newcounter{use at args}
 \newcounter{@record}
-\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
+\newcount\readarrayendlinechar
+\edef\readarraybackslash{\expandafter\@firstoftwo\string\\}
 %
 \newcommand\readdef[2]{\@readdef{#1}{#2}{ArrayRecord}}
 %
@@ -59,62 +61,58 @@
   \expandafter\ra at TermB\expandafter{\@arrayident}%
 }
 %
-\newcommand\readarray{\@ifstar{\read at array@newsyntax[*]}{\read at array@newsyntax[]}}
+\newcommand\readarray{\@ifstar
+    {\read at array@newsyntax[*]}{\read at array@newsyntax[]}}
 %
 \def\arraytomacro#1[#2]#3{%
-  \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.}%
   \fi%
  }\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%
   \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]}}
 %
-\newcommand\@readdef[3]{%
+\def\@readdef#1#2#3{%
   \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 %
   \def#2{}%
   \setcounter{@record}{0}%
   \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%
     \addtocounter{@record}{1}%
     \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}%
     \else%
       \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
           \addtocounter{@row}{1}%
-        }%
+        \fi
       \fi%
     \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%
   \else
   \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%
   \fi\fi
 }
@@ -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
     \addtocounter{@plane}{-1}%
     \setcounter{use at 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 at args}}%
-  \setcounter{@index}{0}%
   \setcounter{@plane}{1}%
   \setcounter{@row}{1}%
   \setcounter{@col}{0}%
-  \whiledo{\value{@index} < \value{use at args}}{%
-    \addtocounter{@index}{1}%
+  \forloop{@index}{1}{\value{@index} < \numexpr\value{use at args}+1}{%
     \addtocounter{@col}{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]%
     \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter%
@@ -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
     \addtocounter{@row}{-1}%
     \setcounter{use at 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 at args}}%
-  \setcounter{@index}{0}%
   \setcounter{@row}{1}%
   \setcounter{@col}{0}%
-  \whiledo{\value{@index} < \value{use at args}}{%
-    \addtocounter{@index}{1}%
+  \forloop{@index}{1}{\value{@index} < \numexpr\value{use at args}+1}{%
     \addtocounter{@col}{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]%
     \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter%
@@ -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%
       \else
-        \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%
           \else
-            \setcounter{@plane}{0}%
-            \whiledo{\value{@plane}<\csname #1PLANES\endcsname}{%
-              \stepcounter{@plane}%
+            \forloop{@plane}{1}{\value{@plane}<\numexpr\csname #1PLANES\endcsname+1}{%
               \expandafter%
-                \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%
             }%
           \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%
 }
 %
-\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}%
+\def\setvalue#1[#2]#3{%
+  \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}%
+}
+%
+\def\initarray#1[#2]{%
+  \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
+}
+%
+\def\mergearray#1#2[#3]{%
+  \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}
+%
 % INITIALIZATION
+% ON \readdef, SEP CHAR INSERTED AFTER EACH RECORD; 
+% ON \readarray, SEP CHAR SERVES AS DATA-FIELD SEPARATOR
 \readarraysepchar{ }
-\nocheckbounds
+% 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}
 %
-\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.}
+\nocheckbounds% DEFAULT IS NO BOUNDS CHECKING
 %
-\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.}
 %
-% SUPPORT/DEBUG ROUTINES
+\def\readarrayboundfailmsg{?}% WHEN ARRAY CALL OUT OF BOUNDS, IF BOUNDS CHECKING ON
+\def\ra at nm#1.{\readarraybackslash#1.}
 %
+% SUPPORT/DEBUG ROUTINES 
+% (THESE ARE DEPRECATED...CONSIDER USING \typesetarray AS AN ALTERNATIVE)
+%
+\def\the at showargs@rule{\kern.2pt\rule{.8ex}{1.6ex}\hspace{.2pt}}%
 % \arraydump INITIALIZATIONS
 \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{}
 %
 \newcommand\arraydump[1]{%
-  \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]%
           \else%
-            \ifnum\csname\@arrayident PLANES\endcsname=0\relax%
+            \ifnum\csname\rdar at macroname#1PLANES\endcsname=0\relax%
               #1[\the at row,\the at col]%
             \else%
               #1[\the at plane,\the at row,\the at col]%
@@ -355,7 +484,7 @@
 \newcommand\scalardump[1]{\bgroup%
   \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:}%
     ~\hrulefill\mbox{}\\}%
   \def\last at row{}%
   \def\plane at msg{}%
@@ -362,6 +491,28 @@
   \def\close at out{\the at showargs@rule\\}%
   \arraydump#1\egroup%
 }
+
+\endinput
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+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)
 %
@@ -422,6 +573,4 @@
       \Arg at list[\value{@index}]}%
   }%
 }
-\endinput
 
-



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