\documentclass[a4paper]{article}
\makeatletter
\def\MakeArray#1#2{% #1: macro that expands to the list, #2: final number
\toks@={1}\@tempcnta=\@ne
\loop\ifnum\@tempcnta<#2\relax
\advance\@tempcnta\@ne
\toks@=\expandafter{\the\expandafter\toks@\expandafter,\number\@tempcnta}%
\repeat
\edef#1{{\the\toks@}}%
}
\makeatother
\begin{document}
\MakeArray\MyArray{4}
\texttt{\meaning\MyArray} % should print macro:->{1,2,3,4}
\end{document}
Doing this with \foreach
is (almost) impossible, because \edef
doesn't perform assignments, only expansion, and \foreach
does tens of assignments to work. You can see from the code that the \edef
I do is just the last thing of the ">1" case (there's no check that the input is sensible, so be careful to say something like \MakeArray\MyArray{x}
that would die horribly.
The idea is simple: I put 1
in the token register \toks@
and then loop until the scratch counter \@tempcnta
reaches the value #2
, augmenting the tokens in \toks@
.
The curious line
\toks@=\expandafter{\the\expandafter\toks@\expandafter,\number\@tempcnta}
deserves an explanation. After \toks@=
TeX wants to see an open brace (after expansion), so it expands the following token, which is \expandafter
; good, this expands after the open brace and the token it finds is \the
. Well, \the
needs to see some specific kinds of (unexpandable) tokens after it, so it expands in order to see what really comes along; the \expandafter
expands the following \expandafter
which finally expands \number
! Now \the
performs its duty, in this case to "free" the contents of \toks@
. So, if \@tempcnta=2
, TeX is presented with
\toks@={1,2}
exactly what we needed.
A different method, which is much more easily customizable, is using expl3
.
\documentclass[a4paper]{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\MakeArray}{ m m }
{% #1: macro that expands to the list, #2: final number
\jeremie_make_array:n { #2 }
\tl_set_eq:NN #1 \l__jeremie_array_temp_tl
}
\tl_new:N \l__jeremie_array_temp_tl
\seq_new:N \l__jeremie_array_temp_seq
\cs_new_protected:Npn \jeremie_make_array:n #1
{
\seq_clear:N \l__jeremie_array_temp_seq
\int_step_inline:nnnn { 1 } { 1 } { #1 }
{
\seq_put_right:Nn \l__jeremie_array_temp_seq { ##1 }
}
\tl_set:Nx \l__jeremie_array_temp_tl { \seq_use:Nn \l__jeremie_array_temp_seq { , } }
}
\ExplSyntaxOff
\begin{document}
\MakeArray\MyArray{4}
\texttt{\meaning\MyArray} % should print macro:->{1,2,3,4}
\MakeArray\MyArray{1}
\texttt{\meaning\MyArray} % should print macro:->{1}
\MakeArray\MyArray{0}
\texttt{\meaning\MyArray} % should print macro:->
\end{document}
