samcarter
I am trying to sequentially add elements to lists, which have the format `{word}{word}{word}` (they are ultimately for a pgf random list, which requires this format).
In the simplified example below, elements are either added to `\lista` or `\listb`, depending on the optional argument of the `\ini` macro.
Currently, I'm testing if the argument is either `a` or `b` and then add the element to the list using the hard coded name of the list:
```
\documentclass{article}
\def\lista{}
\def\listb{}
\def\atext{a}
\def\btext{b}
\ExplSyntaxOn
\NewDocumentCommand{\ini}{om}{
\def\tmp{#1}
\ifx\atext\tmp
\tl_put_right:Nn \lista { {#2} }
\fi
\ifx\btext\tmp
\tl_put_right:Nn \listb { {#2} }
\fi
}
\ExplSyntaxOff
\ini[a]{tophat}
\ini[b]{book}
\ini[b]{signpost}
\begin{document}
\lista
\listb
\end{document}
```
I'm wondering if there isn't an easier way in which the list name can be generated from the optional argument?
I tried some approaches with `\csname ...\endcsname` and friends, but run into errors like
```
! File ended while scanning text of \__kernel_exp_not:w.
<inserted text>
}
<*> document.tex
```
Top Answer
frougon
You can simply use `\tl_put_right:cn`. The second argument, of type `n`, is a “normal”, braced-enclosed argument; so it is not subjet to any special treatment. The first argument, of type `c`, is subject to `\csname ... \endcsname` before being passed to the base form `\tl_put_right:Nn`, which is precisely what you want. So, you only need this:
```
\NewDocumentCommand { \ini } { O{a} m }
{
\tl_put_right:cn { list#1 } { {#2} }
}
```
Not sure if you really want the first argument of `\ini` to be optional; in any case, it *needs* a value, so I gave it a default value here. If you want the default value to be empty, use `O{}` for its argument specifier.
We can add a check to abort with an error message in case the list macro doesn't already exist, which gives the following code:
```
\documentclass{article}
\ExplSyntaxOn
\msg_new:nnn { mypkg } { no-such-list }
{ Can't~ add~ to~ non-existent~ list~ '#1'. }
\NewDocumentCommand { \ini } { O{a} m }
{
\tl_if_exist:cTF { list#1 }
{
\tl_put_right:cn { list#1 } { {#2} }
}
{
\msg_error:nnn { mypkg } { no-such-list } {#1}
}
}
% Iterates over items of a {token}{list}{like}{this} using the specified
% template.
\cs_new_eq:NN \myPrintList \tl_map_inline:Nn
\ExplSyntaxOff
\def\lista{}
\def\listb{}
\ini[a]{tophat}
\ini{default list is a}
\ini[b]{book}
\ini[b]{signpost}
\begin{document}
\lista \par
\myPrintList{\lista}{'#1' }
\medskip
\listb \par
\myPrintList{\listb}{'#1' }
\end{document}
```
![image.png](/image?hash=aeada8ebbff1cef873b7043527705762ab11664ca37fa59ac8128f3d206e9b26)
If you don't want the last separator in the output of `\myPrintList`, consider switching to `seq` variables and using `\seq_use:Nn` or `\seq_use:Nnnn`. But apparently, you're not going to use the lists this way.