2

I need to pass 1,2,3,...,\Num to the variable list argument of the \DefineArrayVar command from the forarray package. If I pass it manually, everything works fine, but, when I pass a command instead, \DefineArrayVar gets confused and fails.

Here is my MWE:

\documentclass{article}

\usepackage{forloop}
\usepackage{forarray}

\newcommand{\Num}{4}

\newcounter{ct}
\setcounter{ct}{1}

\newcommand{\test}{%
    \forloop{ct}{1}{\value{ct}<\Num}{\thect,}\thect%
}

\DefineArrayVar{ArrayName}{@}
{,}{1,2,3,4} % <---- This works 
% {,}{\test} % <---- This doesn't work
% {,}{\forloop{ct}{1}{\value{ct} < \Num}{\thect,}\thect} % <---- This doesn't work either
{,}{4cm,0.8cm,0.6cm,1.6cm}

% This doesn't work
% \expandafter\DefineArrayVar\expandafter{ArrayName}{@}{,}{\test}{,}{4cm,0.8cm,0.6cm,1.6cm}

\DefineArrayDefault{,}{@}{2}{2}{ArrayName}

\begin{document}

\test % To see what 'forloop' is generating

\ArrayName % Proof that it's working (must print "0.8cm")

\end{document}

Based on this answer and this answer (which are very much related to my problem), I also tried to use (separately) \expandafter or \edef like so:

    \expandafter\DefineArrayVar\expandafter{ArrayName}{@}{,}{\test}{,}{4cm,0.8cm,0.6cm,1.6cm}
    \edef\test{\unexpanded\expandafter{\forloop{ct}{1}{\value{ct}<\Num}{\thect,}\thect}}

but it didn't work.

Well, since I do not understand big picture of what I am doing, I can't go further. How do I make it work?

2 Answers 2

1

Would you consider a different package to store and recall arrays?

listofitems supports array constructs and is nice because its array storage technique is fully expandable (that is to say, once read, the recall of array elements is fully expandable).

It also supports multi-dimensional arrays.

\documentclass{article}
\usepackage{listofitems}
\begin{document}
\readlist*\ArrayName{4cm,0.8cm,0.6cm,1.6cm}

ArrayName[2] is \ArrayName[2]

The array has \listlen\ArrayName[] elements.

The whole array is \foreachitem\z\in\ArrayName[]{\ifnum\zcnt=1\else,\fi\z}
\end{document}

enter image description here

2
  • Much easier, thanks!!! I will try to modify my whole document to test it beyond my MWE. I'm still curious about how would I pass a command to \DefineArrayVar's argument though :)
    – Leone
    Mar 17, 2021 at 20:04
  • @Leone Thanks. I'll also give your original problem some thought. Mar 17, 2021 at 20:25
1

The forloop and forarray packages are really outdated. With expl3 you get much more with enhanced flexibility.

Your needs can be fulfilled with “one-liners”.

\documentclass{article}

\ExplSyntaxOn

\NewDocumentCommand{\definelist}{mm}
 {% #1 = list name, #2 = items
  \clist_clear_new:c { l_leone_list_#1_clist }
  \clist_set:cn  { l_leone_list_#1_clist } { #2 }
 }
\NewExpandableDocumentCommand{\getlistitem}{mm}
 {% #1 = list name, #2 = number of item to retrieve
  \clist_item:cn  { l_leone_list_#1_clist } { #2 }
 }
\NewExpandableDocumentCommand{\getlistlen}{m}
 {% #1 = list name
  \clist_count:c  { l_leone_list_#1_clist }
 }

\ExplSyntaxOff

\definelist{ArrayName}{4cm,0.8cm,0.6cm,1.6cm}

\begin{document}

\getlistitem{ArrayName}{4}

X\makebox[\getlistitem{ArrayName}{4}][s]{a\hfil a}X

X\hspace*{1.6cm}X

\end{document}

The last example shows that you can use \getlistitem in any situation where a length is needed, since the list contains lengths.

enter image description here

3
  • Good one too! I actually got close when found this answer of yours, but I didn't know much about expl3 to get things working, because I need to access data with a counter, which I can do now with this answer, thanks! Just an observation: I had to put \usepackage{xparse} in preamble, did you forget it?
    – Leone
    Mar 17, 2021 at 23:47
  • Also, to know that a package is outdated do you see CTAN's timeline? Or is there a place where I can find this information and avoid the old packages? I've found this question, but could find neither forloop nor forarray on its answers.
    – Leone
    Mar 18, 2021 at 0:25
  • 1
    @Leone Outdated is an opinion of mine, but you can see that they’ve been unmaintained for a long time. If you have an up-to-date TeX distribution, xparse is not needed.
    – egreg
    Mar 18, 2021 at 8:11

You must log in to answer this question.

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