You need to use the internal defintion of the array
function which does expect its first argument to be a list of braced elements, i.e.
{2}{3}
and
{2}{3}{5}{8}
in your case, which is exactly what the internal defintion of your theFnIDef
functions has to deal with (because that's what you always do with \pgfmathdeclarefunction{<name>}
, you actually define \pgfmath<name>@
).
So
\pgfmatharray@{#1}{<num>}%
will give you the <num>
th element of your parameters by storing it in \pgfmathresult
.
The array@
function itself just loops through all given {…}
until it has reached the one you've asked for.
In the code below, I'm getting the size of the #1
array by using the dim@
function (same rules apply → using the internal one) which also just loops through all elements incrementing a counter everytime it encounters an element.
This is a very inefficient (O(n²)?) way to access all parameters since it involves multiple loops that do nothing with the actual elements.
But for a more efficient (or easier?) way to use all your elements the actual definition of the function is needed.
This code does … nothing but returns the number of parameters (basically just the first call to dim@
) and writes the elements to the log.
It would be better to also do something with the parameters while we're iterating through them anyway. In another answer of mine the last eight of ten parameters get simply forwarded to other functions (that do expect eight arguments). This is done via the \pgfmath@util@…
functions (and a bit expansion control).
There's also a \pgfmathloop
… \repeatpgfmathloop
with its own self-incrementing counter \pgfmathcounter
(not a TeX count!) but that starts at 1, not at 0, so we would need
\pgfmatharray@{#1}{\numexpr\pgfmathcounter-1\relax}%
in the loop (and \the\numexpr\pgfmathcounter-1\relax
in the \typeout
) to get the PGFmath numbering of the array's index.
I've opted instead for the \pgfutil@loop
(which should be equal to the LaTeX \@loop
but is defined across all platforms that can run PGFmath.
Code
\documentclass{article}
\usepackage{pgfmath}
\makeatletter
\pgfmathdeclarefunction{theFnIDef}{...}{%
\begingroup
\pgfmathdim@{#1}%
\let\pgfmatharraysize\pgfmathresult
\typeout{Array #1 has \pgfmatharraysize\space elements.}%
\c@pgf@countb=0
\pgfutil@loop
\pgfmatharray@{#1}{\c@pgf@countb}%
\typeout{Argument No \the\c@pgf@countb\space is \pgfmathresult.}%
\advance\c@pgf@countb by 1
\ifnum\c@pgf@countb<\pgfmatharraysize\relax
\pgfutil@repeat
\let\pgfmathresult\pgfmatharraysize
\pgfmathsmuggle\pgfmathresult % will just return the number of elements
\endgroup
}
\makeatother
\begin{document}
theFnIDef(2,3): \pgfmathprint{theFnIDef(2,3)}
theFnIDef(2,3,5,8): \pgfmathprint{theFnIDef(2,3,5,8)}
\end{document}
Output (Log)
Array {2}{3} has 2 elements.
Argument No 0 is 2.
Argument No 1 is 3.
Array {2}{3}{5}{8} has 4 elements.
Argument No 0 is 2.
Argument No 1 is 3.
Argument No 2 is 5.
Argument No 3 is 8.
\pgfmatharray
expects as its first argument a comma separated list of values. The...
argument specification doesn't return the arguments in commas but in braced groups.latex \makeatletter \ExplSyntaxOn \seq_new:N \myseq \clist_new:N \myclist \cs_set_eq:NN \@seqsetsplit \seq_set_split:Nnn \cs_set_eq:NN \@clistfromseq \clist_set_from_seq:NN \cs_set_eq:NN \@seqcount \seq_count:N \ExplSyntaxOff \pgfmathdeclarefunction{theFnIDef}{...}{% \begingroup \@seqsetsplit \myseq {} {#1} \@clistfromseq \myclist \myseq \edef\bla{\@seqcount \myseq} % \edef\bla{4} \pgfmatharray{\myclist}{1}% \pgfmathsmuggle\pgfmathresult \endgroup } \makeatother
seems to work.