6

I'm trying to perform a very simple processing task in LaTeX3, namely, defining a series of functions named in terms of the token lists retrieved from a clist as a stack. Each function will set accordingly a token list variable with a name determined by the stack item, too.

My code is as follows:

\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}

I was expecting to get a three-line (well, three single-line paragraphs) page with thedate thename thephone as text, but I only get the last one. What is it that I'm doing wrong? I've tried also with \tl_use:N \l_tmpb_tl in the code, but to no avail.

1 Answer 1

6

To be honest, I would tackle this in a much less complex way, using a mapping:

\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}

Notice that in the above I've used \cs_new:cpx to expand as far as possible the 'setting' functions: this saves a little complexity later.


Taking the original formulation, your problem is actually expansion. In

\cs_gset:cpn { my_ \l_tmpb_tl :n } #1
 {
   \tl_gset:cn  
    { g_my_ \l_tmpb_tl _tl } {#1} %{ \tl_to_str:n {#1} }
 }

you set the command to expand exactly to the tokens you've given. Thus while at the point of definition you have \l_tmpb_tl set to date, name and phone sequentially, each definition just contains \l_tmpb_tl (i.e. not the value of the variable). Thus you have to use an x-type approach here (in my alternative you don't actually have to, although I think it's cleaner). Minimal change is therefore

\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}

although I'd still go with 'pre-converting' the token list name using \exp_not:c.

1
  • I had not taken the time yet to read the `ìnterface3`` doc about mappings to token lists. Your answer makes for further motivation to amend this mistake of mine as soon as possible.
    – Marcos
    Sep 6, 2013 at 22:10

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .