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
|
% how to run.
% \input tree.sty or \documentstyle[tree]{..}
% run through latex as you normally do
% remember to send it to a postscript printer
% Written by Emma Pease
% Modified by Avery Andrews May 1992
% Modifications suggested by Gintautas Grigelionis
% (gintas@theophys.kth.se) added May 1995
% arrows fixed on anodeconnect and aanodeconnect added May 1995 by Emma
% to do, fix barnodeconnect arrows
% clean up code
%% version .91 - May 16, 1995
\typeout{tree-dvips version .91 of May 16, 1995}
% This ensures that the header file for postscript is inserted. Note
% that extracting pages with dvips will keep this header file but that
% extracting with dviselect will not unless the absolute first page is
% included.
\special{header=tree-dvips91.pro}
% The \pscmd command insures that all things in the postscript are
% properly bracketed. Also included are the current parameters for
% nodemargin, width of lines, dashlength, arrow width, length, and inset.
\def\pscmd#1{\special{ps:@beginspec%
/nodemargin \@int{\the\nodemargin}\space pt def %
\@int{\the\treelinewidth}\space pt setlinewidth %
\ifdim\dashlength=0pt [] 0 setdash%
/arrowwidth \@int{\the\arrowwidth}\space pt def %
/arrowlength \@int{\the\arrowlength}\space pt def %
/arrowinset \@int{\the\arrowinset}\space pt def %
\else [\@int{\the\dashlength}\space pt] 0 setdash \fi\space #1 %
@endspec}}
% \@int ensures that the numbers are passed down to the printer
% correctly.
{\catcode`p=12 \catcode`t=12 \gdef\wnum#1pt{#1}}
\def\@int#1{\expandafter\wnum#1}
% PARAMETERS IN TREE MODE
% nodemargin is the extra margin around the hbox enclosing the node.
% treelinewidth is the width of the lines
% dashlength is the length of the dashes
\newdimen\nodemargin %
\nodemargin=2pt
\newdimen\treelinewidth
\treelinewidth=.3pt
\newdimen\dashlength
\dashlength=0pt
% * _
% *
% * * arrowwidth
% *
% * _
% | | arrowlength
% | | arrowinset
% arrowwidth
\newdimen\arrowwidth
\arrowwidth 3pt
\newdimen\arrowlength
\arrowlength 4pt
\newdimen\arrowinset
\arrowinset 1pt
% Some commands to manipulate parameters
\def\thinline{\treelinewidth=.3pt}
% \makedash{dimen} makes dashes of dimen length if dimen = 0pt then
% solid line
\def\makedash#1{\dashlength=#1}
\def\arrowhead#1#2#3{\arrowwidth#1\arrowlength#2\arrowinset#3}
% NODE COMMANDS
% A node defines a region of the page with a height, depth, width, and
% location of the lower left hand corner
\def\node#1#2{\leavevmode
\setbox1=\hbox{#2}\pscmd{/#1 \@int{\the\wd1} \space pt
\@int{\the\ht1} \space pt
\@int{\the\dp1} \space pt
node}\box1\relax}
% nodepoint is a specialized node with 0pt width, height, and depth
% Unlike \node is can be displaced.
% \nodepoint{nodename}[horizontal displacement][vertical displacement]
% default is current point
\def\nodepoint#1{\@ifnextchar [{\@nodepoint{#1}}{\@nodepoint{#1}[0pt][0pt]}}
\def\@nodepoint#1[#2][#3]{{\@tempdima=#2 \@tempdimb=#3%
\pscmd{/nodemargin 0 def %
/#1 \@int{\the\@tempdima}\space pt \@int{\the\@tempdimb}\space pt %
rmoveto 0 0 0 node}}}
\newtoks\pos@t \pos@t={top}
\newtoks\pos@b \pos@b={bottom}
\newtoks\pos@l \pos@l={left}
\newtoks\pos@r \pos@r={right}
\newtoks\pos@tl \pos@tl={topleft}
\newtoks\pos@tr \pos@tr={topright}
\newtoks\pos@bl \pos@bl={bottomleft}
\newtoks\pos@br \pos@br={bottomright}
% COMMANDS FOR CONNECTING NODES
% nodeconnect commands
% \nodeconnect
% \anodeconnect - arrow at toloc
% \aanodeconnect - arrow at both ends
% arguments are [fromloc]{fromnode}[toloc]{tonode}
% \nodeconnect[fromloc]{fromnode}[toloc]{tonode}
\def\nodeconnect{\@ifnextchar [{\@nodeconnect}{\@nodeconnect[b]}}
\def\@nodeconnect[#1]#2{\@ifnextchar [{\@@nodeconnect[#1]{#2}}{\@@nodeconnect[#1]{#2}[t]}}
\def\@@nodeconnect[#1]#2[#3]#4{\pscmd{%
/#2 getnode node\the\csname pos@#1\endcsname \space%
/#4 getnode node\the\csname pos@#3\endcsname\space nodeconnect}}
% \delink[fromloc]{fromnode}[toloc]{tonode}{length}
% places a bar of length perpendicular to and halfway along the line
% connecting the two locations.
\def\delink{\@ifnextchar [{\@delink}{\@delink[b]}}
\def\@delink[#1]#2{\@ifnextchar [{\@@delink[#1]{#2}}{\@@delink[#1]{#2}[t]}}
\def\@@delink[#1]#2[#3]#4#5{\@tempdima=#5%
\pscmd{/blong \@int{\the\@tempdima} \space pt def%
/#2 getnode node\the\csname pos@#1\endcsname \space%
/#4 getnode node\the\csname pos@#3\endcsname\space delink}}
% \anodeconnect[fromloc]{fromnode}[toloc]{tonode}
% The tonode has an arrow pointing to it
\def\anodeconnect{\@ifnextchar [{\@anodeconnect}{\@anodeconnect[b]}}
\def\@anodeconnect[#1]#2{\@ifnextchar [{\@@anodeconnect[#1]{#2}}{\@@anodeconnect[#1]{#2}[t]}}
\def\@@anodeconnect[#1]#2[#3]#4{\pscmd{%
/#2 getnode node\the\csname pos@#1\endcsname \space%
/#4 getnode node\the\csname pos@#3\endcsname\space arrownodeconnect}}
% \aanodeconnect[fromloc]{fromnode}[toloc]{tonode}
% double arrowed line
\def\aanodeconnect{\@ifnextchar [{\@aanodeconnect}{\@aanodeconnect[b]}}
\def\@aanodeconnect[#1]#2{\@ifnextchar [{\@@aanodeconnect[#1]{#2}}{\@@aanodeconnect[#1]{#2}[t]}}
\def\@@aanodeconnect[#1]#2[#3]#4{\pscmd{%
/#2 getnode node\the\csname pos@#1\endcsname \space%
/#4 getnode node\the\csname pos@#3\endcsname\space doublearrownodeconnect}}
% nodecurve commands
% nodecurve... no arrow
% anodecurve.. arrow at to
% aanodecurve.. arrows at to and from
% arguments:
% \..[fromloc][fromang]{fromnode}[toloc][toang]{tonode}{fdepth}[tdepth]
% defaults
% fromloc [b]
% toloc [t]
% fromang 0 (in degrees) direction is calculated counterclockwise
% toang 0 (in degrees) direction is calculated counterclockwise
% tdepth same as fdepth
% nodecurve commands set value of \@arrow, then invoke \nodecurve@
\newcount\@arrow
\newdimen\@tempdimc
\def\nodecurve{\@arrow=0\nodecurve@}
\def\anodecurve{\@arrow=1\nodecurve@}
\def\aanodecurve{\@arrow=2\nodecurve@}
\def\delinkcurve#1{\@tempdimc=#1%
\@arrow=3\nodecurve@}
\def\nodecurve@{\@ifnextchar [{\@nodecurve@}{\@nodecurve@[b]}}
\def\@nodecurve@[#1]{\@ifnextchar [{\a@nodecurve@[#1]}{\a@nodecurve@[#1][0]}}
\def\a@nodecurve@[#1][#2]#3{\@ifnextchar [{\@a@nodecurve@[#1][#2]{#3}}%
{\@a@nodecurve@[#1][#2]{#3}[t]}}
\def\@a@nodecurve@[#1][#2]#3[#4]{\@ifnextchar [{\a@a@nodecurve@[#1][#2]#3[#4]}%
{\a@a@nodecurve@[#1][#2]#3[#4][0]}}
\def\a@a@nodecurve@[#1][#2]#3[#4][#5]#6#7{\@ifnextchar [%
{\@a@a@nodecurve@[#1][#2]{#3}[#4][#5]{#6}{#7}}%
{\@a@a@nodecurve@[#1][#2]{#3}[#4][#5]{#6}{#7}[#7]}}
\def\@a@a@nodecurve@[#1][#2]#3[#4][#5]#6#7[#8]{\@tempdima=#7%
\@tempdimb=#8%
\@tempdimc=10pt%
\pscmd{/depth \@int{\the\@tempdimb} \space pt def %
/toangle \space #5 \space def %
/fromangle \space #2 \space def %
/#6 \the\csname pos@#4\endcsname cur\space %
/depth \@int{\the\@tempdima} \space pt def %
/#3 \the\csname pos@#1\endcsname cur\space %
\ifnum\@arrow=0 nodecurve \else % select & invoke PS command
\ifnum\@arrow=1 arrownodecurve \else
\ifnum\@arrow=2 arrow2nodecurve \else
/blong \@int{\the\@tempdimc} \space pt def
delinkcurve
\fi\fi\fi}}
% above is well tested below is not
\newif\iftransparent
\def\nodebox#1{\pscmd{/#1 nodebox}}
\def\nodeoval#1{\pscmd{/#1 nodeoval}}
\def\nodetriangle#1#2{\pscmd{/#1 /#2 nodetriangle}}
% \nodecircle[depth]{nodename}
\def\nodecircle{\@ifnextchar [ {\@nodecircle}{\@nodecircle[0pt]}}
\def\@nodecircle[#1]#2{\@tempdima=#1%
\iftransparent
\pscmd{\@int{\the\@tempdima}\space pt /#2 nodecircletrans}
\else
\pscmd{\@int{\the\@tempdima}\space pt /#2 nodecircle}\fi}
% \barnodeconnect[depth]{fromnode}{tonode}
\def\barnodeconnect{\@ifnextchar[ {\@barnodeconnect}{\@barnodeconnect[5pt]}}
\def\@barnodeconnect[#1]#2#3{\@tempdima=#1 \ifdim\@tempdima<0pt
\pscmd{\@int{\the\@tempdima}\space pt %
/#2 getnode nodebottom /#3 getnode nodebottom barnodeconnect}
\else
\pscmd{\@int{\the\@tempdima}\space pt %
/#2 getnode nodetop /#3 getnode nodetop barnodeconnect}
\fi}
\def\abarnodeconnect{\@ifnextchar[ {\@abarnodeconnect}{\@abarnodeconnect[5pt]}}
\def\@abarnodeconnect[#1]#2#3{\@tempdima=#1 \ifdim\@tempdima<0pt
\pscmd{\@int{\the\@tempdima}\space pt %
/#2 getnode nodebottom /#3 getnode nodebottom arrowbarnodeconnect}
% above replaces the line below.
% /#2 getnode nodebottom /#3 getnode nodebottom abarnodeconnect}
\else
\pscmd{\@int{\the\@tempdima}\space pt %
/#2 getnode nodetop /#3 getnode nodetop arrowbarnodeconnect}
\fi}
|