\ProvidesPackage{readarray} [2013/04/18 v1.1 Routines for inputting array data and recalling it on an element-by-element basis. Currently supports 2-D and 3-D array] % 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 \usepackage{ifthen} \usepackage{ifnextok} % \newcounter{@index} \newcounter{@plane} \newcounter{@row} \newcounter{@col} \newcounter{use@args} \newcounter{@record} \def\the@rule{\rule{.8ex}{1.6ex}}% % \newcommand\readArrayijk[4]{% \getargsC{#1}% \setcounter{@plane}{\numexpr(\narg/#4/#3)}% \setcounter{use@args}{\numexpr\arabic{@plane}*#3*#4}% \ifthenelse{\arabic{use@args} > \narg}{% \addtocounter{@plane}{-1}% \setcounter{use@args}{\numexpr\arabic{@plane}*#3*#4}% }{}% \expandafter\edef\csname#2PLANES\endcsname{\arabic{@plane}}% \expandafter\edef\csname#2ROWS\endcsname{#3}% \expandafter\edef\csname#2COLS\endcsname{#4}% \expandafter\edef\csname#2CELLS\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} > #4}% {\addtocounter{@row}{1}% \addtocounter{@col}{-#4}}% {}% \ifthenelse{\value{@row} > #3}% {\addtocounter{@plane}{1}% \addtocounter{@row}{-#3}}% {}% \expandafter\protected@edef% \csname#2X\roman{@plane}X\roman{@row}X\roman{@col}\endcsname% {\expandafter\csname arg\roman{@index}\endcsname}% }% } % \newcommand\readArrayij[3]{% \getargsC{#1}% \setcounter{@row}{\numexpr(\narg/#3)}% \setcounter{use@args}{\numexpr\arabic{@row}*#3}% \ifthenelse{\arabic{use@args} > \narg}{% \addtocounter{@row}{-1}% \setcounter{use@args}{\numexpr\arabic{@row}*#3}% }{}% \expandafter\edef\csname#2PLANES\endcsname{1}% \expandafter\edef\csname#2ROWS\endcsname{\arabic{@row}}% \expandafter\edef\csname#2COLS\endcsname{#3}% \expandafter\edef\csname#2CELLS\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} > #3}% {\addtocounter{@row}{1}% \addtocounter{@col}{-#3}}% {}% \expandafter\protected@edef% \csname#2X\roman{@row}X\roman{@col}\endcsname% {\expandafter\csname arg\roman{@index}\endcsname}% }% } % \def\nonposrecordmessage{{\tiny Only positive showrecords permitted}} \def\recordmessage#1{{\tiny RECORD=#1 exceeds records read}} % \def\nonposmessage{{\tiny Only positive array indices permitted}} \def\planemessage#1#2{{\tiny PLANE=#2 exceeds limit for #1}} \def\rowmessage#1#2{{\tiny ROW=#2 exceeds limit for #1}} \def\colmessage#1#2{{\tiny COL=#2 exceeds limit for #1}} % \newcommand\Arrayijk[5][$]{% \setcounter{@plane}{#3}% \setcounter{@row}{#4}% \setcounter{@col}{#5}% \ifthenelse{\value{@plane}<1 \OR \value{@row}<1 \OR \value{@col}<1}{% \if$#1\nonposmessage\else#1\fi}{% \ifthenelse{#3 > \csname#2PLANES\endcsname}{% \if$#1\planemessage{#2}{#3}\else#1\fi}{% \ifthenelse{#4 > \csname#2ROWS\endcsname}{% \if$#1\rowmessage{#2}{#4}\else#1\fi}{% \ifthenelse{#5 > \csname#2COLS\endcsname}{% \if$#1\colmessage{#2}{#5}\else#1\fi}{% \csname#2X\roman{@plane}X\roman{@row}X\roman{@col}\endcsname}% }% }% }% } % \newcommand\Arrayij[4][$]{% \setcounter{@row}{#3}% \setcounter{@col}{#4}% \ifthenelse{\value{@row}<1 \OR \value{@col}<1}{% \if$#1\nonposmessage\else#1\fi}{% \ifthenelse{#3 > \csname#2ROWS\endcsname}{% \if$#1\rowmessage{#2}{#3}\else#1\fi}{% \ifthenelse{#4 > \csname#2COLS\endcsname}{% \if$#1\colmessage{#2}{#4}\else#1\fi}{% \csname#2X\roman{@row}X\roman{@col}\endcsname}% }% }% } % \newcommand\copyrecords[1]{% \setcounter{@record}{0}% \whiledo{\value{@record} < \nrecords}{% \addtocounter{@record}{1}% \expandafter\protected@edef\csname#1X\roman{@record}Xi\endcsname{% \csname record\roman{@record}\endcsname}% }% \expandafter\edef\csname#1PLANES\endcsname{1}% \expandafter\edef\csname#1ROWS\endcsname{\nrecords}% \expandafter\edef\csname#1COLS\endcsname{1}% \expandafter\edef\csname#1CELLS\endcsname{\nrecords}% } % \newcommand\showrecord[2][$]{% \setcounter{@record}{#2}% \ifthenelse{\value{@record}<1}{% \if$#1\nonposrecordmessage\else#1\fi}{% \ifthenelse{#2 > \nrecords}{% \if$#1\recordmessage{#2}\else#1\fi}{% \csname record\roman{@record}\endcsname}% }% } % \newcommand\readdef[2]{% \def\first@row{T}% \def\first@plane{T}% \catcode\endlinechar=10\relax% \def#2{}% \setcounter{@record}{0}% \newread\file% \openin\file=#1% \loop\unless\ifeof\file% \read\file to\fileline % Reads a line of the file into \fileline% \addtocounter{@record}{1}% \protected@edef#2{#2\fileline}% \if T\first@row\getargsC{#2}\setcounter{@col}{\numexpr(\narg-1)}% \edef\ncols{\arabic{@col}}\def\first@row{F}\setcounter{@row}{1}% \else% \if T\first@plane\getargsC{\fileline}\ifthenelse{\equal{\narg}{1}}{% \edef\nrows{\arabic{@row}}\def\first@plane{F}}{% \addtocounter{@row}{1}}% \fi% \fi% \expandafter\protected@edef\csname record\roman{@record}\endcsname{% \fileline}% \repeat% \edef\nrecords{\arabic{@record}}% \closein\file% \catcode\endlinechar=5\relax% } % \newcommand\showargs[1][0]{% narg=\narg:~% \the@rule% \setcounter{arg@index}{0}% \setcounter{break@count}{0}% \whiledo{\value{arg@index} < \narg}{% \addtocounter{arg@index}{1}% \addtocounter{break@count}{1}% \csname arg\roman{arg@index}\endcsname% \the@rule% \ifthenelse{\equal{#1}{\value{break@count}}}{% \ifthenelse{\equal{\value{arg@index}}{\narg}}{}{% \newline\the@rule\addtocounter{break@count}{-#1}}% }% {}% }% \setcounter{arg@index}{0}% } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % The \getargsC macro mimics the behavior of the \getargs macro % of the stringstrings package, but runs faster, and can handle % arbitrary tokens. For the development of \getargsC, significant % assistance was provided by David Carlisle, for which the author is % most appreciative. % http://tex.stackexchange.com/questions/101604/ % parsing-strings-containing-diacritical-marks-macros % \def\string@end{$\SaveHardspace} \def\converttilde{F} \newcounter{arg@index} \newcounter{break@count} \let\SaveHardspace~%%% % \def\getargsC#1{% \if T\converttilde\def~{ }\else\catcode`~=12\fi \protected@edef\the@string{#1}% \setcounter{arg@index}{0}% \lowercase{\expandafter\parse@Block\the@string} \string@end \let~\SaveHardspace% \catcode`~=13 } % \def\parse@Block#1 {% \stepcounter{arg@index}% \@namedef{arg\roman{arg@index}}{#1}% \futurelet\tmp\parse@Block@} % \def\parse@Block@{% \ifx\tmp\string@end\edef\narg{\thearg@index}\expandafter\@gobble \else\expandafter\parse@Block\fi} % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \endinput