summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/synttree/synttree.dtx
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /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.dtx999
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