7

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}

enter image description here

8

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.

enter image description here

  • 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
  • 2
    @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
4

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}

enter image description here

3

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

enter image description here

\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
3

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}

enter image description here

1

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
    \advance\c@mycount by -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}

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.