%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Version: 26 Mar 91
%%
%%		 Primitive Linguistics Tree Formatter
%%
%% Copyright (c) 1991 Avery DeLano Andrews 3rd
%%	You can use these macros to typeset your own documents, or you
%%	can use them as basis for your own macros. In the latter case,
%%	you must (1) give proper credit, and (2) document the usage of
%%	your macros/changes (if the usage of your macros is not worth
%%	documenting, they must not be worth using).
%%
%%      Parameter-list handling technique & above post-copyright notice
%%      blurb cribbed from gloss.sty by Marcel R. van der Goot (1990).
%%
%%
%% Usage:  \tree{...}      prints out a formatted tree.
%%         \treenode{...}  puts formatted tree into \treebox reg.
%%            either leaves \treewidth reg = width of tree
%%                          \treecenter reg. = `center' of tree
%%
%%         {...} above is a `tree list', of the form:
%%           {{<terminal>}}
%%           {<mother>, <d1>,  <dn>}, where each di is a treelist.
%%            
%%         e.g.  {S, {NP, {Det, {{the}}, {N, {{dog}}}}, {VP, {{barked}}}}
%%
%%         The double braces around terminals are annoying, but I haven't
%%          been clever enough to avoid them.  <terminal> & <mother>
%%          can be any well-balanced material, (feature-structures,
%%          stacks of nodes & annotations ...
%%
%%  Parameters:
%%    \sisterskip (dimen)     default spacing between sisters
%%    \daughterskip (dimen)   default vert. mother-daughter spacing
%%
%%  Fiddles:
%%    \daughtergap{<dimen>} in a mother node sets mother-daughter
%%       spacing to <dimen> for daughters of that node.
%%    \sistergap{<dimen>} in a node spaces it <dimen> horizontally
%%       from its *preceeding* sister
%%
%%  LFG Specials:
%%    To make life easier for LFG people, there are two commands for
%%    doing annotated nodes, \tnode for terminals, \ntnode for nonterminals.
%%    Both are defined in terms of \node from Emma Pease's tree.sty, so they
%%    take two braced arguments, the node tag and the node specification.
%%
%%    The node tag is as in tree.sty, but the node specification is a
%%    series of levels separated by `/' (if you want to combine levels
%%    with GPSG slash notation, groupany level containing a slash in
%%    braces).  With \ntnode, the upper levels are set in math mode
%%    and the bottommost in restricted horizontal; with \tnode, the
%%    upper levels are set in math mode and the bottommost in restricted
%%    horizontal with italic font.
%%
%%    If you want to switch off automatic math mode for annotations, you
%%    can do it by redefining the \nodeannotation command as follows:
%%
%%      \def\nodeannotation#1{#1}
%%
%%   If you want to terminals to be, say slanted rather than italics, you can
%%   do it by redefining \tstyle as follows:
%%   
%%      \def\tstyle{\sl}
%%
%%  If you want to use the stacking, etc., facilities, but not the
%%  line-drawing (which depends on tree.sty), you can redefine \node
%%  to effectively do nothing:
%%
%%      \def\node#1#2{#2}
%%
%%
%%  General Remarks:
%%
%%    Coded for reader's comfort, not computer's speed, according
%%    to my rather inexperienced lights.
%%
%%    Processes nodes on a left-corner schedule, first packing
%%    daughters into an hbox, then mother into another hbox,
%%    then both into a vtop (vbox with alignment along the top).
%%
%%    Improvements & Suggestions welcome.  Please notify to:
%%
%%      Avery D Andrews
%%      Linguistics, The Faculties
%%      ANU PO Box 4
%%      Canberra ACT 2601
%%
%%      email:  ada612@fac.anu.edu.au
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

{
\catcode`\_=11     % sets underbar to letter
\catcode` =9       % causes spaces to be ignored
\catcode`\^^M=9    % causes <CR> to be ignored

\newbox\treebox        % box register for returned tree
\newbox\mother_box     %     " for mother
\newbox\daughter_box   %     " for local accumulation of daughters
\newbox\daughterr_box  %     " for upward comm. of dtrs
\newbox\stack_box      % for calculating widths for centering annotations

\newskip\sisterskip     % default space between sisters
\newskip\sister_skip    % space before current sister
\newdimen\daughterskip  % default mother-daughter space (vert)
\newdimen\daughter_skip % current  "
\newdimen\stack_width   % for calculating widths for centering annotations
\newskip\annoteskip     % default space between annotations

\global\sisterskip=2em
\global\daughterskip=2ex
\global\annoteskip=0ex

\newdimen\treewidth
\newdimen\treecenter
\newdimen\mother_offset
\newdimen\first_center
\newdimen\last_center
\newdimen\daughter_center


\gdef\daughtergap#1{\global\daughter_skip=#1}	% chris: should remove global?
\gdef\sistergap#1{\global\sister_skip=#1}

% was: \gdef\tree#1{\tree_node#1,.\leavevmode\box\treebox}
\gdef\tree#1{\tree_node#1,.\ifvmode\leavevmode\fi\hbox{\box\treebox}}
					% formats tree & prints it out.
					% sets treewidth & treecenter

\gdef\treenode#1{\tree_node#1,.}	% formats tree & puts it in treebox
					% sets treewidth & treecenter


\gdef\tree_node#1,#2.{
   \def\daughters{#2}
   \ifx\daughters\empty   % if terminal
      \global\setbox\treebox=\hbox{#1}
      \global\treewidth=\wd\treebox
      \global\treecenter=.5\treewidth
   \else
      \get_daughters#2.
      \daughtergap{\daughterskip}
      \setbox\mother_box=\hbox{#1}
      \mother_offset=\daughter_center
      \advance\mother_offset by -.5\wd\mother_box  % width to center of mother
      \ifdim\mother_offset>0pt
           \global\setbox\treebox=\vtop{
                    \hbox{\hskip\mother_offset\unhbox\mother_box}
                    \vskip\daughter_skip
                    \box\daughterr_box}
      \else
           \global\setbox\treebox=\vtop{
                    \box\mother_box
                    \vskip\daughter_skip
                    \hbox{\hskip-\mother_offset\unhbox\daughterr_box}}
      \fi
      \global\treewidth=\wd\treebox
      \global\treecenter=\daughter_center
      \ifdim\mother_offset<0pt
        \global\advance\treecenter by -\mother_offset
      \fi
   \fi
}


\gdef\d@mmy.{}	% We call this when we are at the end.  A no-op, but you
		% get better performance if you use no-ops!

\gdef\get_daughters#1,#2.{
   \treenode#1     %  process first daughter
   \first_center=\treecenter
   \last_center=\treewidth
   \setbox\daughter_box=\hbox{\box\treebox}
   \def\more{#2}
   \ifx\more\empty
     \global\daughter_center=\first_center
     \global\setbox\daughterr_box=\box\daughter_box
     \let\more=\d@mmy
   \else
     \let\more=\more_daughters
   \fi
   \more#2.
}

\gdef\more_daughters#1,#2.{
   \sistergap{\sisterskip}
   {\treenode#1}
   \setbox\daughter_box=\hbox{
      \unhbox\daughter_box\hskip\sister_skip\box\treebox}
   \def\more{#2}
   \ifx\more\empty
      \advance\last_center by \treecenter
      \advance\last_center by \sister_skip
      \advance\last_center by \first_center
      \divide\last_center by 2
      \global\daughter_center=\last_center
      \global\setbox\daughterr_box=\box\daughter_box  
      \let\more=\d@mmy
   \else
      \advance\last_center by \treewidth
      \advance\last_center by \sister_skip
      \let\more=\more_daughters
   \fi
   \more#2.
}


\gdef\ntnode#1#2{
  \def\t_style{\ntstyle}
  \node{#1}{\node_ann{#2}}
}

\global\let\tstyle=\it
\global\let\ntstyle=\rm

\gdef\tnode#1#2{
  \def\t_style{\tstyle}
  \node{#1}{\node_ann{#2}}
}

\gdef\node_ann#1{
  \global\stack_width=0pt
  \get_widths#1/.
  \vtop{\stack_ann#1/.}
}

\gdef\stack_ann#1/#2.{
  \def\more{#2}
  \ifx\more\empty
    \hbox to \stack_width{\strut\hss\t_style #1\hss}
    \let\more=\d@mmy
  \else
    \hbox to \stack_width{\hss \nodeannotation{#1}\hss}\vskip\annoteskip
    \let\more=\stack_ann
  \fi
  \more#2.
 }

% Default used to be this (for f-descriptions?) \gdef\nodeannotation#1{$#1$}
\gdef\nodeannotation#1{#1}

\gdef\get_widths#1/#2.{
  \def\more{#2}
  \ifx\more\empty
     \setbox\stack_box=\hbox{\t_style #1}
     \let\more=\d@mmy
  \else
     \setbox\stack_box=\hbox{\nodeannotation{#1}}
     \let\more=\get_widths
  \fi
  \ifdim\stack_width<\wd\stack_box
    \global\stack_width=\wd\stack_box
  \fi
  \more#2.
}

}  % end group & restore standard catcodes