3

When I use \pgfresult to get a node label in a \foreach, I have no problem.

However, I can't seem to get the syntax right to create a coordinate with the same method.

\documentclass{article}
\usepackage{tikz}
\usepackage{pgfplots}

\begin{document}


\begin{tikzpicture}
        \def\pinlabel{{"SCL","SDA"}}
        \foreach \x in {0,1}{
        \node at (\x,0){\pgfmathparse{\pinlabel[\x]}\pgfmathresult};  %<==== works!

        %\node at (\x,0){\pgfmathparse{\pinlabel[\x]}\pgfmathresult} coordinate ({\pgfmathparse{\pinlabel[\x]}\pgfmathresult});  %<====== doesnt't work

    }
\end{tikzpicture}
\end{document}

The commented line fails with: incomplete \iffalse; all text was ignored after line 15.

I've tried doing the parse earlier, and just using the \pgfmathresult alone, but that also fails.

2 Answers 2

4

That's an expansion issue. In imprecise and colloquial terms: if the parser sees all the "junk" before the closing brackets, it does not know how to deal with it. But there is also no reason to do the expansion in the brackets. One way, certainly not unique, is

\documentclass{article}
\usepackage{tikz}

\begin{document}


\begin{tikzpicture}
        \def\pinlabel{{"SCL","SDA"}}
        \foreach \X in {0,1}{  
        \path   \pgfextra{\pgfmathparse{\pinlabel[\X]}
            \xdef\tmp{\pgfmathresult}}
        node at (\X,0) {\tmp} coordinate (\tmp);  
    }
    \draw[blue] (SCL) -- ++(1,1); %test
\end{tikzpicture}
\end{document}

If you do not necessarily have to do the computation of the pinlabel while you are constructing the path, you can simply perform it beforehand using \pgfmathsetmacro.

\documentclass{article}
\usepackage{tikz}

\begin{document}


\begin{tikzpicture}
  \def\pinlabel{{"SCL","SDA"}}
  \foreach \X in {0,1}{  
    \pgfmathsetmacro\tmp{\pinlabel[\X]}
    \node at (\X,0) {\tmp} coordinate (\tmp);  
  }
  \draw[blue] (SCL) -- ++(1,1); %test
\end{tikzpicture}
\end{document}

or even more efficiently, because the label doesn't change during one loop iteration, directly evaluate it as part of the \foreach statement.

\documentclass{article}
\usepackage{tikz}

\begin{document}


\begin{tikzpicture}
  \def\pinlabel{{"SCL","SDA"}}
  \foreach \X [evaluate=\X as \tmp using {\pinlabel[\X]}] in {0,1}{  
    \node at (\X,0) {\tmp} coordinate (\tmp);  
  }
  \draw[blue] (SCL) -- ++(1,1); %test
\end{tikzpicture}
\end{document}
8
  • Wouldn't \pgfmathsetmacro\tmp{\pinlabel[\X]} be much easier? Apr 11, 2018 at 0:23
  • @HenriMenkehe I tried that, and had much the same issue. In fact, that failure led me down this path. I'm not sure why it didn't work --- perhaps that should have been my question! Apr 11, 2018 at 0:25
  • I think you at least have to pass through parse. Apr 11, 2018 at 1:28
  • @HenriMenke It might, I have not gone that way because I was under the impression that the OP wants to do these things "on the fly". That's why set everything up in the path command.
    – user121799
    Apr 11, 2018 at 1:31
  • @ScottSeidman I added the solution I was thinking about. @ marmot I hope you don't mind the edit. Apr 11, 2018 at 1:53
2

Array management in TikZ is very clumsy, in my opinion.

Here's an implementation using expl3 that doesn't require \pgfmathparse juggling.

\documentclass{article}
\usepackage{tikz}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\setarray}{mm}
 {% #1 = array name, #2 = items
  \seq_new:c { l_seidman_array_#1_seq }
  \seq_set_from_clist:cn { l_seidman_array_#1_seq } { #2 }
 }
\NewExpandableDocumentCommand{\getitem}{mm}
 {% #1 = array name, #2 = index
  \seq_item:cn { l_seidman_array_#1_seq } { #2 + 1 }
 }
\ExplSyntaxOff

\setarray{pinlabel}{SCL,SDA} % can also be set locally

\begin{document}

\begin{tikzpicture}
\foreach \x in {0,1}{
  \node at (\x,0) {\getitem{pinlabel}{\x}};
  \node at (\x,1) {\getitem{pinlabel}{\x}}
        coordinate (\getitem{pinlabel}{\x});
}
\end{tikzpicture}

\end{document}

enter image description here

4
  • 1
    Calling it clumsy is actually acknowledging its existence :)
    – percusse
    Apr 11, 2018 at 8:08
  • @percusse The main issue, in my opinion, is the idea of allowing different data types into arrays.
    – egreg
    Apr 11, 2018 at 8:43
  • Indeed it is just a comma separated container with no structure.
    – percusse
    Apr 11, 2018 at 8:46
  • @percusse Actually no: entries enclosed in "..." are treated as strings, otherwise they're considered numbers. I'm not sure what applications need this.
    – egreg
    Apr 11, 2018 at 8:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.