我是 LaTeX 的新手,我正在尝试迭代在这个精彩的论坛上找到的可用解决方案。
% Credit: https://tex.stackexchange.com/questions/215563/storing-an-array-of-strings-in-a-command
\ExplSyntaxOn
% Some commands are declared with NewDocumentCommand and NewExpandableDocumentCommand because \ExplSyntaxOn messes up with text
% (produces no spaces)
\NewDocumentCommand{\storedata}{
m % #1: <token list> array name; for example, ``a_wonderful_name_for_my_array"
m % #2: <sequence> that stores braced list of values; for example, ``{one}{two}{three}"
}
{
\au_store_data:nn { #1 } { #2 }
}
\NewDocumentCommand{\appenddata}{
m % #1: <token list> array name; for example, ``a_wonderful_name_for_my_array"
m % #2: <sequence> of values to append; for example, ``{one}{two}{three}"
}
{
\au_append_data:nn { #1 } { #2 }
}
\NewExpandableDocumentCommand{\getdata}{
O{1} % #1: <integer expression> that evalues to the accessed index
m % #2: <token list> array name; for example, ``a_wonderful_name_for_my_array"
}
{
\au_get_data:nn { #1 } { #2 }
}
\NewExpandableDocumentCommand{\getlength}{
m % #1: <token list> array name; for example, ``a_wonderful_name_for_my_array"
}
{
\au_get_length:n { #1 }
}
\NewDocumentCommand{\removelast}{
o % #1: <cname> output variable prefixed with a '\'; for example, scratch variable ``\l_tmpa_tl" or ``\scope_module_description_type"
m % #2: <token list> array name; for example, ``a_wonderful_name_for_my_array"
}
{
\au_remove_last:Nn { #1 } { #2 }
}
\cs_new_protected:Npn \au_store_data:nn
#1 % <token list> array name; for example, ``a_wonderful_name_for_my_array"
#2 % <sequence> that stores braced list of values; for example, ``{one}{two}{three}"
{
% create the sequence if it doesn't exist or clear it if it exists
\seq_clear_new:c { l_au_data_#1_seq }
% append the items
\__au_append_data:nn { #1 } { #2 }
}
\cs_new_protected:Npn \au_append_data:nn
#1 % <token list> array name; for example, ``a_wonderful_name_for_my_array"
#2 % <sequence> of values to append; for example, ``{one}{two}{three}"
{
% create the sequence if it doesn't exist, do nothing if it exists
\seq_if_exist:cF { l_au_data_#1_seq }
{ \seq_new:c { l_au_data_#1_seq } }
% append the items
\__au_append_data:nn { #1 } { #2 }
}
\cs_new:Npn \au_get_data:nn
#1 % <integer expression> that evalues to the accessed index
#2 % <token list> array name; for example, ``a_wonderful_name_for_my_array"
{
% retrieve the requested item
\seq_item:cn { l_au_data_#2_seq } { #1 }
}
\cs_new:Npn \au_get_length:n
#1 % <token list> array name; for example, ``a_wonderful_name_for_my_array"
{
\seq_count:c { l_au_data_#1_seq }
}
\cs_new_protected:Npn \au_remove_last:Nn
#1 % <cname> output variable prefixed with a '\'; for example, scratch variable ``\l_tmpa_tl" or ``\scope_module_description_type"
#2 % <token list> array name; for example, ``a_wonderful_name_for_my_array"
{
\IfNoValueTF { #1 }
{
\__au_remove_last:Nn \l_tmpa_tl { #2 }
}
{
\__au_remove_last:Nn #1 { #2 }
}
}
\cs_new_protected:Npn \__au_append_data:nn
#1 % <token list> array name; for example, ``a_wonderful_name_for_my_array"
#2 % <sequence> of values to append; for example, ``{one}{two}{three}"
{
% append items one at a time
\tl_map_inline:nn { #2 }
{
\seq_put_right:cn { l_au_data_#1_seq } { ##1 }
}
}
\cs_new_protected:Npn \__au_remove_last:Nn
#1 % <cname> output variable prefixed with a '\'; for example, scratch variable ``\l_tmpa_tl" or ``\scope_module_description_type"
#2 % <token list> array name; for example, ``a_wonderful_name_for_my_array"
{
\seq_pop_right:cN { l_au_data_#2_seq } #1
}
\ExplSyntaxOff
% Credit (end)
我想以某种方式模拟用提供的参数替换 #1 等的行为。我已将其放在所有声明之前:
\tl_new:N \g_au_internal_seq_prefix_tl
\tl_gset:Nn \g_au_internal_seq_prefix_tl {l_au_data_}
\tl_new:N \g_au_internal_seq_postfix_tl
\tl_gset:Nn \g_au_internal_seq_postfix_tl {_seq}
并在下面添加了此功能:
\cs_new_protected:Npn \au_get_internal_seq_name_by_array_name:n
#1 % <token list> array name; for example, ``a_wonderful_name_for_my_array"
{
\tl_set_eq:NN \l_tmpa_tl \g_au_internal_seq_prefix_tl
\tl_put_right:Nn \l_tmpa_tl { #1 }
\tl_put_right:NV \l_tmpa_tl \g_au_internal_seq_prefix_tl
\tl:use:N \l_tmpa_tl
}
以下是我尝试使用它的方法:
\cs_new_protected:Npn \au_store_data:nn
#1 % <token list> array name; for example, ``a_wonderful_name_for_my_array"
#2 % <sequence> that stores braced list of values; for example, ``{one}{two}{three}"
{
% create the sequence if it doesn't exist or clear it if it exists
%\seq_clear_new:c { l_au_data_#1_seq }
\seq_clear_new:c { \tl_use:N \au_get_internal_seq_name_by_array_name:n{ #1 } }
% append the items
\__au_append_data:nn { #1 } { #2 }
}
再次强调,我是 LaTeX 新手,http://ctan.mirror.colo-serv.net/macros/latex/contrib/l3kernel/interface3.pdf对我没什么帮助。
答案1
这里介绍一种listofitems
方法,我使用以下四个命令引入了略有不同的语法:
\initializedata<\array>{<comma separated list>}% TO DEFINE LIST
<\array[element number]>% TO RECALL LIST ELEMENT
\replacedata<\array[element number]>{<replacement data>}% TO REPLACE DATA
\extenddata<\array>{<data to extend list>}% TO EXTEND LIST
如果有人喜欢不同的分隔符,我会显示设置的位置,当然,列表分隔符也会遵循该设置。MWE:
\documentclass{article}
\usepackage{listofitems}
\setsepchar{,}% <---LIST SEPARATOR
\newcommand\initializedata[2]{\readlist*#1{#2}}
\makeatletter
\def\replacedata#1[#2]#3{%
\def\tmp{}%
\foreachitem\z\in#1[]{%
\ifnum\zcnt=1\else\g@addto@macro\tmp{,}\fi
\ifnum\zcnt=#2\relax\g@addto@macro\tmp{#3}\else
\expandafter\g@addto@macro\expandafter\tmp\expandafter{\z}%
\fi
}%
\readlist*#1{\tmp}%
}
\newcommand\extenddata[2]{%
\def\tmp{}%
\foreachitem\z\in#1[]{%
\ifnum\zcnt=1\else\g@addto@macro\tmp{,}\fi
\expandafter\g@addto@macro\expandafter\tmp\expandafter{\z}%
}%
\g@addto@macro\tmp{,#2}%
\readlist*#1{\tmp}%
}
\makeatother
\begin{document}
\initializedata\mydata{23, 46, Hi mom, foo, bar}
Element 3 is \mydata[3]
\replacedata\mydata[3]{Bye mom}
Element 3 is \mydata[3]
Element 4 is \mydata[4]
\extenddata\mydata{More, data, added}
Element 7 is \mydata[7]
\end{document}