I was playing around with this question, and in particular tried to modify and expand the linked example. It works fine, but there is an error when I try to use a \foreach
loop to define the different groups of anchors. If I use the loop variable directly, I get an "! Undefined control sequence." error. If I use the value of the counter, only the last value the loop takes on is used. However, as one can see all three anchors are defined. So my questions are:
- Why does that happen?
- How to work around that?
Code
\documentclass[tikz, border=2mm]{standalone}
\tikzset{%
multipoles/.is family,
multipoles,
pin spacing/.initial=5mm,
top left pins/.initial=3,
bottom left pins/.initial=3,
top right pins/.initial=8,
bottom right pins/.initial=0,
top pins/.initial=0,
bottom pins/.initial=0,
}
\newcommand{\mpp}[1]%
{ \pgfkeysvalueof{/tikz/multipoles/#1}
}
\newcounter{mypincounter}
\pgfdeclareshape{ic8pin}{
\anchor{center}{\pgfpointorigin} % within the node, (0,0) is the center
\anchor{text} % this is used to center the text in the node
{\pgfpoint{-.5\wd\pgfnodeparttextbox}{-.5\ht\pgfnodeparttextbox}}
\pgfmathtruncatemacro{\lrd}{max(\mpp{top left pins} +\mpp{bottom left pins} +or(\mpp{top left pins},\mpp{bottom left pins}), \mpp{top right pins} +\mpp{bottom right pins} +or(\mpp{top right pins},\mpp{bottom right pins}) == 0 ? 2 : max(\mpp{top left pins} +\mpp{bottom left pins} +or(\mpp{top left pins},\mpp{bottom left pins}), \mpp{top right pins} +\mpp{bottom right pins} +or(\mpp{top right pins},\mpp{bottom right pins})}
\xdef\LRDivisions{\lrd}
\pgfmathtruncatemacro{\tbd}{max(\mpp{top pins} +and(1,\mpp{top pins}), \mpp{bottom pins} +and(1,\mpp{bottom pins}) == 0 ? 2 : max(\mpp{top pins} +and(1,\mpp{top pins}), \mpp{bottom pins} +and(1,\mpp{bottom pins})}
\xdef\TBDivisions{\tbd}
\foreach \x in {1,...,\mpp{top left pins}}
{ \setcounter{mypincounter}{\x}
\expandafter\savedanchor\csname tlpin\Roman{mypincounter} \endcsname{\pgfpoint{-\TBDivisions*\mpp{pin spacing}/2}{\LRDivisions*\mpp{pin spacing}/2-\mpp{pin spacing}}}
\anchor{pin\x}{\csname tlpin\Roman{mypincounter} \endcsname}
}
\foregroundpath{ % border and pin numbers are drawn here
\pgfsetlinewidth{0.4pt}
\pgfpathrectanglecorners{\pgfpoint{\TBDivisions*\mpp{pin spacing}/2}{\LRDivisions*\mpp{pin spacing}/2}}{\pgfpoint{-\TBDivisions*\mpp{pin spacing}/2}{-\LRDivisions*\mpp{pin spacing}/2}}
\pgfusepath{draw} %draw rectangle
\pgftext[left,at={\pgfpoint{-.5cm}{-.55cm}}]{\scriptsize LR : \textcolor{red}{\LRDivisions}}
\pgftext[left,at={\pgfpoint{-.5cm}{.55cm}}]{\scriptsize TB : \textcolor{red}{\TBDivisions}}
}}
\begin{document}
\begin{tikzpicture}
\draw (0,0) node[ic8pin] (IC1) {IC 1};
\draw (-5,5) node[ic8pin,rotate=90] (IC2) {IC 2};
\draw[red] (IC1.pin1) -- ++ (-1,0.5) -- (IC2.pin1);
\draw[blue] (IC1.pin2) -- ++ (-1,0) -- (IC2.pin2);
\draw[green] (IC1.pin3) -- ++ (-1,-0.5) -- (IC2.pin3);
\end{tikzpicture}
\end{document}
This produces the error (the problem is the *\x
):
\foreach \x in {1,...,\mpp{top left pins}}
{ \setcounter{mypincounter}{\x}
\expandafter\savedanchor\csname tlpin\Roman{mypincounter} \endcsname{\pgfpoint{-\TBDivisions*\mpp{pin spacing}/2}{\LRDivisions*\mpp{pin spacing}/2-\value{mypincounter}*\mpp{pin spacing}*\x}}
\anchor{pin\x}{\csname tlpin\Roman{mypincounter} \endcsname}
}
And this does not work properly (\value{mypincounter}
is always equal 3):
\foreach \x in {1,...,\mpp{top left pins}}
{ \setcounter{mypincounter}{\x}
\xdef\mydummyx{\x}
\expandafter\savedanchor\csname tlpin\Roman{mypincounter} \endcsname{\pgfpoint{-\TBDivisions*\mpp{pin spacing}/2}{\LRDivisions*\mpp{pin spacing}/2-\value{mypincounter}*\mpp{pin spacing}}}
\anchor{pin\x}{\csname tlpin\Roman{mypincounter} \endcsname}
}
*\x
, and using an\xintFor*
loop rather than a\foreach
loop.\value{mypincounter}*\mpp{pin spacing}*\x
intended? doesn't it mean that the value of\x
is used twice once via\value{mypincounter}
then again via\x
?\anchor
does not expand immediately its arguments, so the last set value is used. If I use (in my\xintFor*
loop) something like\anchor{pin#1}{\csname tlpin#1\endcsname}
(with the corresponding\savedanchor
) I do obtain the intended output