diff options
author | Karl Berry <karl@freefriends.org> | 2021-08-08 20:55:00 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2021-08-08 20:55:00 +0000 |
commit | a17b01b849389432a2351e5fa26f64a77b87550a (patch) | |
tree | 75af68e059b7418a0e238c4eb8c793cee929a633 | |
parent | 6d5d3e00a60dafef17b4283f3146b4cdfa0b1e88 (diff) |
readarray (8aug21)
git-svn-id: svn://tug.org/texlive/trunk@60193 c570f23f-e606-0410-a88d-b1316a301751
-rw-r--r-- | Master/texmf-dist/doc/latex/readarray/readarray.pdf | bin | 500598 -> 528752 bytes | |||
-rw-r--r-- | Master/texmf-dist/doc/latex/readarray/readarray.tex | 476 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/readarray/readarray.sty | 415 |
3 files changed, 599 insertions, 292 deletions
diff --git a/Master/texmf-dist/doc/latex/readarray/readarray.pdf b/Master/texmf-dist/doc/latex/readarray/readarray.pdf Binary files differindex d5dec32e1c7..5b8f2b4dbda 100644 --- a/Master/texmf-dist/doc/latex/readarray/readarray.pdf +++ b/Master/texmf-dist/doc/latex/readarray/readarray.pdf diff --git a/Master/texmf-dist/doc/latex/readarray/readarray.tex b/Master/texmf-dist/doc/latex/readarray/readarray.tex index 8376958419f..bd9a4aa114b 100644 --- a/Master/texmf-dist/doc/latex/readarray/readarray.tex +++ b/Master/texmf-dist/doc/latex/readarray/readarray.tex @@ -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 @@ A211 A212 A213 A214 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 @@ A221 A222 A223 A224 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 @@ will \textit{be}, will \textit{be}, will have \textit{been}, will have \textit{b \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@mail.mil\\ +SSegletes@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 @@ Note: for 1-D arrays that are to be simply parsed on the basis of a 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 @@ commands are: \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,28 +132,60 @@ commands are: \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% \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 @@ Individual records of the original file, from the most recent 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,23 +231,10 @@ In addition to the strings of fixed name created during the \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} @@ -229,7 +242,7 @@ The first requirement is to lay out a format for the data interface to 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 @@ However, two things have been accomplished: 1) the file contents are \cmd{def}'e 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 @@ If an array name is reutilized, its prior definitions are cleared, 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 @@ There is a starred version of the command, \cmd{readarray*}, which is used 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 @@ Data from the 2nd plane, 1st row, 2nd column can be obtained via 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 @@ The sequence of commands \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,8 +643,69 @@ The 3-D array metrics are \cmd{tobeConjugationPLANES}, \tobeConjugationCELLS. respectively. - -\section{Recalling Data from Array Structures} +\section{Initializing an Array Structure} + +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 @@ -597,6 +756,74 @@ is given by 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 @@ Results may be also expanded even with \cmd{checkbounds} 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,68 +879,27 @@ The command takes the array name and index as the initial arguments followed 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. - -For the case of 1-D record array \cmd{oneD} employed in prior sections, for - example, the invocations of -\rl\vb|\arraydump\oneD|\\ -\rl\vb|\scalardump\oneD| +\section{Deprecated and Defunct Features} -results in - -\arraydump\oneD -\scalardump\oneD - -\clearpage - -The \cmd{twoD} equivalent, resulting from parsing the same data file as - a 2-D, rather than a 1-D record array, is - -\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 +\textbf{Deprecated} -\arraydump\tobeConjugation +The following commands are supplied, but are no longer the preferred +embodiment of package syntax. +\rl\vb|\arraydump|\\ +\rl\vb|\scalardump| -\section{Deprecated, Vestigial, and Defunct Features} +To replace the function of these, \vb|\typesetarray| is + the preferred embodiment. -\textbf{Deprecated} +\textbf{Defunct} -The following commands are supplied, but are no longer the preferred -embodiment of package syntax. +The following macros are no longer supported. \itshape \rl\vb|\copyrecords{|array-identifier\vb|}|% @@ -733,43 +919,15 @@ embodiment of package syntax. \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} diff --git a/Master/texmf-dist/tex/latex/readarray/readarray.sty b/Master/texmf-dist/tex/latex/readarray/readarray.sty index 562fca33237..fb6c2ba90d5 100644 --- a/Master/texmf-dist/tex/latex/readarray/readarray.sty +++ b/Master/texmf-dist/tex/latex/readarray/readarray.sty @@ -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 @@ element-by-element basis.] % -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 @@ element-by-element basis.] \newcounter{@col} \newcounter{use@args} \newcounter{@record} -\newcounter{arg@index} -\newcounter{break@count} \newcounter{index@count} -\newcounter{loop@count} \newtoks\Arg@toks \newtoks\@arrayident@toks \newread\rdar@file +\newcount\readarrayendlinechar +\edef\readarraybackslash{\expandafter\@firstoftwo\string\\} % \newcommand\readdef[2]{\@readdef{#1}{#2}{ArrayRecord}} % @@ -59,61 +61,57 @@ element-by-element basis.] \expandafter\ra@TermB\expandafter{\@arrayident}% } % -\newcommand\readarray{\@ifstar{\read@array@newsyntax[*]}{\read@array@newsyntax[]}} +\newcommand\readarray{\@ifstar + {\read@array@newsyntax[*]}{\read@array@newsyntax[]}} % \def\arraytomacro#1[#2]#3{% - \edef\@arrayident{\rdar@macroname#1[#2]}% - \@arrayident@toks=\expandafter\expandafter\expandafter{\csname\@arrayident\endcsname}% + \@arrayident@toks=\expandafter\expandafter\expandafter + {\csname\rdar@macroname#1[#2]\endcsname}% \expandafter\def\expandafter#3\expandafter{\the\@arrayident@toks}% } % \newcommand\readarraysepchar[1]{\def\read@array@sepchar{#1}} % -\def\nocheckbounds{\def\rootmacro@aux##1##2##3{##1% +\def\nocheckbounds{\def\rootmacro@aux##1##2{\csname##1[##2]\endcsname% }\typeout{readarray: bounds checking OFF}% } % -\def\checkbounds{\def\rootmacro@aux##1##2##3{##1% - \expandafter\ifx##1\relax\readarrayboundfailmsg% - \setbox0=\hbox{\typeout{readarray Warning: ##1 out of bounds.}}% +\def\checkbounds{\def\rootmacro@aux##1##2{% + \ifcsname##1[##2]\endcsname\csname##1[##2]\endcsname\else% + \readarrayboundfailmsg% + \typeout{readarray Warning: \readarraybackslash##1[##2] undefined.}% \fi% }\typeout{readarray: bounds checking ON}% } % -\def\hypercheckbounds{\def\rootmacro@aux##1##2##3{##1% - \expandafter\ifx##1\relax\readarrayboundfailmsg% - \typeout{readarray Warning: ##1 out of bounds:}% - \fi% - \setcounter{index@count}{0}% - \parse@index##3,\relax% - \setcounter{loop@count}{0}% - \whiledo{\value{loop@count}<\value{index@count}}{% - \stepcounter{loop@count}% - \ifnum\csname parsed@index[\theloop@count]\endcsname<0% - \relax\typeout{\nonposmessage{##2}{##3}}\fi% - }% - \ifnum \value{index@count}=1\relax% - \ifnum\csname parsed@index[1]\endcsname>% - \csname##2CELLS\endcsname\relax\typeout{\recordmessage{##2}{##3}}\fi% - \fi - \ifnum \value{index@count}=2\relax% - \ifnum\csname parsed@index[1]\endcsname>% - \csname##2ROWS\endcsname\relax\typeout{\rowmessage{##2}{% - \csname parsed@index[1]\endcsname}}\fi% - \ifnum\csname parsed@index[2]\endcsname>% - \csname##2COLS\endcsname\relax\typeout{\colmessage{##2}{% - \csname parsed@index[2]\endcsname}}\fi% - \fi - \ifnum \value{index@count}=3\relax% - \ifnum\csname parsed@index[1]\endcsname>% - \csname##2PLANES\endcsname\relax\typeout{\planemessage{##2}{% - \csname parsed@index[1]\endcsname}}\fi% - \ifnum\csname parsed@index[2]\endcsname>% - \csname##2ROWS\endcsname\relax\typeout{\rowmessage{##2}{% - \csname parsed@index[2]\endcsname}}\fi% - \ifnum\csname parsed@index[2]\endcsname>% - \csname##2COLS\endcsname\relax\typeout{\colmessage{##2}{% - \csname parsed@index[3]\endcsname}}\fi% +\def\hypercheckbounds{\def\rootmacro@aux##1##2{% + \ifcsname##1[##2]\endcsname\csname##1[##2]\endcsname\else + \readarrayboundfailmsg% + \typeout{readarray Warning: \readarraybackslash##1[##2] undefined:}% + \setcounter{index@count}{0}% + \parse@index##2,\relax% + \forloop{@index}{1}{\value{@index}<\numexpr\theindex@count+1}{% + \ifnum\parsed@index[\the@index]<1% + \relax\typeout{ \nonpos@message{##1}{##2}}\fi% + }% + \ifnum \value{index@count}=1\relax% + \ifnum\parsed@index[1]>\csname##1CELLS\endcsname\relax + \typeout{ \record@message{##1}{##2}}\fi% + \fi + \ifnum \value{index@count}=2\relax% + \ifnum\parsed@index[1]>\csname##1ROWS\endcsname\relax + \typeout{ \row@message{##1}{\parsed@index[1]}}\fi% + \ifnum\parsed@index[2]>\csname##1COLS\endcsname\relax + \typeout{ \col@message{##1}{\parsed@index[2]}}\fi% + \fi + \ifnum \value{index@count}=3\relax% + \ifnum\parsed@index[1]>\csname##1PLANES\endcsname\relax + \typeout{ \plane@message{##1}{\parsed@index[1]}}\fi% + \ifnum\parsed@index[2]>\csname##1ROWS\endcsname\relax + \typeout{ \row@message{##1}{\parsed@index[2]}}\fi% + \ifnum\parsed@index[3]>\csname##1COLS\endcsname\relax + \typeout{ \col@message{##1}{\parsed@index[3]}}\fi% + \fi% \fi% }\typeout{readarray: bounds hyperchecking ON}% } @@ -122,30 +120,30 @@ element-by-element basis.] % \def\getArg@toks[#1]{\Arg@toks\expandafter\expandafter\expandafter{\Arg@list[#1]}} % -\newcommand\@readdef[3]{% +\def\@readdef#1#2#3{% \clear@array{#3}% \edef\former@recordcount{\csname #3CELLS\endcsname}% \def\first@row{T}% \def\first@plane{T}% - \catcode\endlinechar=9 % + \catcode\endlinechar=\readarrayendlinechar\relax % \def#2{}% \setcounter{@record}{0}% \openin\rdar@file=#1% \loop\unless\ifeof\rdar@file% - \read\rdar@file to\rdar@fileline % Reads a line of the file into \rdar@fileline% + \read\rdar@file to\rdar@fileline % Reads file line into \rdar@fileline% \addtocounter{@record}{1}% \expandafter\g@addto@macro\expandafter#2\expandafter{\rdar@fileline}% - \ifthenelse{\equal{\rdar@fileline}{}}{}{\expandafter\g@addto@macro% - \expandafter#2\expandafter{\read@array@sepchar}}% + \ifx\rdar@fileline\empty\else\expandafter\g@addto@macro% + \expandafter#2\expandafter{\read@array@sepchar}\fi% \if T\first@row\read@array{#2}\setcounter{@col}{\numexpr(\Arg@listlen-1)}% \edef\ncols{\arabic{@col}}\def\first@row{F}\setcounter{@row}{1}% \else% \if T\first@plane% - \ifthenelse{\equal{\rdar@fileline}{}}{% + \ifx\rdar@fileline\empty \edef\nrows{\arabic{@row}}\def\first@plane{F}% - }{% + \else \addtocounter{@row}{1}% - }% + \fi \fi% \fi% \def\record@name{\csname #3[\the@record]\endcsname}% @@ -163,18 +161,17 @@ element-by-element basis.] } % \def\read@array@newsyntax[#1]#2#3[#4,#5]{% - \edef\@arrayident{\rdar@macroname#3}% \setcounter{index@count}{0}% \parse@index#5,\relax% \ifnum\value{index@count}=1\relax% - \def\ra@TermA{\readArrayij#1{#2}}% - \edef\ra@TermB{{\@arrayident}{\csname parsed@index[1]\endcsname}}% + \def\ra@TermA{\read@Arrayij[#1]{#2}}% + \edef\ra@TermB{{\rdar@macroname#3}{\parsed@index[1]}}% \expandafter\ra@TermA\ra@TermB% \else \ifnum\value{index@count}=2\relax% - \def\ra@TermA{\readArrayijk#1{#2}}% - \edef\ra@TermB{{\@arrayident}{\csname parsed@index[1]\endcsname}% - {\csname parsed@index[2]\endcsname}}% + \def\ra@TermA{\read@Arrayijk[#1]{#2}}% + \edef\ra@TermB{{\rdar@macroname#3}{\parsed@index[1]}% + {\parsed@index[2]}}% \expandafter\ra@TermA\ra@TermB% \fi\fi } @@ -184,29 +181,27 @@ element-by-element basis.] \read@array[#1]{#2}% \setcounter{@plane}{\numexpr(\Arg@listlen/#5/#4)}% \setcounter{use@args}{\numexpr\arabic{@plane}*#4*#5}% - \ifthenelse{\arabic{use@args} > \Arg@listlen}{% + \ifnum\arabic{use@args} > \Arg@listlen\relax \addtocounter{@plane}{-1}% \setcounter{use@args}{\numexpr\arabic{@plane}*#4*#5}% - }{}% + \fi% \expandafter\edef\csname#3PLANES\endcsname{\arabic{@plane}}% \expandafter\edef\csname#3ROWS\endcsname{#4}% \expandafter\edef\csname#3COLS\endcsname{#5}% \expandafter\edef\csname#3CELLS\endcsname{\arabic{use@args}}% - \setcounter{@index}{0}% \setcounter{@plane}{1}% \setcounter{@row}{1}% \setcounter{@col}{0}% - \whiledo{\value{@index} < \value{use@args}}{% - \addtocounter{@index}{1}% + \forloop{@index}{1}{\value{@index} < \numexpr\value{use@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@name{\csname#3[\the@plane,\the@row,\the@col]\endcsname}% \getArg@toks[\the@index]% \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter% @@ -220,24 +215,22 @@ element-by-element basis.] \read@array[#1]{#2}% \setcounter{@row}{\numexpr(\Arg@listlen/#4)}% \setcounter{use@args}{\numexpr\arabic{@row}*#4}% - \ifthenelse{\arabic{use@args} > \Arg@listlen}{% + \ifnum\arabic{use@args} > \Arg@listlen\relax \addtocounter{@row}{-1}% \setcounter{use@args}{\numexpr\arabic{@row}*#4}% - }{}% + \fi \expandafter\edef\csname#3PLANES\endcsname{0}% \expandafter\edef\csname#3ROWS\endcsname{\arabic{@row}}% \expandafter\edef\csname#3COLS\endcsname{#4}% \expandafter\edef\csname#3CELLS\endcsname{\arabic{use@args}}% - \setcounter{@index}{0}% \setcounter{@row}{1}% \setcounter{@col}{0}% - \whiledo{\value{@index} < \value{use@args}}{% - \addtocounter{@index}{1}% + \forloop{@index}{1}{\value{@index} < \numexpr\value{use@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@name{\csname#3[\the@row,\the@col]\endcsname}% \getArg@toks[\the@index]% \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter% @@ -246,44 +239,163 @@ element-by-element basis.] \define@rootmacro{#3}% } % -\newcommand\clear@array[1]{% - \expandafter\ifx\csname #1\endcsname\relax\else% - \setcounter{@row}{0}% - \whiledo{\value{@row}<\csname #1ROWS\endcsname}{% - \stepcounter{@row}% +\newcommand\read@array[2][]{% + \bgroup% + \ifx\empty\read@array@sepchar + \setsepchar{\empty}% + \else + \expandafter\setsepchar\expandafter{\read@array@sepchar}% + \fi + \greadlist#1\Arg@list{#2}% + \egroup% + \edef\Arg@listCELLS{\Arg@listlen}% +} +% +\def\clear@array#1{% + \ifcsname #1\endcsname% + \forloop{@row}{1}{\value{@row}<\numexpr\csname #1ROWS\endcsname+1}{% \ifnum\csname #1COLS\endcsname=0\relax% - \expandafter\let\csname #1[\the@row]\endcsname\relax% + \expandafter\let\csname #1[\the@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@row,\the@col]\endcsname\relax% + \expandafter\let\csname #1[\the@row,\the@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@plane,\the@row,\the@col]\endcsname\relax% + \let\csname #1[\the@plane,\the@row,\the@col]\endcsname + \undefined% }% \fi% }% \fi% }% + \expandafter\let\csname #1PLANES\endcsname\undefined + \expandafter\let\csname #1ROWS\endcsname\undefined + \expandafter\let\csname #1PLANES\endcsname\undefined + \expandafter\let\csname #1\endcsname\undefined \fi% } % -\newcommand\read@array[2][]{% - \bgroup% - \expandafter\setsepchar\expandafter{\read@array@sepchar}% - \greadlist#1\Arg@list{#2}% - \egroup% - \edef\Arg@listCELLS{\Arg@listlen}% +\def\setvalue#1[#2]#3{% + \ifcsname\rdar@macroname#1[#2]\endcsname + \expandafter\def\csname\rdar@macroname#1[#2]\endcsname{#3}% + \else + \typeout{readarray Warning (setvalue = #3): + \readarraybackslash\rdar@macroname#1[#2] undefined.}% + \fi% +} +% +\def\readarray@initializedata#1[#2]#3{% + \expandafter\def\csname + \rdar@macroname#1[#2]\expandafter\endcsname\expandafter{#3}% +} +% +\def\initarray#1[#2]{% + \edef\@tmp{\rdar@macroname#1}% + \expandafter\clear@array\expandafter{\@tmp}% + \expandafter\define@rootmacro\expandafter{\@tmp}% + \setcounter{index@count}{0}% + \parse@index#2,\relax + \ifnum\value{index@count}=2\relax + \setcounter{use@args}{\numexpr\parsed@index[1]*\parsed@index[2]} + \expandafter\def\csname\@tmp PLANES\endcsname{0} + \expandafter\edef\csname\@tmp ROWS\endcsname{\parsed@index[1]} + \expandafter\edef\csname\@tmp COLS\endcsname{\parsed@index[2]} + \expandafter\edef\csname\@tmp CELLS\endcsname{\theuse@args} + \forloop{@row}{1}{\value{@row}<\numexpr\parsed@index[1]+1}{% + \forloop{@col}{1}{\value{@col}<\numexpr\parsed@index[2]+1}{% + \readarray@initializedata#1[\the@row,\the@col]{\readarrayinitvalue}}} + \else + \ifnum\value{index@count}=3\relax + \setcounter{use@args}{\numexpr\parsed@index[1]* + \parsed@index[2]*\parsed@index[3]} + \expandafter\edef\csname\@tmp PLANES\endcsname{\parsed@index[1]} + \expandafter\edef\csname\@tmp ROWS\endcsname{\parsed@index[2]} + \expandafter\edef\csname\@tmp COLS\endcsname{\parsed@index[3]} + \expandafter\edef\csname\@tmp CELLS\endcsname{\theuse@args} + \forloop{@plane}{1}{\value{@plane}<\numexpr\parsed@index[1]+1}{% + \forloop{@row}{1}{\value{@row}<\numexpr\parsed@index[2]+1}{% + \forloop{@col}{1}{\value{@col}<\numexpr\parsed@index[3]+1}{% + \readarray@initializedata#1[\the@plane,\the@row,\the@col]{% + \readarrayinitvalue}}}} + \else + [initarray ERROR: 2-D or 3-D arrays only] + \fi + \fi +} +% +\def\mergearray#1#2[#3]{% + \setcounter{index@count}{0}% + \parse@index#3,\relax + \ifnum\value{index@count}=2\relax + \forloop{@row}{1}{\value{@row}< + \numexpr\csname\rdar@macroname#1ROWS\endcsname+1}{% + \forloop{@col}{1}{\value{@col}< + \numexpr\csname\rdar@macroname#1COLS\endcsname+1}{% + \edef\tmpA{\the\numexpr\the@row+\parsed@index[1]-1,% + \the\numexpr\the@col+\parsed@index[2]-1}% + \edef\tmpB{\csname\rdar@macroname#1[\the@row,\the@col]\endcsname}% + \def\tmpC{\setvalue#2[\tmpA]}% + \expandafter\tmpC\expandafter{\tmpB}}}% + \else + \ifnum\value{index@count}=3\relax + \forloop{@plane}{1}{\value{@plane}< + \numexpr\csname\rdar@macroname#1PLANES\endcsname+1}{% + \forloop{@row}{1}{\value{@row}< + \numexpr\csname\rdar@macroname#1ROWS\endcsname+1}{% + \forloop{@col}{1}{\value{@col}< + \numexpr\csname\rdar@macroname#1COLS\endcsname+1}{% + \edef\tmpA{\the\numexpr\the@plane+\parsed@index[1]-1,% + \the\numexpr\the@row+\parsed@index[2]-1,% + \the\numexpr\the@col+\parsed@index[3]-1}% + \edef\tmpB{\csname\rdar@macroname#1% + [\the@plane,\the@row,\the@col]\endcsname}% + \def\tmpC{\setvalue#2[\tmpA]}% + \expandafter\tmpC\expandafter{\tmpB}}}}% + \else + [mergearray ERROR: 2-D or 3-D arrays only] + \fi + \fi +} +% +\def\addtoArg@toks#1{\Arg@toks\expandafter{\the\Arg@toks#1}} +\def\xaddtoArg@toks#1{\expandafter\addtoArg@toks\expandafter{#1}} +\def\xxaddtoArg@toks#1{\expandafter\xaddtoArg@toks\expandafter{#1}} +% +\def\typesetarray#1{\noindent\Arg@toks{}% + \ifnum\csname\rdar@macroname#1PLANES\endcsname>0\relax + \forloop{@plane}{1}{\value{@plane}< + \numexpr\csname\rdar@macroname#1PLANES\endcsname+1}{% + \ifnum\the@plane=1 \else\xaddtoArg@toks{\typesetplanesepchar}\fi% + \forloop{@row}{1}{\value{@row}< + \numexpr\csname\rdar@macroname#1ROWS\endcsname+1}{% + \ifnum\the@row=1 \else\xaddtoArg@toks{\typesetrowsepchar}\fi% + \forloop{@col}{1}{\value{@col}< + \numexpr\csname\rdar@macroname#1COLS\endcsname+1}{% + \ifnum\the@col=1 \else\xaddtoArg@toks{\typesetcolsepchar}\fi% + \xaddtoArg@toks{\expandafter\typesetcell\expandafter + {\csname\rdar@macroname#1[\the@plane,\the@row,\the@col]\endcsname}}}% + }% + }% + \else + \forloop{@row}{1}{\value{@row}< + \numexpr\csname\rdar@macroname#1ROWS\endcsname+1}{% + \ifnum\the@row=1 \else\xaddtoArg@toks{\typesetrowsepchar}\fi% + \forloop{@col}{1}{\value{@col}< + \numexpr\csname\rdar@macroname#1COLS\endcsname+1}{% + \ifnum\the@col=1 \else\xaddtoArg@toks{\typesetcolsepchar}\fi% + \xaddtoArg@toks{\expandafter\typesetcell\expandafter + {\csname\rdar@macroname#1[\the@row,\the@col]\endcsname}}% + }% + }% + \fi + \the\Arg@toks } % \def\define@rootmacro#1{% - \expandafter\def\csname#1\endcsname[##1]{% - \expandafter\rootmacro@aux\csname #1[##1]\endcsname{#1}{##1}}% + \expandafter\def\csname#1\endcsname[##1]{\rootmacro@aux{#1}{##1}}% } % \def\parse@index#1,#2\relax{% @@ -291,21 +403,43 @@ element-by-element basis.] \expandafter\gdef\csname parsed@index[\theindex@count]\endcsname{#1}% \ifx\relax#2\relax\else\parse@index#2\relax\fi% } +% +\def\parsed@index[#1]{\csname parsed@index[#1]\endcsname} +% % INITIALIZATION +% ON \readdef, SEP CHAR INSERTED AFTER EACH RECORD; +% ON \readarray, SEP CHAR SERVES AS DATA-FIELD SEPARATOR \readarraysepchar{ } -\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@showargs@rule{\kern.2pt\rule{.8ex}{1.6ex}\hspace{.2pt}}% -\def\readarrayboundfailmsg{?}% DISPLAYED WHEN ARRAY CALL OUT OF BOUNDS +\def\nonpos@message#1#2{Nonpositive index [#2] prohibited for \ra@nm#1.} +\def\record@message#1#2{% + RECORD=#2 exceeds bounds(=\csname#1CELLS\endcsname) for \ra@nm#1.} +\def\plane@message#1#2{% + PLANE=#2 exceeds bounds(=\csname#1PLANES\endcsname) for \ra@nm#1.} +\def\row@message#1#2{% + ROW=#2 exceeds bounds(=\csname#1ROWS\endcsname) for \ra@nm#1.} +\def\col@message#1#2{% + COL=#2 exceeds bounds(=\csname#1COLS\endcsname) for \ra@nm#1.} +% +\def\readarrayboundfailmsg{?}% WHEN ARRAY CALL OUT OF BOUNDS, IF BOUNDS CHECKING ON +\def\ra@nm#1.{\readarraybackslash#1.} % -% SUPPORT/DEBUG ROUTINES +% SUPPORT/DEBUG ROUTINES +% (THESE ARE DEPRECATED...CONSIDER USING \typesetarray AS AN ALTERNATIVE) % +\def\the@showargs@rule{\kern.2pt\rule{.8ex}{1.6ex}\hspace{.2pt}}% % \arraydump INITIALIZATIONS \def\row@spacer{\\} \def\row@msg{\the@showargs@rule\hfill{\scriptsize\scshape$<$\row@sign~\arabic{@row}$>$}} @@ -315,32 +449,27 @@ element-by-element basis.] \def\close@out{} % \newcommand\arraydump[1]{% - \edef\@arrayident{\rdar@macroname#1}% - \expandafter\ifx\csname\@arrayident\endcsname\relax\else% - \edef\ra@TmpA{\csname\@arrayident PLANES\endcsname}% - \edef\ra@TmpB{\csname\@arrayident COLS\endcsname}% + \expandafter\ifx\csname\rdar@macroname#1\endcsname\relax\else% + \edef\ra@TmpA{\csname\rdar@macroname#1PLANES\endcsname}% + \edef\ra@TmpB{\csname\rdar@macroname#1COLS\endcsname}% \def\ra@rank{3-D}% \ifnum\ra@TmpA=0\relax\def\ra@TmpA{1}\def\plane@sign{\mbox{}}\def\ra@rank{2-D}% \else\def\plane@sign{{\scriptsize\scshape Plane \arabic{@plane}}}\fi% \ifnum\ra@TmpB=0\relax\def\ra@TmpB{1}\def\row@sign{Record}\def\ra@rank{1-D}% \else\def\row@sign{Row}\fi% \par\noindent\header@msg% - \setcounter{@plane}{0}% - \whiledo{\value{@plane}<\ra@TmpA}{% - \stepcounter{@plane}% + \forloop{@plane}{1}{\value{@plane}<\numexpr\ra@TmpA+1}{% \plane@msg% - \setcounter{@row}{0}% - \whiledo{\value{@row}<\csname\@arrayident ROWS\endcsname}{% - \ifnum\value{@row}=0\relax\else\row@spacer\fi% - \stepcounter{@row}% - \setcounter{@col}{0}% - \whiledo{\value{@col}<\ra@TmpB}{% + \forloop{@row}{1}{\value{@row}< + \numexpr\csname\rdar@macroname#1ROWS\endcsname+1}{% + \ifnum\value{@row}=1\relax\else\row@spacer\fi% + \forloop{@col}{1}{\value{@col}< + \numexpr\ra@TmpB+1}{% \the@showargs@rule% - \stepcounter{@col}% - \ifnum\csname\@arrayident COLS\endcsname=0\relax% + \ifnum\csname\rdar@macroname#1COLS\endcsname=0\relax% #1[\the@row]% \else% - \ifnum\csname\@arrayident PLANES\endcsname=0\relax% + \ifnum\csname\rdar@macroname#1PLANES\endcsname=0\relax% #1[\the@row,\the@col]% \else% #1[\the@plane,\the@row,\the@col]% @@ -355,13 +484,35 @@ element-by-element basis.] \newcommand\scalardump[1]{\bgroup% \def\row@spacer{}% \def\row@msg{}% - \def\header@msg{{\bfseries\csname\@arrayident CELLS\endcsname\ ELEMENTS:}% + \def\header@msg{{\bfseries\csname\rdar@macroname####1CELLS\endcsname\ ELEMENTS:}% ~\hrulefill\mbox{}\\}% \def\last@row{}% \def\plane@msg{}% \def\close@out{\the@showargs@rule\\}% \arraydump#1\egroup% } + +\endinput + + + + + + + + + + + + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +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 @@ element-by-element basis.] \Arg@list[\value{@index}]}% }% } -\endinput - |