% !TeX spellcheck = en_US
% !TeX root = tikz-ext-manual.tex
% Copyright 2022 by Qrrbrbirlbel
%
% This file may be distributed and/or modified
%
% 1. under the LaTeX Project Public License and/or
% 2. under the GNU Free Documentation License.
%
\section{Node Families}
\begin{tikzlibrary}{ext.node-families}
  With this library the user can instruct multiple nodes to have the same
  width, height, text width, text height or text width.
  This uses the hook \referenceKeyandIndexO{execute at end picture} to write the nodes'
  measurements to the \filetype{aux} file.
  
  Unfortunately, this does not work with the |external| library.\indexLibraryO{external}%
  \footnote{First of all, I can't figure out how to use the \textsc{aux} file during externalization since it gets written to the \textsc{log} instead.
            And then there's the question about how \texttt{external} would notice the need to export the picture again until it's stable \dots}

  \inspiration{NodeFam-Q}{NodeFam-A}

\end{tikzlibrary}

Before we get to the interesting keys, a common prefix can be set for the families' names.
Initially this is |\pgfpictureid-| so that families of different pictures don't interact.
\begin{key}{/tikz/node family/prefix=\meta{prefix}(initially \string\pgfpictureid-)}
The family names are prefixed with the value of |/tikz/node family/prefix|.
\end{key}

\subsection{Text Box}
\label{ssec:nf-text}
The following keys~-- when setup, see below~-- work with every shape with one single node part.%
\footnote{Technically, it will also work with shapes with multiple node parts but it will only affect the main node part.}
Initially though, only \referenceShapeandIndexO{circle} and \referenceShapeandIndexO{rectangle} are set up that way.
\begin{key}{/tikz/node family/text height=\meta{name} (initially \{\})}
Nodes with the same \meta{name} will have the same text height.
An empty \meta{name} disables the evaluation by the library.
\end{key}

\begin{key}{/tikz/node family/text depth=\meta{name} (initially \{\})}
Nodes with the same \meta{name}  will have the same text depth.
An empty \meta{name} disables the evaluation by the library.
\end{key}

\begin{key}{/tikz/node family/text width=\meta{name} (initially \{\})}
Nodes with the same \meta{name} will have the same text width.
An empty \meta{name} disables the evaluation by the library.
\end{key}

\begin{key}{/tikz/node family/text=\meta{name}}
Sets |text height|, |text depth| and |text width|.
\end{key}

Since the width of the node's content's box is setup much earlier,
the previous key only extends the width of that box which would make the text
seem as if it where aligned to the left.
With |text width family align| this can changed.
\begin{key}{/tikz/node family/text width align=\meta{alignment}(initially center)}
\meta{alignment} is one of |left|, |center| or |right|.

\begin{codeexample}[preamble=\usetikzlibrary{positioning,ext.node-families},/tikz/node distance=.5cm]
\tikzexternaldisable % ext.node-families does not work with active externalization
\begin{tikzpicture}[nodes={rectangle, draw, node family={text width=manual, text width align=right}}]
\node (a) {Foo};
\node[below=of a] (b) {Foobar};
\end{tikzpicture}
\end{codeexample}
\end{key}

\begin{key}{/tikz/node family/setup shape=\meta{shape}}
This adds instructions to the \meta{shape}'s definition which
adjust the text box's dimensions according to the family.

This should be only used once per shape.
\end{key}

\subsection{Minimum Width/Height}
While the keys of the previous subsection work well enough for nodes of the same shape
(and the same |inner sep|s), for different node shapes the text box dimensions will be used
differently for the node's total dimension.

For this, the following keys are necessary.
When one of the keys are used the values of |minimum width| and/or |minimum height| are set to |nf_width| or |nf_height| respectively.
\begin{key}{/tikz/node family/width=\meta{name} (initially \{\})}
Nodes with the same \meta{name} will have the same \referenceKeyandIndexO[/pgf/]{minimum width}.
An empty \meta{name} disables the evaluation by the library.
\begin{codeexample}[preamble=\usetikzlibrary{positioning,ext.node-families},/tikz/node distance=.5cm]
\tikzexternaldisable % ext.node-families does not work with active externalization
\begin{tikzpicture}[nodes={rectangle, draw, node family/width=manual}]
\node (a) {Foo};
\node[below=of a] (b) {Foobar};
\end{tikzpicture}
\end{codeexample}
\end{key}
\begin{key}{/tikz/node family/height=\meta{name} (initially \{\})}
Nodes with the same \meta{name} will have the same \referenceKeyandIndexO[/pgf/]{minimum height}.
An empty \meta{name} disables the evaluation by the library.
\end{key}
\begin{key}{/tikz/node family/size=\meta{name}}
Sets both |height| and |width|.
\end{key}

\clearpage
\subsection{More shapes that support the keys \texttt{width} and \texttt{height}}
\begin{tikzlibrary}{ext.node-families.shapes.geometric}
  This library adds support for the keys \referenceKeyandIndex[/tikz/node family/]{width} and
  \referenceKeyandIndex[/tikz/node family/]{height} for the shapes of
  the \pgfname\space library \referenceLibraryandIndexO{shapes.geometric}.

  \inspirationQ{NodeFam-Ellipse}
\end{tikzlibrary}
The shapes are also setup for the keys from subsection~\ref{ssec:nf-text}.

\begin{codeexample}[width=9cm,preamble=\usetikzlibrary{ext.node-families.shapes.geometric}]
\tikzexternaldisable % ext.node-families does not work with active externalization
\begin{tikzpicture}
\foreach \cnt[count=\Cnt] in {a,...,h}
  \node[draw, diamond, node family/text=aTOh] (\cnt)
    at (right:\Cnt) {\cnt};
\draw[help lines] (a.south) -- (h.south) (a.north) -- (h.north) (a.base-|a.west) -- (h.base-|h.east);
\end{tikzpicture}
\end{codeexample}
\endinput