# TikZ: can I get an arbitrary list format for foreach?

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.

-
You can cut the "a lot of work" into a half via going in the wrong direction such as \foreach \x in {{(1,0)--(2,2)},{(3,4)--(2,1)}}{\draw \x;}. This requires 1 pair of braces per two coordinates, but hey, improvement is improvement! :) –  percusse Oct 27 '11 at 23:59

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 ().

-

You can, but you would have to wrap each coordinate in a {} since the \foreach uses the , to separate args:

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


However, I normally tend to define the coordinate first with names, and use:

\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\coordinate (A) at (1,0);
\coordinate (B) at (2,2);
\coordinate (C) at (3,4);
\coordinate (D) at (2,1);

\foreach \pointA/\pointB in {A/B, C/D}{
\draw (\pointA) -- (\pointB);
}
\end{tikzpicture}
\end{document}

-