# multi-part nodes/anchors in a resistor-like symbol which has been split horizontally

I would like to take the symbol described in this post and create a two part node. Currently, the anchor for text is located at the center of the symbol. I would like to create two text anchors, at the centers of the two compartments which arise from splitting the resistor-like symbol vertically.

I note that sections 75.1.4 and 75.2.2 in tikz manual for version 2.10 are relevant. I found this post to be quite useful.

First of all, I must use the tikz library:

\usetikzlibrary{shapes.multipart}


I the example alluded to immediately above we see that the following commands:

\let\pgfnodeparttrbox\pgfnodeparttwobox
\let\pgfnodepartblbox\pgfnodepartthreebox
\let\pgfnodepartbrbox\pgfnodepartfourbox


Are placed immediately following the \makeatletter command as indicated in Section 75.2.2 of manual. Immediately following the \pgfdeclareshape{}{ command opening I see

\nodeparts{text,two,three,four}%


In which the node part names are declared. For each of the nodepart names excluding the node part text whose anchor location, i'm assuming, is inherited, there is an anchor definition that may look something like this:

\savedanchor\twoanchor{%
\pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner xsep}}%
\pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/inner ysep}}%
\pgf@yb\dp\pgfnodeparttextbox
\pgf@yc\dp\pgfnodeparttwobox
\ifdim\pgf@yb>\pgf@yc
\pgf@yc\pgf@yb
\fi
}%


I don't fully follow what is happening here. It looks like the values of inner xsep and inner ysep are used (added to other dimensions) in order to offset the box from the anchor position. Half of some dimension is used to populate x and y-dimension variables... Then it looks as though the greater of two y-variables is added to another y-variable. At the moment, I don't quite understand what is happening here in general terms. I can say that the operations performed within the \savedanchor command are slightly different for each node. After all the low level anchor declarations we have this

\anchor{two}{\twoanchor}%
\anchor{three}{\threeanchor}%
\anchor{four}{\fouranchor}%


We don't concern ourselves with \beforebackgroundpath{...} and \behindbackgroundpath{...} at this time. Finally, here is the high level call:

\node [options] (s) {text \nodepart{two} two \nodepart{three} three \nodepart{four} four};


Using the guidance above, I have modified the code contributed by @Qrrbrbirlbel, indicating the additions with comments. Note also that I have removed the stems associated with the symbol as they are unnecessary; the tikz draw operation takes care of this.

modifiedsymbol.tex

\makeatletter
%\let\pgfnodeparttrbox\pgfnodeparttextbbox   % needed? for the textb' box
% I don't know if \pgfnodeparttrbox, \pgfnodepartblbox and \pgfnodepartbrbox are user-defined or are defined in one of the libraries?
\pgfkeys{/pgf/symbol shape ratio/.initial=.5}
\pgfdeclareshape{symbol shape}{%
%\nodeparts{text,textb}% needed
%\savedanchor\textbanchor{% this defines the position of the anchor
%        ...
%    }%
\savedmacro\barratio{%
\pgfmathsetmacro\barratio{\pgfkeysvalueof{/pgf/symbol shape ratio}}%
\ifdim\barratio pt<0pt\relax
% the ratio is < 0
\else\ifdim\barratio pt>1pt\relax
% the ratio is > 1
\fi
\fi
}
\inheritsavedanchors[from=rectangle ee]
\inheritanchor[from=rectangle ee]{center}
\inheritanchor[from=rectangle ee]{north}
\inheritanchor[from=rectangle ee]{south}
\inheritanchor[from=rectangle ee]{east}
\inheritanchor[from=rectangle ee]{west}
\inheritanchor[from=rectangle ee]{north east}
\inheritanchor[from=rectangle ee]{north west}
\inheritanchor[from=rectangle ee]{south east}
\inheritanchor[from=rectangle ee]{south west}
\inheritanchor[from=rectangle ee]{input}
\inheritanchor[from=rectangle ee]{output}
\anchor{bar north}{%
\pgf@xa\pgf@x
\pgf@x\pgf@xa
}
\anchor{bar south}{%
\pgfmathsetmacro\pgf@tempa{\pgfkeysvalueof{/pgf/symbol shape ratio}}%
\pgf@xa\pgf@x\pgf@ya\pgf@y
\pgf@x\pgf@xa
\pgf@y\pgf@ya
}
\anchor{bar center}{%
\pgfmathsetmacro\pgf@tempa{\pgfkeysvalueof{/pgf/symbol shape ratio}}%
\pgf@xa\pgf@x\pgf@ya.5\pgf@y
\pgf@x\pgf@xa
}
%\anchor{textb}{\textbanchor}   % anchor for textb
\inheritanchorborder[from=rectangle ee]
\inheritbackgroundpath[from=rectangle ee]
\behindbackgroundpath{%
\pgf@xa\pgf@x\pgf@ya\pgf@y
\pgf@xb\pgf@x\pgf@yb\pgf@y
% The center point: c = .5 * (a + b)
\pgf@xc.5\pgf@xb
\pgf@yc.5\pgf@yb
% we don't want to overdraw lines and subtract/add half the line width (not affected by outer seps)
%      \pgfutil@tempdima\pgf@xa
%      \pgfutil@tempdimb-.5\pgf@xc
%      \pgfpathmoveto{\pgfqpoint{\pgfutil@tempdima}{\pgf@yc}}%
%      \pgfpathlineto{\pgfqpoint{\pgfutil@tempdimb}{\pgf@yc}}%
%      \pgfutil@tempdima\pgf@xb
%      \pgfutil@tempdimb-.5\pgf@xc
%      \pgfpathmoveto{\pgfqpoint{\pgfutil@tempdima}{\pgf@yc}}%
%      \pgfpathlineto{\pgfqpoint{\pgfutil@tempdimb}{\pgf@yc}}%
%
\advance\pgf@xa\barratio\pgf@xb%                                     left x value + ratio*width
\pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@ya}}%
\pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@yb}}%
\pgfsetbuttcap
\pgfusepathqstroke
}%
}
\makeatother


