summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/familytree/ft-sibling.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/contrib/familytree/ft-sibling.dtx')
-rw-r--r--macros/latex/contrib/familytree/ft-sibling.dtx333
1 files changed, 333 insertions, 0 deletions
diff --git a/macros/latex/contrib/familytree/ft-sibling.dtx b/macros/latex/contrib/familytree/ft-sibling.dtx
new file mode 100644
index 0000000000..fcb6a3645d
--- /dev/null
+++ b/macros/latex/contrib/familytree/ft-sibling.dtx
@@ -0,0 +1,333 @@
+% \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
+%
+% \section{Sibling Box (\texttt{ft-sibling.dtx})}
+%
+% \DescribeMacro{\sblngdef}
+% \cmd{\sblngdef
+% \marg{new box name}
+% \marg{name list of individual boxes}
+% }
+% \medskip
+%
+% \marg{name list of individual boxes} is the comma separated box names
+% which are defined by |\indvdldef|.
+% They are aligned and connected by a line.
+% All names are NOT \CS{} (no backslash).
+%
+% If any of the siblings has a |\maleline| attribute, then the length of
+% all lines are set to the longest one.
+% \medskip
+%
+% Like |\indvdldef|, |\sblngdef| defines a few connection points (\CS)
+% to be used later. The origin is left-bottom of the box and the unit is |pt|.
+%
+% \begin{itemize}
+% \item \meta{box name}|nameCY|
+% \par
+% Center of the line which connects all the siblings.
+% \par
+% The line begins at the head of the child-mark of the
+% first element of the given list, and ends at the last element.
+%
+% \item \meta{box name}\meta{individual box name}|nameCY|
+% \par
+% Center of the height for each individual name.
+% \par
+% In other words, shifted \meta{individual box name}|nameCY| which
+% |\indvdldef| defined.
+% \end{itemize}
+% \medskip
+%
+% \noindent
+% \DescribeMacro{\ivaldef}
+% \cmd{\ivaldef
+% \marg{new box name}
+% \marg{length}
+% }
+% \medskip
+%
+% Sometimes an extra space is necessary between the siblings who have
+% many descendants.
+% For such spaces, you can define an interval box by |\ivaldef|. It
+% defines an blank box who has a specified size. There are three
+% pre-defined interval boxes, |\ival|, |\ivali|, and |\ivalii|. They
+% have the size of |0.5em|, |1em|, |2em| for each.
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{Customization}
+%
+% \DescribeMacro{\sblngboxcfg}
+% \cmd{\sblngboxcfg
+% \marg{space between the siblings}
+% }
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{Example}
+%
+% \begin{enumerate}
+% \item
+% \srcfig{fig2base}
+%
+% \item
+% \srcfig{fig2sis}
+%
+% \item
+% \srcfig{fig2ival}
+% \end{enumerate}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsectImpl
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsubsection{Interval box}
+%
+% \DescribeMacro{\ftivaldef}
+% \DescribeMacro{\ivaldef}
+%
+% \begin{macrocode}
+\newcommand{\ftivaldef}[2]{% box-name length
+ \ft@newnamebox{#1}{\vbox to #2{\hsize=1pt}}%
+ \ft@len=#2%
+ \ft@namexdefstrip{#1ival}{\ft@len}% just a flag
+ \divide\ft@len 2%
+ \ft@namexdefstrip{#1nameCY}{\ft@len}%
+}
+\ft@alias{ivaldef}
+% \end{macrocode}
+%
+% \parag{Pre-defined interval boxes}
+%
+% \DescribeMacro{\ftival}
+% \DescribeMacro{\ival}
+% \NoDescription
+% \begin{macrocode}
+\ftivaldef{ftival}{.5\ft@unit}
+\ft@alias{ival}
+\ft@alias{ivalnameCY}
+\ft@alias{ivalival}
+% \end{macrocode}
+%
+% \DescribeMacro{\ftivali}
+% \DescribeMacro{\ivali}
+% \NoDescription
+% \begin{macrocode}
+\ftivaldef{ftivali}{1\ft@unit}
+\ft@alias{ivali}
+\ft@alias{ivalinameCY}
+\ft@alias{ivaliival}
+% \end{macrocode}
+%
+% \DescribeMacro{\ftivalii}
+% \DescribeMacro{\ivalii}
+% \NoDescription
+% \begin{macrocode}
+\ftivaldef{ftivalii}{2\ft@unit}
+\ft@alias{ivalii}
+\ft@alias{ivaliinameCY}
+\ft@alias{ivaliiival}
+% \end{macrocode}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \parag{Customization}
+%
+% \DescribeMacro{\ftsblngboxcfg}
+% \DescribeMacro{\sblngboxcfg}
+%
+% \begin{macrocode}
+\newlength{\ft@sblng@vsp}
+\setlength{\ft@sblng@vsp}{.5\baselineskip}%
+\newcommand{\ftsblngboxcfg}[1]{% space-length
+ \global\ft@sblng@vsp=#1%
+}
+\ft@alias{sblngboxcfg}
+% \end{macrocode}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsubsection{Sibling box --- core}
+%
+% If any of the siblings has an attributes |\maleline| or alike, then
+% finds the longest one and sets its length to all others.
+% Between the name and |\maleline|, insert a space
+% |\ft@namebox@maleline@sp|.
+%
+% \begin{macrocode}
+\newcommand{\ft@sblng@maleline}[2]{% sibling y
+ \@ifundefined{#1hasmaleline}{}{%
+ \ft@x=\@nameuse{#1nameX}pt\relax%
+ \ifdim\ft@x<\ft@width%
+ \put(\strip@pt\ft@x,\strip@pt#2){%
+ \line(1,0){\strip@pt\dimexpr\ft@width - \ft@x}%
+ }%
+ \fi%
+ }%
+}
+% \end{macrocode}
+%
+% \DescribeMacro{\ft@sblng@connect}
+%
+% \begin{macrocode}
+\newlength{\ft@c}
+\newcommand{\ft@sblng@connect}[1]{% box-name
+ %
+ % draw a line to connect all the siblings
+ % length = eldest CY - youngest CY
+ % and calculate nameCY of the box
+ % nameCY = length/2 + youngest CY
+ %
+ \ft@y=\@nameuse{#1\ft@lastcmark nameCY}pt%
+ \ft@dbgplot{1,\strip@pt\ft@y}%
+ \ft@yy=\@nameuse{#1\ft@firstcmark nameCY}pt%
+ \ft@dbgplot{1,\strip@pt\ft@yy}%
+ \ft@len=\dimexpr\ft@yy - \ft@y\relax%
+ %
+ \ft@c=\dimexpr\ft@len/2 + \ft@y\relax%
+ \ft@namexdefstrip{#1nameCY}{\ft@c}%
+ \ft@dbgplot{1,\strip@pt\ft@c}%
+ %
+ \ifnum\@nameuse{\ft@lastcmark hascmark}=\ftadopted%
+ \advance\ft@y -\dimexpr\ft@cmarkbox@adopted@sep/2\relax%
+ \advance\ft@len \dimexpr\ft@cmarkbox@adopted@sep/2\relax%
+ \fi%
+ \ifnum\@nameuse{\ft@firstcmark hascmark}=\ftadopted%
+ \advance\ft@len \dimexpr\ft@cmarkbox@adopted@sep/2\relax%
+ \fi%
+ %
+ \ifdim\ft@len<2pt%
+ %\ft@len=\@nameuse{\ft@firstcmark nameCY}pt\relax%
+ \else%
+ \advance\ft@y -\dimexpr\arrayrulewidth/2\relax%
+ \advance\ft@len \arrayrulewidth%
+ \put(0,\strip@pt\ft@y){\line(0,1){\strip@pt\ft@len}}%
+ \fi%
+}
+% \end{macrocode}
+%
+% \DescribeMacro{\ft@sblng@layout}
+%
+% \begin{macrocode}
+\newcommand{\ft@sblng@layout}[2]{% box-name individual-name-list
+ \ft@newnamebox{#1}{%
+ \edef\@w{\strip@pt\ft@width}%
+ \edef\@h{\strip@pt\ft@height}%
+ \begin{picture}(\@w,\@h)%
+ \ft@dbgframe{\@w,\@h}%
+ %
+ \@for\@temptokena:=#2\do{%
+ \edef\ft@sblng@name{\@temptokena}%
+ \ft@dbgmsg{H \the\ft@height,%
+ \ft@sblng@name nameCY \@nameuse{\ft@sblng@name nameCY}pt,%
+ \the\ft@y}%
+ %
+ % calculate the nameCY for each
+ \advance\ft@height -\ht\@nameuse{\ft@sblng@name}%
+ \global\ft@y=\dimexpr\@nameuse{\ft@sblng@name nameCY}pt%
+ + \ft@height\relax%
+ \ft@dbgplot{0,\strip@pt\ft@y}%
+ \ft@namexdefstrip{#1\ft@sblng@name nameCY}{\ft@y}%
+ %
+ % align the malelines
+ \ft@sblng@maleline{\ft@sblng@name}{\ft@y}%
+ %
+ % place the individual boxes
+ \put(0,\strip@pt\ft@height){\usebox{\@nameuse{\ft@sblng@name}}}%
+ \advance\ft@height -\dimexpr\dp\@nameuse{\ft@sblng@name}%
+ + \ft@sblng@vsp\relax%
+ }%
+ %
+ % connect them
+ \ifx\ft@firstcmark\relax\else%
+ \ifx\ft@firstcmark\ft@lastcmark\else%
+ \ft@sblng@connect{#1}%
+ \fi%
+ \fi%
+ \end{picture}%
+ }%
+ % height should hold the original value
+ \ft@nameboxsz{#1}{\ft@height}{\ft@depth}%
+}
+% \end{macrocode}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsubsection{Sibling box --- interface}
+%
+% \DescribeMacro{\ftsblngdef}
+% \DescribeMacro{\sblngdef}
+%
+% \begin{macrocode}
+\newcommand{\ftsblngdef}[2]{% box-name comma-separated-individuals
+ %
+ % calculate the size of the box
+ \ft@width=0pt%
+ \ft@height=0pt%
+ \ft@theight=0pt%
+ \ft@box@has@malelinefalse%
+ \@tempswatrue%
+ \let\ft@firstcmark=\relax%
+ \let\ft@lastcmark=\relax%
+ \def\ft@dpri##1{\ft@dbgmsg{##1 W \the\ft@width, H \the\ft@height,%
+ D \the\ft@depth}}%
+ \ft@dpri{h0}%
+ \@for\@temptokena:=#2\do{%
+ \if@tempswa%
+ \xdef\ft@eldest{\@temptokena}%
+ \@tempswafalse%
+ \fi%
+ \xdef\ft@youngest{\@temptokena}%
+ \@ifundefined{ft@firstcmark}{%
+ \@ifundefined{\ft@youngest hascmark}{}{%
+ \global\let\ft@firstcmark=\ft@youngest%
+ }%
+ }{%
+ \@ifundefined{\ft@youngest hascmark}{}{%
+ \global\let\ft@lastcmark=\ft@youngest%
+ }%
+ }%
+ \@ifundefined{\ft@youngest hasmaleline}{}{%
+ \global\ft@box@has@malelinetrue%
+ }%
+ %
+ \setlength{\ft@len}{\wd\@nameuse{\ft@youngest}}%
+ \ifdim\ft@width<\ft@len%
+ \global\ft@width=\ft@len%
+ \@ifundefined{\ft@youngest hasmaleline}{%
+ \global\ft@widest@has@no@malelinetrue%
+ }{%
+ \global\ft@widest@has@no@malelinefalse%
+ }%
+ \fi%
+ \global\advance\ft@theight \dimexpr\ht\@nameuse{\ft@youngest}%
+ + \dp\@nameuse{\ft@youngest} + \ft@sblng@vsp\relax%
+ \ft@dpri{\ft@youngest}%
+ }%
+ \advance\ft@theight -\ft@sblng@vsp%
+ \ft@depth=\dp\@nameuse{\ft@youngest}%
+ \ft@height=\ft@theight%
+ \advance\ft@height -\ft@depth%
+ \ifft@widest@has@no@maleline%
+ \ifft@box@has@maleline%
+ \global\advance\ft@width \dimexpr\ft@namebox@maleline@sp%
+ + \ft@namebox@maleline@length\relax%
+ \fi%
+ \fi%
+ %
+ % layout the all boxes
+ \ft@sblng@layout{#1}{#2}%
+ \ft@dbgbox{\@nameuse{#1}}%
+}
+\ft@alias{sblngdef}
+% \end{macrocode}