![关于从 LaTeX3 堆栈检索数据的困惑](https://linux22.com/image/274935/%E5%85%B3%E4%BA%8E%E4%BB%8E%20LaTeX3%20%E5%A0%86%E6%A0%88%E6%A3%80%E7%B4%A2%E6%95%B0%E6%8D%AE%E7%9A%84%E5%9B%B0%E6%83%91.png)
我正在尝试在 LaTeX3 中执行一个非常简单的处理任务,即定义一系列以从堆栈中检索到的标记列表命名的函数clist
。每个函数都会相应地设置一个标记列表变量,其名称也由堆栈项决定。
我的代码如下:
\RequirePackage{expl3}
\documentclass{memoir}
\ExplSyntaxOn
\clist_new:N \l_my_clist
\clist_gset:Nn \l_my_clist {date,name,phone}
\bool_do_while:nn
{ ! \clist_if_empty_p:N \l_my_clist }
{
\clist_pop:NN \l_my_clist \l_tmpb_tl
\tl_new:c { g_my_ \l_tmpb_tl _tl }
\cs_gset:cpn { my_ \l_tmpb_tl :n } #1
{
\tl_gset:cn
{ g_my_ \l_tmpb_tl _tl } {#1} %{ \tl_to_str:n {#1} }
}
}
\my_date:n {the date}
\my_name:n {the name}
\my_phone:n {the phone}
\AtBeginDocument
{
\g_my_date_tl\par
\g_my_name_tl\par
\g_my_phone_tl
}
\ExplSyntaxOff
\begin{document}
\end{document}
我原本希望得到一个包含三行(好吧,三个单行段落)thedate
thename
thephone
文本的页面,但我只得到了最后一行。我做错了什么?我也尝试过使用\tl_use:N \l_tmpb_tl
代码,但无济于事。
答案1
老实说,我会用一种不太复杂的方法来解决这个问题,使用映射:
\RequirePackage{expl3}
\documentclass{memoir}
\ExplSyntaxOn
\clist_map_inline:nn { date , name , phone }
{
\tl_new:c { g_my_ #1 _tl }
\cs_new:cpx { my_ #1 :n } ##1
{ \tl_gset:Nn \exp_not:c { g_my_ #1 _tl } {##1} }
}
\my_date:n { the~date }
\my_name:n { the~name }
\my_phone:n { the~phone }
\AtBeginDocument
{
\g_my_date_tl
\c_space_tl
\g_my_name_tl
\c_space_tl
\g_my_phone_tl
}
\ExplSyntaxOff
\begin{document}
\end{document}
请注意,在上面我\cs_new:cpx
尽可能地扩展了“设置”功能:这可以节省以后的一点复杂性。
按照原来的公式,你的问题实际上是扩展。在
\cs_gset:cpn { my_ \l_tmpb_tl :n } #1
{
\tl_gset:cn
{ g_my_ \l_tmpb_tl _tl } {#1} %{ \tl_to_str:n {#1} }
}
您将命令设置为精确扩展为您给出的标记。因此,虽然在定义点您已 \l_tmpb_tl
设置为date
,name
并且phone
按顺序,每个定义仅包含\l_tmpb_tl
(IE而不是变量的值)。因此你有在这里使用x
-type 方法(在我的替代方案中,你实际上不必这样做,尽管我认为它更简洁)。因此,最小的变化是
\RequirePackage{expl3}
\documentclass{memoir}
\ExplSyntaxOn
\clist_new:N \l_my_clist
\clist_set:Nn \l_my_clist { date , name , phone }
\bool_do_while:nn
{ ! \clist_if_empty_p:N \l_my_clist }
{
\clist_pop:NN \l_my_clist \l_tmpb_tl
\tl_new:c { g_my_ \l_tmpb_tl _tl }
\cs_gset:cpx { my_ \l_tmpb_tl :n } #1
{
\tl_gset:cn
{ g_my_ \l_tmpb_tl _tl } {#1} %{ \tl_to_str:n {#1} }
}
}
\my_date:n {the date}
\my_name:n {the name}
\my_phone:n {the phone}
\AtBeginDocument
{
\g_my_date_tl
\g_my_name_tl
\g_my_phone_tl
}
\ExplSyntaxOff
\begin{document}
\end{document}
尽管我仍然会使用来“预转换”令牌列表名称\exp_not:c
。