# Macro evaluating number of arguments without limitation

Is it possible to have a macro like this one:

\documentclass{article}
\usepackage{xparse}
\pagestyle{empty}
\ExplSyntaxOn
\NewDocumentCommand{\HowManyArguments}{ oooooooo }
{
\IfNoValueTF {#1} { 0 }{
\IfNoValueTF {#2} { 1 }{
\IfNoValueTF {#3}  { 2 }{
\IfNoValueTF {#4}  { 3 }{
\IfNoValueTF {#5}  { 4 }{
\IfNoValueTF {#6}  { 5 }{
\IfNoValueTF {#7}  { 6 }{
\IfNoValueTF {#8}  { 7 }{ So many }
}
}
}
}
}
}
}
}
\ExplSyntaxOff
\begin{document}

The amount of arguments in this macro is \HowManyArguments[Cake][Chair][Stool][Bicycle] .

\end{document}


Except one that doesn't have limitations, a bit like the \powertower thread, where the result is embedded in the rest every time: How do I typeset a tenfold powering (a tower-of-powers) with LaTeX?

The idea is then to use the first argument of the macro to define the number of arguments.

The reason why I need the "powertower" approach is because of part 2: I want to rotate between colours based on the number of the argument.

Try compiling this:

\documentclass{article}
\usepackage{xparse}
\usepackage{xcolor}
\pagestyle{empty}
\ExplSyntaxOn
\NewDocumentCommand{\HowManyArguments}{ oooooooo }
{
\IfNoValueTF {#1} {}{
\IfNoValueTF {#2} {\textcolor{blue}{#1(}...\textcolor{blue}{)}}{
\IfNoValueTF {#3}  {\textcolor{blue}{#1(}\textcolor{green}{#2(}...\textcolor{green}{)}\textcolor{blue}{)}}{
\IfNoValueTF {#4}  {\textcolor{blue}{#1(}\textcolor{green}{#2(}\textcolor{red}{#3(}...\textcolor{red}{)}\textcolor{green}{)}\textcolor{blue}{)}}{
\IfNoValueTF {#5}  {\textcolor{blue}{#1(}\textcolor{green}{#2(}\textcolor{red}{#3(}\textcolor{blue}{#4(}...\textcolor{blue}{)}\textcolor{red}{)}\textcolor{green}{)}\textcolor{blue}{)}}{
\IfNoValueTF {#6}  {\textcolor{blue}{#1(}\textcolor{green}{#2(}\textcolor{red}{#3(}\textcolor{blue}{#4(}\textcolor{green}{#5(}...\textcolor{green}{)}\textcolor{blue}{)}\textcolor{red}{)}\textcolor{green}{)}\textcolor{blue}{)}}{
\IfNoValueTF {#7}  {\textcolor{blue}{#1(}\textcolor{green}{#2(}\textcolor{red}{#3(}\textcolor{blue}{#4(}\textcolor{green}{#5(}\textcolor{red}{#6(}...\textcolor{red}{)}\textcolor{green}{)}\textcolor{blue}{)}\textcolor{red}{)}\textcolor{green}{)}\textcolor{blue}{)}}{
\IfNoValueTF {#8}  {\textcolor{blue}{#1(}\textcolor{green}{#2(}\textcolor{red}{#3(}\textcolor{blue}{#4(}\textcolor{green}{#5(}\textcolor{red}{#6(}\textcolor{blue}{#7(}...\textcolor{blue}{)}\textcolor{red}{)}\textcolor{green}{)}\textcolor{blue}{)}\textcolor{red}{)}\textcolor{green}{)}\textcolor{blue}{)}}{\textcolor{blue}{#1(}\textcolor{green}{#2(}\textcolor{red}{#3(}\textcolor{blue}{#4(}\textcolor{green}{#5(}\textcolor{red}{#6(}\textcolor{blue}{#7(}\textcolor{green}{#8(}...\textcolor{green}{)}\textcolor{blue}{)}\textcolor{red}{)}\textcolor{green}{)}\textcolor{blue}{)}\textcolor{red}{)}\textcolor{green}{)}\textcolor{blue}{)}}
}
}
}
}
}
}
}
}
\ExplSyntaxOff
\begin{document}

\end{document}


This is the full idea of what I'm trying to build, but without limitations.

-
You could, but you should not. LaTeX tries hard to give commands a consistent interface and the argument forms in LaTeX never depend on the values of of earlier arguments. If you want unlimited arguments use a comma separated list. That is why the syntax for color is \color[named]{red} and \color[rgb]{1,0,0} not \color[rgb]{1}{0}{0} the number of arguments doesn't depend on the colour model even though the logical number of parameters needed does depend on the model. –  David Carlisle May 7 at 14:26

It would be more consistent with the design of LaTeX to use a comma separated list:

\documentclass{article}

\makeatletter
\newcommand\HowManyArguments[1]{{%
\count@\z@
There are \the\count@\ arguments\par
\@for\tmp:=#1\do{(\tmp}%
\@for\tmp:=#1\do{)}}}
\makeatother

\begin{document}

\end{document}


Or with colour

\documentclass{article}

\usepackage{color}
\makeatletter
\newcommand\HowManyArguments[1]{{%
\count@\z@
There are \the\count@\ arguments\par
\@tempcnta\z@
\@for\tmp:=#1\do{%
\textcolor[RGB]{\the\numexpr255*\@tempcnta/(\count@)\relax,
0,
\the\numexpr255-(255*\@tempcnta/(\count@))\relax}%
{\tmp(}}%
\@tempcnta\count@
\@for\tmp:=#1\do{%
\textcolor[RGB]{\the\numexpr255*\@tempcnta/(\count@)\relax,
0,
\the\numexpr255-(255*\@tempcnta/(\count@))\relax}%
{)}%
}}}
\makeatother

\begin{document}

\end{document}

-
Or you could of course use a latex3 comma separated list:-) –  David Carlisle May 7 at 14:52
This looks really nice. Is it possible to use a dynamic color scheme to these? You're not using any \newcounters or anything so I don't think LaTeX keeps track of the number of arguments for reuse in other variables? Or would I have to embed this somewhere in your \@for\tmp:=#1\do{(<somewhere.here>\tmp}%? Alternatively, where can I find some good introductory reading matter to understand what's happening here? –  1010011010 May 7 at 14:56
@1010011010 well as you see the first loop increments a counter each time, if you reset it to 0 and added the advance to each of the loops then \the\count@ will be 1,2,3 at each iteration –  David Carlisle May 7 at 15:10
@1010011010 see edit with arguments fading from blue to red –  David Carlisle May 7 at 15:22
This is 99% what I was looking for. The other 1% consists of the first parentheses (before Lots, and at the end) and the possibility to add colour to the parentheses to stress the idea of nesting. Other than that, definitely amazed. –  1010011010 May 7 at 15:33

An expl3 solution (just to please David). I do the computation only once, by filling two token lists and delivering them.

\documentclass{article}
\usepackage{xparse,xcolor}

\ExplSyntaxOn
\NewDocumentCommand{\HMA}{m}
{
\leavevmode
\group_begin:
\hma_process_args:n { #1 }
\group_end:
}

\seq_new:N \l__hma_args_seq
\tl_new:N \l__hma_opening_tl
\tl_new:N \l__hma_closing_tl
\int_new:N \l__hma_step_int
\int_new:N \l__hma_args_int

\cs_new_protected:Npn \hma_process_args:n #1
{
\seq_set_split:Nnn \l__hma_args_seq { , } { #1 }
\tl_clear:N \l__hma_opening_tl
\tl_set:Nn \l__hma_closing_tl { \dots }
\int_zero:N \l__hma_step_int
\int_set:Nn \l__hma_args_int { \seq_count:N \l__hma_args_seq }
\color[RGB]{0,0,255}
\seq_map_inline:Nn \l__hma_args_seq
{
\int_incr:N \l__hma_step_int
\tl_put_right:Nx \l__hma_opening_tl
{
\exp_not:n { ##1 ( }
\group_begin:
\exp_not:N \color[RGB] { \__hma_set_color: }
}
\tl_put_right:Nn \l__hma_closing_tl { \group_end: ) }
}
\tl_use:N \l__hma_opening_tl \tl_use:N \l__hma_closing_tl
}

\cs_new:Npn \__hma_set_color:
{
\int_eval:n { 255 * \l__hma_step_int / \l__hma_args_int },
0,
\int_eval:n { 255 - ( 255 * \l__hma_step_int / \l__hma_args_int ) }
}

\ExplSyntaxOff

\begin{document}

\end{document}


Just changing one line allows to avoid the dots and use the last item for the innermost parentheses.

\documentclass{article}
\usepackage{xparse,xcolor}

\ExplSyntaxOn
\NewDocumentCommand{\HMA}{m}
{
\leavevmode
\group_begin:
\hma_process_args:n { #1 }
\group_end:
}

\seq_new:N \l__hma_args_seq
\tl_new:N \l__hma_opening_tl
\tl_new:N \l__hma_closing_tl
\int_new:N \l__hma_step_int
\int_new:N \l__hma_args_int

\cs_new_protected:Npn \hma_process_args:n #1
{
\seq_set_split:Nnn \l__hma_args_seq { , } { #1 }
\tl_clear:N \l__hma_opening_tl
\seq_pop_right:NN \l__hma_args_seq \l__hma_closing_tl % <---- CHANGE
\int_zero:N \l__hma_step_int
\int_set:Nn \l__hma_args_int { \seq_count:N \l__hma_args_seq }
\color[RGB]{0,0,255}
\seq_map_inline:Nn \l__hma_args_seq
{
\int_incr:N \l__hma_step_int
\tl_put_right:Nx \l__hma_opening_tl
{
\exp_not:n { ##1 ( }
\group_begin:
\exp_not:N \color[RGB] { \__hma_set_color: }
}
\tl_put_right:Nn \l__hma_closing_tl { \group_end: ) }
}
\tl_use:N \l__hma_opening_tl \tl_use:N \l__hma_closing_tl
}

\cs_new:Npn \__hma_set_color:
{
\int_eval:n { 255 * \l__hma_step_int / \l__hma_args_int },
0,
\int_eval:n { 255 - ( 255 * \l__hma_step_int / \l__hma_args_int ) }
}

\ExplSyntaxOff

\begin{document}

\end{document}


-

To address the OP's desire for something like Lots(of(arguments(in(this(thread))))), I created the macro \groupargs{{}{}{}{}} and give an example.

While I change colors discretely modulo the nesting level (as done in the OP's MWE), any algorithm could be inserted to calculate the color as a function of the nesting level.

\documentclass{article}
\usepackage{xcolor}
\newcounter{argindex}
\newcounter{colindex}
\def\groupargs#1{\def\lparen{}\def\rparen{}\getargsC{#1}%
\setcounter{argindex}{0}\setcounter{colindex}{0}\nextarg}
\def\nextarg{\stepcounter{argindex}\stepcounter{colindex}%
\ifnum\theargindex>\narg\else\lparen%
\ifnum\thecolindex=1\def\mycolor{blue}\else%
\ifnum\thecolindex=2\def\mycolor{green}\else%
\ifnum\thecolindex=3\def\mycolor{red}\setcounter{colindex}{0}%
\fi\fi\fi%
\def\lparen{(}%
\textcolor{\mycolor}{\csname arg\romannumeral\theargindex\endcsname%
{\def\rparen{)}\nextarg}}\rparen\fi%
}
\begin{document}
\groupargs{Mandatory Argument What Have {You Indeed} Done ...}
\end{document}


-
I'll edit the OP to clarify a bit more. –  1010011010 May 7 at 14:30
@1010011010 Does my revision cove closer to what you seek? –  Steven B. Segletes May 7 at 14:52
It does come closer, but how do I do that nesting thing ? I think what your solution does is pretty much just counting the number of arguments seperated by spaces or curly braces... How do I get from that to the text in braces thing? –  1010011010 May 7 at 14:59
@1010011010 I think I resolve the issue. –  Steven B. Segletes May 7 at 15:31
The output is easily controllable and the code is accessible to understand... I like this solution. :-) –  1010011010 May 7 at 15:34