[Tex/LaTex] TikZ: can I get an arbitrary list format for foreach

foreachtikz-pgf

I'd like very much to define a foreach loop that looks like this:

\foreach \pointA-\pointB in {(1,0)-(2,2),(3,4)-(2,1)}{
    \draw \pointA -- \pointB
}

so that for each couple of points the lines between them would get drawn.

Can I get \foreach to accept this kind of input? Or is there another way to do this? I'm going to define a macro to quickly draw lines between couples of points.

I know I could use / instead of - but then I would also have to wrap the coordinates in { }, which is a lot of work.

Best Answer

You can use / instead of -. You also need to wrap the coordinates in {} (see the comments on this answer by Martin if you wish to know why), then your example would become:

\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\foreach \pointA/\pointB in {{(1,0)}/{(2,2)},{(3,4)}/{(2,1)}}{
  \draw \pointA -- \pointB;
}
\end{tikzpicture}
\end{document}

This can also be extended to more than 2 elements, just add another / \pointC. All of this is treated on page 506 of the Tikz manual.

EDIT Ok, after your edit (better to specify that, otherwise Peter and I look silly ;)), my answer isn't all that great anymore. Basically you can't do what you want due to the same reasons as in the comment I referenced above. You can work around it though. Note: this is just something hacked together quickly, it probably doesn't handle everything great, but it handles your MWE and can probably be extended.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\newcounter{n}
\makeatletter
\def\wrap(#1)#2{%
    \stepcounter{n}%
    \coordinate (\number\value{n}) at (#1);%
    \if#2(%
        \wraprest#2%
    \else\fi%
}
\def\wraprest(#1)#2{%
    \stepcounter{n}%
    \coordinate (\number\value{n}) at (#1);%
    \if#2(% 
        \wrap#2%
    \else\fi%
}
\begin{document}
\begin{tikzpicture}
\wrap(1,0)(2,0)(3,0)(4,0)(5,0)(6,0)(7,0)(8,0)x%
\foreach \pointA in {1,3,...,\number\value{n}}{
    \pgfmathsetmacro{\pointB}{\pointA+1}
  \draw (\pointA) -- (\pointB);
}
\end{tikzpicture}
\makeatother
\end{document}

This uses Peter's method of defining coordinates and using those in the list. First a coordinate is created for each (x,y) and these are numbered, such that lines go from n to n+1 where n is odd. If you want delimiters between pairs those can be added with a slight modification. (The x at the end of the wrap can be anything, just not ().

Related Question