1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
|
%% \CheckSum{747}
% \iffalse meta-comment
%% synttree.dtx
%% Package `synttree' for use with LaTeX 2e
%% Version 1.4.1
%
% 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.
%
%<*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.1}}
% \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 #1 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@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)}%
\else%
\put(0,0){\MTr@drawline%
(\MTr@treev,\MTr@parenty)%
(\MTr@childparam{#1}{x},\MTr@tempcnta)}%
\fi%
}
% \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
|