3

I need to have several lists with access by index (array-like). My minimum non-working example follows:

\documentclass{minimal}
\usepackage{etoolbox}

\newcounter{listAcounter}

\newcommand\addToList[3]{%
\stepcounter{#2}%
\csdef{#1\the#2}{#3}
} 

\newcommand\getFromList[2]{%
\csuse{#1#2}
}

\begin{document}

\addToList{listA}{listAcounter}{one}
\addToList{listA}{listAcounter}{two}
\addToList{listA}{listAcounter}{three}

This is element 2 from list A: \getFromList{listA}{2}.

\end{document}

I get from compiling with pdflatex:

! You can't use `the letter l' after \the.
<argument> listA\the l
                  istAcounter
l.17 \addToList{listA}{listAcounter}{one}

How can I fix this code? Why is this wrong?

  • 1
    Welcome to TeX.SX! Perhaps \csdef{#1\csuse{the#2}}{#3} will work. – egreg Feb 24 '15 at 14:04
3

When you type \the#2 you have an already formed token, so this will not be merged into a single command name such as \thelistAcounter. You have to build the name yourself:

\documentclass{article}
\usepackage{etoolbox}

\newcounter{listAcounter}

\newcommand\addToList[3]{%
  \stepcounter{#2}%
  \csdef{#1\csuse{the#2}}{#3}
}

\newcommand\getFromList[2]{%
  \csuse{#1#2}%
}

\begin{document}

\addToList{listA}{listAcounter}{one}
\addToList{listA}{listAcounter}{two}
\addToList{listA}{listAcounter}{three}

This is element 2 from list A: \getFromList{listA}{2}.

\end{document}

Note the % after \csuse{#1#2}.


An easier implementation with expl3, that avoids defining a counter.

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\newList}{m}
 {
  \seq_new:c { l_kees_list_#1_seq }
 }
\NewDocumentCommand{\addToList}{mm}
 {
  \seq_put_right:cn { l_kees_list_#1_seq } { #2 }
 }
\NewDocumentCommand{\getFromList}{mm}
 {
  \seq_item:cn { l_kees_list_#1_seq } { #2 }
 }
\ExplSyntaxOff

\begin{document}

\newList{listA}
\addToList{listA}{one}
\addToList{listA}{two}
\addToList{listA}{three}

This is element 2 from list A: \getFromList{listA}{2}.

\end{document}

enter image description here

  • Why use the % after \csuse{#1#2}? – Marc Kees Feb 24 '15 at 14:10
  • @MarcKees Because it would produce an unwanted space, otherwise. – egreg Feb 24 '15 at 14:11
  • Ok. Thanks! Nice example with expl3. – Marc Kees Feb 24 '15 at 14:18

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.