call.tex

\documentclass[tikz,convert=false]{standalone}
\usetikzlibrary{circuits,circuits.ee.IEC,shapes.multipart}
\input{symbols/modifiedsymbol.tex}% retrieve symbol definition
\tikzset{
circuit declare symbol=symbol,
set symbol graphic={
shape=symbol shape,
draw,
transform shape,
circuit symbol size=width 14 height 2,
}
}
\begin{document}
\def\Ratio{0.38}
\begin{tikzpicture}[circuit ee IEC]
\node[symbol, symbol shape ratio=\Ratio] at (0,0) (thesymbol) {A};
%\node[symbol, symbol shape ratio=\Ratio] at (0,0) (thesymbol) {A \nodepart{textb} B};  % two-part node version
\end{tikzpicture}
\end{document}


So, my question is how to write the \savedanchor{...} or \anchor{...} commands in order to position the multipart nodes/text box anchors in a resistor-like symbol which has been split horizontally?

• (+1) Good question. ;) Sorry, I haven’t seen your follow-up question (you could have left a comment on the other one). I will take a closer look tomorrow and hopefully be able to answer your questions. One question though: How should we deal with the bar ratio and the node parts widths? Say you want a ratio of .1 but the left node part is much wider than the right? You might end up with very wide but very empty parts. What has a higher priority? – Qrrbrbirlbel Jul 13 '13 at 2:27
• The vertical dividing line should set the boundary between the node parts. The leftmost node part will have east anchors which are equivalent with the west anchors of the rightmost part. In the case of ratio being equal to one or zero, the east, center, and west nodes of the empty node part would all be equivalent with either the east or west anchors of the non-empty node part. Does that make sense? – John Chris Jul 13 '13 at 15:40
• Sure sure, but what about the node parts, the actual text (in your example A/A and B)? If you have a ratio of one or zero you won’t have space for the text? Or don’t you actually want node parts but the anchors? Though, I have to ask another question: Aren’t all anchors defined anyway? The west anchor of the left node part is the west anchor of the shape. The east anchor of the left node part is the bar center anchor which is the same as the west anchor of the right node part whereas the east anchor of the right node part is the east anchor of the shape. – Qrrbrbirlbel Jul 14 '13 at 0:01
• Well, yes, the east and west anchors are defined and perhaps only need to be renamed. The center node, however, is not. I think that if one of the node parts were very small, I would use an arrow from the center anchor of that node part to an anchor located above and center. – John Chris Jul 14 '13 at 17:59

You encounter a few problems when defining a node shape:

• You cannot use TikZ, you need to use PGF.

• PGF distinguishes between saved anchors and other anchors which position will be calculation from saved anchors and/or saved dimensions and/or saved macros. When computing the positions of these other anchors you cannot use values like minimum width or \pgflinewidth to calculate something. They will have changed (think a thick node but a thin line that will connect the node).

• All coordinates will be in a special local coordinate system of its node (this is a good thing, the transformation will be saved when the node is created). Its origin is at the left point of the baseline (where the .text anchor lies).

Let us take a look at a basic shape, the rectangle (pgfmoduleshapes.code.tex). As your shape is based on it, its working will help understand the adjustments I will do later.

The rectangle shape only defines two anchors: \northeast and \southwest. Their definitions (starting with \savedanchor) are very similar. They calculate the minimal dimensions of the node, this includes the dimension of the \pgfnodeparttextbox itself (which is the always existing box for the first and mostly only node part).

If these dimensions are smaller than the values of the keys minimum width and minimum height they will be set to these.

Then the actual coordinates of the anchors are calculated. The center of the node lies always in the center of the text box. AT the end of the definition \pgf@x and \pgf@y should hold the correct dimensions. Everything else is lost after that and needs to be calculated again. (\pgf@x and \pgf@y survive but I wouldn’t rely on that.)

The shape definition of the rectangle contains a lot of anchor definitions in the form of \anchor{<name of anchor>}{<definition>}. These are those anchors which will be computed firstly when they are used. In the rectangle shape they only rely on the saved anchors \northeast and \southwest as well as a few basic given facts, e.g. baseline at y = 0.

The definition of paths and the anchor border is an entirely different topic and doesn’t to be discussed here. (We will also define anchors \northeast and \southwest in our shape definition so we can again inherit everything from rectangle, we can inherit background path and anchor border, too.)

Multi-part nodes have a few additional rules:

1. Every node part needs its own TeX box.

They were previously (I assume in older versions of TikZ) called \pgfnodepartsecondbox, \…third…, \…fourth… but this was later changed to …two…, …three…, …four…. The rectangle split shape is even able to handle up to twenty boxes/parts.

The circle split family also defines the lower box.

The lines

\let\pgfnodeparttrbox\pgfnodeparttwobox
\let\pgfnodepartblbox\pgfnodepartthreebox
\let\pgfnodepartbrbox\pgfnodepartfourbox


do not declare a new box but simply “mirror” those box names. We can use \nodepart{tr} instead of \nodepart{two} which may have been preferred in the linked case.

In the same way are …second… and …two… linked.

2. Every node part needs its anchor!

The first node part (text = one) already has its primitive anchor at the origin, this doesn’t need to be defined every time. It doesn’t need to be a saved anchor and, in fact, only the \anchor{two}{…} definition will suffice for the \pgfnodeparttwobox. (But it will be a saved anchor because it is dependent on the text boxes and oftentimes the inner separators and whatnot.)

We don’t need the shapes.multipart library here.

As already said, we only change the definition of \northeast and \southwest and also add the definition of the \textbanchor. The factor \barratio will be a saved macro (or we need to make one of the bar macros a saved anchor (which would suffice if we don’t want the text center and textb center anchors). As the \northeast and the \southwest anchors already include the outer xsep (which we don’t consider part of the node’s width) we also save it in a macro called \outerxsep.

The ratio of 0 and 1 will be catched (otherwise we would perform a division by zero). It may be safer to test for a certain range (say < 0.05 is considered unsafe) but I expect some awareness from the user. ;)

There are many comments in the definition of the main saved anchor which are very similar to begin with.

Take also a look at the definition of the split rectangle with rounded corners shape where I have used one \savedmacro to save a few other macros (which moonlight as anchors). This is very helpful if all your saved values (macros, dimens, anchors) depend on common factors/values.

As you noticed, there is no direct approach to set the actual node content via the circuits library while using the shape on a to path. Though, we can patch the circuit handle symbol key that is internally used whenever the symbol is used. The etoolbox package help us here to do this patching without writing up the whole definition again. The \patchcmd is used three times, replacing {} by {\tikz@lib@circ@Text} whereas the Text key is set up to set \tikz@lib@circ@Text. (The lowercase text key is already used for setting the color of the node text.)

As the circuits library install a inner sep of 0.5pt by default we can revert to its default with setting it to .333em in the value to the set symbol graphic key. We can now use the shape and Text on a to path:

\draw (0,0) to [symbol={symbol shape ratio=.2,Text=B \nodepart{textb} C}] (6,0);


## Code

\documentclass[tikz,convert=false]{standalone}
\usetikzlibrary{circuits,circuits.ee.IEC}
\usepackage{etoolbox}
\makeatletter
\tikzset{Text/.code=\def\tikz@lib@circ@Text{#1}}
\expandafter\patchcmd\csname pgfk@/tikz/circuit handle symbol/.@cmd\endcsname
{{}}{{\tikz@lib@circ@Text}}{}{}
\expandafter\patchcmd\csname pgfk@/tikz/circuit handle symbol/.@cmd\endcsname
{{}}{{\tikz@lib@circ@Text}}{}{}
\expandafter\patchcmd\csname pgfk@/tikz/circuit handle symbol/.@cmd\endcsname
{{}}{{\tikz@lib@circ@Text}}{}{}
\tikzset{
circuit declare symbol=symbol,
set symbol graphic={
shape=symbol shape,
draw,
transform shape,
circuit symbol size=width 14 height 2,
inner sep=+.3333em
}
}
%% We need a box for the second node part. We could use a possibly already existing 'lower' or 'two' here but let's use our own:
\newbox\pgfnodeparttextbbox

\pgfkeys{/pgf/symbol shape ratio/.initial=.5}
\pgfdeclareshape{symbol shape}{%
\nodeparts{text,textb}% needed
\savedmacro\barratio{%
\pgfmathsetmacro\barratio{\pgfkeysvalueof{/pgf/symbol shape ratio}}%
}
\saveddimen\outerxsep{%
\pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}%
}
\savedanchor\southwest{%
\pgfmathsetlength\pgf@xc{\pgfkeysvalueof{/pgf/inner xsep}}%
\pgfmathsetlength\pgf@yc{\pgfkeysvalueof{/pgf/inner ysep}}%
%
%
% First: Include the inner xseps
\pgf@xa=\wd\pgfnodeparttextbox
\pgf@xb=\wd\pgfnodeparttextbbox
\ifdim\barratio pt=0pt\relax
\pgf@xa=0pt%
\else
\pgfmathsetlength\pgf@xa{\pgf@xa/\barratio}% calculate the horizontal dimension for the total shape if nodepart one would be dominant
\fi
\ifdim\barratio pt=1pt\relax
\pgf@xb=0pt
\else
\pgfmathsetlength\pgf@xb{\pgf@xb/(1-\barratio)}% same for the second node part
\fi
% Which one is dominant? \pgf@xa will hold the horizontal dimension of the node
\ifdim\pgf@xa<\pgf@xb
\pgf@xa\pgf@xb
\fi
\pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/minimum width}}%
\ifdim\pgf@xa<\pgf@xb % oh minimum width was greater anyway
\pgf@xa=\pgf@xb
\fi
% So, \pgf@xa holds the final width.
% Where now lies the most left vertical line (and thus the x value of the south west anchor)?
% Well it lies at (<width of first node part>-<final width>*<bar ratio>)/2
\pgf@x=\wd\pgfnodeparttextbox
\pgf@x=.5\pgf@x
\pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/outer xsep}}%
%
%
% Now the height, that's easier, we just check the maximum of the depths and the heights of the nodeparts
%
\pgf@ya=\dp\pgfnodeparttextbox
\pgf@yb=\dp\pgfnodeparttextbbox
\ifdim\pgf@ya<\pgf@yb
\pgf@ya=\pgf@yb
\fi
\pgf@yb=\ht\pgfnodeparttextbox
\ifdim\pgf@yb<\ht\pgfnodeparttextbbox
\pgf@yb=\ht\pgfnodeparttextbbox
\fi
\pgfmathsetlength\pgf@yb{\pgfkeysvalueof{/pgf/minimum height}}%
\ifdim\pgf@ya<\pgf@yb
\pgf@ya=\pgf@yb
\fi
% So, \pgf@ya holds the final height.
\pgf@y=-.5\pgf@ya
\pgf@ya=\dp\pgfnodeparttextbox
\pgf@yb=\dp\pgfnodeparttextbbox
\ifdim\pgf@ya>\pgf@yb
\else
\fi
\pgf@yb=\ht\pgfnodeparttextbox
\ifdim\pgf@yb>\ht\pgfnodeparttextbbox
\else
\fi
\pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/outer ysep}}%
}
\savedanchor\northeast{%
\pgfmathsetlength\pgf@xc{\pgfkeysvalueof{/pgf/inner xsep}}%
\pgfmathsetlength\pgf@yc{\pgfkeysvalueof{/pgf/inner ysep}}%
%
%
% First: Include the inner xseps
\pgf@xa=\wd\pgfnodeparttextbox
\pgf@xb=\wd\pgfnodeparttextbbox
\ifdim\barratio pt=0pt\relax
\pgf@xa=0pt%
\else
\pgfmathsetlength\pgf@xa{\pgf@xa/\barratio}% calculate the horizontal dimension for the total shape if nodepart one would be dominant
\fi
\ifdim\barratio pt=1pt\relax
\pgf@xb=0pt
\else
\pgfmathsetlength\pgf@xb{\pgf@xb/(1-\barratio)}% same for the second node part
\fi
% Which one is dominant? \pgf@xa will hold the horizontal dimension of the node
\ifdim\pgf@xa<\pgf@xb
\pgf@xa\pgf@xb
\fi
\pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/minimum width}}%
\ifdim\pgf@xa<\pgf@xb % oh minimum width was greater anyway
\pgf@xa\pgf@xb
\fi
% So, \pgf@xa holds the final width.
% Where now lies the most right vertical line (and thus the x value of the north east anchor)?
\pgf@x=\wd\pgfnodeparttextbox
\pgf@x=.5\pgf@x
\pgfutil@tempdima=-\barratio pt
\pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/outer xsep}}%
%
%
% Now the height, that's easier, we just check the maximum of the depths and the heights of the nodeparts
%
\pgf@ya=\dp\pgfnodeparttextbox
\pgf@yb=\dp\pgfnodeparttextbbox
\ifdim\pgf@ya<\pgf@yb
\pgf@ya=\pgf@yb
\fi
\pgf@yb=\ht\pgfnodeparttextbox
\ifdim\pgf@yb<\ht\pgfnodeparttextbbox
\pgf@yb=\ht\pgfnodeparttextbbox
\fi
\pgfmathsetlength\pgf@yb{\pgfkeysvalueof{/pgf/minimum height}}%
\ifdim\pgf@ya<\pgf@yb
\pgf@ya=\pgf@yb
\fi
% So, \pgf@ya holds the final height.
\pgf@y=.5\pgf@ya
\pgf@ya=\dp\pgfnodeparttextbox
\pgf@yb=\dp\pgfnodeparttextbbox
\ifdim\pgf@ya>\pgf@yb
\else
\fi
\pgf@yb=\ht\pgfnodeparttextbox
\ifdim\pgf@yb>\ht\pgfnodeparttextbbox
\else
\fi
\pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/outer ysep}}%
}
\savedanchor\textbanchor{%
\pgfmathsetlength\pgf@xc{\pgfkeysvalueof{/pgf/inner xsep}}%
%
%
% First: Include the inner xseps
\pgf@xa=\wd\pgfnodeparttextbox
\pgf@xb=\wd\pgfnodeparttextbbox
\ifdim\barratio pt=0pt\relax
\pgf@xa=0pt%
\else
\pgfmathsetlength\pgf@xa{\pgf@xa/\barratio}% calculate the horizontal dimension for the total shape if nodepart one would be dominant
\fi
\ifdim\barratio pt=1pt\relax
\pgf@xb=0pt
\else
\pgfmathsetlength\pgf@xb{\pgf@xb/(1-\barratio)}% same for the second node part
\fi
% Which one is dominant? \pgf@xa will hold the horizontal dimension of the node
\ifdim\pgf@xa<\pgf@xb
\pgf@xa\pgf@xb
\fi
\pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/minimum width}}%
\ifdim\pgf@xa<\pgf@xb % oh minimum width was greater anyway
\pgf@xa\pgf@xb
\fi
% So, \pgf@xa holds the final width.
% Where now lies the most right vertical line (and thus the x value of the north east anchor)?
%    % Well it lies at (<width of first node part>-<final width>*<bar ratio>)/2
\pgf@x=\wd\pgfnodeparttextbox
\pgf@x=.5\pgf@x
\pgfutil@tempdima=-\barratio pt
\pgfutil@tempdima=.5\pgfutil@tempdima
%
\pgf@y=0pt
}

