# Loop over an optional argument

I'd like to use the command \foo with an optional argument to step and print the counter value iterated according to the number passed.

So, for example, \foo[5] should step the counter 5 times, one by one.

(!) Note that it is not the same as \stepcounter{}{5}.

MWE

\documentclass{report}

\newcounter{mycount}
\setcounter{mycount}{0}
\newcommand{\foo}{\stepcounter{mycount}counter is \textbf{\themycount}}

\begin{document}
first use: \foo

second use: \foo

now using with option to iterate: \foo[2]

\medskip

\textit{desired output from line above should be:}

\medskip

now using with option to iterate: counter is \textbf{3,4}

\end{document}


With expl3 it's just a few lines.

\documentclass{report}
\usepackage{xparse}

\newcounter{mycount}
\setcounter{mycount}{0}

\ExplSyntaxOn
\NewDocumentCommand{\foo}{O{1}}
{
\int_compare:nT { #1 > 0 }
{
\int_compare:nTF { #1 = 1 } {counter~is} {counters~are}~
\stepcounter{mycount}
\textbf{\themycount}
\prg_replicate:nn { #1 - 1 } {,\stepcounter{mycount}\textbf{\themycount}}
}
}
\ExplSyntaxOff

\begin{document}
first use: \foo

second use: \foo

now using with option to iterate: \foo[2]

now using with option to iterate: counters are \textbf{3,4}

\foo[5]

\end{document}


The trick is to do the first iteration and then proceed again adding first a comma.

If the number passed is zero or less nothing happens.

• Exactly what I need. – Sigur Jan 18 at 23:56
• Do you think is it possible to change the text also if there is argument? I mean, to print counters are 5,6,7,8 for example. – Sigur Jan 18 at 23:57
• @Sigur Your wish is my command. Updated. – egreg Jan 19 at 0:03
• Oh, I think I should learn about \NewDocumentCommand as soon as possible. Amazing and powerful. – Sigur Jan 19 at 0:08

Here is short code with multido, xparse and etoolbox:

\documentclass{report}
\usepackage{multido}
\usepackage{xparse, etoolbox}
\newcounter{mycount}
\setcounter{mycount}{0}
\NewDocumentCommand{\foo}{O{1}}{counter is \multido{\i=1+1}{#1}{\stepcounter{mycount}\textbf{\themycount}\ifnumless{\multidocount}{#1}{,\,}{.}}}

\begin{document}

first use: \foo

second use: \foo

now using with option to iterate: \foo[5]

\end{document}


Here is an approach using multido for looping and a delayed delimiter definition:

\documentclass{article}

\usepackage{multido}

\newcounter{mycount}

\newcommand{\foo}[1][1]{%
counter%
\ifnum#1>1\relax s are\else \space is\fi
\space
% https://tex.stackexchange.com/a/89187/5764
\def\itemdelim{\unskip\space\def\itemdelim{,\space}}% Item delimiter delayed by one cycle
{\bfseries\multido{\i=1+1}{#1}{\itemdelim \stepcounter{mycount}\themycount}}%
}

\begin{document}

first use: \foo

second use: \foo

now using with option to iterate: \foo[2]

\medskip

\textit{desired output from line above should be:}

\medskip

now using with option to iterate: counters are \textbf{3, 4}

\end{document}

• This solution is more understandable to me... but I had never done it by myself. Very nice. – Sigur Jan 19 at 0:11

With pgffor it is even less lines.

\documentclass{report}
\usepackage{pgffor}
\newcounter{mycount}
\setcounter{mycount}{0}
\newcommand{\foo}[1][1]{counter is \foreach \X [count=\Y] in
{1,...,#1}{\stepcounter{mycount}%
\textbf{\themycount}\ifnum\Y=#1%
\else%
,\fi}}

\begin{document}
first use: \foo

second use: \foo

now using with option to iterate: \foo[2]

\end{document}


A bit more code but without additional packages:

\documentclass{report}

\newcounter{mycount}
\setcounter{mycount}{0}

\newcommand\Exchange[2]{#2#1}%
\newcommand{\foo}[1][1]{\fooloop{#1}{}{counter value is}}
\makeatletter
\newcommand{\fooloop}[3]{%
\ifnum#1>0 \stepcounter{mycount}\fi
\ifnum#1>1 \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{%
\begingroup
\protected@edef\@tempa{\themycount}%
\c@mycount=#1\relax
\expandafter\endgroup
\expandafter\fooloop\expandafter
{\number\expandafter\c@mycount\expandafter}\expandafter
{\romannumeral0\expandafter\Exchange\expandafter{\@tempa}{ #2}, }%
{counter values are}%
}{%
#3 \textbf{#2\themycount}%
}%
}%
\makeatother

\begin{document}
first use: \foo

second use: \foo

now using with option to iterate: \foo[4]

\medskip

\textit{desired output from line above should be:}

\medskip

now using with option to iterate: counter values are \textbf{3, 4, 5, 6}

\medskip

now using with option to iterate 0 times---counter is unchanged and displayed: \foo[0]

\medskip

now using with option to iterate -1 times---counter is unchanged and displayed: \foo[-1]

\end{document}