Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Foreach fails over pairs of coordinates #1354

Open
memeplex opened this issue Jul 31, 2024 · 1 comment
Open

Foreach fails over pairs of coordinates #1354

memeplex opened this issue Jul 31, 2024 · 1 comment

Comments

@memeplex
Copy link

Brief outline of the bug

I've asked it in https://tex.stackexchange.com/questions/723558/why-is-foreach-over-pairs-of-coordinates-failing but I think it's a bug. Or a couple of bugs.

It's all explained there, but in brief, take this working example:

\documentclass[border=10pt,tikz]{standalone}
\begin{document}
\begin{tikzpicture}
  \foreach \x / \y in {(2.0,3.0)/{(2.0,5.0)}, (2.0,3.0)/{(2.0,5.0)}, (2.0,3.0)/{(2.0,5.0)}}
  {
    \draw \x -- \y;
  }
\end{tikzpicture}
\end{document}

And modify it in two ways:

  • Add a newline after the list closing brace, then Package tikz: Cannot parse this coordinate
  • Use to or edge instead of --, then
    Package pgf: No shape named `' is known.
    Package tikz: (, +, coordinate, pic, or node expected.
    

Minimal working example (MWE)

\documentclass[border=10pt,tikz]{standalone}
\begin{document}
\begin{tikzpicture}
  \foreach \x / \y in {(2.0,3.0)/{(2.0,5.0)}, (2.0,3.0)/{(2.0,5.0)}, (2.0,3.0)/{(2.0,5.0)}
}
  {
    \draw \x -- \y;
  }
\end{tikzpicture}
\end{document}
@Qrrbrbirlbel
Copy link
Contributor

Qrrbrbirlbel commented Jul 31, 2024

There are two problems:

  1. The space at the end of your last item. Remove it with %.
    This also happens if you have a space between an entry and the next ,.

    We could do

    \def\pgffor@scanround(#1)#2,{\pgfkeys@spdef\pgffor@value{(#1)#2}\pgffor@scanned}
    \def\pgffor@scanone#1,{\pgfkeys@spdef\pgffor@value{#1}\pgffor@scanned}
    

    but this doesn't strip the braces around /, and maybe we don't want that.

  2. A macro after to or edge. This has nothing to do with PGFFor:

    \begin{tikzpicture}
    \newcommand*\p{(1,1)}
    \path (0,0) to                       \p;
    \path (0,0) edge                     \p;
    \end{tikzpicture}
    

    The to and edge parser have a different collector which does not simply at least try to expand what's coming next:

    \def\tikz@@to@collect{%
    \pgfutil@ifnextchar(\tikz@@to@or@edge@coordinate%)
    {\pgfutil@ifnextchar n{\tikz@collect@label@onpath\tikz@@to@collect}%
    {\pgfutil@ifnextchar p{\tikz@collect@pic@onpath\tikz@@to@collect}%
    {\pgfutil@ifnextchar c{\tikz@collect@coordinate@onpath\tikz@@to@collect}%
    {\pgfutil@ifnextchar +{\tikz@scan@one@point\tikz@@to@or@edge@math}%
    {\tikzerror{(, +, coordinate, pic, or node expected}%)
    \tikz@@to@or@edge@coordinate()}}}}}%
    }%

    This might be because a relative coordinate must be treated differently than an absolute one.

    This is a start:

     \documentclass{article}
     \usepackage{tikz}
     \makeatletter
     \def\tikz@@to@collect{%
       \pgfutil@ifnextchar n{\tikz@collect@label@onpath\tikz@@to@collect}%
         {\pgfutil@ifnextchar p{\tikz@collect@pic@onpath\tikz@@to@collect}%
           {\pgfutil@ifnextchar c{\tikz@collect@coordinate@onpath\tikz@@to@collect}%
             {\pgfutil@ifnextchar +{\tikz@scan@one@point\tikz@@to@or@edge@math}%
               {\pgfutil@ifnextchar({\tikz@@to@or@edge@coordinate}{%
                 \advance\tikz@expandcount by -10
                 \ifnum\tikz@expandcount<0
                   \def\pgfutil@next{%
                     \tikz@resetexpandcount
                     \tikzerror{(, +, coordinate, pic, or node expected}%
                     \tikz@@to@or@edge@coordinate()}%
                 \else
                   \def\pgfutil@next{\expandafter\tikz@@to@collect}%
                 \fi
                 \pgfutil@next
               }}}}}%
     }
     \makeatother
     \begin{document}
     \begin{tikzpicture}[every path/.append style=draw]
     \newcommand*\p{(1,1)}
     \draw[help lines] (0,0) grid (4,2);
     \path[red]               (0, 0) to   \p -- +(1,.5);
     \path[green, very thick] (1, 0) to  +\p -- +(1,.5);
     \path[blue]              (2, 0) to ++\p -- +(1,.5);
     \end{tikzpicture}
     \end{document}
    

    I'm not quite sure if we need another \tikz@resetexpandcount before so that it always starts with 100 for to/edge parser.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants