关于从 LaTeX3 堆栈检索数据的困惑

关于从 LaTeX3 堆栈检索数据的困惑

我正在尝试在 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设置为datename并且phone按顺序,每个定义仅包含\l_tmpb_tlIE而不是变量的值)。因此你在这里使用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

相关内容