diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex209/contrib/trees |
Initial commit
Diffstat (limited to 'macros/latex209/contrib/trees')
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 Binary files differnew file mode 100644 index 0000000000..18506c160d --- /dev/null +++ b/macros/latex209/contrib/trees/pstrees/trees 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 Binary files differnew file mode 100644 index 0000000000..1244a2c275 --- /dev/null +++ b/macros/latex209/contrib/trees/pstrees/trees.doc.pdf 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 Binary files differnew file mode 100644 index 0000000000..3f77416afa --- /dev/null +++ b/macros/latex209/contrib/trees/tree-dvips/lingmacros-manual.pdf 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 ¬} + +\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 ¬} + +\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 Binary files differnew file mode 100644 index 0000000000..02fa97f402 --- /dev/null +++ b/macros/latex209/contrib/trees/tree-dvips/tree-manual.pdf 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 Binary files differnew file mode 100644 index 0000000000..b9a228bf20 --- /dev/null +++ b/macros/latex209/contrib/trees/vanroose/trees.pdf 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} |