summaryrefslogtreecommitdiff
path: root/macros/latex209/contrib/trees
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/latex209/contrib/trees
Initial commit
Diffstat (limited to 'macros/latex209/contrib/trees')
-rw-r--r--macros/latex209/contrib/trees/eppstein/trees.sty120
-rw-r--r--macros/latex209/contrib/trees/pstrees/README50
-rw-r--r--macros/latex209/contrib/trees/pstrees/align.h27
-rw-r--r--macros/latex209/contrib/trees/pstrees/ansi.c63
-rw-r--r--macros/latex209/contrib/trees/pstrees/columns.c132
-rw-r--r--macros/latex209/contrib/trees/pstrees/makefile6
-rw-r--r--macros/latex209/contrib/trees/pstrees/slurp.c211
-rw-r--r--macros/latex209/contrib/trees/pstrees/test.txp20
-rw-r--r--macros/latex209/contrib/trees/pstrees/treesbin0 -> 49152 bytes
-rw-r--r--macros/latex209/contrib/trees/pstrees/trees.156
-rw-r--r--macros/latex209/contrib/trees/pstrees/trees.c372
-rw-r--r--macros/latex209/contrib/trees/pstrees/trees.doc.pdfbin0 -> 69752 bytes
-rw-r--r--macros/latex209/contrib/trees/pstrees/trees.doc.tex338
-rw-r--r--macros/latex209/contrib/trees/pstrees/trees.doc.txp311
-rw-r--r--macros/latex209/contrib/trees/pstrees/trees.sty258
-rw-r--r--macros/latex209/contrib/trees/pstrees/words.c292
-rw-r--r--macros/latex209/contrib/trees/tree-dvips/Makefile12
-rw-r--r--macros/latex209/contrib/trees/tree-dvips/README48
-rw-r--r--macros/latex209/contrib/trees/tree-dvips/avm-doc.sty122
-rw-r--r--macros/latex209/contrib/trees/tree-dvips/avm-doc.tex1245
-rw-r--r--macros/latex209/contrib/trees/tree-dvips/avm.sty158
-rw-r--r--macros/latex209/contrib/trees/tree-dvips/lingmacros-manual.pdfbin0 -> 32938 bytes
-rw-r--r--macros/latex209/contrib/trees/tree-dvips/lingmacros-manual.tex124
-rw-r--r--macros/latex209/contrib/trees/tree-dvips/lingmacros.sty312
-rw-r--r--macros/latex209/contrib/trees/tree-dvips/tree-dvips.sty271
-rw-r--r--macros/latex209/contrib/trees/tree-dvips/tree-dvips91.pro110
-rw-r--r--macros/latex209/contrib/trees/tree-dvips/tree-dvips91.script718
-rw-r--r--macros/latex209/contrib/trees/tree-dvips/tree-manual.pdfbin0 -> 70864 bytes
-rw-r--r--macros/latex209/contrib/trees/tree-dvips/tree-manual.tex603
-rw-r--r--macros/latex209/contrib/trees/tree_tex/Makefile70
-rw-r--r--macros/latex209/contrib/trees/tree_tex/README58
-rw-r--r--macros/latex209/contrib/trees/tree_tex/layout.c382
-rw-r--r--macros/latex209/contrib/trees/tree_tex/layout.h77
-rw-r--r--macros/latex209/contrib/trees/tree_tex/test1.tex44
-rw-r--r--macros/latex209/contrib/trees/tree_tex/test2.tex72
-rw-r--r--macros/latex209/contrib/trees/tree_tex/treetex.c529
-rw-r--r--macros/latex209/contrib/trees/tree_tex/treetex.sty107
-rw-r--r--macros/latex209/contrib/trees/vanroose/trees.pdfbin0 -> 32067 bytes
-rw-r--r--macros/latex209/contrib/trees/vanroose/trees.sty86
-rw-r--r--macros/latex209/contrib/trees/vanroose/trees.tex64
40 files changed, 7468 insertions, 0 deletions
diff --git a/macros/latex209/contrib/trees/eppstein/trees.sty b/macros/latex209/contrib/trees/eppstein/trees.sty
new file mode 100644
index 0000000000..be4c556cd4
--- /dev/null
+++ b/macros/latex209/contrib/trees/eppstein/trees.sty
@@ -0,0 +1,120 @@
+% treedef.tex
+%
+% These definitions for tree macros are taken from "Trees in TeX",
+% by David Eppstein, as published in TUGboat 6#1, March 1985.
+% David Eppstein's address (as of 15 June 1988) is
+% Computer Science Department
+% Columbia University
+% New York, NY 10027
+% Eppstein@cs.Columbia.edu
+
+\newbox\treebox
+\def\tree{\global\setbox\treebox=\boxtree}
+\def\subtree{\ettext \boxtree}
+\def\leaf#1{\subtree#1\endsubtree}
+
+\def\endsubtree{\ettext \egroup}
+\def\endtree{\endsubtree \settreesizes \typesettree}
+
+\newif\iftreetext\treetextfalse % Whether still aligning text
+\def\boxtree{\hbox\bgroup % Start outer box of tree or subtree
+ \baselineskip 2.5ex % Narrow line spacing slightly
+ \tabskip 0pt % No spurious glue in alignment
+ \vbox\bgroup % Start inner text \vbox
+ \treetexttrue % Remember for \ettext
+ \let\par\crcr \obeylines % New line breaks without explicit \cr
+ \halign\bgroup##\hfil\cr} % Start alignment with simple template
+\def\ettext{\iftreetext % Are we still in inner text \vbox?
+ \crcr\egroup \egroup \fi} % Yes, end alignment and box
+
+\def\cons#1#2{\edef#2{\xmark #1#2}} % Add something to start of list.
+\def\car#1{\expandafter\docar#1\docar} % Take first element of list
+\def\docar\xmark#1\xmark#2\docar{#1} % ..by ignoring rest in expansion.
+\def\cdr#1{\expandafter\docdr#1\docdr#1} % Similarly, drop first element.
+\def\docdr\xmark#1\xmark#2\docdr#3{\def#3{\xmark #2}}
+\def\xmark{\noexpand\xmark} % List separator expands to self.
+\def\nil{\xmark} % Empty list is just a separator.
+
+\def\settreesizes{\setbox0=\copy\treebox \global\let\treesizes\nil \setsizes}
+\newdimen\treewidth % Width of this part of the tree.
+\def\setsizes{\setbox0=\hbox\bgroup % Get a horiz list as a workspace.
+ \unhbox0\unskip % Take tree, unpack it into horiz list.
+ \inittreewidth % Get old width at this level.
+ \sizesubtrees % Recurse through all subtrees.
+ \sizelevel % Now set width from remaining \vbox.
+ \egroup} % All done, finish our \hbox.
+
+\def\inittreewidth{\ifx\treesizes\nil % If this is the first at this level
+ \treewidth=0pt % ..then we have no previous max width.
+ \else \treewidth=\car\treesizes % Otherwise take old max level width
+ \global\cdr\treesizes % ..and advance level width storage
+ \fi} % ..in preparation for next level.
+
+\def\sizesubtrees{\loop % For each box in horiz list (subtree)
+ \setbox0=\lastbox \unskip % ..pull it off list and flush glue.
+ \ifhbox0 \setsizes % If hbox, it's a subtree - recurse
+ \repeat} % ..and loop; end loop on tree text.
+
+\def\sizelevel{\ifdim\treewidth<\wd0 % If greater than previous maximum
+ \treewidth=\wd0 \fi % Then set max to new high
+ \global\cons{\the\treewidth}\treesizes}% In either case, put back on list
+
+\newdimen\treeheight % Height of this part of the tree.
+\newif\ifleaf % Tree has no subtrees (is a leaf).
+\newif\ifbotsub % Bottom subtree of parent.
+\newif\iftopsub % Top subtree of parent.
+\def\typesettree{\medskip \maketree \medskip} % Make whole tree with spacing.
+\def\maketree{\hbox{\treewidth=\car\treesizes % Get width at this level.
+ \cdr\treesizes % Set up width list for recursion.
+ \makesubtreebox\unskip % Set \treebox to text, make subtrees.
+ \ifleaf \makeleaf % No subtrees, add glue.
+ \else \makeparent \fi}} % Have subtrees, stick them at right.
+
+{\catcode`@=11 % Be able to use \voidb@x.
+\gdef\makesubtreebox{\unhbox\treebox % Open up tree or subtree.
+ \unskip\global\setbox\treebox\lastbox % Pick up very last box.
+ \ifvbox\treebox % If we're already at the \vbox
+ \global\leaftrue \let\next\relax % ..then this is a leaf.
+ \else \botsubtrue % Otherwise, we have subtrees.
+ \setbox0\box\voidb@x % Init stack of processed subs
+ \botsubtrue \let\next\makesubtree % ..and call \maketree on them.
+ \fi \next}} % Finish up for whichever it was.
+
+\def\makesubtree{\setbox1\maketree % Call \maketree on this subtree.
+ \unskip\global\setbox\treebox\lastbox % Pick up box before it.
+ \treeheight=\ht1 % Get height of subtree we made
+ \advance\treeheight 2ex % Add some room around the edges
+ \ifhbox\treebox \topsubfalse % If picked up box is a \vbox,
+ \else \topsubtrue \fi % ..this is the top, otherwise not.
+ \addsubtreebox % Stack subtree with the rest.
+ \iftopsub \global\leaffalse % If top, remember not a leaf
+ \let\next\relax \else % ..(after recursion), set return.
+ \botsubfalse \let\next\makesubtree % Otherwise, we have more subtrees.
+ \fi \next} % Do tail recursion or return.
+
+\def\addsubtreebox{\setbox0=\vbox{\subtreebox\unvbox0}}
+\def\subtreebox{\hbox\bgroup % Start \hbox of tree and lines
+ \vbox to \treeheight\bgroup % Start \vbox for vertical rules.
+ \ifbotsub \iftopsub \vfil % If both bottom and top subtree
+ \hrule width 0.4pt % ..vertical rule is just a dot.
+ \else \treehalfrule \fi \vfil % Bottom gets half-height rule.
+ \else \iftopsub \vfil \treehalfrule % Top gets half-height the other way.
+ \else \hrule width 0.4pt height \treeheight \fi\fi % Middle, full height.
+ \egroup % Finish vertical rule \vbox.
+ \treectrbox{\hrule width 1em}\hskip 0.2em\treectrbox{\box1}\egroup}
+
+\def\treectrbox#1{\vbox to \treeheight{\vfil #1\vfil}}
+\def\treehalfrule{\dimen0=\treeheight % Get total height.
+ \divide\dimen0 2\advance\dimen0 0.2pt % Divide by two, add half horiz height.
+ \hrule width 0.4pt height \dimen0} % Make a vertical rule that high.
+
+\def\makeleaf{\box\treebox} % Add leaf box to horiz list.
+\def\makeparent{\ifdim\ht\treebox>\ht0 % If text is higher than subtrees
+ \treeheight=\ht\treebox % ..use that height.
+ \else \treeheight=\ht0 \fi % Otherwise use height of subtrees.
+ \advance\treewidth-\wd\treebox % Take remainder of level width
+ \advance\treewidth 1em % ..after accounting for text and glue.
+ \treectrbox{\box\treebox}\hskip 0.2em % Add text, space before connection.
+ \treectrbox{\hrule width \treewidth}\treectrbox{\box0}} % Add \hrule, subs.
+
+\endinput
diff --git a/macros/latex209/contrib/trees/pstrees/README b/macros/latex209/contrib/trees/pstrees/README
new file mode 100644
index 0000000000..1192159365
--- /dev/null
+++ b/macros/latex209/contrib/trees/pstrees/README
@@ -0,0 +1,50 @@
+This package consists of a preprocessor and some macro-definitions,
+by which linguistics-style trees can be specified as convenient
+indented lists, with spacing and line-drawing done automatically.
+
+It depends on Emma Pease's tree-dvips package, available from
+pub/TeXfiles on csli.stanford.edu, and requires the use of dvips
+(Radial Eye Softrware) for the lines to be drawn automatically.
+
+
+Files included are:
+
+ trees.sty: Macros for linguistics tree layout.
+
+ trees.doc.txp/tex/dvi/ps: Documentation for tree-formatting system,
+ including a preprocessor and tree-layout macros.
+
+ trees: executable (by Suns, at least) for tree-preprocessor.
+
+ tree.c, etc.; makefile: source files for compilation of preprocessor.
+
+ test.txp: a (very) little test file.
+
+ BUGS
+
+Sometimes, when `\\ ' appears in the input, `\\\` appears in the
+output.
+
+ LICENSE
+
+
+The package maybe be freely used by individuals for reporting research
+(including academic book publishing), and adapted, as long as the
+adapted versions contain reference and acknowledgement to the original
+author, Avery D. Andrews.
+
+Essentially commerical use is prohibited without explicit permission.
+
+The package is presented for use as is, with no warrantee as to its
+suitablility for any particular purpose, and no liability accepted
+for any consequences of use.
+
+Avery.Andrews@anu.edu.au
+
+ Avery D Andrews
+ Linguistics, The Faculties
+ ANU PO Box 4
+ Canberra ACT 2601
+ Australia, The Faculties
+
+
diff --git a/macros/latex209/contrib/trees/pstrees/align.h b/macros/latex209/contrib/trees/pstrees/align.h
new file mode 100644
index 0000000000..499554e233
--- /dev/null
+++ b/macros/latex209/contrib/trees/pstrees/align.h
@@ -0,0 +1,27 @@
+
+/* Constants and Types for align */
+
+/* utility constants */
+
+#define TRUE 1
+#define FALSE 0
+
+
+/* operating parameters */
+
+#define linesize 512 /* max size of input line */
+#define charmax 2000 /* maximum # char storable */
+#define ROWSIZE 50 /* maximum # words in row - 1 */
+#define stackmax 5 /* maximum nesting of Scribe envs in word */
+#define COLSIZE 4 /* maximum # rows - 1 */
+#define TRANSMAX 5 /* max # lines int translation (really an error
+ catcher) */
+
+/* Global Types */
+
+typedef struct {
+ char *loc; /* location of start of word */
+ int size; /* estimated output length of word */
+ int bracket; /* a delimiter type that can be put round word in output */
+} word;
+
diff --git a/macros/latex209/contrib/trees/pstrees/ansi.c b/macros/latex209/contrib/trees/pstrees/ansi.c
new file mode 100644
index 0000000000..895df389b8
--- /dev/null
+++ b/macros/latex209/contrib/trees/pstrees/ansi.c
@@ -0,0 +1,63 @@
+#include <strings.h>
+
+/* this `type less' definition of max is doubtless dangerous,
+ but it *seems* to work */
+
+
+extern void *malloc();
+
+max(a, b)
+{
+ if (a > b) return(a);
+ else return(b);
+}
+
+void reverse(s)
+char s[];
+{
+ int c, i, j;
+
+for (i=0, j = strlen(s)-1; i<j; i++,j--) {
+ c = s[i];
+ s[i] = s[j];
+ s[j] = c;
+ }
+}
+
+
+void itoa(n,s)
+char s[];
+int n;
+{
+ int i, sign;
+
+ if ((sign = n) < 0) /* record sign */
+ n = -n; /* make n positive */
+ i = 0;
+ do { /* generate digits in reverse order */
+ s[i++] = n % 10 + ' 0'; /* get next digit */
+ } while ((n /= 10) > 0); /* delete it */
+ if (sign < 0)
+ s[i++] = '-';
+ s[i] = '\0';
+ reverse(s);
+}
+
+/*
+#include <stdio.h>
+
+main()
+{
+ char s[5];
+
+ strcpy(s,"dog");
+
+ printf("%s\n",s);
+
+ reverse(s);
+
+ itoa(4,s);
+
+ printf("%s\n",s);
+}
+*/
diff --git a/macros/latex209/contrib/trees/pstrees/columns.c b/macros/latex209/contrib/trees/pstrees/columns.c
new file mode 100644
index 0000000000..af283dcba7
--- /dev/null
+++ b/macros/latex209/contrib/trees/pstrees/columns.c
@@ -0,0 +1,132 @@
+# include "align.h"
+# include <stdio.h>
+
+/* externals */
+ /* from slurp.c */
+extern void fetchline();
+extern char nextchar();
+extern char peekchar();
+extern int eoln();
+extern FILE *outstream;
+
+ /* from words.c */
+extern void readword_col();
+extern void init_store();
+
+/* externals from errors.c */
+extern goof(); /* error-writing routine
+ void goof(char *s); */
+extern int sinned, error; /* error-flags */
+
+
+/* local word-ending function */
+static int endword(c)
+char c;
+{
+ char d;
+ if (eoln() || ((c == ' ' && ((d = squizchar()) == ' ' || d == '\n')))
+ || c == '|')
+ return(TRUE);
+ else
+ return(FALSE);
+}
+
+/* skips over `|''s and blanks, getting width */
+static int chewspace()
+{
+ int count;
+ char c;
+
+ count = 0;
+ if (!eoln()) {
+ while ((c = squizchar()) == ' ' || c == '|') {
+ count++;
+ nextchar();
+ }
+ }
+ return(count);
+}
+
+
+do_word()
+{
+ word holder;
+ int space;
+ int stop;
+
+ if (!eoln()) {
+ init_store();
+ readword_col(&holder,&stop,endword,nextchar);
+/* printf("word = %s; eol = %d\n",holder.loc,eoln()); */
+ space = chewspace();
+/* printf("chewed space %d:: eol = %d\n",space,eoln()); */
+ if (!error) {
+ if (eoln()) {
+ fprintf(outstream,"%s",holder.loc);
+ }
+ else {
+ space = space+holder.size+1;
+ fprintf(outstream,"\\cbx{%d}{%s}",space,holder.loc);
+ }
+ }
+ }
+}
+
+do_line()
+{
+ int initspace;
+
+ initspace = chewspace();
+ if (!eoln() && initspace > 0)
+ fprintf(outstream,"\\cbx{%d}{}",initspace);
+ while (!eoln())
+ do_word();
+ fprintf(outstream, "\\\\\n");
+}
+
+
+/* top-level routine, that reads in lines until it encounters
+ end-of-example or eof */
+
+void columns()
+{
+ int go;
+
+ error = FALSE;
+ go = TRUE;
+ while (go) {
+ fetchline();
+
+ if (matchstr(".>"))
+ go = FALSE;
+ if (eof()) {
+ goof("file ends in example");
+ go = FALSE;
+ }
+ if (go) do_line();
+ }
+}
+
+/*
+char delmark = '\\';
+int wordmax = 60;
+
+main()
+{
+word sample;
+int stop;
+int s;
+
+get_com_widths("widths.dat");
+open_source("text.dat");
+init_store();
+
+advance();
+readword_col(&sample,&stop,endword,nextchar);
+printf("%s, size = %d, bracket= %d\n",sample.loc,sample.size,sample.bracket);
+if (stop) printf("stop!\n");
+}
+*/
+
+
+
diff --git a/macros/latex209/contrib/trees/pstrees/makefile b/macros/latex209/contrib/trees/pstrees/makefile
new file mode 100644
index 0000000000..dde80b9a95
--- /dev/null
+++ b/macros/latex209/contrib/trees/pstrees/makefile
@@ -0,0 +1,6 @@
+%.o: %.c
+ cc -c $< -g
+
+trees: trees.o slurp.o words.o ansi.o columns.o
+ cc -o trees trees.o slurp.o words.o ansi.o columns.o -lm
+
diff --git a/macros/latex209/contrib/trees/pstrees/slurp.c b/macros/latex209/contrib/trees/pstrees/slurp.c
new file mode 100644
index 0000000000..27286165f7
--- /dev/null
+++ b/macros/latex209/contrib/trees/pstrees/slurp.c
@@ -0,0 +1,211 @@
+#include "align.h"
+/* VAX/VMS verion
+#include <unixio>
+*/
+#include <stdio.h>
+#include <ctype.h>
+
+char *input_pointer;
+
+FILE *outstream;
+
+static FILE *input_stream;
+ char input_buffer[512];
+static int input_eof = TRUE;
+static int input_eoln = TRUE;
+static int line_count;
+
+
+int open_source(file)
+char *file;
+{
+ input_pointer = input_buffer;
+ line_count = 0;
+ if (strcmp(file,"stdin") == 0) {
+ input_eof = FALSE;
+ input_stream = stdin;
+ return(TRUE);
+ }
+ else
+ if ((input_stream = fopen(file,"r")) != NULL) {
+ input_eof = FALSE;
+ return(TRUE);
+ }
+ else {
+ input_eof = TRUE;
+ return(FALSE);
+ }
+}
+
+
+int fetchline()
+{
+ if (fgets(input_buffer,511,input_stream) == NULL) {
+ input_eof=TRUE;
+ return(FALSE);
+ }
+ else {
+ input_pointer = input_buffer;
+ line_count++;
+ input_eoln = FALSE;
+ return(TRUE);
+ }
+}
+
+
+/* returns the next character, interpreting EOLN as ' ', calling
+ for new line at EOLN, and maintaining input_eoln flag. */
+char nextchar()
+{
+ char c;
+
+ if (input_eoln) {
+ if (fetchline())
+ input_eoln = FALSE;
+ else return(' ');
+ }
+
+ c = *input_pointer++;
+ if (c == '\n') {
+ input_eoln = TRUE;
+ return(' ');
+ }
+ else return(c);
+
+}
+
+/* returns nextchar without advancing char pointer */
+char peekchar()
+{
+ char c;
+ c = nextchar();
+ input_pointer--;
+ return(c);
+}
+
+/* returns current position (old)
+int currentpos()
+{
+ return(input_pointer-input_buffer);
+}
+*/
+
+int currentpos()
+{
+ int pos;
+ char *point;
+
+ pos = 0;
+ for (point = input_buffer; point <= input_pointer; point++)
+ if (*point == '\t') {
+ pos = pos - (pos%8)+8;
+ }
+ else pos++;
+ return(pos);
+}
+
+
+/* returns TRUE if remainder of line matches string */
+int matchstr(s)
+char s[];
+{
+ if (!strncmp(input_pointer,s,strlen(s)))
+ return(TRUE);
+ else
+ return(FALSE);
+}
+
+/* returns whether end-of-line has been reached */
+int eoln()
+{
+ return(input_eoln);
+}
+
+/* returns whether end-of-file has been reached */
+int eof()
+{return(input_eof);}
+
+/* advances to next printing char */
+void advance()
+{
+ while (nextchar() == ' ' && !eof()) {};
+ input_pointer--;
+}
+
+/* advances to next printing char or eoln, returning TRUE if not eoln */
+int advanceeoln()
+{
+ char c;
+
+ if (eoln()) return(FALSE);
+ while ((c = nextchar()) == ' ' || c == '\t')
+ if (eoln()) return(FALSE);
+ input_pointer--;
+ return (TRUE);
+}
+
+/* returns actual next char, no fiddles */
+char squizchar()
+{
+ return(*input_pointer);
+}
+
+
+int advanceeoln_pos(pos)
+int *pos;
+{
+ int okay;
+
+ okay = advanceeoln();
+ *pos = currentpos();
+ return(okay);
+}
+
+skip_to(to)
+char to[];
+{
+ int l;
+ l = strlen(to);
+ while (!(strncmp(to,input_pointer,l) == 0 || eof())) {
+ nextchar();
+ }
+}
+
+gettoken(t)
+char *t;
+{
+ if (advanceeoln()) {
+ if (isalnum(*t++ = nextchar())) {
+ while (isalnum(*t++ = nextchar())) {}
+ input_pointer--;
+ t--;
+ }
+ *t = '\0';
+ return(TRUE);
+ }
+ else return(FALSE);
+}
+
+
+int linecount()
+{return(line_count);}
+
+void writeline()
+{
+ fputs(input_buffer,outstream);
+}
+
+/*
+main()
+{
+
+ char s[30];
+
+ open_source("stdin");
+ printf(": ");
+
+ fetchline();
+ while (gettoken(s))
+ printf("%s\n",s);
+}
+*/
diff --git a/macros/latex209/contrib/trees/pstrees/test.txp b/macros/latex209/contrib/trees/pstrees/test.txp
new file mode 100644
index 0000000000..8c8366a55a
--- /dev/null
+++ b/macros/latex209/contrib/trees/pstrees/test.txp
@@ -0,0 +1,20 @@
+\documentstyle[11pt,trees,tree-dvips]{article}
+
+\begin{document}
+
+Here is a sample tree:
+\begin{center}
+.[
+S
+ NP
+ this
+ N
+ tree
+ VP
+ V
+ works
+.]
+\end{center}
+
+
+\end{document}
diff --git a/macros/latex209/contrib/trees/pstrees/trees b/macros/latex209/contrib/trees/pstrees/trees
new file mode 100644
index 0000000000..18506c160d
--- /dev/null
+++ b/macros/latex209/contrib/trees/pstrees/trees
Binary files differ
diff --git a/macros/latex209/contrib/trees/pstrees/trees.1 b/macros/latex209/contrib/trees/pstrees/trees.1
new file mode 100644
index 0000000000..cc265de7bd
--- /dev/null
+++ b/macros/latex209/contrib/trees/pstrees/trees.1
@@ -0,0 +1,56 @@
+.\" @(#)trees.1 1.0 93/12/07
+.TH TREES 1 "8 December 1993"
+.SH NAME
+trees \- Preprocessor for LaTeX documents including trees.
+.SH SYNOPSIS
+.B trees
+.IB filename
+.SH DESCRIPTION
+By convention the filename must end in \fB.txp\fP but that ending is
+not included on the command line. Output goes into
+\fBname_tx2.tex\fP which can be latexed. See the manual for full
+instructions.
+.SH PACKAGE DESCRIPTION
+This package consists of a preprocessor and some macro-definitions,
+by which linguistics-style trees can be specified as convenient
+indented lists, with spacing and line-drawing done automatically.
+
+It depends on Emma Pease's tree-dvips package, available from
+pub/TeXfiles on csli.stanford.edu, and requires the use of dvips
+(Radial Eye Software) for the lines to be drawn automatically.
+Files included are:
+
+trees.sty: Macros for linguistics tree layout.
+
+trees.doc.txp/tex/dvi/ps: Documentation for tree-formatting system,
+including a preprocessor and tree-layout macros.
+
+trees: executable (by Suns, at least) for tree-preprocessor.
+
+tree.c, etc.; makefile: source files for compilation of preprocessor.
+
+test.txp: a (very) little test file.
+
+.SH BUGS
+Sometimes, when `\\\\ ' appears in the input, `\\\\\\` appears in the
+output.
+.SH LICENSE
+The package maybe be freely used by individuals for reporting research
+(including academic book publishing), and adapted, as long as the
+adapted versions contain reference and acknowledgement to the original
+author, Avery D. Andrews.
+.LP
+Essentially commerical use is prohibited without explicit permission.
+.LP
+The package is presented for use as is, with no warrantee as to its
+suitablility for any particular purpose, and no liability accepted
+for any consequences of use.
+.LP
+Avery.Andrews@anu.edu.au
+.LP
+ Avery D Andrews
+ Linguistics, The Faculties
+ ANU PO Box 4
+ Canberra ACT 2601
+ Australia, The Faculties
+
diff --git a/macros/latex209/contrib/trees/pstrees/trees.c b/macros/latex209/contrib/trees/pstrees/trees.c
new file mode 100644
index 0000000000..0d3cc8cd3b
--- /dev/null
+++ b/macros/latex209/contrib/trees/pstrees/trees.c
@@ -0,0 +1,372 @@
+# include "align.h"
+/* VAX VMS
+# include <unixio>
+*/
+# include <stdio.h>
+
+/* #define INC_COLUMNS */
+
+ /* externals from slurp */
+extern char nextchar();
+extern char peekchar();
+extern int fetchline();
+extern void writeline();
+extern void skip_to();
+extern FILE *outstream;
+
+
+/* externals from words */
+extern void readword();
+extern void initstore();
+
+/* types */
+struct tnode {
+ word name;
+ int branch, term, tri;
+ struct tnode *mother, *daughters, *next;
+ char tag[10]; /* text of tag held in charstore */
+};
+
+typedef struct tnode treenode;
+
+/* error stuff */
+int sinned = FALSE; /* error has occurred in run */
+int error = FALSE; /* error has occurred in current example */
+
+FILE *error_file;
+char error_name[50];
+
+
+void goof(s)
+char *s;
+{
+ if (!sinned) {
+ error_file = fopen(error_name,"w");
+ sinned = TRUE;
+ }
+ fprintf(stderr,"%s at line %d\n",s,linecount());
+ fprintf(error_file,"%s at line %d\n",s,linecount);
+ error = TRUE;
+}
+
+
+
+char delmark = '|'; /* delimiter */
+int tagcount; /* keeps track of tags */
+
+/* strequ */
+int strequ(s1,s2)
+char *s1, *s2;
+{
+ if (strcmp(s1,s2) == 0)
+ return(TRUE);
+ else
+ return(FALSE);
+}
+
+/* local node label & annotation-ending function */
+static int endlabel(c)
+char c;
+{
+ if (eoln() || c == delmark) {
+ return(TRUE);
+ }
+ else
+ return(FALSE);
+}
+
+/* local command-word ending function */
+static int endcom(c)
+char c;
+{
+ if (c == ' ' || c == delmark) {
+ return(TRUE);
+ }
+ else
+ return(FALSE);
+}
+
+/* adapted from K&R itoa */
+void convert(n,s)
+int n;
+char s[];
+{
+ int i;
+
+ i = 0;
+ do {
+ s[i++] = n % 26 + 'a';
+ } while ((n /= 26) > 0);
+ s[i] = '\0';
+}
+
+char grabchar()
+{
+char c;
+ c = nextchar();
+ if (c == '%') {
+ fetchline();
+ return(grabchar());
+ } else
+ return (c);
+}
+
+/* allocates nodespace, reads in info, etc. */
+treenode *build_node()
+{
+ int go;
+
+ treenode *node;
+ word holder;
+ char **pointer;
+
+ pointer = &(holder.loc);
+ node = (treenode *)malloc(sizeof(treenode));
+ readword(&node->name,&go,endlabel,grabchar,FALSE);
+ node->next = NULL;
+ node->daughters = NULL;
+ node->mother = NULL;
+ node->tri = FALSE;
+ node->term = TRUE;
+ node->tag[0]='\0';
+ while (go) {
+ readword(&holder,&go,endcom,nextchar,FALSE);
+ if (strequ(*pointer,"tri"))
+ node->tri=TRUE;
+ else
+ if (strequ(*pointer,"tag")) {
+ readword(&holder,&go,endcom,nextchar,FALSE);
+ strcpy(node->tag,*pointer);
+ }
+ }
+
+ if (node->tag[0] == '\0') {
+ node->tag[0] = 'Z';
+ convert(tagcount++,&(node->tag[1]));
+ }
+ return(node);
+}
+
+/* gets a node, assuming that the line the node is on is already read
+ in */
+treenode *get_node()
+{
+ int pos,dpos;
+
+ treenode *node;
+
+ advanceeoln_pos(&pos);
+ if (eoln()) {
+ goof("blank line in tree");
+ fetchline();
+ return(NULL);
+ }
+ node = build_node();
+ fetchline();
+ advanceeoln_pos(&dpos);
+ if (dpos > pos) {
+ get_daughters(node,dpos);
+ }
+ return(node);
+}
+
+get_daughters(node,dpos)
+treenode *node; /* node of which daughters are being read */
+int dpos; /* position where daughters are supposed to be */
+{
+ int pos;
+ treenode *current;
+
+ current = get_node();
+ current->mother = node;
+ node->daughters = current;
+ node->term = FALSE;
+
+ while (currentpos() == dpos && !error) { /* as long as we're getting daughters */
+ current->next = get_node();
+ current = current->next;
+ current->mother = node;
+ }
+}
+
+void show_tree(node, ind)
+treenode *node;
+int ind;
+{
+ int i;
+
+ if (node != NULL) {
+ for (i = 1; i<=ind; i++)
+ putc(' ', outstream);
+ fprintf(outstream,"%s\n",node->name.loc);
+if (node->tri) printf("TRI\n");
+printf("tag = %s\n",node->tag);
+ for (node = node->daughters; node !=NULL; node=node->next)
+ show_tree(node,ind+2);
+ }
+}
+
+
+
+void write_tree(node, ind)
+treenode *node;
+int ind;
+{
+ int i;
+ treenode *mother;
+
+ if (node != NULL) {
+ mother = node;
+ for (i = 1; i<=ind; i++) /* print indentation */
+ putc(' ', outstream);
+ if (node->term) {
+ fprintf(outstream,"{\\tnode{%s}{%s}}",node->tag,node->name.loc);
+ }
+ else {
+ fprintf(outstream,"{\\ntnode{%s}{%s},\n",node->tag,node->name.loc);
+ for (node = node->daughters; node !=NULL; node=node->next)
+ write_tree(node,ind+2);
+/*
+ for (i = 1; i<=ind; i++)
+ putc(' ', outstream);
+*/
+ putc('}',outstream);
+ };
+
+ if (mother->next != NULL) fprintf(outstream,",\n");
+/*
+ else fprintf(outstream,"%\n");
+ if (node->next != NULL && node->mother != NULL)
+ putc(',',outstream);
+ putc('\n',outstream);
+*/
+ }
+}
+
+void draw_lines(node)
+treenode *node;
+{
+ int i;
+ char *m; /* mother & daughter tags */
+ treenode *mother; /* mother */
+
+ if (node != NULL) {
+ mother = node;
+ m = mother->tag;
+ for (node = mother->daughters; node !=NULL; node=node->next) {
+ if (node->tri)
+ fprintf(outstream,"\\nodetriangle{%s}{%s}%%\n",m,node->tag);
+ else
+ fprintf(outstream,"\\nodeconnect{%s}{%s}%%\n",m,node->tag);
+ }
+ for (node = mother->daughters; node !=NULL; node=node->next)
+ draw_lines(node);
+ }
+}
+
+
+void free_tree(node)
+treenode *node;
+{
+
+ if (node !=NULL) {
+ for (node = node->daughters; node !=NULL; node=node->next)
+ free_tree(node);
+ free(node);
+ node=NULL;
+ }
+}
+
+
+void tree()
+{
+ treenode *node;
+
+ delmark = '|';
+ error = FALSE;
+ tagcount = 0;
+
+ init_store();
+ fetchline();
+ node=get_node();
+ if (!matchstr(".]") && !error)
+ goof("bad tree indentation");
+ if (error) {
+ fprintf(outstream,"\nBAD TREE\n");
+ error = FALSE;
+ }
+ else {
+ fprintf(outstream,"\\tree");
+ write_tree(node,0);
+ fprintf(outstream,"%%\n"),
+ draw_lines(node);
+ }
+ free_tree(node);
+}
+
+void extendfilename(name,extension,result)
+/* chris: fix parameter declarations */
+char name[];
+char extension[];
+char result[];
+{
+ strcpy(result,name);
+ strcat(result,extension);
+}
+
+
+
+main(argc, argv)
+int argc;
+char *argv[];
+
+{
+
+ char infile[200];
+ char outfile[200];
+
+ char c;
+
+ /* chris - let it run as filter */
+ if (argc < 2)
+ {
+ strcpy(infile, "stdin");
+ strcpy(error_name, "trees.err");
+ }
+ else
+ {
+ extendfilename(argv[1],".txp",infile);
+ extendfilename(argv[1],"_tx2.tex",outfile);
+ extendfilename(argv[1],".err",error_name);
+ }
+
+/* VAX/VMS reading from logical `source', writing to logical `product'
+ open_source("source");
+ outstream = fopen("product","w");
+*/
+
+ if (open_source(infile)) {
+ /* chris - letting it run as a filter still */
+ if (argc < 2)
+ outstream = stdout;
+ else
+ outstream = fopen(outfile,"w");
+ while (fetchline()) { /* as long as there's input */
+ if (nextchar() == '.') {
+ if ((c = nextchar()) == '[') {
+ tree();
+ }
+#ifdef INC_COLUMNS
+ else
+ if (c == '<') {
+ columns();
+ }
+#endif
+ }
+ else {
+ writeline();
+ }
+ }
+ } else printf("file `%s' not found\n",infile);
+ return(sinned);
+}
diff --git a/macros/latex209/contrib/trees/pstrees/trees.doc.pdf b/macros/latex209/contrib/trees/pstrees/trees.doc.pdf
new file mode 100644
index 0000000000..1244a2c275
--- /dev/null
+++ b/macros/latex209/contrib/trees/pstrees/trees.doc.pdf
Binary files differ
diff --git a/macros/latex209/contrib/trees/pstrees/trees.doc.tex b/macros/latex209/contrib/trees/pstrees/trees.doc.tex
new file mode 100644
index 0000000000..c8983a3fbb
--- /dev/null
+++ b/macros/latex209/contrib/trees/pstrees/trees.doc.tex
@@ -0,0 +1,338 @@
+\documentstyle[11pt,lingmacros,tree-dvips,trees]{article}
+\textheight=9in
+\textwidth=6.5in
+\oddsidemargin=0in
+\evensidemargin=0in
+\topmargin=-.5in
+
+\begin{document}
+\begin{center}
+{\large\bf Avery Andrews'}\\
+\medskip
+{\Large\bf The Trees Preprocessor}
+\end{center}
+\medskip
+
+Consider the tree shown in \ex{1} drawn from Newmeyer (1986) following GKPS:
+
+\begin{example}
+\hspace*{-1.8em}\small
+\tree{\ntnode{Za}{S},
+ {\ntnode{Zb}{NP},
+ {\tnode{Zc}{that book}}},
+ {\ntnode{Zd}{{S/NP}},
+ {\ntnode{Ze}{NP},
+ {\tnode{Zf}{I}}},
+ {\ntnode{Zg}{{VP/NP}},
+ {\ntnode{Zh}{V},
+ {\tnode{Zi}{want}}},
+ {\ntnode{Zj}{{VP/NP}},
+ {\tnode{Zk}{to}},
+ {\ntnode{Zl}{{VP/NP}},
+ {\ntnode{Zm}{V},
+ {\tnode{Zn}{ask}}},
+ {\ntnode{Zo}{NP},
+ {\tnode{Zp}{Mary}}},
+ {\ntnode{Zq}{{VP/NP}},
+ {\tnode{Zr}{to}},
+ {\ntnode{Zs}{{VP/NP}},
+ {\ntnode{Zt}{V},
+ {\tnode{Zu}{tell}}},
+ {\ntnode{Zv}{NP},
+ {\tnode{Zw}{Tom}}},
+ {\ntnode{Zx}{{VP/NP}},
+ {\tnode{Zy}{to}},
+ {\ntnode{Zz}{{VP/NP}},
+ {\ntnode{Zab}{V},
+ {\tnode{Zbb}{read}}},
+ {\ntnode{Zcb}{{NP/NP}},
+ {\tnode{Zdb}{e}}}}}}}}}}}}%
+\nodeconnect{Za}{Zb}%
+\nodeconnect{Za}{Zd}%
+\nodetriangle{Zb}{Zc}%
+\nodeconnect{Zd}{Ze}%
+\nodeconnect{Zd}{Zg}%
+\nodeconnect{Ze}{Zf}%
+\nodeconnect{Zg}{Zh}%
+\nodeconnect{Zg}{Zj}%
+\nodeconnect{Zh}{Zi}%
+\nodeconnect{Zj}{Zk}%
+\nodeconnect{Zj}{Zl}%
+\nodeconnect{Zl}{Zm}%
+\nodeconnect{Zl}{Zo}%
+\nodeconnect{Zl}{Zq}%
+\nodeconnect{Zm}{Zn}%
+\nodeconnect{Zo}{Zp}%
+\nodeconnect{Zq}{Zr}%
+\nodeconnect{Zq}{Zs}%
+\nodeconnect{Zs}{Zt}%
+\nodeconnect{Zs}{Zv}%
+\nodeconnect{Zs}{Zx}%
+\nodeconnect{Zt}{Zu}%
+\nodeconnect{Zv}{Zw}%
+\nodeconnect{Zx}{Zy}%
+\nodeconnect{Zx}{Zz}%
+\nodeconnect{Zz}{Zab}%
+\nodeconnect{Zz}{Zcb}%
+\nodeconnect{Zab}{Zbb}%
+\nodeconnect{Zcb}{Zdb}%
+\end{example}
+This would require some drama to do by hand, but the {\sf trees'} system
+makes it reasonably easy.
+
+The system consists of three components: a preprocessor that
+converts a simple tree format into \TeX\ input; a \TeX\ macro file that
+lays out the nodes for trees, and Emma Pease's tree macro package that
+interfaces to Postscript and draws lines, and assorted other fancier sorts
+of graphics.
+
+\section{The trees preprocessor}
+\subsection{Usage}
+
+If you give a file-name argument {\tt trees test}, the input will
+be read from `test.txp', and written to `test{\_}tx2.tex', the latter
+being what you then submit to {\TeX} (the clumsy and complicated
+name is to make it easy to clean up directories without accidentally
+deleting source files). Errors go to `test.err'. The resulting
+dvi file will be `test{\_}tx2.dvi': the nuisance of specifying clumy
+names can be reduced by putting the parts of papers requiring
+preprocessing into include files.
+
+Alternatively, with no filename argument,
+the input is read from stdin, output written to stdout, errors
+written to stderr.
+
+A sample input file is test.tex
+
+A tree begins with \verb+.[+, ends with \verb+.]+, and are preprocessed for
+joint use with `tree-dvips.sty' (node boxing \& line drawing) and `trees.sty'
+(tree layout).
+
+Nesting is indicated by increasing depth of embedding, sisters
+must be indented equally, i.e.:
+\begin{verbatim}
+ .[
+ S
+ NP
+ John
+ VP
+ V
+ bit
+ NP
+ Fido
+ .]
+ \end{verbatim}
+If a node is to be connected to its mother by a triangle, it
+is followed by the flag \verb+|tri+. If it is to be given a special
+tag (for boxing, or whatever), the flag \verb+|tag fred+ (or whatever)
+is supplied.
+
+
+\section{Trees}
+
+1. Purpose.
+Trees is a preprocessor designed to work together with my `trees.sty'
+(La)Tex macro package \& Emma Pease's `tree-dvips.sty' package
+to help with
+tree-formatting. It probably doesn't do anything that couldn't actually
+be done entirely in TeX, but for the moment I leave to others to spend
+their lives figuring out how.
+
+2. Basic Operation.
+The file needs to invoke trees.sty \& tree-dvips.sty, e.g., in LaTex, it
+might start out:
+\begin{verbatim}
+ \documentstyle[tree-dvips,trees]{article}
+\end{verbatim}
+(or you could have \verb+\input{tree-dvips.sty}\input{trees.sty}+ in the text).
+
+The signal for `trees' to kick into action is a line beginning with
+`.['. The tree is then presented as an indented list, with a first
+daughter appearing (directly) after and more deeply embedded than its
+mother, and subsequent sisters indented equally to the first. The tree
+closes with `.]' (at the beginning of the line).
+
+E.g.:
+
+(1)
+\begin{verbatim}
+ .[
+ S
+ NP
+ Det
+ a
+ Nom
+ A
+ savage
+ Nom
+ N
+ puppy
+ VP
+ V
+ destroyed
+ NP
+ Det
+ the
+ Nom
+ shoe
+ .]
+\end{verbatim}
+What comes out of the preprocessor is input to be handled by
+`trees.sty' (which does tree layout) and `tree-dvips.sty' (which does the
+line-drawing).
+
+So from (1) we get (2):
+
+(2)
+\begin{verbatim}
+\tree{\ntnode{Za}{S},
+ {\ntnode{Zb}{NP},
+ {\ntnode{Zc}{Det},
+ {\tnode{Zd}{a}}
+ },
+ {\ntnode{Ze}{Nom},
+ {\ntnode{Zf}{A},
+ {\tnode{Zg}{savage}}
+ },
+ {\ntnode{Zh}{Nom},
+ {\ntnode{Zi}{N},
+ {\tnode{Zj}{puppy}}
+ }
+ }
+ }
+ },
+ {\ntnode{Zk}{VP},
+ {\ntnode{Zl}{V},
+ {\tnode{Zm}{destroyed}}
+ },
+ {\ntnode{Zn}{NP},
+ {\ntnode{Zo}{Det},
+ {\tnode{Zp}{the}}
+ },
+ {\ntnode{Zq}{Nom},
+ {\tnode{Zr}{shoe}}
+ }
+ }
+ }
+}
+\nodeconnect{Za}{Zb}
+\nodeconnect{Za}{Zk}
+\nodeconnect{Zb}{Zc}
+\nodeconnect{Zb}{Ze}
+\nodeconnect{Zc}{Zd}
+\nodeconnect{Ze}{Zf}
+\nodeconnect{Ze}{Zh}
+\nodeconnect{Zf}{Zg}
+\nodeconnect{Zh}{Zi}
+\nodeconnect{Zi}{Zj}
+\nodeconnect{Zk}{Zl}
+\nodeconnect{Zk}{Zn}
+\nodeconnect{Zl}{Zm}
+\nodeconnect{Zn}{Zo}
+\nodeconnect{Zn}{Zq}
+\nodeconnect{Zo}{Zp}
+\nodeconnect{Zq}{Zr}
+\end{verbatim}
+
+The preprocessor has converted the visually convenient indented list notation
+into appropriate TeX grouping for the \tree macro (defined in trees.sty), and
+has put the node labels into `\ntnode' (nonterminal) and `tnode' (terminal
+commands), which feed the \node command (in `tree-dvips.sty') as discussed
+briefly below. Each node has also been assigned a tag starting with
+`Z', and linedrawing commands (`tree-dvips.sty') issued as appropriate.
+
+
+3. Options.
+Options are separated from the node label by a vertical bar (`$\|$'). There
+are currently two of them. The `tri' option connecs the node to its mother
+with a triangle instead of a line. And the `tag TAG' option, where TAG
+is any alphabetic string, sets TAG as the tag of the node. Both of these
+are illustrated in:
+
+(3)
+\begin{verbatim}
+ .[
+ S
+ NP
+ the puppy|tri
+ VP|tag vp
+ barked
+ .]
+ \nodecircle{vp}
+\end{verbatim}
+Putting your own label on the VP node makes it easy to use tree-dvips.sty
+commands on it freely.
+
+Two additional useful options are handled directly by the
+{\sf trees.sty} definitions. First, one sometimes wants to specify the
+space between the mother and daughters (if the tree is rather wide,
+for example, the default spacing at the top might be too small).
+This can be done by putting a command such as \verb+\daughterskip{4ex}+
+somewhere in the mother node, e.g.:
+
+(4)
+\begin{verbatim}
+ .[
+ S\daughtergap{4ex}
+ NP
+ the annoying child|tri
+ VP
+ ran away from the crazed puppy|tri
+ .]
+\end{verbatim}
+It is also possible to specify the distance between a node and its
+previous sister with a command such as \verb+\sistergap{-2em}+. This can
+be especially useful in packing `wide trees' that wouldn't otherwise
+fit.
+
+The default spacings for sisters \& daughters can also be altered,
+as discussed in trees.sty.
+
+4. \verb+\ntnode & \tnode.+
+The \verb+\ntnode+ and \verb+\tnode+ commands do some moderately
+complicated things
+that are basically adapted to make it easier to write LFG papers. Both
+commands operate on node specifications where a bunch of annotations
+are specified as sitting on top of the main node label. E.g.:
+\begin{verbatim}
+ \ntnode{a}{(\uparrow SUBJ)=\downarrow/NP}
+\end{verbatim}
+Puts the annotation on top of the node-label, and automatically sets
+it in math-mode.. The levels are separated by a slash, and there can be as
+many as you like. The difference between \verb+\ntnode+ and \verb+\tnode+
+is that the
+latter sets the last level in italics, as is the norm for terminals.
+
+(5)
+\begin{verbatim}
+ .[
+ S
+ (\uparrow SUBJ)=\downarrow/NP
+ \uparrow = \downarrow/N
+ Mary
+ \uparrow = \downarrow/VP
+ yelled
+ .]
+\end{verbatim}
+For information on altering the operations of \verb+\ntnode & \tnode+, see
+trees.sty. One could also switch off all of this stuff by redefining
+them to in effect do nothing:
+\begin{verbatim}
+ \def\ntnode#1#2{#2}
+ \def\tnode#1#2{#2}
+\end{verbatim}
+\subsection{Assembly}
+The program has so far run under Sun cc, and Turbo C 2.
+For Sun cc, the module ansi.c is required, to supply some
+library functions that appear to be missing. There are some
+bits of code for the VMS/VAX C version, but the adjustments would
+need to be made by hand. A executable and source files with a
+Unix makefile are provided.
+
+\subsection{Availability}
+Emma Pease's tree-dvips may be found in tree.tar.Z in /pub/TeXfiles
+on csli.stanford.edu.
+The preprocessor plus trees.sty may be found in pstrees.tar.Z
+in /pub/TMP on csli.stanford.edu
+
+\end{document}
diff --git a/macros/latex209/contrib/trees/pstrees/trees.doc.txp b/macros/latex209/contrib/trees/pstrees/trees.doc.txp
new file mode 100644
index 0000000000..3af25ed1a9
--- /dev/null
+++ b/macros/latex209/contrib/trees/pstrees/trees.doc.txp
@@ -0,0 +1,311 @@
+\documentstyle[11pt,lingmacros,tree-dvips,trees]{article}
+\textheight=9in
+\textwidth=6.5in
+\oddsidemargin=0in
+\evensidemargin=0in
+\topmargin=-.5in
+
+\begin{document}
+\begin{center}
+{\large\bf Avery Andrews'}\\
+\medskip
+{\Large\bf The Trees Preprocessor}
+\end{center}
+\medskip
+
+Consider the tree shown in \ex{1} drawn from Newmeyer (1986) following GKPS:
+
+\begin{example}
+\hspace*{-1.8em}\small
+.[
+S
+ NP
+ that book|tri
+ {S/NP}
+ NP
+ I
+ {VP/NP}
+ V
+ want
+ {VP/NP}
+ to
+ {VP/NP}
+ V
+ ask
+ NP
+ Mary
+ {VP/NP}
+ to
+ {VP/NP}
+ V
+ tell
+ NP
+ Tom
+ {VP/NP}
+ to
+ {VP/NP}
+ V
+ read
+ {NP/NP}
+ e
+.]
+\end{example}
+This would require some drama to do by hand, but the {\sf trees'} system
+makes it reasonably easy.
+
+The system consists of three components: a preprocessor that
+converts a simple tree format into \TeX\ input; a \TeX\ macro file that
+lays out the nodes for trees, and Emma Pease's tree macro package that
+interfaces to Postscript and draws lines, and assorted other fancier sorts
+of graphics.
+
+\section{The trees preprocessor}
+\subsection{Usage}
+
+If you give a file-name argument {\tt trees test}, the input will
+be read from `test.txp', and written to `test{\_}tx2.tex', the latter
+being what you then submit to {\TeX} (the clumsy and complicated
+name is to make it easy to clean up directories without accidentally
+deleting source files). Errors go to `test.err'. The resulting
+dvi file will be `test{\_}tx2.dvi': the nuisance of specifying clumy
+names can be reduced by putting the parts of papers requiring
+preprocessing into include files.
+
+Alternatively, with no filename argument,
+the input is read from stdin, output written to stdout, errors
+written to stderr.
+
+A sample input file is test.tex
+
+A tree begins with \verb+.[+, ends with \verb+.]+, and are preprocessed for
+joint use with `tree-dvips.sty' (node boxing \& line drawing) and `trees.sty'
+(tree layout).
+
+Nesting is indicated by increasing depth of embedding, sisters
+must be indented equally, i.e.:
+\begin{verbatim}
+ .[
+ S
+ NP
+ John
+ VP
+ V
+ bit
+ NP
+ Fido
+ .]
+ \end{verbatim}
+If a node is to be connected to its mother by a triangle, it
+is followed by the flag \verb+|tri+. If it is to be given a special
+tag (for boxing, or whatever), the flag \verb+|tag fred+ (or whatever)
+is supplied.
+
+
+\section{Trees}
+
+1. Purpose.
+Trees is a preprocessor designed to work together with my `trees.sty'
+(La)Tex macro package \& Emma Pease's `tree-dvips.sty' package
+to help with
+tree-formatting. It probably doesn't do anything that couldn't actually
+be done entirely in TeX, but for the moment I leave to others to spend
+their lives figuring out how.
+
+2. Basic Operation.
+The file needs to invoke trees.sty \& tree-dvips.sty, e.g., in LaTex, it
+might start out:
+\begin{verbatim}
+ \documentstyle[tree-dvips,trees]{article}
+\end{verbatim}
+(or you could have \verb+\input{tree-dvips.sty}\input{trees.sty}+ in the text).
+
+The signal for `trees' to kick into action is a line beginning with
+`.['. The tree is then presented as an indented list, with a first
+daughter appearing (directly) after and more deeply embedded than its
+mother, and subsequent sisters indented equally to the first. The tree
+closes with `.]' (at the beginning of the line).
+
+E.g.:
+
+(1)
+\begin{verbatim}
+ .[
+ S
+ NP
+ Det
+ a
+ Nom
+ A
+ savage
+ Nom
+ N
+ puppy
+ VP
+ V
+ destroyed
+ NP
+ Det
+ the
+ Nom
+ shoe
+ .]
+\end{verbatim}
+What comes out of the preprocessor is input to be handled by
+`trees.sty' (which does tree layout) and `tree-dvips.sty' (which does the
+line-drawing).
+
+So from (1) we get (2):
+
+(2)
+\begin{verbatim}
+\tree{\ntnode{Za}{S},
+ {\ntnode{Zb}{NP},
+ {\ntnode{Zc}{Det},
+ {\tnode{Zd}{a}}
+ },
+ {\ntnode{Ze}{Nom},
+ {\ntnode{Zf}{A},
+ {\tnode{Zg}{savage}}
+ },
+ {\ntnode{Zh}{Nom},
+ {\ntnode{Zi}{N},
+ {\tnode{Zj}{puppy}}
+ }
+ }
+ }
+ },
+ {\ntnode{Zk}{VP},
+ {\ntnode{Zl}{V},
+ {\tnode{Zm}{destroyed}}
+ },
+ {\ntnode{Zn}{NP},
+ {\ntnode{Zo}{Det},
+ {\tnode{Zp}{the}}
+ },
+ {\ntnode{Zq}{Nom},
+ {\tnode{Zr}{shoe}}
+ }
+ }
+ }
+}
+\nodeconnect{Za}{Zb}
+\nodeconnect{Za}{Zk}
+\nodeconnect{Zb}{Zc}
+\nodeconnect{Zb}{Ze}
+\nodeconnect{Zc}{Zd}
+\nodeconnect{Ze}{Zf}
+\nodeconnect{Ze}{Zh}
+\nodeconnect{Zf}{Zg}
+\nodeconnect{Zh}{Zi}
+\nodeconnect{Zi}{Zj}
+\nodeconnect{Zk}{Zl}
+\nodeconnect{Zk}{Zn}
+\nodeconnect{Zl}{Zm}
+\nodeconnect{Zn}{Zo}
+\nodeconnect{Zn}{Zq}
+\nodeconnect{Zo}{Zp}
+\nodeconnect{Zq}{Zr}
+\end{verbatim}
+
+The preprocessor has converted the visually convenient indented list notation
+into appropriate TeX grouping for the \tree macro (defined in trees.sty), and
+has put the node labels into `\ntnode' (nonterminal) and `tnode' (terminal
+commands), which feed the \node command (in `tree-dvips.sty') as discussed
+briefly below. Each node has also been assigned a tag starting with
+`Z', and linedrawing commands (`tree-dvips.sty') issued as appropriate.
+
+
+3. Options.
+Options are separated from the node label by a vertical bar (`$\|$'). There
+are currently two of them. The `tri' option connecs the node to its mother
+with a triangle instead of a line. And the `tag TAG' option, where TAG
+is any alphabetic string, sets TAG as the tag of the node. Both of these
+are illustrated in:
+
+(3)
+\begin{verbatim}
+ .[
+ S
+ NP
+ the puppy|tri
+ VP|tag vp
+ barked
+ .]
+ \nodecircle{vp}
+\end{verbatim}
+Putting your own label on the VP node makes it easy to use tree-dvips.sty
+commands on it freely.
+
+Two additional useful options are handled directly by the
+{\sf trees.sty} definitions. First, one sometimes wants to specify the
+space between the mother and daughters (if the tree is rather wide,
+for example, the default spacing at the top might be too small).
+This can be done by putting a command such as \verb+\daughterskip{4ex}+
+somewhere in the mother node, e.g.:
+
+(4)
+\begin{verbatim}
+ .[
+ S\daughtergap{4ex}
+ NP
+ the annoying child|tri
+ VP
+ ran away from the crazed puppy|tri
+ .]
+\end{verbatim}
+It is also possible to specify the distance between a node and its
+previous sister with a command such as \verb+\sistergap{-2em}+. This can
+be especially useful in packing `wide trees' that wouldn't otherwise
+fit.
+
+The default spacings for sisters \& daughters can also be altered,
+as discussed in trees.sty.
+
+4. \verb+\ntnode & \tnode.+
+The \verb+\ntnode+ and \verb+\tnode+ commands do some moderately
+complicated things
+that are basically adapted to make it easier to write LFG papers. Both
+commands operate on node specifications where a bunch of annotations
+are specified as sitting on top of the main node label. E.g.:
+\begin{verbatim}
+ \ntnode{a}{(\uparrow SUBJ)=\downarrow/NP}
+\end{verbatim}
+Puts the annotation on top of the node-label, and automatically sets
+it in math-mode.. The levels are separated by a slash, and there can be as
+many as you like. The difference between \verb+\ntnode+ and \verb+\tnode+
+is that the
+latter sets the last level in italics, as is the norm for terminals.
+
+(5)
+\begin{verbatim}
+ .[
+ S
+ (\uparrow SUBJ)=\downarrow/NP
+ \uparrow = \downarrow/N
+ Mary
+ \uparrow = \downarrow/VP
+ yelled
+ .]
+\end{verbatim}
+For information on altering the operations of \verb+\ntnode & \tnode+, see
+trees.sty. One could also switch off all of this stuff by redefining
+them to in effect do nothing:
+\begin{verbatim}
+ \def\ntnode#1#2{#2}
+ \def\tnode#1#2{#2}
+\end{verbatim}
+\subsection{Assembly}
+The program has so far run under Sun cc, and Turbo C 2.
+For Sun cc, the module ansi.c is required, to supply some
+library functions that appear to be missing. There are some
+bits of code for the VMS/VAX C version, but the adjustments would
+need to be made by hand. A executable and source files with a
+Unix makefile are provided.
+
+\subsection{Availability}
+Emma Pease's tree-dvips may be found in tree.tar.Z in /pub/TeXfiles
+on csli.stanford.edu.
+The preprocessor plus trees.sty may be found in pstrees.tar.Z
+in /pub/TMP on csli.stanford.edu
+
+\end{document}
diff --git a/macros/latex209/contrib/trees/pstrees/trees.sty b/macros/latex209/contrib/trees/pstrees/trees.sty
new file mode 100644
index 0000000000..0addd0aaea
--- /dev/null
+++ b/macros/latex209/contrib/trees/pstrees/trees.sty
@@ -0,0 +1,258 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 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
diff --git a/macros/latex209/contrib/trees/pstrees/words.c b/macros/latex209/contrib/trees/pstrees/words.c
new file mode 100644
index 0000000000..7bf3a28c35
--- /dev/null
+++ b/macros/latex209/contrib/trees/pstrees/words.c
@@ -0,0 +1,292 @@
+/* in this module appeaars machinery connected with the recognition
+ storage of words */
+
+#include "align.h" /* align definitions */
+/* VAX/VMS version
+#include <unixio>
+*/
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <math.h>
+
+
+/* externals from errors.c */
+extern goof(); /* error-writing routine
+ void goof(char *s); */
+extern int sinned, error; /* error-flags */
+
+/* externals from slurp.c */
+extern char *input_pointer;
+extern nextchar(); /* gets next character
+ char nextchar(); */
+extern peekchar(); /* peeks at next char
+ char peekchar() */
+extern advance(); /* advances to next printing char
+ void advance(); */
+
+/* externals from glosses */
+extern char delmark; /* example delimiter */
+extern int wordmax; /* maximum length of word */
+
+/* word storage */
+
+static char store[charmax]; /* array for storing string */
+static char *free_char; /* pointer to first available position */
+static char *top_char; /* pointer to top of store */
+
+/* initializes store */
+init_store()
+{
+ free_char = store;
+ top_char = store+charmax;
+}
+
+/* stows characters */
+int stow(c)
+char c;
+{
+ if (free_char<top_char) {
+ *(free_char++) = c;
+ return(TRUE);
+ }
+ else {
+ goof("too many characters in example");
+ }
+}
+
+
+static int envpointer; /* keeps track of group nesting */
+
+void readword(here, stop, quit, grab, lookahead)
+word *here; /* location of word record to be filled in */
+int *stop; /* where to record whether stop-delimiter encountered */
+int (*quit)(); /* function specifying whether to stop */
+char (*grab)(); /* character-reading procedure to be used */
+int lookahead; /* whether to advance to next printing char */
+{
+
+ char c; /* character holder */
+
+ *stop = FALSE;
+ envpointer = 0;
+
+ here->loc=free_char;
+ c=grab();
+ while (envpointer > 0 || !quit(c)) { /* there is nothing
+ in the stack, or neither of the word-enders encountered */
+ stow(c);
+ if (error) return;
+ else
+ if (c == '\\') {
+ if (peekchar() == ' ') {
+ grab(c);
+ stow(c);
+ }
+ }
+ else
+ if (c == '{')
+ envpointer++;
+ if (envpointer > 0 && c == '}')
+ envpointer--;
+ c=grab();
+ if (c == delmark && envpointer > 0) {
+ goof("line-break within TeX command");
+ envpointer = 0;
+ }
+ }
+
+ stow('\0'); /* mark end of word i store */
+ if (c == delmark) *stop = TRUE;
+ if (!*stop) {
+ if (lookahead) {
+ advance();
+ if (peekchar()==delmark) {
+ *stop = TRUE;
+ nextchar();
+ }
+ }
+ }
+}
+
+/* scantil_c
+ looks for the first instance in arg2 of some char in arg1; returns 1
+ if found; otherwise 0; arg3 points to char if found, arg2
+ otherwise */
+
+int scantil_c(forchars,instring,wherefound)
+char *forchars;
+char *instring;
+char **wherefound;
+{
+ char *whichchar;
+ char *locus;
+
+ locus = instring;
+
+
+ while (*locus != NULL) {
+ whichchar = forchars;
+ while (*whichchar !=NULL) {
+ if (*whichchar == *locus) {
+ *wherefound = locus;
+ return(TRUE);
+ }
+ else whichchar++;
+ }
+ locus++;
+ }
+ *wherefound = instring;
+ return(FALSE);
+}
+
+void stow_stuff(from,to)
+char *from;
+char *to;
+{
+ while (from != to) {
+ stow(*from);
+ from++;
+ }
+ input_pointer = to;
+}
+
+void pull_args(locus)
+char **locus;
+{
+ char *nextloc;
+
+ while (**locus == '{') {
+ scantil_c("}{",(*locus)+1,&nextloc);
+ if (*nextloc == '}') {
+ nextloc++;
+ if (*nextloc == '{') {
+ *locus = nextloc;
+ }
+ else break;
+ }
+ else break;
+ }
+}
+
+
+
+/* command is parsed as anything between \ and a member of the
+ 1st arg. of scantil_c. pull_args gets all args but last,
+ not allowing embedded commands in these (for labels, etc). */
+
+void get_command()
+{
+ char *locus;
+
+ scantil_c("{ \\|$_^",input_pointer,&locus);
+ pull_args(&locus);
+ stow_stuff(input_pointer,locus);
+
+}
+
+
+
+/* readword hacked for the peculiar demands of the `columns'
+module, essentially being that length calculations are done so
+that alignments can be worked out on the screen */
+
+void readword_col(here, bar, quit)
+word *here; /* location of word record to be filled in */
+int *bar; /* where to record whether bar-delimiter encountered */
+int (*quit)(); /* function specifying whether to stop */
+{
+
+ char c,d; /* character holder */
+ int size;
+
+ *bar = FALSE;
+ envpointer = 0;
+
+ here->loc=free_char;
+ size=0;
+ c=nextchar();
+ while (envpointer > 0 || !quit(c)) { /* there is nothing
+ in the stack, or neither of the word-enders encountered */
+ stow(c);
+ if (error) return;
+ else
+ if (c == '\\') {
+ get_command();
+ if ((d = peekchar()) != '{')
+ size++;
+ }
+ else
+ if (c == '{')
+ envpointer++;
+ else
+ if (envpointer > 0 && c == '}')
+ envpointer--;
+ else
+ if (c == '$') {}
+ else
+ size++;
+ c=nextchar();
+ if (c == delmark && envpointer > 0) {
+ goof("line-break within TeX command");
+ envpointer = 0;
+ }
+ }
+ stow('\0'); /* mark end of word i store */
+ here->size = size;
+ if (c == '|') *bar = TRUE;
+
+}
+
+/* writes words to a stream */
+void writeword(out,it)
+FILE *out;
+word *it;
+{
+ fprintf(out,"{%s}",it->loc);
+}
+
+/*
+char delmark = '\\';
+int wordmax = 60;
+
+main()
+{
+word sample;
+int stop;
+
+get_com_widths("widths.dat");
+open_source("text.dat");
+init_store();
+
+
+advance();
+readword(&sample,&stop,' ',nextchar,0);
+printf("%s, size = %d, bracket= %d\n",sample.loc,sample.size,sample.bracket);
+if (stop) printf("stop!\n");
+
+}
+
+*/
+
+/*
+
+char delmark;
+
+main(argc,argv)
+int argc;
+char **argv;
+{
+ char **s;
+ int whether;
+
+ whether = scantil_c(argv[1],argv[2],s);
+
+ if (whether) {
+ puts("yes: ");
+ }
+ else puts("no: ");
+ puts(*s);
+}
+*/
+
diff --git a/macros/latex209/contrib/trees/tree-dvips/Makefile b/macros/latex209/contrib/trees/tree-dvips/Makefile
new file mode 100644
index 0000000000..348d436136
--- /dev/null
+++ b/macros/latex209/contrib/trees/tree-dvips/Makefile
@@ -0,0 +1,12 @@
+
+ALLFILES = README Makefile lingmacros.sty tree-dvips.sty avm.sty tree-dvips91.pro \
+ tree-dvips91.script tree-manual.tex lingmacros-manual.tex avm-doc.tex \
+ avm-doc.sty
+
+all: tree-dvips.pro
+
+tar:
+ tar cf tree-dvips.tar ${ALLFILES}
+
+tree-dvips.pro: tree-dvips.script
+ squeeze < tree-dvips.script > tree-dvips.pro
diff --git a/macros/latex209/contrib/trees/tree-dvips/README b/macros/latex209/contrib/trees/tree-dvips/README
new file mode 100644
index 0000000000..19ce0b8266
--- /dev/null
+++ b/macros/latex209/contrib/trees/tree-dvips/README
@@ -0,0 +1,48 @@
+tree-dvips: There are three items in this package. All files released
+under the LaTeX Project Public License, version 1, or (at your option),
+any later version.
+
+1. CSLI postscript drawing macros. Created by Emma Pease
+(erpease at gmail dot com).
+
+latest update: May 16, 1995
+version .91
+
+These macros were originally created to draw the lines between nodes
+in the trees created by the tree macros in lingmacros.sty. They will
+only work with dvips version 541 or later (by Tomas Rokicki available
+on labrea.stanford.edu) but can be easily modified to be used with
+earlier versions of dvips and slightly less easily modified for other
+dvi to postscript convertors.
+
+Problems:
+
+Be wary of using page extraction programs such as dviselect as you may
+accidently drop the special command loading the header file if you do
+not include the first page. dvips's own page selection commands will
+keep the special.
+
+If rotating, the nodeconnects should be included within the boundaries
+of the \rotate command
+
+
+2. CSLI linguistics macros (lingmacros.sty). Created by various folk at
+CSLI but maintained by Emma Pease.
+
+3. The avm.sty file is a separate package created by Chris Manning
+(manning@lcl.cmu.edu) while he was at csli. It is included by
+permission from him.
+
+
+To install, place
+
+tree-dvips.pro
+
+in the postscript header path for dvips.
+
+place the three .sty files where you put latex style files
+
+Two things not included in this file but may be needed are
+the squeeze program and rotate.sty. Both are available with dvips.
+
+
diff --git a/macros/latex209/contrib/trees/tree-dvips/avm-doc.sty b/macros/latex209/contrib/trees/tree-dvips/avm-doc.sty
new file mode 100644
index 0000000000..a03fc69bf9
--- /dev/null
+++ b/macros/latex209/contrib/trees/tree-dvips/avm-doc.sty
@@ -0,0 +1,122 @@
+\textheight=9in
+\textwidth=6.5in
+\oddsidemargin=0in
+\evensidemargin=0in
+\topmargin=-.5in
+
+\def\av{{\sf avm.sty}}
+\def\AVM{\small AVM}
+\avmfont{\sc}
+\avmsortfont{\scriptsize\it}
+\def\ssf{\small\sf}
+
+% This was used in trees to make the tree skips bigger and the avm skips
+% smaller.
+\def\avmtreeparms{\avmvskip{.1ex}\avmhskip{.5em}%
+\avmbskip{-.2em}\daughterskip=4ex\sisterskip=3em}
+
+%chris+
+% The \ex definition
+% modified Feb 13 1991 to provide \exn for bare example number,
+% \ex for normal xref format, in parentheses.
+% further modified to have (following) optional argument for sublabel
+% beware if you follow it by a square bracket for other reasons!
+%\newcounter{tempcnt}
+
+% this one doesn't gobble spaces while looking for a [ and so will leave a
+% space after an optional argument.
+\def\@ifverynextchar#1#2#3{\let\@tempe #1\def\@tempa{#2}\def
+ \@tempb{#3}\futurelet\@tempc\@ifvnch}
+\def\@ifvnch{\ifx \@tempc \@tempe\let\@tempd\@tempa\else\let\@tempd\@tempb\fi
+ \@tempd}
+
+\newcommand{\exn}[1]{\setcounter{tempcnt}{\value{enums}}%
+\addtocounter{tempcnt}{#1}%
+\arabic{tempcnt}}
+
+\def\@ex#1[#2]{(\exn{#1}#2)}
+
+\def\ex#1{\@ifverynextchar[{\@ex#1}% %]
+{\@ex#1[]}}
+
+\def\exx#1#2{(\exn{#1}--\exn{#2})}
+
+\def\exxref#1#2{(\ref{#1}--\ref{#2})}
+
+% \exref for label-references: (ADA 13 Feb 1991)
+\def\exref#1{\@ifverynextchar[{\@exref#1}% %]
+{\@exref#1[]}}
+
+\def\@exref#1[#2]{(\ref{#1}#2)}
+%chris-
+
+
+
+% taken from Chris's personal macros
+%chris+
+% Examples environment. This is a slightly non-standard environment that
+% has two optional parameters:
+% o the first is a number or other label to give the example. This
+% optional argument must be surrounded in ( ); if none is supplied the
+% enums counter is used; either will be surrounded by ( ) in the text.
+% o the second is a string representing the longest piece of text you
+% allege you will want to llap with \bad below and the indentation of
+% examples is increased by the width of it to allow for this.
+% (Note that LaTeX doesn't officially support optional arguments to
+% environments, and having two kinds of optional arguments is a bit of an
+% innovation, but they're not difficult to implement in practice.)
+% Examples:
+% A complete example:
+% \begin{examples}(18)[\#\#] \item \bad{\#\#}A bone ate a dog.
+% \item A dog ate a bone. \end{examples}
+% Other prologues:
+% \begin{examples} (92) \begin{examples}[??] \begin{examples}
+\newbox\ll@pbox % for calculating width of llap'ed material
+\newdimen\llapdimen
+\llapdimen=0pt
+\newdimen\exlabel
+\exlabel=20pt
+
+\def\bad#1{\leavevmode\llap{#1}} % put badness ratings in here!
+
+% these clauses provide a definition of the `examples' pseudo-environment
+\def\examples{\@ifnextchar({\ex@@mples}% %)
+{\refstepcounter{enums}\ex@@mples(\theenums)}}
+
+\long\def\ex@@mples(#1){\@ifnextchar[{\ex@mples(#1)}% %]
+{\ex@mples(#1)[]}}
+
+\long\def\ex@mples(#1)[#2]{\def\eelabel{#1}
+\setbox\@tempboxa=\hbox{(#1)}%There used to be a space here which was crazy
+\@tempdima=\wd\@tempboxa
+\ifdim\exlabel>\@tempdima \@tempdima=\exlabel\fi
+%\advance\@tempdima by -20pt
+\setbox\ll@pbox=\hbox{#2}
+\@tempdimb=\wd\ll@pbox
+\ifdim\llapdimen>\@tempdimb \@tempdimb=\llapdimen\fi
+\begin{list}{\alph{enumsi}.}{\usecounter{enumsi}%
+% abandon auto width determination until I can get it right...
+%\labelwidth=\@tempdima\leftmargin=\@tempdima
+\advance\leftmargin by \eeindent\advance\labelwidth by \eeindent
+\advance\leftmargin by \@tempdimb\advance\labelsep by \@tempdimb
+\advance\leftmargin by\widelabel \advance\labelwidth by \widelabel
+%\itemsep=0pt % Optional, but sometimes examples look better scrunched a bit
+\let\makelabel=\enummakelabel}}
+
+\def\endexamples{\end{list}}
+
+% example environment
+\def\example{\@ifnextchar({\ex@@mple}% %)
+{\refstepcounter{enums}\ex@@mple(\theenums)}}
+
+\long\def\ex@@mple(#1){\@ifnextchar[{\ex@mple(#1)}% %]
+{\ex@mple(#1)[]}}
+
+\long\def\ex@mple(#1)[#2]{\setbox\ll@pbox=\hbox{#2}%
+\begin{list}{}{\advance\leftmargin by \wd\ll@pbox%
+\advance\leftmargin by\widelabel \advance\labelwidth by\widelabel
+\advance\labelsep by \wd\ll@pbox}
+\item[(#1)]}
+
+\def\endexample{\end{list}}
+%chris-
diff --git a/macros/latex209/contrib/trees/tree-dvips/avm-doc.tex b/macros/latex209/contrib/trees/tree-dvips/avm-doc.tex
new file mode 100644
index 0000000000..a6a3f2bf6f
--- /dev/null
+++ b/macros/latex209/contrib/trees/tree-dvips/avm-doc.tex
@@ -0,0 +1,1245 @@
+% This is the authoritative version (the one at PARC)
+%\documentstyle[11pt,avm,lingmacros,samesizesectionfont,tree]{article}
+\documentstyle[11pt,avm,lingmacros,avm-doc,tree-dvips]{article}
+
+% To do:
+% Get it so you can embed avm environments DONE
+% Put example of subscripted index in DONE
+% Document new features. DONE
+% Work out the semantics of fonts and document it DONE
+% Fix verbatim in footnote DONE
+% Fix fonts and descriptions - blows when nested DONE
+% Change use of boxes to be all even as indicated in plain.tex! DONE
+% Get labels on all corners. DONE (except for Jackendoff position).
+% Fix it so that one can nest with tabular/more avms. DONE
+% Find out why there is the extra space in tavm.tex @ qW
+% (this happens only if you define nodes)
+
+\title{{\sf avm.sty}}
+\author{Christopher Manning\\{\ssf manning@csli.stanford.edu}}
+\date{Version 1.00 -- December 12, 1993}
+
+\begin{document}
+\maketitle
+
+\av\ is a \TeX\ macro package that makes it easy to draw attribute-value
+matrices ({\AVM}s, also known as feature structures and signs), things like
+\ex{1}:
+%
+\begin{example}
+\begin{avm}
+\sort{indexed-obj}{\[ index & \osort{index}{\[
+ variable & \@1 \osort{variable}{\[ per & \rm 3rd \\
+ num & \rm sing \\
+ gend & \rm neut \]} \\
+ restriction & \osort{psoa}{\[relation & \rm book \\
+ instance & \@1 \]} \]}
+ \setbox2=\hbox{Does this screw it?} % Testing whether this screws things
+ \]}
+\end{avm}
+\end{example}
+%
+It is a special
+mode, like math mode, in which various things are redefined in order to
+make it easy to typeset a certain type of thing. In fact, \av\
+supports several sub-modes of {\AVM} entry that are tailored to different
+needs. This document first describes the basic mode of \av\ and then shows
+how the specialized modes deviate from it. Everything that can be done in
+one of the specialized sub-modes can also be done in the main mode; it's
+just that you might be able to do it with less keystrokes. \av\ has
+been designed so that it will work with either \TeX\ or \LaTeX; the few
+differences between using these two formats are mentioned at the
+appropriate places below.
+
+\section{Loading this option}
+
+If you are using \LaTeX, \av\ should be included among the other
+document-style options that you load. For example, you might type
+at the beginning of your document:
+%
+\begin{example}
+\begin{verbatim}
+\documentstyle[11pt,avm,lingmacros]{article}
+\end{verbatim}
+\end{example}
+
+In \TeX, you input the file by including the following near the beginning
+of your document:
+\begin{example}
+\begin{verbatim}
+\input avm.sty
+\end{verbatim}
+\end{example}
+Either of these assumes that the file \av\ is somewhere on the search path for
+input files (the TEXINPUTS environment variable). This search path usually
+includes the current directory.
+
+\section{The `standard' environment}
+
+Most commands (except those that establish defaults) are only available
+within an {\AVM} environment. To enter and exit this environment, in \LaTeX\
+you type:
+\begin{example}
+\begin{verbatim}
+\begin{avm}
+...
+\end{avm}
+\end{verbatim}
+\end{example}
+while in \TeX\ you type:
+\begin{example}
+\begin{verbatim}
+\avm
+...
+\endavm
+\end{verbatim}
+\end{example}
+
+\subsection{Making AVMs in square brackets}
+
+The commands \verb+\[+ and \verb+\]+ begin and end a square-bracketed {\AVM}.
+Within an {\AVM}, a new line is begun by typing \verb+\\+.\footnote
+ {\TeX\ users can use {\tt \char'134 cr}, if they prefer. \LaTeX\ users
+ (only!) can follow the {\tt \char'134 \char'134 } with any of the things
+ that can follow {\tt \char'134 \char'134 } in {\tt tabular}
+ environments. So you can put extra space below one line of an AVM, by
+ typing {\tt \char'134 \char'134 [2ex]}, for example.}
+It is unnecessary to type \verb+\\+ following the
+last row of the {\AVM}. Within a line columns are divided by the ampersand
+`\verb+&+'. There can actually be any number of columns, although in most
+applications of {\AVM}s there are only two. For example:\footnote
+ {Here is one in a footnote (note the smaller fonts):
+ \begin{example}(i)
+ \begin{avm}
+ \[ ind & \[ pers & 3\\ num & \em sg\\ gend & \em masc\\refind & \@{12} \] \]
+ \end{avm}
+ \end{example}}
+\begin{examples}
+\item
+\begin{avm}
+\[ cat\|subcat & \<NP$_{it}$, NP$_{\@2}$, S[comp]:\@3\> \\
+ content & \[ relation & \bf bother\\
+ bothered & \@2 \\
+ soa-arg & \@3 \] \]
+\end{avm}
+
+\item
+\begin{avm}
+\[ subj & \[ pers & 3 \\
+ num & sg \\
+ gend & masc\\
+ pred & \rm `pro' \]\\
+
+ pred & \rm `eat\q<SUBJ, OBJ\q>'\\
+
+ obj & \[ pers & 3 \\
+ num & pl \\
+ gend & fem \\
+ pred & \rm `pro' \]
+\]
+\end{avm}
+\end{examples}
+
+\begin{examples}
+
+\item
+{\obeyspaces
+\begin{verbatim}
+\begin{avm}
+\[ cat\|subcat & \<NP$_{it}$, NP$_{\@2}$, S[comp]:\@3\> \\
+ content & \[ relation & \bf bother\\
+ bothered & \@2 \\
+ soa-arg & \@3 \] \]
+\end{avm}
+\end{verbatim}}
+
+\item
+{\obeyspaces
+\begin{verbatim}
+\begin{avm}
+\[ subj & \[ pers & 3 \\
+ num & sg \\
+ gend & masc\\
+ pred & \rm `pro' \]\\
+ pred & \rm `eat\q<SUBJ, OBJ\q>'\\
+ obj & \[ pers & 3 \\
+ num & pl \\
+ gend & fem \\
+ pred & \rm `pro' \]
+\]
+\end{avm}
+\end{verbatim}}
+\end{examples}
+The underlying environment is based on \TeX's \verb+\halign+ (which also
+underlies \LaTeX's \verb+tabular+ environment), and so the normal
+conventions of these apply. Note that spaces are ignored on both sides of
+an \verb+&+ or \verb+\\+, as in \LaTeX's \verb+tabular+ environment (but not
+in Plain \TeX's \verb+\halign+).
+
+\subsubsection{When you don't want to align columns}
+
+There are some occasions when you don't want things lined up in columns. For
+example, with a long HPSG path, we probably want the output to look as in
+\ex{1}[a] not \ex{1}[b].
+\begin{examples}
+\item
+\avmoptions{active}
+\begin{avm}
+[ synsem|local|content\;@2\\
+ qstore\;{ [ det & \rm forall \\
+ restpar & @2 [para & @1\\
+ restr & { [ reln & \rm book\\
+ inst & @1 ] } ] ] } ]
+\end{avm}\label{forall}
+
+\item
+\avmoptions{active}
+\begin{avm}
+[ synsem|local|content & @2\\
+ qstore & { [ det & \rm forall \\
+ restpar & @2 [para & @1\\
+ restr & { [ reln & \rm book\\
+ inst & @1 ] } ] ] } ]
+\end{avm}
+\end{examples}
+%
+There are several ways to achieve this, which will be presented in order
+from the quick and dirty fix to the best solution. One way is just to not
+use \verb+&+s. That way everything will be in one column:
+\begin{examples}
+\item
+\begin{avm}
+\[ short \rm value$_1$ \\
+ extremely-loooooooooong \rm value$_2$ \]
+\end{avm}
+
+\item
+\begin{verbatim}
+\begin{avm}
+\[ short \rm value$_1$ \\
+ extremely-loooooooooong \rm value$_2$ \]
+\end{avm}
+\end{verbatim}
+\end{examples}
+%
+However, the discerning eye will notice that there is then only a normal
+space width between attributes and values, and that looks bad.
+But \av\ defines a command \verb+\;+ analogous to the `thick space' in math
+mode that will put in the normal spacing between attributes and values. So
+the above example can be improved by typing it as follows.
+\begin{examples}
+\item
+\begin{avm}
+\[ short\; \rm value$_1$ \\
+ extremely-loooooooooong\; \rm value$_3$ \]
+\end{avm}
+
+\item
+\begin{verbatim}
+\begin{avm}
+\[ short\; \rm value$_1$ \\
+ extremely-loooooooooong\; \rm value$_3$ \]
+\end{avm}
+\end{verbatim}
+\end{examples}
+%
+However, to make elegant {\AVM}s it is often the case that you want most
+columns to be lined up, and in this case, you should use \verb+&+ in most
+columns as usual, but make the entire exceptional rows an argument of the
+command \verb+\avmspan+ as shown below:
+\begin{examples}
+\item
+\begin{avm}
+\[ content & \[ reln & \bf cause \\
+ causer & \@1 \\
+ causee & \@2 \\
+ \avmspan{caused-event\|reln\;\@3} \] \]
+\end{avm}
+\item
+{\obeyspaces\begin{verbatim}
+\begin{avm}
+\[ content & \[ reln & \bf cause \\
+ causer & \@1 \\
+ causee & \@2 \\
+ \avmspan{caused-event\|reln\;\@3} \] \]
+\end{avm}
+\end{verbatim}}
+\end{examples}
+
+\subsection{Other types of brackets and braces}
+
+\av\ also provides other types of large extendable braces and brackets.
+One uses \verb+\{+ and \verb+\}+ for curly braces, \verb+\(+ and \verb+\)+
+for round parentheses, \verb+\<+ and \verb+\>+ for angle brackets and
+\verb+\avml+ and \verb+\avmr+ for no brackets at all. Note that angle
+brackets have a maximum size, though, and are not infinitely stretchable
+like the other types of brackets. As is usual in
+\TeX, an opening bracket must be matched by a closing bracket, but the two
+need not be of the same sort. All these commands provide exactly the same
+internal
+environment as was described above for square brackets (e.g., use of
+\verb+&+ and \verb+\\+), although, in general, these fancier options are
+less used with these types of braces. Some examples follow (note the
+`misuse' of a 3 column {\AVM} in \ex{1}[c]):
+\begin{examples}
+\item
+\begin{avm}
+\[ qstore & \{ \[ det & \rm the \\
+ restpar & \[ para & \@1 \\
+ restr & \{ \[ reln & \rm poss \\
+ possessor & \@3 \\
+ possessed & \@1\]\}\ \bf union \q\{\@2\q\}
+\] \] \} \]
+\end{avm}
+
+\item
+{\obeyspaces\begin{verbatim}
+\begin{avm}
+\[qstore & \{ \[det & \rm the \\
+ restpar & \[para & \@1 \\
+ restr & \{ \[reln & \rm poss \\
+ possessor & \@3 \\
+ possessed & \@1\]\}\ \bf union \q\{\@2\q\}
+\] \] \} \]
+\end{avm}
+\end{verbatim}}
+
+\item
+{\avmfont{}\avmvalfont{}
+\footnotesize\sc
+\begin{avm}
+\avml
+\avml \rm kak\\
+\[subcat \< \[pos&n\\case&nm\\ind&\@1\], \[pos&n\\case&ac\\ind&\@2\] \>\]
+\avmr
+& $\Longrightarrow$ &
+\avml \rm kak-ase\\
+\[subcat \< \[pos&n\\case&nm\\ind&\@3\], \[pos&n\\case&dt\\ind&\@1\],
+ \[pos&n\\case&ac\\ind&\@2\] \>\]
+\avmr \avmr
+\end{avm}
+}
+
+\item
+{\obeyspaces\begin{verbatim}
+\begin{avm}
+\avml
+\avml \rm kak\\
+\[subcat \< \[pos&n\\case&nm\\ind&\@1\], \[pos&n\\case&ac\\ind&\@2\] \>\]
+\avmr
+& $\Longrightarrow$ &
+\avml \rm kak-ase\\
+\[subcat \< \[pos&n\\case&nm\\ind&\@3\], \[pos&n\\case&dt\\ind&\@1\],
+ \[pos&n\\case&ac\\ind&\@2\] \>\]
+\avmr \avmr
+\end{avm}
+\end{verbatim}}
+
+\item
+\begin{avm}
+\{ \[ pred & \rm `see\q<girl, Mary\q>' \\
+ subj & \rm `girl' \\
+ obj & \rm `Mary' \] \\
+ \[ pred & \rm `heard\q<girl, Bill\q>' \\
+ subj & \rm `girl' \\
+ obj & \rm `Bill' \] \}
+\end{avm}
+
+\item
+{\obeyspaces\begin{verbatim}
+\begin{avm}
+\{ \[ pred & \rm `see\q<girl, Mary\q>' \\
+ subj & \rm `girl' \\
+ obj & \rm `Mary' \] \\
+ \[ pred & \rm `heard\q<girl, Bill\q>' \\
+ subj & \rm `girl' \\
+ obj & \rm `Bill' \] \}
+\end{avm}
+\end{verbatim}}
+
+\end{examples}
+
+For normal text size brackets, \verb+[+, \verb+]+, \verb+(+ and \verb+)+
+work in the usual way. Curly braces and angle brackets can be made
+using the \verb+\q+ (`quote' command), by writing \verb+\q\{+, \verb+\q\}+,
+\verb+\q<+ and \verb+\q>+, as in \ex{0}[b,f]. Or they can
+be made by going into math mode in the usual way.
+
+\subsection{Other features}
+
+\subsubsection{Sort labels}
+
+The commands \verb+\sort+ and \verb+\osort+ put sort labels at the
+corner of any structure. They differ in that the label of
+\verb+\sort+ takes up space in the column or text where it appears whereas
+\verb+\osort+ overlaps its label into the previous column or text.
+\verb+\osort+ does not check for collisions so you have to use your
+judgment. For example, (1) was typeset with these commands:
+%
+\begin{example}\label{firstverbatim}
+{\obeyspaces\begin{verbatim}
+\begin{avm}
+\sort{indexed-obj}{\[ index & \osort{index}{\[
+ variable & \@1 \osort{variable}{\[ per & \rm 3rd \\
+ num & \rm sing \\
+ gend & \rm neut \]} \\
+ restriction & \osort{psoa}{\[relation & \rm book \\
+ instance & \@1 \]} \]} \]}
+\end{avm}
+\end{verbatim}}
+\end{example}
+%
+If one wants (almost) all square-bracketed feature structures sorted,
+it is more convenient to use the sub-mode \verb+sorted+ (see
+Section~\ref{sorted-sec}). See also Section~\ref{corners} for how to vary
+the sort label position.
+
+\subsubsection{Bars, index boxes, nodes and lines}
+
+The command \verb+\|+ will produce a vertical bar with a
+little space on either side. The command \verb+\@{...}+ will produce a
+labeled index box, as used in PATR and HPSG. If the index is a single
+digit, the braces may be omitted. The \verb+\@+ command only works within
+the {\AVM} environment, but since you often want to refer to index boxes in
+the text of your paper, the additional command \verb+\avmbox{...}+ can be
+used anywhere to draw an index box.
+
+For curved lines connecting {\AVM}s (as widely used in LFG), Emma Pease's
+{\sf tree-dvips.sty} can be used as normal, but \av\ also adds the
+shortcut whereby \verb+\!+ can be used instead of \verb+\node+.
+One often wants these curved lines to connect to a dash or an empty
+feature structure. So \av\ provides the one-parameter commands
+\verb+\avmd+ and \verb+\avmb+ (for dash and box, respectively), that draw
+such an object and
+label it with their parameter. These are illustrated below:
+%
+\begin{examples}
+\item
+\nodemargin=0pt
+\begin{avm}
+\[ subj & \!{a}{\[ pred & \rm `pro'\\
+ num & sg \\
+ pers & 1 \]} \\
+ pred & \rm `want\q<\avmd{aa}, \avmd{bb}\ \q>' \\
+ xcomp & \!{b}{\[ pred & \rm `go\q<\avmd{aaaa}\q>' \\
+ subj & \avmb{aaa} \]} \]
+\end{avm}
+\nodecurve[r]{a}[t]{aa}{.3in}[.2in] % was .4
+\nodecurve[b]{aa}[t]{aaaa}{.2in}
+\nodecurve[r]{aaa}[b]{aaaa}{.25in} % was .15
+\nodecurve[r]{bb}[r]{b}{.5in}[.5in]
+
+\item
+{\obeyspaces\begin{verbatim}
+\begin{avm}
+\[ subj & \!{a}{\[ pred & \rm `pro'\\
+ num & sg \\
+ pers & 1 \]} \\
+ pred & \rm `want\q<\avmd{aa}, \avmd{bb}\ \q>' \\
+ xcomp & \!{b}{\[ pred & \rm `go\q<\avmd{aaaa}\q>' \\
+ subj & \avmb{aaa} \]} \]
+\end{avm}
+\nodecurve[r]{a}[t]{aa}{.4in}
+\nodecurve[b]{aa}[t]{aaaa}{.2in}
+\nodecurve[r]{aaa}[b]{aaaa}{.15in}
+\nodecurve[r]{bb}[r]{b}{.5in}[.5in]
+\end{verbatim}}
+\end{examples}
+%
+If one wants (almost) all square-bracketed feature structures labeled,
+it is more convenient to use the sub-mode \verb+labeled+ (see
+Section~\ref{sorted-sec}).
+
+\section{Fonts}
+By default, \av\ puts {\AVM}s in the type size and style that is currently
+being used. This allows one to easily type things like the following (in
+\LaTeX):
+
+\begin{examples}
+\item
+{\avmfont{}\footnotesize\sf \begin{avm}
+\[ content \[ reln & \bf cause \\
+ causer & \@1 \\
+ causee & \@2 \\
+ \avmspan{caused-event\|reln\;\@3} \] \]
+\end{avm}}
+\item
+{\obeyspaces\begin{verbatim}
+{\footnotesize\sf \begin{avm}
+\[ content \[ reln & \bf cause \\
+ causer & \@1 \\
+ causee & \@2 \\
+ \avmspan{caused-event\|reln\;\@3} \] \]
+\end{avm}}
+\end{verbatim}}
+\end{examples}
+%
+However, one often wants all {\AVM}s to be set in certain fonts and so \av\
+lets you specify default fonts for {\AVM}s. This is done with the following
+commands:
+%
+\begin{examples}
+\item \verb+\avmfont{...}+
+\item \verb+\avmvalfont{...}+
+\item \verb+\avmsortfont{...}+
+\end{examples}
+%
+This is how fonts work: (i)~index box contents are set in the
+\verb+\scriptstyle+ (smaller subscript size) of the current math font;
+(ii)~if \verb+\avmsortfont+ is defined, sort names for {\AVM}s are set in
+the \verb+\avmsortfont+; (iii)~if \verb+\avmvalfont+ is defined, value
+names (items in the second and subsequent columns of the {\AVM}
+environment) are set in the \verb+\avmvalfont+; (iv) everything not
+assigned a font so far is set in the \verb+\avmfont+, if this is
+defined, and in the current default font otherwise.
+
+Most of the examples in this
+document are set in small capitals using the following (\LaTeX) defaults:
+%
+\begin{example}
+\verb+\avmfont{\sc}+\\
+\verb+\avmsortfont{\scriptsize\it}+
+\end{example}
+%
+After setting up a default font, to reset things so that \av\ uses the
+current font, simply call the same commands with an empty argument, for
+example, \verb+\avmfont{}+.
+
+Note for Plain \TeX\ users: by default, neither the small capitals font nor
+the equivalent of \LaTeX's \verb+\scriptsize+ italic font is loaded.
+To get similar output in Plain \TeX, the minimum you must add somewhere
+near the beginning of your file is:
+\begin{example}
+\begin{verbatim}
+\font\tensc=cmcsc10
+\font\seveni=cmti7
+\avmfont{\tensc}
+\avmsortfont{\seveni}
+\end{verbatim}
+\end{example}
+%
+However, more setup would be required to fully integrate these fonts into
+Plain \TeX\ or to get things to work with different font sizes or scalings.
+
+The font of any individual item can be changed in the usual way with a font
+changing command, as shown in \exref{firstverbatim}.
+Note that in any of the bracketed structures, font
+changes are always only local (having scope until the next \verb+&+ or
+\verb+\\+), so it is generally not necessary to use braces to delimit
+font changes.
+
+\section{User-specified options}
+
+\av\ has various (well, eight) options that you can specify. Three of these
+activate sub-modes which alter how you input {\AVM}s, while the others
+alter the way {\AVM}s appear in the output. You
+activate these options by using the \verb+\avmoptions+ command. This
+command takes a comma-separated list of options to be turned on and all the
+other options are turned off. So, three options are turned on
+with \ex{1}[a] and all are turned off (returning things to the default
+mode) with the command \ex{1}[b]. Just \verb+labeled+ can be
+selected with command \ex{1}[c]. Note that the parameter to an
+\verb+\avmoptions+ command must not contain any spaces! The options
+are \verb+active+; \verb+sorted+, \verb+labeled+; \verb+center+ and
+\verb+bottom+; \verb+topleft+, \verb+topright+, and \verb+bottomright+.
+Options within each semicolon-separated set are mutually exclusive, but
+otherwise the options can be freely combined.
+%
+\begin{examples}
+\item \verb+\avmoptions{active,sorted,bottom}+
+\item \verb+\avmoptions{}+
+\item \verb+\avmoptions{labeled}+
+\end{examples}
+%
+Setting these options is local to a group and so the domain of effect can
+be delimited with braces. Also, since all \LaTeX\ environments (things
+enclosed in \verb+\begin+ \ldots\ \verb+\end+ pairs) define their
+own group, including an options command within such a \verb+\begin+ \ldots\
+\verb+\end+ pair will affect only the processing of the rest of that
+environment.
+
+\subsection{Sort labels in different corners: {\tt topleft},
+ {\tt topright}, and {\tt bottomright}}\label{corners}
+
+While {\small HPSG} normally places sort labels in the bottom left corner
+of {\AVM}s, with {\av} you can actually have sort labels in any corner that
+you wish. You select different corners for the \verb+\sort+ and
+\verb+\osort+ commands and the \verb+sorted+ option with the options {\tt
+topleft}, {\tt topright}, and {\tt bottomright}. This is illustrated in
+the next section.
+
+\subsection{The {\tt sorted} and {\tt labeled} sub-modes}\label{sorted-sec}
+
+These modes both affect just the behavior of the square brackets commands
+(in either the default mode or the \verb+active+ sub-mode) and are
+mutually exclusive. Left square-bracket commands take one argument, which
+is the sort or node label name for this {\AVM}. The \verb+labeled+ mode
+gives the same results as using \verb+\!+ (i.e., \verb+\node+), but
+lessens the typing required:
+%
+\begin{examples}
+\item
+\nodemargin=0pt
+\avmoptions{labeled}
+\begin{avm}
+\[{a} subj & \[{b} num & pl \] \\
+ tense & pres \\
+ pred & \rm `bark\q<\avmd{c}\q>' \]
+\end{avm}
+\nodecurve[br]{b}[t]{c}{15pt}
+
+\item
+{\obeyspaces\begin{verbatim}
+\avmoptions{labeled}
+\begin{avm}
+\[{a} subj & \[{b} num & pl \] \\
+ tense & pres \\
+ pred & \rm `bark\q<\avmd{c}\q>' \]
+\end{avm}
+\nodecurve[br]{b}[t]{c}{15pt}
+\end{verbatim}}
+\end{examples}
+
+The \verb+sorted+ sub-mode gives a combination of the effects of the
+\verb+\sort+ and \verb+\osort+ commands (trying to give you what you
+probably want).
+If the corner sub-mode is {\tt topright} or {\tt bottomright} then it
+always behaves as \verb+\sort+. If the sub-mode is {\tt topleft}, or the
+default which puts labels in the bottom left, then it behaves like
+\verb+\osort+, except at the outermost level of the {\AVM}, where it
+behaves like \verb+\sort+.\footnote
+ {This is so the outermost sort label will not overlap the text
+ preceding it, whereas if
+ you use the {\tt\char'134 osort} command, no extra space is added, even
+ at the
+ outermost level. This means that if you are building AVMs with sorts in
+ parts, you will want to use {\tt\char'134 osort} rather than the
+ {\tt sorted} sub-mode.}
+Example \ex{1} was produced by preceding \ex{2} by each of the commands in
+\ex{3} in turn.
+%
+\begin{example}
+\avmvalfont{\rm}
+\avmoptions{topleft,sorted}
+\begin{avm}
+\[{index} variable & \@1 \[{variable} per & 3rd \\
+ num & sing \\
+ gend & neut \] \\
+ restr & \[{psoa} relation & book \\
+ instance & \@1 \] \]
+\end{avm}
+\hfill
+\avmoptions{topright,sorted}
+\begin{avm}
+\[{index} variable & \@1 \[{variable} per & 3rd \\
+ num & sing \\
+ gend & neut \] \\
+ restr & \[{psoa} relation & book \\
+ instance & \@1 \] \]
+\end{avm}\\[2ex]
+\avmoptions{sorted}
+\begin{avm}
+\[{index} variable & \@1 \[{variable} per & 3rd \\
+ num & sing \\
+ gend & neut \] \\
+ restr & \[{psoa} relation & book \\
+ instance & \@1 \] \]
+\end{avm}
+\hfill
+\avmoptions{bottomright,sorted}
+\begin{avm}
+\[{index} variable & \@1 \[{variable} per & 3rd \\
+ num & sing \\
+ gend & neut \] \\
+ restr & \[{psoa} relation & book \\
+ instance & \@1 \] \]
+\end{avm}
+\end{example}
+
+\begin{example}
+{\obeyspaces\begin{verbatim}
+\begin{avm}
+\[{index} variable & \@1 \[{variable} per & 3rd \\
+ num & sing \\
+ gend & neut \] \\
+ restr & \[{psoa} relation & book \\
+ instance & \@1 \] \]
+\end{avm}
+\end{verbatim}}
+\end{example}
+
+\begin{examples}
+\item \verb+\avmvalfont{\rm}+\\
+ \verb+\avmoptions{topleft,sorted}+
+
+\item \verb+\avmoptions{topright,sorted}+
+\item \verb+\avmoptions{sorted}+
+\item \verb+\avmoptions{bottomright,sorted}+
+\end{examples}
+
+
+
+%\item
+%\nodemargin=0pt
+%\avmoptions{labeled}
+%\begin{avm}
+%\[{x} subj & \[{a} pred & \rm `pro'\\
+% num & sg \\
+% pers & 1 \] \\
+% pred & \rm `want\q<\[{aa}\;\], \[{bb}\;\]\ \q>' \\
+% xcomp & \[{b} pred & \rm `go\q<\[{aaaa}\;\]\q>' \\
+% subj & \[{aaa}\;\] \] \]
+%\end{avm}
+%\nodecurve[t]{aa}[r]{a}{.4in}
+%\nodecurve[b]{aa}[t]{aaaa}{.2in}
+%\nodecurve[r]{aaa}[b]{aaaa}{.15in}
+%\nodecurve[r]{bb}[r]{b}{.5in}[.5in]
+%\nodecurve[l]{x}[l]{b}{.3in}
+
+\subsection{The {\tt active} sub-mode}
+
+The {\AVM}s above looked okay, but it can get tiring typing all the
+backslashes. So an alternative environment in which bracket characters are
+`active' (i.e., they are commands) is also provided. Using it, one can
+type the {\AVM} in \exref{forall} as follows:
+
+\begin{example}
+{\obeyspaces\begin{verbatim}
+\avmoptions{active}
+\begin{avm}
+[ synsem|local|content\; @2 \\
+ qstore\; \{ [ det & \rm forall \\
+ restpar & @2 [para & @1\\
+ restr & \{ [ reln & \rm book\\
+ inst & @1 ] \} ] ] \} ]
+\end{avm}
+\end{verbatim}}
+\end{example}
+%
+%To be able to type {\AVM}s like this, you need to give the command
+%\verb+\avmoptions{active}+ before beginning the \verb+avm+
+%environment (with either \verb+\avm+ (\TeX) or \verb+\begin{avm}+ (\LaTeX)).
+
+The functionality of this environment is exactly the same as that of
+the default mode described above; all that differs is how various commands
+are called. The following table defines the correspondence between
+commands in the two versions:
+%
+\begin{example}
+\setbox1=\hbox{\begin{tabular}[t]{|l|l||l|l|}
+\hline
+Default & \verb+active+ mode & Default & \verb+active+ mode\\ \hline
+\verb+\[+ & \verb+[+ & \verb+\]+ & \verb+]+ \\
+\verb+\(+ & \verb+(+ & \verb+\)+ & \verb+)+ \\
+\verb+\<+ & \verb+<+ & \verb+\>+ & \verb+>+ \\
+\verb+\{+ & \verb+\{+ & \verb+\}+ & \verb+\}+ \\
+\verb+[+ & \verb+\[+ & \verb+]+ & \verb+\]+ \\
+\verb+(+ & \verb+\(+ & \verb+)+ & \verb+\)+ \\
+\verb+\q<+ & \verb+\<+ & \verb+\q>+ & \verb+\>+ \\
+\verb+\q\{+ & \verb+\q\{+ & \verb+\q\}+ & \verb+\q\{+ \\
+\verb+\@{...}+ & \verb+@{...}+ & \verb+\|+ & \verb+|+ \\ \hline
+\end{tabular}}
+\evnup[.75ex]{\box1}
+\end{example}
+%
+All other commands in the \verb+avm+ environment are unchanged when
+the \verb+active+ sub-mode is in effect. Note that curly braces
+still require a preceding backslash. This is so curly braces can retain
+their usual \TeX\ functions.
+
+Unfortunately, there is a major restriction on being able to use this
+environment. Because of
+the way \TeX\ works, such an environment cannot appear inside the argument
+of any command (such as \verb+\footnote+ or the \verb+\enumsentence+ macro
+of Emma Pease's {\sf lingmacros.sty}).\footnote
+ {This is because characters receive a permanent {\em catcode} when first
+ read as a macro argument. This is a fundamental feature of \TeX\ and
+ nothing to do with this package. Hence it isn't likely to change.}
+However, the \verb+active+ sub-mode can be used within \LaTeX\
+environments or between Plain \TeX\
+commands that serve as a preamble and postamble. For example, the author
+has an \verb+example+ environment that produces output similar to the
+\verb+\enumsentence+ macro, and using it and the \verb+active+ sub-mode, he
+could draw the structure in \ex{1} by using the commands in \ex{2}.
+\begin{example}\label{complex}
+\avmoptions{active}
+\begin{avm}
+[ qcontent & < [ det & \rm some \\
+ restpar & [ para & @3 \\
+ restr & \{ [ reln & \rm poem\\
+ inst & @3 ] \} ] ] > \\
+ dcontent & [ relation & \rm know \\
+ knower & @2 [ pers & 1 \\ num & sg ] ] ]
+\end{avm}
+\end{example}
+
+\begin{example}
+{\obeyspaces\begin{verbatim}
+\begin{example}
+\avmoptions{active}
+\begin{avm}
+[ qcontent & < [ det & \rm some \\
+ restpar & [ para & @3 \\
+ restr & \{ [ reln & \rm poem\\
+ inst & @3 ] \} ] ] > \\
+ dcontent & [ relation & \rm know \\
+ knower & @2 [ pers & 1 \\ num & sg ] ] ]
+\end{avm}
+\end{example}
+\end{verbatim}}
+\end{example}
+
+Here is one more example of the \verb+active+ sub-mode (in
+combination with the \verb+sorted+ sub-mode), included mainly to exercise
+the other commands in the sub-mode.
+%
+\begin{examples}
+\item
+\avmoptions{active,sorted}
+\begin{avm}
+[{test} testing & ( stuff & [{widget} attr$_1$ & \< value$_{@1}$ \> \\
+ attr$_2$ & \( value \) \\
+ attr$_3$ & \[ \q\{ value \q\} \] ] ) ]
+\end{avm}
+
+\item
+{\obeyspaces\begin{verbatim}
+\avmoptions{active,sorted}
+\begin{avm}
+[{test} testing & ( stuff & [{widget} attr$_1$ & \< value$_{@1}$ \> \\
+ attr$_2$ & \( value \) \\
+ attr$_3$ & \[ \q\{ value \q\} \] ] ) ]
+\end{avm}
+\end{verbatim}}
+\end{examples}
+
+\subsection{The {\tt center} and {\tt bottom} options}
+
+These parameters determine the positioning of the whole {\AVM}. Although
+an {\AVM}
+usually appears in a display environment, it is actually like one huge
+character as far as \TeX\ is concerned, and if you choose to put it near
+other characters, you might want any of the top, bottom or center of it
+aligned with those other characters. By default you get alignment along
+the top (usually what you want), but you can change this by specifying
+\verb+bottom+ or \verb+center+ to the \verb+\avmoptions+ command.
+Giving any \verb+\avmoptions+ command that does not specify \verb+center+
+or \verb+bottom+ will return you to using alignment along the top.
+All three possibilities are shown in the below:
+
+\begin{examples}
+\item
+Top \avmoptions{active}\begin{avm}
+[ case & acc \\ gend & fem \\ num & pl ]
+\end{avm},
+bottom \avmoptions{active,bottom}\begin{avm}
+[ case & acc \\ gend & fem \\ num & pl ]
+\end{avm}
+or center \avmoptions{active,center}\begin{avm}
+[ case & acc \\ gend & fem \\ num & pl ]
+\end{avm}.
+
+\item
+{\obeyspaces\begin{verbatim}
+Top \avmoptions{active}\begin{avm}
+[ case & acc \\ gend & fem \\ num & pl ]
+\end{avm},
+bottom \avmoptions{active,bottom}\begin{avm}
+[ case & acc \\ gend & fem \\ num & pl ]
+\end{avm}
+or center \avmoptions{active,center}\begin{avm}
+[ case & acc \\ gend & fem \\ num & pl ]
+\end{avm}.
+\end{verbatim}}
+\end{examples}
+Within the {\AVM} environment, bracketed structures are always aligned
+along their centers. But you can get different alignments by nesting
+{\AVM} environments (as opposed to nesting brackets within a single {\AVM} environment).
+
+\section{Advanced topics}
+
+\subsection{Layout parameters}
+
+Three parameters control the spacing in {\AVM}s. \verb+\avmvskip+ determines
+the extra vertical space added at the beginning, end and between every row
+of an aligned structure. \verb+\avmhskip+ determines the spacing between
+two columns of an aligned structure. At the left and right borders of an
+aligned structure (between the bracket and the first or last column) the
+spacing is \verb+\avmbskip+.
+The default values of these parameters (determined by eyeballing) are:
+%
+\begin{examples}
+\item \verb+\avmvskip{+{\tt \avmjvskip}\verb+}+
+\item \verb+\avmhskip{+{\tt \avmjhskip}\verb+}+
+\item \verb+\avmbskip{+{\tt \avmjbskip}\verb+}+
+\end{examples}
+%
+These defaults are defined in terms of the font-dependent units \verb+em+
+and \verb+ex+ so that they vary with the font size, but these parameters
+can be defined as any
+$\langle${\em dimen}$\rangle$. For more compressed {\AVM}s (such as those
+embedded in phrase-structure trees), the author tends to issue the
+following commands:
+%
+\begin{example}
+\verb+\avmvskip{.1ex}\avmhskip{.5em}+
+\end{example}
+
+
+\subsection{Using boxes to build huge AVMs}
+
+Note that \TeX\ has only a finite capacity for nesting, and if a
+structure is too complicated \TeX\ may be unable to set it. The vertical
+length of an {\AVM} is fairly unimportant; the critical parameter is the
+horizontal depth of nesting of stretchable brackets. On the \TeX\ I am
+using, one can embed
+stretchable brackets to about the level shown in \exref{complex} (when
+already within a
+\LaTeX\ list environment). To set a
+more complex {\AVM} than this, you unfortunately have to set pieces
+separately, store them in box registers and then set the whole {\AVM} (or
+else find a \TeX\ with a larger {\em semantic nest size\/}). An example of
+how to do this is shown below. Not the use of the {\tt center}
+sub-mode.\footnote
+ {Note also that \TeX\ box manipulation commands are shown. These work
+ perfectly well under \LaTeX\ as well, but if you want to find out about the
+ official \LaTeX\ box manipulation commands, see pp.~96--101 of the \LaTeX\
+ book.}
+%
+\begin{examples}
+\item
+\newbox\mybox \newbox\myboxtoo \avmoptions{center}
+
+\setbox\mybox=\hbox{\begin{avm}
+ \osort{ppro}{\[index & \osort{index}{\[ per & \it 3rd\\
+ num & \it sing\\
+ gend & \it fem \]} \]}
+ \end{avm}}
+\setbox\myboxtoo=\hbox{\begin{avm}
+ \sort{soa}{\[reln & \it female \\
+ inst & \@1 \]}
+\end{avm}}
+
+\avmoptions{active,sorted}
+\begin{avm}
+[{sign} phonology\;\<\rm she\> \\
+ synsem\;[{synsem} local & [{local} category & [{cat} head &
+ \it noun{\sc \[case\;{\it nom}\]}\\
+ subcat & \< \> ] \\
+content & [{ref-obj} para & @1 \box\mybox \\
+ restr & \q\{ \q\}] \\
+context & [{context} backgr & \{ \box\myboxtoo \} ]]]]
+\end{avm}
+
+\item
+{\obeyspaces\begin{verbatim}
+\newbox\mybox \newbox\myboxtoo \avmoptions{center}
+
+\setbox\mybox=\hbox{\begin{avm}
+ \osort{ppro}{\[index & \osort{index}{\[ per & \it 3rd\\
+ num & \it sing\\
+ gend & \it fem \]} \]}
+ \end{avm}}
+\setbox\myboxtoo=\hbox{\begin{avm}
+ \sort{soa}{\[reln & \it female \\
+ inst & \@1 \]}
+ \end{avm}}
+
+\avmoptions{active,sorted}
+\begin{avm}
+[{sign} phonology\;\<\rm she\> \\
+ synsem\;[{synsem} local & [{local} category & [{cat} head &
+ \it noun{\sc \[case\;{\it nom}\]}\\
+ subcat & \< \> ] \\
+content & [{ref-obj} para & @1 \box\mybox \\
+ restr & \q\{ \q\}] \\
+context & [{context} backgr & \{ \box\myboxtoo \} ]]]]
+\end{avm}
+\end{verbatim}}
+\end{examples}
+%
+It would be nice if \av\ could be made more economical in its use of this
+\TeX\ resource, but I don't know how to do that without compromising
+the functionality or the user interface of \av.
+
+\subsection{Known problems}
+
+All known bugs were fixed for the Version 1.00 release. Please send bug
+reports and ideas for improvements to the email address given at the
+beginning of this document.
+
+
+\end{document}
+
+Finally, note that \verb+avm+ environments can be nested while
+\verb+specialavm+ cannot, though it is unclear to me why anyone would want
+to nest these environments anyway.
+\begin{examples}
+
+
+\item \begin{avm} \osort{x}{\[ \]} \end{avm}A AA A[
+
+\item \newbox\testing
+\setbox\testing=\hbox{\begin{avm} \osort{x}{\[ A \]} \end{avm}}
+\leavevmode\box\testing A
+
+\item \begin{avm}
+\[ a & b \\[3ex]
+c & d \\[6ex]
+e & f \\
+g & h \]
+\end{avm}
+
+\item \begin{avm}
+\< \begin{avm} \[ case & nom\\ gend & fem \] \end{avm},
+\begin{avm} \[ case & abl\\ gend & fem \] \end{avm} \>
+\end{avm}
+
+\item
+{\obeyspaces\begin{verbatim}
+\begin{avm}
+\< \begin{avm} \[ case & nom\\ gend & fem \] \end{avm},
+\begin{avm} \[ case & abl\\ gend & fem \] \end{avm} \>
+\end{avm}
+\end{verbatim}}
+\end{examples}
+
+\begin{examples}
+\avmoptions{active}
+\item \begin{avm}
+< \begin{avm} [ case & nom\\ gend & fem ] \end{avm},
+\begin{avm} [ case & abl\\ gend & fem ] \end{avm} >
+\end{avm}
+
+\item
+{\obeyspaces\begin{verbatim}
+\begin{avm}
+\< \begin{avm} \[ case & nom\\ gend & fem \] \end{avm},
+\begin{avm} \[ case & abl\\ gend & fem \] \end{avm} \>
+\end{avm}
+\end{verbatim}}
+\end{examples}
+
+
+
+\begin{examples}
+\item
+\avmoptions{topleft}
+\begin{avm}
+\sort{indexed-obj}{\[ index & \osort{index}{\[
+ variable & \@1 \osort{variable}{\[ per & \rm 3rd \\
+ num & \rm sing \\
+ gend & \rm neut \]} \\
+ restriction & \osort{psoa}{\[relation & \rm book \\
+ instance & \@1 \]} \]} \]}
+\end{avm}
+
+\item
+\avmoptions{topright}
+\begin{avm}
+\sort{indexed-obj}{\[ index & \osort{index}{\[
+ variable & \@1 \osort{variable}{\[ per & \rm 3rd \\
+ num & \rm sing \\
+ gend & \rm neut \]} \\
+ restriction & \osort{psoa}{\[relation & \rm book \\
+ instance & \@1 \]} \]} \]}
+\end{avm}
+
+\item
+\avmoptions{bottomright}
+\begin{avm}
+\sort{indexed-obj}{\[ index & \osort{index}{\[
+ variable & \@1 \osort{variable}{\[ per & \rm 3rd \\
+ num & \rm sing \\
+ gend & \rm neut \]} \\
+ restriction & \osort{psoa}{\[relation & \rm book \\
+ instance & \@1 \]} \]} \]}
+\end{avm}
+
+\item
+\avmoptions{}
+\begin{avm}
+\sort{indexed-obj}{\[ index & \osort{index}{\[
+ variable & \@1 \osort{variable}{\[ per & \rm 3rd \\
+ num & \rm sing \\
+ gend & \rm neut \]} \\
+ restriction & \osort{psoa}{\[relation & \rm book \\
+ instance & \@1 \]} \]} \]}
+\end{avm}
+
+\item \avmvalfont{\it}
+\begin{avm}
+\[ phonology & \rm \q<who\q>\\
+synsem\|local & \[ category & \[ head & noun\\
+ subcat & \q<\q> \] \\
+ content\|parameter & \@1 npro\\
+ context\|background & \{ \[ relation & human\\
+ instance & \@1 \] \} \] \]
+\end{avm}
+
+\item {\obeyspaces
+\begin{verbatim}
+\begin{avm}
+\[ phonology & \rm \q<who\q>\\
+synsem\|local & \[ category & \[ head & \it noun\\
+ subcat & \q<\q> \] \\
+ content\|parameter & \@1 \it npro\\
+ context\|background & \{ \[ relation & \it human\\
+ instance & \@1 \] \} \] \]
+\end{avm}
+\end{verbatim}}
+
+\item
+\avmoptions{sorted}
+\begin{avm}
+\[{boris} ind & \[{wilbur} num & sg \\ gend & fem \] \]
+\end{avm}
+
+\item
+{\obeyspaces\begin{verbatim}
+\avmoptions{sorted}
+\begin{avm}
+\[{boris} ind & \[{wilbur} num & sg \\ gend & fem \] \]
+\end{avm}
+\end{verbatim}}
+
+\item
+\begin{avm}
+\avml subcat & \< \[pos & n\\case & acc\],
+ \[pos & v\\vform & inf\] \> \avmr
+\end{avm}
+
+\item
+{\obeyspaces\begin{verbatim}
+\begin{avm}
+\lavm subcat & \< \[pos & n\\case & acc\],
+ \[pos & v\\vform & inf\] \> \ravm
+\end{avm}
+\end{verbatim}}
+
+\end{examples}
+
+Describe avmbox, sorts on different corners, new options to end of line
+command. Anything else?
+
+
+
+\end{document}
+
+
+provides severaltwo environments: one where all commands are still preceded with
+the backslash character `$\backslash$', and another where the various
+bracket characters are defined as active characters (commands). However,
+using the latter imposes certain restrictions and so it will only be
+described later.\footnote
+ {The user interface of the `active' environment of \av\ is derived from
+ the style file {\sf
+ hpsg.sty} by Harry Bratt. However, not only does this package work with
+ both \TeX\ and \LaTeX, but it corrects various failings of the
+ latter: text in {\AVM}s is set in horizontal (LR) mode, not math mode;
+ \av\ properly restores the parameters and definitions it fiddles with
+ (so you can load \av\ anywhere among your list of
+ document-style options!) and the availability of the `standard' environment
+ allows feature structures to appear within the arguments of other
+ commands.}
+
+
+\item \avmoptions{center}
+\setbox7=\hbox{\begin{avm}
+\osort{ppro}{\[index & \osort{index}{\[ per & \it 3rd\\
+num & \it sing\\
+gend & \it fem \]} \]}
+\end{avm}}
+
+{\avmoptions{active,sorted}
+\begin{avm}
+\sort{sign}{[{} phonology & \<\rm she\> \\
+ synsem|local & [{local} category & [{cat} head &
+ \it noun{\sc \[ case\;{\it nom}\]}\\
+ subcat & \< \> ] \\
+content & [{ref-obj} para & \box7 ]]]}
+\end{avm}}
+
+
+\item \begin{avm}
+\[ pers & mum \\
+ ind & \[ ind2 & \[ ind3 & \[ ind4 & \[ nose & ear\\
+ ear & wig \] \] \] \]\\
+ case & acc \]
+\end{avm}
+%\item \begin{avm}
+%\[ attr & \begin{avm} \[ a1 & v1\\ a2 & v2\]\\
+% attr2 & val \]
+%
+%{\avmoptions{active}
+%\item \begin{avm}
+%[ attr & \begin{avm} [ a1 & v1\\ a2 & v2]\\
+% attr2 & val ]
+%}
+%\item
+%\begin{avm}
+%\[ pers & 3\\
+% num & sg\]
+%\end{avm}
+%\begin{avm}
+%\[ pers & 3\\
+% num & sg \\ \]
+%\end{avm}
+
+%
+%\item
+%\begin{avm}
+%\[{content}qcontent & \< \[{} det & \rm some \\
+% restpar & \[{}para & \@3 \\
+% restr & \{ \[{}reln & \rm poem\\
+% inst & @3 \] \} \] \] \> \\
+% dcontent & \[{} relation & \rm know \\
+% knower & \@2 \[{} pers & 1 \\ num & sg \] \] \]
+%\end{avm}
+
+\begin{examples}
+\item
+\avmoptions{topleft}
+\begin{avm}
+\sort{indexed-obj}{\[ index & \osort{index}{\[
+ variable & \@1 \osort{variable}{\[ per & \rm 3rd \\
+ num & \rm sing \\
+ gend & \rm neut \]} \\
+ restriction & \osort{psoa}{\[relation & \rm book \\
+ instance & \@1 \]} \]} \]}
+\end{avm}
+
+\item
+\avmoptions{topright}
+\begin{avm}
+\sort{indexed-obj}{\[ index & \osort{index}{\[
+ variable & \@1 \osort{variable}{\[ per & \rm 3rd \\
+ num & \rm sing \\
+ gend & \rm neut \]} \\
+ restriction & \osort{psoa}{\[relation & \rm book \\
+ instance & \@1 \]} \]} \]}
+\end{avm}
+
+\item
+\avmoptions{}
+\begin{avm}
+\sort{indexed-obj}{\[ index & \osort{index}{\[
+ variable & \@1 \osort{variable}{\[ per & \rm 3rd \\
+ num & \rm sing \\
+ gend & \rm neut \]} \\
+ restriction & \osort{psoa}{\[relation & \rm book \\
+ instance & \@1 \]} \]} \]}
+\end{avm}
+
+\item
+\avmoptions{bottomright}
+\begin{avm}
+\sort{indexed-obj}{\[ index & \osort{index}{\[
+ variable & \@1 \osort{variable}{\[ per & \rm 3rd \\
+ num & \rm sing \\
+ gend & \rm neut \]} \\
+ restriction & \osort{psoa}{\[relation & \rm book \\
+ instance & \@1 \]} \]} \]}
+\end{avm}
+\end{examples}
+
diff --git a/macros/latex209/contrib/trees/tree-dvips/avm.sty b/macros/latex209/contrib/trees/tree-dvips/avm.sty
new file mode 100644
index 0000000000..1b38c8160e
--- /dev/null
+++ b/macros/latex209/contrib/trees/tree-dvips/avm.sty
@@ -0,0 +1,158 @@
+% avm.sty -- for attribute-value matrices -- mar 29, 1992; rev. dec 6, 1993
+% (c) 1992 christopher manning (manning@csli.stanford.edu) -- see avm.doc.tex
+
+\newif\ifavmactive\newif\ifavmsorted\newif\ifavmlabeled
+\newif\ifavmcenter\newif\ifavmbottom
+\newif\ifavmbottomright\newif\ifavmtopleft\newif\ifavmtopright
+
+\newdimen\avmdimen
+\newbox\avmboxone\newbox\avmboxthree
+
+\def\avmoptions#1{\avmactivefalse\avmsortedfalse\avmlabeledfalse
+ \avmcenterfalse\avmbottomfalse
+ \avmbottomrightfalse\avmtopleftfalse\avmtoprightfalse
+ \def\more{#1}\ifx\more\empty\else\avmjoptions#1,\@nil\fi}
+\def\avmjoptions#1,#2\@nil{\def\more{#2}\csname avm#1true\endcsname
+ \ifx\more\empty\else\avmjoptions#2\@nil\fi}
+
+
+\def\avmfont#1{\def\avmjfont{#1}}
+\def\avmjfont{}
+
+\def\avmvalfont#1{\def\avmjvalfont{#1}}
+\def\avmjvalfont{}
+
+\def\avmsortfont#1{\def\avmjsortfont{#1}}
+\def\avmjsortfont{}
+
+\def\avmhskip#1{\def\avmjhskip{#1}}
+\def\avmjhskip{1em}
+
+\def\avmbskip#1{\def\avmjbskip{#1}}
+\def\avmjbskip{0em}
+
+\def\avmvskip#1{\def\avmjvskip{#1}}
+\def\avmjvskip{0.385ex}%was .3875
+
+
+\def\avmjprolog#1{$\mskip-\thinmuskip
+ \left#1\hskip\avmjbskip\vcenter\bgroup\vskip\avmjvskip
+ \ialign\bgroup\avmjfont
+ \strut ##\unskip\hfil
+ &&\hskip\avmjhskip\avmjvalfont ##\unskip\hfil\cr}
+\def\avmjpostlog#1{\crcr\egroup\vskip\avmjvskip\egroup
+ \hskip\avmjbskip\right#1\mskip-\thinmuskip$\ignorespaces}
+
+
+\def\avmjcatcode{\let\lparen=(\let\rparen=)\catcode`\[=13\catcode`\]=13
+ \catcode`\<=13\catcode`\@=13\catcode`\(=13\catcode`\)=13
+ \catcode`\>=13\catcode`\|=13}
+
+{\avmjcatcode % new group: redefine above catcodes as active
+
+\gdef\specialavm{\avmjcatcode
+\def({\avmjprolog\lparen}%
+\def){\avmjpostlog\rparen}%
+\def<{\avmjprolog\langle}%
+\def>{\avmjpostlog\rangle}%
+\ifavmsorted
+\def[##1{\setbox\avmboxthree=\hbox{\avmjsortfont##1\/}\setbox2=\hbox
+ \bgroup\avmjprolog\lbrack}%
+\def]{\avmjpostlog\rbrack\egroup\avmjsort}%
+\else\ifavmlabeled
+\def[##1{\def\more{##1}\setbox2=\hbox\bgroup\avmjprolog[}%
+\def]{\avmjpostlog]\egroup\node{\more}{\box2}}%
+\else
+\def[{\avmjprolog\lbrack}%
+\def]{\avmjpostlog\rbrack}%
+\fi\fi
+%
+\def\<{$\langle$}\def\>{$\rangle$}%
+\def\({\lparen}\def\){\rparen}%
+\def\[{\lbrack}\def\]{\rbrack}%
+\def|{$\,\vert\,$}%
+\def@##1{\avmbox{##1}}%
+} % end defn of \specialavm
+} % restore active catcodes
+
+
+\long\def\avm{\begingroup
+\ifavmactive\specialavm
+\else
+\def\({\avmjprolog(}%
+\def\){\avmjpostlog)}%
+\def\<{\avmjprolog\langle}%
+\def\>{\avmjpostlog\rangle}%
+%
+\ifavmsorted
+\def\[##1{\setbox\avmboxthree=\hbox{\avmjsortfont##1\/}\setbox
+ 2=\hbox\bgroup\avmjprolog[}%
+\def\]{\avmjpostlog]\egroup\avmjsort}%
+\else\ifavmlabeled
+\def\[##1{\def\more{##1}\setbox2=\hbox\bgroup\avmjprolog[}%
+\def\]{\avmjpostlog]\egroup\node{\more}{\box2}}%
+\else
+\def\[{\avmjprolog[}%
+\def\]{\avmjpostlog]}%
+\fi\fi
+%
+\def\|{$\,\vert\,$}%
+\def\@##1{\avmbox{##1}}%
+\fi % end not active
+%
+\ifx\LaTeX\undefined\def\\{\cr}% running under TeX
+\else \def\\{\@tabularcr}% Leverage off LaTeX's \\*[dimen] options
+\fi
+\def\!{\node}%
+\long\def\avmjsort{\dimen2=\ht2\advance\dimen2 by -.25\baselineskip
+ \global\dimen\avmdimen=\wd\avmboxthree
+ \ifavmtopleft \raise\dimen2\llap{\box\avmboxthree}\box2%
+ \else\ifavmtopright \box2\raise\dimen2\box\avmboxthree%
+ \else\ifavmbottomright \box2\lower\dimen2\box\avmboxthree%
+ \else \lower\dimen2\llap{\box\avmboxthree}\box2%
+ \fi\fi\fi}%
+\long\def\sort##1##2{\setbox2=\hbox{##2}\setbox
+ \avmboxthree=\hbox{\avmjsortfont##1\/}\dimen2=\ht2
+ \advance\dimen2 by -.25\baselineskip
+ \ifavmtopleft \raise\dimen2\box\avmboxthree\box2%
+ \else\ifavmtopright \box2\raise\dimen2\box\avmboxthree%
+ \else\ifavmbottomright \box2\lower\dimen2\box\avmboxthree%
+ \else \lower\dimen2\box\avmboxthree\box2%
+ \fi\fi\fi}%
+\long\def\osort##1##2{\setbox2=\hbox{##2}\setbox
+ \avmboxthree=\hbox{\avmjsortfont ##1\/}\avmjsort}%
+\def\avml{\avmjprolog.}%
+\def\avmr{\avmjpostlog.}%
+\def\avmb##1{\node{##1}{\lbrack\;\rbrack}}%
+\def\avmd##1{\node{##1}{---}}%
+\def\q##1{\ifx ##1\{$\lbrace$\else
+ \ifx ##1\}$\rbrace$\else
+ \ifx ##1<$\langle$\else
+ \ifx ##1>$\rangle$\fi \fi \fi \fi}%
+\def\{{\avmjprolog\lbrace}%
+\def\}{\avmjpostlog\rbrace}%
+\def\;{\hskip\avmjhskip}%
+\def\avmspan##1{\multispan2\strut ##1\expandafter\hfil}%
+\avmjfont
+\openup\avmjvskip
+\setbox\avmboxone=\hbox\bgroup\ignorespaces
+} % end defn of \avm
+
+
+\def\endavm{\egroup\ifvmode\leavevmode\fi % this if is useful!
+ \ifavmsorted\null\hskip\dimen\avmdimen\fi
+ \ifavmcenter
+ \box\avmboxone
+ \else \ifavmbottom
+ \lower.575\baselineskip\hbox{\vbox{\box\avmboxone\null}}%
+ \else
+% the next bit is ripped off from Emma's \evnup in lingmacros.sty
+ \dimen2=\ht\avmboxone\advance\dimen2 by -.725\baselineskip
+ \lower\dimen2\box\avmboxone
+\fi \fi \endgroup}
+
+
+% based on TeXbook exercise 21.3
+\def\avmbox#1{\setbox2=\hbox{$\scriptstyle #1$}\lower.2ex\vbox{\hrule
+ \hbox{\vrule\kern1.25pt
+ \vbox{\kern1.25pt\box2\kern1.25pt}\kern1.25pt\vrule}\hrule}}
diff --git a/macros/latex209/contrib/trees/tree-dvips/lingmacros-manual.pdf b/macros/latex209/contrib/trees/tree-dvips/lingmacros-manual.pdf
new file mode 100644
index 0000000000..3f77416afa
--- /dev/null
+++ b/macros/latex209/contrib/trees/tree-dvips/lingmacros-manual.pdf
Binary files differ
diff --git a/macros/latex209/contrib/trees/tree-dvips/lingmacros-manual.tex b/macros/latex209/contrib/trees/tree-dvips/lingmacros-manual.tex
new file mode 100644
index 0000000000..23b0c84d50
--- /dev/null
+++ b/macros/latex209/contrib/trees/tree-dvips/lingmacros-manual.tex
@@ -0,0 +1,124 @@
+\documentstyle[lingmacros]{article}
+
+\title{Linguistic Macros}
+\author{Emma Pease}
+\date{May 10,1995}
+
+\begin{document}
+
+\maketitle
+
+The lingmacros file contains a few macros that may be of use to
+linguists. The major commands are
+\begin{enumerate}
+\item The enumsentence macros for creating example sentences
+\begin{center}
+\begin{verbatim}
+\enumsentence[label]{sentence}
+\eenumsentence[label]{\item[label] sentence 1
+ \item[label] sentence 2}
+\end{verbatim}
+\end{center}
+ The enumsentence macros are similar to the math equation environment
+except that they take regular text. The \verb+\label+ command can be
+used inside of them.\footnote{The enumsentence macros use the counter,
+enums. For more information read the style file.} Inside of the
+eenumsentence either the \verb+\toplabel+ command for the sentence
+number only or the \verb+\label+ for sentence number and sublabel.
+Also defined is
+\verb+\ex{number}+ which gives a relative reference. \verb+(\ex{1})+
+or \verb+(\ref{senta})+ give the number of the next enumsentence (\ex{1})
+or (\ref{senta}); \verb+(\ex{2})+ or \verb+(\ref{sentb})+ of the second
+succeeding enumsentence (\ex{2}) or (\ref{sentb}).
+\verb+(\ref{sentbb})+ will give (\ref{sentbb}).
+ \enumsentence{This is the first sentence\label{senta}}
+\eenumsentence{\item this is a second sentence \toplabel{sentb}
+ \item this is a third sentence\label{sentbb}}
+\begin{center}
+\begin{verbatim}
+\enumsentence{This is the first sentence\label{senta}}
+\eenumsentence{\item this is a second sentence \toplabel{sentb}
+ \item this is a third sentence\label{sentbb}}
+\end{verbatim}
+\end{center}
+
+
+\item The tree macros
+\begin{center}
+\begin{verbatim}
+\smalltree{alignment structure}
+\modsmalltree{number of columns}{alignment structure}
+\end{verbatim}
+\end{center}
+\verb+\smalltree+ is based on the tabular environment with a large
+baselineskip. A simple example should suffice.
+\enumsentence{\smalltree{& &a\\
+ &b& &c\\
+ d& &e& &f}}
+\begin{center}
+\begin{verbatim}
+\enumsentence{\smalltree{& &a\\
+ &b& &c\\
+ d& &e& &f}}
+\end{verbatim}
+\end{center}
+\verb+\modsmalltree+ sometime works better.
+\enumsentence{\modsmalltree{5}{& &a\\
+ &b& \mc{3}{this is long}\\
+ d& &e& &f}}
+\begin{center}
+\begin{verbatim}
+\enumsentence{\modsmalltree{5}{& &a\\
+ &b& \mc{3}{this is long}\\
+ d& &e& &f}}
+\end{verbatim}
+\end{center}
+ Note the use of the \verb+\mc{number of columns}{text}+ to span
+several columns. The \verb+\clap{text}+ might also be useful; it is
+similar to the \verb+\rlap+ and \verb+\llap+ commands and produces a
+centered hbox of zero width. Lines need to be drawn in by hand or one
+can use the tree-dvips macros.
+
+\item The gloss macros
+\begin{center}
+\begin{verbatim}
+\shortex{number of columns}{first line}{second line}{gloss}
+\shortexnt{number of columns}{first line}{second line}
+\end{verbatim}
+\end{center}
+These can be combined to produce most of the glosses that linguists
+should need.
+\enumsentence{\shortex{6}{Was & ist & dem & Kind & geschenkt&worden?}
+ {What& is & the & child& given &been?}
+ {What has been given to the child?}
+ \item \shortexnt{7}
+{Das & Fin\'anzamt & hat & ihn & geschnappt &(und & nicht}
+{the &finance authority & has & him & caught &(and &not}
+
+\shortex{2}{die &Polizei).}
+ {the &police).}
+ {It was the IRS that caught him (and not the police).}}
+\begin{center}
+\begin{verbatim}
+\enumsentence{\shortex{6}{Was & ist & dem & Kind & geschenkt&worden?}
+ {What& is & the & child& given &been?}
+ {What has been given to the child?}}
+ \item \shortexnt{7}
+{Das & Fin\'anzamt & hat & ihn & geschnappt &(und & nicht}
+{the &finance authority & has & him & caught &(and &not}
+
+\shortex{2}{die &Polizei).}
+ {the &police)}
+ {It was the IRS that caught him (and not the police).}}
+\end{verbatim}
+\end{center}
+Unfortunately, I've not figured out a fullproof method of breaking
+the glosses automatically so they have to be done by hand.
+
+\item AVM structures: These exist within lingmacros but Chris
+Manning's AVM macro package is better.
+
+
+\end{enumerate}
+\end{document}
+
diff --git a/macros/latex209/contrib/trees/tree-dvips/lingmacros.sty b/macros/latex209/contrib/trees/tree-dvips/lingmacros.sty
new file mode 100644
index 0000000000..829effe52c
--- /dev/null
+++ b/macros/latex209/contrib/trees/tree-dvips/lingmacros.sty
@@ -0,0 +1,312 @@
+% Lingmacros
+% include
+% \enumsentence, \eenumsentence, \ex
+% \smalltree
+% \shortex, \shortexnt (\shortexdt no longer needed)
+% \clap, \ollap, \orlap, \oclap on analogy with \rlap and \llap
+% \outerfs
+
+% this file created 1/23/89 by Emma Pease, CSLI
+% modified 4/1/91 by Emma Pease
+% some comments added 8/25/94 by Emma Pease
+
+%Note (for those who use jbmacros):
+% (a) the enumsentence macro is very similar to the \example command
+% in jbmacros; however, it does not have the annoying habit of leaving
+% the example number on one page and the example on the next (some
+% jbmacros don't have this problem). The eenumsentence macro is very
+% similar to the \examples macro.
+% (b) \ex may be different
+
+% the enumsentence macro.
+%
+% \enumsentence{This is an example}
+% produces
+% (1) This is an example
+% while
+% \enumsentence[(a)]{This is another example}
+% produces
+% (a) This is another example
+%
+% A related macros is
+% \eenumsentence{\item[a.] A third example
+% \item[b.] A fourth example}
+% which produces
+% (2) a. A third example
+% b. A fourth example
+%
+% other macro is \ex{1} which produces the number of the following
+% enumsentence (\ex{0} produces number of preceeding enumsentence and
+% so on.)
+%
+% The standard \label command also works within \enumsentence and
+% \eenumsentence.
+%
+% the \enumsentence counter.
+\newcounter{enums}
+
+% Use the command
+%
+% \@addtoreset{enums}{chapter}
+%
+% if you wish it to automatically reset counting at the start of each chapter.
+% Since this is a \@ command you will need to surround it by
+% \makeatletter ... \makeatother
+% if it is in your document proper instead of a style file
+% do not use these commands if the \@addtoreset is in a style file or
+% things will break.
+
+
+% \widelabel is defined for use when the width of the enumsentence or
+% eenumsentence number is wider than 20pt (default labelwidth). As a
+% rule of thumb if your enumerated sentences are only 1 or 2 digit
+% you don't need to worry. At 3 digits, set \widelabel to 2.78pt at 4
+% digits set to 7.78pt.
+
+\newdimen\widelabel
+\widelabel=0pt
+
+
+\def\enumsentence{\@ifnextchar[{\@enumsentence}% %]
+{\refstepcounter{enums}\@enumsentence[(\theenums)]}}
+
+\long\def\@enumsentence[#1]#2{\begin{list}{}{%
+\advance\leftmargin by\widelabel \advance\labelwidth by \widelabel}
+\item[#1] #2
+\end{list}}
+
+% The \ex definition
+\newcounter{tempcnt}
+
+\newcommand{\ex}[1]{\setcounter{tempcnt}{\value{enums}}%
+\addtocounter{tempcnt}{#1}%
+\arabic{tempcnt}}
+
+% modified \@item command \unhbox\@tempboxa replaces \makelabel{#1}
+% Used to get \eenumsentence to work correctly
+\def\@item[#1]{\if@noparitem \@donoparitem
+ \else \if@inlabel \indent \par \fi
+ \ifhmode \unskip\unskip \par \fi
+ \if@newlist \if@nobreak \@nbitem \else
+ \addpenalty\@beginparpenalty
+ \addvspace\@topsep \addvspace{-\parskip}\fi
+ \else \addpenalty\@itempenalty \addvspace\itemsep
+ \fi
+ \global\@inlabeltrue
+\fi
+\everypar{\global\@minipagefalse\global\@newlistfalse
+ \if@inlabel\global\@inlabelfalse \hskip -\parindent \box\@labels
+ \penalty\z@ \fi
+ \everypar{}}\global\@nobreakfalse
+\if@noitemarg \@noitemargfalse \if@nmbrlist \refstepcounter{\@listctr}\fi \fi
+\setbox\@tempboxa\hbox{\makelabel{#1}}%
+\global\setbox\@labels
+ \hbox{\unhbox\@labels \hskip \itemindent
+ \hskip -\labelwidth \hskip -\labelsep
+ \ifdim \wd\@tempboxa >\labelwidth
+ \box\@tempboxa
+ \else \hbox to\labelwidth {\unhbox\@tempboxa}\fi
+ \hskip \labelsep}\ignorespaces}
+
+% for enumerated enumsentences. Internal enumeration is alpha if not
+% otherwise defined.
+
+% counter for items within \eenumsentence. (might use enumi instead?)
+\newcounter{enumsi}
+
+% \eenumsentence{\item[a.] A third \label{bar}example \toplabel{foo}
+% \item[b.] A fourth \label{baz}example}
+% Testing references \ref{foo}, \ref{bar}, and \ref{baz}.
+% which produces
+% (3) a. A third example
+% b. A fourth example
+% Testing references 3, 3a, and 3b.
+
+% To ensure that labels in \eenumsentence come out right.
+%
+\def\theenumsi{\theenums\alph{enumsi}}
+\newdimen\eeindent
+\eeindent=15pt
+% changes \leftmargin increased by \eeindent
+% \labelwidth increased by \eeindent
+% .. .. .leftmargin.. .. .. .. ..
+% oldlabelwidth eeindent labelsep actual entry
+% 20pt 15pt 5pt
+% (enumlabel) eelabel
+% eelabel
+
+\def\@mklab#1{\hfil#1}
+\def\enummklab#1{\hfil(\eelabel)\hbox to \eeindent{\hfil#1}}
+\def\enummakelabel#1{\enummklab{#1}\global\let\makelabel=\@mklab}
+\def\toplabel#1{{\edef\@currentlabel{\p@enums\theenums}\label{#1}}}
+
+\def\eenumsentence{\@ifnextchar[{\@eenumsentence}% %]
+{\refstepcounter{enums}\@eenumsentence[\theenums]}}
+
+\long\def\@eenumsentence[#1]#2{\def\eelabel{#1}\let\holdlabel\makelabel%
+\begin{list}{\alph{enumsi}.}{\usecounter{enumsi}%
+\advance\leftmargin by \eeindent \advance\leftmargin by \widelabel%
+\advance\labelwidth by \eeindent \advance\labelwidth by \widelabel%
+\let\makelabel=\enummakelabel}
+#2
+\end{list}\let\makelabel\holdlabel}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% smalltree
+% use
+% \smalltree{& &a\\
+% &b& &c\\
+% d& &e& &f}
+% produces
+% a
+% b c
+% d e f
+
+
+\long\def\smalltree#1{\leavevmode{\def\\{\cr\noalign{\vskip12pt}}%
+\def\mc##1##2{\multispan{##1}{\hfil##2\hfil}}%
+\tabskip=1em%
+\hbox{\vtop{\halign{&\hfil##\hfil\cr
+#1\crcr}}}}}
+
+% modsmalltree
+% use
+% \modsmalltree{3}{&&a\\ &b&&c\\ d&&e&&f}
+% and produces the same output
+% \mc{n}{item} within either will produce item centered across n
+% number of columns
+% \modsmalltree[arraystretch]{num of cols}{argument}
+%
+\def\modsmalltree{\@ifnextchar[{\@modsmalltree}{\@modsmalltree[2]}}
+
+\long\def\@modsmalltree[#1]#2#3{{\def\mc##1##2{%
+\multicolumn{##1}{c}{\def\arraystretch{1}##2}}%
+\def\arraystretch{#1}%
+\def\ns{\def\arraystretch{1}}%
+\setbox0=\hbox{\begin{tabular}[t]{@{}*{#2}{c}@{}}
+#3
+\end{tabular}}%
+\dimen0=\ht0
+\advance\dimen0 by -\arraystretch \ht\strutbox
+\advance\dimen0 by \ht\strutbox
+\ht0=\dimen0
+\dimen0=\dp0
+\advance\dimen0 by -\arraystretch \dp\strutbox
+\advance\dimen0 by \dp\strutbox
+\dp0=\dimen0
+\leavevmode\box0}}
+
+% center lap creates a box of 0 width centered on the point
+\def\clap#1{\hbox to 0pt{\hss#1\hss}}
+%The first argument in both of these commands is the distance above the
+%baseline desired. The second is what is the actual text.
+% over right lap
+\def\orlap#1#2{\vbox to0pt{\vss\hbox to 0pt{#2\hss}\hbox{\vrule height#1
+width0pt depth0pt}}}
+% over left lap
+\def\ollap#1#2{\vbox to0pt{\vss\hbox to 0pt{\hss#2}\hbox{\vrule height#1
+width0pt depth0pt}}}
+% over center lap
+\def\oclap#1#2{\vbox to0pt{\vss\hbox to 0pt{\hss#2\hss}\hbox{\vrule height#1
+width0pt depth0pt}}}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% need to be modified?
+
+% Format
+% \shortex{4}{a & b & c & d}
+% {z & y & x & w}
+% {mnop}
+% produces
+% a b c d
+% z y x w
+% mnop
+%
+% \shortexdt takes two gloss lines
+% \shortexnt takes no gloss lines
+
+\def\shortex#1#2#3#4{\begin{tabular}[t]{@{}*{#1}{l@{\ }}}
+#2\\ #3\\ \multicolumn{#1}{@{}l@{}}{\parbox{\linewidth}{#4}}
+\end{tabular}}
+
+%\def\shortexdt#1#2#3#4#5{\begin{tabular}[t]{@{}*{#1}{l@{\ }}}
+%#2\\ #3\\ \multicolumn{#1}{@{}l@{}}{#4}\\
+%\multicolumn{#1}{@{}l@{}}{#5}
+%\end{tabular}}
+
+\def\shortexnt#1#2#3{\begin{tabular}[t]{@{}*{#1}{l@{\ }}}
+#2\\ #3
+\end{tabular}}
+
+%%%%%%%%%
+% Long-example macros
+%
+% \longex{4}{2}
+% {a & b & c & d}{e & f}
+% {z & y & x & w}{v & u}
+% {mnopqrs}
+% produces
+% a b c d
+% z y x w
+% e f
+% v u
+% mnopqrs
+%
+% \longexdt takes two translation lines
+% \longexnt takes no translation lines
+% \longex can also handle multiple translations, as can \shortex above.
+
+\def\longex#1#2#3#4#5#6#7{\begin{tabular}[t]{@{}l}
+ \begin{tabular}[t]{@{}*{#1}{l@{\ \ }}}
+ #3\\ #5 \end{tabular}\vspace{.5ex}\\
+ \begin{tabular}[t]{@{}*{#2}{l@{\ \ }}}
+ #4\\ #6\\[.5ex] \multicolumn{#2}{@{}l@{}}{\begin{tabular}[t]{@{}l@{}}
+ #7 \end{tabular}} \end{tabular} \end{tabular}}
+
+\def\longexdt#1#2#3#4#5#6#7#8{\begin{tabular}[t]{@{}l}
+ \begin{tabular}[t]{@{}*{#1}{l@{\ \ }}}
+ #3\\ #5 \end{tabular}\vspace{.5ex}\\
+ \begin{tabular}[t]{@{}*{#2}{l@{\ \ }}}
+ #4\\ #6\\[.5ex] \multicolumn{#2}{@{}l@{}}{#7}\\
+ \multicolumn{#2}{@{}l@{}}{#8}
+ \end{tabular} \end{tabular}}
+
+\def\longexnt#1#2#3#4#5#6{\begin{tabular}[t]{@{}l}
+ \begin{tabular}[t]{@{}*{#1}{l@{\ \ }}}
+ #3\\ #5 \end{tabular}\vspace{.5ex}\\
+ \begin{tabular}[t]{@{}*{#2}{l@{\ \ }}}
+ #4\\ #6 \end{tabular} \end{tabular}}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% need to create equivalent of AVM structures.
+
+% Structure is
+% \outerfs{alpha & beta\\ gamma & delta}
+% produces
+% __ __
+% | alpha beta |
+% | gamma delta |
+% -- --
+%
+% \outerfs can be nested.
+% inside of enumsentence use with \evnup[2pt]{\outerfs{. . .}}
+% to ensure that top of fs structure lines up with the number
+%
+% Note that you can use \\[1ex] to increase the space between
+% individual lines
+
+\def\outerfs#1{$\left[\begin{tabular}{ll}#1\end{tabular}\right]$}
+
+% \evnup is used to line up the enumsentence number and an entry along
+% the top. It can take an argument to improve lining up.
+\def\evnup{\@ifnextchar[{\@evnup}{\@evnup[0pt]}}
+
+\def\@evnup[#1]#2{\setbox1=\hbox{#2}%
+\dimen1=\ht1 \advance\dimen1 by -.5\baselineskip%
+\advance\dimen1 by -#1%
+\leavevmode\lower\dimen1\box1}
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% End of main lingmacros
+%
diff --git a/macros/latex209/contrib/trees/tree-dvips/tree-dvips.sty b/macros/latex209/contrib/trees/tree-dvips/tree-dvips.sty
new file mode 100644
index 0000000000..31218352a8
--- /dev/null
+++ b/macros/latex209/contrib/trees/tree-dvips/tree-dvips.sty
@@ -0,0 +1,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}
+
+
diff --git a/macros/latex209/contrib/trees/tree-dvips/tree-dvips91.pro b/macros/latex209/contrib/trees/tree-dvips/tree-dvips91.pro
new file mode 100644
index 0000000000..3ecf33fbd9
--- /dev/null
+++ b/macros/latex209/contrib/trees/tree-dvips/tree-dvips91.pro
@@ -0,0 +1,110 @@
+%!
+TeXDict begin /@beginspec{gsave Resolution 72 div VResolution -72 div scale
+treedict begin}def /@endspec{end grestore}def /treedict 200 dict def treedict
+begin /pt{72 mul 72.07 div}def /nodemargin 2 def /nodes 100 dict def /node{
+/dpth exch def /hght exch def /wdth exch def 4 dict dup begin /x /y
+currentpoint dpth sub nodemargin sub exch 3 1 roll def nodemargin sub def /h
+hght dpth add nodemargin dup add add def /w wdth nodemargin dup add add def
+end nodes 3 1 roll put}def /nodebottom{begin x w 2 div add y end}def /nodetop{
+begin x w 2 div add y h add end}def /nodeleft{begin x y h 2 div add end}def
+/noderight{begin x w add y h 2 div add end}def /nodetopleft{begin x y h add
+end}def /nodetopright{begin x w add y h add end}def /nodebottomleft{begin x y
+end}def /nodebottomright{begin x w add y end}def /farright{begin x w add depth
+add h 2 div y add end}def /farleft{begin x depth sub h 2 div y add end}def
+/farbottom{begin x w 2 div add y depth sub end}def /fartop{begin x w 2 div add
+y h add depth add end}def /farbottomleft{begin x depth 45 cos mul sub y depth
+45 sin mul sub end}def /farbottomright{begin x w add depth 45 cos mul add y
+depth 45 sin mul sub end}def /fartopright{begin x w add depth 45 cos mul add y
+h add depth 45 sin mul add end}def /fartopleft{begin x depth 45 cos mul sub y
+h add depth 45 sin mul add end}def /alignpoint{2 copy sub abs 1 le{add 2 div
+round dup}if}def /getnode{nodes exch get}def /nodeconnect{gsave transform 4 2
+roll transform exch 4 1 roll alignpoint 4 2 roll alignpoint 4 1 roll exch
+itransform moveto itransform lineto stroke grestore}def /arrowdict 15 dict def
+arrowdict begin /mtrx matrix def end /arrow{arrowdict begin /insetlength exch
+def /headlength exch def /halfheadthickness exch 2 div def /tipy exch def
+/tipx exch def /taily exch def /tailx exch def /dx tipx tailx sub def /dy tipy
+taily sub def /angle dy dx atan def /savematrix mtrx currentmatrix def tipx
+tipy translate angle rotate 0 0 moveto headlength neg halfheadthickness neg
+lineto headlength insetlength sub neg 0 lineto headlength neg
+halfheadthickness lineto closepath fill savematrix setmatrix end}def
+/arrowfill{gsave newpath arrowwidth arrowlength arrowinset arrow grestore}def
+/arrowline{arrowdict begin gsave newpath /tipfix exch def /tailfix exch def
+/tipy exch def /tipx exch def /taily exch def /tailx exch def /dx tipx tailx
+sub def /dy tipy taily sub def /angle dy dx atan def /savematrix mtrx
+currentmatrix def tipx tipy translate angle rotate tipfix neg 0 moveto
+savematrix setmatrix /savematrix mtrx currentmatrix def tailx taily translate
+angle rotate tailfix 0 lineto savematrix setmatrix stroke grestore end}def
+/arrownodeconnect{gsave transform 4 2 roll transform exch 4 1 roll alignpoint
+4 2 roll alignpoint 4 1 roll exch itransform 4 2 roll itransform 4 copy 0
+arrowdict begin arrowlength arrowinset sub end arrowline gsave newpath
+arrowfill grestore grestore}def /doublearrownodeconnect{gsave transform 4 2
+roll transform exch 4 1 roll alignpoint 4 2 roll alignpoint 4 1 roll exch
+itransform 4 2 roll itransform 4 copy arrowdict begin arrowlength arrowinset
+sub end dup arrowline 4 copy gsave newpath arrowfill grestore gsave newpath 4
+2 roll arrowfill grestore grestore}def /barnodeconnect{4 2 roll 2 copy moveto
+5 -1 roll add dup 3 1 roll lineto 2 index exch lineto lineto stroke}def
+/arrowbarnodeconnect{4 2 roll 2 copy moveto 5 -1 roll add dup 3 1 roll lineto
+2 index exch 4 copy lineto lineto gsave newpath 4 2 roll arrowfill fill
+grestore stroke}def /nodetriangle{gsave exch nodes exch get nodebottom moveto
+dup nodes exch get nodetopleft lineto nodes exch get nodetopright lineto
+closepath stroke grestore}def /slope{/y1 exch def /x1 exch def /y0 exch def
+/x0 exch def y1 y0 sub x1 x0 sub div}def /midpoint{/y1 exch def /x1 exch def
+/y0 exch def /x0 exch def x1 x0 sub abs x1 x0 ge{x0 add}{x1 add}ifelse y1 y0
+sub abs y1 y0 ge{y0 add}{y1 add}ifelse}def /tancurveto{1 index exch curveto}
+def /nodetancurve{/depth exch def /to exch def /from exch def gsave nodes from
+get noderight moveto nodes to get noderight tancurveto stroke grestore}def
+/getloc{3 -1 roll nodes exch get dup begin depth end 3 1 roll exch cvx exec 4
+2 roll}def /rightcur{0 /noderight getloc}def /leftcur{180 /nodeleft getloc}
+def /topcur{90 /nodetop getloc}def /bottomcur{270 /nodebottom getloc}def
+/topleftcur{135 /nodetopleft getloc}def /toprightcur{45 /nodetopright getloc}
+def /bottomleftcur{225 /nodebottomleft getloc}def /bottomrightcur{315
+/nodebottomright getloc}def /arrowfiddledict 10 dict def /arrowfiddle{
+arrowfiddledict begin /twist exch def /shift exch def /shaft exch def /angle
+exch twist add def /tipy exch def /tipx exch def tipx angle cos shaft mul add
+tipy angle sin shaft mul add tipx angle cos shift mul add tipy angle sin shift
+mul add end}def /nodecurve{gsave 0 fromangle arrowfiddle moveto 6 2 roll 0
+toangle arrowfiddle curveto stroke grestore}def /arrownodecurve{gsave 0
+fromangle arrowfiddle moveto 6 2 roll 4 copy 10 4 roll arrowlength arrowinset
+sub toangle arrowfiddle curveto 0 toangle arrowfiddle arrowfill stroke
+grestore}def /arrow2nodecurve{gsave 4 copy 0 fromangle arrowfiddle arrowfill
+arrowlength arrowinset sub fromangle arrowfiddle moveto 6 2 roll 4 copy 10 4
+roll arrowlength arrowinset sub toangle arrowfiddle curveto 0 toangle
+arrowfiddle arrowfill stroke grestore}def /delink{gsave 4 copy newslope 6 2
+roll newmidpoint delinkline}def /delinkline{moveto dup 0 eq{blong 2 div neg 0
+rmoveto blong 0 rlineto 2 pop}{exch dup 0 eq{0 blong 2 div neg rmoveto 0 blong
+rlineto 2 pop}{div neg dup dup mul 1 add sqrt blong exch div 2 copy mul 2 copy
+2 div neg exch 2 div neg exch rmoveto rlineto 1 pop}ifelse}ifelse stroke
+grestore}def /delinkcurve{8 copy 8 copy bezslope 10 2 roll bezmidpoint
+delinkline}def /xyarrange{exch 3 1 roll 5 -1 roll 7 -1 roll exch 4 2 roll}def
+/calcx{exch 3 mul 3 -1 roll 3 mul add add add 8 mul}def /calcy{add exch sub
+exch sub}def /bezmidpoint{xyarrange calcx 5 1 roll calcx exch}def /bezslope{
+xyarrange calcy 5 1 roll calcy exch}def /newmidpoint{exch 4 -1 roll add 2 div
+3 1 roll add 2 div}def /newslope{4 -1 roll exch 4 1 roll sub 3 1 roll sub exch
+}def /nodebox{nodes exch get begin gsave newpath x y moveto h w dobox cleanup
+stroke grestore end}def /nodecircle{nodes exch get begin gsave newpath w 2 div
+x add h 2 div y add w w mul h h mul add sqrt 2 div 4 -1 roll add 360 0 arcn
+cleanup stroke grestore end}def /nodecircletrans{nodes exch get begin gsave
+newpath w 2 div x add h 2 div y add w w mul h h mul add sqrt 2 div 4 -1 roll
+add 360 0 arcn stroke grestore end}def /nodeoval{nodes exch get begin gsave
+newpath x 2 sub y 2 sub moveto h 4 add w 4 add dooval cleanup stroke grestore
+end}def /testnodeoval{nodes exch get begin gsave newpath h h mul w w mul add
+sqrt div dup dup dup w mul neg x add exch h mul neg y add moveto dup h mul 2
+mul h add exch w mul 2 mul w add testdooval stroke grestore end}def /cleanup{
+gsave x y moveto h nodemargin sub .5 add w nodemargin sub .5 add doccbox 1
+setgray fill grestore}def /boxdict 4 dict def boxdict /mtrx matrix put /dobox{
+boxdict begin /w exch def /h exch def /savematrix mtrx currentmatrix def 0 h
+rlineto w 0 rlineto 0 h neg rlineto closepath savematrix setmatrix end}def
+/doccbox{boxdict begin /w exch def /h exch def /savematrix mtrx currentmatrix
+def w 0 rlineto 0 h rlineto w neg 0 rlineto closepath savematrix setmatrix end
+}def /ovaldict 6 dict def ovaldict /mtrx matrix put /dooval{ovaldict begin /w
+exch def /h exch def /savematrix mtrx currentmatrix def 0 h 2 div rmoveto 0 h
+2 div nodemargin sub nodemargin h 2 div w 2 div h 2 div rcurveto w 2 div
+nodemargin sub 0 w 2 div nodemargin neg w 2 div h 2 div neg rcurveto 0 h 2 div
+neg nodemargin add nodemargin neg h 2 div neg w 2 div neg h 2 div neg rcurveto
+w 2 div neg nodemargin add 0 w 2 div neg nodemargin w 2 div neg h 2 div
+rcurveto savematrix setmatrix end}def /testdooval{ovaldict begin /w exch def
+/h exch def /r exch def h 2 div neg r mul dup h 2 div dup r mul 3 1 roll 2 r
+sub mul 0 h rcurveto w 2 div dup r mul exch 2 r sub mul w 2 div r mul dup 3 1
+roll w 0 rcurveto h 2 div r mul dup h 2 div neg dup r mul 3 1 roll 2 r sub mul
+0 h neg rcurveto w 2 div neg dup r mul exch 2 r sub mul w 2 div neg r mul dup
+3 1 roll w neg 0 rcurveto end}def end end
diff --git a/macros/latex209/contrib/trees/tree-dvips/tree-dvips91.script b/macros/latex209/contrib/trees/tree-dvips/tree-dvips91.script
new file mode 100644
index 0000000000..cc0937f43c
--- /dev/null
+++ b/macros/latex209/contrib/trees/tree-dvips/tree-dvips91.script
@@ -0,0 +1,718 @@
+% grestore
+% special commands for setting up tree macros
+%% version .91 - May 16, 1995
+
+TeXDict begin
+
+% the commands needed to get any of this working. The first section
+% may need to be modified if different dvi to postscript programs are
+% used.
+
+% redefinition of /@beginspec suggested by Gintas Grigelionis
+% (gintas@theophys.kth.se) 5/95. also dropped bop_hook and texpsmatrix
+%
+% /@beginspec {gsave texpsmatrix setmatrix treedict begin} def
+/@beginspec {gsave
+ Resolution 72 div VResolution -72 div scale
+ treedict begin} def
+/@endspec {end grestore} def
+
+% for landscape Landscape=true, letter Landscape=false
+% In dvips 5.5 and later, the matrix in landscape was changed from
+% [0.0 -1.0 1.0 0.0 0.0 0.0] to the current setting of [0.0 1.0 -1.0
+% 0.0 0.0 0.0]. If you are using an earlier version, switch back.
+
+/treedict 200 dict def treedict begin
+
+% num pt num (converts a number in TeX pts (72.27 pts/in) to
+% postscript pts (72pts/in)
+/pt {72 mul 72.07 div} def
+
+% end of first section
+
+% definition of a node as a box containing the following information
+% The x y location of the lower left hand corner of the box
+% the height of the box (h)
+% the width of the box (w)
+% nodemargin is added to all sides to ensure a boundary around the box
+% str w h d node -
+% (nodemargin is defined in the TeX file)
+/nodemargin 2 def
+/nodes 100 dict def
+/node { /dpth exch def
+ /hght exch def
+ /wdth exch def
+ 4 dict dup begin
+ /x /y currentpoint
+ dpth sub nodemargin sub exch 3 1 roll def
+ nodemargin sub def
+ /h hght dpth add nodemargin dup add add def
+ /w wdth nodemargin dup add add def
+ end nodes 3 1 roll put} def
+
+
+% commands to find various locations around the nodebox
+%
+% nodetopleft nodetop nodetopright
+% *--------*--------*
+% | |
+% | |
+% nodeleft * (nodebox) * noderight
+% | |
+% | |
+% *--------*--------*
+% nodebotleft nodebottom nodebotright
+%
+
+
+% all of these take
+% dict nodebottom x1 y1 [dict has x y h w defined]
+/nodebottom {begin
+ x w 2 div add y
+ end} def
+/nodetop {begin
+ x w 2 div add y h add
+ end} def
+/nodeleft {begin
+ x y h 2 div add
+ end} def
+/noderight {begin
+ x w add y h 2 div add
+ end} def
+/nodetopleft {begin
+ x y h add
+ end} def
+/nodetopright {begin
+ x w add y h add
+ end} def
+/nodebottomleft {begin
+ x y
+ end} def
+/nodebottomright {begin
+ x w add y
+ end} def
+
+% some more locations of use
+/farright {begin
+ x w add depth add h 2 div y add
+ end} def
+
+/farleft {begin
+ x depth sub h 2 div y add
+ end} def
+
+/farbottom {begin
+ x w 2 div add y depth sub
+ end} def
+
+/fartop {begin
+ x w 2 div add y h add depth add
+ end} def
+
+/farbottomleft {begin
+ x depth 45 cos mul sub y depth 45 sin mul sub
+ end} def
+
+/farbottomright {begin
+ x w add depth 45 cos mul add y depth 45 sin mul sub
+ end} def
+
+/fartopright {begin
+ x w add depth 45 cos mul add y h add depth 45 sin mul add
+ end} def
+
+/fartopleft {begin
+ x depth 45 cos mul sub y h add depth 45 sin mul add
+ end} def
+
+
+% connects two nodes with a straight line
+% add location information (e.g., whether to go from
+% nodetop to nodeleft ...
+
+% nodename1 loc1 nodename2 loc2 nodeconnect -
+% e.g., a nodetop b nodebottom nodeconnect
+
+% to see if straight lines are indeed straight
+% x1 x2 alignpoint x1' x2' finds out if the two numbers are less than
+% one pixel apart if so make x1'=x2'
+
+/alignpoint {2 copy sub abs 1 le {add 2 div round dup} if} def
+
+% nodelocation nodename getnodepoint x y
+/getnode {nodes exch get} def
+
+% xfrom yfrom xto yto nodeconnect -
+/nodeconnect { gsave
+ transform 4 2 roll
+ transform
+ exch 4 1 roll alignpoint
+ 4 2 roll alignpoint
+ 4 1 roll exch
+ itransform moveto itransform lineto
+ stroke
+ grestore
+ } def
+
+% arrowheads
+% xtail ytail xtip ytip headthickness headlength insetlength arrow -
+
+/arrowdict 15 dict def
+
+arrowdict begin
+ /mtrx matrix def
+end
+
+/arrow {arrowdict begin
+ /insetlength exch def
+ /headlength exch def
+ /halfheadthickness exch 2 div def
+ /tipy exch def /tipx exch def
+ /taily exch def /tailx exch def
+
+ /dx tipx tailx sub def
+ /dy tipy taily sub def
+ /angle dy dx atan def
+
+ /savematrix mtrx currentmatrix def
+ tipx tipy translate
+ angle rotate
+% following is for arrow
+ 0 0 moveto
+ headlength neg halfheadthickness neg lineto
+ headlength insetlength sub neg 0 lineto
+ headlength neg halfheadthickness lineto
+ closepath
+ fill
+ savematrix setmatrix
+ end } def
+
+% does regular filled arrowhead
+/arrowfill {gsave
+ newpath
+ arrowwidth arrowlength arrowinset arrow
+ grestore} def
+
+% draws line for arrow but not arrow head(s)
+% xtail ytail xtip ytip tailfix tipfix arrowline
+/arrowline {arrowdict begin
+ gsave
+ newpath
+ /tipfix exch def
+ /tailfix exch def
+ /tipy exch def /tipx exch def
+ /taily exch def /tailx exch def
+
+ /dx tipx tailx sub def
+ /dy tipy taily sub def
+ /angle dy dx atan def
+
+ /savematrix mtrx currentmatrix def
+ tipx tipy translate
+ angle rotate
+ tipfix neg 0 moveto
+ savematrix setmatrix
+ /savematrix mtrx currentmatrix def
+ tailx taily translate
+ angle rotate
+ tailfix 0 lineto
+ savematrix setmatrix
+ stroke
+ grestore
+ end} def
+
+
+% xfrom yfrom xto yto testcmd -
+% arrownodeconnect
+/arrownodeconnect{ gsave
+ transform 4 2 roll
+ transform
+ exch 4 1 roll alignpoint
+ 4 2 roll alignpoint
+ 4 1 roll exch
+ itransform 4 2 roll itransform
+% line
+ 4 copy
+ 0 arrowdict begin arrowlength arrowinset sub end arrowline
+% arrow
+ gsave
+ newpath
+ arrowfill
+ grestore
+ grestore
+ } def
+
+
+/doublearrownodeconnect{ gsave
+ transform 4 2 roll
+ transform
+ exch 4 1 roll alignpoint
+ 4 2 roll alignpoint
+ 4 1 roll exch
+ itransform 4 2 roll itransform
+% line
+% 4 copy moveto lineto
+% stroke
+ 4 copy
+ arrowdict begin arrowlength arrowinset sub end dup arrowline
+ 4 copy
+% arrow at one end
+ gsave
+ newpath
+ arrowfill
+ grestore
+% arrow at other end
+ gsave
+ newpath
+ 4 2 roll arrowfill
+ grestore
+ grestore
+ } def
+
+
+% connecting with a bar like
+% _______________
+% | |
+% or like
+% _______________
+% | |
+% | node
+% node
+
+% depth fromnode fromloc tonode toloc
+% depth x1 y1 x2 y2 barnodeconnect -
+/barnodeconnect {4 2 roll
+ 2 copy moveto
+ 5 -1 roll add
+ dup 3 1 roll
+ lineto
+ 2 index exch
+ lineto lineto
+ stroke
+ } def
+
+/arrowbarnodeconnect {4 2 roll
+ 2 copy moveto
+ 5 -1 roll add
+ dup 3 1 roll
+ lineto
+ 2 index exch
+ 4 copy lineto lineto
+ gsave
+ newpath
+ 4 2 roll
+ arrowfill
+ fill
+ grestore
+ stroke
+ } def
+
+
+% Takes two nodes and forms a triangle
+% node1
+% /\
+% / \
+% ----
+% nodess
+%
+% fromnodename tonodename nodetriangle -
+/nodetriangle {
+ gsave
+ exch
+ nodes exch get nodebottom moveto
+ dup
+ nodes exch get nodetopleft lineto
+ nodes exch get nodetopright lineto
+ closepath
+ stroke
+ grestore } def
+
+
+% not sure what I am using the following for
+% x y x y slope num
+/slope {/y1 exch def
+ /x1 exch def
+ /y0 exch def
+ /x0 exch def
+ y1 y0 sub x1 x0 sub div
+ } def
+
+% x y x y midpoint x y
+/midpoint {/y1 exch def
+ /x1 exch def
+ /y0 exch def
+ /x0 exch def
+ x1 x0 sub abs
+ x1 x0 ge {x0 add} {x1 add} ifelse
+ y1 y0 sub abs
+ y1 y0 ge {y0 add} {y1 add} ifelse
+ } def
+
+
+% variant of curveto where x1 y1 = x2 y2
+/tancurveto {1 index exch
+ curveto} def
+
+/nodetancurve {/depth exch def
+ /to exch def
+ /from exch def
+ gsave
+ nodes from get noderight moveto
+
+ nodes to get noderight
+ tancurveto
+ stroke
+ grestore } def
+
+
+
+% the node curves draw curves between two points
+%
+% this swaps a dictionary around an angle, pulls out depth, & dismisses
+% the dictionary.
+% node locname farloc angle depth
+
+/getloc {3 -1 roll
+ nodes exch get dup
+ begin depth end
+ 3 1 roll
+ exch cvx exec
+ 4 2 roll} def
+
+% nodename rightcur x1 y1 x2 y2
+/rightcur {0 /noderight getloc} def
+/leftcur {180 /nodeleft getloc } def
+/topcur {90 /nodetop getloc} def
+/bottomcur {270 /nodebottom getloc} def
+/topleftcur {135 /nodetopleft getloc} def
+/toprightcur {45 /nodetopright getloc} def
+/bottomleftcur {225 /nodebottomleft getloc} def
+/bottomrightcur {315 /nodebottomright getloc} def
+
+% (depth predefined) x1 y1 x2 y2 x3 y3 x4 y4 nodecurve -
+% where nodename nodeposition produces x1 y1 x2 y2
+% where x1 y1 are the endpoint, x2 y2 end-control, etc.
+
+% adjustments for arrowheads, etc.
+/arrowfiddledict 10 dict def
+
+% x1 y1 angle depth shift twist arrowfiddle x3 y3 x4 y4
+% where x3 y3 are revised endpoint for arrow-headed bezier curves
+/arrowfiddle {arrowfiddledict begin
+ /twist exch def
+ /shift exch def
+ /shaft exch def
+ /angle exch twist add def
+ /tipy exch def /tipx exch def
+ tipx angle cos shaft mul add
+ tipy angle sin shaft mul add
+ tipx angle cos shift mul add
+ tipy angle sin shift mul add
+ end} def
+
+/nodecurve {gsave
+ 0 fromangle arrowfiddle moveto
+ 6 2 roll
+ 0 toangle arrowfiddle curveto
+ stroke
+ grestore} def
+
+/arrownodecurve {gsave
+ 0 fromangle arrowfiddle % adjust from angle
+ moveto
+ 6 2 roll
+ 4 copy 10 4 roll % prepare arrowhead material
+ arrowlength arrowinset sub %arrowfiddle param.
+ toangle % ditto
+ arrowfiddle
+ curveto
+ 0 toangle arrowfiddle arrowfill
+ stroke
+ grestore} def
+
+/arrow2nodecurve {gsave
+ 4 copy
+ 0 fromangle arrowfiddle arrowfill
+ arrowlength arrowinset sub fromangle arrowfiddle
+ moveto
+ 6 2 roll
+ 4 copy 10 4 roll % prepare arrowhead material
+ arrowlength arrowinset sub %arrowfiddle param.
+ toangle % ditto
+ arrowfiddle
+ curveto
+ 0 toangle arrowfiddle arrowfill
+ stroke
+ grestore} def
+
+
+% commands for doing things along line
+% blong (predefined) xfrom yfrom xto yto delink -
+% need to find halfway point
+/delink { gsave
+ 4 copy newslope
+ 6 2 roll newmidpoint
+ delinkline } def
+
+%% calculated (dx dy xmid ymid) now moveto midpoint
+% moveto dup 0 eq
+%% duplicate dy and check whether line is horizontal
+% {blong 2 div neg 0 rmoveto blong 0 rlineto 2 pop}
+%% line not horizontal so check whether vertical
+% {exch dup 0 eq
+% {0 blong 2 div neg rmoveto 0 blong rlineto 2 pop}
+%% If neither than calculate standard case (dy dx)
+% {div neg dup dup mul 1 add sqrt
+% blong exch div
+% 2 copy mul 2 copy 2 div neg exch 2 div neg exch
+% rmoveto rlineto 1 pop} ifelse} ifelse
+% stroke
+% grestore
+% } def
+
+% actually draws the line
+% dx dy xmid ymid delinkline -
+
+/delinkline { moveto dup 0 eq
+% duplicate dy and check whether line is horizontal
+ {blong 2 div neg 0 rmoveto blong 0 rlineto 2 pop}
+% line not horizontal so check whether vertical
+ {exch dup 0 eq
+ {0 blong 2 div neg rmoveto 0 blong rlineto 2 pop}
+% If neither than calculate standard case (dy dx)
+ {div neg dup dup mul 1 add sqrt
+ blong exch div
+ 2 copy mul 2 copy 2 div neg exch 2 div neg exch
+ rmoveto rlineto 1 pop} ifelse} ifelse
+ stroke
+ grestore
+ } def
+
+
+%
+% delink curve
+% blong (predefined) x0 y0 x1 y1 x2 y2 x3 y3 delinkcurve -
+
+/delinkcurve { 8 copy 8 copy
+ bezslope 10 2 roll % push to back
+ bezmidpoint
+ delinkline
+} def
+
+% x0 y0 x1 y1 x2 y2 x3 y3 xyarrange x0 x1 x2 x3 y0 y1 y2 y3
+ % x0 y0 x1 y1 x2 y2 x3 y3
+/xyarrange { exch % x0 y0 x1 y1 x2 y2 y3 x3
+ 3 1 roll % x0 y0 x1 y1 x2 x3 y2 y3
+ 5 -1 roll % x0 y0 x1 x2 x3 y2 y3 y1
+ 7 -1 roll % x0 x1 x2 x3 y2 y3 y1 y0
+ exch % x0 x1 x2 x3 y2 y3 y0 y1
+ 4 2 roll } def % x0 x1 x2 x3 y0 y1 y2 y3
+
+% x0 x1 x2 x3 calcx xn 8(x3+3x2+3x1+x0)=xn
+/calcx { exch 3 mul
+ 3 -1 roll 3 mul
+ add add add 8 mul} def
+
+% x0 x1 x2 x3 calcx xn x3+x2-x1-x0=xn
+/calcy { add exch sub exch sub } def
+
+
+% x0 y0 x1 y1 x2 y2 x3 y3 bezmidpoint xm ym
+% using the following equations
+% xb=8*(x3+3x2+3x1+x0)
+% yb=8*(y3+3y2+3y1+y0)
+
+/bezmidpoint {xyarrange
+calcx 5 1 roll calcx exch
+} def
+
+
+% x0 y0 x1 y1 x2 y2 x3 y3 bezslope dx dy
+% equations are dx=x3+x2-x1-x0
+% dy=y3+y2-y1-y0
+/bezslope {xyarrange
+calcy 5 1 roll calcy exch
+} def
+
+% finds midpoint between two points xfrom yfrom xto yto newmidpoint xmid ymid
+/newmidpoint { exch
+ 4 -1 roll
+ add 2 div
+ 3 1 roll
+ add 2 div
+ } def
+
+% finds slope between two points: xfrom yfrom xto yto newslope dx dy
+/newslope { 4 -1 roll
+ exch
+ 4 1 roll
+ sub 3 1 roll sub exch
+ } def
+
+
+%% commands for drawing things around nodes
+% nodename nodebox -
+/nodebox {nodes exch get begin
+ gsave
+ newpath
+ x y moveto
+ h w dobox
+ cleanup
+ stroke
+ grestore
+ end} def
+
+
+% nodename nodecircle -
+% would be nice to have a parameter that adjusts diameter of circle
+% depth nodename nodecircle -
+/nodecircle {nodes exch get begin
+ gsave
+ newpath
+ w 2 div x add h 2 div y add
+ w w mul h h mul add sqrt 2 div 4 -1 roll add
+ 360 0 arcn
+ cleanup
+ stroke
+ grestore
+ end} def
+
+% no cleanup
+/nodecircletrans {nodes exch get begin
+ gsave
+ newpath
+ w 2 div x add h 2 div y add
+ w w mul h h mul add sqrt 2 div 4 -1 roll add
+ 360 0 arcn
+ stroke
+ grestore
+ end} def
+
+% nodename nodeoval -
+/nodeoval {nodes exch get begin
+ gsave
+ newpath
+ x 2 sub y 2 sub moveto
+ h 4 add w 4 add dooval
+ cleanup
+ stroke
+ grestore
+ end } def
+
+% ratio depth nodename testnodeoval -
+% ratio should be between 0 and 1
+/testnodeoval {nodes exch get begin
+ gsave
+ newpath
+ h h mul w w mul add sqrt div dup dup dup
+ w mul neg x add exch
+ h mul neg y add
+ moveto
+ dup
+ h mul 2 mul h add exch
+ w mul 2 mul w add
+ testdooval
+ stroke
+ grestore
+ end } def
+
+
+/cleanup{gsave
+ x y moveto
+ h nodemargin sub .5 add w nodemargin sub .5 add doccbox
+ 1 setgray fill grestore
+}def
+
+/boxdict 4 dict def
+boxdict /mtrx matrix put
+
+/dobox{boxdict begin
+ /w exch def
+ /h exch def
+ /savematrix mtrx currentmatrix def
+ 0 h rlineto
+ w 0 rlineto
+ 0 h neg rlineto
+ closepath
+ savematrix setmatrix
+ end} def
+
+% do box in counterclockwise fashion
+/doccbox{boxdict begin
+ /w exch def
+ /h exch def
+ /savematrix mtrx currentmatrix def
+ w 0 rlineto
+ 0 h rlineto
+ w neg 0 rlineto
+ closepath
+ savematrix setmatrix
+ end} def
+
+
+/ovaldict 6 dict def
+ovaldict /mtrx matrix put
+
+% h w ovaldict -
+/dooval{ovaldict begin
+ /w exch def
+ /h exch def
+ /savematrix mtrx currentmatrix def
+ 0 h 2 div rmoveto
+ 0 h 2 div nodemargin sub
+ nodemargin h 2 div
+ w 2 div h 2 div
+ rcurveto
+ w 2 div nodemargin sub 0
+ w 2 div nodemargin neg
+ w 2 div h 2 div neg
+ rcurveto
+ 0 h 2 div neg nodemargin add
+ nodemargin neg h 2 div neg
+ w 2 div neg h 2 div neg
+ rcurveto
+ w 2 div neg nodemargin add 0
+ w 2 div neg nodemargin
+ w 2 div neg h 2 div
+ rcurveto
+ savematrix setmatrix
+ end} def
+
+% give height and width of a box and the lower left hand point
+% produce a curve that will enclose the box.
+% initial point already defined
+% ratio h w testdooval -
+/testdooval{ovaldict begin
+ /w exch def
+ /h exch def
+ /r exch def
+ h 2 div neg r mul dup
+ h 2 div dup
+ r mul 3 1 roll
+ 2 r sub mul
+ 0 h
+ rcurveto
+ w 2 div dup
+ r mul exch
+ 2 r sub mul
+ w 2 div r mul dup 3 1 roll
+ w 0
+ rcurveto
+ h 2 div r mul dup
+ h 2 div neg dup
+ r mul 3 1 roll
+ 2 r sub mul
+ 0 h neg
+ rcurveto
+ w 2 div neg dup
+ r mul exch
+ 2 r sub mul
+ w 2 div neg r mul dup 3 1 roll
+ w neg 0
+ rcurveto
+ end} def
+
+end % of treedict
+
+end % of TeXdict
+% gsave
diff --git a/macros/latex209/contrib/trees/tree-dvips/tree-manual.pdf b/macros/latex209/contrib/trees/tree-dvips/tree-manual.pdf
new file mode 100644
index 0000000000..02fa97f402
--- /dev/null
+++ b/macros/latex209/contrib/trees/tree-dvips/tree-manual.pdf
Binary files differ
diff --git a/macros/latex209/contrib/trees/tree-dvips/tree-manual.tex b/macros/latex209/contrib/trees/tree-dvips/tree-manual.tex
new file mode 100644
index 0000000000..9f942fd415
--- /dev/null
+++ b/macros/latex209/contrib/trees/tree-dvips/tree-manual.tex
@@ -0,0 +1,603 @@
+\documentstyle[tree-dvips,rotate,lingmacros]{article}
+
+\title{Tree Macros}
+\author{Emma Pease}
+\date{May 10, 1995}
+
+\begin{document}
+
+\maketitle
+
+The tree macros package allows one to integrate \LaTeX\ and Postscript.
+For example, one can use \LaTeX\ to layout a tree and have Postscript
+draw the lines.
+\begin{center}
+ \begin{tabular}{ccc}
+&\node{ab}{top node}\\[3ex]
+\node{ac}{left node} && \node{c}{right node}\\[3ex]
+ && \node{d}{odd node}
+\end{tabular}
+\nodeconnect{ab}{ac}
+\nodeconnect{ab}{c}
+\nodeconnect{c}{d}
+\nodecurve[r]{ab}[r]{d}{1in}
+\anodeconnect[b]{ac}[l]{d}
+\anodecurve[l]{ab}[l]{ac}{1in}
+\end{center}
+
+These macros work by defining locations on a page and then
+manipulating them in a variety of ways. The commands that created the
+above tree are as follows:
+ \begin{verbatim}
+\begin{tabular}{ccc}
+ &\node{a}{top node}\\[3ex]
+\node{b}{left node} & & \node{c}{right node}\\[3ex]
+ & & \node{d}{odd node}
+\end{tabular}
+\nodeconnect{a}{b}
+\nodeconnect{a}{c}
+\nodeconnect{c}{d}
+\nodecurve[r]{a}[r]{d}{1in}
+\anodeconnect[b]{b}[l]{d}
+\anodecurve[l]{a}[l]{b}{1in}
+\end{verbatim}
+ You will notice that four nodes are defined, a, b, c, and d, using the
+\verb+\node+ command. These nodes are then connected using the
+\verb+\nodeconnect+ and \verb+\nodecurve+ commands.
+
+\section{Locating Commands}
+
+Location commands are those that deal with defining a location on a
+page. The basic command
+ \begin{center}
+\begin{verbatim}
+\node{nodename}{object}
+\end{verbatim}
+\end{center}
+ Each node has its name, height, width, and the location of the lower
+left hand corner point passed down to postscript where it will remain
+until needed. Note that the object will be printed by \TeX\ but the
+lines drawn by Postscript. A variant
+of this command is
+ \begin{center}
+\begin{verbatim}
+\nodepoint{nodename}[horizontal displace][vertical displace]
+\end{verbatim}
+\end{center}
+ The node's height and width are 0pts, but the location can be
+displaced.
+
+\section{Connecting Commands}
+
+These commands connect two or more nodes.
+
+\subsection{nodeconnect}
+
+One basic command is
+\begin{center}
+\begin{verbatim}
+\nodeconnect[fromloc]{fromnodename}[toloc]{tonodename}
+\end{verbatim}
+\end{center}
+ fromnodename and tonodename must be the names of two existing nodes.
+Imagine the node as a box, fromloc and toloc are the locations on that
+box to draw the connecting lines.
+\begin{center}\nodemargin=9pt
+\begin{tabular}{lcr}
+tl & {t} &{tr}\\[2ex]
+{l} & \node{a}{object} &{r}\\[2ex]
+{bl}& {b} &{br}
+\end{tabular}
+\nodebox{a}
+\end{center}
+ The present choices are t [top], b [bottom], l [left], r [right], tl
+[topleft], tr [topright], bl [bottomleft], and br [bottomright].
+These could be expanded. By default the fromloc is bottom and the
+toloc is top.
+
+Variants of this command are
+\begin{verbatim}
+\anodeconnect[fromloc]{fromnodename}[toloc]{tonodename}
+\aanodeconnect[fromloc]{fromnodename}[toloc]{tonodename}
+\end{verbatim}
+The first places an arrow pointing to the second node. The second puts
+arrows on both ends of the line.
+\begin{center}
+\begin{tabular}{ccccc}
+ &\node{a}{Top node}\\[3ex]
+\node{b}{left node\strut} & & \node{c}{right node\strut}&\qquad &\node{d}{farright\strut}
+\end{tabular}
+\nodeconnect{a}{b}
+\nodeconnect[t]{c}[b]{a}
+\anodeconnect[r]{b}[l]{c}
+\aanodeconnect[r]{c}[l]{d}
+\end{center}
+\begin{verbatim}
+\begin{tabular}{ccccc}
+ &\node{a}{Top node}\\[3ex]
+\node{b}{left node\strut} & & \node{c}{right node\strut}
+ &\qquad &\node{d}{farright\strut}
+\end{tabular}
+\nodeconnect{a}{b}
+\nodeconnect[t]{c}[b]{a}
+\anodeconnect[r]{b}[l]{c}
+\aanodeconnect[r]{c}[l]{d}
+\end{verbatim}
+Note the \verb+\strut+. This ensures that both nodes have the same
+height and depth.
+
+\subsection{barnodeconnect}
+
+Another way of connecting is via the bar connect commands
+\begin{verbatim}
+\barnodeconnect[depth]{fromnodename}{tonodename}
+\abarnodeconnect[depth]{fromnodename}{tonodename}
+\end{verbatim}
+For example,
+\begin{center}
+\node{c}{\strut This} \node{a}{\strut is} a \node{b}{\strut test} of
+barnodeconnect.
+\barnodeconnect{a}{b}
+\barnodeconnect[-5pt]{a}{c}
+\bigskip\bigskip
+
+\node{c}{\strut This} \node{a}{\strut is} a \node{b}{\strut test}
+\node{d}{\strut of} abarnodeconnect. \node{e}{\strut Note} arrows.
+\abarnodeconnect[10pt]{a}{b}
+\abarnodeconnect[-10pt]{a}{c}
+\abarnodeconnect[-10pt]{b}{d}
+\abarnodeconnect[10pt]{e}{d}
+\end{center}\bigskip
+\begin{verbatim}
+\node{c}{\strut This} \node{a}{\strut is} a \node{b}{\strut test}
+of barnodeconnect.
+\barnodeconnect{a}{b}
+\barnodeconnect[-5pt]{a}{c}
+\bigskip\bigskip
+
+\node{c}{\strut This} \node{a}{\strut is} a \node{b}{\strut test}
+\node{d}{\strut of} abarnodeconnect. \node{e}{\strut Note} arrows.
+\abarnodeconnect[10pt]{a}{b}
+\abarnodeconnect[-10pt]{a}{c}
+\abarnodeconnect[-10pt]{b}{d}
+\abarnodeconnect[10pt]{e}{d}
+\end{verbatim}
+ A negative depth places the bar below the line; a positive depth (or
+the default, which is 5pt) places the bar above the line.
+
+
+\subsection{nodecurve}
+
+The nodecurve commands allow curves between nodes.
+\begin{verbatim}
+\nodecurve[fromloc][fromang]{fromnodename}[toloc][toang]{tonodename}{fdepth}[tdepth]
+\anodecurve[fromloc][fromang]{fromnodename}[toloc][toang]{tonodename}{fdepth}[tdepth]
+\aanodecurve[fromloc][fromang]{fromnodename}[toloc][toang]{tonodename}{fdepth}[tdepth]
+\end{verbatim}
+The options fromloc and toloc are the same as for \verb+\nodeconnect+.
+The options fromang and toang are the angle of incidence in degrees to the
+location with 0 being perpendicular and the default. Angles are
+calculated counterclockwise. fdepth and tdepth are dimensions and
+allow one to adjust how curved the curve is.
+\begin{center}
+\begin{tabular}{ccc}
+ &\node{a}{Top node}\\[3ex]
+\node{b}{left node\strut} & & \node{c}{right node\strut}
+\end{tabular}
+\nodecurve[b]{b}[b]{c}{.3in}
+\anodecurve[l]{a}[l]{b}{20pt}[40pt]
+\aanodecurve[r]{a}[r]{c}{60pt}[20pt]
+\hfill
+\begin{tabular}{c}
+\node{d}{Top}\\
+\node{e}{Bottom}
+\end{tabular}
+\nodecurve[l]{d}[l]{e}{30pt}
+\nodecurve[l]{d}[l]{e}{30pt}[40pt]
+\nodecurve[l]{d}[l]{e}{30pt}[50pt]
+\nodecurve[l]{d}[l]{e}{30pt}[5pt]
+
+\nodecurve[r]{d}[r]{e}{30pt}
+\nodecurve[r][20]{d}[r][-30]{e}{30pt}
+
+\bigskip
+
+\end{center}
+\begin{verbatim}
+\begin{tabular}{ccc}
+ &\node{a}{Top node}\\[3ex]
+\node{b}{left node\strut} & & \node{c}{right node\strut}
+\end{tabular}
+\nodecurve[b]{b}[b]{c}{.3in}
+\anodecurve[l]{a}[l]{b}{20pt}[40pt]
+\aanodecurve[r]{a}[r]{c}{60pt}[20pt]
+\hfill
+\begin{tabular}{c}
+\node{d}{Top}\\
+\node{e}{Bottom}
+\end{tabular}
+% here follow some curves that adjust fdepth and tdepth
+\nodecurve[l]{d}[l]{e}{30pt}
+\nodecurve[l]{d}[l]{e}{30pt}[40pt]
+\nodecurve[l]{d}[l]{e}{30pt}[50pt]
+\nodecurve[l]{d}[l]{e}{30pt}[5pt]
+
+% here follow some curves that adjust toang and fromang
+\nodecurve[r]{d}[r]{e}{30pt}
+\nodecurve[r][20]{d}[r][-30]{e}{30pt}
+\end{verbatim}
+
+\subsection{Other connecting commands}
+
+A few odd commands
+\begin{verbatim}
+\nodetriangle{fromnodename}{tonodename}
+\end{verbatim}
+This creates a triangle whose apex is the bottom of
+\verb+fromnodename+ and whose base is the top of \verb+tonodename+.
+\begin{center}
+\begin{tabular}{c}
+\node{a}{Top}\\[4ex]
+\node{b}{This is the bottom}
+\end{tabular}
+\nodetriangle{a}{b}
+
+\end{center}
+\begin{verbatim}
+\begin{tabular}{c}
+\node{a}{Top}\\[4ex]
+\node{b}{This is the bottom}
+\end{tabular}
+\nodetriangle{a}{b}
+\end{verbatim}
+The last command is meant to be used with the \verb+\nodeconnect+
+command. It causes a short line to cross perpendicular to the line.
+\begin{verbatim}
+\delink[fromloc]{fromnodename}[toloc]{tonodename}{length}
+\end{verbatim}
+An example follows
+\begin{center}
+\node{a}{leftnode\strut}\hspace{1in}\node{b}{rightnode\strut}
+\nodeconnect[r]{a}[l]{b}
+\delink[r]{a}[l]{b}{10pt}
+\end{center}
+
+\section{Single Node commands}
+
+These commands adjust something around a single node rather than
+connecting nodes. The basic commands are
+ \begin{center}
+\begin{verbatim}
+\nodebox{nodename}
+\nodecircle[depth]{nodename}
+\nodeoval{nodename}
+\end{verbatim}
+\end{center}
+They draw, respectively, a box, circle, or oval around the given node.
+\begin{center}
+\node{a}{node}\hfill \node{b}{node} \hfill \node{c}{node}
+\nodebox{a} \nodecircle{b} \nodeoval{c}
+\end{center}
+ You will probably wish to call these commands after you have called
+all the connecting commands you will be using in a particular diagram.
+
+
+\section{Parameters}
+
+At the moment there are three parameters that can be changed. They
+are
+\begin{itemize}
+\item \verb+\nodemargin+ - A node's height and width are defined as
+the height plus depth and width of an hbox enclosing the object plus the
+nodemargin on each side. The default is 2pt.
+
+\item \verb+\treelinewidth+ - The width of the lines. The default is .3pt.
+
+\item \verb+\dashlength+ - The length of the dash, if you are using
+dashed lines. The default is 0pt (solid line).\footnote{The length
+of the dash and the length between the dashes are the same. An
+exercise for someone who knows postscript and tex is to allow the dash
+and the blank to vary in size.}
+
+\item \verb+\arrowwidth+ - the width of the arrowhead in the
+ \verb+\anodeconnect+ and \verb+\anodecurve+ commands. Default is
+ 3 pt.
+
+\item \verb+\arrowlength+ - the length of the arrowhead. Default is
+ 4pt.
+
+\item \verb+\arrowinset+ - the inset in the arrow. Default is 1pt.
+
+\end{itemize}
+The command \verb+\arrowhead{width}{length}{inset}+ allows one to
+define all three parameters in one go.
+\begin{center}
+\node{a}{This} \node{b}{is} a \node{c}{line}.\\[5ex]
+\node{d}{This} \node{e}{is} a \node{f}{line}.%
+% The following gives examples of differing insets of arrowheads
+\arrowhead{4pt}{6pt}{0pt}%
+\anodeconnect{a}{d}%
+\arrowhead{4pt}{6pt}{1pt}%
+\anodeconnect{b}{e}%
+\arrowhead{4pt}{6pt}{3pt}%
+\anodeconnect{c}{f}%
+
+% the following gives examples of differing lengths
+% and widths of the arrowhead
+\arrowhead{4pt}{6pt}{2pt}%
+\anodeconnect[t]{d}[b]{a}%
+\arrowhead{4pt}{8pt}{2pt}%
+\anodeconnect[t]{e}[b]{b}%
+\arrowhead{2pt}{6pt}{2pt}%
+\anodeconnect[t]{f}[b]{c}%
+
+\end{center}
+\begin{verbatim}
+\node{a}{This} \node{b}{is} a \node{c}{line}.\\[5ex]
+\node{d}{This} \node{e}{is} a \node{f}{line}.%
+% The arrows pointing down give examples of differing insets of arrowheads
+\arrowhead{4pt}{6pt}{0pt}%
+\anodeconnect{a}{d}%
+\arrowhead{4pt}{6pt}{1pt}%
+\anodeconnect{b}{e}%
+\arrowhead{4pt}{6pt}{3pt}%
+\anodeconnect{c}{f}%
+
+% the arrows pointing up give examples of differing lengths
+% and widths of the arrowheads.
+\arrowhead{4pt}{6pt}{2pt}%
+\anodeconnect[t]{d}[b]{a}%
+\arrowhead{4pt}{8pt}{2pt}%
+\anodeconnect[t]{e}[b]{b}%
+\arrowhead{2pt}{6pt}{2pt}%
+\anodeconnect[t]{f}[b]{c}%
+\end{verbatim}
+
+\section{How to Run}
+
+Add the style file, tree-dvips.sty,
+\begin{verbatim}
+\documentstyle[tree-dvips]{article}
+\end{verbatim}
+Run through \LaTeX\ and send to a postscript printer using dvips
+(written by Tomas Rokicki).
+
+
+\section{Examples}
+
+A series of examples follow.
+\begin{center}
+\let\mc=\multicolumn
+\begin{tabular}[t]{@{}lllllllll@{}}
+ & & & &\node{a}{VP} \\[2ex]
+ &\node{b}{PP}
+ & & & & &\mc{2}{c}{\node{c}{V$'$}}\\[2ex]
+ & & &\node{d}{NP} \\[2ex]
+ & &\nodepoint{e}
+ & &\node{f}{NP} \\
+ & & &\hfill\nodepoint{r}[0pt][3pt] \\
+ &\hfil\node{g}{AP}
+ & &\hfil\node{h}{NP}
+ & & & &\hfil\node{i}{NP}\\[2ex]
+\node{j}{P}
+ &\hfil\node{k}{A}
+ & \node{l}{Prt}
+ &\hfil\node{m}{N}
+ &\node{n}{Prt}
+ &\node{o}{N}
+ &\node{p}{V}
+ &\hfil\node{q}{N}\\[2ex]
+`zaw &`oN &`geq&?njiaw&`geq&`dou& khe &tshjaN \\
+toward &red & & bird & &head& open&gun \\[1ex]
+\mc{9}{@{}l}{`shoot at the red head of the bird'} \\
+\end{tabular}
+\nodeconnect{a}{b}
+\nodeconnect{a}{c}
+\nodeconnect{b}{d}
+\nodeconnect{b}{j}
+\nodeconnect{c}{p}
+\nodeconnect{c}{i}
+\nodeconnect{d}{e}
+\nodeconnect{e}{g}
+\nodeconnect{e}{l}
+\nodeconnect{d}{f}
+\nodeconnect{g}{k}
+\nodeconnect{f}{r}
+\nodeconnect{r}{h}
+\nodeconnect{r}{n}
+\nodeconnect{f}{o}
+\nodeconnect{h}{m}
+\nodeconnect{i}{q}
+
+\end{center}
+\begin{verbatim}
+\let\mc=\multicolumn
+\begin{tabular}[t]{@{}lllllllll@{}}
+ & & & &\node{a}{VP} \\[2ex]
+ &\node{b}{PP}
+ & & & & &\mc{2}{c}{\node{c}{V$'$}}\\[2ex]
+ & & &\node{d}{NP} \\[2ex]
+ & &\nodepoint{e}
+ & &\node{f}{NP} \\
+ & & &\hfill\nodepoint{r}[0pt][3pt] \\
+ &\hfil\node{g}{AP}
+ & &\hfil\node{h}{NP}
+ & & & &\hfil\node{i}{NP}\\[2ex]
+\node{j}{P}
+ &\hfil\node{k}{A}
+ & \node{l}{Prt}
+ &\hfil\node{m}{N}
+ &\node{n}{Prt}
+ &\node{o}{N}
+ &\node{p}{V}
+ &\hfil\node{q}{N}\\[2ex]
+`zaw&`oN &`geq&?njiaw&`geq&`dou& khe &tshjaN \\
+toward &red & & bird & &head& open&gun \\[1ex]
+\mc{9}{@{}l}{`shoot at the red head of the bird'} \\
+\end{tabular}
+\nodeconnect{a}{b} \nodeconnect{e}{l}
+\nodeconnect{a}{c} \nodeconnect{d}{f}
+\nodeconnect{b}{d} \nodeconnect{g}{k}
+\nodeconnect{b}{j} \nodeconnect{f}{r}
+\nodeconnect{c}{p} \nodeconnect{r}{h}
+\nodeconnect{c}{i} \nodeconnect{r}{n}
+\nodeconnect{d}{e} \nodeconnect{f}{o}
+\nodeconnect{e}{g} \nodeconnect{h}{m}
+\nodeconnect{i}{q}
+\end{verbatim}
+ The following two examples use \verb+\outerfs+ and
+\verb+\modsmalltree+; these are both part of the lingmacros package.
+See \verb+lingmacros.sty+ for more information.
+ \enumsentence[(100)]{\evnup[2pt]
+{\outerfs{ Focus & \outerfs{subj & \outerfs{\ \nodepoint{a}\ }\\[1ex]
+ obl$_{th}$ & \outerfs{Pred & `Pro'\\
+ Refl & +}\\[1ex]
+ Pred & `proud$\langle(\uparrow {\rm subj})
+ (\uparrow {\rm obl}_{th})\rangle$'}\nodepoint{d}[-3pt][0pt]\\[2ex]
+ Subj & \outerfs{Pred & `Max'}\\[1ex]
+ Comp & \outerfs{Subj &\outerfs{Pred & `Larry'}\nodepoint{c}[-3pt][0pt]\\[1ex]
+ Xcomp&\outerfs{\ \nodepoint{b}\ }\\[1ex]
+ Pred & `be$\langle(\uparrow {\rm xcomp})
+ (\uparrow {\rm subj})\rangle$'}\\[1ex]
+ Pred & `think$\langle(\uparrow {\rm subj})
+ (\uparrow {\rm comp})\rangle$'}\\
+}
+\nodecurve[r]{a}[r]{c}{2in}[.5in]
+\anodecurve[r]{d}[r]{b}{1in}[2in]
+}
+\begin{verbatim}
+\enumsentence[(100)]{\evnup[2pt]
+{\outerfs{
+Focus & \outerfs{subj & \outerfs{\ \nodepoint{a}\ }\\[1ex]
+ obl$_{th}$ & \outerfs{Pred & `Pro'\\
+ Refl & +}\\[1ex]
+ Pred & `proud$\langle(\uparrow {\rm subj})
+ (\uparrow {\rm obl}_{th})\rangle$'}%
+\nodepoint{d}[-3pt][0pt]\\[2ex]
+Subj & \outerfs{Pred & `Max'}\\[1ex]
+Comp & \outerfs{Subj &\outerfs{Pred & `Larry'}%
+\nodepoint{c}[-3pt][0pt]\\[1ex]
+ Xcomp&\outerfs{\ \nodepoint{b}\ }\\[1ex]
+ Pred & `be$\langle(\uparrow {\rm xcomp})
+ (\uparrow {\rm subj})\rangle$'}\\[1ex]
+Pred & `think$\langle(\uparrow {\rm subj})
+ (\uparrow {\rm comp})\rangle$'}\\
+}
+\nodecurve[r]{a}[r]{c}{2in}[.5in]
+\anodecurve[r]{d}[r]{b}{1in}[2in]
+}
+\end{verbatim}
+\enumsentence{\modsmalltree{6}{
+ & & &\ns\node{a}{\begin{tabular}[t]{@{}c@{}}S\\
+ {}[+R]\end{tabular}} \\
+ &\node{b}{NP} & & & & \node{c}{VP} \\
+\node{d}{Det}& &\node{e}{N$^1$} \\
+\node{h}{the}&\node{i}{N} & & \node{f}{PP} &&\node{g}{are
+ totally false}\\
+ &\node{n}{rumors}&\node{j}{P} &&\ns\node{k}{\begin{tabular}[t]{@{}c@{}}NP\\
+ {}[+R] \end{tabular}}\\
+ & &\node{l}{about} &&\node{m}{whom}}
+\nodeconnect{a}{b}
+\nodeconnect{a}{c}
+\nodeconnect{b}{d}
+\nodeconnect{b}{e}
+\nodeconnect{d}{h}
+\nodeconnect{e}{i}
+\nodeconnect{e}{f}
+\nodeconnect{i}{n}
+\nodeconnect{f}{j}
+\nodeconnect{f}{k}
+\nodeconnect{j}{l}
+\nodeconnect{k}{m}
+\nodetriangle{c}{g}
+{\makedash{4pt}
+\anodecurve[t]{b}[l]{a}{10pt}
+\anodecurve[t]{e}[r]{b}{10pt}
+\anodecurve[t]{f}[r]{e}{10pt}
+\anodecurve[t]{k}[r]{f}{10pt}
+}}
+\begin{verbatim}
+\enumsentence{\modsmalltree{6}{
+ & & &\ns\node{a}{\begin{tabular}[t]{@{}c@{}}S\\
+ {}[+R]\end{tabular}} \\
+ &\node{b}{NP}
+ & & && \node{c}{VP} \\
+\node{d}{Det}
+ & &\node{e}{N$^1$} \\
+\node{h}{the}
+ &\node{i}{N}
+ & &\node{f}{PP}
+ &&\node{g}{are totally false}\\
+ &\node{n}{rumors}
+ &\node{j}{P}
+ & &\ns\node{k}{\begin{tabular}[t]{@{}c@{}}NP\\
+ {}[+R] \end{tabular}}\\
+ & &\node{l}{about}
+ & &\node{m}{whom}}
+\nodeconnect{a}{b} \nodeconnect{e}{f}
+\nodeconnect{a}{c} \nodeconnect{i}{n}
+\nodeconnect{b}{d} \nodeconnect{f}{j}
+\nodeconnect{b}{e} \nodeconnect{f}{k}
+\nodeconnect{d}{h} \nodeconnect{j}{l}
+\nodeconnect{e}{i} \nodeconnect{k}{m}
+\nodetriangle{c}{g}
+{\makedash{4pt}
+\anodecurve[t]{b}[l]{a}{10pt} \anodecurve[t]{f}[r]{e}{10pt}
+\anodecurve[t]{e}[r]{b}{10pt} \anodecurve[t]{k}[r]{f}{10pt}
+}}
+\end{verbatim}
+
+\section{Rotation}
+
+With the {\tt rotate.sty} file one can also rotate figures. This is
+useful with wide figures that won't fit on within the page boundaries
+unless turned sideways. Earlier versions of the tree macros didn't
+work with this.
+
+\rotate[l]{\modsmalltree{3}{&\node{a}{top}\\
+\node{b}{left} && \node{c}{right}}
+\nodeconnect{a}{b}
+\nodeconnect{a}{c}
+}
+
+\begin{verbatim}
+\rotate[l]{\modsmalltree{3}{&\node{a}{top}\\
+\node{b}{left} && \node{c}{right}}
+\nodeconnect{a}{b}
+\nodeconnect{a}{c}
+}
+\end{verbatim}
+
+Note that the connection commands are within the boundaries of the
+\verb+\rotate+ command.
+
+\section{Errors}
+
+A multitude of caveats.
+\begin{itemize}
+ \item Any commands calling nodes must be read while \TeX\ is still
+processing the page the nodes are defined on. In other words don't
+define the nodes on page 1 and connect them with commands that appear
+at the end of the paper.
+
+\item Nodes mentioned in node connecting commands must exist or else
+ the job won't print.
+
+\item Make sure the dvips postscript output is sent to a postscript
+printer. It is possible to send the dvi, but not the postscript,
+output to another printer; the lines just won't appear, assuming the
+printer ignores specials it doesn't know about.
+
+
+\end{itemize}
+
+\section{Thanks}
+
+Thanks to all those who've helped me over the years, including Avery
+Andrews who revamped the arrows for me and Gintas Grigelionis who
+suggested how to finally get the rotation to work correctly.
+
+
+\end{document}
+
+
diff --git a/macros/latex209/contrib/trees/tree_tex/Makefile b/macros/latex209/contrib/trees/tree_tex/Makefile
new file mode 100644
index 0000000000..83a60bb15a
--- /dev/null
+++ b/macros/latex209/contrib/trees/tree_tex/Makefile
@@ -0,0 +1,70 @@
+#Author: Anthony Bloesch
+#Title: generate.c
+#
+#Copyright (C) Anthony Bloesch 1993
+#
+#Version: 1.0
+#
+#Usage:
+# make
+#
+# also
+#
+# make lint
+# make clean
+# make shar
+# make test
+
+#Debugging
+#DEBUG=-g
+#OPTIMIZATION=
+
+#Production
+DEBUG=
+OPTIMIZATION=-fast
+
+CC=/usr/lang/acc
+LATEX=/usr/local/tex/latex
+LINT=/usr/lang/alint
+SHAR=/usr/local/shar/shar
+
+COMPILE=${CC} ${DEBUG} -c -vc -Xc ${OPTIMIZATION}
+LINK=${CC} ${DEBUG}
+
+SOURCE1=Makefile layout.c layout.h treetex.c
+SOURCE2=README treetex.1 test1.tex test2.tex treetex.sty
+SOURCE=${SOURCE1} ${SOURCE2}
+
+all: treetex
+
+treetex: Makefile treetex.o layout.o
+ ${LINK} -o treetex treetex.o layout.o
+
+treetex.o: Makefile treetex.c layout.h
+ ${COMPILE} -o treetex.o treetex.c
+
+layout.o: Makefile layout.c layout.h
+ ${COMPILE} -o layout.o layout.c
+
+# Utilities
+
+clean:
+ rm -f *.o *.tli *.tlo *.dvi *.aux *.log *.plg *.shar? *~ treetex
+
+lint:
+ ${LINT} treetex.c layout.c
+
+shar:
+ ${SHAR} -n1 -e2 ${SOURCE1} >treetex.shar1
+ ${SHAR} -n2 -e2 ${SOURCE2} >treetex.shar2
+
+test: treetex
+ ${LATEX} test1.tex
+ ./treetex testtreea
+ ./treetex testtreeb
+ ./treetex testtreec
+ ${LATEX} test1.tex
+ ${LATEX} test2.tex
+ ./treetex testtreed
+ ./treetex testtreee
+ ${LATEX} test2.tex
diff --git a/macros/latex209/contrib/trees/tree_tex/README b/macros/latex209/contrib/trees/tree_tex/README
new file mode 100644
index 0000000000..9adb66044f
--- /dev/null
+++ b/macros/latex209/contrib/trees/tree_tex/README
@@ -0,0 +1,58 @@
+Author: Anthony Bloesch
+Title: README
+
+Copyright (C) Anthony Bloesch 1993
+
+Version: 1.0
+
+The treetex software performs automatic layout of n-ary trees, with
+arbitrary sized nodes, in LaTeX. To use the software you describe the
+tree in a tree environment. For example:
+
+ \begin{tree}[l]{testtreea}
+ \rootnode{root node}
+ \treenode{nodeA}{root}{left root child}
+ \treenode{nodeB}{root}{right root child}
+ \treenode{nodeC}{nodeA}{nodeA child}
+ \end{tree}
+
+will be layed out something like:
+
+ root node
+ |
+ -------------------
+ | |
+ left root child right root child
+ |
+ nodeA child
+
+Also trees can be layed out sideways. The software is fully described
+in the file `treetex.sty'. To make the software edit the makefile to
+set up the macros correctly and then type:
+
+ make
+
+to test it, type:
+
+ make test
+
+Bug reports and questions can be directed, by email, to me at
+`anthonyb@cs.uq.oz.au.' and by ordinary post to:
+
+ Anthony Bloesch
+ University of Queensland
+ St Lucia, 4072
+ Australia
+
+And last but not least the dreaded disclaimer:
+
+ This software is distributed in the hope that it will prove useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+You may however do anything you want to the software provided you keep
+the copyright notices and the above disclaimer, and make it clear that
+the software has been altered.
+
+
+ Anthony
diff --git a/macros/latex209/contrib/trees/tree_tex/layout.c b/macros/latex209/contrib/trees/tree_tex/layout.c
new file mode 100644
index 0000000000..3d1c051a24
--- /dev/null
+++ b/macros/latex209/contrib/trees/tree_tex/layout.c
@@ -0,0 +1,382 @@
+/*
+Author: Anthony Bloesch
+Title: layout.c
+
+Copyright (C) Anthony Bloesch 1991
+
+Purpose: Allow n-ary trees with arbitrary nodes to be aestheticaly
+ layed out.
+*/
+
+#include "layout.h"
+#include <stddef.h>
+#include <stdlib.h>
+
+typedef struct edge {
+/* The outline of a tree.
+ INV: all i in [yPosition, last(offset)] * Valid(offset[i])
+*/
+
+ unsigned yPosition; /* The first value of <offset> that is valid. */
+ int offset[1]; /* Variable sized array */
+} edge;
+
+static
+edge *newEdge(unsigned height)
+/* Return a new tree outline of height <height>.
+
+ Pre:
+ Post:
+*/
+
+{
+ edge *result;
+
+ result = (edge *)malloc((size_t)(sizeof(edge)+
+ height*sizeof(int)-sizeof(int)));
+
+ if ((edge *)NULL != result)
+ result->yPosition = height;
+
+ return result;
+
+} /* newEdge */
+
+int addBranch(Tree branch,
+ TreeNode *node)
+{
+ TreeNode **newBranch;
+
+ node->nrBranches++;
+
+ if ((Tree *)NULL == node->branches) /* No existing branches. */
+ node->branches = (TreeNode **)malloc(
+ (size_t)(node->nrBranches*sizeof(TreeNode *)));
+
+ else { /* Existing branches. */
+ newBranch = (TreeNode **)realloc(node->branches,
+ (size_t)(node->nrBranches*sizeof(TreeNode *)));
+
+ if (newBranch != node->branches)
+ (void)free(node->branches);
+
+ else
+ node->branches = newBranch;
+ } /* if */
+
+ if ((Tree *)NULL != node->branches)
+ node->branches[node->nrBranches-1] = branch;
+
+ return (Tree *)NULL != node->branches;
+
+} /* addBranch */
+
+void deleteNode(TreeNode *node)
+{
+ if ((Tree)NULL != node) {
+ (void)free((char *)node->name);
+ (void)free((char *)node->parent);
+ (void)free((char *)node->branches);
+ (void)free((char *)node);
+ } /* if */
+} /* deleteNode */
+
+void deleteTree(Tree tree)
+{
+ postorderTraverse(tree, deleteNode);
+
+} /* deleteTree */
+
+Tree newTree(char *nodeName,
+ char *parentName,
+ unsigned height,
+ unsigned width,
+ unsigned depth)
+{
+ Tree result;
+
+ result = (Tree)malloc(sizeof(TreeNode));
+
+ if (NULL != result) {
+ result->name = nodeName;
+ result->parent = parentName;
+ result->height = height;
+ result->width = width;
+ result->depth = depth;
+ result->x = 0;
+ result->y = 0;
+ result->nrBranches = 0;
+ result->branches = (Tree *)NULL;
+ } /* if */
+
+ return result;
+} /* newTree */
+
+void inorderTraverse(Tree tree,
+ NodeFunction *nodeFunction)
+{
+ unsigned i;
+
+ if ((Tree)NULL != tree) {
+ for(i = 0; i < tree->nrBranches; i++) {
+ postorderTraverse(tree->branches[i], nodeFunction);
+ nodeFunction(tree);
+ } /* for */
+ } /* if */
+} /* inorderTraverse */
+
+void postorderTraverse(Tree tree,
+ NodeFunction *nodeFunction)
+{
+ unsigned i;
+
+ if (tree != NULL) {
+ for(i = 0; i < tree->nrBranches; i++)
+ postorderTraverse(tree->branches[i], nodeFunction);
+
+ nodeFunction(tree);
+ } /* if */
+} /* postorderTraverse */
+
+void preorderTraverse(Tree tree,
+ NodeFunction *nodeFunction)
+{
+ unsigned i;
+
+ if(tree != (Tree)NULL) {
+ nodeFunction(tree);
+
+ for(i = 0; i < tree->nrBranches; i++)
+ preorderTraverse(tree->branches[i], nodeFunction);
+ } /* if */
+} /* preorderTraverse */
+
+static
+int intMax(int x,
+ int y)
+/* Return the maximun of <x> and <y>.
+
+ Pre:
+ Post: intMax' = max(x, y)
+*/
+{
+ if (x > y)
+ return x;
+
+ else
+ return y;
+
+} /* intMax */
+
+static
+int intMin(int x,
+ int y)
+/* Return the maximun of <x> and <y>.
+
+ Pre:
+ Post: intMax' = max(x, y)
+*/
+{
+ if (x < y)
+ return x;
+
+ else
+ return y;
+
+} /* intMin */
+
+static
+unsigned unsignedMax(unsigned x,
+ unsigned y)
+/* Return the maximun of <x> and <y>.
+
+ Pre:
+ Post: unsignedMax' = max(x, y)
+*/
+{
+ if (x > y)
+ return x;
+
+ else
+ return y;
+
+} /* unsignedMax */
+
+static
+unsigned unsignedMin(unsigned x,
+ unsigned y)
+/* Return the maximun of <x> and <y>.
+
+ Pre:
+ Post: unsignedMax' = max(x, y)
+*/
+{
+ if (x < y)
+ return x;
+
+ else
+ return y;
+
+} /* unsignedMin */
+
+static
+void doShapeTree(
+ Tree tree,
+ unsigned height,
+ unsigned yPosition,
+ edge **left,
+ edge **right,
+ unsigned xSeparation,
+ unsigned ySeparation)
+/* Aestheticaly layout <tree> using Bloesch's SPE algorithm. Assume the
+ tree has height <height> in rasters its top edge is at <yPosition> and
+ the x & y node separations are to be <xSeparation> and <ySeparation>.
+ Return the left and right outlines of the layed out tree in <left> and
+ <right>.
+
+ Pre: tree != NULL &
+ height(tree) = height
+ Post: leftOutline(tree) = left &
+ rightOutline(tree) = right
+*/
+{
+ int centre; /* The x position of the root node. */
+ unsigned i;
+ unsigned j;
+ edge **leftOutline; /* The left outlines of the subbranches */
+ int overlap; /* The amount of overlap between two branches. */
+ edge **rightOutline; /* The right outlines of the subbranches */
+
+ if (tree->nrBranches == 0) { /* No children. */
+ *left = newEdge(height);
+ *right = newEdge(height);
+ (*left)->yPosition = yPosition+tree->height-1;
+ (*right)->yPosition = yPosition+tree->height-1; }
+
+ else { /* Children. */
+ leftOutline = (edge **)malloc((size_t)(tree->nrBranches*sizeof(edge *)));
+ rightOutline = (edge **)malloc((size_t)(tree->nrBranches*sizeof(edge *)));
+
+ for (i = 0; i < tree->nrBranches; i++)
+ doShapeTree(tree->branches[i], height,
+ (int)(yPosition+tree->height+ySeparation),
+ &leftOutline[i], &rightOutline[i],
+ xSeparation, ySeparation);
+
+ /* Set up left and right. */
+ *left = leftOutline[0];
+ *right = rightOutline[0];
+
+ /* Position branches relative to the left branch. */
+ tree->branches[0]->x = 0;
+ for (i = 0; i < tree->nrBranches - 1; i++) {
+ /* Calculate maximum overlap. */
+ overlap = 0;
+ for (j = yPosition+tree->height+ySeparation;
+ j <= intMin(leftOutline[i+1]->yPosition, (*right)->yPosition);
+ j++)
+ overlap = intMax(overlap, leftOutline[i+1]->offset[j] +
+ (*right)->offset[j]);
+
+ /* Push branches apart. */
+ tree->branches[i+1]->x = overlap+xSeparation;
+
+ /* Adjust left outline. */
+ for (j = (*left)->yPosition+1; j <= leftOutline[i+1]->yPosition; j++)
+ (*left)->offset[j] = leftOutline[i+1]->offset[j] -
+ tree->branches[i+1]->x;
+ (*left)->yPosition = unsignedMax((*left)->yPosition,
+ leftOutline[i+1]->yPosition);
+
+ /* Adjust right outline */
+ for (j = yPosition; j <= rightOutline[i+1]->yPosition; j++)
+ (*right)->offset[j] = rightOutline[i+1]->offset[j] +
+ tree->branches[i+1]->x;
+ (*right)->yPosition = unsignedMax((*right)->yPosition,
+ rightOutline[i+1]->yPosition);
+ } /* for */
+
+ if (tree->nrBranches > 1) {
+ /* Position branches relative to the centre. */
+ centre = tree->branches[tree->nrBranches-1]->x/2;
+
+ for (i = 0; i < tree->nrBranches; i++)
+ tree->branches[i]->x -= centre;
+
+ for (i = yPosition; i <= (*left)->yPosition; i++)
+ (*left)->offset[i] += centre;
+
+ for (i = yPosition; i <= (*right)->yPosition; i++)
+ (*right)->offset[i] -= centre;
+ } /* if */
+
+ /* Free the old outlines. */
+ for (i = 1; i < tree->nrBranches; i++) {
+ (void)free((char *)leftOutline[i]);
+ (void)free((char *)rightOutline[i]);
+ } /* for */
+ } /* if */
+
+ /* Add node to tree outline. */
+ for (i = yPosition - ySeparation; i < yPosition+tree->height; i++) {
+ (*left)->offset[i] = tree->width/2;
+ (*right)->offset[i] = (tree->width+1)/2;
+ } /* for */
+
+ tree->y = yPosition;
+
+} /* doShapeTree */
+
+static
+int treeHeight(Tree tree,
+ unsigned ySeparation)
+/* Return the height of <tree> assuming the y separation is <ySeparation>.
+
+ Pre:
+ Post:
+*/
+{
+ unsigned height = 0;
+ unsigned i;
+ unsigned newHeight;
+
+ if (tree != (Tree)NULL) {
+ for (i = 0; i < tree->nrBranches; i++) {
+ newHeight = treeHeight(tree->branches[i], ySeparation);
+ if (newHeight > height)
+ height = newHeight;
+ } /* for */
+ height += ySeparation+tree->height;
+ } /* if */
+
+ return height;
+
+} /* treeHeight */
+
+void shapeTree(Tree tree,
+ unsigned *height,
+ unsigned *leftWidth,
+ unsigned *rightWidth,
+ unsigned xSeparation,
+ unsigned ySeparation)
+{
+ unsigned i;
+ edge *left; /* Left outline of tree. */
+ edge *right; /* Right outline of tree. */
+
+ *height = treeHeight(tree, ySeparation);
+
+ doShapeTree(tree, *height, ySeparation, &left, &right,
+ xSeparation, ySeparation);
+
+ *leftWidth = 0;
+ *rightWidth = 0;
+ for (i = 0; i < *height; i++) {
+ *leftWidth = (unsigned)intMax((int)*leftWidth, left->offset[i]);
+ *rightWidth = (unsigned)intMax((int)*rightWidth, right->offset[i]);
+ } /* for */
+
+ (void)free((char *)left);
+ (void)free((char *)right);
+
+} /* shapeTree */
diff --git a/macros/latex209/contrib/trees/tree_tex/layout.h b/macros/latex209/contrib/trees/tree_tex/layout.h
new file mode 100644
index 0000000000..3efdc10347
--- /dev/null
+++ b/macros/latex209/contrib/trees/tree_tex/layout.h
@@ -0,0 +1,77 @@
+/*
+Author: Anthony Bloesch
+Title: layout.h
+
+Copyright (C) Anthony Bloesch 1991
+
+Purpose: Allow n-ary trees with arbitrary nodes to be aestheticaly
+ layed out.
+*/
+
+#ifndef _LAYOUT_H
+#define _LAYOUT_H
+
+typedef struct TreeNode {
+ char *name;
+ char *parent;
+ unsigned height;
+ unsigned width;
+ unsigned depth;
+ int x;
+ int y;
+ unsigned nrBranches;
+ struct TreeNode **branches;} TreeNode;
+typedef TreeNode *Tree;
+typedef void NodeFunction(TreeNode *node);
+
+extern
+int addBranch(Tree branch,
+ TreeNode *node);
+
+extern
+void deleteNode(TreeNode *node);
+
+extern
+void deleteTree(Tree tree);
+/* Recursively deallocate the storage used by tree.
+
+ Pre: Valid(tree)
+ Post: Invalid(tree)
+*/
+
+extern
+Tree newTree(char *nodeName,
+ char *parentName,
+ unsigned height,
+ unsigned width,
+ unsigned depth);
+/* Return a new tree initialized to the specified height and width with the
+ branches initialized to NULL.
+
+ Pre:
+ Post: newTree'->height = height &
+ newTree'->width = width &
+ All i 0<=i<NR_BRANCHES -> newTree'->branches[i]
+*/
+
+extern
+void shapeTree(Tree tree,
+ unsigned *height,
+ unsigned *leftWidth,
+ unsigned *rightWidth,
+ unsigned xSeparation,
+ unsigned ySeparation);
+
+extern
+void inorderTraverse(Tree tree,
+ NodeFunction *nodeFunction);
+
+extern
+void postorderTraverse(Tree tree,
+ NodeFunction *nodeFunction);
+
+extern
+void preorderTraverse(Tree tree,
+ NodeFunction *nodeFunction);
+
+#endif /* _LAYOUT_H */
diff --git a/macros/latex209/contrib/trees/tree_tex/test1.tex b/macros/latex209/contrib/trees/tree_tex/test1.tex
new file mode 100644
index 0000000000..c2ba181bda
--- /dev/null
+++ b/macros/latex209/contrib/trees/tree_tex/test1.tex
@@ -0,0 +1,44 @@
+%Author: Anthony Bloesch
+%Title: test1.tex
+%
+%Copyright (C) Anthony Bloesch 1993
+
+\documentstyle[treetex]{article}
+
+\begin{document}
+\begin{center}
+\begin{tree}{testtreea}
+ \rootnode{root node}
+ \treenode{nodeA}{root}{left root child}
+ \treenode{nodeB}{root}{right root child}
+ \treenode{nodeC}{nodeB}{nodeB child 1}
+ \treenode{nodeD}{nodeA}{nodeA child 1}
+ \treenode{nodeE}{nodeA}{nodeA child 2}
+ \treenode{nodeF}{nodeA}{nodeA child 3}
+\end{tree}
+\end{center}
+
+\begin{center}
+\begin{tree}[t]{testtreeb}
+ \rootnode{root node}
+ \treenode{nodeA}{root}{left root child}
+ \treenode{nodeB}{root}{right root child}
+ \treenode{nodeC}{nodeB}{nodeB child 1}
+ \treenode{nodeD}{nodeA}{nodeA child 1}
+ \treenode{nodeE}{nodeA}{nodeA child 2}
+ \treenode{nodeF}{nodeA}{nodeA child 3}
+\end{tree}
+\end{center}
+
+\begin{center}
+\begin{tree}[l]{testtreec}
+ \rootnode{root node}
+ \treenode{nodeA}{root}{left root child}
+ \treenode{nodeB}{root}{right root child}
+ \treenode{nodeC}{nodeB}{nodeB child 1}
+ \treenode{nodeD}{nodeA}{nodeA child 1}
+ \treenode{nodeE}{nodeA}{nodeA child 2}
+ \treenode{nodeF}{nodeA}{nodeA child 3}
+\end{tree}
+\end{center}
+\end{document}
diff --git a/macros/latex209/contrib/trees/tree_tex/test2.tex b/macros/latex209/contrib/trees/tree_tex/test2.tex
new file mode 100644
index 0000000000..b685d8e9a4
--- /dev/null
+++ b/macros/latex209/contrib/trees/tree_tex/test2.tex
@@ -0,0 +1,72 @@
+%Author: Anthony Bloesch
+%Title: test2.tex
+%
+%Copyright (C) Anthony Bloesch 1993
+
+\documentstyle[treetex]{article}
+
+\newcommand{\closed}{\times}
+\newcommand{\justfalse}{\mathord{\strutrule{12pt}\overline{\truesign}}}
+\newcommand{\justtrue}{\mathord{\strutrule{12pt}\overline{\falsesign}}}
+\renewcommand{\land}{{\mathrel\wedge}}
+\newcommand{\pred}[1]{\mathord{\mbox{\rm #1}}}
+\newcommand{\strutrule}[1]{\protect\rule{0cm}{#1}}
+\newcommand{\truesign}{\mbox{\bf T}}
+
+\begin{document}
+\begin{center}
+\begin{tree}{testtreed}
+ \rootnode{\shortstack[l]{$\truesign\;\pred{P}$\\
+ $\truesign\;\pred{Q}$\\
+ $\justfalse\;\pred{P}\land\pred{Q}$}}
+ \treenode{nodeA}{root}{\shortstack{\shortstack[l]{$\justfalse\;\pred{P}$\\
+ $\justfalse\;\pred{P}\land\pred{Q}$\\
+ $\justfalse\;\pred{Q}\land\pred{Q}$\\
+ $\justfalse\;\pred{P}\land\pred{R}$\\
+ $\truesign\;\pred{P}\land\pred{Q}$\\
+ $\truesign\;\pred{Q}$}\\
+ $\closed$}}
+ \treenode{nodeB}{root}{\shortstack[l]{$\justfalse\;\pred{Q}$\\
+ $\justfalse\;\pred{Q}\land\pred{Q}$}}
+ \treenode{nodeC}{nodeB}{\shortstack{\shortstack[l]{$\justfalse\;\pred{Q}$\\
+ $\truesign\;\pred{P}$\\
+ $\truesign\;\pred{Q}$\\
+ $\justfalse\;\pred{P}\land\pred{Q}$}\\
+ $\closed$}}
+ \treenode{nodeD}{nodeB}{\shortstack{\shortstack[l]{$\justfalse\;\pred{Q}$\\
+ $\justfalse\;\pred{Q}$\\
+ $\truesign\;\pred{P}$\\
+ $\truesign\;\pred{Q}$\\
+ $\justfalse\;\pred{P}\land\pred{Q}$}\\
+ $\closed$}}
+\end{tree}
+\end{center}
+
+\begin{center}
+\begin{tree}[l]{testtreee}
+ \rootnode{\shortstack[l]{$\truesign\;\pred{P}$\\
+ $\truesign\;\pred{Q}$\\
+ $\justfalse\;\pred{P}\land\pred{Q}$}}
+ \treenode{nodeA}{root}{\shortstack{\shortstack[l]{$\justfalse\;\pred{P}$\\
+ $\justfalse\;\pred{P}\land\pred{Q}$\\
+ $\justfalse\;\pred{Q}\land\pred{Q}$\\
+ $\justfalse\;\pred{P}\land\pred{R}$\\
+ $\truesign\;\pred{P}\land\pred{Q}$\\
+ $\truesign\;\pred{Q}$}\\
+ $\closed$}}
+ \treenode{nodeB}{root}{\shortstack[l]{$\justfalse\;\pred{Q}$\\
+ $\justfalse\;\pred{Q}\land\pred{Q}$}}
+ \treenode{nodeC}{nodeB}{\shortstack{\shortstack[l]{$\justfalse\;\pred{Q}$\\
+ $\truesign\;\pred{P}$\\
+ $\truesign\;\pred{Q}$\\
+ $\justfalse\;\pred{P}\land\pred{Q}$}\\
+ $\closed$}}
+ \treenode{nodeD}{nodeB}{\shortstack{\shortstack[l]{$\justfalse\;\pred{Q}$\\
+ $\justfalse\;\pred{Q}$\\
+ $\truesign\;\pred{P}$\\
+ $\truesign\;\pred{Q}$\\
+ $\justfalse\;\pred{P}\land\pred{Q}$}\\
+ $\closed$}}
+\end{tree}
+\end{center}
+\end{document}
diff --git a/macros/latex209/contrib/trees/tree_tex/treetex.c b/macros/latex209/contrib/trees/tree_tex/treetex.c
new file mode 100644
index 0000000000..6b59d4e08c
--- /dev/null
+++ b/macros/latex209/contrib/trees/tree_tex/treetex.c
@@ -0,0 +1,529 @@
+/*
+Author: Anthony Bloesch
+Title: generate.c
+
+Copyright (C) Anthony Bloesch 1993
+
+Version: 1.0
+
+Purpose: Take a .tlo file generated by treetex.sty and generate the
+ corresponding .tli file. That is, an aesthetic layout of the
+ tree specified in the .tlo file.
+
+ A .tlo is expected to be of the form:
+
+ TLO <- ROOT_POS
+ (ROOT_SPEC | NODE_SPEC) {ROOT_SPEC | NODE_SPEC}
+ ROOT_POS <- t|l
+ ROOT_SPEC <- NODE_NAME
+ WIDTH HEIGHT
+ NODE_SPEC <- NODE_NAME PARENT_NAME
+ WIDTH HEIGHT DEPTH
+ NODE_NAME <- NAME
+ PARENT_NAME <- NAME
+ WIDTH <- PT_SIZE
+ HEIGHT <- PT_SIZE
+ DEPTH <- PT_SIZE
+ NAME <- LETTER{LETTER}
+ LETTER <- A|B|...|Z|a|b|...|z
+ PT_SIZE <- NUMBER[.[NUMBER]]pt
+ NUMBER <- DIGIT{DIGIT}
+ DIGIT <- 0|1|...|9
+
+ For example:
+
+ t
+ 10.0pt 10.0pt
+ root
+ 42.2501pt 6.94444pt 0.0pt
+ nodeA root
+ 59.75012pt 6.94444pt 0.0pt
+ nodeB root
+ 66.44458pt 6.94444pt 1.94444pt
+ nodeC nodeA
+ 52.5001pt 6.94444pt 0.0pt
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include "layout.h"
+
+#define MAX_NAME_SIZE 100 /* Maximum length of input strings. */
+#define SCALE 1 /* Rasters per printer's pt (pt). */
+
+typedef enum {eTop, eLeft} RootPos; /* Position of the root of a tree. */
+
+static
+TreeNode *findNode(char *name,
+ TreeNode **nodes,
+ unsigned nrNodes);
+/* Return a pointer to the first node named <name> in <nodes> where there
+ are <nrNodes> nodes. If no such node exists return NULL.
+
+ Pre:
+ Post: name in nodes -> findNode'.name = name &
+ name notin nodes -> findNode' = NULL
+*/
+
+static
+void printTree(FILE *outfile,
+ Tree tree,
+ unsigned height,
+ unsigned leftWidth,
+ unsigned rightWidth,
+ RootPos rootPos);
+/* Output <tree> to <outfile> as a LaTeX picture. Assume that the tree
+ is <height> high and has widths <leftWidth>, <rightWidth> centered
+ on the top center of the root node of <tree>. The tree will be layed
+ out so that the root will be at <rootPos> (i.e. rotate it if
+ <rootPos> = eLeft).
+
+ Pre: open(outfile) &
+ tree != NULL
+ Post:
+*/
+
+static
+void readTree(FILE *infile,
+ Tree *tree,
+ double *xSeparation,
+ double *ySeparation,
+ RootPos *rootPos);
+/* Read in the tree <tree> from <infile> and also return the desired
+ x & y seperations <xSeparation> and <ySeparation>, and the desired
+ position of the tree's root <rootPos>.
+
+ Pre: open(infile)
+ Post:
+*/
+
+int main(int argc,
+ char **argv)
+{
+ FILE *infile;
+ char infilename[MAX_NAME_SIZE];
+ FILE *outfile;
+ char outfilename[MAX_NAME_SIZE];
+ RootPos rootPos;
+ Tree tree;
+ unsigned treeHeight;
+ unsigned treeLeftWidth; /* Width to the left of the root node. */
+ unsigned treeRightWidth; /* Width to the right of the root node. */
+ double xSeparation; /* Min x distance between nodes. */
+ double ySeparation; /* Min y distance between nodes. */
+
+ /* Construct filenames adding ".tlo" or ".tli" if necessary. */
+ if (argc == 2 &&
+ (strlen(argv[1]) <= 4 ||
+ strcmp(".tlo", &(argv[1][strlen(argv[1])-4])))) { /* No .tlo suffix. */
+ if (MAX_NAME_SIZE <= strlen(argv[1]) + 5) {
+ (void)fprintf(stderr, "Filename too long.\n");
+
+ exit(1);
+ } /* if */
+
+ (void)strcpy(infilename, argv[1]);
+ (void)strcat(infilename, ".tlo");
+
+ (void)strcpy(outfilename, argv[1]);
+ (void)strcat(outfilename, ".tli"); }
+
+ else { /* Has .tlo suffix. */
+ (void)strcpy(infilename, argv[1]);
+
+ (void)strcpy(outfilename, argv[1]);
+ outfilename[strlen(argv[1])-1] = 'i';
+ } /* if */
+
+ /* Open input file. */
+ if (argc != 2 ||
+ NULL == (infile = fopen(infilename, "r"))) {
+ (void)fprintf(stderr, "Usage: %s filename[.tlo]\n", argv[0]);
+
+ exit(1);
+ } /* if */
+
+ readTree(infile, &tree, &xSeparation, &ySeparation, &rootPos);
+
+ shapeTree(tree, &treeHeight, &treeLeftWidth, &treeRightWidth,
+ (unsigned)xSeparation, (unsigned)ySeparation);
+
+ /* Open output file. */
+ if (NULL == (outfile = fopen(outfilename, "w"))) {
+ (void)fprintf(stderr, "Unable to open %s for writing.\n", outfilename);
+
+ exit(1);
+ } /* if */
+
+ printTree(outfile, tree, treeHeight, treeLeftWidth, treeRightWidth, rootPos);
+
+ deleteTree(tree);
+
+ return 0;
+
+} /* main */
+
+static
+TreeNode *findNode(char *name,
+ TreeNode **nodes,
+ unsigned nrNodes)
+{
+ unsigned i;
+
+ for (i = 0; i < nrNodes; i++)
+ if (!strcmp(name, nodes[i]->name))
+ return nodes[i];
+
+ return NULL;
+
+} /* findNode */
+
+static
+void printNode(FILE *outfile,
+ TreeNode *node,
+ int rootX,
+ RootPos rootPos)
+/* Output <node> to <outfile> as part of a LaTeX picture. Assume that the
+ top of the node is to be centered at <rootX>. Position the node to be
+ consistent with a tree root at <rootPos> (i.e. rotate it if
+ <rootPos> = eLeft).
+
+ Pre: open(outfile) &
+ node != NULL
+ Post:
+*/
+
+{
+ switch (rootPos) {
+ case eTop:
+ (void)fprintf(outfile, " \\put(%d,%d){\\shownode{\\%s}}\n",
+ rootX + node->x - (int)node->width/2,
+ -(node->y + (int)node->height - node->depth),
+ node->name);
+ break;
+
+ case eLeft:
+ (void)fprintf(outfile, " \\put(%d,%d){\\shownode{\\%s}}\n",
+ node->y,
+ rootX + node->x - (int)node->width/2 + node->depth,
+ node->name);
+ break;
+ } /* switch */
+} /* printNode */
+
+static
+void printLine(FILE *outfile,
+ int x,
+ int y,
+ int deltaX,
+ int deltaY,
+ unsigned length,
+ RootPos rootPos)
+/* Print a line from (<x>, <y>) in the direction (<deltaX>, <deltaY>) of
+ length <length>. Position the line to be consistent with a tree root at
+ <rootPos> (i.e. rotate it if <rootPos> = eLeft).
+
+ Pre: deltaX in {-1, 0, 1} &
+ deltaY in {-1, 0, 1}
+ Post:
+*/
+{
+ switch (rootPos) {
+ case eTop:
+ (void)fprintf(outfile, " \\put(%d,%d){\\line(%d,%d){%d}}\n",
+ x, y, deltaX, deltaY, length);
+ break;
+
+ case eLeft:
+ (void)fprintf(outfile, " \\put(%d,%d){\\line(%d,%d){%d}}\n",
+ -y, x, -deltaY, deltaX, length);
+ break;
+ } /* switch */
+} /* printLine */
+
+static
+void doPrintTree(FILE *outfile,
+ Tree tree,
+ int rootX,
+ RootPos rootPos)
+/* Output <tree> to <outfile> as part of a LaTeX picture. Assume that the
+ top of the node is to be centered at <rootX>. Position the tree to be
+ consistent with a tree root at <rootPos> (i.e. rotate it if
+ <rootPos> = eLeft).
+
+ Pre: open(outfile) &
+ tree != NULL
+ Post:
+*/
+{
+ unsigned i;
+
+ printNode(outfile, tree, rootX, rootPos);
+
+ if (tree->nrBranches == 1) { /* Down line. */
+ printLine(outfile,
+ rootX + tree->x,
+ -(tree->y + (int)tree->height),
+ 0, -1,
+ tree->branches[0]->y - (tree->y + (int)tree->height),
+ rootPos);
+
+ doPrintTree(outfile, tree->branches[0], rootX+tree->x, rootPos); }
+
+ else if (tree->nrBranches >= 2) {
+ /* Down line. */
+ printLine(outfile,
+ rootX + tree->x,
+ -(tree->y + (int)tree->height),
+ 0, -1,
+ (tree->branches[0]->y - (tree->y + (int)tree->height))/2,
+ rootPos);
+
+ /* Cross bar */
+ printLine(outfile,
+ rootX + tree->x + tree->branches[0]->x,
+ (tree->y + (int)tree->height + tree->branches[0]->y)/-2,
+ 1, 0,
+ tree->branches[tree->nrBranches-1]->x - tree->branches[0]->x,
+ rootPos);
+
+ /* Subnodes. */
+ for (i = 0; i < tree->nrBranches; i++) {
+ /* Down line from crossbar. */
+ printLine(outfile,
+ rootX + tree->x + tree->branches[i]->x,
+ (tree->y + (int)tree->height + tree->branches[i]->y)/-2,
+ 0, -1,
+ (tree->branches[i]->y - (tree->y + (int)tree->height))/2,
+ rootPos);
+
+ doPrintTree(outfile, tree->branches[i], rootX+tree->x, rootPos);
+ } /* for */
+ } /* if */
+} /* doPrintTree */
+
+static
+void printTree(FILE *outfile,
+ Tree tree,
+ unsigned height,
+ unsigned leftWidth,
+ unsigned rightWidth,
+ RootPos rootPos)
+{
+ switch (rootPos) {
+ case eTop:
+ (void)fprintf(outfile, "\\setlength{\\unitlength}{%.2fpt}\n\
+\\begin{picture}(%u,%u)(%d,%d)\n \\thicklines\n",
+ 1.0/SCALE,
+ leftWidth+rightWidth,
+ height,
+ -leftWidth,
+ -height);
+ break;
+
+ case eLeft:
+ (void)fprintf(outfile, "\\setlength{\\unitlength}{%.2fpt}\n\
+\\begin{picture}(%u,%u)(%d,%d)\n \\thicklines\n",
+ 1.0/SCALE,
+ height,
+ leftWidth+rightWidth,
+ 0,
+ -leftWidth);
+ break;
+ } /* switch */
+
+ doPrintTree(outfile, tree, 0, rootPos);
+
+ (void)fprintf(outfile, "\\end{picture}\n");
+
+} /* printTree */
+
+static
+void readTree(FILE *infile,
+ Tree *tree,
+ double *xSeparation,
+ double *ySeparation,
+ RootPos *rootPos)
+{
+ TreeNode *child;
+ unsigned i;
+ TreeNode **nodes;
+ unsigned nrNodes = 0;
+ unsigned maxNodes = 10;
+ double nodeDepth;
+ double nodeHeight;
+ int nodeIsRoot;
+ char nodeName[MAX_NAME_SIZE];
+ double nodeWidth;
+ TreeNode *parent;
+ char parentName[MAX_NAME_SIZE];
+ int rootFound = 0;
+ char tmpChar; /* Scratch */
+ double tmpFloat1; /* Scratch */
+ double tmpFloat2; /* Scratch */
+ double tmpFloat3; /* Scratch */
+ TreeNode **tmpNodes; /* Scratch */
+ char *tmpStr1; /* Scratch */
+ char *tmpStr2; /* Scratch */
+
+ nodes = (TreeNode **)malloc(maxNodes*sizeof(TreeNode *));
+ if (NULL == nodes) {
+ (void)fprintf(stderr, "The tree is too big.\n");
+
+ exit(1);
+ } /* if */
+
+ /* Read rootPos. */
+ if (1 != fscanf(infile, "%1s", &tmpChar) ||
+ !('t' == tmpChar || 'l' == tmpChar)) {
+ (void)fprintf(stderr, "Could not read tree orientation.\n");
+
+ exit(1);
+ } /* if */
+
+ switch (tmpChar) {
+ case 'l': *rootPos = eLeft; break;
+ case 't': *rootPos = eTop; break;
+ } /* switch */
+
+ /* Read xSeparation and ySeparation. */
+ if (2 != fscanf(infile, "%lfpt %lfpt", &(*xSeparation), &(*ySeparation))) {
+ (void)fprintf(stderr, "Could not read x & y separations.\n");
+
+ exit(1);
+ } /* if */
+
+ *xSeparation *= SCALE;
+ *ySeparation *= SCALE;
+
+ /* Read nodes. */
+ while (EOF != fscanf(infile, "%s", nodeName)) {
+ nodeIsRoot = !strcmp(nodeName, "root");
+ if (nodeIsRoot) {
+ if (rootFound) {
+ (void)fprintf(stderr, "Too many root nodes.\n");
+
+ exit(1);
+ } /* if */
+
+ rootFound = 1;
+ parentName[0] = '\0'; }
+
+ else if ((TreeNode *)NULL != findNode(nodeName, nodes, nrNodes)) {
+ /* Node already exists. */
+ (void)fprintf(stderr,
+ "The node name `%s' has been used more than once.\n",
+ nodeName);
+
+ exit(1);
+ } /* if */
+
+
+ else if (1 != fscanf(infile, "%s", parentName)) {/* Not root node. */
+ (void)fprintf(stderr, "Could not read parent of %s.\n", nodeName);
+
+ exit(1);
+ } /* if */
+
+ /* Read node width height and depth. */
+ if (3 != fscanf(infile, "%lfpt %lfpt %lfpt",
+ &tmpFloat1, &tmpFloat2, &tmpFloat3)) {
+ (void)fprintf(stderr, "Could not read width, height and depth of %s.\n",
+ nodeName);
+
+ exit(1);
+ } /* if */
+
+ switch (*rootPos) {
+ case eTop:
+ nodeWidth = tmpFloat1;
+ nodeHeight = tmpFloat2 + tmpFloat3;
+ nodeDepth = tmpFloat3;
+ break;
+
+ case eLeft:
+ nodeWidth = tmpFloat2 + tmpFloat3;
+ nodeHeight = tmpFloat1;
+ nodeDepth = tmpFloat3;
+ break;
+ } /* switch */
+
+ /* Add node. */
+ nrNodes++;
+ if (nrNodes > maxNodes) { /* Resize <nodes> array. */
+ maxNodes *= 2;
+ tmpNodes = (TreeNode **)realloc(nodes,
+ (unsigned)(maxNodes*sizeof(TreeNode *)));
+ if (NULL == tmpNodes) {
+ (void)fprintf(stderr, "The tree is too big.\n");
+
+ exit(1);
+ } /* if */
+
+ if (tmpNodes != nodes) (void)free(nodes);
+
+ nodes = tmpNodes;
+
+ } /* if */
+
+ tmpStr1 = malloc((size_t)((strlen(nodeName)+1)*sizeof(char)));
+ if (NULL == tmpStr1) {
+ (void)fprintf(stderr, "The tree is too big.\n");
+
+ exit(1);
+ } /* if */
+
+ (void)strcpy(tmpStr1, nodeName);
+
+ tmpStr2 = malloc((size_t)((strlen(parentName)+1)*sizeof(char)));
+ if (NULL == tmpStr2) {
+ (void)fprintf(stderr, "The tree is too big.\n");
+
+ exit(1);
+ } /* if */
+
+ (void)strcpy(tmpStr2, parentName);
+
+ nodes[nrNodes-1] = newTree(tmpStr1, tmpStr2,
+ (unsigned)(SCALE*nodeHeight),
+ (unsigned)(SCALE*nodeWidth),
+ (unsigned)(SCALE*nodeDepth));
+
+ if ((TreeNode *)NULL == nodes[nrNodes-1]) {
+ (void)fprintf(stderr, "The tree is too big.\n");
+
+ exit(1);
+ } /* if */
+
+ } /* while */
+
+ if (!rootFound) {
+ (void)fprintf(stderr, "No root node.\n");
+
+ exit(1);
+ } /* if */
+
+ *tree = findNode("root", nodes, nrNodes); /* The root node. */
+
+ /* Construct tree. */
+ for (i = 0; i < nrNodes; i++) {
+ child = nodes[i];
+ if (child != *tree) {
+ parent = findNode(child->parent, nodes, nrNodes);
+ if ((TreeNode *)NULL == parent) {
+ (void)fprintf(stderr, "The parent (%s) of node %s does not exist.\n",
+ child->parent, parent->name);
+
+ exit(1);
+ } /* if */
+
+ if (!addBranch(child, parent)) {
+ (void)fprintf(stderr, "The tree is too big.\n");
+
+ exit(1);
+ } /* if */
+ } /* if */
+ } /* for */
+} /* readTree */
diff --git a/macros/latex209/contrib/trees/tree_tex/treetex.sty b/macros/latex209/contrib/trees/tree_tex/treetex.sty
new file mode 100644
index 0000000000..9ff17e51c4
--- /dev/null
+++ b/macros/latex209/contrib/trees/tree_tex/treetex.sty
@@ -0,0 +1,107 @@
+% Author: Anthony Bloesch
+% Title: tree.sty
+%
+% Copyright (C) Anthony Bloesch 1993
+%
+% Version: 1.0
+%
+% Purpose: Allow the automatic layout of n-ary trees with arbitrary node
+% sizes in LaTeX.
+%
+% Usage: \begin{tree}[ROOT_POSITION]{TREE_NAME}
+% \rootnode{ ... }
+% \treenode{NODE_NAME1}{PARENT_1}{ ... }
+% .
+% .
+% .
+% \end{tree}
+%
+% To layout a tree:
+% 1. Describe the tree in a tree environment.
+% 2. Run LaTeX on the file.
+% 3. Run treetex on the generated .tlo file to generate a .tli file.
+% 4. Run LaTeX again.
+% 5. If the tree is ever changed repeat steps 3 and 4.
+%
+% Example:
+% \begin{tree}{testtreea}
+% \rootnode{root node}
+% \treenode{nodeA}{root}{left root child}
+% \treenode{nodeB}{root}{right root child}
+% \treenode{nodeC}{nodeA}{nodeA child}
+% \end{tree}
+%
+% The argument of the environment (e.g. "testtreea") gives the
+% name of the file to be generated. Each tree must have
+% exactly one root node which is defined with the \rootnode
+% macro; its argument is the contents of the node. All other
+% nodes are defined with the \treenode macro. The first
+% argument of \treenode is its name (consisting only of
+% alphabetical characters); the second is its parent's name;
+% and the third is its contents.
+%
+% The tree environment has an optional environment describing
+% where the root of the tree should go relative to the tree.
+% If the parameter is `t' (the default) then the root goes at the
+% top of the tree with branches hanging down from it;
+% otherwise the parameter must be a `l' and the root goes at
+% the left of the tree with the branches spreading to the right.
+%
+% Example:
+% \begin{tree}[l]{testtreea}
+% \rootnode{root node}
+% \treenode{nodeA}{root}{left root child}
+% \treenode{nodeB}{root}{right root child}
+% \treenode{nodeC}{nodeA}{nodeA child}
+% \end{tree}
+%
+% Children of a node will be layed out, left to right, in the
+% same order as they appear in the tree environment.
+%
+% The tree environment will generate a warning when the .tli
+% file has not been generated and inconsistencies between the
+% .tlo and .tli files are detected.
+%
+% The minimum seperation between nodes in the x and y
+% directions can be changed setting the lengths
+% \treexseparation and \treeyseparation.
+
+\newlength\treexseparation
+\treexseparation 10pt
+\newlength\treeyseparation
+\treeyseparation 10pt
+
+\newwrite\@tlo
+
+\def\tree{\@ifnextchar[{\@xtree}{\@xtree[t]}}
+\def\@xtree[#1]#2{\bgroup
+ \def\@treename{#2}
+ \immediate\openout\@tlo=\@treename.tlo
+ \immediate\write\@tlo{#1}
+ \immediate\write\@tlo{\the\treexseparation\space\the\treeyseparation}
+ \def\@printwdhtdp##1{
+ \setbox\@tempboxa\hbox{##1}
+ \edef\tempa{\immediate\write\@tlo{\space\space\the\wd\@tempboxa\space
+ \the\ht\@tempboxa\space\the\dp\@tempboxa}}
+ \tempa
+ \relax}
+ \def\rootnode##1{
+ \def\root{##1}
+ \immediate\write\@tlo{root }\@printwdhtdp{##1}}
+ \def\treenode##1##2##3{
+ \expandafter\def\csname ##1\endcsname{##3}
+ \immediate\write\@tlo{##1 ##2 }\@printwdhtdp{##3}}
+}
+
+\def\endtree{
+ \immediate\closeout\@tlo
+ \def\shownode##1{\edef\@tempa{\expandafter\@cdr\string ##1\@nil}%
+ \@ifundefined{\@tempa}{\@warning{Run treetex on \@treename}}{##1}}
+ \openin1=\@treename.tli
+ \ifeof1
+ \@warning{Run treetex on \@treename}
+ \fbox{\fbox{Run treetex on \@treename.}}
+ \else
+ \closein1 \relax\@@input\@treename.tli
+ \fi
+ \egroup}
diff --git a/macros/latex209/contrib/trees/vanroose/trees.pdf b/macros/latex209/contrib/trees/vanroose/trees.pdf
new file mode 100644
index 0000000000..b9a228bf20
--- /dev/null
+++ b/macros/latex209/contrib/trees/vanroose/trees.pdf
Binary files differ
diff --git a/macros/latex209/contrib/trees/vanroose/trees.sty b/macros/latex209/contrib/trees/vanroose/trees.sty
new file mode 100644
index 0000000000..bb5d5e0ff1
--- /dev/null
+++ b/macros/latex209/contrib/trees/vanroose/trees.sty
@@ -0,0 +1,86 @@
+%---------- trees.sty --------------------
+% Peter Vanroose, 18 april 1990.
+\newcount\branchwidth\newcount\xcoord\newcount\ycoord\newcount\coordstep
+\def\branchlabels#1#2#3{\edef\labela{#1}\edef\labelb{#2}\edef\labelc{#3}}
+\branchlabels012
+%
+\def\root(#1,#2) #3.{\catcode32=9 % ignore spaces
+ % #3 is the node label of the root
+ \expandafter\xdef\csname nodex#3\endcsname{#1}
+ \expandafter\xdef\csname nodey#3\endcsname{#2}
+ \put(#1,#2){
+ \put(0,0){\line(-1,0)6}\put(-6,0){\line(0,-1)3}\put(-9,-3){\line(1,0)6}}}
+%
+\def\branch#1#2#3:#4,#5.{ \branchwidth=#1
+ \xcoord=\expandafter\number\csname nodex#3\endcsname
+ \ycoord=\expandafter\number\csname nodey#3\endcsname
+ \edef\coord{(\number\xcoord,\number\ycoord)}
+ \advance\xcoord by 12 % #4,#5 are the labels of the childs
+ \expandafter\xdef\csname nodex#4\endcsname{\number\xcoord}
+ \expandafter\xdef\csname nodex#5\endcsname{\number\xcoord}
+ \ifcase\branchwidth
+ \advance\ycoord by 24\coordstep=-48 \or % case 0
+ \advance\ycoord by 12\coordstep=-24 \or % case 1
+ \advance\ycoord by 6\coordstep=-12 \or % case 2
+ \advance\ycoord by 3\coordstep=- 6 \fi % case 3
+ \expandafter\xdef\csname nodey#4\endcsname{\number\ycoord}
+ \advance\ycoord by \coordstep
+ \expandafter\xdef\csname nodey#5\endcsname{\number\ycoord}
+ \expandafter\put\coord{
+ \put(0,0){\circle*1}\put(0,1.5){\makebox(0,0){\scriptsize #2}}
+ \ifcase\branchwidth
+ \put(0,0){\line(1,2){12}}\put(0,0){\line(1,-2){12}}
+ \put(5,12){\tiny$\labela$}\put(5,-12){\tiny$\labelb$} \or % case 0
+ \put(0,0){\line(1,1){12}}\put(0,0){\line(1,-1){12}}
+ \put(6,7){\tiny$\labela$}\put(6,-8){\tiny$\labelb$} \or % case 1
+ \put(0,0){\line(2,1){12}}\put(0,0){\line(2,-1){12}}
+ \put(6,3.6){\tiny$\labela$}\put(6,-5){\tiny$\labelb$} \or % case 2
+ \put(0,0){\line(4,1){12}}\put(0,0){\line(4,-1){12}}
+ \put(6,2){\tiny$\labela$}\put(6,-3){\tiny$\labelb$} \fi % case 3
+}}
+%
+\def\tbranch#1#2#3:#4,#5,#6.{
+ \branchwidth=#1
+ \xcoord=\expandafter\number\csname nodex#3\endcsname
+ \ycoord=\expandafter\number\csname nodey#3\endcsname
+ \edef\coord{(\number\xcoord,\number\ycoord)}
+ \advance\xcoord by 12
+ \expandafter\xdef\csname nodex#4\endcsname{\number\xcoord}
+ \expandafter\xdef\csname nodex#5\endcsname{\number\xcoord}
+ \expandafter\xdef\csname nodex#6\endcsname{\number\xcoord}
+ \ifcase\branchwidth
+ \advance\ycoord by 24\coordstep=-24 \or % case 0
+ \advance\ycoord by 12\coordstep=-12 \or % case 1
+ \advance\ycoord by 6\coordstep= -6 \or % case 2
+ \advance\ycoord by 3\coordstep= -3 \fi % case 3
+ \expandafter\xdef\csname nodey#4\endcsname{\number\ycoord}
+ \advance\ycoord by \coordstep
+ \expandafter\xdef\csname nodey#5\endcsname{\number\ycoord}
+ \advance\ycoord by \coordstep
+ \expandafter\xdef\csname nodey#6\endcsname{\number\ycoord}
+ \expandafter\put\coord{
+ \put(0,0){\circle*1}\put(0,1.5){\makebox(0,0){\scriptsize #2}}
+ \ifcase\branchwidth
+ \put(0,0){\line(1,2){12}}\put(0,0){\line(1,0){12}}\put(0,0){\line(1,-2){12}}
+ \put(5,12){\tiny$\labela$}\put(5,0.6){\tiny$\labelb$}\put
+ (5,-12){\tiny$\labelc$} \or % case 0
+ \put(0,0){\line(1,1){12}}\put(0,0){\line(1,0){12}}\put(0,0){\line(1,-1){12}}
+ \put(6,7){\tiny$\labela$}\put(6,0.5){\tiny$\labelb$}\put
+ (6,-8){\tiny$\labelc$} \or % case 1
+ \put(0,0){\line(2,1){12}}\put(0,0){\line(1,0){12}}\put(0,0){\line(2,-1){12}}
+ \put(6,3.6){\tiny$\labela$}\put(6,0.5){\tiny$\labelb$}\put
+ (6,-5){\tiny$\labelc$} \or % case 2
+ \put(0,0){\line(4,1){12}}\put(0,0){\line(1,0){12}}\put(0,0){\line(4,-1){12}}
+ \put(6,2){\tiny$\labela$}\put(6,0.25){\tiny$\labelb$}\put
+ (6,-3){\tiny$\labelc$} \fi % case 3
+}}
+%
+\def\leaf#1#2#3.{
+ \xcoord=\expandafter\number\csname nodex#3\endcsname
+ \ycoord=\expandafter\number\csname nodey#3\endcsname
+ \edef\coord{(\number\xcoord,\number\ycoord)}
+ \expandafter\put\coord{
+ \put(0,0){\circle*1}\put(0,1.5){\makebox(0,0){\scriptsize #1}}
+ \put(2,-0.6){\makebox(0,0)[l]{#2}}}}
+%
+%-------- end of trees.sty -------------
diff --git a/macros/latex209/contrib/trees/vanroose/trees.tex b/macros/latex209/contrib/trees/vanroose/trees.tex
new file mode 100644
index 0000000000..8e839bf65c
--- /dev/null
+++ b/macros/latex209/contrib/trees/vanroose/trees.tex
@@ -0,0 +1,64 @@
+\documentstyle[trees,fullpage]{article}
+
+\title{{\tt trees.sty}: A Macro for Drawing Binary \\
+ or Ternary Trees}
+
+\author{Peter Vanroose \\
+ peter@dit.lth.se}
+\date{18 april 1990}
+
+\begin{document}
+
+\maketitle
+
+The following macros let you draw a (binary or ternary) tree of any size.
+For each "internal node", you only have to specify which are the descending
+nodes, with a \verb|\branch| command (\verb|\tbranch| for ternary node.).
+To this end, nodes are given a label (only used internally!). These macros
+will give you some ideas on designing similar things for, e.g.,
+digital circuits.
+
+Trees are constructed with labels on the branches (default 0 and 1), and
+with text (e.g., its name or value) on the nodes. The first parameter to
+\verb|\branch| (0, 1, 2 or 3) determines the steepness of the branches.
+
+Example:
+\small
+\begin{verbatim}
+\begin{picture}(100,100)(-50,10)
+\unitlength=2mm
+\branchlabels ABC % 012 is the default
+\root(2,10) 0. % root at absolute coordinate (2,10)
+ % its (internally used) label is 0
+ % the space before the 0 is obligatory
+\branch2{16} 0:1,2. % node 0 (i.e., the root) has children 1 and 2
+ % the text "1.00" is written above it
+ % space is optional, :,. are obligatory
+ \leaf{4}{$u_1$} 1. % node 1 is a leaf
+ % "0.45" written above, "$u_1$" to the right
+ \branch2{12} 2:3,7. % branch to node 3 goes up, and has label A
+ \tbranch2{9} 3:4,5,6.
+ \leaf{4}{$u_3$}4. % the symbols 0--7 can be replaced by anything
+ \leaf{3}{$u_4$}5.
+ \leaf{2}{$u_5$}6.
+ \leaf{3}{$u_2$} 7.
+\end{picture}
+\end{verbatim}
+\normalsize
+will typeset something like:
+\begin{flushleft}
+\begin{picture}(100,100)(-50,10)
+\unitlength=2mm
+\branchlabels ABC
+\root(2,10) 0.
+\branch2{16} 0:1,2.
+ \leaf{4}{$u_1$} 1.
+ \branch2{12} 2:3,7.
+ \tbranch2{9} 3:4,5,6.
+ \leaf{4}{$u_3$}4.
+ \leaf{3}{$u_4$}5.
+ \leaf{2}{$u_5$}6.
+ \leaf{3}{$u_2$} 7.
+\end{picture}
+\end{flushleft}
+\end{document}