%  \inheritsavedanchors[from=rectangle ee]
\inheritanchor[from=rectangle ee]{center}
\inheritanchor[from=rectangle ee]{north}
\inheritanchor[from=rectangle ee]{south}
\inheritanchor[from=rectangle ee]{east}
\inheritanchor[from=rectangle ee]{west}
\inheritanchor[from=rectangle ee]{north east}
\inheritanchor[from=rectangle ee]{north west}
\inheritanchor[from=rectangle ee]{south east}
\inheritanchor[from=rectangle ee]{south west}
\inheritanchor[from=rectangle ee]{input}
\inheritanchor[from=rectangle ee]{output}
\inheritanchor[from=rectangle ee]{mid east}
\inheritanchor[from=rectangle ee]{mid west}
\inheritanchor[from=rectangle ee]{mid}
\inheritanchor[from=rectangle ee]{base west}
\inheritanchor[from=rectangle ee]{base east}
\inheritanchor[from=rectangle ee]{base}
\anchor{bar north}{%
\pgf@xa\pgf@x
\pgf@x\pgf@xa
}
\anchor{bar south}{%
\pgf@xa\pgf@x\pgf@ya\pgf@y
\pgf@x\pgf@xa
\pgf@y\pgf@ya
}
\anchor{bar center}{%
\pgf@xa\pgf@x\pgf@ya.5\pgf@y
\pgf@x\pgf@xa
}
\anchor{textb}{\textbanchor}% anchor for textb
\anchor{text west}{\pgf@sh@reanchor{symbol shape}{west}}
\anchor{textb east}{\pgf@sh@reanchor{symbol shape}{east}}
\anchor{text east}{\pgf@sh@reanchor{symbol shape}{bar center}}
\anchor{textb west}{\pgf@sh@reanchor{symbol shape}{bar center}}
\anchor{text center}{%
\southwest
\pgf@xa\pgf@x
\pgf@process{\pgf@sh@reanchor{symbol shape}{bar center}}%
\pgf@x.5\pgf@x
}
\anchor{text base}{\pgf@sh@reanchor{symbol shape}{text center}\pgf@y=0pt}
\anchor{textb center}{%
\northeast
\pgf@xa\pgf@x
\pgf@process{\pgf@sh@reanchor{symbol shape}{bar center}}%
\pgf@x.5\pgf@x
}
\anchor{textb base}{\pgf@sh@reanchor{symbol shape}{textb center}\pgf@y=0pt}
\inheritanchorborder[from=rectangle ee]
\inheritbackgroundpath[from=rectangle ee]
\beforebackgroundpath{%
\pgf@xa\pgf@x\pgf@ya\pgf@y
\pgf@xb\pgf@x\pgf@yb\pgf@y
% The center point: c = .5 * (a + b)
%     \pgf@xc.5\pgf@xb
%     \pgf@yc.5\pgf@yb
% we don't want to overdraw lines and subtract/add half the line width (not affected by outer seps)
%     \pgfutil@tempdima\pgf@xa
%     \pgfutil@tempdimb-.5\pgf@xc
%     \pgfpathmoveto{\pgfqpoint{\pgfutil@tempdima}{\pgf@yc}}%
%     \pgfpathlineto{\pgfqpoint{\pgfutil@tempdimb}{\pgf@yc}}%
%     \pgfutil@tempdima\pgf@xb
%     \pgfutil@tempdimb-.5\pgf@xc
%     \pgfpathmoveto{\pgfqpoint{\pgfutil@tempdima}{\pgf@yc}}%
%     \pgfpathlineto{\pgfqpoint{\pgfutil@tempdimb}{\pgf@yc}}%
%
\advance\pgf@xa\barratio\pgf@xb%                                      left x value + ratio*width
\pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@ya}}%
\pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@yb}}%
\pgfsetbuttcap
\pgfusepathqstroke
}%
}
\makeatother
\tikzset{
shape example/.style={
color=black!30,
draw,
fill=yellow!30,
line width=.5cm,
inner xsep=2.5cm,
inner ysep=0.5cm}
}
\begin{document}\Huge
\begin{tikzpicture}[circuit ee IEC]
\node[symbol, symbol shape ratio=.3, shape example, name=s] {A\vrule width 1pt height 2cm \nodepart{textb} \TeX t\vrule width 1pt height 2cm};
\foreach \anchor/\placement in {north west/above left, north/above, north east/above right,
west/left, center/above, east/right,
mid west/right, mid/above, mid east/left,
base west/left, base/below, base east/right,
south west/below left, south/below, south east/below right,
text/left, 10/right, 130/above}
\draw[shift=(s.\anchor)] plot[mark=x] coordinates{(0,0)} node[\placement] {\scriptsize\texttt{(s.\anchor)}};
\foreach \anchor/\placement in {bar north/above, bar south/below, bar center/above,
text west/above, textb east/above, textb/left,
text east/left, textb west/right, text center/above,%
text base/below, textb center/above, textb base/below%
}
\draw[red,shift=(s.\anchor)] plot[mark=x] coordinates{(0,0)} node[\placement] {\scriptsize\texttt{(s.\anchor)}};
\end{tikzpicture}
\begin{tikzpicture}[circuit ee IEC]
\draw (0,0) to [symbol={symbol shape ratio=.2,Text=B \nodepart{textb} C}] (6,0);
\end{tikzpicture}
\end{document}


## Output

• Firstly, thanks very much for the explanation and example code. I'm currently testing the symbol out. I find that If I try to use the symbol \draw[symbol shape ratio=.2, minimum width = 14 cm, minimum height = 1.5cm] (midpoint.center) to [symbol={info=B \nodepart{textb} C}] (endpoint); like this, I get an an unexpected result. The \nodepart{textb} text does not appear. – John Chris Jul 18 '13 at 16:59
• @JohnChris Both node parts do not appear. The info key is simply a wrapper for the label key for the symbol shape. As far as I know the circuits libraries do not support actual node text in the shapes … – Qrrbrbirlbel Jul 18 '13 at 17:13
• Do you suspect there is a way to annotate or label the node parts in the following construction: \draw (0,0) to [symbol, symbol shape ratio=.2, minimum width = 14 cm, minimum height = 1.5cm] (16,0); – John Chris Jul 18 '13 at 18:19
• @JohnChris See my updated answer. A little tricky but doable. The circuits library is apparently not made for shapes with text. – Qrrbrbirlbel Jul 19 '13 at 23:51
• When I include the modified symbol definition (specifically, the code found between \makeatletter and \makeatother) in a file in which I create the minimal graphic \begin{tikzpicture}[circuit ee IEC] \draw (0,0) to [resistor] (2,0);\end{tikzpicture} I receive an error message. I'm wondering if the tricks employed in order to display text on the symbol discussed above result in a requirement to do the basic stuff (such as drawing a resistor) in a slightly different way. – John Chris Jul 29 '13 at 19:40

