Read cell value from string array and it assign to macro
\readrecordarray
is meant for one-dimensional arrays, but \mydata[...]
is used as 2-D array.
Rather use \readdef{myfile.txt}\myfile
to provide a 'data-macro' and apply \readarray\myfile\mydata[2,2]
later on.
\documentclass{article}
\usepackage{readarray}[2016-11-07]
\begin{filecontents*}{myfile.txt}
Alfred; Koch
Mildred; Jane
\end{filecontents*}
\usepackage[utf8]{inputenc}
\usepackage[T2A,T1]{fontenc}
\usepackage[ukrainian]{babel}
%\usepackage{filecontents}
\begin{document}
\readarraysepchar{;}
\readdef{myfile.txt}\myfile
\readarray\myfile\mydata[2,2]
\def\Nameone{\mydata[1,1]}
\def\Nametwo{\mydata[2,1]}
\def\Surnameone{\mydata[1,2]}
\def\Surnametwo{\mydata[2,2]}
\Nameone\ \Surnameone
\Nametwo\ \Surnametwo
\end{document}
I propose an altogether different approach, which has the advantage of being “fully expandable”; for example you can even do
\MakeUppercase{\Nameone}
and it will print
ALFRED
Here is the code. The idea is to read the file line by line; each line is stored as the item of a sequence, but the internal items are transformed in the form {item1}{item2}
, so they can be retrieved expandably with \tl_item:nn
(in its variant form \tl_item:fn
, because we first extract the row from the sequence).
\begin{filecontents*}{\jobname.dat}
Alfred; Koch
Mildred; Jane
\end{filecontents*}
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
% variables
\ior_new:N \g_kapone_array_file_stream
\tl_new:N \l_kapone_array_separator_tl
\seq_new:N \l__kapone_array_temp_seq
\tl_new:N \l__kapone_array_temp_tl
% user level commands
\NewDocumentCommand{\readarrayfile}{mm}
{
\seq_clear_new:c { kapone_array_#1_seq }
\ior_open:Nn \g_kapone_array_file_stream { #2 }
\ior_map_inline:Nn \g_kapone_array_file_stream
{
\kapone_array_line:nn { #1 } { ##1 }
}
}
\NewDocumentCommand{\arrayseparator}{m}
{
\tl_set:Nn \l_kapone_array_separator_tl { #1 }
}
\arrayseparator{,} % default
\NewExpandableDocumentCommand{\arrayitem}{mmm}
{
\kapone_array_item:nnn { #1 } { #2 } { #3 }
}
% lower level functions
\cs_new_protected:Nn \kapone_array_line:nn
{
\seq_set_split:NVn \l__kapone_array_temp_seq \l_kapone_array_separator_tl { #2 }
\tl_clear:N \l__kapone_array_temp_tl
\seq_map_inline:Nn \l__kapone_array_temp_seq
{
\tl_put_right:Nn \l__kapone_array_temp_tl { {##1} }
}
\seq_put_right:cV { kapone_array_#1_seq } \l__kapone_array_temp_tl
}
\cs_new:Nn \kapone_array_item:nnn
{
\tl_item:fn { \seq_item:cn { kapone_array_#1_seq } { #2 } } { #3 }
}
% variants
\cs_generate_variant:Nn \seq_set_split:Nnn { NV }
\cs_generate_variant:Nn \seq_put_right:Nn { cV }
\cs_generate_variant:Nn \tl_item:nn { f }
\ExplSyntaxOff
\begin{document}
\arrayseparator{;}
\readarrayfile{mydata}{\jobname.dat}
\newcommand{\Nameone}{\arrayitem{mydata}{1}{1}}
\newcommand{\Nametwo}{\arrayitem{mydata}{2}{1}}
\newcommand{\Surnameone}{\arrayitem{mydata}{1}{2}}
\newcommand{\Surnametwo}{\arrayitem{mydata}{2}{2}}
\Nameone
\Nametwo
\Surnameone
\Surnametwo
\edef\test{\arrayitem{mydata}{1}{1}}
\texttt{\meaning\test}
\end{document}
An extended version where one can access the number of rows and columns of an array.
\begin{filecontents*}{\jobname.dat}
Alfred; Koch
Mildred; Jane
\end{filecontents*}
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
% variables
\ior_new:N \g_kapone_array_file_stream
\tl_new:N \l_kapone_array_separator_tl
\seq_new:N \l__kapone_array_temp_seq
\tl_new:N \l__kapone_array_temp_tl
% user level commands
\NewDocumentCommand{\readarrayfile}{mm}
{
\seq_clear_new:c { l_kapone_array_#1_seq }
\int_zero_new:c { l_kapone_array_cols_#1_int }
\ior_open:Nn \g_kapone_array_file_stream { #2 }
\ior_map_inline:Nn \g_kapone_array_file_stream
{
\kapone_array_line:nn { #1 } { ##1 }
}
}
\NewDocumentCommand{\arrayseparator}{m}
{
\tl_set:Nn \l_kapone_array_separator_tl { #1 }
}
\arrayseparator{,} % default
\NewExpandableDocumentCommand{\arrayitem}{mmm}
{
\kapone_array_item:nnn { #1 } { #2 } { #3 }
}
\NewExpandableDocumentCommand{\arrayrows}{m}
{
\seq_count:c { l_kapone_array_#1_seq }
}
\NewExpandableDocumentCommand{\arraycols}{m}
{
\int_use:c { l_kapone_array_cols_#1_int }
}
% lower level functions
\cs_new_protected:Nn \kapone_array_line:nn
{
\seq_set_split:NVn \l__kapone_array_temp_seq \l_kapone_array_separator_tl { #2 }
\int_set:cn { l_kapone_array_cols_#1_int }
{
\int_max:nn
{ \int_use:c { l_kapone_array_cols_#1_int } }
{ \seq_count:N \l__kapone_array_temp_seq }
}
\tl_clear:N \l__kapone_array_temp_tl
\seq_map_inline:Nn \l__kapone_array_temp_seq
{
\tl_put_right:Nn \l__kapone_array_temp_tl { {##1} }
}
\seq_put_right:cV { l_kapone_array_#1_seq } \l__kapone_array_temp_tl
}
\cs_new:Nn \kapone_array_item:nnn
{
\tl_item:fn { \seq_item:cn { l_kapone_array_#1_seq } { #2 } } { #3 }
}
% variants
\cs_generate_variant:Nn \seq_set_split:Nnn { NV }
\cs_generate_variant:Nn \seq_put_right:Nn { cV }
\cs_generate_variant:Nn \tl_item:nn { f }
\ExplSyntaxOff
\begin{document}
\arrayseparator{;}
\readarrayfile{mydata}{\jobname.dat}
\newcommand{\Nameone}{\arrayitem{mydata}{1}{1}}
\newcommand{\Nametwo}{\arrayitem{mydata}{2}{1}}
\newcommand{\Surnameone}{\arrayitem{mydata}{1}{2}}
\newcommand{\Surnametwo}{\arrayitem{mydata}{2}{2}}
\Nameone
\Nametwo
\Surnameone
\Surnametwo
\MakeUppercase{\Nameone}
The array \texttt{mydata} has \arrayrows{mydata} rows
and \arraycols{mydata} columns.
\edef\test{\arrayitem{mydata}{1}{1}}
\texttt{\meaning\test}
\end{document}