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


