From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001
From: Norbert Preining <norbert@preining.info>
Date: Mon, 2 Sep 2019 13:46:59 +0900
Subject: Initial commit

---
 macros/latex/contrib/readarray/readarray.sty | 427 +++++++++++++++++++++++++++
 1 file changed, 427 insertions(+)
 create mode 100644 macros/latex/contrib/readarray/readarray.sty

(limited to 'macros/latex/contrib/readarray/readarray.sty')

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
+
+
-- 
cgit v1.2.3

