I am trying to create a custom tikz object (mainly based on Complex objects in TikZ: pgfkeys scope and best practice), called blk, which is basically a node with some additional anchor points and optional arguments.
For instance, here blk is simply a node with an additional text label below:
\documentclass[tikz]{standalone}
\usepackage{ifthen}
\makeatletter
% attribute of my custom object
\pgfkeys{
/blk/.cd,
label/.initial={},
}
% Custom object 'blk' :
\newcommand*{\blk}[1][]{\@blk[#1]}
\def\@blk[#1]#2(#3)#4;{{
\pgfkeys{/blk/.cd,#1}
\pgfkeysgetvalue{/blk/label}\@label
%
\node [draw,name/.expand once=#2] at (#3) {#4};
% label below 'blk'
\ifthenelse{\equal{\@label}{}}{%empty label
}{%
\node (lab) [below] at (#2.south) {\@label};
}
}}
\makeatother
\begin{document}
\begin{tikzpicture}
\blk[label=test blk]{A}(0,0){block with label};
\blk{B}(0,-2){block without label};
\end{tikzpicture}
\end{document}
which gives

As this object is mainly a node, I would like to be able to pass standard node options (like anchor, color, text width) through it, that is to say I would like to be able to
pass individual optional arguments as
\blk[label= test blk,color = blue]{C}(0,-3){block with label and with a style};
without having to manually add all the keys in the definition of my object,
and/or pass directly styles
\tikzset{active/.style={color=blue}} \blk[label= test blk,active]{C}(0,-3){block with label and with a style};
I feel that the posts How to submit a set of tikz command with pgfkeys? and Expansion Issues When Passing TikZ Styles to Macro Created by Macro may answer the second point, but I have some difficulties to understand them precisely as I am still struggling to understand tikz (and more generally latex) internal mechanics.
Edit To clarify the overall goal, here is my full blk object in its current state :
It is basically a node which has, in addition, a direction dir, a number of inputs nu and a number of output ny and a text label label.
When a block blk is created, the anchor points associated to the inputs and outputs are created automatically on the adequate side of the node (determined by its direction).
\makeatletter
\pgfkeys{
/blk/.cd,
ny/.initial=1,
nu/.initial=1,
dir/.initial={right},
name/.initial={},
label/.initial=,
height/.initial=-1,
align/.initial=center,
anchor/.initial=center,
borderColor/.initial=black,
txtwidth/.initial={},
color/.initial={},
}
\newcommand*{\blk}[1][]{\@blk[#1]}
\def\@blk[#1]#2(#3)#4;{{
\pgfkeys{/blk/.cd,#1}
% get and save the values of the arguments
\pgfkeysgetvalue{/blk/ny}\@ny
\pgfkeysgetvalue{/blk/nu}\@nu
\pgfkeysgetvalue{/blk/dir}\@dir
\pgfkeysgetvalue{/blk/label}\@label
\pgfkeysgetvalue{/blk/height}\@height
\pgfkeysgetvalue{/blk/align}\@align
\pgfkeysgetvalue{/blk/borderColor}\@borderColor
\pgfkeysgetvalue{/blk/txtwidth}\@blkwidth
\coordinate (blkPos) at (#3);%
\ifthenelse{\equal{\@blkwidth}{}}{
\node [draw=\@borderColor ,name/.expand once=#2,minimum height=\@height, align=\@align ,anchor =\pgfkeysvalueof{/blk/anchor}] at (blkPos) {#4};
}{
\node [draw=\@borderColor ,name/.expand once=#2,minimum height=\@height, align=\@align ,anchor =\pgfkeysvalueof{/blk/anchor},text width=\@blkwidth ] at (blkPos) {#4};
}
%\node [name/.expand once=#2] at (blkPos) {#4};
% orientation of the block left to right (standard) or right to left (feedback)
\ifthenelse{\equal{\@dir}{right}}{%
\coordinate (#2 inputSide) at (#2.west);
\coordinate (#2 outputSide) at (#2.east);
\pgfmathsetmacro{\minD}{-4}
}{%
\coordinate (#2 inputSide) at (#2.east);
\coordinate (#2 outputSide) at (#2.west);
\pgfmathsetmacro{\minD}{4}
}
% label of the block
\ifthenelse{\equal{\@label}{}}{%empty label
}{%
\node (lab) [below] at (#2.south) {\@label};
}
% height of the block
\newdimen{\yt}
\pgfextracty{\yt}{\pgfpointanchor{#2}{north}}
\newdimen{\yb}
\pgfextracty{\yb}{\pgfpointanchor{#2}{south}}
\pgfmathabs{\yt-\yb}
\pgfmathsetmacro{\height}{\pgfmathresult*0.035}
% adding inputs
\foreach \inNum in {1,...,\@nu}
{
% creation of the anchor points for the inputs
\coordinate (#2 initu\inNum) at ($(#2 inputSide) + (0,{(\@nu/2-((\inNum-1)+1/2))*\height/\@nu})$);
\coordinate (#2 u\inNum) at ($(#2 initu\inNum)+(\minD pt,0)$);
}
%adding outputs
\foreach \outNum in {1,...,\@ny}
{
\coordinate (#2 inity\outNum) at ($(#2 outputSide) + (0,{(\@ny/2-((\outNum-1)+1/2))*\height/\@ny})$);
\coordinate (#2 y\outNum) at ($(#2 inity\outNum)-(\minD pt,0)$);
}
}}
\makeatother
As you can see, I began to add additional keys to blk to pass optional arguments to the underlying node but this became tedious..
Together with another object called signal (in charge of drawing the path between 2 blocks), I can writte quite easily block diagrams
\begin{tikzpicture}
\blk[nu=3,ny=3,anchor = east,align=center]{A}(0,0){A};
\blk[nu=2,ny=1,anchor = east]{B}({$(A u2)-(1.5,0)$}){B};
\blk[dir=left,nu=2,ny=1,anchor = south east,align=center]{C}({$(B.east)+(0,0.5)$}){C};
\blk[ny=1,align=center]{D}({$(B u2) +(-2,0)$}){D};
\blk[nu=2,ny=1,anchor=north east]{E}({$(B.east)-(0,0.5)$}){E};
% direct link can be handled easily
\signal(C y1)(B u1);
\signal(B y1)(A u2);
\signal(E y1)(A u3);
\signal(D y1)(B u2);
% backward signals
\signal(A y1)(C u1);
\signal[ctrl=1,yoffset={-0.9cm,0},xoffset={0.1cm,0.1cm}](A y2)(E u1);
\signal[ctrl=1,yoffset={-1cm,0}](A y3)(E u2);
\end{tikzpicture}
which gives


\picoffered bytikz. – Apr 15 '15 at 08:25blkis to build block diagrams. That is to say that each block has a given number of inputs/outputs (specified as optional argument) with associated anchor points and labels. The inputs and outputs of these blocks can then be linked together through a custom objectsignalwhich draws an orthogonal path. The example given here is just the basis of theblkobject. So I am not sure to see how\pic(which I did not know though) could help me. – Pierre Vuillemin Apr 15 '15 at 08:55pic. Try it :-) – Apr 15 '15 at 09:00