The following is a minimum working example in which I have tried to illustrate the error alluded to in the thread of comments above.

The code for the symbol:

\makeatletter
\tikzset{Text/.code=\def\tikz@lib@circ@Text{#1}}
\expandafter\patchcmd\csname pgfk@/tikz/circuit handle symbol/.@cmd\endcsname
{{}}{{\tikz@lib@circ@Text}}{}{}
\expandafter\patchcmd\csname pgfk@/tikz/circuit handle symbol/.@cmd\endcsname
{{}}{{\tikz@lib@circ@Text}}{}{}
\expandafter\patchcmd\csname pgfk@/tikz/circuit handle symbol/.@cmd\endcsname
{{}}{{\tikz@lib@circ@Text}}{}{}
\tikzset{
circuit declare symbol=symbol,
set symbol graphic={
shape=symbol shape,
draw,
transform shape,
circuit symbol size=width 14 height 2,
inner sep=+.3333em
}
}
%% We need a box for the second node part. We could use a possibly already existing 'lower' or 'two' here but let's use our own:
\newbox\pgfnodeparttextbbox

\pgfkeys{/pgf/symbol shape ratio/.initial=.5}
\pgfdeclareshape{symbol shape}{%
\nodeparts{text,textb}% needed
\savedmacro\barratio{%
\pgfmathsetmacro\barratio{\pgfkeysvalueof{/pgf/symbol shape ratio}}%
}
\saveddimen\outerxsep{%
\pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}%
}
\savedanchor\southwest{%
\pgfmathsetlength\pgf@xc{\pgfkeysvalueof{/pgf/inner xsep}}%
\pgfmathsetlength\pgf@yc{\pgfkeysvalueof{/pgf/inner ysep}}%
%
%
% First: Include the inner xseps
\pgf@xa=\wd\pgfnodeparttextbox
\pgf@xb=\wd\pgfnodeparttextbbox
\ifdim\barratio pt=0pt\relax
\pgf@xa=0pt%
\else
\pgfmathsetlength\pgf@xa{\pgf@xa/\barratio}% calculate the horizontal dimension for the total shape if nodepart one would be dominant
\fi
\ifdim\barratio pt=1pt\relax
\pgf@xb=0pt
\else
\pgfmathsetlength\pgf@xb{\pgf@xb/(1-\barratio)}% same for the second node part
\fi
% Which one is dominant? \pgf@xa will hold the horizontal dimension of the node
\ifdim\pgf@xa<\pgf@xb
\pgf@xa\pgf@xb
\fi
\pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/minimum width}}%
\ifdim\pgf@xa<\pgf@xb % oh minimum width was greater anyway
\pgf@xa=\pgf@xb
\fi
% So, \pgf@xa holds the final width.
% Where now lies the most left vertical line (and thus the x value of the south west anchor)?
% Well it lies at (<width of first node part>-<final width>*<bar ratio>)/2
\pgf@x=\wd\pgfnodeparttextbox
\pgf@x=.5\pgf@x
\pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/outer xsep}}%
%
%
% Now the height, that's easier, we just check the maximum of the depths and the heights of the nodeparts
%
\pgf@ya=\dp\pgfnodeparttextbox
\pgf@yb=\dp\pgfnodeparttextbbox
\ifdim\pgf@ya<\pgf@yb
\pgf@ya=\pgf@yb
\fi
\pgf@yb=\ht\pgfnodeparttextbox
\ifdim\pgf@yb<\ht\pgfnodeparttextbbox
\pgf@yb=\ht\pgfnodeparttextbbox
\fi
\pgfmathsetlength\pgf@yb{\pgfkeysvalueof{/pgf/minimum height}}%
\ifdim\pgf@ya<\pgf@yb
\pgf@ya=\pgf@yb
\fi
% So, \pgf@ya holds the final height.
\pgf@y=-.5\pgf@ya
\pgf@ya=\dp\pgfnodeparttextbox
\pgf@yb=\dp\pgfnodeparttextbbox
\ifdim\pgf@ya>\pgf@yb
\else
\fi
\pgf@yb=\ht\pgfnodeparttextbox
\ifdim\pgf@yb>\ht\pgfnodeparttextbbox
\else
\fi
\pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/outer ysep}}%
}
\savedanchor\northeast{%
\pgfmathsetlength\pgf@xc{\pgfkeysvalueof{/pgf/inner xsep}}%
\pgfmathsetlength\pgf@yc{\pgfkeysvalueof{/pgf/inner ysep}}%
%
%
% First: Include the inner xseps
\pgf@xa=\wd\pgfnodeparttextbox
\pgf@xb=\wd\pgfnodeparttextbbox
\ifdim\barratio pt=0pt\relax
\pgf@xa=0pt%
\else
\pgfmathsetlength\pgf@xa{\pgf@xa/\barratio}% calculate the horizontal dimension for the total shape if nodepart one would be dominant
\fi
\ifdim\barratio pt=1pt\relax
\pgf@xb=0pt
\else
\pgfmathsetlength\pgf@xb{\pgf@xb/(1-\barratio)}% same for the second node part
\fi
% Which one is dominant? \pgf@xa will hold the horizontal dimension of the node
\ifdim\pgf@xa<\pgf@xb
\pgf@xa\pgf@xb
\fi
\pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/minimum width}}%
\ifdim\pgf@xa<\pgf@xb % oh minimum width was greater anyway
\pgf@xa\pgf@xb
\fi
% So, \pgf@xa holds the final width.
% Where now lies the most right vertical line (and thus the x value of the north east anchor)?
\pgf@x=\wd\pgfnodeparttextbox
\pgf@x=.5\pgf@x
\pgfutil@tempdima=-\barratio pt
\pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/outer xsep}}%
%
%
% Now the height, that's easier, we just check the maximum of the depths and the heights of the nodeparts
%
\pgf@ya=\dp\pgfnodeparttextbox
\pgf@yb=\dp\pgfnodeparttextbbox
\ifdim\pgf@ya<\pgf@yb
\pgf@ya=\pgf@yb
\fi
\pgf@yb=\ht\pgfnodeparttextbox
\ifdim\pgf@yb<\ht\pgfnodeparttextbbox
\pgf@yb=\ht\pgfnodeparttextbbox
\fi
\pgfmathsetlength\pgf@yb{\pgfkeysvalueof{/pgf/minimum height}}%
\ifdim\pgf@ya<\pgf@yb
\pgf@ya=\pgf@yb
\fi
% So, \pgf@ya holds the final height.
\pgf@y=.5\pgf@ya
\pgf@ya=\dp\pgfnodeparttextbox
\pgf@yb=\dp\pgfnodeparttextbbox
\ifdim\pgf@ya>\pgf@yb
\else
\fi
\pgf@yb=\ht\pgfnodeparttextbox
\ifdim\pgf@yb>\ht\pgfnodeparttextbbox
\else
\fi
\pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/outer ysep}}%
}
\savedanchor\textbanchor{%
\pgfmathsetlength\pgf@xc{\pgfkeysvalueof{/pgf/inner xsep}}%
%
%
% First: Include the inner xseps
\pgf@xa=\wd\pgfnodeparttextbox
\pgf@xb=\wd\pgfnodeparttextbbox
\ifdim\barratio pt=0pt\relax
\pgf@xa=0pt%
\else
\pgfmathsetlength\pgf@xa{\pgf@xa/\barratio}% calculate the horizontal dimension for the total shape if nodepart one would be dominant
\fi
\ifdim\barratio pt=1pt\relax
\pgf@xb=0pt
\else
\pgfmathsetlength\pgf@xb{\pgf@xb/(1-\barratio)}% same for the second node part
\fi
% Which one is dominant? \pgf@xa will hold the horizontal dimension of the node
\ifdim\pgf@xa<\pgf@xb
\pgf@xa\pgf@xb
\fi
\pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/minimum width}}%
\ifdim\pgf@xa<\pgf@xb % oh minimum width was greater anyway
\pgf@xa\pgf@xb
\fi
% So, \pgf@xa holds the final width.
% Where now lies the most right vertical line (and thus the x value of the north east anchor)?
%    % Well it lies at (<width of first node part>-<final width>*<bar ratio>)/2
\pgf@x=\wd\pgfnodeparttextbox
\pgf@x=.5\pgf@x
\pgfutil@tempdima=-\barratio pt
\pgfutil@tempdima=.5\pgfutil@tempdima
%
\pgf@y=0pt
}

