summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/familytree/ft-gens.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/contrib/familytree/ft-gens.dtx')
-rw-r--r--macros/latex/contrib/familytree/ft-gens.dtx365
1 files changed, 365 insertions, 0 deletions
diff --git a/macros/latex/contrib/familytree/ft-gens.dtx b/macros/latex/contrib/familytree/ft-gens.dtx
new file mode 100644
index 0000000000..f179f060ec
--- /dev/null
+++ b/macros/latex/contrib/familytree/ft-gens.dtx
@@ -0,0 +1,365 @@
+% \iffalse
+% Copyright 2022 Jiro Senju
+%
+% This package is free software; you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation; either version 2 of the License, or
+% any later version.
+%
+% This package is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this package. If not, see <http://www.gnu.org/licenses/>.
+% \fi
+%
+% \newcommand{\tOne}{Parent-child Relationship Box or Generations Box}
+% \newcommand{\tTwo}{(\texttt{ft-gens.dtx})}
+% \section[\tOne{} \tTwo]{\tOne\\\tTwo}
+%
+% \DescribeMacro{\pcdef}
+% \cmd{\pcdef
+% \marg{new box name}
+% \marg{parent box name}
+% \marg{child box name}
+% }
+% \medskip
+%
+% Defines a parent-child relationship box.
+% Connects the given \meta{parent box} and \meta{child box} by a line,
+% and creates a new box \meta{new box name}.
+%
+% \meta{parent box} is a box who has only one line from an individual
+% name to one's child. For example, the box created by |\indvdldef| with
+% |\maleline| attribute (and equivalent) is specified.
+% Obviously, \meta{child box} is a box who has a line to one's parent.
+% For example, the box created by |\indvdldef| with |\biological| or
+% |\adopted| is specified as a child mark.
+%
+% |\pcdef| is a simplified version of |\gensdef|, which is discussed next.
+% \bigskip
+%
+% \noindent
+% \DescribeMacro{\gensdef}
+% \cmd{\gensdef
+% \marg{new box name}
+% \marg{parent box name}
+% \marg{list of connection-pair}
+% }
+%
+% \begin{tabbing}
+% \hspace{4em} \=\kill
+% \texttt{connection-pair :=}\\
+% \> \marg{individual box name in the parent box}\\
+% \> \marg{child box name}
+% \end{tabbing}
+% \medskip
+%
+% Defines a two-generations box.
+% Same to |\pcdef|, \meta{child box} is a box who has only one line to
+% the parent, but \meta{parent box} can have multiple lines to one's child.
+% It is \meta{connection-pair} that makes it clear which parent connects
+% to which child box.
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{Example}
+%
+% \begin{enumerate}
+% \item
+% |\sblngdef| for daughters, |\pcdef|, and then |\sblngdef| for their
+% parent generation.
+% \srcfig{fig3Robert1}
+%
+% \needspace{2\baselineskip}
+% \item
+% two |\sblngdef|, and then |\gensdef|. The result is essentially same.
+% One difference is the space between the siblings which was
+% automatically adjusted in previous example.
+% \srcfig{fig3Robert2}
+% \end{enumerate}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{The order of connecting multiple boxes}
+% \label{sec:Lily1}
+%
+% If we get |\sblngdef| as a tool to align the individual boxes in
+% column, then |\pcdef| and |\gensdef| are the tool to align the boxes
+% in row.
+% When the siblings have their child for each, then there are multiple
+% parent-child relationships, so it is better to call it generations box
+% rather than parent-child box.
+%
+% There are two ways to draw such tree. One is to define parent-child
+% first and then define the siblings of the parent generation. The other
+% is in the reverse order, eg. to define the siblings of the parent
+% generation first and then define the parent-child relationship for each.
+%
+% Let's consider about these two ways.
+%
+% \begin{enumerate}
+% \needspace{2\baselineskip}
+% \item
+% define two parent-child relationships, and then define the siblings.
+%
+% \srcfig{fig3Lily1}
+%
+% \needspace{3\baselineskip}
+% \item
+% define the sisters, and then define the parent-child for each.
+%
+% \srcfig{fig3Lily2}
+% \end{enumerate}
+%
+% As you see, by the 1st method the length of two lines to their child
+% differs and the positions (in horizontal) of the child generation are
+% not equal. That makes the tree uneasy to understand straightforward.
+% It is because that the feature of |\sblngdef| to set the line length
+% to the longest one didn't work.
+% The argument passed to |\sblngdef| were already connected to the child,
+% so if |\sblngdef| extended the line it would be much worse result.
+%
+% On the other hand, by the 2nd method, the argument passed to
+% |\sblngdef| were not connected to the child. So it is harmless if
+% |\sblngdef| extends the line.
+% \smallskip
+%
+% Even if you took the 1st method, there still exists to make the line
+% length equal.
+% Using |\indvdldef| feature to adjust the line length, set the length
+% of Lily's |\femaleline| (|\matrilineal|) to the one of Petunia's.
+% To achieve this, calculate the difference of the name length of these
+% sisters and give an optional argument of |\indvdldef|.
+% The result should be same to above.
+% \medskip
+%
+% \srcfig{fig3Lily3}
+% \medskip
+%
+% You can get the same result if you use |\nameboxcfg| since it has a
+% feature to set the length of a line to child.
+% But it is not a good idea to use |\nameboxcfg| every time when you
+% |\indvdldef|. The value set by |\nameboxcfg| should be applied wider,
+% and it is not supposed to use for a single |\indvdldef|. It is better
+% to append an optional argument to |\indvdldef|.
+% \smallskip
+%
+% There is one more option. It is to set the length of Lily's name to Petunia's.
+% By this method, the space between Lily's name and the line to child
+% becomes wider and the length of lines become equal.
+% \medskip
+%
+% \srcfig{fig3Lily4}
+% \medskip
+%
+% The sequence or the order to define and connect the boxes is important.
+% In connecting the boxes, this package considers the size of the
+% being connected individual boxes. For example, the sibling box
+% considers the height of the
+% individual box and makes the boxes to be never overlapped.
+% But in connecting a child to the already defined sibling box, this
+% feature doesn't work. So the children of the siblings may be
+% overlapped. In this case, you need to insert the interval box between
+% the siblings manually.
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsectImpl
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsubsection{Generations box --- core}
+%
+% \iffalse
+% \parag{Customization}
+%
+% \DescribeMacro{\ftgenscfg}
+% \NoDescription
+% \begin{macrocode}
+% \newcommand{\ftgenscfg}[1]{%
+% }
+% \end{macrocode}
+% \fi
+%
+% \parag{Connection pair}
+%
+% \DescribeMacro{\ft@getpair}
+% Extracts a connection-pair from the given list,
+% defines the connection-point in the parent box (the former of the pair)
+% as |\ft@cpoint|, and defines the child box name (the latter of the
+% pair) as |\ft@kids|.
+% \smallskip
+%
+% \begin{macrocode}
+\def\ft@getpair#1#2#3{% connection-pair parent-box-name
+ \ft@dbgmsg{args #1, #2, #3}%
+ \@ifundefined{#3#1nameCY}{%
+ \@ifundefined{#3#1mrrgCY}{%
+ \xdef\ft@cpoint{#1nameCY}%
+ }{%
+ \xdef\ft@cpoint{#3#1mrrgCY}%
+ }%
+ }{%
+ \xdef\ft@cpoint{#3#1nameCY}%
+ }%
+ \xdef\ft@kids{#2}%
+}
+% \end{macrocode}
+%
+% \parag{Top margin}
+%
+% \DescribeMacro{\def@calc@xtop}
+%
+% \begin{macrocode}
+\newcommand{\ft@calc@xtop}[4]{% name parent cpoint kids
+ % top half of kids
+ \ft@len=\dimexpr\ht\@nameuse{#4} - \@nameuse{#4nameCY}pt\relax\relax%
+ % top half of parent cpoint
+ \@tempskipa=\dimexpr\ht\@nameuse{#2} - \@nameuse{#3}pt\relax\relax%
+ %
+ \ifdim\ft@len<\@tempskipa%
+ \ft@len=0pt%
+ \else%
+ \advance\ft@len -\@tempskipa%
+ \fi%
+ \global#1=\ft@len%
+}
+% \end{macrocode}
+%
+% \parag{Bottom margin}
+%
+% \DescribeMacro{\ft@calc@xbottom}
+%
+% \begin{macrocode}
+\newcommand{\ft@calc@xbottom}[4]{% name parent cpoint kids
+ % bottom half of kids
+ \ft@len=\@nameuse{#4nameCY}pt\relax%
+ % bottom half of parent cpoint
+ \@tempskipa=\@nameuse{#3}pt\relax%
+ %
+ \ifdim\ft@len=\@tempskipa%
+ \ft@len=0pt%
+ \global\setlength{\ft@depth}{\dp\@nameuse{#2}}%
+ \ifdim\ft@depth<\dp\@nameuse{#4}%
+ \global\setlength{\ft@depth}{\dp\@nameuse{#4}}%
+ \fi%
+ \else%
+ \ifdim\ft@len<\@tempskipa%
+ \ft@len=0pt%
+ \global\setlength{\ft@depth}{\dp\@nameuse{#2}}%
+ \else%
+ \advance\ft@len -\@tempskipa%
+ \global\setlength{\ft@depth}{\dp\@nameuse{#4}}%
+ \fi%
+ \fi%
+ \global#1=\ft@len%
+}
+% \end{macrocode}
+%
+% \parag{Calculate the box size}
+%
+% \DescribeMacro{\ft@gens@size}
+%
+% \begin{macrocode}
+\newlength{\ft@xtop}
+\newlength{\ft@xbottom}
+\newcommand{\ft@gens@size}[2]{% parent-box connect-pair-list
+ \@tempswatrue%
+ \ft@width=0pt%
+ \@for\@temptokena:=#2\do{%
+ \expandafter\ft@getpair\@temptokena{#1}%
+ \ft@dbgmsg{\ft@cpoint and \ft@kids}%
+ \if@tempswa%
+ \ft@calc@xtop{\ft@xtop}{#1}{\ft@cpoint}{\ft@kids}%
+ \@tempswafalse%
+ \fi%
+ \setlength{\ft@len}{\wd\@nameuse{\ft@kids}}%
+ \ifdim\ft@width<\ft@len%
+ \global\ft@width=\ft@len%
+ \fi%
+ }%
+ \ft@calc@xbottom{\ft@xbottom}{#1}{\ft@cpoint}{\ft@kids}%
+ \ft@dbgmsg{xtop \the\ft@xtop, xbottom \the\ft@xbottom}%
+ %
+ \ft@x=\dimexpr\wd\@nameuse{#1}% - \ft@cmarkbox@length\relax%
+ \ft@dbgmsg{x \the\ft@x}%
+ \advance\ft@width \ft@x%
+ \ft@dbgmsg{w \the\ft@width}%
+ \ft@height=\dimexpr\ht\@nameuse{#1} + \ft@xtop + \ft@xbottom\relax%
+ \ft@dbgmsg{kids H \the\ht\@nameuse{\ft@kids}}%
+ \ft@dbgmsg{H \strip@pt\ft@height, D \strip@pt\ft@depth}%
+}
+% \end{macrocode}
+%
+% \parag{Layout}
+%
+% \DescribeMacro{\ft@gens@layout}
+%
+% \begin{macrocode}
+\newcommand{\ft@gens@layout}[3]{%
+ % box-name parent-box-name {{parent-name} {child-name}, ...}
+ \ft@newnamebox{#1}{%
+ \edef\@w{\strip@pt\ft@width}%
+ \edef\@h{\strip@pt\ft@height}%
+ \begin{picture}(\@w,\@h)%
+ \ft@dbgframe{\@w,\@h}%
+ %
+ \ft@y=\ft@xbottom%
+ \ft@dbgplot{0,\strip@pt\ft@y}%
+ \put(0,\strip@pt\ft@y){\usebox{\@nameuse{#2}}}%
+ \advance\ft@y \@nameuse{#2nameCY}pt%
+ \ft@namexdefstrip{#1nameCY}{\ft@y}%
+ %\ft@namexdefstrip{#1#2nameCY}{\ft@y}%
+ %
+ \@for\@temptokena:=#3\do{%%
+ \expandafter\ft@getpair\@temptokena{#2}%
+ \ft@dbgmsg{\ft@cpoint and \ft@kids}%
+ %
+ \ft@y=\dimexpr\ft@xbottom + \@nameuse{\ft@cpoint}pt\relax%
+ \ft@dbgmsg{parent cpoint \the\ft@y}%
+ \ft@dbgplot{\strip@pt\ft@x,\strip@pt\ft@y}%
+ %
+ \advance\ft@y -\@nameuse{\ft@kids nameCY}pt%
+ \ft@dbgmsg{final child y \the\ft@y}%
+ \put(\strip@pt\ft@x,\strip@pt\ft@y){%
+ \usebox{\@nameuse{\ft@kids}}}%
+ \ft@namexdefstrip{#1\ft@kids Y}{\ft@y}%
+ }%
+ \end{picture}%
+ }%
+}
+% \end{macrocode}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsubsection{Generations box --- interface}
+%
+% \DescribeMacro{\ftgensdef}
+%
+% \begin{macrocode}
+\newcommand{\ftgensdef}[3]{%
+ % box-name parent-box-name {{parent-name} {child-name}, ...}
+ %
+ % calculate the size of the new box
+ \ft@gens@size{#2}{#3}%
+ %
+ % draw them all
+ \ft@gens@layout{#1}{#2}{#3}%
+ %
+ \@ifundefined{#2hascmark}{}{%
+ \ft@namexdef{#1hascmark}{\@nameuse{#2hascmark}}%
+ }%
+ \ft@nameboxsz{#1}{\ft@height}{\ft@depth}%
+}
+\ft@alias{gensdef}
+% \end{macrocode}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsubsection{Parent-child box --- interface}
+%
+% \DescribeMacro{\ftpcdef}
+%
+% \begin{macrocode}
+\newcommand{\ftpcdef}[3]{% box-name parent-box-name child-box-name
+ \ftgensdef{#1}{#2}{{#2}{#3}}%
+}
+\ft@alias{pcdef}
+% \end{macrocode}