Problem with the macro foreach and the syntax “…”

I have not programmed for a few years and I'm trying to get back to work but I have some problems with updates of "pgf" (perhaps ...) I am having a problem with the syntax "..." that I did not have before. I installed the latest versions of texlive, pgf etc ...

\documentclass{article}
\makeatletter
\def\DrawPolygon(#1,#2){%
\begingroup
\draw(#1)
\foreach \pt in {#2}{--(\pt)}--cycle;%
\endgroup
}
\makeatother

\usepackage{tikz}

\begin{document}
\begin{tikzpicture}
\coordinate (A) at (4,0);
\coordinate (B) at (2,4);
\coordinate (C) at (0,0);
% \DrawPolygon(A,...,C) % error
% now error undefined\ifpgffor@alphabeticsequence \else \ifpgffor@assign@parse \begingroup
% ! File ended while scanning use of \pgffor@@dotscharcheck.
\DrawPolygon(A,B,C)
\end{tikzpicture}
\end{document}


The syntax (A,...,C) gives an error

• \DrawPolygon(A,...,C) is \foreach \pt in {...,C} with no start for the loop, what range did you intend? – David Carlisle Jul 24 at 9:55
• Indeed, the drawing works if one replaces \DrawPolygon(A,...,C) with \DrawPolygon(A,B,...,C) (which is not very different from \DrawPolygon(A,B,C), but one doesn't need to stop at C!) so that the \foreach loop sees a start value. – frougon Jul 24 at 10:49
• @DavidCarlisle The first value is A. I gave a new example with more points and the result is fine. – Alain Matthes Jul 24 at 19:56
• but #2 is the part after the first comma so \foreach \pt in {#2} is \foreach \pt in {...,C} and you do not pass in the first value. that is why oerpli uses #1,#2 in his/her answer, to add the starting value back. – David Carlisle Jul 24 at 19:58
• @AlainMatthes this could never have worked. – David Carlisle Jul 24 at 19:58

Not too much TikZish, but, hey, it works!

\documentclass{article}
\usepackage{tikz}

\def\DrawPolygon(#1){%
\begingroup
\xdef\temppolygon{}%
\foreach \pt in {#1}{\xdef\temppolygon{\temppolygon(\pt)--}}%
\xdef\temppolygon{\endgroup\noexpand\draw\temppolygon cycle}%
\temppolygon;
}

\begin{document}
\begin{tikzpicture}
\coordinate (A) at (4,0);
\coordinate (B) at (2,4);
\coordinate (C) at (0,0);
\DrawPolygon(A,...,C) % error
\end{tikzpicture}
\end{document}


(I changed the example from A,B,C to A,...,E to make some points a bit more clear)

I think the problem is, that the first argument of DrawPolygon(A,...,E) (i.e: A) is consumed and the second argument (#2) is then expanded to (,...,E) instead of the desired A,...,E.

Fix this be either passing the start point as well as a list from the second or end (DrawPolygon(A,B,...,E) or by modifying the definition of your function as follows:

\documentclass{article}
\makeatletter
\def\DrawPolygon(#1,#2){%
\begingroup
\draw(#1)
% change is in this line, {#1,#2} instead of {#2}
\foreach \pt in {#1,#2}{--(\pt)}--cycle;
\endgroup
}
\makeatother
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\coordinate (A) at (4,4);
\coordinate (B) at (0,4);
\coordinate (C) at (0,0);
\coordinate (D) at (4,0);
\coordinate (E) at (7,0);
\DrawPolygon(A,...,E)
\end{tikzpicture}
\end{document}


\foreach does have a loop counter. It can be assigned to a macro with option count. Then, the connecting line can be set in the second and later loop rounds.

\documentclass{article}
\usepackage{tikz}

\def\DrawPolygon(#1){%
\draw
\foreach[count=\pti] \pt in {#1} {
\ifnum\pti>1 --\fi
(\pt)
}
-- cycle
;
}

\begin{document}
\begin{tikzpicture}
\coordinate (A) at (4,4);
\coordinate (B) at (0,4);
\coordinate (C) at (0,0);
\coordinate (D) at (4,0);
\coordinate (E) at (7,0);
\DrawPolygon(A,...,E)
\end{tikzpicture}
\end{document}