%  \inheritsavedanchors[from=rectangle ee]
\inheritanchor[from=rectangle ee]{center}
\inheritanchor[from=rectangle ee]{north}
\inheritanchor[from=rectangle ee]{south}
\inheritanchor[from=rectangle ee]{east}
\inheritanchor[from=rectangle ee]{west}
\inheritanchor[from=rectangle ee]{north east}
\inheritanchor[from=rectangle ee]{north west}
\inheritanchor[from=rectangle ee]{south east}
\inheritanchor[from=rectangle ee]{south west}
\inheritanchor[from=rectangle ee]{input}
\inheritanchor[from=rectangle ee]{output}
\inheritanchor[from=rectangle ee]{mid east}
\inheritanchor[from=rectangle ee]{mid west}
\inheritanchor[from=rectangle ee]{mid}
\inheritanchor[from=rectangle ee]{base west}
\inheritanchor[from=rectangle ee]{base east}
\inheritanchor[from=rectangle ee]{base}
\anchor{bar north}{%
\pgf@xa\pgf@x
\pgf@x\pgf@xa
}
\anchor{bar south}{%
\pgf@xa\pgf@x\pgf@ya\pgf@y
\pgf@x\pgf@xa
\pgf@y\pgf@ya
}
\anchor{bar center}{%
\pgf@xa\pgf@x\pgf@ya.5\pgf@y
\pgf@x\pgf@xa
}
\anchor{textb}{\textbanchor}% anchor for textb
\anchor{text west}{\pgf@sh@reanchor{symbol shape}{west}}
\anchor{textb east}{\pgf@sh@reanchor{symbol shape}{east}}
\anchor{text east}{\pgf@sh@reanchor{symbol shape}{bar center}}
\anchor{textb west}{\pgf@sh@reanchor{symbol shape}{bar center}}
\anchor{text center}{%
\southwest
\pgf@xa\pgf@x
\pgf@process{\pgf@sh@reanchor{symbol shape}{bar center}}%
\pgf@x.5\pgf@x
}
\anchor{text base}{\pgf@sh@reanchor{symbol shape}{text center}\pgf@y=0pt}
\anchor{textb center}{%
\northeast
\pgf@xa\pgf@x
\pgf@process{\pgf@sh@reanchor{symbol shape}{bar center}}%
\pgf@x.5\pgf@x
}
\anchor{textb base}{\pgf@sh@reanchor{symbol shape}{textb center}\pgf@y=0pt}
\inheritanchorborder[from=rectangle ee]
\inheritbackgroundpath[from=rectangle ee]
\beforebackgroundpath{%
\pgf@xa\pgf@x\pgf@ya\pgf@y
\pgf@xb\pgf@x\pgf@yb\pgf@y
% The center point: c = .5 * (a + b)
%     \pgf@xc.5\pgf@xb
%     \pgf@yc.5\pgf@yb
% we don't want to overdraw lines and subtract/add half the line width (not affected by outer seps)
%     \pgfutil@tempdima\pgf@xa
%     \pgfutil@tempdimb-.5\pgf@xc
%     \pgfpathmoveto{\pgfqpoint{\pgfutil@tempdima}{\pgf@yc}}%
%     \pgfpathlineto{\pgfqpoint{\pgfutil@tempdimb}{\pgf@yc}}%
%     \pgfutil@tempdima\pgf@xb
%     \pgfutil@tempdimb-.5\pgf@xc
%     \pgfpathmoveto{\pgfqpoint{\pgfutil@tempdima}{\pgf@yc}}%
%     \pgfpathlineto{\pgfqpoint{\pgfutil@tempdimb}{\pgf@yc}}%
%
\advance\pgf@xa\barratio\pgf@xb%                                      left x value + ratio*width
\pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@ya}}%
\pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@yb}}%
\pgfsetbuttcap
\pgfusepathqstroke
}%
}
\makeatother


