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.

I have a complex TikZ sub-drawing (I call it “object”) that I use over and over in many figures. It's way more complex than what's called a “shape” in the TikZ/pgf context and contains itself several nodes. It has some connection points like the anchors of a shape, and I define them with coordinate (object name_connection name). If it would be real anchors of a shape, I could use the syntax (object name.connection name), but that's not possible in standard tikz (also stated in the manual). Is there a way to circumvent this and give a name containing a “.” to a coordinate? It would help to have cleaner code and to stay closer to the TikZ/pgf syntax.

The example below illustrates what I mean. It's kind of minimal working example, my original code is at the moment approx. 200 lines of code.

\documentclass{article}

\usepackage{tikz}

\pgfkeys{
  /object/.cd,
  left node/.style={draw,red},
  right node/.style={draw,blue},
}

\def\object[#1](#2,#3)#4;{
  \pgfkeys{/object/.cd,#1}
  \begin{scope}[shift={(#2,#3)}]
    \node [/object/left node] (#4_left) at (-1,0) {#4};
    \node [/object/right node]  (#4_right) at (1,0) {#4};
    \draw (#4_left) -- (#4_right);
    \draw (#4_right) -- ++(.5,.5) coordinate (#4_connection b);
    \draw (#4_left) -- ++(-.5,-.5) coordinate (#4_connection a);
  \end{scope}
}

\begin{document}
\begin{tikzpicture}
  \object[](0,-1){A};
  \object[left node/.append style={green}](0,1){B};
  \begin{scope}[orange]
    \draw (-2,0) -- (A_connection a);
    % \draw (-2,0) -- (A.connection a);
    \draw (A_connection b) to[out=45,in=225] (B_connection a);
    % \draw (A.connection b) to[out=45,in=225] (B.connection a);
  \end{scope}
\end{tikzpicture}
\end{document}

Related: Complex objects in TikZ: pgfkeys scope and best practice

share|improve this question
1  
You could declare your object as shape with \pgfdeclareshape, and then provide code for as many anchors as you wish –  Lionel MANSUY Jan 28 '13 at 15:21
    
@Lionel MANSUY: Yes, but that's what I try to avoid, because I don't want to use basic pgf to define my object but higher level TikZ structures like shown in the example. –  Chris Jan 28 '13 at 15:25
    
Why do you want to avoid pgf? –  Matthew Leingang Jan 28 '13 at 16:11
    
I have several reasons. 1) I have already >230 lines of TikZ code. 2) I utilize styles and node positioning a lot within my object and it utilizes additionally several circuit elements. 3) I have many years of TikZ experience, using it during studies, diploma thesis and many papers. I used \def to define my objects since I was never able to dig into the complexity of pgf. So I have 0 years of pgf experience. I'm not a programmer, and pgf looks really complex. I had always the impression that TikZ is lacking some higher level object facility. I believe a lot of people use C-c C-v instead. –  Chris Jan 28 '13 at 16:58
    
What about declaring generic anchors with \pgfdeclaregenericanchor? It's undocumented, it seems... :-( but I've used it already so I know it works. ---But that's pgf again, I'm afraid ... –  Sašo Živanović Jan 29 '13 at 1:56

1 Answer 1

As you can see, the primary goal is met: it's possible to write (A.connection left).

However: the information about coordinates within the object is duplicated, and when more than one object type comes into play, we need to distinguish between them. So, to make everything really work, one would need to the store object type and some internal coordinates ... which would essentially duplicate pgf's shape mechanism.

Another thing: an anchor (including generic anchors) returns a point, so (A.left) doesn't really refer to the node, but to its anchor. In other words, I don't believe that recursion (A.left.north) can be implemented in this way.

\documentclass{article}
\usepackage{tikz}

\pgfkeys{
  /object/.cd,
  left node/.style={draw,red},
  right node/.style={draw,blue},
}

\def\object[#1](#2,#3)#4;{
  \pgfkeys{/object/.cd,#1}
  \begin{scope}[shift={(#2,#3)}]
    \path coordinate(#4);
    \node [/object/left node] (#4_left) at (-1,0) {#4};
    \node [/object/right node]  (#4_right) at (1,0) {#4};
    \draw (#4_left) -- (#4_right);
    \draw (#4_left) -- ++(-.5,-.5);
    \draw (#4_right) -- ++(.5,.5);
  \end{scope}
}
\pgfdeclaregenericanchor{left}{\pgfpointxy{-1}{0}}
\pgfdeclaregenericanchor{right}{\pgfpointxy{1}{0}}
\pgfdeclaregenericanchor{connection left}{\pgfpointxy{-1.5}{-0.5}}
\pgfdeclaregenericanchor{connection right}{\pgfpointxy{1.5}{0.5}}


\begin{document}
\begin{tikzpicture}
  \object[](0,-1){A};
  \object[left node/.append style={green}](0,1){B};
  \begin{scope}[orange]
    \draw[->] (-2,0) -- (A.connection left);
    \draw (A.connection right) to[out=45,in=225] (B.connection left);
  \end{scope}
\end{tikzpicture}
\end{document}
share|improve this answer

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.