diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/synttree/synttree.dtx |
Initial commit
Diffstat (limited to 'macros/latex/contrib/synttree/synttree.dtx')
-rw-r--r-- | macros/latex/contrib/synttree/synttree.dtx | 999 |
1 files changed, 999 insertions, 0 deletions
diff --git a/macros/latex/contrib/synttree/synttree.dtx b/macros/latex/contrib/synttree/synttree.dtx new file mode 100644 index 0000000000..5c219f1761 --- /dev/null +++ b/macros/latex/contrib/synttree/synttree.dtx @@ -0,0 +1,999 @@ +%% \CheckSum{753} +% \iffalse meta-comment +%% synttree.dtx +%% Package `synttree' for use with LaTeX 2e +%% Version 1.4.2 +% +% See the section "Author and License" below for copyright and licensing +% information +% +% \fi +% +%% \CharacterTable +%% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z +%% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z +%% Digits \0\1\2\3\4\5\6\7\8\9 +%% Exclamation \! Double quote \" Hash (number) \# +%% Dollar \$ Percent \% Ampersand \& +%% Acute accent \' Left paren \( Right paren \) +%% Asterisk \* Plus \+ Comma \, +%% Minus \- Point \. Solidus \/ +%% Colon \: Semicolon \; Less than \< +%% Equals \= Greater than \> Question mark \? +%% Commercial at \@ Left bracket \[ Backslash \\ +%% Right bracket \] Circumflex \^ Underscore \_ +%% Grave accent \` Left brace \{ Vertical bar \| +%% Right brace \} Tilde \~} +%% +%\iffalse This is a METACOMMENT +% +% Version: Date: Changes: +% 0.9 1998/07/19 First version as a .dtx distibution. +% 0.9a ? ? +% 1.0 ? ? +% 1.0a 1999/10/02 Bugfix: bt combination changed to x. +% 1.1 1999/10/13 More children, better code. +% 1.2 2001 Totally new system +% 1.3 2004/11/07 New system up and running. +% 1.3.1 2004/11/07 Prepared for packaging, clarified licensing. +% 2004/12/30 Ignore leading and trailing spaces in labels. +% 2005/04/13 Allow up to 10 children (or any number, in theory). +% 1.4 2005/05/01 Allow any number of children, just warn. +% Updated documentation. +% 1.4.1 2006/07/20 Remove spurious spaces in output. +% Simplify label typesetting. +% 1.4.2 2008/03/30 Fix dot option warning message. +% Some refactoring to allow hacks. +% +%<*driver> +\documentclass[a4paper]{ltxdoc} +\usepackage[specials]{synttree} +\EnableCrossrefs + %\DisableCrossrefs % Say \DisableCrossrefs if index is ready +\CodelineIndex +\RecordChanges % Gather update information + %\OnlyDescription % comment out for implementation details + \OldMakeindex % use if your MakeIndex is pre-v2.9 +\setlength\hfuzz{15pt} % dont make so many +\hbadness=7000 % over and under full box warnings +\begin{document} + \DocInput{synttree.dtx} +\end{document} +%</driver> +% +%\fi +%\MakeShortVerb{\"} +% \title{The "synttree" package for typesetting syntactic +% trees.\footnote{Package version 1.4.2}} +% \author{Matijs van Zuijlen\footnote{e-mail: \texttt{mvz@xs4all}; web: +% \texttt{http://www.matijs.net/}}} +% +% \maketitle +% +% \begin{abstract} +% The "synttree" package provides a simple way to typeset syntactic +% trees as used in Chomsky's Generative Grammar. +% \end{abstract} +% +% {\parskip 0pt ^^A We have to reset \parskip +% ^^A (bug in \LaTeX) +% \tableofcontents +% } +% \section{Introduction} +% +% The "synttree" package provides a macro for creating syntactic tree +% structures such as those used in Noam Chomsky's Generative Grammar. +% It is designed to create a tree that looks nice, without manual +% tweaking, and with as little use of `special effects', such as +% PostScript, as possible. +% +% Since the application is very specific, there is no need for a very +% complex set of options: "synttree" is designed to do one thing, and do +% it well. +% +% Using "synttree", you can create trees of any depth, and an unlimited +% number of branches (up to the memory limit of your version of \TeX, of +% course). +% +% \section{Usage} +% +% \subsection{Drawing Options} +% +% The current implementation can use either em\TeX{} "\special"'s or +% \LaTeXe{}'s "\qbezier" macro to draw the lines in the tree, +% although the latter option is probably technically not very nice. Still, +% the behavior defaults to the \LaTeXe{} version. +% +% In order to switch between the two modes, the following options are +% supported: +% +% \begin{description} +% +% \item[specials] Use em\TeX{} special commands. +% \item[nospecials] Don't use em\TeX{} special commands. This is the +% default. +% +% \end{description} +% +% \subsection{Defined Macros} +% +% \DescribeMacro{\synttree} +% The main macro defined by this package is the "\synttree" macro. It +% takes as arguments first an optional parameter indicating the +% maximum depth of the tree, and second a parameter describing the +% structure of the tree, delimited by square brackets ("[" and "]"). +% +% A tree consists of the parent node's label, followed by the child trees. +% In principle, an unlimited number of children can be specified, but +% to signal runaway trees, a warning will be issued when the number is +% more than ten. +% Each of the child trees is again surrounded by square brackets. +% For example, the line +%\begin{verbatim} +%\synttree[A[B][C]] +%\end{verbatim} +% creates the following tree: +% \begin{trivlist} +% \item \synttree[A[B][C]] +% \end{trivlist} +% +% Note that leading and trailing spaces in the label will be ignored, so +% the following has the same result: +%\begin{verbatim} +%\synttree[ A [ B ][ C ]] +%\end{verbatim} +%^^A Nodes and subtrees are surrounded by square +%^^A brackets ("[" and "]"), as is the entire tree. +% +% Before the label, a parameter may be added. This is specified +% by appending a period (".") to the opening bracket, and appending a letter +% that modifies the appearance of the tree. Append a "t" to +% create a triangle instead of a line going from the label to the +% level above it, and a "b" to specify that the node has to appear at +% the bottom of the tree, on a line with the lowest leaves. To +% use "b", a maximum tree depth has to be specified. To combine the +% two features, use "x". +% +% Using the optional parameters, the code +%\begin{verbatim} +%\synttree{4} +%[A +% [B [.x Some text] ] +% [D [E] [F[.t G]] [H] ] +%] +%\end{verbatim}% +% creates this tree: +% \begin{trivlist} +% \item +% \synttree{4} +% [A +% [B [.x Some text] ] +% [D [E] [F[.t G]] [H] ] +% ] +% \end{trivlist} +% +% If brackets are included in the label, surround +% them (or the entire label) by braces: +% +%\begin{verbatim} +% \synttree[A[{B]D}][C]] +%\end{verbatim} +% \begin{trivlist} +% \item \synttree[ +% A[{B]D}][C]] +% \end{trivlist} +% +% The other defined macros affect the look and sizing of the trees. +% The distance between levels can be adjusted by using +% \DescribeMacro{\branchheight} +% "\branchheight". It takes a length as its argument, and sets the +% distance to that length. The default distance is half an inch. This +% value is the distance between the baselines of the labels, so setting it +% to zero will cause everything to be on one line. +% The minimum horizontal separation between edges of two children is set +% by +% \DescribeMacro{\childsidesep} +% "\childsidesep". The default is "1em". +% The length +% \DescribeMacro{\childattachsep} +% "\childattachsep" indicates the minimum distance between the +% attachment points of two children. Here, the default is "0.5in". +% Finally, the balancing of the triangles can be adjusted by using +% \DescribeMacro{\trianglebalance} +% "\trianglebalance". It takes a number from 0 to 100, indicating the +% percentage of the triangle on the right side of its attachment point to +% the parent. The default is 50, resulting in isosceles triangles. +% +% \section{Wish List and Bugs} +% +% It is important to note that this package may not prevent you from doing +% certain things `wrong'. For example, triangles on non-leaf nodes are +% not forbidden, but may not give the desired result. +% +% Sometimes, the label of a parent may be a phrase, and it may be +% desirable to attach the children to a particular element in that phrase +% (e.g., to elaborate on the structure of that particular element). This +% is currently not possible: The children are always attached to the +% center of the label. Support for this may be added sooner or later. +% +% \section{Related Packages} +% A more complex package is the TreeTeX +% system\cite{TreeTeX}. This system, however, produces nodes +% consisting of a node symbol \emph{and} a label, whereas in +% syntactic trees the label \emph{is} the node symbol. Additionally, +% the method of specifying the tree structure itself makes the source +% code hard to read. +% +% The "xyling" package\cite{xyling} is a very powerful package, allowing +% many things that "synttree" will not do. However, the nodes have to be +% laid out meticulously in an array. Once that's done, however, the result +% looks very good. +% +% The ``\LaTeX\ for Linguists'' website\cite{LfL} lists other tree-drawing +% packages, with comments on their usefulness. +% +% \section{Author and License} +% +% Copyright (c) 1998, 1999, 2001, 2004--2006 Matijs van Zuijlen. +% +% The "synttree" package is free software. It has been released under the +% terms of the Latex Project Public License, version 1.3a. +% +% This work has the LPPL maintenance status `maintained'. Its current +% maintainer is Matijs van Zuijlen. This work consists of the files +% "synttree.dtx" and "synttree.ins". +% +% \StopEventually{ +% \begin{thebibliography}{1} +% \bibitem{LfL} Doug Arnold +% \newblock {\it \LaTeX\ for Linguists} \\ +% \newblock {At \texttt{http://www.essex.ac.uk/linguistics/clmt/latex4ling/}} +% \bibitem{TreeTeX} A. Br{\"u}ggemann-Klein and D. Wood. +% \newblock {\it Drawing trees nicely with \TeX{}} +% \newblock {File \texttt{tree\_doc.tex} in the "treetex" package} +% \bibitem{BasicControl} Jonathan Fine. +% \newblock {\it Some Basic Control Macros for \TeX{}} +% \newblock {TUGboat, Volume 13 (1992), No. 1} +% \bibitem{xyling} Ralf Vogel +% \newblock {\it xyling --- \LaTeX\ macros for linguistic graphics} \\ +% \newblock {At \texttt{http://www.ling.uni-potsdam.de/~rvogel/xyling/}} +% \end{thebibliography} +% } +% +% \section{Implementation} +% +% \subsection{Utility macros} +% +% Very useful for putting stuff after a "\fi" (as the name implies) +% \cite{BasicControl}. +% \begin{macrocode} +\def\@AfterFi#1\fi{\fi#1} +\def\@AfterElseFi#1\else#2\fi{\fi#1} +% \end{macrocode} +% +% \subsection{Drawing commands} +% +% These command are used to draw the lines between the nodes. There are two +% versions: one that uses the \LaTeXe{} "\qbezier" command, and one that is +% an adaptation of the unsupported "eepic" package, and uses specials. +% Currently, the package just uses the \LaTeXe{} version. +% +% First, the line drawing macros themselves. These simply draw a line +% between the two points given. Arguments are counters. +% \begin{macrocode} +\def\MTr@latexdrawline(#1,#2)(#3,#4){% + {% + \count0=#1 \advance\count0 by #3 \divide\count0 2 + \count1=#2 \advance\count1 by #4 \divide\count1 2 + \qbezier(#1,#2)(\count0,\count1)(#3,#4)% + }% +} +\def\MTr@etexdrawline(#1,#2)(#3,#4){% + {% + \count0=\@wholewidth \divide\count0 by 4736 + \special{pn \the\count0}% + \count0= #1\advance \count0 2368 \divide \count0 4736 + \count1=-#2\advance \count1 -2368 \divide \count1 4736 + \special{pa \the\count0 \space \the\count1}% + \count0= #3\advance \count0 2368 \divide \count0 4736 + \count1=-#4\advance \count1 -2368 \divide \count1 4736 + \special{pa \the\count0 \space \the\count1}% + \special{fp}% + }% +} +% \end{macrocode} +% +% Options to select either version: +% \begin{macrocode} +\DeclareOption{specials}{ + \let\MTr@drawline\MTr@etexdrawline% +} +\DeclareOption{nospecials}{ + \let\MTr@drawline\MTr@latexdrawline% +} +\ExecuteOptions{nospecials}% +\ProcessOptions% +% \end{macrocode} +% +% \subsection{Definitions} +% +% Some counters etc.\ are defined: The current level, the number of +% children the current node has, the maximum level specified, also, the +% current "branchmult", and whether the current node should be typeset +% with a triangle. We need a separate counter to hold the current +% "branchmult", because we calculate it before parsing the children, which +% will each set "branchmult" globally to save it into the child registers. +% \begin{macrocode} +\newcount\MTr@level +\newcount\MTr@numchildren +\newcount\MTr@maxlevel +\newcount\MTr@mybranchmult +\newif\ifMTr@mytriangle +% \end{macrocode} +% +% A boolean to specify whether read tokens that are not "[" or "]" should +% be used as a label for a node, or just ignored. +% \begin{macrocode} +\newif\ifMTr@uselabel +% \end{macrocode} +% +% Two "savebox"es, one for the label, one to put the child in while it is +% being defined. +% ^^A There was: , and a token register, to put the label in before it is +% ^^A ready. +% \begin{macrocode} +\newbox\MTr@labelbox +\newbox\MTr@treebox +% \end{macrocode} +% +% \subsection{Storage for information on (sub)trees} +% +% Define storage space to store contents of and information about a tree's +% children. Distances are measured from the child's label's virtual +% attachment point to the line to its parent --- in reality, for aesthetic +% reasons, the line is drawn up to a point that lies slightly higher. +% Drawing a box around the whole child tree, we find the distance from the +% left side to the central point, $v$, the distance from the right side, +% $w$. Then, we have the height (equal to the height of the label), and the +% depth (the height of the box minus the height of the label). There are +% also two external dimensions: the vertical distance from the parent +% label, $y$, and the horizontal distance from the parent tree's box, $x$. +% Usually, a child node is typeset one level below its parent. However, we +% may set it lower, e.g., to set the child on the bottom level. +% "branchmult" indicates how many levels below the parent the child should +% be typeset. +% \begin{macrocode} +\def\MTr@makechildcounter#1{% + \expandafter\newcount\csname MTr@child#1\endcsname% +} +\def\MTr@makechildstoreage#1{% + \expandafter\newsavebox\csname MTr@child#1box\endcsname% + \MTr@makechildcounter{#1x}% + \MTr@makechildcounter{#1y}% + \MTr@makechildcounter{#1v}% + \MTr@makechildcounter{#1w}% + \MTr@makechildcounter{#1height}% + \MTr@makechildcounter{#1depth}% + \MTr@makechildcounter{#1branchmult}% + \MTr@makechildcounter{#1picheight}% + \MTr@makechildcounter{#1triangle}% +} +% \end{macrocode} +% +% \begin{macro}{\MTr@childparam} +% We also need an easy way to retrieve each child's parameters. This way, +% we don't have to use the "\csname" construct all the time. +% \begin{macrocode} +\def\MTr@childparam#1#2{\csname MTr@child#1#2\endcsname} +% \end{macrocode} +% \end{macro} +% +% Store info for current subtree: $v$, $w$ ($x$ and $y$ are external, thus +% not important), height, depth, "branchmult", triangle status. +% \begin{macrocode} +\newcount\MTr@treev +\newcount\MTr@treew +\newcount\MTr@treeheight +\newcount\MTr@treedepth +\newcount\MTr@branchmult +\MTr@branchmult 1 +\newif\ifMTr@triangle +% \end{macrocode} +% Next, the depth, height and half the width of the label. +% \begin{macrocode} +\newcount\MTr@labeldepth +\newcount\MTr@labelheight +\newcount\MTr@labelhalfwidth +% \end{macrocode} +% When drawing, we need "morex", to store extra shift to the right when +% drawing the children, and "parenty", the vertical position of the point +% where the line from the parent to the child starts. Also, we need the +% width and height of the picture being drawn. +% \begin{macrocode} +\newcount\MTr@morex +\newcount\MTr@parenty +\newcount\MTr@picwidth +\newcount\MTr@picheight +% \end{macrocode} +% Finally, we need a temporary length, and four temporary counters. +% \begin{macrocode} +\newlength{\MTr@templength} +\newcount\MTr@loopcnta +\newcount\MTr@tempcnta +\newcount\MTr@tempcntb +\newcount\MTr@tempcntc +% \end{macrocode} +% +% \subsection{Adjustable and other parameters} +% \begin{macro}{\branchheight} +% The user can set up several parameters. +% First, "\branchheight" will set the distance +% between levels. Default value is half an inch. +% ^^A TODO: let default value depend on font size. +% \begin{macrocode} +\newcount\MTr@branchheight% +\newcommand{\branchheight}[1]{% + \setlength{\MTr@templength}{#1}% + \MTr@branchheight\MTr@templength% +} +\branchheight{.5in}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\trianglebalance}Next, "\trianglebalance" will set the +% balancing of the triangle. Default value is $50$. +% \begin{macrocode} +\newcount\MTr@trianglemultright% +\newcount\MTr@trianglemultleft% +\newcommand{\trianglebalance}[1]{% + \MTr@trianglemultleft100% + \MTr@trianglemultright#1% + \advance\MTr@trianglemultleft-#1% +} +\trianglebalance{50}% +% \end{macrocode} +% \end{macro} +% Distance between the labels and the lines. +% \begin{macrocode} +\newcount\MTr@lineoffset +\setlength{\MTr@templength}{2pt}% +\MTr@lineoffset\MTr@templength% +% \end{macrocode} +% Minimum label height. +% \begin{macrocode} +\newlength{\MTr@minheight} +\setlength{\MTr@minheight}{8pt}% +% \end{macrocode} +% \begin{macro}{\childsidesep} Minimum separation between edges of two +% children. +% \begin{macrocode} +\newcount\MTr@childsidesep +\newcommand{\childsidesep}[1]{% + \setlength{\MTr@templength}{#1}% + \MTr@childsidesep\MTr@templength% + \ignorespaces% +} +\childsidesep{1em} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\childattachsep}How far apart are the attachment points of +% two children? +% \begin{macrocode} +\newcount\MTr@childattachsep +\newcommand{\childattachsep}[1]{% + \setlength{\MTr@templength}{#1}% + \MTr@childattachsep\MTr@templength% + \ignorespaces% +} +\childattachsep{0.5in} +% \end{macrocode} +% \end{macro} +% +% \subsection{Main macro} +% \begin{macro}{\synttree} +% "\synttree" is the main macro. +% If the user has not provided a maximum depth, set it to 0. There +% will be no messages concerning depth, except when the bottomlevel +% modifier is used. +% Control is passed on to "\MTr@synttree" +% \begin{macrocode} +\def\synttree{% + \@ifnextchar[{\MTr@synttree{0}}{\MTr@synttree}%] +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\MTr@synttree} +% This macro sets maximum depth, end sets picture coordinates to scaled +% points. Next, initial values of some variables are set, and the first +% real parsing macro, "\MTr@parserightbracket", is called. +% \begin{macrocode} +\def\MTr@synttree#1{% + \MTr@maxlevel#1% + \unitlength 1sp% + \MTr@level=0% + \MTr@numchildren=0% + \MTr@uselabelfalse% + \MTr@parserightbracket% +} +% \end{macrocode} +% \end{macro} +% +% \subsection{Parsing} +% \iffalse[[[\fi^^A Brackets needed for bracket balancing in text editor +% +% Parsing will only work if at least one "]" is present. +% \begin{macro}{\MTr@parserightbracket} +% First, scan until the first occurrance of "]". Argument "#1" will contain no +% "]", but may contain some "[", which are detected by +% "\MTr@parseleftbracket". After "#1" has been processed, lower the nesting +% level. If we're back at 0, we're done. Otherwise, continue looking for +% "]". +% \begin{macrocode} +\def\MTr@parserightbracket#1]{% + \MTr@parseleftbracket#1[:\END% + \advance\MTr@level by -1% + \MTr@dorightbracket% + \ifnum\MTr@level=0% + \unhbox\MTr@childibox{}% + \else + \@AfterFi{\MTr@parserightbracket}% + \fi% +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\Mtr@parseleftbracket} +% ^^A Scan after we already had one or more children: Just ignore anything +% ^^A that is not a "[" or "]". +% Scan until the first occurrance of "[". Argument "#1" will contain no "]" +% or "[". "#2" may contain more "]". +% Possibly, "#1" is a label. +% If "#2"=":", the "[" was placed by "\MTr@parserightbracket", and we're +% done. +% \begin{macrocode} +\def\MTr@parseleftbracket#1[#2\END{% + \ifMTr@uselabel% + \MTr@bottomnodefalse% + \MTr@mytrianglefalse% + \MTr@parsedot#1.: \END% + \fi% + \ifx:#2% + \else% + \MTr@doleftbracket% + \advance\MTr@level by 1% + \@AfterFi{\MTr@parseleftbracket#2\END}% + \fi% +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\Mtr@parsedot} +% Parse the optional node argument. +%^^A TODO: Maybe this can be done simpler by using "\futurelet" in some way. +% \begin{macrocode} +\def\MTr@parsedot#1.#2 #3\END{% + \ifx:#2% + \setbox\MTr@labelbox\hbox{\ignorespaces#1\unskip}% + \else + \ifx#2b\MTr@bottomnodetrue\else% + \ifx#2x\MTr@bottomnodetrue\MTr@mytriangletrue\else% + \ifx#2t\MTr@mytriangletrue\else% + \typeout{synttree Warning: unknown dot option #2 in tree}% + \fi\fi\fi% + \MTr@parsedot#3\END + \fi +} +% \end{macrocode} +% \end{macro} +% +% \subsection{Action} +% +% The next macros implement the actions to be undertaken when encountering +% one of the square brackets. +% +% \begin{macro}{\MTr@doleftbracket} +% Upon encountering a "[", we go one level deeper: Begin a group, and reset +% parameters. +% \begin{macrocode} +\def\MTr@doleftbracket{% + \bgroup% + \MTr@numchildren=0% + \MTr@uselabeltrue% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\MTr@dorightbracket} +% Upon encountering a "]", we typeset the current group's tree, and end the +% group. Until we encounter some brackets, we should not add tokens to any +% label. Save the just-typeset tree as the newest child in the parent group +% --- now the current group. +% ^^A TODO: Put this back into parserightbracket. +% \begin{macrocode} +\def\MTr@dorightbracket{% + \MTr@maketreebox% + \egroup% + \MTr@uselabelfalse% + \MTr@savecurrentchildbox% +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\MTr@savecurrentchildbox} +% Save the current picture, with all its data, in the box and registers for +% the next empty child. +% \begin{macrocode} +\def\MTr@savecurrentchildbox{% + \advance\MTr@numchildren by 1 + \ifnum\MTr@numchildren<1% + \typeout{synttree internal warning: There is no child box to save.}% + \else + \ifnum\MTr@numchildren>10% + \typeout{synttree warning: More than 10 child boxes. + Can this be true?}% + \fi + \MTr@savechildbox{\romannumeral\MTr@numchildren}% + \fi +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\MTr@savechildbox} +% Save current tree in a specific child box. Basically, we just copy from +% the tree registers to the child registers, except $x$ is set to $v$ +% initially. Used only in "\MTr@savecurrentchildbox". +% \begin{macrocode} +\def\MTr@savechildbox#1{% + \expandafter + \ifx\csname MTr@child#1box\endcsname\relax% + \MTr@makechildstoreage{#1}% + \fi% + \setbox% + \csname MTr@child#1box\endcsname% + \hbox{\unhbox\MTr@treebox}% + \csname MTr@child#1v\endcsname\MTr@treev% + \csname MTr@child#1w\endcsname\MTr@treew% + \csname MTr@child#1x\endcsname\MTr@treev% + \csname MTr@child#1height\endcsname\MTr@treeheight% + \csname MTr@child#1depth\endcsname\MTr@treedepth% + \csname MTr@child#1branchmult\endcsname\MTr@branchmult% + \ifMTr@triangle% + \csname MTr@child#1triangle\endcsname 1% + \else% + \csname MTr@child#1triangle\endcsname 0% + \fi +} +% \end{macrocode} +% \end{macro} +% +% \subsection{Bottom Nodes} +% +% For bottom nodes, we have to adapt the vertical position so that +% they become, indeed, bottom nodes. This is done by the macros +% "\MTr@bottomnodetrue" and "\MTr@bottomnodefalse". +% +% \begin{macro}{\MTr@bottomnodetrue} +% The node is a bottom node. Calculate the difference between this +% level and the bottom level as passed to "\synttree", and use this to +% determine how many levels the node has to be advanced vertically to +% get it at the correct position. In effect, the distance between two +% levels is multiplied by the ``branch multiplication.'' For +% non-bottom nodes this is set to 1. +% ^^A TODO: always check levels if a maxlevel has been specified. +% \begin{macrocode} +\def\MTr@bottomnodetrue{% + \MTr@branchmult\MTr@maxlevel% + \advance\MTr@branchmult-\MTr@level% + \advance\MTr@branchmult 1% + \ifnum\MTr@branchmult<1% + \typeout{synttree Warning: Tree has more levels than indicated.}% + \typeout{>> Indicated: \the\MTr@maxlevel.}% + \typeout{>> Level now: \the\MTr@level.}% + \MTr@branchmult1% + \fi% + \MTr@mybranchmult\MTr@branchmult% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\MTr@bottomnodefalse} +% It's not a bottom node: Just set the branch multiplication to 1. +% \begin{macrocode} +\def\MTr@bottomnodefalse{% + \MTr@mybranchmult1% +} +% \end{macrocode} +% \end{macro} +% +% \subsection{Utility macros for the output routines} +% +% \begin{macro}{\MTr@setverticalchilddimens} +% Set vertical dimensions for a given child: $y$ and "picheight". +% ^^A TODO: Maybe we can set these while saving the child. +% \begin{macrocode} +\def\MTr@setverticalchilddimens#1{% + \MTr@tempcnta-\MTr@branchheight% + \multiply\MTr@tempcnta\MTr@childparam{#1}{branchmult}% + \MTr@tempcntb-\MTr@tempcnta% + \advance\MTr@tempcntb\csname MTr@child#1depth\endcsname% + \advance\MTr@tempcnta-\MTr@labelheight% + \advance\MTr@tempcnta\csname MTr@child#1height\endcsname% + \csname MTr@child#1y\endcsname\MTr@tempcnta% + \csname MTr@child#1picheight\endcsname\MTr@tempcntb% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\MTr@adjustdistance} +% Adjust the distance between two children. For the pair of +% neighboring children, "tempcnta" is used temporarily to store what +% amounts to the distance between the central points of the two children +% (the left child's $w$, plus the right child's $v$). +% If it is below the value "childattachsep", adjust values so that is equal +% to it. "tempcnta" stores the resulting value. +% The right child's $x$ is now set to put it in the correct position +% w.r.t.\ the left child. +% \begin{macrocode} +\def\MTr@adjustdistance#1#2{% + \MTr@tempcnta\MTr@childparam{#1}{w}% + \advance\MTr@tempcnta\MTr@childsidesep% + \advance\MTr@tempcnta\csname MTr@child#2v\endcsname% + \ifnum\MTr@tempcnta<\MTr@childattachsep% + \MTr@tempcnta\MTr@childattachsep% + \fi% + \csname MTr@child#2x\endcsname\MTr@childparam{#1}{x}% + \advance\csname MTr@child#2x\endcsname\MTr@tempcnta% +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\MTr@setparentdimens} +% Set some parameters for the parent node. Parameters are the leftmost and +% rightmost child label. +% \begin{macrocode} +\def\MTr@setparentdimens#1#2{% +% \end{macrocode} +% Calculate the subtree's $v$ and $w$: +% \begin{macrocode} + \MTr@tempcnta\MTr@childparam{#2}{x}% + \advance \MTr@tempcnta -\MTr@childparam{#1}{x}% + \divide\MTr@tempcnta 2% + \MTr@treev\MTr@tempcnta% + \MTr@treew\MTr@treev% + \advance \MTr@treev \csname MTr@child#1x\endcsname% + \advance \MTr@treew \csname MTr@child#2w\endcsname% +% \end{macrocode} +% Calculate "morex": The distance the (first) subtree has to be shifted to +% the right to accomodate a large parent label size. +% \begin{macrocode} + \MTr@morex\MTr@labelhalfwidth% + \advance\MTr@morex-\MTr@treev% + \ifnum\MTr@morex<0\MTr@morex0\fi% +% \end{macrocode} +% Large label sizes are also incorporated into $w$ and $x$. +% \begin{macrocode} + \ifnum\MTr@treew<\MTr@labelhalfwidth + \MTr@treew\MTr@labelhalfwidth + \fi% + \ifnum\MTr@treev<\MTr@labelhalfwidth + \MTr@treev\MTr@labelhalfwidth + \fi% +% \end{macrocode} +% Picture width. +% \begin{macrocode} + \MTr@picwidth\MTr@treev% + \advance\MTr@picwidth\MTr@treew% +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\MTr@setpictureparameters} +% Set some parameters for the picture. +% \begin{macrocode} +\def\MTr@setpictureparameters{% + \global\MTr@treedepth\MTr@picheight% + \advance\MTr@picheight\MTr@labelheight% + \global\MTr@treeheight\MTr@labelheight% + \MTr@parenty-\MTr@labelheight% + \advance\MTr@parenty-\MTr@labeldepth% + \advance\MTr@parenty-\MTr@lineoffset% + \global\MTr@treev\MTr@treev% + \global\MTr@treew\MTr@treew% +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\MTr@drawlabel} +% \begin{macrocode} +\def\MTr@drawlabel{% + \put(\MTr@treev,0){% + \makebox(0,0)[t]{% + \rule{0pt}{\MTr@minheight}% + \usebox{\MTr@labelbox}}}% +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\MTr@drawchild} +% Draws the saved child node's picture. +% \begin{macrocode} +\def\MTr@drawchild#1{% + \MTr@tempcnta\MTr@childparam{#1}{x} + \advance\MTr@tempcnta-\MTr@childparam{#1}{v} + \put(\MTr@tempcnta,\MTr@childparam{#1}{y}){% + \makebox(0,0)[tl]{% + \usebox{\csname MTr@child#1box\endcsname}}}% +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\MTr@drawchildline} +% Draws the line or triangle from the parent to the given child. +% \begin{macrocode} +\def\MTr@drawchildline#1{ +% \end{macrocode} +% Use child's $y$, but advance it to make the line stop just above the +% label. +% \begin{macrocode} + \MTr@tempcnta\MTr@childparam{#1}{y} + \advance\MTr@tempcnta\MTr@lineoffset% + \expandafter + \ifnum\csname MTr@child#1triangle\endcsname=1% + \MTr@drawchildlinetriangle{#1}% + \else% + \MTr@drawchildlineline{#1}% + \fi% +} +\def\MTr@drawchildlineline#1{% + \put(0,0){\MTr@drawline% + (\MTr@treev,\MTr@parenty)% + (\MTr@childparam{#1}{x},\MTr@tempcnta)}% +} +\def\MTr@drawchildlinetriangle#1{% + \MTr@tempcntb\MTr@childparam{#1}{x}% + \MTr@tempcntc\MTr@tempcntb% + \advance\MTr@tempcntb \MTr@childparam{#1}{w}% + \advance\MTr@tempcntc -\MTr@childparam{#1}{v}% + \put(0,0){\MTr@drawline% + (\MTr@treev,\MTr@parenty)% + (\MTr@tempcntc,\MTr@tempcnta)}% + \put(0,0){\MTr@drawline% + (\MTr@treev,\MTr@parenty)% + (\MTr@tempcntb,\MTr@tempcnta)}% + \put(0,0){\MTr@drawline% + (\MTr@tempcntc,\MTr@tempcnta)% + (\MTr@tempcntb,\MTr@tempcnta)}% +} +% \end{macrocode} +% \end{macro} +% +% \subsection{Output routines} +% +% \begin{macro}{\MTr@maketreebox} +% This is the main macro that starts the output. +% ^^A TODO: Maybe move \global\setbox\MTr@treebox out of the \ifnum s +% \begin{macrocode} +\def\MTr@maketreebox{% + \MTr@labelheight\ht\MTr@labelbox% + \ifnum\MTr@labelheight<\MTr@minheight\MTr@labelheight\MTr@minheight\fi%% + \MTr@labeldepth\dp\MTr@labelbox% + \MTr@labelhalfwidth\wd\MTr@labelbox% + \divide\MTr@labelhalfwidth 2% + \ifnum\MTr@numchildren=0% + \global\setbox\MTr@treebox\hbox{\MTr@outputlabel}% + \fi% + \ifnum\MTr@numchildren>0% + \global\setbox\MTr@treebox\hbox{\MTr@outputchildren{\the\MTr@numchildren}}% + \fi% + \global\MTr@branchmult\MTr@mybranchmult% + \ifMTr@mytriangle% + \global\MTr@triangletrue% + \else% + \global\MTr@trianglefalse% + \fi% +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\MTr@outputlabel} +% Output a tree that is just a label, with no children. +% \begin{macrocode} +\def\MTr@outputlabel{% +% \end{macrocode} +% First, set parameters: Height and depth of the subtree are equal to +% height and depth of the label. The $x$ and $w$ of the subtree each equal +% half the width of the label. Optionally, $x$ may be zero and $w$ may +% equal to the entire width of the label. The width and height of the +% picture to be drawn equal the width of the label and the height of the +% tree. +% \begin{macrocode} + \global\MTr@treeheight\MTr@labelheight% + \global\MTr@treedepth\MTr@labeldepth% + \ifMTr@mytriangle% + \MTr@treew\MTr@labelhalfwidth% + \MTr@treev\MTr@labelhalfwidth% + \multiply\MTr@treew \MTr@trianglemultright% + \multiply\MTr@treev \MTr@trianglemultleft% + \divide\MTr@treew 50% + \divide\MTr@treev 50% + \global\MTr@treew\MTr@treew% + \global\MTr@treev\MTr@treev% + \else% + \global\MTr@treew\MTr@labelhalfwidth% + \global\MTr@treev\MTr@labelhalfwidth% + \fi% + \MTr@picwidth\wd\MTr@labelbox% + \MTr@picheight\MTr@treeheight% +% \end{macrocode} +% Second, draw the picture. The coordinates for the picture are nearly +% the same throughout. In any event, the label is centered in the +% picture, its baseline aligned with the bottom of the picture. +% \begin{macrocode} + \advance\MTr@picheight\MTr@treedepth% + \begin{picture}% + (\MTr@picwidth,\MTr@picheight)% + (-\MTr@treev,-\MTr@picheight)% + %\put(-\MTr@treev,-\MTr@picheight){\framebox(\MTr@picwidth,\MTr@picheight){}}% + \put(-\MTr@treev,0){% + \makebox(0,0)[tl]{% + \rule{0pt}{\MTr@minheight}% + \usebox{\MTr@labelbox}}}% + \end{picture}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\MTr@outputchildren} +% Output a tree or subtree with at least one child tree. +% \begin{macrocode} +\def\MTr@outputchildren#1{% +% \end{macrocode} +% Calculate desired distance between the children. +% The cumulative value is put into "treev". +% \begin{macrocode} + \ifnum#1>1 + \MTr@loopcnta 1 + \loop + \edef\MTr@temp{\romannumeral\MTr@loopcnta}% + \ifnum\MTr@loopcnta<#1 + \advance \MTr@loopcnta by 1 + \MTr@adjustdistance{\MTr@temp}{\romannumeral\MTr@loopcnta}% + \repeat + \fi +% \end{macrocode} +% Calculate the subtree's $v$ and $w$, based on the children, and the +% label's width. +% \begin{macrocode} + \MTr@setparentdimens{i}{\romannumeral#1}% +% \end{macrocode} +% After the call to "setparentdimens", all children's $x$ +% values must be advanced by "morex". In the same loop, also +% set vertical position and picture height for each child. +% The height of the picture is the height of the largest child. +% \begin{macrocode} + \MTr@picheight 0% + \MTr@loopcnta #1 + \loop + \edef\MTr@temp{\romannumeral\MTr@loopcnta}% + \advance\MTr@childparam{\MTr@temp}{x}\MTr@morex% + \MTr@setverticalchilddimens{\romannumeral\MTr@loopcnta}% + \ifnum\MTr@childparam{\MTr@temp}{picheight}>\MTr@picheight% + \MTr@picheight\MTr@childparam{\MTr@temp}{picheight}% + \fi% + \advance \MTr@loopcnta by -1 \ifnum\MTr@loopcnta>0 \repeat +% \end{macrocode} +% Set various other parameters. +% \begin{macrocode} + \MTr@setpictureparameters% +% \end{macrocode} +% Start the picture and draw the label. Next, draw each child, and the line +% to that child. Then, end the picture. +% \begin{macrocode} + \begin{picture}(\MTr@picwidth,\MTr@picheight)(0,-\MTr@picheight)% + %\put(0,-\MTr@picheight){\framebox(\MTr@picwidth,\MTr@picheight){}}% + \MTr@drawlabel% + \MTr@loopcnta #1 + \loop + \expandafter\MTr@drawchild{\romannumeral\MTr@loopcnta}% + \expandafter\MTr@drawchildline{\romannumeral\MTr@loopcnta} + \advance \MTr@loopcnta by -1 \ifnum\MTr@loopcnta>0 \repeat + \end{picture}% +} +% \end{macrocode} +% \end{macro} +% +% \Finale +% \PrintIndex \PrintChanges +\endinput |