Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I am trying to make a "for loop" that will iterate the variable reaches 1. However, none of the "for loops" I have found in the Internet works.

These files will be distributed to other people and thus it would help if we only stick to the default packages. In this case, I'm using the ifthen package.

\newcommand{\displayauthors}[1]
{
\newcounter{blargh}
\setcounter{blargh}{#1}
\ifthenelse{#1 = 0}{

}{
\the\value{blargh}
\displayauthors{\value{blargh}}
}

This command is error-free. However, when I run

\displayauthors{2}

LaTeX complains that

Command \c@blargh already defined.

What is causing this and how do I fix this?

share|improve this question
1  
Not related to your specific problem but you and your colleagues who are working on the same files might be interested to read: Why is the ifthen package obsolete? –  hpesoj626 Dec 30 '12 at 3:02

3 Answers 3

up vote 19 down vote accepted

The following solution doesn't need any package nor any counter, is much faster, resolves tail recursion, is expandable, and deals with the trailing/last comma (,).

\documentclass{article}
\def\displayauthors#1{%
  \ifnum#1>0 #1\ifnum\numexpr#1-1>0, \fi
    \expandafter\displayauthors\expandafter{\number\numexpr#1-1\expandafter}%
  \fi
}
\begin{document}
\displayauthors{10}

\edef\x{\displayauthors{10}}\x
\end{document} 
share|improve this answer
2  
+1 that's what I'd do, but I thought I'd keep my answer closer to the MWE to show what was wrong with the original code, rather than just replace all of it. Good to show this alternative though. –  David Carlisle Dec 30 '12 at 3:37
    
Hey thanks. That seems to work. May I know the logic behind this? I don't know what \displayauthors#1 does, among other things. Does anyone have a good source I can read? –  guissmo Dec 31 '12 at 6:19
1  
"The Tex Book" by D.E. Knuth. –  Ahmed Musa Jan 2 '13 at 17:03

Move

\newcounter{blargh}

out of the macro body and place it before the definition. You do not want to allocate a new register on each use, each loop should use the same register which is allocated once at the start.


Also you need to decrement the counter and a few % at ends of lines

enter image description here

\documentclass{article}
\usepackage{ifthen}
\newcounter{blargh}

\newcommand{\displayauthors}[1]
{%
\setcounter{blargh}{#1}%
\ifthenelse{#1 = 0}{%
}{%
\theblargh, %
\addtocounter{blargh}{-1}%
\displayauthors{\value{blargh}}%
}}

\begin{document}

\displayauthors{10}

\end{document}
share|improve this answer

You mention not finding any success with a for loop. Here's one option:

enter image description here

\documentclass{article}
\usepackage{multido}% http://ctan.org/pkg/multido
\newcommand{\displaynums}[1]{%
  \ifnum#1<0\else\multido{\i=#1+-1}{#1}{\i\ }\unskip\fi}
\begin{document}
4: \displaynums{4}\par
12: \displaynums{12}\par
1: \displaynums{1}\par
0: \displaynums{0}\par
-7: \displaynums{-7}
\end{document}

multido provides an iterative/sequential interface to variables:

\multido{<var>=<start>+<increment>}{<times>}{<stuff>}

There is some difference between real/integer usage. See the multido documentation for more information.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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