3

I'm trying to define a LIST using \greadlist from the listofitems package. I would like to give a dynamic name to that list, something like LISTN, where N depends on a counter.

I tried something like

\documentclass{amsart}
\usepackage{listofitems}

\begin{document}
\newcounter{num}\setcounter{num}{1}
\setsepchar{,}
\greadlist*{\expandafter\noexpand\csname LIST\roman{num}\endcsname}{a,b,c}
\end{document}

But this just make LaTeX not stop running...

3 Answers 3

3

Expand the \csname before invoking the \greadlist.

\documentclass{amsart}
\usepackage{listofitems}

\begin{document}
\newcounter{num}\setcounter{num}{4}
\setsepchar{,}
\expandafter\greadlist\expandafter*\csname 
  LIST\roman{num}\endcsname{a,b,c}

\LISTiv[2]
\end{document}

enter image description here

4

You can define your own variation of the commands.

\documentclass{amsart}
\usepackage{listofitems}

\ExplSyntaxOn
\NewDocumentCommand{\readnamedlist}{smm}
 {
  \IfBooleanTF{#1}
   {\exp_args:NNc \readlist*{#2}{#3}} % * variant
   {\exp_args:Nc \readlist{#2}{#3}}
 }
\NewDocumentCommand{\greadnamedlist}{smm}
 {
  \IfBooleanTF{#1}
   {\exp_args:NNc \greadlist*{#2}{#3}} % *-variant
   {\exp_args:Nc \greadlist{#2}{#3}}
 }
\ExplSyntaxOff

\begin{document}
\newcounter{num}\setcounter{num}{1}
\setsepchar{,}

\greadnamedlist*{LIST\roman{num}}{a,b,c}

\LISTi[1],\LISTi[2],\LISTi[3]

\stepcounter{num}

\readnamedlist{LIST\roman{num}}{d,e,f}

\LISTii[1],\LISTii[2],\LISTii[3]

\end{document}

enter image description here

What does \exp_args:Nc do? It jumps over the next token and applies \csname...\endcsname to the contents of the following braced group. Similarly \exp_args:NNc that jumps over two tokens.

If you prefer a “classical” implementation, here's an argument reversing procedure.

\documentclass{amsart}
\usepackage{listofitems}

\makeatletter
\newcommand{\readnamedlist}{%
  \@ifstar{\@readnamedlist{\readlist*}}{\@readnamedlist{\readlist}}%
}
\newcommand{\greadnamedlist}{%
  \@ifstar{\@readnamedlist{\greadlist*}}{\@readnamedlist{\greadlist}}%
}
\newcommand{\@readnamedlist}[2]{%
  \expandafter\@@readnamedlist\csname #2\endcsname{#1}%
}
\newcommand{\@@readnamedlist}[2]{#2#1}
\makeatother

\begin{document}
\newcounter{num}\setcounter{num}{1}
\setsepchar{,}

\greadnamedlist*{LIST\roman{num}}{a,b,c}

\LISTi[1],\LISTi[2],\LISTi[3]

\stepcounter{num}

\readnamedlist{LIST\roman{num}}{d,e,f}

\LISTii[1],\LISTii[2],\LISTii[3]

\end{document}
1
  • @UlrichDiez Maybe, but I find this clearer and more in line with expl3 guidelines.
    – egreg
    Apr 30 at 20:49
2

I think those days expl3-solutions are state of the art, so I'd in any case prefer egreg's solution.

The following is just for exhibiting the technique of exchanging arguments after expansion:

\documentclass{amsart}
\usepackage{listofitems}

\newcommand\PassFirstToSecond[2]{#2{#1}}%

\begin{document}
\newcounter{num}\setcounter{num}{1}
\setsepchar{,}
\expandafter\PassFirstToSecond\expandafter{\csname LIST\roman{num}\endcsname}{\greadlist*}{a,b,c}
\end{document}

Alternatively a macro
\CsNameToCsToken⟨stuff not in braces⟩{NameOfCs}

⟨stuff not in braces⟩\NameOfCs
can help avoiding/hiding \expandafter...\csname..\endcsname-orgies:

\documentclass{amsart}
\usepackage{listofitems}

%%===============================================================================
%% Obtain control sequence token from name of control sequence token:
%%===============================================================================
%% \CsNameToCsToken<stuff not in braces>{NameOfCs}
%% ->  <stuff not in braces>\NameOfCs
%% (<stuff not in braces> may be empty.)
\csname @ifdefinable\endcsname\CsNameToCsToken{%
  \long\def\CsNameToCsToken#1#{\InnerCsNameToCsToken{#1}}%
}%
\newcommand\InnerCsNameToCsToken[2]{%
  \expandafter\exchange\expandafter{\csname#2\endcsname}{#1}%
}%
\newcommand\exchange[2]{#2#1}%
%%===============================================================================

\begin{document}
\newcounter{num}\setcounter{num}{1}
\setsepchar{,}
\CsNameToCsToken\greadlist*{LIST\roman{num}}{a,b,c}
\end{document}

(If it were implemented there, in expl3 the name of \CsNameToCsToken would probably be something like \exp_args:wc or whatever argument-type you use instead of w for an argument which must not be nested in braces but is delimited by a left brace {.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.