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 learn \foreach in TikZ and I am confused because of all the errors I get. Here is a code sample I tried that gave me:

ForeachEvaluateTest.tex:0:File ended while scanning use of \pgffor@stripcontext
\documentclass{article}
\usepackage{tikz}

\begin{document} 
 \pgfmathsetmacro{\dx}{5}
 \pgfmathsetmacro{\offx}{2}

 \begin{tikzpicture}
  \pgfmathsetmacro{\endi}{\offx+\dx}
  \pgfmathsetmacro{\starti}{\offx}

  \foreach \i [evaluate=\i] in {\starti,...+1,\endi}
  {
   \draw (\i,0) -- (\i,1);
  }
 \end{tikzpicture}    
\end{document}

I manage to fix this by a strange modification which can not possibly be the best way to fix it.

\documentclass{article}
\usepackage{tikz}

\begin{document} 
 \pgfmathsetmacro{\dx}{5}
 \pgfmathsetmacro{\offx}{2}

 \begin{tikzpicture}
  \pgfmathsetmacro{\endi}{\offx+\dx-1}
  \pgfmathsetmacro{\starti}{\offx-1}

  \foreach \i [evaluate=\i] in {\starti+1,...+1,\endi+1}
  {
   \draw (\i,0) -- (\i,1);
  }
 \end{tikzpicture}    
\end{document}

Any pointers to why this makes a difference?

share|improve this question
    
Welcome to TeX.SX! A tip: You can use backticks ` to mark your inline code as I did in my edit. –  Tobi Nov 4 '13 at 11:31
2  
the ... notaion is taken literally. so whatever is around the ..., is stripped from the other entries too. so that the pattern matches. what you did is the way to go. –  percusse Nov 4 '13 at 11:38
1  
Or, if you want to avoid having sums in the list, this is another possibility: \foreach \i [evaluate=\i as \j using int(\i+1)] in {\starti,...,\endi} { \draw (\j,0) -- (\j,1); } –  Claudio Fiandrino Nov 4 '13 at 11:43

1 Answer 1

up vote 6 down vote accepted

See p505 of the TikZ/PGF manual:

A final special case for the ... statement is contextual replacement. If the ... is used in some context, for example, sin(...), this context will be interpreted correctly, provided that the list items prior to the ... statement have exactly the same pattern, except that, instead of dots, they have a number or a character: \foreach \x in {2^1,2^...,2^7} {$\x$, } yields 21, 22, 23, 24, 25, 26, 27, [...]\foreach \x in {A_1,..._1,H_1} {$\x$, } yields A1, B1, C1, D1, E1, F1, G1, H1.

Your first approach cannot work because you use the ... notation, but the list elements have no common pattern. No contextual replacement can take place there.

Your second approach works because all elements in your list end with +1. That's a pattern that pgffor recognises, and contextual replacement can take place in that case. pgffor fills in the missing values by "replacing" \starti+1,...+1,\endi+1 by the comma-separated list composed of \starti+1, \starti+1+1, \starti+2+1, ..., \endi+1.

However, that second approach involves subtracting 1 in the definition of \starti and \endi, only to add 1 in each element of the list. That's a rather roundabout way of doing things. A more straightforward approach, in my opinion, is to define a macro for the second element in the list:

\documentclass{article}
\usepackage{tikz}

\begin{document} 
 \pgfmathsetmacro{\dx}{5}
 \pgfmathsetmacro{\offx}{2}

 \begin{tikzpicture}
  \pgfmathsetmacro\starti{\offx}
  \pgfmathsetmacro\secondi{\starti+1}
  \pgfmathsetmacro\endi{\offx+\dx}

  \foreach \i in {\starti,\secondi,...,\endi}
  {
   \draw (\i,0) -- (\i,1);
  }
 \end{tikzpicture}    
\end{document}

Refer to section 56 of the manual for more details on \foreach.

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.