%% \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} % % %\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