Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

In defining a new shape with \pgfdeclareshape, I have problems to add many anchors with the \foreach statement. Each anchor is defined with three arguments. In the example, the argument #1 is OK but the program complains with #2 and #3. How can I generate so many anchors with different keys with \foreach?

\documentclass[a4paper,landscape]{article}
\usepackage{tikz}
\usetikzlibrary{calc,arrows}
\usepackage{amsmath}
\usepackage[left=1cm,right=1cm]{geometry}
\pagestyle{empty}

\begin{document}
\makeatletter
% Define shapes
\pgfdeclareshape{PE}{
  % Inherit from rectangle
  \inheritsavedanchors[from=rectangle]
  \inheritanchor[from=rectangle]{center}
  \inheritanchorborder[from=rectangle]

  % In the following I want to make many anchors with some loop. For example,
  %\foreach \x/\Y/\z in {een/1/.7,ee/1/0,ees/1/-1}
  %{\anchor{\x}{
  %  \pgf@process{\northeast}%
  %  \pgf@x=\y\pgf@x%
  %  \pgf@y=\z\pgf@y%
  %}}
  %However, while #1 is replaced but #2 and #2 are not. 
  %How can I use \foreach or TeX loop?        

  \anchor{een}{
    \pgf@process{\northeast}%
    \pgf@x=1\pgf@x%
    \pgf@y=.7\pgf@y%
  }
  \anchor{ee}{
    \pgf@process{\northeast}%
    \pgf@x=1\pgf@x%
    \pgf@y=0\pgf@y%
  }
  \anchor{ees}{
    \pgf@process{\northeast}%
    \pgf@x=1\pgf@x%
    \pgf@y=-.7\pgf@y%
  }
    \anchor{se}{
    \pgf@process{\northeast}%
    \pgf@x=1\pgf@x%
    \pgf@y=-1\pgf@y%
  }

  % Draw the rectangle box and the port labels
  \backgroundpath{
    % Rectangle box
    \pgfpathrectanglecorners{\southwest}{\northeast}
  %Add labels
  %The following code doesn't work.
  %\foreach \x/\y in {een,ee,ees}
  %  {
  %  \pgf@anchor@PE@\x
  %  \pgftext[at={\pgfpoint{\pgf@x}{\pgf@y}},x=-\pgfshapeinnerxsep,y=0]{\raisebox{-.75ex}{\y}}
  % }
  %\foreach \x/\y in {anchor@PE@een/een,\pgf@anchor@PE@ee/ee,\pgf@anchor@PE@ees/ees}
  %{
  %  \x
  %  \pgftext[at={\pgfpoint{\pgf@x}{\pgf@y}},x=-\pgfshapeinnerxsep,y=0]{\raisebox{-.75ex}{\y}}
  %}
}
\makeatother

\begin{tikzpicture}[>=stealth']
  \tikzset{PE/port labels/.style={font=\sffamily\scriptsize}}
  \tikzset{every PE node/.style={draw=blue,minimum width=2cm,minimum
    height=3cm,very thick,inner sep=1mm,outer sep=0pt,cap=round}}
  % Place PEs
  \foreach \m in {0,...,3}
    \node [shape=PE] (PE\m) at ($ 4*(\m,0)$) {};
\end{tikzpicture}
\end{document}
share|improve this question

1 Answer 1

up vote 11 down vote accepted

Expanding in foreach loops is always problematic so you need to make sure that macros are expanded properly (or some of them are nor expanded while the variables are expanded)

\documentclass[border=2mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc,arrows}

\makeatletter

\pgfdeclareshape{PE}{

  \inheritsavedanchors[from=rectangle]
  \inheritanchor[from=rectangle]{center}
  \inheritanchorborder[from=rectangle]

  \foreach \x/\z in {een/.7,ee/0,ees/-1}
  {
    \xdef\doanchor{
      \noexpand\anchor{\x}{
      \noexpand\northeast
      \noexpand\pgf@y=\z\noexpand\pgf@y%
      }
    }\doanchor
  }
  \backgroundpath{
    % Rectangle box
    \pgfpathrectanglecorners{\southwest}{\northeast}
  }
}
\makeatother

\begin{document}

\begin{tikzpicture}[>=stealth']
  \tikzset{PE/port labels/.style={font=\sffamily\scriptsize}}
  \tikzset{every PE node/.style={draw=blue,minimum width=2cm,minimum
    height=3cm,very thick,inner sep=1mm,outer sep=0pt,cap=round}}
  % Place PEs
  \foreach \m in {0,...,2}{    \node [shape=PE] (PE\m) at ($ 4*(\m,0.25*\m)$) {};}
    \draw (PE0.een) to[bend right] (PE1.ee) to[bend right] (PE2.ees);
    %\draw (PE0.ees) -|++(3cm,-2cm) -| (PE1.ees);
    \node at (PE2.een)  {a};
    \node at (PE2.ee)   {b};
    \node at (PE2.ees)  {c};
\end{tikzpicture}
\end{document}

enter image description here

share|improve this answer
    
Thanks percusse, it works great. Aftere creating the shape I want to add labels in \pgfdeclareshape. However it's a long list that must be simplified with \foreach again. (The code is added) How can I shorten this code for long listing? –  gnoejh Jul 31 '12 at 5:26
    
@gnoejh You might better do it with a node style and using the option label=anchor:text instead of hardcoding into the shape. –  percusse Jul 31 '12 at 22:35

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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