如何从字符串数组中读取一些值并将其分配给宏
\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}
\readrecordarray{myfile.txt}\mydata
\readarraysepchar{;}
\def\ThisOneWork{\mydata[1]}
\def\Nameone{\mydata[1,1]}
\def\Nametwo{\mydata[1,2]}
\def\Surnameone{\mydata[2,1]}
\def\Surnametwo{\mydata[2,2]}
Only this one work \ThisOneWork
\Nameone
\Nametwo
\Surnameone
\Surnametwo
\end{document}
或者也许有其他方便的软件包可以解决这个问题?
答案1
\readrecordarray
用于一维数组,但\mydata[...]
用作二维数组。
而是用来\readdef{myfile.txt}\myfile
提供“数据宏”并\readarray\myfile\mydata[2,2]
稍后应用。
\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}
答案2
我提出了一种完全不同的方法,它的优点是“完全可扩展”;例如,你甚至可以这样做
\MakeUppercase{\Nameone}
它将打印
阿尔弗雷德
这是代码。其思想是逐行读取文件;每行都存储为序列的项目,但内部项目以 的形式进行转换{item1}{item2}
,因此可以使用 进行扩展检索\tl_item:nn
(以其变体形式\tl_item:fn
,因为我们首先从序列中提取行)。
\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}
可以访问数组的行数和列数的扩展版本。
\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}