The calling document code:

\documentclass[tikz,convert=false]{standalone}
\usepackage{tikz}
\usetikzlibrary{circuits,circuits.ee.IEC}
\usepackage{etoolbox}

\input{symbols/symbol.tex}

\newlength{\dimvoffset}
\setlength{\dimvoffset}{0.2cm}

\newlength{\lengtha}
\setlength{\lengtha}{150cm} % a
\newlength{\lengthb}
\setlength{\lengthb}{30cm}  % b
\def\ratioa{\lengtha/(\lengtha + \lengthb)} % compute ratio

\newlength{\lengthc}
\setlength{\lengthc}{160cm} % c
\newlength{\lengthd}
\setlength{\lengthd}{70cm}  % d
\def\ratiob{\lengthc/(\lengthc + \lengthd)} % compute ratio

\begin{document}
\begin{tikzpicture}[circuit ee IEC]
\draw (0,0) to [symbol={symbol shape ratio=\ratioa,Text=A \nodepart{textb} B, name = thesymbola}] (4,0);

\draw (4,0) to [symbol={symbol shape ratio=\ratiob,Text=C \nodepart{textb} D, name = thesymbolb}] (10,0);

\draw[|<->|,>= latex] ($(thesymbolb.south west)+(0,-\dimvoffset)$) -- ($(thesymbolb.bar south)+(0,-\dimvoffset)$) node[midway,below] (columnlength){};
\node[] at ($(columnlength)+(0,-\dimvoffset)$) {\tiny $l_{\mathrm{C}}$};

\draw[|<->|,>= latex] ($(thesymbolb.bar south)+(0,-\dimvoffset)$) -- ($(thesymbolb.south east)+(0,-\dimvoffset)$) node[midway,below] (columnlength){};
\node[] at ($(columnlength)+(0,-\dimvoffset)$) {\tiny $l_{D}$};

\end{tikzpicture}
\end{document}


Here is the same code which gives the error:

\documentclass[tikz,convert=false]{standalone}
\usepackage{tikz}
\usetikzlibrary{circuits,circuits.ee.IEC}
\usepackage{etoolbox}

\input{symbols/symbol.tex}

\newlength{\dimvoffset}
\setlength{\dimvoffset}{0.2cm}

\newlength{\lengtha}
\setlength{\lengtha}{150cm} % a
\newlength{\lengthb}
\setlength{\lengthb}{30cm}  % b
\def\ratioa{\lengtha/(\lengtha + \lengthb)} % compute ratio

\newlength{\lengthc}
\setlength{\lengthc}{160cm} % c
\newlength{\lengthd}
\setlength{\lengthd}{70cm}  % d
\def\ratiob{\lengthc/(\lengthc + \lengthd)} % compute ratio

\begin{document}
\begin{tikzpicture}[circuit ee IEC]
\draw (0,0) to [resistor] (4,0);

\draw (4,0) to [symbol={symbol shape ratio=\ratiob,Text=C \nodepart{textb} D, name = thesymbolb}] (10,0);

\draw[|<->|,>= latex] ($(thesymbolb.south west)+(0,-\dimvoffset)$) -- ($(thesymbolb.bar south)+(0,-\dimvoffset)$) node[midway,below] (columnlength){};
\node[] at ($(columnlength)+(0,-\dimvoffset)$) {\tiny $l_{\mathrm{C}}$};

\draw[|<->|,>= latex] ($(thesymbolb.bar south)+(0,-\dimvoffset)$) -- ($(thesymbolb.south east)+(0,-\dimvoffset)$) node[midway,below] (columnlength){};
\node[] at ($(columnlength)+(0,-\dimvoffset)$) {\tiny $l_{D}$};

\end{tikzpicture}
\end{document}
`