diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/readarray |
Initial commit
Diffstat (limited to 'macros/latex/contrib/readarray')
-rw-r--r-- | macros/latex/contrib/readarray/README | 28 | ||||
-rw-r--r-- | macros/latex/contrib/readarray/readarray.pdf | bin | 0 -> 500598 bytes | |||
-rw-r--r-- | macros/latex/contrib/readarray/readarray.sty | 427 | ||||
-rw-r--r-- | macros/latex/contrib/readarray/readarray.tex | 800 |
4 files changed, 1255 insertions, 0 deletions
diff --git a/macros/latex/contrib/readarray/README b/macros/latex/contrib/readarray/README new file mode 100644 index 0000000000..cff2c617f9 --- /dev/null +++ b/macros/latex/contrib/readarray/README @@ -0,0 +1,28 @@ +The readarray package allows one to input formatted data into elements +of a 2-D or 3-D array (or a 1-D file-record array). Subsequently, that +data may be recalled at will using an array-cell indexing nomenclature. +The data can be but need not be numerical in nature. It can be, for +example, formatted text. In this regard, the array stores the +unexpanded data from the file, if macros are present in the data. + +As of V2.0, the separator by which data is parsed may be customized by +the user. A totally new package syntax has also been introduced (the +prior syntax is retained as deprecated macros). Various levels of bound +checking are now available to the user. + +While the package can be used for any application where indexed data is +called for, the package proves particularly useful when elements of +multiple arrays must be recallable and dynamically combined at time of +compilation, rather than in advance. + +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. + +The Current Maintainer of this work is Steven B. Segletes. diff --git a/macros/latex/contrib/readarray/readarray.pdf b/macros/latex/contrib/readarray/readarray.pdf Binary files differnew file mode 100644 index 0000000000..d5dec32e1c --- /dev/null +++ b/macros/latex/contrib/readarray/readarray.pdf diff --git a/macros/latex/contrib/readarray/readarray.sty b/macros/latex/contrib/readarray/readarray.sty new file mode 100644 index 0000000000..562fca3323 --- /dev/null +++ b/macros/latex/contrib/readarray/readarray.sty @@ -0,0 +1,427 @@ +\def\readarrayPackageVersion{2.0} +\def\readarrayPackageDate{2016/11/07} +\ProvidesPackage{readarray} +[\readarrayPackageDate\ \readarrayPackageVersion\ % +Routines for inputting 2D and 3D array data and recalling it on an +element-by-element basis.] +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3c or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +% +% This work has the LPPL maintenance status `maintained'. +% +% The Current Maintainer of this work is Steven B. Segletes. +% +% 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). +% v2.0 -Converted parsing to listofitems package. This allows for +% ANY parsing character or combination of characters (via logical OR). +% -Replaced all \protected@edef's with appropriately expanded \def's. +% -Use listofitems package in preference to \getargsC. +% -Deprecated \Arrayijk, \arrayijk, \Arrayij, & \arrayij. Direct +% access now preferred, e.g., \xyz[2,3,1]. +% -Deprecated most other commands in favor of a more natural syntax. +\RequirePackage{ifthen} +\RequirePackage{listofitems}[2016-10-22] +% +\newcounter{@index} +\newcounter{@plane} +\newcounter{@row} +\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 +% +\newcommand\readdef[2]{\@readdef{#1}{#2}{ArrayRecord}} +% +\newcommand\readrecordarray[2]{% + \edef\@arrayident{\rdar@macroname#2}% + \def\ra@TermA{\@readdef{#1}}% + \def\ra@TermB{\expandafter\ra@TermA\csname\@arrayident def\endcsname}% + \expandafter\ra@TermB\expandafter{\@arrayident}% +} +% +\newcommand\readarray{\@ifstar{\read@array@newsyntax[*]}{\read@array@newsyntax[]}} +% +\def\arraytomacro#1[#2]#3{% + \edef\@arrayident{\rdar@macroname#1[#2]}% + \@arrayident@toks=\expandafter\expandafter\expandafter{\csname\@arrayident\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% + }\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.}}% + \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% + \fi% + }\typeout{readarray: bounds hyperchecking ON}% +} +% +\def\rdar@macroname{\expandafter\@gobble\string} +% +\def\getArg@toks[#1]{\Arg@toks\expandafter\expandafter\expandafter{\Arg@list[#1]}} +% +\newcommand\@readdef[3]{% + \clear@array{#3}% + \edef\former@recordcount{\csname #3CELLS\endcsname}% + \def\first@row{T}% + \def\first@plane{T}% + \catcode\endlinechar=9 % + \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% + \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}}% + \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}{}}{% + \edef\nrows{\arabic{@row}}\def\first@plane{F}% + }{% + \addtocounter{@row}{1}% + }% + \fi% + \fi% + \def\record@name{\csname #3[\the@record]\endcsname}% + \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter% + \expandafter\def\expandafter\record@name\expandafter{\rdar@fileline}% + \repeat% + \edef\nrecords{\arabic{@record}}% + \expandafter\edef\csname #3PLANES\endcsname{0}% + \expandafter\edef\csname #3ROWS\endcsname{\nrecords}% + \expandafter\edef\csname #3COLS\endcsname{0}% + \expandafter\edef\csname #3CELLS\endcsname{\nrecords}% + \closein\rdar@file% + \catcode\endlinechar=5 % + \define@rootmacro{#3}% +} +% +\def\read@array@newsyntax[#1]#2#3[#4,#5]{% + \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}}% + \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}}% + \expandafter\ra@TermA\ra@TermB% + \fi\fi +} +% +\newcommand\read@Arrayijk[5][]{% + \clear@array{#3}% + \read@array[#1]{#2}% + \setcounter{@plane}{\numexpr(\Arg@listlen/#5/#4)}% + \setcounter{use@args}{\numexpr\arabic{@plane}*#4*#5}% + \ifthenelse{\arabic{use@args} > \Arg@listlen}{% + \addtocounter{@plane}{-1}% + \setcounter{use@args}{\numexpr\arabic{@plane}*#4*#5}% + }{}% + \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}% + \addtocounter{@col}{1}% + \ifthenelse{\value{@col} > #5}% + {\addtocounter{@row}{1}% + \addtocounter{@col}{-#5}}% + {}% + \ifthenelse{\value{@row} > #4}% + {\addtocounter{@plane}{1}% + \addtocounter{@row}{-#4}}% + {}% + \def\arg@name{\csname#3[\the@plane,\the@row,\the@col]\endcsname}% + \getArg@toks[\the@index]% + \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter% + \expandafter\def\expandafter\arg@name\expandafter{\the\Arg@toks}% + }% + \define@rootmacro{#3}% +} +% +\newcommand\read@Arrayij[4][]{% + \clear@array{#3}% + \read@array[#1]{#2}% + \setcounter{@row}{\numexpr(\Arg@listlen/#4)}% + \setcounter{use@args}{\numexpr\arabic{@row}*#4}% + \ifthenelse{\arabic{use@args} > \Arg@listlen}{% + \addtocounter{@row}{-1}% + \setcounter{use@args}{\numexpr\arabic{@row}*#4}% + }{}% + \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}% + \addtocounter{@col}{1}% + \ifthenelse{\value{@col} > #4}% + {\addtocounter{@row}{1}% + \addtocounter{@col}{-#4}}% + {}% + \def\arg@name{\csname#3[\the@row,\the@col]\endcsname}% + \getArg@toks[\the@index]% + \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter% + \expandafter\def\expandafter\arg@name\expandafter{\the\Arg@toks}% + }% + \define@rootmacro{#3}% +} +% +\newcommand\clear@array[1]{% + \expandafter\ifx\csname #1\endcsname\relax\else% + \setcounter{@row}{0}% + \whiledo{\value{@row}<\csname #1ROWS\endcsname}{% + \stepcounter{@row}% + \ifnum\csname #1COLS\endcsname=0\relax% + \expandafter\let\csname #1[\the@row]\endcsname\relax% + \else + \setcounter{@col}{0}% + \whiledo{\value{@col}<\csname #1COLS\endcsname}{% + \stepcounter{@col}% + \ifnum\csname #1PLANES\endcsname=0\relax% + \expandafter\let\csname #1[\the@row,\the@col]\endcsname\relax% + \else + \setcounter{@plane}{0}% + \whiledo{\value{@plane}<\csname #1PLANES\endcsname}{% + \stepcounter{@plane}% + \expandafter% + \let\csname #1[\the@plane,\the@row,\the@col]\endcsname\relax% + }% + \fi% + }% + \fi% + }% + \fi% +} +% +\newcommand\read@array[2][]{% + \bgroup% + \expandafter\setsepchar\expandafter{\read@array@sepchar}% + \greadlist#1\Arg@list{#2}% + \egroup% + \edef\Arg@listCELLS{\Arg@listlen}% +} +% +\def\define@rootmacro#1{% + \expandafter\def\csname#1\endcsname[##1]{% + \expandafter\rootmacro@aux\csname #1[##1]\endcsname{#1}{##1}}% +} +% +\def\parse@index#1,#2\relax{% + \stepcounter{index@count}% + \expandafter\gdef\csname parsed@index[\theindex@count]\endcsname{#1}% + \ifx\relax#2\relax\else\parse@index#2\relax\fi% +} +% INITIALIZATION +\readarraysepchar{ } +\nocheckbounds +% +\def\nonposmessage#1#2{Negative index [#2] impermissable for #1.} +\def\recordmessage#1#2{RECORD=#2 exceeds bounds(=\csname#1CELLS\endcsname) for #1.} +\def\planemessage#1#2{PLANE=#2 exceeds bounds(=\csname#1PLANES\endcsname) for #1.} +\def\rowmessage#1#2{ROW=#2 exceeds bounds(=\csname#1ROWS\endcsname) for #1.} +\def\colmessage#1#2{COL=#2 exceeds bounds(=\csname#1COLS\endcsname) for #1.} +% +\def\the@showargs@rule{\kern.2pt\rule{.8ex}{1.6ex}\hspace{.2pt}}% +\def\readarrayboundfailmsg{?}% DISPLAYED WHEN ARRAY CALL OUT OF BOUNDS +% +% SUPPORT/DEBUG ROUTINES +% +% \arraydump INITIALIZATIONS +\def\row@spacer{\\} +\def\row@msg{\the@showargs@rule\hfill{\scriptsize\scshape$<$\row@sign~\arabic{@row}$>$}} +\def\header@msg{{\bfseries\ra@rank:}~} +\def\last@row{\\} +\def\plane@msg{\plane@sign\hrulefill\mbox{}\\} +\def\close@out{} +% +\newcommand\arraydump[1]{% + \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}% + \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}% + \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}{% + \the@showargs@rule% + \stepcounter{@col}% + \ifnum\csname\@arrayident COLS\endcsname=0\relax% + #1[\the@row]% + \else% + \ifnum\csname\@arrayident PLANES\endcsname=0\relax% + #1[\the@row,\the@col]% + \else% + #1[\the@plane,\the@row,\the@col]% + \fi% + \fi% + }\row@msg% + }\last@row% + }\close@out\mbox{}\hrulefill\mbox{}\par% + \fi% +} +% +\newcommand\scalardump[1]{\bgroup% + \def\row@spacer{}% + \def\row@msg{}% + \def\header@msg{{\bfseries\csname\@arrayident CELLS\endcsname\ ELEMENTS:}% + ~\hrulefill\mbox{}\\}% + \def\last@row{}% + \def\plane@msg{}% + \def\close@out{\the@showargs@rule\\}% + \arraydump#1\egroup% +} +% +% DEPRECATED COMMANDS (NOT PREFERRED EMBODIMENT OF PACKAGE SYNTAX) +% +\newcommand\readArrayijk{\@ifstar{\read@Arrayijk[*]}{\read@Arrayijk}} +\newcommand\readArrayij{\@ifstar{\read@Arrayij[*]}{\read@Arrayij}} +\newcommand\arrayijk[4]{\csname#1[#2,#3,#4]\endcsname} +\newcommand\arrayij[3]{\csname#1[#2,#3]\endcsname} +\newcommand\Arrayijk[5][\relax]{% + \bgroup% + \ifx\relax#1\else\def\readarrayboundfailmsg{#1}\fi\csname#2\endcsname[#3,#4,#5]% + \egroup% +} +\newcommand\Arrayij[4][\relax]{% + \bgroup% + \ifx\relax#1\else\def\readarrayboundfailmsg{#1}\fi\csname#2\endcsname[#3,#4]% + \egroup% +} +\newcommand\copyrecords[1]{% + \clear@array{#1}% + \edef\former@recordcount{\csname #1CELLS\endcsname}% + \setcounter{@record}{0}% + \whiledo{\value{@record} < \nrecords}{% + \addtocounter{@record}{1}% + \def\arg@name{\csname#1[\the@record]\endcsname}% + \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter% + \expandafter\def\expandafter\arg@name\expandafter{% + \csname ArrayRecord[\the@record]\endcsname}% + }% + \expandafter\edef\csname#1PLANES\endcsname{0}% + \expandafter\edef\csname#1ROWS\endcsname{\nrecords}% + \expandafter\edef\csname#1COLS\endcsname{0}% + \expandafter\edef\csname#1CELLS\endcsname{\nrecords}% + \define@rootmacro{#1}% +} +\newcommand\showargs[1][0]{\bgroup% + \def\Arg@listPLANES{0}% + \def\Arg@listCOLS{0}% + \let\Arg@listROWS\Arg@listCELLS% + \scalardump\Arg@list\egroup% +} +\newcommand\showrecord[2][\relax]{% + \bgroup\ifx\relax#1\else\def\readarrayboundfailmsg{#1}\fi\ArrayRecord[#2]\egroup% +} +% The support routine \getargs{} is provided for backward compatibility. +% It is preferable to directly use facilities of the +% listofitems package to accomplish these tasks. +\def\getargsC#1{% + \bgroup% + \expandafter\setsepchar\expandafter{\read@array@sepchar}% + \greadlist\Arg@list{#1}% + \egroup% + \edef\narg{\Arg@listlen}% + \let\Arg@listCELLS\narg% + \setcounter{@index}{0}% + \whiledo{\value{@index}<\narg}{% + \stepcounter{@index}% + \expandafter\edef\csname arg\romannumeral\value{@index}\endcsname{% + \Arg@list[\value{@index}]}% + }% +} +\endinput + + diff --git a/macros/latex/contrib/readarray/readarray.tex b/macros/latex/contrib/readarray/readarray.tex new file mode 100644 index 0000000000..8376958419 --- /dev/null +++ b/macros/latex/contrib/readarray/readarray.tex @@ -0,0 +1,800 @@ +\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} +\parskip 1em +\parindent 0em +\newcommand\rl{\rule{1em}{0in}} +\def\rdar{\textsf{readarray}} +\def\loi{\textsf{listofitems}} +\def\cmd#1{\texttt{\string\ \unskip#1}} +\usepackage{readarray} +\usepackage{verbatimbox} +\usepackage{filecontents} +\begin{filecontents*}{file1data.txt} +A111 A112 A113 A114 +A121 A122 A123 A124 +A131 A132 A133 A134 + +A211 A212 A213 A214 +A221 A222 A223 A224 +A231 A232 A233 A234 +\end{filecontents*} +\begin{filecontents*}{file2data.txt} +\def{\dataA}{% +A111 A112 A113 A114 +A121 A122 A123 A124 +A131 A132 A133 A134 +% +A211 A212 A213 A214 +A221 A222 A223 A224 +A231 A232 A233 A234 +} +\end{filecontents*} +\begin{filecontents*}{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} + +\textit{was} , \textit{were}, had \textit{been}, had \textit{been} +\textit{were}, \textit{were}, had \textit{been}, had \textit{been} +\textit{was} , \textit{were}, had \textit{been}, had \textit{been} + +will \textit{be}, will \textit{be}, will have \textit{been}, will have \textit{been} +will \textit{be}, will \textit{be}, will have \textit{been}, will have \textit{been} +will \textit{be}, will \textit{be}, will have \textit{been}, will have \textit{been} +\end{filecontents*} + + +\let\vb\verb +\def\bs{{\ttfamily\char'134}} +\reversemarginpar +\marginparwidth 1.5in +\newcommand\margcmd[1]{\marginpar{\hfill\ttfamily\char'134#1}} + +\begin{document} +\begin{center} +\LARGE The {\rdar} Package\\ +\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\\ +\rule{0em}{1.7em}\readarrayPackageDate\\ +V\readarrayPackageVersion +\end{center} + +\section*{Comments About Version 2.0} + +Version 2.0 of the \rdar{} package has 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. +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. + +\section{Description and Commands} + +The {\rdar} package allows for the creation of data arrays (numeric, + string, or even formatted) using either file contents or \vb|\def| + format for input, such that the elements of multiple arrays can be + set and later recalled in an orderly fashion, on a cell-by-cell basis. +Routines have been developed to support the storage and recall of both + 2-D and 3-D arrays, as well as 1-D file-record arrays.% +\footnote{ +Note: for 1-D arrays that are to be simply parsed on the basis of a + specified separator, the \loi{} package is already prepared + 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: + + +\itshape +\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|\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|]|% + \hfill\textup{(3-D)}\\ +\textup{Same as above, with leading/trailing spaces removed from array cells:}\\ +\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|]|% + \hfill\textup{(3-D)}\\ +\textup{Recall 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% + \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|\readarraysepchar{|parsing-separator-char\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 + 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 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. + +Unlike earlier versions of this package, where error messages were + output into the typeset document, error messages are now + set in the log file. +The level of error messaging is defined by the level of bounds checking, + with \cmd{hypercheckbounds} providing the + most intense level of error checking. +When a bounds-checking error is found in an array invocation, in addition + to the error message in the log file, a ``?'' is typeset in the document, + unless bound checking is disabled with \cmd{nocheckbounds}. + + +Several strings of fixed name are defined through the use the +\cmd{readdef} command, which are accessible to the user: + +\itshape +\rl\vb|\nrows|\\ +\rl\vb|\ncols|\\ +\rl\vb|\nrecords|\\ +\rl\vb|\ArrayRecord[|record\vb|]|% + \hfill\textup{(to retrieve record from most recent \cmd{readdef})}\upshape + +The macros \cmd{nrows} and \cmd{ncols}, which were gleaned from the file + structure, may be used in the subsequent \cmd{readarray} + invocation to specify the array dimensions. +Alternately, those values may be manually overridden by specifying + the desired values in the \cmd{readarray} invocation. +Individual records of the original file, from the most recent + \cmd{readdef}, may be recalled with the + \cmd{ArrayRecord} macro. + +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 + +\itshape +\rl\vb|\|array-identifier\vb|CELLS|\\ +\rl\vb|\|array-identifier\vb|PLANES|\\ +\rl\vb|\|array-identifier\vb|ROWS|\\ +\rl\vb|\|array-identifier\vb|COLS|\upshape + +where \textit{array-identifier} is the alphabetic-character string by which +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 + 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 + 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: + +\TABstackTextstyle{\tiny} +\setstackgap{L}{3pt} +\newcommand\SEP{\,\langle\smash{\raisebox{1pt}{\tabbedCenterstack{s\\e\\p}}}\rangle\,} +\renewcommand\arraystretch{1.1} +{\arraycolsep=3pt\relax\small\( +\begin{array}{lll@{\hspace{2pt}}ll} +A_{11}\SEP &A_{12}\SEP &A_{13}\SEP & \ldots & A_{1\mathrm{(columns)}} \\ +A_{21}\SEP &A_{22}\SEP & \ldots && \\ +\vdots&&&&\\ +A_{\mathrm{(rows)}1}\SEP &A_{\mathrm{(rows)}2}\SEP &A_{\mathrm{(rows)}3}\SEP & + \ldots & A_{\mathrm{(rows)}\mathrm{(columns)}} \\ +\end{array} +\)} + +For 3-D arrays, the following structure is employed: + +{\arraycolsep=3pt\relax\small\( +\begin{array}{lll@{\hspace{2pt}}ll} +A_{111}\SEP &A_{112}\SEP &A_{113}\SEP & \ldots & A_{11\mathrm{(columns)}} \\ +A_{121}\SEP &A_{122}\SEP & \ldots && \\ +\vdots&&&&\\ +A_{1\mathrm{(rows)}1}\SEP &A_{1\mathrm{(rows)}2}\SEP &A_{1\mathrm{(rows)}3}\SEP & + \ldots & A_{1\mathrm{(rows)}\mathrm{(columns)}} \\ +\rlap{\scriptsize$<$blank line$>$}&&&&\\ +A_{211}\SEP &A_{212}\SEP &A_{213} & \ldots & A_{21\mathrm{(columns)}} \\ +A_{221}\SEP &A_{222}\SEP & \ldots && \\ +\vdots&&&&\\ +A_{2\mathrm{(rows)}1}\SEP &A_{2\mathrm{(rows)}2}\SEP &A_{2\mathrm{(rows)}3}\SEP & + \ldots & A_{2\mathrm{(rows)}\mathrm{(columns)}} \\ +&&&&\\ +\vdots&&&&\\ +&&&&\\ +A_{\mathrm{(planes)}11}\SEP &A_{\mathrm{(planes)}12}\SEP &A_{\mathrm{(planes)}13}\SEP & \ldots & A_{\mathrm{(planes)}1\mathrm{(columns)}} \\ +A_{\mathrm{(planes)}21}\SEP &A_{\mathrm{(planes)}22}\SEP & \ldots && \\ +\vdots&&&&\\ +A_{\mathrm{(planes)}\mathrm{(rows)}1}\SEP &A_{\mathrm{(planes)}\mathrm{(rows)}2}\SEP &A_{\mathrm{(planes)}\mathrm{(rows)}3}\SEP & + \ldots & A_{\mathrm{(planes)}\mathrm{(rows)}\mathrm{(columns)}} \\ +\end{array} +\)} + + +Here,\,$\SEP${}\,is the data separator that is used to parse the input. +Terms like $A_{\mathrm{(plane)}\mathrm{(row)}\mathrm{(column)}}$ refers + to the \LaTeX{}-formatted data to be associated with the particlar plane, + row, and column of data. +Note, that for 3-D arrays, a blank line can be used to signify to the + parsing algorithm the size of a data plane (alternately, the number of + rows per data plane can be explicitly provided to the \cmd{readarray} + command). + +\section{Getting Data into Array Structures\label{s:ex}} + +One can provide data to be digested by this package in one of two ways: +either through an external file, or by way of ``cut and paste'' into a +\vb|\def|. If one chooses the external file approach, the command +\vb|\readdef|\margcmd{readdef} is the command which can achieve this +result. The command takes two arguments. The first is the file in +which the data is stored, while the second is the data macro into which the +file's data will be placed, for example + +\rl\vb|\readdef{data.txt}{\dataA}|\readdef{file1data.txt}{\dataA} + +In this case, the contents of the file \vb|data.txt| will be placed + into the data macro \vb|\dataA|. +Two alterations to the format occur during this conversion from file + to \cmd{def}: 1) blank lines in the file are ignored; and + 2) a data separator replaces the end-of-line. +At this point, the data is still not digested into a 2-D or 3-D data + ``array.'' +However, two things have been accomplished: 1) the file contents are \cmd{def}'ed + into the data macro \cmd{dataA}; and 2) they are also placed into a 1-D + file record array, \cmd{ArrayRecord}. + +There is no +\textit{requirement} that the input file be organized with structured rows + of data corresponding to individual file records, nor that blank + lines exist between planes of data (if the data is 3-D). +\textit{However}, there is a reason to do so, nonetheless. +In particular, for datafiles that are organized in the +preferred fashion, for example: + +\verbfilebox{file1data.txt} +\rl\theverbbox + +a \vb|\readdef| attempts to estimate the number columns, and + rows-per-plane of the dataset by analyzing the data structure. +These estimates are given by + \vb|\ncols|\margcmd{ncols} and \vb|\nrows|\margcmd{nrows}, in this + case to values of \texttt{\ncols} and \texttt{\nrows}, respectively. +Such data could prove useful if the array size is not known in advance. +When \verb|\readdef| is invoked, a string + \verb|\nrecords|\margcmd{nrecords} will also be set to the number of + file records processed by the \vb|\readdef| command, in this case, + to \texttt{\nrecords}. +Finally, the 1-D file-record array, \cmd{ArrayRecord}\margcmd{ArrayRecord}, + is created to allow access to the most recently read file records. +For example, \vb|\ArrayRecord[3]| produces: ``\ArrayRecord[3]''. +Note, however, that the array, \cmd{ArrayRecord}, will be overwritten on + the subsequent invocation of \cmd{readdef}. + +Because \cmd{ArrayRecord} is only a 1-D file-record array, the + \textit{actual} array metrics, given by \cmd{ArrayRecordCOLS}, + \cmd{ArrayRecordROWS}, \cmd{ArrayRecordPLANES}, and + \cmd{ArrayRecordCELLS} are + \ArrayRecordCOLS, \ArrayRecordROWS, \ArrayRecordPLANES, and + \ArrayRecordCELLS, respectively, which do not align with the + estimations provided by \cmd{ncols} and \cmd{nrows}. + +In lieu of \verb|\readdef|, a generally less preferred, but viable way +to make the data available is to cut and paste into a \vb|\def|. +However, because a blank line is not permitted as part of the \vb|\def|, +a filler symbol (\vb|%| or \vb|\relax|) must be used in its place, if it +is desired to visually separate planes of data, as shown in the +\verb|\def| example at the top of the following page. Note that the +\vb|%| is also required at the end of the line containing \vb|\def|, in +order to guarantee that, in this case, \vb|A111| is the first element of +data (and not a space separator). However, unlike \vb|\readdef|, this +definition will neither set the value of \vb|\ncols| nor \vb|\nrows|. + +\verbfilebox{file2data.txt} +\rl\theverbbox + +Once the data to be placed into an array is available in a macro, + by way of either + \vb|\readdef| or \vb|\def|, the command to digest the data into an + array is \vb|\readarray| for the case of 2-D or 3-D data. +For 1-D file-record arrays, in contrast, the \cmd{readrecordarray} + command is used to go directly from a file into the 1-D array, + bypassing the intermediate step of a data macro. + +\subsection{1-D File-Record Arrays} + +If the desire is merely to parse a string of data based on a common + data separator, such as a comma or any other character, there is + no need to use the \rdar{} package. +The \loi{} package, which is employed by \rdar, already has those provisions + and should be used directly.% +\begin{verbbox}[\footnotesize] +\setsepchar{ } +\readlist\oneDlist{\dataA} +\oneDlistlen{} list items, 12th item is ``\oneDlist[12]''. +\end{verbbox} +\footnote{% +For a simple 1-D list punctuated by data separators, one may use the +\loi{} package directly:\\ +\rl\theverbbox\\ +which produces the following output: +\setsepchar{ }% +\readlist\oneDlist{\dataA}% +\oneDlistlen{} list items, 12th item is ``\oneDlist[12]''. +} + +On the other hand, if one wishes a 1-D file-record array, in which each + array element corresponds to the record from a file, then \rdar{} + can be used. +The command \cmd{readrecordarray} can be used to stick the individual + ``file records'' from a designated file into a 1-D array. + +The \cmd{readrecordarray} command takes two arguments: a file + name containing data records, and the name of a 1-D record-array + into which to place the file records. + +So, for example, with the invocation of + \vb|\readrecordarray{data.txt}\oneD|, the data from the file + \texttt{data.txt} is now saved in the \cmd{oneD} array, and can + be retrieved, for example, the 3rd record, with \cmd{oneD[3]}, which + returns \readrecordarray{file1data.txt}\oneD``\oneD[3]''. + +If an array name is reutilized, its prior definitions are cleared, + so that ``old'' data is not inadvertantly retrieved following the + reutilization. + + +\subsection{Creating 2-D and 3-D Arrays} + +The \cmd{readarray}\margcmd{readarray} command, used to convert + raw parsable data into data arrays, + takes three arguments. +The first is the data macro into which the unarrayed raw data had + previously been stuffed (e.g., by way of \cmd{readdef} or \cmd{def}). +The second is array-identifier macro into which the parsed data is to + be placed. +Finally, the last compound argument, enclosed in square brackets, denotes the + rank and range of the array to be created. + +There is a starred version of the command, \cmd{readarray*}, which is used + to remove leading/trailing spaces from the array elements, when parsed. +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} +For a 2-D array, this last argument of \cmd{readarray} will be + of the form \vb|[-,<columns>]|. +If the data had recently been read by way of \vb|\readdef|, the + string \vb|\ncols| may be used to signify the \vb|<columns>| value. +The \texttt{-} (or any other character before the initial comma) + reminds us that the range of row numbers is not specified in advance, + but is dictated by the length of the data macro containing the raw + file data. +For such a 2-D array, only the column range is specified. +\end{sloppypar} + +Consider, for example, the previously discussed file, \texttt{dataA.txt}, + which had been digested into the data macro \cmd{dataA}. +One can process that as a 2-D array with an invocation of + \vb|\readarray\dataA\twoD[-,\ncols]|, since \cmd{ncols} had been + set to a value of \texttt{\ncols}, based on the prior \cmd{readdef}. +Thereafter, data may be retieved, for example the 3rd row, 2nd column, + with \cmd{twoD[3,2]}, to give +\readarray\dataA\twoD[-,\ncols] +``\twoD[3,2]''. + +The actual array size is given by +\cmd{twoDROWS}, \cmd{twoDCOLS}, \cmd{twoDCELLS} +as +\twoDROWS, \twoDCOLS, and \twoDCELLS, respectively. +The number of rows in the array is fewer than the number of file records, + \oneDCELLS, because blank rows in the input file are ignored. +One should also note that if the end of the data stream results in a + partial final row of data, the partial row will be discarded. + +\subsubsection{3-D Arrays} + +For the 3-D case, the only difference in the invocation of + \vb|\readarray| is in the 3rd argument, in which the + rank and range of the array is specified. +This last argument will be of the form + \vb|[-,<rows>,<columns>]|. +As before, the \vb|-| denotes the fact that the range of the planes + of data is unknown before the fact, and governed by the length + of data in the dataset. +Only the range of rows and columns are specifiable here. +If \vb|\readdef| had been used on a properly formed +input file, both \vb|\nrows| and \vb|\ncols| may be used to supply the +range arguments of the 3-D array. + +For example, using the same \cmd{dataA} dataset, but reading it as a + 3-D array can be accomplished with + \vb|\readarray\dataA\threeD[-,\nrows,\ncols]|.% +\readarray\dataA\threeD[-,\nrows,\ncols] +This results in an array with \threeDPLANES{} planes, + \threeDROWS{} rows, and \threeDCOLS{} columns +(\threeDCELLS{} data cells total). +Data from the 2nd plane, 1st row, 2nd column can be obtained via +\cmd{threeD[2,1,2]} as ``\threeD[2,1,2]''. + +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} + +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} + +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 the data parsing, by specifying a + \textbf{logical-OR} (\vb+||+) separated list: \vb:\readarraysepchar{,||.}:. +Similarly, a multicharacter separator is possible, so that setting + \vb|\readarraysepchar{!!}| will cause \cmd{readarray} to look for + instances of ``!!'' to divide the data into separate array elements. + +Consider the following comma-separated input in, let us say, the file + \textsf{conjugation.txt}. + +\verbfilebox[\footnotesize]{file3data.txt} +\rl\theverbbox + +The sequence of commands + +\begin{verbbox} +\readarraysepchar{,} +\readdef{conjugation.txt}\dataC +\readarray*\dataC\tobeConjugation[-,\nrows,\ncols] +\end{verbbox} +\rl\theverbbox +\readarraysepchar{,} +\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}. +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 +\cmd{tobeConjugation[1,3,3]} will yield the entry from the + 1st plane, 3rd row, 3rd column as ``\tobeConjugation[1,3,3]''. + +The 3-D array metrics are \cmd{tobeConjugationPLANES}, + \cmd{tobeConjugationROWS}, \cmd{tobeConjugationCOLS}, and + \cmd{tobeConjugationCELLS}, which are + here given as \tobeConjugationPLANES, + \tobeConjugationROWS, \tobeConjugationCOLS, and + \tobeConjugationCELLS. + respectively. + + +\section{Recalling 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 +be known to the user, if the values employed came from the +\vb|\readdef| estimations of +\vb|\ncols| and \vb|\nrows|. Therefore, the \cmd{readrray} +\margcmd{{\rmfamily\itshape array-identifier}CELLS}% +\margcmd{{\rmfamily\itshape array-identifier}PLANES}% +\margcmd{{\rmfamily\itshape array-identifier}ROWS}% +\margcmd{{\rmfamily\itshape array-identifier}COLS}% +command variants also define the following strings: +\itshape\vb|\|array-identifier\vb|CELLS|, \vb|\|array-identifier\vb|PLANES|, +\vb|\|array-identifier\vb|ROWS|{\upshape, and} +\vb|\|array-identifier\vb|COLS|\upshape, where +\cmd{array-identifier} is the array name supplied to +the \cmd{readarray} command. Note, for 3-D arrays, that +\end{sloppypar} + +\rl\itshape\vb|\|array-identifier\vb|CELLS| $=$ \\\rl\quad + \vb|\|array-identifier\vb|PLANES| $\times$ \vb|\|array-identifier\vb|ROWS| + $\times$ \vb|\|array-identifier\vb|COLS|\upshape + +For the \cmd{tobeConjugation} example of the prior section, +\tobeConjugationCELLS $=$\tobeConjugationPLANES +$\times$\tobeConjugationROWS $\times$% +\tobeConjugationCOLS. Likewise, for 2-D arrays + +\rl\itshape\vb|\|array-identifier\vb|CELLS| $=$ \vb|\|array-identifier\vb|ROWS| +$\times$ \vb|\|array-identifier\vb|COLS|\upshape + +To retrieve the data from the array, one merely supplies the + array name in the form of + \cmd{}\textit{array-identifier}\margcmd{\rmfamily\itshape array-identifier% + \upshape\ttfamily[...]}, + along with the array-cell nomenclature in the form of + \textit{\texttt{\upshape[}plane\texttt{\upshape,}row\texttt{\upshape,}% + column\texttt{\upshape]}} for 3-D arrays, + \textit{\texttt{\upshape[}row\texttt{\upshape,}% + column\texttt{\upshape]}} for 2-D arrays, and + \textit{\texttt{\upshape[}row\texttt{\upshape]}} for 1-D arrays. + +Thus, in the case of the earlier example involving conjugation of the +verb \textit{to be}, the second-person future-perfect tense of the verb +is given by + +\rl\cmd{tobeConjugation[3,2,4]} + +which yields ``\tobeConjugation[3,2,4]''. + +\section{Bounds Checking} + +While the user is developing his or her application involving the {\rdar} +package, there may accidentally arise the unintended circumstance where +an array element is requested which falls outside the array bounds. +In general, when a non-existent array element is requested in the + absence of bounds checking, the call will expand to \cmd{relax}. + +The package provides three declarations to set the manner in + which array bounds are be monitored. +The setting \cmd{nocheckbounds}\margcmd{nocheckbounds} is used when bounds + are not to be checked. +This is the default behavior for \rdar. +For some bounds checking, \cmd{checkbounds}\margcmd{checkbounds} + may be set. +With this setting, bounds violations are noted, but no guidance is + provided as to the allowable index range for the array. +However, with \cmd{hypercheckbounds}\margcmd{hypercheckbounds} set, + full bounds checking is possible. +With this setting, not only are violations noted, but a description + of the actual array range is provided. + +As of V2.0, bounds violations are noted in the log file, rather than the + document itself. +However, if an array bound is violated when bounds checking is turned on, +a ``?'' shows up in the document itself. + + +\section{Accessing Array Cells if Full Expansion is Required + (e.g., placed in an \texttt{\bs edef}) } + +If full expansion is required of array cell contents (and assuming the cell + content is expandable), it is advisable to set \cmd{nocheckbounds}% + , so that the error checking code is not + included in the expansion. +Results may be also expanded even with \cmd{checkbounds} + set, though the error-checking code is part of the expansion. +However, with \cmd{hypercheckbounds} set, full + expansion of array cells is no longer possible. + +\section{Accessing Array Cells if No Expansion is Required} + +With the normal use of \cmd{\rmfamily\itshape array-identifier} syntax + for accessing array cells, + several levels of expansion are required to directly recover the original + tokens of the cell, and then only when bounds checking is disabled. +When the actual unexpanded tokens of cell are required, the use of the + \cmd{arraytomacro}\margcmd{arraytomacro} command provides the means + to accomplish this. +The command takes the array name and index as the initial arguments followed + by a generic macro name into which to place the unexpanded tokens of the + indexed array cell. + +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 +\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| + +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 + +\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|}|% +\\ +\rl\vb|\readArrayij{\|data-macro\vb|}{|array-identifier\vb|}{|columns\vb|}|% +\\ +\rl\vb|\readArrayij*{\|data-macro\vb|}{|array-identifier\vb|}{|columns\vb|}|% +\\ +\rl\vb|\readArrayijk{\|data-macro\vb|}{|array-identifier\vb|}{|rows\vb|}{|columns\vb|}|% +\\ +\rl\vb|\readArrayijk*{\|data-macro\vb|}{|array-identifier\vb|}{|rows\vb|}{|columns\vb|}|% +\\ +\rl\vb|\showrecord[|error\vb|]{|record number\vb|}|\\ +\rl\vb|\Arrayij[|error\vb|]{|array-identifier\vb|}{|row\vb|}{|column\vb|}|\\ +\rl\vb|\Arrayijk[|error\vb|]{|array-identifier\vb|}{|plane\vb|}{|row\vb|}{|% + column\vb|}|\\ +\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 + my simplistic (read ``deficient'') \textsf{getargs} package to + inspire his effort in creating the powerful \loi{} package. +It is precisely the tool I have sought for a long time, and I have + adapted its use into the workings of this package. + +I would like to thank Dr. David Carlisle for his assistance in +helping the author rewrite the \vb|\getargs| command, originally found +in the \textsf{stringstrings} package. To distinguish the two versions, +and in deference to him, it is herein named \vb|\getargsC|. However, +as of V2.0, its presence is vestigial, having instead been superceded with +the \loi{} package macros. + +I am likewise grateful to Ken Kubota, who suggested moving the + \vb|\newread| outside of \vb|\readdef|, so as not to prematurely + exhaust the 16 available file streams. + +\clearpage +\section{Code Listing} + +\verbfilenobox[\footnotesize]{readarray.sty} +\end{document} + + + |