From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Mon, 2 Sep 2019 13:46:59 +0900 Subject: Initial commit --- macros/latex/contrib/LingTrees/CDM/avm.sty | 164 ++++ .../latex/contrib/LingTrees/CDM/cm-lingmacros.sty | 367 ++++++++ .../latex/contrib/LingTrees/Development/macros.txo | 34 + .../contrib/LingTrees/Development/texoptarg.py | 203 +++++ .../contrib/LingTrees/Examples/lingtrees.doc.txp | 991 +++++++++++++++++++++ .../contrib/LingTrees/Examples/outputfiles.tex | 20 + .../LingTrees/Examples/outputfiles_trees.txp | 44 + .../LingTrees/Examples/pst-tree-dvips-emu.doc.tex | 358 ++++++++ macros/latex/contrib/LingTrees/Examples/simple.txp | 20 + macros/latex/contrib/LingTrees/GUI/treebutton.py | 312 +++++++ macros/latex/contrib/LingTrees/GUI/treerunner.ico | Bin 0 -> 318 bytes macros/latex/contrib/LingTrees/GUI/usage.txt | 24 + macros/latex/contrib/LingTrees/README | 46 + macros/latex/contrib/LingTrees/READMORE.txt | 123 +++ macros/latex/contrib/LingTrees/changelog.txt | 9 + .../LingTrees/lingtrees-without-pstricks.sty | 9 + macros/latex/contrib/LingTrees/lingtrees.doc.pdf | Bin 0 -> 109099 bytes macros/latex/contrib/LingTrees/lingtrees.sty | 366 ++++++++ .../contrib/LingTrees/pst-tree-dvips-emu.doc.pdf | Bin 0 -> 48322 bytes .../latex/contrib/LingTrees/pst-tree-dvips-emu.sty | 451 ++++++++++ macros/latex/contrib/LingTrees/trees.py | 309 +++++++ 21 files changed, 3850 insertions(+) create mode 100644 macros/latex/contrib/LingTrees/CDM/avm.sty create mode 100644 macros/latex/contrib/LingTrees/CDM/cm-lingmacros.sty create mode 100644 macros/latex/contrib/LingTrees/Development/macros.txo create mode 100644 macros/latex/contrib/LingTrees/Development/texoptarg.py create mode 100644 macros/latex/contrib/LingTrees/Examples/lingtrees.doc.txp create mode 100644 macros/latex/contrib/LingTrees/Examples/outputfiles.tex create mode 100644 macros/latex/contrib/LingTrees/Examples/outputfiles_trees.txp create mode 100644 macros/latex/contrib/LingTrees/Examples/pst-tree-dvips-emu.doc.tex create mode 100644 macros/latex/contrib/LingTrees/Examples/simple.txp create mode 100644 macros/latex/contrib/LingTrees/GUI/treebutton.py create mode 100644 macros/latex/contrib/LingTrees/GUI/treerunner.ico create mode 100644 macros/latex/contrib/LingTrees/GUI/usage.txt create mode 100644 macros/latex/contrib/LingTrees/README create mode 100644 macros/latex/contrib/LingTrees/READMORE.txt create mode 100644 macros/latex/contrib/LingTrees/changelog.txt create mode 100644 macros/latex/contrib/LingTrees/lingtrees-without-pstricks.sty create mode 100644 macros/latex/contrib/LingTrees/lingtrees.doc.pdf create mode 100644 macros/latex/contrib/LingTrees/lingtrees.sty create mode 100644 macros/latex/contrib/LingTrees/pst-tree-dvips-emu.doc.pdf create mode 100644 macros/latex/contrib/LingTrees/pst-tree-dvips-emu.sty create mode 100644 macros/latex/contrib/LingTrees/trees.py (limited to 'macros/latex/contrib/LingTrees') diff --git a/macros/latex/contrib/LingTrees/CDM/avm.sty b/macros/latex/contrib/LingTrees/CDM/avm.sty new file mode 100644 index 0000000000..8c188630ea --- /dev/null +++ b/macros/latex/contrib/LingTrees/CDM/avm.sty @@ -0,0 +1,164 @@ +% avm.sty -- for attribute-value matrices -- v 1.00 mar 29, 1992 +% v 1.01 dec 6, 1993; v 1.02 jan 5, 2006 +% (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 \ifx\@tabularcr\relax +\def\\{\@arraycr} % fix for the Mainz array package +\else +\def\\{\@tabularcr}% Leverage off LaTeX's \\*[dimen] options +\fi +\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\asort##1{\avmspan{\avmjsortfont ##1}\\} +\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/latex/contrib/LingTrees/CDM/cm-lingmacros.sty b/macros/latex/contrib/LingTrees/CDM/cm-lingmacros.sty new file mode 100644 index 0000000000..96ca73e75d --- /dev/null +++ b/macros/latex/contrib/LingTrees/CDM/cm-lingmacros.sty @@ -0,0 +1,367 @@ +% 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 +% modified by Chris Manning and Avery Andrews (has Emma's mods until 8/10/92) + +%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. Add [chapter] if using report style +\newcounter{enums} + +% \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}} + +%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) +% allows the order \exref{-2}[b] -- which I greatly prefer. cdm. +\def\exref#1{\@ifverynextchar[{\@exref#1}% %] +{\@exref#1[]}} + +\def\@exref#1[#2]{(\ref{#1}#2)} +%chris- + +% 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} + + +%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- + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% 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}} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% 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 +% + +%chris+ +% for easier hand entry of csli bib items. +\def\bib{\bibitem[]{}} +%chris- diff --git a/macros/latex/contrib/LingTrees/Development/macros.txo b/macros/latex/contrib/LingTrees/Development/macros.txo new file mode 100644 index 0000000000..0a25fdbee5 --- /dev/null +++ b/macros/latex/contrib/LingTrees/Development/macros.txo @@ -0,0 +1,34 @@ +% +% Macro templates for pst-tree-dvips-emu.sty +% +% run 'texoptarg macrox.txo' to get a file 'macros.tex' +% processing the optional arguments. +% + +% \putpoint{label}{distance}(angle)[from corner]{from node} +% 1 2 3 4 5 + +\gdef\putpoint#1#2(#3=0)[#4]#5 + + +% \nodeconnect(pre-options)[fromloc]{fromnode}[toloc]{tonode}[style parameters] +% 1 2 3 4 5 6 7 +% +\gdef\nodeconnect<#1=\pcline>(#2)[#3=b]#4[#5=t]#6[#7] + +% \nodecurve(pre-option)[fromloc]{fromnode}[toloc]{tonode}(curve)[style options] +% 1 2 3 4 5 6 7 8 +% for curve, either one number or 2, separated by commas, eg: (2) or (1,2) +% 1 does nothing for the moment, but maybe someday (curved zigags?) +% +\gdef\nodecurve <#1=\pccurve>(#2)[#3=b]#4[#5=t]#6(#7)[#8] + +% \barnodeconnect(pre-options)[arm]{from}{to}[style] +% 1 2 3 4 5 +% +\gdef \barnodeconnect (#1)[#2]#3#4[#5] + +% \nodetriangle {apex}{base}[style] +% 1 2 3 +% +\gdef \nodetriangle#1#2[#3] diff --git a/macros/latex/contrib/LingTrees/Development/texoptarg.py b/macros/latex/contrib/LingTrees/Development/texoptarg.py new file mode 100644 index 0000000000..8b725d1fd1 --- /dev/null +++ b/macros/latex/contrib/LingTrees/Development/texoptarg.py @@ -0,0 +1,203 @@ +#! /usr/bin/python +# +# COPYRIGHT 2006, Avery D Andrews 3rd +# +# License: GPL2 +# +# Purpose: this script converts macro 'declarations' in the style +# of the accompanying macros.txo to a chain of TeX macros with +# optional arguments, with [#d=X] indicating an optional argument +# with default value X. Allowed delimiters are [], (), <>; Input +# verification not very thorough. + +# +# changelog at end + +import sys, string, os, re + +# +# would be an idea to subclass 'file', but then I wouldn't +# know how to make it work with sys.stdin +# +class Source: + + def __init__(self, source): + self.linenum = 0 + self.file = source + self.nextline = source.readline() + + def readline(self): + self.linenum = self.linenum+1 + returnline = self.nextline + self.nextline = self.file.readline() + return returnline + +class ProgramError(Exception): + + def __init__(self, value): + self.value = value+'\n' + # + # UGH: there must be a better way to do this + # + global error_occurred + error_occurred=1 + + # + # UMM: actually this doesn't seem to do what I expect it to (be + # the spelling of an error instance in backquotes) + # + def __str__(self): + return self.value + +# +# complain and set error flag but don't stop +# +def ProgramWhinge(issue): + sys.stderr.write(issue) + global error_occurred + error_occurred=1 + + +blanklinepattern = re.compile("^\s*(%.*)?$") + +# +# pulls out three fields, the first ought be \def, \gdef etc. +# the second is the name, preceeding by backslash +# the third is the arguments. +# they can be separated by whitespace, but don't have to be +# +deflinepattern = re.compile("^\s*(\\\\[a-zA-Z]+)\s*(\\\\[a-zA-Z@]+)\s*(\S*)\s*$") + +# [ indicates [, (, <, likewise ]. 1 indicates any digit +# +# #1 or [#1#], not followed by a closing bracket +# +oblargpattern = re.compile("([\[\(<])?#(\d)(?![=\]\)>])(#[\]\)>])?(.*)") +# 1 2 3 4 +# +# [#1(=opt)] +# +optargpattern = re.compile("([\[\(<])#(\d)(=[^[([\]\)>]*)?([([\]\)>])(.*)") +# 1 2 3 4 5 +# +def process_file(infile, outfile): + global error_occurred + error_occurred =0 + while 1: + line = infile.readline() + if line == '': + break; + blankmatch = blanklinepattern.match(line) + if blankmatch: + pass + else: + defmatch = deflinepattern.match(line) + if defmatch: + (defin, name, arguments) = defmatch.group(1,2,3) + outfile.write("\n%%\n%% %s\n%%\n%%\n"%name) + produce_definition(defin, name, arguments, 1, [], infile, outfile) + else: + raise ProgramError("line %d ill-formed"%infile.linenum) + +def produce_definition(defcom, name, arguments, count, arglist, infile, outfile): + blankmatch = blanklinepattern.match(arguments) + if blankmatch: + write_definition(defcom, name, arglist, outfile) + return + # + # obligatory arguments + # + argmatch = oblargpattern.match(arguments) + if argmatch: +# print "%s: %s"%(name,argmatch.group(3)) + if argmatch.group(1): + if not argmatch.group(3): + raise ProgramError("no closing bracket in line %d"%infile.linenum) + if argmatch.group(3): + if not argmatch.group(2): + raise ProgramError("no opening bracket in line %d"%infile.linenum) + if count!=int(argmatch.group(2)): + raise ProgramError("argument number sequence error line %d"%infile.linenum) + if argmatch.group(1): +# print `argmatch.group(2)` + arg = "%s#%d%s"%(argmatch.group(1), count, argmatch.group(3)) + arglist.append((arg,arg)) + else: + arglist.append(("#%d"%count, "{#%d}"%count)) + produce_definition(defcom,name,argmatch.group(4),count+1, arglist,infile, outfile) + return + # + # optional arguments + # + argmatch = optargpattern.match(arguments) + if argmatch: + write_definition_start(defcom, name, arglist, outfile) + nextname = '\@'+name[1:] + outfile.write("{\@ifnextchar %s\n {%s"%(argmatch.group(1), nextname)) + # + # iftrue + # + write_args_in_def(arglist,outfile) + outfile.write("}") + outfile.write("\n") + # + # iffalse + # + if argmatch.group(3): + defaultval = argmatch.group(3)[1:] + else: + defaultval = "" +# print "default: %s"%defaultval + outfile.write(" {%s"%nextname) + write_args_in_def(arglist,outfile) + outfile.write("%s%s%s}\n}\n"%(argmatch.group(1),defaultval,argmatch.group(4))) + # + # next argument + # + arg ="%s#%s%s"%argmatch.group(1,2,4) + arglist.append((arg, arg)) + produce_definition(defcom, nextname, argmatch.group(5), count+1, arglist, infile, outfile) + + +def write_args_in_def(arglist, outfile): + for arg in arglist: + outfile.write(arg[1]) + +def write_definition_start(defcom, name, arglist, outfile): + outfile.write("%s%s"%(defcom, name)) + for arg in arglist: + outfile.write(arg[0]) + +def write_definition(defcom, name, arglist, outfile): + write_definition_start(defcom, name, arglist, outfile) + outfile.write("{\n\n}\n") + +if __name__=="__main__": + argv=sys.argv +# print 'cwd:'+os.getcwd() + if len(argv)<2:# run as filter + infile=sys.stdin + outfile=sys.stdout + errfilename = 'texoptarg.err' +# errfile=open("texoptarg.err","w") + else: + infile=open(argv[1]+'.txo','r') + outfile=open(argv[1]+'.tex','w') + errfilename = argv[1]+'.err' +# errfile=open(argv[1]+'.err','w') + + try: + process_file(Source(infile), outfile) + except ProgramError, error: + sys.stderr.write(error.value) + errfile=open(errfilename,'w') + errfile.write(error.value) + if error_occurred: + sys.exit(1) + sys.stderr.write("texoptarg ran without issues\n") + +# +# Changelog: +# +# Jan 24 2006: first apparently working version +# diff --git a/macros/latex/contrib/LingTrees/Examples/lingtrees.doc.txp b/macros/latex/contrib/LingTrees/Examples/lingtrees.doc.txp new file mode 100644 index 0000000000..71ea849717 --- /dev/null +++ b/macros/latex/contrib/LingTrees/Examples/lingtrees.doc.txp @@ -0,0 +1,991 @@ +\documentclass[12pt]{article} +\usepackage{cm-lingmacros, lingtrees, avm,url} + +\def\bk{$\backslash$} + +\def\pstricks{PSTricks} +\def\texlatex{\TeX/\LaTeX} + +\begin{document} +\begin{center} +{\Large\bf Linguistics Trees Preprocessor}\\ +\medskip +{\large\bf Avery Andrews}\\ +\medskip +v. 3.0 ({\tt pst-nodes} based)\\ +March, 2006 +\end{center} +\medskip + +Consider the tree shown in \ex{1} drawn from Newmeyer (1986) following GKPS: + +\begin{example} +\sisterskip=1.2em +\hspace*{-1.8em}\small +.[ +S + NP + that book|tri + {S/NP} + NP + I + {VP/NP} + V + want + {VP/NP} + to + {VP/NP}\sistergap{0em} + V + ask + NP + Mary + {VP/NP} + to + {VP/NP}\sistergap{0em} + V + tell + NP + Tom + {VP/NP} + to + {VP/NP}\sistergap{0em} + V + read + {NP/NP} + e +.] +\end{example} +This would require some drama to do by hand, but the {\sf LingTrees} +package provided here makes it reasonably easy. + +The package consists of a preprocessor that converts an indented +list tree format into \LaTeX\ input (plain {\TeX} doesn't seem to work), +and some macro files which lay out the trees and draw the +lines. There are currently two possibilities for the line-drawing, +one a partial emulation and extension of Emma Pease's {\sf tree-dvips} +based on the powerful graphics package {\pstricks} (the default), and the +the other the original {\sf tree-dvips}, in case there is a problem with +using {\pstricks}. Some of the more advanced features won't work with +{\sf tree-dvips}; these are noted as they come up below. + +This package is probably most suited for irregularly-branching trees with +wide node-labels, as found in LFG or HPSG. Some other +packages worth looking at are {\sf pst-jtree} (John Frampton), +{\sf qtree} (Jeffrey Siskind and Alexis Dimitriadis), {\sf xytree} +(Koaunghi Un), and for unusual situtations, +the {\sf pst-tree} module of {\pstricks} (which is oriented towards +tree-like structures in mathematics, rather than linguistics, and can +do wierd things such as change the direction of the branching in +the middle of the tree). + +\section{Setup} +The current version of the preprocessor is a Python script {\tt trees.py}.\footnote + {The original was written in C; a slightly modified version of the + source can be found on Chris Manning's (La)TeX web-page + \url{http://nlp.stanford.edu/~manning/tex/}.} +For Windows (98 thru XP), there is a free-standing executable with installer +that doesn't require Python to be installed that can be downloaded from +\url{http://arts.anu.edu.au/linguistics/People/AveryAndrews/Software/latex}.\\ +% +% utter bitch of a line-break here! +% +Most Linux distros and later versions of MacOS will have an adequate +version of Python included (the preprocessor works for at least Python 1.5.2 thru +Python 2.4.2). Otherwise, Python will have to be installed. Instructions +for installing and running {\tt trees.py} under various OS's +can be found in the file \verb&00_readme.txt&. + +At the above URL there are also links to the `TreeRunner' GUI for +running the preprocessor and other {\LaTeX} components, which I find +to be a useful alternative to setting up a {\tt make} file for small projects. + +The macro files are {\sf lingtrees.sty}, {\sf pst-tree-dvips-emu.sty} +and {\sf trees-without-pstricks.sty}; they will have to be put whereever +you put custom {\texlatex} files (\verb&c:\localtexmf\tex\latex& for +MikTeX). You'll also need the {\pstricks} package +(including the {\sf pst-nodes} module), and {\sf tree-dvips} if you're planning +to use that, both available on CTAN and included in many {\texlatex} distributions. +If you have to install either of these yourself, note that they include files +with the extension {\tt .pro} defining special commands for PostScript; these +must be put somewhere where the {\sf dvips} program can see them +({\tt localtexmf/dvips} in MiKTeX). + +\section{Basic Usage} +The document needs to load the {\sf lingtrees.sty} style file, with a line like +this before the \verb&\begin{document}&: +\begin{example} +\begin{verbatim} +\usepackage{lingtrees} +\end{verbatim} +\end{example} +This will load up the {\pstricks}-based implementation, to use the +old {\sf tree-dvips}-based one instead, use {\tt lingtrees-without-pstricks} +instead. + +In the document, a tree begins with \verb+.[+, ends with \verb+.]+, and has each +node represented by a line of text, where +nesting is indicated by increasing depth of embedding, so that sisters +must be indented equally, i.e.: +\begin{example} +\begin{verbatim} + .[ + S + NP + John + VP + V + bit + NP + Fido + .] +\end{verbatim} +\end{example} +Blank lines are not allowed, and error messages will be +triggered by various kinds of discrepancies, although +there are plenty of ways of getting the wrong output without +producing an error message, so the results need to be checked +carefully. + +After running the preprocessor, you run \LaTeX. Many current {\tt .dvi} +viewers can then show the lines, at least in simple cases, but: +\begin{examples} +\item some drawn lines get wrongly obliterated by other material +\item some things aren't positioned correctly +\end{examples} +So if you really +want to be sure that you're seeing how it's going to be, you'll need to run +{\tt dvips} and look at it with a postscript viewer. The TreeRunner GUI can +launch these automatically. + +The result of the above tree is: +\begin{example} +.[ +S + NP + John + VP + V + bit + NP + Fido +.] +\end{example} +A complete file of this example can be found in {\tt examples/simple.txp}. + +\section{Work Methods} +The method used above is to have your source document be say {\tt paper.txp}, +and run the preprocessor every time you change the text. I personally don't +tend to do things this way, since I find it alarming to have anything +overwriting big files with the extension {\tt .tex}. So an alternative +method is to +put all of the trees in a file of their own, with a name ending in +{\tt \_trees.tex}, and then use the preprocessor's {\tt .>} +directive to send the output of the next tree to the filename coming +after the {\tt .>} (on the same line). So that if for example the +preprocessor encounters the line {\tt .> trees/firsttree.tex}, then +the following tree gets written to the file {\tt trees/firsttree.tex} (and the +material in between the {\tt .>}-line and the start of the tree, but +nothing after the tree). Then you use a \verb%\input trees/firsttree.tex% +statement in your +document to include the tree (I find it tidy to put them in a subfolder). +This works nicely if you're the sort of person who rarely gets around +to setting up makefiles for writing projects (since you only have to +run the preprocessor when you change a tree, which is really not that +often, in practice). The technique is also useful for keeping trees +synchronized between a paper +and a handout or presentation. To send more than the next tree to +a specific file, use {\tt .>> [filename]}; output will then go +to file name until either the next {\tt .>>} directive, or a {\tt .<<} +directive, which reverts the output to the default output file. + +These possibilites are illustrated in {\tt examples/outputfiles\_trees.txp}, +which makes the trees for {\tt examples/outputfiles.tex}. Using +{\tt .>} after {\tt .>>} will produce an error message. Summing up the +preprocessor directives, they are: +\begin{example} +\begin{tabular}[t]{lcl} +{\tt .[} &:& begin a tree\\ +{\tt .]} &:& end a tree\\ +{\tt .-} &:& continuation line (see below)\\ +{\tt .>} {\it file} &:& write next tree to {\it file}\\ +{\tt .>>} {\it file} &:& write following material until {\tt .<<} to {\it file}\\ +{\tt .<<} &:& stop writing to file +\end{tabular} +\end{example} + + +\section{Line-drawing Options} +Line-drawing options are separated from the node label and each other by a vertical bar +(`$\mid$'). There are currently five basic ones which will work with +either the {\pstricks} or {\tt tree-dvips} as the line-drawer, the last +three mutually exclusive:\footnote + {And due to Chris Manning.} +\begin{examples} +\item {\tt tag TAG}, where TAG is any alphabetic string, +sets TAG as the tag of the node, for later use by +custom line-drawing commands. +\item {\tt tri} connects the node to its mother with a `triangle of laziness'. +\item {\tt none} causes the line to the mother to be omitted +\item {\tt dash} causes the line to the mother to be dashes +\item {\tt dot} causes the line to the mother to be dotted + its mother +\end{examples} +Here's a sample illustrating some of the options: +\newpage +\begin{examples} +\item +\begin{verbatim} + .[ + S + NP + the puppy|tri|tag a + VP + V|dot + barked|tag b + .] +\abarnodeconnect ab +\end{verbatim} +\item +.[ + S + NP + the puppy|tri|tag a + VP + V|dot + barked|tag b +.] +\abarnodeconnect[1ex] ab +\end{examples} +Some more advanced possibilities will be illustrated later. + +\section{Node-Building Options} +There are various options for controlling the spacing and style +of nodes. +\subsection{Spacing} +Sometimes the default spacing produces not-so-good results. For example +the vanilla input (b) below produces the too-wide-and-spread-out result +(a): +\begin{examples} +\item +.[ +S + NP + the annoying child|tri + VP + V + V + ran + Prt + away + PP + from the crazed puppy|tri +.] +\newpage +\item +\begin{verbatim} + .[ + S + NP + the annoying child|tri + VP + V + V + ran + Prt + away + PP + from the crazed puppy|tri + .] +\end{verbatim} + +\end{examples} +We can make it look better by increasing the vertical mother-daughter +spacing by setting the \verb&\daughterskip& dimension, and decreasing the +horizontal spacing between sisters with the \verb&\sisterskip& dimension: +\begin{examples} +\item +\daughterskip=3ex +\sisterskip=1em +.[ +S + NP + the annoying child|tri + VP + V + V + ran + Prt + away + PP + from the crazed puppy|tri +.] +\item +\begin{verbatim} +\daughterskip=3ex +\sisterskip=1em + .[ + S + NP + the annoying child|tri + VP + . + . + . + .] +\end{verbatim} +\end{examples} +This is a bit better, but the triangles are still too flat, and there's a bit +too much space between the subject NP node and the top V. +These problems can be addressed with the \verb&\daughtergap& command, +placed somewhere in a node to set the vertical spacing to its +daughters, and the \verb&\sistergap& command, placed somewhere in a node +to set the spacing between it and its \emph{preceeding} daughter: +\begin{examples} +\item +\daughterskip=3ex +\sisterskip=1em +.[ +S + NP\daughtergap{4ex} + the annoying child|tri + VP\sistergap{0em} + V + V + ran + Prt + away + PP\daughtergap{5ex} + from the crazed puppy|tri +.] +\item +\begin{verbatim} +\daughterskip=3ex +\sisterskip=1em + .[ + S + NP\daughtergap{4ex} + the annoying child|tri + VP\sistergap{0em} + V + V + ran + Prt + away + PP\daughtergap{5ex} + from the crazed puppy|tri + .] +\end{verbatim} +\end{examples} + +\subsection{Nodes without Labels} +Sometimes we want at least some nonterminal nodes to lack labels. +Such trees look rather bad unless the lines all make constant +angles, which can be effected with the \verb&\treeslantratio{rise/run}& +command: +\begin{examples} +\item +\treeslantratio{4/10} +.[ +{} + {} + the + dog + {}\sistergap{-1em} + {} + freaked + out + {} + at + {} + the + cat +.] +\item +\begin{verbatim} + \treeslantratio{4/10} + .[ + {} + {} + the + dog + {}\sistergap{-1em} + {} + freaked + out + {} + at + {} + the + cat + .] +\end{verbatim} +\end{examples} +This works by seizing control of the vertical spacing, so +that \verb&\daughterskip& ceases to have any effect. + +Some trees look also look better with the length of the lines +kept mostly uniform, which can be achieved by setting the +\verb&\nodewidth& dimension, which causes all nodes to be treated +as having the value of that dimension as their width: +\begin{examples} +\item +\nodewidth=6em +\treeslantratio{7/20} +\sisterskip=1em +.[ +{} + John + {} + thinks + {} + that + {} + Suzie + {} + wants + {} + to + {} + kill + him +.] +\item +\begin{verbatim} + \nodewidth=6em + \treeslantratio{7/20} + \sisterskip=1em + .[ + {} + John + {} + thinks + {} + that + {} + Suzie + {} + wants + {} + to + {} + kill + him + .] +\end{verbatim} +\end{examples} +To my eye, the final branch looks a bit too wide; we can fix +this by using the \verb&dtwidths& preprocessor command to +set a different width for the daughters of some of the nodes +near the bottom. It takes a bit of fiddling to make things +look nice: +\begin{examples} +\item +\nodewidth=5em +\treeslantratio{7/20} +.[ +{} + John + {} + thinks + {} + that + {} + Suzie + {}|dtwidths 4.5em + wants + {}|dtwidths 3.5em + to + {}|dtwidths 3em + kill + him +.] +\item +\begin{verbatim} + \nodewidth=5em + \treeslantratio{7/20} + .[ + {} + John + {} + thinks + {} + that + {} + Suzie + {}|dtwidths 4.5em + wants + {}|dtwidths 3.5em + to + {}|dtwidths 3em + kill + him + .] +\end{verbatim} +\end{examples} +Fixed width nodes can easily result in labels overlapping each +other; one way to deal with this is to emulate the {\sf pst-jtree} +\verb&\longer& command by putting in a right-branch with a nolabel +node and no line: +\begin{examples} +\item +\hspace{4em} +\nodewidth=5em +\treeslantratio{7/20} +.[ +{} + {} + {} + the + {} + cheese + {} + that + {} + Fred + {} + ate + t + {}|none + {} + is + rotten +.] +\newpage +\item +\begin{verbatim} + \hspace{4em} + \nodewidth=5em + \treeslantratio{7/20} + .[ + {} + {} + {} + the + {} + cheese + {} + that + {} + Fred + {} + ate + t + {}|none + {} + is + rotten + .] +\end{verbatim} +\end{examples} + +\subsection{Stacking} +For writing LFG papers, there is a facility for `stacking' labels +and annotations, by separating the things to be stacked with the +`{\tt /}' symbol. So for an annotated tree we can write: +\begin{example} +\begin{verbatim} + .[ + S + ($\uparrow$ SUBJ)=$\downarrow$/NP + $\uparrow=\downarrow$/N + ($\uparrow$ PRED)=`Fido'/Fido + $\uparrow=\downarrow$/VP + $\uparrow=\downarrow$/V + ($\uparrow$ TENSE)=PAST/($\uparrow$ PRED)=`Bark(SUBJ)'/barked + .] +\end{verbatim} +\end{example} +which produces: +\begin{example} +.[ +S + ($\uparrow$ SUBJ)=$\downarrow$/NP + $\uparrow=\downarrow$/N + ($\uparrow$ PRED)=`Fido'/Fido + $\uparrow=\downarrow$/VP + $\uparrow=\downarrow$/V + ($\uparrow$ TENSE)=PAST/($\uparrow$ PRED)=`Bark(SUBJ)'/barked +.] +\end{example} +To include {\tt /} in the text, enclose it in braces. + +\subsection{Node Styles} +The default is that the bottom line of a terminal nodes is set in italics, +other things in roman. If you want the terminals to be, say slanted rather than +italics, you can do this by redefining \verb%\tstyle% as follows: +\verb%\def\tstyle{\sl}%. Similarly using \verb&\rm& if you want them +to be set in roman. The nonterminal style can be changed +with the same kind of redefinition of \verb%\ntstyle%. + +A more profound effect on nodes (which didn't used to work right) +can be achieved by redefining the \verb%\nodeannotation#1{}% +command, which is wrapped around each line in a stack (the same for +terminal and nonterminal). The default definition is: +\begin{example} +\begin{verbatim} +\gdef\nodeannotation#1{#1} +\end{verbatim} +\end{example} +But if you want to set each line of each node in math mode, without +having to write in lots of \$'s, you can do it by redefining +\verb%\nodeannotation% as follows: +\begin{example} +\begin{verbatim} +\def\nodeannotation#1{$#1$} +\end{verbatim} +\end{example} + +For a more likely use, which can involve a new preprocessor feature +as well, suppose you want to set trees whose nodes are avms, as +produced by Christopher Manning's {\sf avm.sty} file. If all of +the nodes are going to be avms, we can spare ourselves the annoyance +of typing out lots of \verb%\begin{avm}% and \verb%\end{avm}% commands +by redefining \verb%\nodeannotation%: +\begin{example} +\begin{verbatim} +\def\nodeannotation#1{\begin{avm}#1\end{avm}} +\end{verbatim} +\end{example} +The one-node-per line convention of {\tt trees.py} is irksome +for something like a complex avm, so there's a new `continuation +line' directive; if a line in a tree begins with {\tt .-}, then +it's interpreted as a continuation of the one before it: + +So using all this, example (12) from page 121 of Wechsler and Zlati\'{c} +(2003) {\it The Many Faces of Agreement} (CSLI Publications) can +be set like this: +\begin{examples} +\item +\begin{verbatim} +\def\nodeannotation#1{\begin{avm}#1\end{avm}} +\def\tstyle{\rm} + .[ + NP\[ HEAD & \@1\]\daughtergap{4ex} + \@2AP + ovih/these.GEN.PL + N$'$\[HEAD & \@1\] + N\[HEAD & \@1\\ + .- SPR & \<\@2\>\\ + .- COMPS& \<\@3\>\] + pet/five + \@3NP\daughtergap{3ex} + studenata/students.GEN.PL|tri + .] +\end{verbatim} +\item +\def\nodeannotation#1{\begin{avm}#1\end{avm}} +\def\tstyle{\rm} +.[ +NP\[ HEAD & \@1\]\daughtergap{4ex} + \@2AP + ovih/these.GEN.PL + N$'$\[HEAD & \@1\] + N\[HEAD & \@1\\ +.- SPR & \<\@2\>\\ +.- COMPS& \<\@3\>\] + pet/five + \@3NP\daughtergap{3ex} + studenata/students.GEN.PL|tri +.] +\end{examples} +Note that the stacking facility proved useful for HPSG as well as LFG, +and that the fact that all nodes were set as avm's doesn't matter, +since {\sf avm.sty} doesn't do anything until it encounters one of +its commands. + +\section{{\pstricks}-based techniques} +The use of {\pstricks} enables a substantial assortment of further +possibilities. {\sf lingtrees.sty} uses the {\sf pst-nodes} module +of {\pstricks} via a partial emulation of {\sf tree-dvips}, provided +by {\sf pst-tree-dvips-emu.sty}, which has its own included documentation +{\sf pst-tree-dvips-emu.doc.pdf}. In combination with {\sf lingtrees}, +you can combine techniques from the emulator (somewhat more convenient +for certain linguistics tasks) and {\pstricks} itself (much more +powerful). + +\subsection{More Line-Drawing Options} +The easiest is {\tt dotted}, which gives {\pstricks}-style round +dots instead of very short dashes: +\begin{examples} +\item +\begin{verbatim} + .[ + S + NP + the dog|tri|dotted + VP + V|dotted + barked + .] +\end{verbatim} +\item +.[ +S + NP + the dog|tri|dotted + VP + V|dotted + barked +.] +\end{examples} +Dots seem to be almost invisible with the usual {\sf lingtrees} line +thickness, so they're set a bit thicker with the dimension {\tt treedotwidth}, +which is set to 0.6pt in {\sf lingtrees.sty}. + +Any \verb&\psset&-able property of the connecting line can be set with the {\tt style} +option: what comes after `{\tt style}' must be an OK argument of +\verb&\psset&. For example: +\begin{examples} +\item +.[ +S + NP + the dog + VP\daughtergap{4ex} + V|dash|style dash=3pt 3pt, arrows=-> + barked +.] +\item +\begin{verbatim} + .[ + S + NP + the dog + VP\daughtergap{4ex} + V|dash|style dash=3pt 3pt, arrows=-> + barked + .] +\end{verbatim} +\end{examples} + +The {\tt after} option is followed by any well-formed string of +{\LaTeX} text, which appears in the output +after the node connection command. This is especially +useful for using the {\pstricks} label-positioning commands, which +appear after the command drawing the lines they are to attach +labels to. Here's an example where we use these to attach Greek letter +labels to some of the lines: +\begin{examples} +\item +.[ +S + NP|after \lput{U}(.2){\rput(-1.2em,.3ex){$\sigma$}} + the dog|tri + VP|after \lput{U}(.2){\rput(1.2em,.3ex){$\pi$}} + V|after \lput{U}{\rput(.8em,0ex){$\alpha$}} + barked|after \lput{U}(.3){\rput(.8em,0ex){$\lambda$}} +.] +\item +\begin{verbatim} + .[ + S + NP|after \lput{U}(.2){\rput(-1.2em,.3ex){$\sigma$}} + the dog|tri + VP|after \lput{U}(.2){\rput(1.2em,.3ex){$\pi$}} + V|after \lput{U}{\rput(.8em,0ex){$\alpha$}} + barked|after \lput{U}(.3){\rput(.8em,0ex){$\lambda$}} + .] +\end{verbatim} +\end{examples} +It is a bit tricky to get the positions right, but I think that +it's easier to position them relative to the lines than to the +nodes. + +My {\tt .dvi} viewer (Yap) doesn't get the positions of things placed by +{\tt lput} right, so check the results in postscript if things look wrong. + +The {\tt none} and {\tt after} options together can be used to +entirely replace the line-drawing command that the preprocessor +normally produces, but a slightly more convenient option +is {\tt connect}, whose following material is put in +place of the usual line-drawing command (\verb&\nodeconnect&), +in front of the mother and daughter arguments. So with +a {\tt connect} option such as \verb&\nodeconnect<\pccoil>&, +(see {\sf pst-tree-dvips-emu.doc.pdf}), +you could replace a normal line with a coil. + +A final preprocessor option is \verb &|width&, followed by a dimension, +which sets the width of a particular node, rather than its daughters. + +\subsection{Together with {\pstricks}} +A major reason for using {\pstricks} as the basis is to be able to combine +the powerful facilities of the latter with the convenience of the tree-formatter +and the {\sf tree-dvips} commands it uses. For example, one can produce something +like this, where {\pstricks} allows loops to be drawn around sets of nodes, +and labels to be attached to arrows: +\newpage +\begin{example} +\makebox[0ex]{}\\[5ex] +\hspace*{-1.8em} +\sisterskip=1.3em +.[ +S|tag s + NP|tag su + Det|tag sud + the + N|tag sun + dog + VP|tag vp + V|tag v + chased + NP\sistergap{2.5em}|tag ob + Det|tag obd + the + N|tag obn + cat +.] +{\SpecialCoor +% loop around subject +\putpoint{sutop}{1ex}(90)[t]{su} +\putpoint{sunrt}{1ex}(-40)[r]{sun} +\putpoint{sudlt}{1ex}(220)[l]{sud} +\psccurve(sutop)(sunrt)(sudlt) +% loop around S, VP V +\putpoint{stop}{2ex}(120)[t]{s} +\putpoint{vl}{1ex}(220)[l]{v} +\putpoint{vpr}{1ex}(-40)[br]{vp} +\putpoint{vprb}{1ex}(40)[tr]{vp} +\psccurve(stop)(vl)(vpr)(vprb) +% loop around object +\putpoint{obtop}{1ex}(90)[t]{ob} +\putpoint{obnrt}{1ex}(-40)[r]{obn} +\putpoint{obdlt}{1ex}(220)[l]{obd} +\psccurve(obtop)(obnrt)(obdlt) +% +\hskip 2em +\begin{avm} +\!{f}{\[SUBJ & \!{subj}{\[PRED & `Dog'\\ + NUM & SG\\ + CASE & NOM\]}\\ + TENSE & PAST\\ + OBJ & \!{obj}{\[PRED & `Cat'\\ + NUM & SG\\ + CASE & ACC\]} \]} +\end{avm} +% properties of phi arrows +\treelinewidth=1pt +\psset{linestyle=dotted} +% arrow to whole f-structure +\anodecurve[tr]{vprb}[l]f +\mput*{$\phi$} %label for this +% arrow to the SUBJ +\anodecurve[t]{sutop}[tl]{subj}[angleA=60,angleB=145] +\mput*{$\phi$} +\anodecurve[br]{obnrt}[bl]{obj}(.9)[angleA=-60] +\mput*{$\phi$} +}\vskip 4ex +\end{example} +This was produced as follow. First, the tree, with labels placed on many of the +nodes (also some preliminary stuff to help the diagram fit into the space +on the page): +\begin{example} +\begin{verbatim} +\makebox[0ex]{}\\[5ex] +\hspace*{-1.8em} +\sisterskip=1.3em + .[ + S|tag s + NP|tag su + Det|tag sud + the + N|tag sun + dog + VP|tag vp + V|tag v + chased + NP\sistergap{2.5em}|tag ob + Det|tag obd + the + N|tag obn + cat + .] +\end{verbatim} +\end{example} +And then some commands to place points at positions relative to the corners of +the nodes, and run closed curves through those points. These begin with +the {\pstricks} {\tt SpecialCoor} command, which allows a wide range of +`Special Coordinate' specifications to be used, such as, here, the name +of a node in parentheses as the specification of a point location: +\begin{example} +\begin{verbatim} + {\SpecialCoor +% loop around subject +\putpoint{sutop}{1ex}(90)[t]{su} +\putpoint{sunrt}{1ex}(-40)[r]{sun} +\putpoint{sudlt}{1ex}(220)[l]{sud} +\psccurve(sutop)(sunrt)(sudlt) +% loop around S, VP V +\putpoint{stop}{2ex}(120)[t]{s} +\putpoint{vl}{1ex}(220)[l]{v} +\putpoint{vpr}{1ex}(-40)[br]{vp} +\putpoint{vprb}{1ex}(40)[tr]{vp} +\psccurve(stop)(vl)(vpr)(vprb) +% loop around object +\putpoint{obtop}{1ex}(90)[t]{ob} +\putpoint{obnrt}{1ex}(-40)[r]{obn} +\putpoint{obdlt}{1ex}(220)[l]{obd} +\psccurve(obtop)(obnrt)(obdlt) +\end{verbatim} +\end{example} +The difference between \verb&\putpoint& and the {\pstricks} +command \verb&\uput& is that \verb&\putpoint& defines the +`corners' ({\tt tl}, {\tt tr}, {\tt br}, {\tt bl}) and +`edges' ({\tt t}, {\tt r}, {\tt b}, {\tt l} of the point, +which are all the same location, but allows the +{\tt pst-tree-dvips-emu.sty} commands \verb&\(a)nodeconnect& +and \verb&\(a)nodecurve& to work, and sets the default direction +of incoming arrows for the latter in accord with the standard +conventions of {\sf tree-dvips}. + +So next we produce the f-structure, done with +Chris Manning's {\sf avm.sty} package. In {\sf avm.sty}, the \verb&\!{lab}{stuff}& +command is an abbreviation inside avm's for \verb&\node{lab}{stuff}&, and it works +when the nodes are implemented by {\sf pst-tree-dvips-emu.sty} as well as original +{\sf tree-dvips.sty}: +\begin{example} +\begin{verbatim} +\hskip 2em +\begin{avm} +\!{f}{\[SUBJ & \!{subj}{\[PRED & `Dog'\\ + NUM & SG\\ + CASE & NOM\]}\\ + TENSE & PAST\\ + OBJ & \!{obj}{\[PRED & `Cat'\\ + NUM & SG\\ + CASE & ACC\]} \]} +\end{avm} +\end{verbatim} +\end{example} +And so all that remains is to draw the arrows from the +loops to the f-structures (representing the c-structure- +f-structure correspondence). One could use the the +{\pstricks} \verb&\pccurve& command for this, but +\verb&\anodecurve& is more convenient, although sometimes +we want to override the default angles for the corners and +the edges. After each connection comes a \verb&\mput*& +command to label the arrow. +\begin{example} +\begin{verbatim} + % properties of phi arrows + \treelinewidth=1pt + \psset{linestyle=dotted} + % arrow to whole f-structure + \anodecurve[tr]{vprb}[l]f + \mput*{$\phi$} %label for this + % arrow to the SUBJq + \anodecurve[t]{sutop}[tl]{subj}[angleA=60,angleB=145] + \mput*{$\phi$} + \anodecurve[br]{obnrt}[bl]{obj}(.9)[angleA=-60] + \mput*{$\phi$} +} +\end{verbatim} +\end{example} +I wish I could say it was easy to produce diagrams like +this with this method, but that would be an untruth. However +it is possible, and isn't ridiculously hard. + +\section{Availability} +This package may be found at +\url{http://arts.anu.edu.au/linguistics/people/AveryAndrews/Software/LaTeX}. +I plan to submit it to CTAN fairly soon. +\end{document} diff --git a/macros/latex/contrib/LingTrees/Examples/outputfiles.tex b/macros/latex/contrib/LingTrees/Examples/outputfiles.tex new file mode 100644 index 0000000000..11a06598a0 --- /dev/null +++ b/macros/latex/contrib/LingTrees/Examples/outputfiles.tex @@ -0,0 +1,20 @@ +\documentclass[12pt]{article} + +\usepackage{cm-lingmacros, trees, tree-test} + +\begin{document} + +This document uses trees written to independent files by the +{\tt trees} preprocessor. Here's the first one, one with {\tt .>}: +\begin{example} +\input trees/firsttree.tex +\end{example} +And here's the second, done likewise: +\begin{example} +\input trees/secondtree.tex +\end{example} +And here are two trees done with {\tt .>>}: +\begin{examples} +\input trees/twotrees.tex +\end{examples} +\end{document} diff --git a/macros/latex/contrib/LingTrees/Examples/outputfiles_trees.txp b/macros/latex/contrib/LingTrees/Examples/outputfiles_trees.txp new file mode 100644 index 0000000000..f2b2426ad1 --- /dev/null +++ b/macros/latex/contrib/LingTrees/Examples/outputfiles_trees.txp @@ -0,0 +1,44 @@ +.> trees/firsttree.tex +.[ +S + NP + Uther + VP + slept +.] + +this bit is ignored + +.> trees/secondtree.tex +.[ +S + NP + Uther + VP + woke +.] + +.>> trees/twotrees.tex +\item +.[ +S + NP + Merlin + VP + yawned +.] +\item +.[ +S\daughtergap{3ex} + NP + Elegabalus + VP + V + threw + NP + Det + a + N + party +.] + \ No newline at end of file diff --git a/macros/latex/contrib/LingTrees/Examples/pst-tree-dvips-emu.doc.tex b/macros/latex/contrib/LingTrees/Examples/pst-tree-dvips-emu.doc.tex new file mode 100644 index 0000000000..a9157d12f1 --- /dev/null +++ b/macros/latex/contrib/LingTrees/Examples/pst-tree-dvips-emu.doc.tex @@ -0,0 +1,358 @@ +\documentclass[12pt]{article} + +\usepackage{cm-lingmacros, pst-tree-dvips-emu, avm, pst-coil} + +\def\pstricks{PSTricks} + + \def\bck{\char'134} + +\def\makespace#1{\makebox[#1]{}} + +\begin{document} +\begin{center}{\large Partial Emulation of {\sf tree-dvips.sty} in {\pstricks} +({\sf pst-node} module)}\\ +Avery D Andrews\\ +Jan 2006 +\end{center} +The {\pstricks} package {\sf pst-node} is far more powerful than Emma Pease's +{\sf tree-dvips}, but the latter strikes me as being frequently more convenient +for tasks that arise in linguistics. So this is a partial emulation of +{\sf tree-dvips} built on the {\sf pst-node} module of \pstricks. +Most of the original {\sf tree-dvips} commands work unaltered +(\verb&\(a)nodecurve& being the most important exception), although some +have been extended to take advantage of the facilities of \pstricks. + +So in this emulation, some {\sf tree-dvips} facilities are extended to support +additional possibilities afforded by {\sf pst-node} (and its parent package +{\pstricks}), while others will require (modest) changes in the source text +to run. And there are a few completely new facilities which seem to me to +be useful and in the spirit of {\sf tree-dvips}, and easy to provide with +{\sf pst-node} available as the basis. + +One of the advantages of {\sf pst-node} is that many {\tt .dvi} viewers +understand its Postscript specials, so that lines will tend to be drawn. +However not always quite correctly: in Yap, for example (the Postscript +viewer that comes with MiKTeX), lines aren't drawn when they cross over nodes, +resulting in wrong-looking displays of arrows leading into f-structures, for +example. And some of the positioning commands don't work either. +So if things look wrong, check the postscript output before attempting +serious debugging of your line-drawing code. + +It might also be worth mentioning that the {\pstricks} error-messages aren't +always very illuminating, and the {\sf tree-dvips} emulation layer does +nothing to improve this situation. + +The treatment is divided into basics, which can be used without serious knowledge +of \pstricks, and advanced. It assumes previous knowledge of {\sf tree-dvips}. + +\section{Basic Commands} +\subsection{\tt \bck node(point)} +The \verb&\node& command looks just like it does in {\sf tree-dvips}: +\begin{example} +\begin{verbatim} +\node{label}{stuff} +\end{verbatim} +\end{example} +{\tt stuff} can be anything, even a regular {\pstricks} node. + +\verb&\nodepoint& is slightly extended with an option for the final argument +to be an angle, in parentheses: +\begin{example} +\begin{verbatim} +\nodepoint{label}[horizontal displacement][vertical displacement] +\nodepoint{label}[displacement](angle} +\end{verbatim} +\end{example} +where the displacements are dimensions, and the angle is a number, 0 by +default, so sole displacement is always horizontal to the right. + +\subsection{\tt \bck treelinewidth} +This is a dimension, setting the default width of the lines produced +by the node connection commands. Its default is .4pt, rather thinner +than default {\pstricks} lines. So if we want the thicken up the +node connection lines a bit, this will do the trick: +\begin{example} +\begin{verbatim} +\treelinewidth=.6pt +\end{verbatim} +\end{example} +The {\tt linewidth} graphics parameter in individual line-drawing commands +overrides this. + +\subsection{\tt \bck(a)nodeconnect} +\verb&\nodeconnect& takes the same arguments as in {\sf tree-dvips}, with a final optional +\verb&[ ]& argument taking {\pstricks} graphics parameters: +\begin{example} +\begin{verbatim} +\nodeconnect[from loc]{from node}[to loc]{to node}[gr. params] +\end{verbatim} +\end{example} +The locations are the usual edges and corners, +\verb&t&, \verb&tr&, \verb&r&, \verb&br&, \verb&b&, \verb&bl&, +\verb&l&, and \verb&tl&, with the obvious interpretations. + +So here's an example: +\begin{example} +\node{a}{\begin{tabular}{c}Some fairly\\silly stuff\end{tabular}}\hskip 3em +\node{b}{explained} +\nodeconnect[r]a[l]b[linewidth=1pt, nodesepB=.5ex] +\end{example} +which is produced by this input: +\begin{example} +\begin{verbatim} +\node{a}{\begin{tabular}{c}Some fairly\\silly stuff\end{tabular}}\hskip 3em +\node{b}{explained} +\nodeconnect[r]a[l]b[linewidth=1pt, nodesepB=.5ex] +\end{verbatim} +\end{example} +The final (new) {\tt [ ]} argument allows many further properties of the +line to be set; for example we get this: +\begin{example} +\node{a}{\begin{tabular}{c}Some fairly\\silly stuff\end{tabular}}\hskip 3em +\node{b}{explained} +\nodeconnect[r]a[l]b[linewidth=1pt, nodesepB=.5ex, arrows=->>] +\end{example} +from this: +\begin{example} +\begin{verbatim} +\node{a}{\begin{tabular}{c}Some fairly\\silly stuff\end{tabular}}\hskip 3em +\node{b}{explained} +\nodeconnect[r]a[l]b[linewidth=1pt, nodesepB=.5ex, arrows=->>] +\end{verbatim} +\end{example} +For the full assortment of graphics parameters, see the {\pstricks} +documentation, but here are some that strike me as useful in the +present context: +\begin{examples} +\item {\tt nodesep=Xdim}, {\tt nodesepA=Xdim}, {\tt nodesepB=Xdim}: the distance between +the edge of the node and the endpoints of the connection line; {\tt nodesep} +applies to beginning and the end, {\tt nodesepA} only to the beginning, +and {\tt nodesepB} only to the end. +\item {\tt arrows=ARR}: the style of arrow head, stated iconically (value of +{\tt -} gives no arrowhead) +\item {\tt linewidth=Xdim} +\item {\tt dashed}: (no value) +\item {\tt dash=Xdim Ydim}: {\tt Xdim} is the length of the blank portion, +{\tt Ydim} of the dashes +\item {\tt dotted}: (no value) +\end{examples} + +\verb&\anodeconnect& takes all the same arguments as \verb&\nodeconnect&, +but draws an arrowhead at the end of the connection. So from this: +\begin{example} +\begin{verbatim} +\node{a}{\begin{tabular}{c}Some fairly\\silly stuff\end{tabular}}\hskip 3em +\node{b}{explained} +\anodeconnect[r]a[l]b[nodesepB=.5ex] +\end{verbatim} +\end{example} +We get this: +\begin{example} +\node{a}{\begin{tabular}{c}Some fairly\\silly stuff\end{tabular}}\hskip 3em +\node{b}{explained} +\anodeconnect[r]a[l]b[nodesepB=.5ex] +\end{example} +You can or course specify an {\tt arrows} parameter with {\tt anodeconnect}, +but if you do, plain old {\tt nodeconnect} would do the job as well. + +\subsection{\tt \bck arrow(width|length)} +These aren't implemented, since the {\pstricks} scheme is so different. +Use: +\begin{example} +\begin{verbatim} +\psset{arrowsize=Xdim Y, arrowlength=Z. arrowinset=W} +\end{verbatim} +\end{example} +{\tt pst-tree-dvips-emu.sty} sets defaults which look decent to me. + + +\subsection{\tt \bck (a)nodecurve} +Not a full implementation, because the way in which {\pstricks} handles +curvature of links between nodes is quite different from the way in which +{\sf tree-dvips} does (and, I'd say, is better). {\sf tree-dvips} requires +a final argument which specifies the curvature in terms of a dimension, +with no sensible default, while {\pstricks} uses a number that does have +a sensible default. The current \verb&\anodecurve& command simply doesn't +read this final argument, so it will be dumped into the text, so that an +the input: +\begin{example} +\begin{verbatim} +\node{a}{the dog}\hskip 5em\node{b}{barked} +\nodecurve[tr]a[tl]b{2ex} +\end{verbatim} +\end{example} +produces this wrong result +\begin{example} +\node{a}{the dog}\hskip 5em\node{b}{barked} +\nodecurve[tr]a[tl]b{2ex} +\end{example} +What we have instead to specify curvature is an optional argument in +parentheses, containing one or two numbers, the bigger the number, the bigger +the `pull' of the curve away from its beginning or final endpoint. So to +get this: +\begin{example}\vskip 4ex +\node{a}{the dog}\hskip 5em\node{b}{barked} +\nodecurve[tr]a[tl]b(1.3) +\end{example} +we write this: +\begin{example} +\begin{verbatim} +\node{a}{the dog}\hskip 5em\node{b}{barked} +\nodecurve[tr]a[tl]b(1.3) +\end{verbatim} +\end{example} +And this: +\begin{example} +\begin{verbatim} +\node{a}{the dog}\hskip 5em\node{b}{barked} +\nodecurve[tr]a[tl]b(2,.4) +\end{verbatim} +\end{example} +yields this: +\begin{example} +\node{a}{the dog}\hskip 5em\node{b}{barked} +\nodecurve[tr]a[tl]b(2,.4) +\end{example} +And finally we get all the usual graphics parameterss in square brackets at +the end. Of these, there are two that are specifically important for curves, +{\tt angleA} and {\tt angleB}. These specify the angle at which the line +goes from its source and two its target node. If nothing is specified, +this is determined by the position just as in {\sf tree-dvips}. So we +can `flatten' the curve above by writing for example: +\begin{example} +%begin{verbatim} +\node{a}{the dog}\hskip 5em\node{b}{barked} +\nodecurve[tr]a[tl]b[angleA=20, angleB=160] +%\end{verbatim} +\end{example} +An angle of 0 degrees points to the right edge of the page. + +\subsection{\tt \bck (a)barnodeconnect} +As in {\sf tree-dvips.sty}, except with final graphics parameters. +So we get this: +\begin{example} +\node{a}{connect} some words with a + \node{b}{\tt barnodeconnect} command +\barnodeconnect {a}{b} +\end{example} +from this: +\begin{example} +\begin{verbatim} +\node{a}{connect} some words with a + \node{b}{\tt barnodeconnect} command +\barnodeconnect {a}{b} +\end{verbatim} +\end{example} +A useful set of options is {\tt offset(A|B)}, which shifts the connection +points to the left or right, so that: +\begin{example} +\begin{verbatim} +\node{a}{connect} some words with the + \node{b}{barnodeconnect} command +\barnodeconnect[2ex]{a}{b}[offsetB=3em] +\end{verbatim} +\end{example} +produces: +\begin{example} +\node{a}{connect} some words with the + \node{b}{barnodeconnect} command +\barnodeconnect[2ex]{a}{b}[offsetB=3em] +\end{example} + +And if we want an arrow at the end, we can use \verb&\abarnodeconnect&, +which takes all the same options. + + +\subsection{\tt \bck nodetriangle} +\verb&\nodetriangle{a}{b}[gr. params]& draws a triangle with apex +at bottom of {\tt a}, and base the top side of {\tt b} (for `triangles of +laziness') in syntax trees). + +\subsection{\tt \bck node\{circle|oval|box\}} +Circle and oval require dimensions to be specified, but since I have hopes of eventually +overcoming this limitations, the specifications are in parentheses even +though they're obligatory. For the circle there is one dimension, the radius, +for the oval, two: \verb&(height,width)&. Here's some sample input: +\begin{example} +\begin{verbatim} +\makespace{2em}\node{a}{A} +\nodecircle{a}(1em)[linewidth=1pt, linestyle=dotted]\\[4ex] +\makespace{2em}\node{a}{A} +\nodeoval{a}(2em, 1em)\\[4ex] +\end{verbatim} +\end{example} +These commands differ from the {\pstricks} ovalnode, etc, in that they +don't create nodes (ovalnodes containing text are bigger than a plain node +containing the same text), but just draw lines around a pre-existing +node. + +The \verb&\nodebox{node}& box works as in {\sf tree-dvips}, drawing +the box at a distance of \verb&\nodemargin& around its content. Put +as usual, there's an optional square-bracketted graphics parameter argument, +which can be used to specify the corner-rounding {\tt framearc} parameter: +\begin{examples} +\item +\node{a}{Some Stuff$\/$} +\nodebox{a}[framearc=.3] +\item +\begin{verbatim} +\node{a}{Some Stuff$\/$} +\nodebox{a}[framearc=.3] +\end{verbatim} +\end{examples} + + +\section{More advanced} +These commands depend on a bit more of a knowledge of {\pstricks} than +the previous ones. +\subsection{\tt \bck putpoint, \bck putstuff} +\verb&\putpoint& one puts a {\pstricks} point node at a position relative to a +{\sf tree-dvips} node center or corner. The usage is: +\begin{example} +\begin{verbatim} +\putpoint{new node name}{distance}(angle)[corner]{old node name} +\end{verbatim} +\end{example} +Where {\tt distance} can be either a single dimension (distance), or a + pair of dimensions + \verb&{horizontal, vertical}&, in which case the +angle is ignored. +For examples, see the file {\tt treetest.txp}, where it is used in +conjunction with \verb&\psccurve& to put loops around contiguous +sets of phrase-structure nodes. + +\verb&\putstuff& takes the same arguments, except that the first one +is any +regular text or {\LaTeX} code, rather than a label for a point node. + +\subsection{\tt (options) arguments to \bck nodeconnect} +In addition to the regular arguments, \verb&\nodeconnect& can take an +initial argument in angle-brackets, to specify the actual node connection +command to be used, followed by graphics parameters in parentheses. This makes +it easy to define variants of the node connection commands, such as +\verb%\coilconnect% +below: +\begin{examples} +\item +\begin{verbatim} +\def\coilconnect{\nodeconnect<\nccoil>(coilwidth=1ex,coilarmA=1ex, + coilarmB=2ex, arrows=->)} +\node{a}{source}\hskip 5em\node{b}{target} +\coilconnect[r]a[l]b +\end{verbatim} +\item +\def\coilconnect{\nodeconnect<\pccoil>(coilwidth=1ex,coilarmA=1ex, + coilarmB=2ex, arrows=->)} +\node{a}{source}\hskip 5em\node{b}{target} +\coilconnect[r]a[l]b +\end{examples} +Only \verb$\pc...$ commands will work here, their \verb$\nc...$ commands +will produce enigmatic errors, such as \verb&! Argument of \nodeloc has an extra }&. + +\subsection{\tt \bck nodeloc} +This command delivers locations of nodes, taking the corner/edge as the first, +argument, the node name as the second. These locations can only be used when +\verb$\SpecialCoor$ is active, and must be enclosed in parentheses to work. +For examples, look at some of the definitions in {\tt pst-tree-dvips-emu.sty}. + +\end{document} \ No newline at end of file diff --git a/macros/latex/contrib/LingTrees/Examples/simple.txp b/macros/latex/contrib/LingTrees/Examples/simple.txp new file mode 100644 index 0000000000..25c42075d1 --- /dev/null +++ b/macros/latex/contrib/LingTrees/Examples/simple.txp @@ -0,0 +1,20 @@ +\documentclass[12pt]{article} + +\usepackage{cm-lingmacros, lingtrees} + +\begin{document} +Here is a very simple example: +\begin{example} +.[ +S + NP + John + VP + V + bit + NP|tri + Fido's best mate|tri +.] +\end{example} +That was easy, wasn't it? +\end{document} \ No newline at end of file diff --git a/macros/latex/contrib/LingTrees/GUI/treebutton.py b/macros/latex/contrib/LingTrees/GUI/treebutton.py new file mode 100644 index 0000000000..8d80e53b87 --- /dev/null +++ b/macros/latex/contrib/LingTrees/GUI/treebutton.py @@ -0,0 +1,312 @@ +#! /usr/bin/python +# +# Saved in Unix format (by TextPad) so that the cretinous bash shell +# can find the interpreter. Above line may need to be tweaked for *nix +# depending on how Python is set up. +# +# COPYRIGHT 2005, 2006, Avery D Andrews 3rd, except for the DataDialog +# class cribbed from Frederik Lundh +# +# License: GPL 2 +# +# changelog at end + +import os, os.path, subprocess, sys, re, string, time +import Tix +from Tkinter import * +from Tkconstants import * +import zlib # (for compressed distributable) + +import trees + +################################# +# +# Default Options +# the r"..." notation causes backslashes to be taken verbatim, +# rather than as escapes +# +BALLOONWAIT = 2000 # delay for balloon help +FLOATONTOP = 0 #Windoze only + + +# +# crap to organize shutdown: isn't there a decent way to do this? +# +TCL_ALL_EVENTS = 0 + + +class RunSample: + + def __init__(self, w): + + + # + # defaults that can be overridden + # + + self.options = {'initwait' : BALLOONWAIT, + 'floatwin' : FLOATONTOP} + + for option in self.options.keys(): + setattr(self,option,self.options[option]) + + + # + # where am I + # + self.path = sys.path[0] + path1, path2 = os.path.split(self.path) + if path2 == "library.zip": + self.path=path1 + + # + # crap for organizing orderly shutdown + # + z = w.winfo_toplevel() + z.wm_protocol("WM_DELETE_WINDOW", lambda self=self: self.shutdown()) + self.exit = -1 + self.root = w + # + # the help balloon + # + balloon = Tix.Balloon(w, initwait=self.initwait) + # + # folderFrame line: an entry for the folder where the files are + # + folderFrame = Tix.Frame(w) + + self.folderName = StringVar() + self.treesFileName = StringVar() + self.floatWin = IntVar() + self.floatWin.set(FLOATONTOP) + + # + # make window float or not + # + if sys.platform[0:3]=="win": + self.floatWin.set(self.floatwin) + + def setFolder(event, self=self): + name = self.dirLabelEntry.entry.get() + self.folderName.set(name) + self.treesFileDialog.fsbox.config(directory=name) + self.treesFileName.set("") + self.texFileName.set("") + + self.dirLabelEntry = dirLabelEntry= Tix.LabelEntry(folderFrame, takefocus=0, + label='Folder: ', options = '''entry.width 20 label.width 9 label.anchor e''') + dirLabelEntry.entry["textvariable"] = self.folderName + dirLabelEntry.entry.bind("", setFolder) + dirLabelEntry.pack(side=RIGHT, expand=YES, fill=X) + balloon.bind_widget(dirLabelEntry, + msg="You can enter the directory for the trees file here, but it's usually better to browse with the '...' button below.\n") + folderFrame.pack(side=TOP, expand=YES, fill=X) + # + # next line: the Trees file + # + treesFrame = Tix.Frame(w) + self.treesLabelEntry = treesLabelEntry = Tix.LabelEntry(treesFrame, label = " Trees file: ", options = ''' + entry.width 20 + label.width 9 label.anchor e + ''') + + treesLabelEntry.entry["textvariable"] = self.treesFileName + + def treesFileCommand(filePath, self=self): + dirName, fileName = os.path.split(filePath) + self.treesFileName.set(fileName) + if dirName!=self.folderName.get(): +# print dirName +# print self.folderName.get() + self.folderName.set(dirName) + + self.treesFileDialog = treesFileDialog = Tix.ExFileSelectDialog(root, title="Trees File Selection", command=treesFileCommand) + self.treesFileDialog.fsbox.config(pattern="*.txp") + + def selectTreesFile(dialog=treesFileDialog): + dialog.popup() + + linepattern = re.compile("\s*(.+?)\s*=\s*(.+?)\s*$") + # + # load up history + # + self.historypath = historypath = os.path.join(self.path, "TreeButton.cfg") + if os.path.exists(historypath): + history = open(historypath,"r") + line = history.readline() + treesdir = treesFileDialog.fsbox.dir + while line != "": + linematch = linepattern.match(line) + if linematch: + if linematch.group(1)=="treesfolder": + treesdir.insert(0,linematch.group(2)) + elif linematch.group(1)=="folder": + self.folderName.set(linematch.group(2)) + elif linematch.group(1)=="treesfile": + self.treesFileName.set(linematch.group(2)) + else: + item = linematch.group(1) + if item == "floatwin": + self.floatWin.set(int(linematch.group(2))) + elif item in self.options.keys(): + setattr(self,item,linematch.group(2)) + else: + print "Unknown Setup Option: %s"%line + else: + print 'matchless: '+line + line = history.readline() + for dialog in (treesFileDialog,): + box = dialog.fsbox + list = box.dir.slistbox.listbox + if list.size()>0: + box.config(directory=list.get(0)) + + tbt = Tix.Button(treesFrame,text="...", command=selectTreesFile) + tbt.pack(side=RIGHT) + treesLabelEntry.pack(side=RIGHT, expand=YES, fill=X) + treesFrame.pack(side=TOP, expand=YES, fill=X) + # + # bottom line: the view buttons + # + runButFrame = Tix.Frame(w) + + def treesCommand(self=self): + os.chdir(self.folderName.get()) + treesFile = self.treesFileName.get() + base, ext = os.path.splitext(treesFile) + treesout = base+".tex" + global errfilename + trees.errfilename = base+".err" + if 1: + infile = open(treesFile, "r") + outfile = open(treesout, "w") + trees.process_file(trees.Source(infile), outfile) + if trees.error_occurred: + print "Trees had a problem" + return + else: + print "Trees ran without issues" + outfile.close() + + treesButFrame = Tix.Frame(runButFrame) + txb = Tix.Button(treesButFrame, text="Run Trees", command=treesCommand) + txb.pack(side=LEFT, anchor=W) + + + if sys.platform[0:3]=="win": +# floatFrame = Tix.Frame(w) + floatLabel = Tix.Label(treesButFrame, text="Keep TreeButton on top") + floatLabel.pack(side=RIGHT, anchor=E) + floatCheck = Tix.Checkbutton(treesButFrame, variable=self.floatWin, + command=lambda self=self: self.checkFloat()) + floatCheck.pack(side=RIGHT, anchor=E) +# floatFrame.pack(side=TOP, anchor=W) + + treesButFrame.pack(side=LEFT,anchor=N) + + runButFrame.pack(side=TOP) + + + if sys.platform[0:3]=="win": + # if 0: # disable this stuff for now + menubar = Menu(w) + w.configure(menu = menubar) + system_menu = Menu(menubar, tearoff=0, name="system") + system_menu.add_separator() + for (label, command) in [("Run trees", treesCommand), + ]: + system_menu.add_command(label=label, command=command) + menubar.add_cascade(menu = system_menu) + + + # + # load icon if possible s/b late to avoid goofy-looking startup + # + iconpath = os.path.join(self.path,'treerunner.ico') + if os.path.exists(iconpath): + self.iconpath = iconpath + try: + z.wm_iconbitmap(bitmap=iconpath) + except: + pass + else: + self.iconpath = None + # + # ready to rock and roll + # + print "TreeButton is ready." + + + # + # float on top stuff + # + def checkFloat(self): + if sys.platform[0:3]=="win": + self.root.wm_attributes("-topmost", self.floatWin.get()) + if self.floatWin.get()==0: + self.root.lift() + + # + # shutdown crap + # + def mainloop(self): + while self.exit < 0: + self.root.tk.dooneevent(TCL_ALL_EVENTS) + + + def shutdown(self): + global errno, strerror + try: + history = open(self.historypath,"w") + for label, list in [("treesfolder", self.treesFileDialog.fsbox.dir.slistbox.listbox)]: + try: + for i in range(list.size()-1,-1,-1): + history.write("%s = %s\n"%(label, list.get(i))) + if i==10: + break + except TclError: + print "Tcl had a problem; no history saved" + history.write("%s = %s\n"%('folder',self.folderName.get())) + history.write("%s = %s\n"%('treesfile',self.treesFileName.get())) + for option in self.options.keys(): + value = getattr(self,option) + if option == "floatwin": + value = `self.floatWin.get()` + if value!=self.options[option]: + history.write("%s = %s\n"%(option, value)) + history.close() + except Exception, instance: + print instance.__class__.__name__ + ": "+str(instance) + +# print "*"+`texlist.get(0, texlist.size()-1)`+"*" + + self.exit=0 + + + print "Goodbye from TreeButton" + + + + +if __name__ == '__main__': + # + # sys.path[0] is the folder containing the script, + # + # print sys.path + + errfilename = "" + + root = Tix.Tk(className=" TreeButton") + runner = RunSample(root) +# root.wm_attributes("-topmost", 1) + runner.checkFloat() + runner.mainloop() + +# +# changelog +# +# Mar 5 2006 +# derive from TreeRunner by removing stuff +# +# Feb 14 2006 +# version 1 diff --git a/macros/latex/contrib/LingTrees/GUI/treerunner.ico b/macros/latex/contrib/LingTrees/GUI/treerunner.ico new file mode 100644 index 0000000000..595545d05e Binary files /dev/null and b/macros/latex/contrib/LingTrees/GUI/treerunner.ico differ diff --git a/macros/latex/contrib/LingTrees/GUI/usage.txt b/macros/latex/contrib/LingTrees/GUI/usage.txt new file mode 100644 index 0000000000..03c0f51cb3 --- /dev/null +++ b/macros/latex/contrib/LingTrees/GUI/usage.txt @@ -0,0 +1,24 @@ + + TreeButton GUI for Trees + +Put treebutton.py and treerunner.ico in the same folder as trees.py. +The icon only works in Windoze. + +Requires Python 2.4 with Tkinter and Tix installed. These are now +nominally standard parts of a Python distribution, but don't always +appear in all Linux distros as of March 2006. E.g. Tix seems to be +broken in Ubuntu 5.10, and absent from the default install of SUSE 10.0 +(but present if you select all the geek stuff). I had success with +ActiveState python 2.4.10 on Ubuntu (installed GNU readline5.1 prior +to that; dunno if that was essential) + +Freestanding Windows executables with installer may be found at: + + http://arts.anu.edu.au/Linguistics/People/AveryAndrews/Software/latex + +TreeButton can be made to interact reasonably well with the TeXnicCenter +front-end for (La)TeX by changing the "%Wm" at the end of the command +line specifications in the output profiles to "%bm" (base-name without +extension of file being edited). Then you can have the .txp file +loaded in the TXC window, push the TreeButton button to run Trees, and +then build as usual in TXC. \ No newline at end of file diff --git a/macros/latex/contrib/LingTrees/README b/macros/latex/contrib/LingTrees/README new file mode 100644 index 0000000000..10660a21f5 --- /dev/null +++ b/macros/latex/contrib/LingTrees/README @@ -0,0 +1,46 @@ + + LingTrees Linguistics Tree-formatting Preprocessor and Macros + Avery D Andrews, March 2006 + +Purpose: + +This is a LateX2e package for formatting linguistics trees (upside-down, +hanging by the root, with slanted branches from mother to daughters), +consisting of a prepreprocessor written in Python (freely downloadable from +http://www.python.org or http://www.activestate.com; the latter might be +easier to get working in Linux), and some LaTeX .sty files. The preprocessor +allows trees to be entered as indented lists (no brackets to worry about), +and also deploys line-drawing and various other commands. The macros are +responsible for the details of positioning. Plain TeX is currently not +supported. + +In addition to the preprocessor itself (trees.py), there's a simple +GUI for running it by pushing a button in the GUI subdirectory. +Free-standing executables for Windows may be found at: + + http://arts.anu.edu.au/Linguistics/People/AveryAndrews/Software/latex + +The package is probably most suitable for irregularly-branching trees +with wide and complex node-labels, such as are prevalent for example in +LFG and HPSG. Other packages that might be worth looking at are pst-jtree +(good for heavily right-branching trees with small node-labels) and +qtree (which works with pdflatex). It is an upwards-compatible +successor to the 'trees' package at CTAN/latex209/contrib/pstrees/trees. + +Dependencies: + +It requires either the pst-nodes module of the PSTricks, or Emma Pease's +tree-dvips (with less functionality), both available on CTAN. + +License: + + LaTeX macros: LaTeX Project Public License + trees.py: GPL 2 + +Documentation: + +The documentation for the macros and preprocessor commands is in the +file lingtrees.doc.pdf. pst-nodes is accessed thru a partial emulation +of tree-dvips, documented in pst-tree-dvips-emu.doc.pdf. + +For more information, see READMORE.txt and the pdf documentation. diff --git a/macros/latex/contrib/LingTrees/READMORE.txt b/macros/latex/contrib/LingTrees/READMORE.txt new file mode 100644 index 0000000000..cd37b3ad6d --- /dev/null +++ b/macros/latex/contrib/LingTrees/READMORE.txt @@ -0,0 +1,123 @@ + + + LingTrees Linguistics Tree-formatting Preprocessor and Macros + Avery D Andrews, March 2006 + +Purpose: + +This is a LateX2e package for formatting linguistics trees (upside-down, +hanging by the root, with slanted branches from mother to daughters), +consisting of a prepreprocessor written in Python (freely downloadable from +http://www.python.org or http://www.activestate.com; the latter might be +easier to get working in Linux), and some LaTeX .sty files. The preprocessor +allows trees to be entered as indented lists (no brackets to worry about), +and also deploys line-drawing and various other commands. The macros are +responsible for the details of positioning. Plain TeX is currently not +supported. + +In addition to the preprocessor itself (trees.py), there's a simple +GUI for running it by pushing a button in the GUI subdirectory. +Free-standing executables for Windows may be found at: + + http://arts.anu.edu.au/Linguistics/People/AveryAndrews/Software/latex + +The package is probably most suitable for irregularly-branching trees +with wide and complex node-labels, such as are prevalent for example in +LFG and HPSG. Other packages that might be worth looking at are pst-jtree +(good for heavily right-branching trees with small node-labels) and +qtree (which works with pdflatex). It is an upwards-compatible +successor to the 'trees' package at CTAN/latex209/contrib/pstrees/trees. + +Dependencies: + +It requires either the pst-nodes module of the PSTricks, or Emma Pease's +tree-dvips (with less functionality), both available on CTAN. The source +for the documentation file lingtrees.doc.txp also requires Chris +Manning's avm.sty, of which version 1.02 is also included here with +permission. + +License: + + LaTeX macros: LaTeX Project Public License + trees.py: GPL 2 + +Documentation: + +The documentation for the macros and preprocessor commands is in the +file lingtrees.doc.pdf. pst-nodes is accessed thru a partial emulation +of tree-dvips, documented in pst-tree-dvips-emu.doc.pdf. + + +Installation: + +The .sty files are: + + lingtrees.sty + pst-tree-dvips-emu.sty + lingrees-without-pstricks.sty + avm.sty and cm-lingamcros (by Chris Manning), needed for generating the + docs; see http://nlp.stanford.edu/~manning/tex/ for more information. + +put them whereever you put your custom LaTeX files. You will +also need to have Pstricks or tree-dvips installed (both available +on CTAN, and already present in many LaTeX distributions). + +For the preprocessor itself, script trees.py can be +run directly with Python. Or, Windows users can collect a free-standing +executable with an installer from + + http://arts.anu.edu.au/Linguistics/People/AveryAndrews/Software/latex + +The exact procedure for running trees.py depends on the OS. A rather +generic procedure that should always work is: + + 1. put trees.py in some folder, say c:\bin + 2. have a terminal/dos window cd'd to the folder where your work is + 3. have the input file called something like work.txp (.txp + being the assumed extension for the input file) + 4. type: + python c:\bin\trees.py work + (no extension; assumes the Python executable is on your PATH) + 5. the output should be written to work.tex (.tex being + the supplied extension for the output file) + +It should however usually be possible to get the script to run just +by typing their names. + +For Linux, Unix, etc. you can place the script somewhere on your PATH +variable, make it executable, and perhaps edit the 'shebang' line at +the top to reflect exactly where Python is (and maybe remove the .py +extension from the name). + +For Windows 2000 and XP, you can again put the script somewhere on your +path, and then select Start|Settings|Control Panel|System|Advanced| +Environment Variables, and edit or add PATHEXT so that it ends with +.PY;.PYW. If you have Administrator privileges you can do this in the +System Variables for everybody; otherwise only in the User Variables for +yourself. + +trees.py will also run as a filter, but due to a bug in the handling of +io-redirection in Windoze with PATHEXT, you have to explicitly invoke +Python in order for this to work, i.e.: + + python c:\exe\trees.py < work.txp > work.tex + +Win9x users can use the generic method above, or get the free-standing +executable. Frederik Lundh's exemaker program would also be a way +to avoid invoking Python explicitly (although it does require +python to be installed). + +Generating the Docs: + +The docs sources are in the Samples folder. To generate them you'll +need cm-lingmacros.sty and amv.sty, included here in the CDM folder, +and: + + urls.sty ([CTAN]macros/latex/contrib/misc/url.sty) + PStricks ([CTAN]graphics/pstricks; pst-node and pst-coil modules) + +Both included in MikTeX large. + + + + diff --git a/macros/latex/contrib/LingTrees/changelog.txt b/macros/latex/contrib/LingTrees/changelog.txt new file mode 100644 index 0000000000..28c121297d --- /dev/null +++ b/macros/latex/contrib/LingTrees/changelog.txt @@ -0,0 +1,9 @@ +Feb 28, 2006 (3.0) + +Labelless nodes, fixed node width spacing working. + +Get +Jan 30, 2006 (3.0 beta) + +Rewrite as trees package as lingtrees package, using pst-nodes + instead of tree-dvips. diff --git a/macros/latex/contrib/LingTrees/lingtrees-without-pstricks.sty b/macros/latex/contrib/LingTrees/lingtrees-without-pstricks.sty new file mode 100644 index 0000000000..ce0a5d07fb --- /dev/null +++ b/macros/latex/contrib/LingTrees/lingtrees-without-pstricks.sty @@ -0,0 +1,9 @@ +% +% defines LingTreesNoPSTricks in order to block loading of pst-node.sty +% by lingtrees.sty, and make it load tree-dvips.sty instead +% +% +\let\LingTreesWithoutPSTricks\relax +\input lingtrees.sty + + diff --git a/macros/latex/contrib/LingTrees/lingtrees.doc.pdf b/macros/latex/contrib/LingTrees/lingtrees.doc.pdf new file mode 100644 index 0000000000..332903b8e3 Binary files /dev/null and b/macros/latex/contrib/LingTrees/lingtrees.doc.pdf differ diff --git a/macros/latex/contrib/LingTrees/lingtrees.sty b/macros/latex/contrib/LingTrees/lingtrees.sty new file mode 100644 index 0000000000..80d9b827f2 --- /dev/null +++ b/macros/latex/contrib/LingTrees/lingtrees.sty @@ -0,0 +1,366 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Version: 28 Dec 2005 +%% changelog at end +%% +%% Primitive Linguistics Tree Formatter +%% +%% Copyright (c) 1991, 2005, 2006 Avery DeLano Andrews 3rd +%% These macros can be redistributed and/or modified under the terms +%% of the LaTeX Project Public License Distributed from CTAN +%% archives in directory macros/latex/base/lppl.txt. +%% +%% Parameter-list handling technique cribbed from gloss.sty +%% by Marcel R. van der Goot (1990). +%% Advice and some edits by Christopher D Manning +%% +%% License: LaTeX Project Public License +%% +%% 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: +%% {{}} +%% {, , }, 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. & +%% 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{} in a mother node sets mother-daughter +%% spacing to for daughters of that node. +%% \sistergap{} in a node spaces it 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. +%% +%% Annotation are now by default in the current mode (usually text). +%% If you want to switch on 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 +%% School of Language Studies +%% Faculty of Arts +%% The Australian national University +%% Acton ACT 2600 +%% +%% email: Avery.Andrews@anu.edu.au +%% +%% Changelog: +%% 27 Dec 2005: \nodeannotation bugfixed +%% \sistergap bug fixed +%% +%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\csname LingTreesLoaded\endcsname +\let\LingTreesLoaded\endinput + +\ifx\LingTreesWithoutPSTricks\relax\input tree-dvips.sty\else +\ifx\PSTTreeDvipsEmuLoaded\endinput\else\input pst-tree-dvips-emu.sty\fi\relax\fi\relax + +\def\CR{ +} +{ +\catcode`\_=11 % sets underbar to letter +\catcode` =9 % causes spaces to be ignored +\catcode`\^^M=9 % causes 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 +\newdimen\raise_daughter + + +\newdimen\daughter_spread +\newcount\daughter_count +\newcount\treerationum +\newcount\treeratiodenom +\global\treerationum=0 +\global\treeratiodenom=0 +\gdef\treeslantratio#1{\@treeslantratio[#1]} +\gdef\@treeslantratio[#1/#2]{% +\treerationum=#1 +\treeratiodenom=#2 +} + +\newdimen\treedotwidth +\global\treedotwidth=0.6pt + +\newdimen\nodewidth +\newdimen\node_width +\global\nodewidth=0em +\gdef\@nwbox#1{\hbox{\makebox[\node_width][c]{#1}}} +\gdef\@ifnodewidthzero#1#2{\ifdim\node_width=0em #1\else #2\fi} +\gdef\@fwbox#1{\@ifnodewidthzero{\hbox{#1}}{\@nwbox{#1}}} + +\gdef\setnodewidth#1{\global\node_width=#1} + +\gdef\daughtergap#1{\global\daughter_skip=#1} % chris: should remove global? +\gdef\sistergap#1{\global\sister_skip=#1} % avery: no, doesn't work. wish I could + % remember how it was supposed to! + +% 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\treeann#1{\node_ann{#1}} % annotation stack + +% for centered tree in math mode. cdm Mar 1996 +\gdef\treecent#1{\tree_node#1,.\ifvmode\leavevmode\fi\vcenter{\box\treebox}} + +\gdef\tree_node#1,#2.{ + \def\daughters{#2} + \ifx\daughters\empty % if terminal +% \message{terminal\CR} + \global\setbox\treebox=\@fwbox{#1} +% \message{got_term} + \global\treewidth=\wd\treebox + \global\treecenter=.5\treewidth + \else +% \message{get daughters} + \global\node_width=\nodewidth%\message{RestoreA\CR} + \get_daughters#2. +% \message{got daughters} + \global\node_width=\nodewidth%\message{RestoreB\CR} + \ifnum\treeratiodenom=0 + \daughtergap{\daughterskip} + \else + \ifnum\daughter_count=1 + \daughtergap{\daughterskip} + \else + \daughter_spread=\last_center + \advance \daughter_spread by -\first_center + \multiply \daughter_spread by \treerationum + \divide\daughter_spread by \treeratiodenom + \daughtergap{\daughter_spread} + \fi + \fi + \setbox\mother_box=\@fwbox{#1} +% \message{got mother\CR} + \ifdim\ht\mother_box=0em + \advance\daughter_skip by -2\nodemargin + \fi + \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 + \@ifnodewidthzero + {\global\treewidth=\wd\treebox} + {\global\treewidth=\node_width} + \global\treecenter=\daughter_center + \ifdim\mother_offset<0pt + \global\advance\treecenter by -\mother_offset + \fi +% \global\node_width=\nodewidth\message{Restore\CR} + \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! [cdm] + +\gdef\d@@mmy.{}{} % two-argument version. + +\gdef\get_daughters#1,#2.{ +% \global\node_width=\nodewidth\message{PreRestore\noexpand\node_width\CR} + {\treenode#1} % process first daughter +% \message{got first daughter\CR} + \first_center=\treecenter + \last_center=\treewidth + \daughter_count=1 + \setbox\daughter_box=\hbox{\raise\raise_daughter\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. + \@ifnodewidthzero{} + {\global\setbox\daughterr_box=\@fwbox{\box\daughterr_box} + \global\daughter_center=.5\node_width + } +} + +\gdef\more_daughters#1,#2.{ + \sistergap{\sisterskip} + \node_width=\nodewidth + {\treenode#1} + \advance\daughter_count by 1 + \@ifnodewidthzero % leave out sisterskip for fixed width + {\setbox\daughter_box=\hbox{ + \unhbox\daughter_box\hskip\sister_skip\raise\raise_daughter\box\treebox}} + {\setbox\daughter_box=\hbox{ + \unhbox\daughter_box\raise\raise_daughter\box\treebox}} + \def\more{#2} + \ifx\more\empty + \advance\last_center by \treecenter + \@ifnodewidthzero + {\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 + \@ifnodewidthzero + {\advance\last_center by \sister_skip} + {} + \let\more=\more_daughters + \fi + \more#2. + \sistergap{\sisterskip} +} + + +\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 + \ifdim\stack_width=0em + \hbox to\stack_width{\vbox to 0em{}} + \global\raise_daughter=\ht\strutbox + \else + \hbox to \stack_width{\strut\hss\t_style {\nodeannotation{#1}}\hss} + \global\raise_daughter=0ex + \fi + \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 math, (for f-descriptions?) but this was a pain! +% \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 \nodeannotation{#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 + +%% Changelog +%% +%% 26 Feb 2006 +%% get vertical spacing with no-label nodes to work +%% \setnodewidth command and ancilliaries working +%% +%% 28 Dec 2005 +%% fix bugs with \nodeannotation and \sistergap +%% +%% 21 Sep 1997 + diff --git a/macros/latex/contrib/LingTrees/pst-tree-dvips-emu.doc.pdf b/macros/latex/contrib/LingTrees/pst-tree-dvips-emu.doc.pdf new file mode 100644 index 0000000000..459378e968 Binary files /dev/null and b/macros/latex/contrib/LingTrees/pst-tree-dvips-emu.doc.pdf differ diff --git a/macros/latex/contrib/LingTrees/pst-tree-dvips-emu.sty b/macros/latex/contrib/LingTrees/pst-tree-dvips-emu.sty new file mode 100644 index 0000000000..a6fc94dc33 --- /dev/null +++ b/macros/latex/contrib/LingTrees/pst-tree-dvips-emu.sty @@ -0,0 +1,451 @@ +%% +%% Partial Emulation of Emma Pease's tree-dvips.sty using pst-nodes +%% +%% version 0.5 (an alpha) +%% +%% License: LaTeX Project Public License +%% +%% c. Avery D Andrews 2006 +%% +%% acknowledgements +%% Herbert Voss for info on how to get at the corners +%% Robert Levine and John Frampton for incitement +%% Emma Pease for the original +%% +%% the philosophy is to combine a reasonable amount of backward +%% compatibility for documents based on tree-dvips, without +%% trying to push that notation much further (but a little bit, +%% if it's easy and seems like it might be useful). +%% +%% \(a)nodecurve seems to be the biggest problem, since tree-dvips +%% wants dimension for curvature, and pst-node's nccurv etc. +%% want numbers. The solution adopted is have \(a)nodecurve require +%% numbers in the curvature parameters, so that these will have to +%% be changed in the documents, but add \pcnodecurve not requiring +%% any curvature parameters, but taking linestyle options as a final +%% optional [] parameter. +%% +%% \nodepoint affords a similar problem; no easy way to get vert +%% displacement. Implementation treats height parameter as angle +%% +%% Implemented: +%% \node +%% \nodepoint (extended with angle option) +%% \(a)nodeconnect, \nodeconnect (extended) +%% \treelinewidth +%% \(a)nodecurve (with curvature issue) +%% \pcnodecuve (non tree-dvips) +%% \(a)barnodeconnect +%% \nodetriangle +%% \putstuff: non-tree-dvips, but useful +%% \putpoint: " +%% +%% Partially Implemented: +%% +%% \nodebox, \nodeoval, \nodecircle : dimension parameters needed +%% + +\csname PSTTreeDvipsEmuLoaded\endcsname +\let\PSTTreeDvipsEmuLoaded\endinput + +\ifx\PSTnodesLoaded\endinput\else\input pst-node.tex\fi\relax + + +{ +\catcode`\_=11 % sets underbar to letter +\catcode` =9 % causes spaces to be ignored +\catcode`\^^M=9 % causes to be ignored + +% +% Some tree mode parameters (from tree-dvips.sty) +% +% +\newdimen\nodemargin % +\global\nodemargin=2pt +\newdimen\treelinewidth + +\global\treelinewidth=.4pt + +\newbox\tempbox + +\gdef\thinline{\treelinewidth=.3pt} + +\newdimen\dashlength +% +% makedash at end so spaces will work +% + +% +% cheap and nasty test for empty argument, assuming a real +% one doesn't start with a colon +% +\gdef\ada@ifempty#1#2#3{\test@empty#1:{#2}{#3}} +\gdef\test@empty{\@ifnextchar :{\@testfirst}{\@testsecond}} +\gdef\@testfirst#1:#2#3{#2} +\gdef\@testsecond#1:#2#3{#3} + +\gdef\ada@ifnotempty#1#2{\ada@ifempty{#1}{}{#2}} + +% +% machinery for parsing an arglist of the form [a(,b)] +% n-ary generalization possible? Yes, see gloss/lingtrees code! +% +\gdef\oneortwoargs#1#2[#3]{\@oneortwoargs{#1}{#2}[#3,]} +\gdef\@oneortwoargs#1#2[#3,{\@ifnextchar ] + {#1[#3} + {\@secondarg{#2}[#3]} +} +\gdef\@secondarg#1[#2]#3,]{#1[#2,#3]} + +% +% These commands retrieve coords from names, for use when +% pstricks \SpecialCoor is active. They must be surrounded +% by parens in their environments in order to work +% +\gdef\loc@tl#1{#1_tl} +\gdef\loc@t#1{#1|#1_tl} +\gdef\loc@tr#1{#1_br|#1_tl} +\gdef\loc@r#1{#1_br|#1} +\gdef\loc@br#1{#1_br} +\gdef\loc@b#1{#1|#1_br} +\gdef\loc@bl#1{#1_tl|#1_br} +\gdef\loc@l#1{#1_tl|#1} +\gdef\loc@c#1{#1} + +\gdef\ang@tl{135} +\gdef\ang@t{90} +\gdef\ang@tr{45} +\gdef\ang@r{0} +\gdef\ang@br{-45} +\gdef\ang@b{-90} +\gdef\ang@bl{-135} +\gdef\ang@l{180} + + +% +% a prettier package for the above, usable in the document +% +\gdef\nodeloc#1#2{\csname loc@#1\endcsname{#2}} +% #2 for node; does nothing yet, but maybe someday ... +\gdef\nodeang#1#2{\csname ang@#1\endcsname} + + +% \node{label}{content} +% Perhaps a dive into postscript could let us do it with one node instead of 3 +% (if, in postscript, nodes know how big they are) +% +\gdef\node#1#2{ + \rnode[tl]{#1_tl}{ + \rnode[br]{#1_br}{ + \rnode{#1}{#2} + } + } +} + +% +% \nodepoint{nodename}[displacement distance](angle) +% default is current point. Maybe someday [vertical displacement] +% +\gdef\nodepoint#1{\@ifnextchar [{\@nodepoint#1}{\pnode{#1}}} +\gdef\@nodepoint#1[#2]{\@ifnextchar ({\@@nodepoint#1[#2]} + {\@ifnextchar [{\@@@nodepoint#1[#2]} + {\@@nodepoint#1[#2](0)} + } +} +\gdef\@@nodepoint#1[#2](#3){{ + \SpecialCoor + \pnode{@a} + % + % this below seems excessive but how else to get \nodeconnect to work? + % + \uput{#2}[#3](@a){\pnode{#1}\pnode{#1_tl}\pnode{#1_br}} +}} + +\gdef\@@@nodepoint#1[#2][#3]{{ + \psset{xunit=#2, yunit=#3} + \uput{0}[0](1,1){\pnode{#1}\pnode{#1_tl}\pnode{#1_br}} + }} + +% \putpoint{label}{distance}(angle)[from corner]{from node} +% 1 2 3 4 5 +% 2 is either {num} or {num,num}=x,y; in the latter case 3 is ignored +% +\gdef\putpoint#1#2{\@ifnextchar ( + {\@putpoint{#1}{#2}} + {\@putpoint{#1}{#2}(0)} +} +\gdef\@putpoint#1#2(#3){\@ifnextchar [ + {\@@putpoint{#1}{#2}(#3)} + {\@@putpoint{#1}{#2}(#3)[]} +} +\gdef\@@putpoint#1#2(#3)[#4]#5{ + \def\procloc[##1]{\oneortwoargs{\oneloc}{\twolocs}[##1]} + \def\oneloc[##1]{\putpoint_ang} + \def\twolocs[##1,##2]{\putpoint_cart} + \procloc[#2]{#1}[#2]{#3}[#4]{#5} +} +\gdef\putpoint_ang#1[#2]#3[#4]#5{{ + \SpecialCoor + \uput{#2}[#3](\nodeloc{#4}{#5}){\nodepoint{#1}} + \uput{#2}[#3](\nodeloc{#4}{#5}){\nodepoint{#1_tl}} + \uput{#2}[#3](\nodeloc{#4}{#5}){\nodepoint{#1_br}} +}} +\gdef\putpoint_cart#1[#2,#3]#4[#5]#6{{ + \SpecialCoor +% \message{xunit is #2} + \ifdim #2=0em + \putpoint_ang{#1}[#3]{90}[#5]{#6} + \else + \ifdim #3=0em + \putpoint_ang{#1}[#2]{0}[#5]{#6} + \else + \psset{xunit=#2,yunit=#3} + \rput(\nodeloc{#5}{#6}){\uput{0}[0](1,1){\nodepoint{#1}}} + \rput(\nodeloc{#5}{#6}){\uput{0}[0](1,1){\nodepoint{#1_tl}}} + \rput(\nodeloc{#5}{#6}){\uput{0}[0](1,1){\nodepoint{#1_br}}} + \fi + \fi +}} + +% \putstuff{label}{distance}(angle)[from corner]{from node} +% 1 2 3 4 5 +% 2 is either {num} or {num,num}=x,y; in the latter case 3 is ignored +% +\gdef\putstuff#1#2{\@ifnextchar ( + {\@putstuff{#1}{#2}} + {\@putstuff{#1}{#2}(0)} +} +\gdef\@putstuff#1#2(#3){\@ifnextchar [ + {\@@putstuff{#1}{#2}(#3)} + {\@@putstuff{#1}{#2}(#3)[]} +} +\gdef\@@putstuff#1#2(#3)[#4]#5{ + \def\procloc[##1]{\oneortwoargs{\oneloc}{\twolocs}[##1]} + \def\oneloc[##1]{\putstuff_ang} + \def\twolocs[##1,##2]{\putstuff_cart} + \tracingmacros=1 + \procloc[#2]{#1}[#2]{#3}[#4]{#5} +} +\gdef\putstuff_ang#1[#2]#3[#4]#5{{ + \SpecialCoor + \uput{#2}[#3](\nodeloc{#4}{#5}){\nodestuff{#1}} + \uput{#2}[#3](\nodeloc{#4}{#5}){\nodestuff{#1_tl}} + \uput{#2}[#3](\nodeloc{#4}{#5}){\nodestuff{#1_br}} +}} +\gdef\putstuff_cart#1[#2,#3]#4[#5]#6{{ + \SpecialCoor +% \message{xunit is #2} + \ifdim #2=0em + \putstuff_ang{#1}[#3]{90}[#5]{#6} + \else + \ifdim #3=0em + \putstuff_ang{#1}[#2]{0}[#5]{#6} + \else + \psset{xunit=#2,yunit=#3} + \rput(\nodeloc{#5}{#6}){\uput{0}[0](1,1){#1}} + \fi + \fi +}} + + +% \nodeconnect(pre-options)[fromloc]{fromnode}[toloc]{tonode}[style parameters] +% 1 2 3 4 5 6 7 +% +% plain lines by default. \pc node connection command should work; \nc's won't +% +% the pre-options are for defining variants (e.g. \anodeconnect), not general use +% in definitions, inherent properties first, then pre-option and finally the +% style parameters +% +\gdef\nodeconnect{\@ifnextchar < + {\@nodeconnect} + {\@nodeconnect<\pcline>} +} +\gdef\@nodeconnect<#1>{\@ifnextchar ( + {\@@nodeconnect<#1>} + {\@@nodeconnect<#1>()} +} +\gdef\@@nodeconnect<#1>(#2){\@ifnextchar [ + {\@@@nodeconnect<#1>(#2)} + {\@@@nodeconnect<#1>(#2)[b]} +} +\gdef\@@@nodeconnect<#1>(#2)[#3]#4{\@ifnextchar [ + {\@@@@nodeconnect<#1>(#2)[#3]{#4}} + {\@@@@nodeconnect<#1>(#2)[#3]{#4}[t]} +} +\gdef\@@@@nodeconnect<#1>(#2)[#3]#4[#5]#6{\@ifnextchar [ + {\@@@@@nodeconnect<#1>(#2)[#3]{#4}[#5]{#6}} + {\@@@@@nodeconnect<#1>(#2)[#3]{#4}[#5]{#6}[]} +} +\gdef\@@@@@nodeconnect<#1>(#2)[#3]#4[#5]#6[#7]{{\SpecialCoor + \psset{nodesep=0pt, linewidth=\treelinewidth} + \ada@ifnotempty{#2}{\psset{#2}} + \ada@ifnotempty{#7}{\psset{#7}} + #1(\nodeloc{#3}{#4})(\nodeloc{#5}{#6}) +}} + +% \anodeconnect[fromloc]{fromnode}[toloc]{tonode}[style options] +% +% connecting line with arrow at the end (for complicated arrows, +% use \nodeconnect with arrows option) +% +\gdef\anodeconnect{\nodeconnect(arrows=->)} + +% +% application of oneortwoargs machinery for the nodecurve curvature argument +% +\gdef\getncurv[#1]{\oneortwoargs{\ncurv@}{\ncurv@AB}[#1]} +\gdef\ncurv@[#1]{\psset{ncurv=#1}} +\gdef\ncurv@AB[#1,#2]{\psset{ncurvA=#1,ncurvB=#2}} + + +% \nodecurve(pre-option)[fromloc]{fromnode}[toloc]{tonode}(curve)[style options] +% 1 2 3 4 5 6 7 8 +% for curve, either one number or 2, separated by commas, eg: (2) or (1,2) +% 1 does nothing for the moment, but maybe someday (curved zigags?) +% +% for curve, either one number or 2, separated by commas, eg: (2) or (1,2) +% +\gdef\nodecurve{\@ifnextchar < + {\@nodecurve} + {\@nodecurve<\pccurve>} +} +\gdef\@nodecurve<#1>{\@ifnextchar ( + {\@@nodecurve<#1>} + {\@@nodecurve<#1>()} +} +\gdef\@@nodecurve<#1>(#2){\@ifnextchar [ + {\@@@nodecurve<#1>(#2)} + {\@@@nodecurve<#1>(#2)[b]} +} +\gdef\@@@nodecurve<#1>(#2)[#3]#4{\@ifnextchar [ + {\@@@@nodecurve<#1>(#2)[#3]{#4}} + {\@@@@nodecurve<#1>(#2)[#3]{#4}[t]} +} +\gdef\@@@@nodecurve<#1>(#2)[#3]#4[#5]#6{\@ifnextchar ( + {\@@@@@nodecurve<#1>(#2)[#3]{#4}[#5]{#6}} + {\@@@@@nodecurve<#1>(#2)[#3]{#4}[#5]{#6}()} +} +\gdef\@@@@@nodecurve<#1>(#2)[#3]#4[#5]#6(#7){\@ifnextchar [ + {\@@@@@@nodecurve<#1>(#2)[#3]{#4}[#5]{#6}(#7)} + {\@@@@@@nodecurve<#1>(#2)[#3]{#4}[#5]{#6}(#7)[]} +} +\gdef\@@@@@@nodecurve<#1>(#2)[#3]#4[#5]#6(#7)[#8]{{ + \SpecialCoor + \ada@ifnotempty{#7}{\getncurv[#7]} + \psset{nodesep=\nodemargin, linewidth=\treelinewidth, angleA=\nodeang{#3}{#4}, + angleB=\nodeang{#5}{#6}} + \ada@ifnotempty{#2}{\psset{#2}} + \ada@ifnotempty{#8}{\psset{#8}} + #1(\nodeloc{#3}{#4})(\nodeloc{#5}{#6}) +}} + + +% \anodecurve[fromloc]{fromnode}[toloc]{tonode}{depth} +% for fancy options use \pcnodecurve with arrows style. +% +\gdef\anodecurve{\nodecurve(arrows=->)} + + +% +% connect two words with straight-edge U +% +% \barnodeconnect(pre-options)[arm]{from}{to}[style] +% 1 2 3 4 5 +% +\gdef\barnodeconnect{\@ifnextchar ( + {\@barnodeconnect} + {\@barnodeconnect()} +} +\gdef\@barnodeconnect(#1){\@ifnextchar [ + {\@@barnodeconnect(#1)} + {\@@barnodeconnect(#1)[]} +} +\gdef\@@barnodeconnect(#1)[#2]#3#4{\@ifnextchar [ + {\@@@barnodeconnect(#1)[#2]{#3}{#4}} + {\@@@barnodeconnect(#1)[#2]{#3}{#4}[]} +} +\gdef\@@@barnodeconnect(#1)[#2]#3#4[#5]{{ + \psset{nodesep=\nodemargin, linewidth=\treelinewidth, angle=-90} + \ada@ifnotempty{#1}{\psset{#1}} + \ada@ifnotempty{#2}{\psset{arm=#2}} + \ada@ifnotempty{#5}{\psset{#5}} + \ncbar{#3}{#4} +}} + +% +% \abarnodeconnect[arm]{from}{to}[linestyle] +% +\gdef\abarnodeconnect{\barnodeconnect(arrows=->)} + +% triangles of laziness +% +% \nodetriangle {apex}{base}[style] +% 1 2 3 +% +\gdef\nodetriangle#1#2{\@ifnextchar [ + {\@nodetriangle{#1}{#2}} + {\@nodetriangle{#1}{#2}[]} +} +\gdef\@nodetriangle#1#2[#3]{{ + \nodeconnect{#1}[tl]{#2}[#3] + \nodeconnect{#1}[tr]{#2}[#3] + \nodeconnect[tl]{#2}[tr]{#2}[#3] +}} + + +% +% \nodecircle{node}{radius}[style options[ +% +\gdef\nodecircle#1(#2){\@ifnextchar [ + {\@nodecircle#1(#2)} + {\@nodecircle#1(#2)[]} +} +\gdef\@nodecircle#1(#2)[#3] +{{ + \SpecialCoor + \ada@ifempty{#3}{\pscircle(#1){#2}} + {\pscircle[#3](#1){#2}} % \psset{#3} doesn't seem to work here +}} + +% +% \nodeoval{node}{hradius, vradius}[style options] +% +\gdef\nodeoval#1(#2){\@ifnextchar [ + {\@nodeellipse#1(#2)} + {\@nodeellipse#1(#2)[]} +} +\gdef\@nodeellipse#1(#2,#3)[#4] +{{ + \SpecialCoor + \ada@ifempty{#4}{\psellipse(#1)(#2,#3)} + {\psellipse[#4](#1)(#2,#3)} +}} + +% +% \nodebox{node}[style options] +% +\gdef\nodebox#1{\@ifnextchar [ + {\@nodebox#1} + {\@nodebox#1[]} +} + +\gdef\@nodebox#1[#2] +{{ + \SpecialCoor + \putpoint{@a}{\nodemargin}(135)[tl]{#1} + \putpoint{@b}{\nodemargin}(-45)[br]{#1} + \ada@ifempty{#2}{\psframe(@a)(@b)} + {\message{fuccon arg #2} + \psframe[#2](@a)(@b)} % \psset{#3} doesn't seem to work here +}} + + +} % end group & restore standard catcodes + +% \makedash{dimen} makes dashes of dimen length (0 dimen = none not solid) +\gdef\makedash#1{\psset{linestyle=dashed, dash=2pt #1}} + +\gdef\nodepointerror{third argument of nodepoint must now be angle (number)} + +\psset{arrowsize=2pt 2, arrowlength=1.2, arrowinset=.3} \ No newline at end of file diff --git a/macros/latex/contrib/LingTrees/trees.py b/macros/latex/contrib/LingTrees/trees.py new file mode 100644 index 0000000000..4fcbb243ef --- /dev/null +++ b/macros/latex/contrib/LingTrees/trees.py @@ -0,0 +1,309 @@ +#! /usr/bin/python +# +# COPYRIGHT 2005, 2006, Avery D Andrews 3rd +# +# GPL2 +# +# changelog at end + +import sys, string, os, re + +# +# would be an idea to subclass 'file', but then I wouldn't +# know how to make it work with sys.stdin +# +class Source: + + def __init__(self, source): + self.linenum = 0 + self.file = source + self.nextline = source.readline() + + def readline(self): + self.linenum = self.linenum+1 + returnline = self.nextline + self.nextline = self.file.readline() + return returnline + +class TreesError(Exception): + + def __init__(self, value): + self.value = value+'\n' + # + # UGH: there must be a better way to do this + # + global error_occurred + error_occurred=1 + + # + # UMM: actually this doesn't seem to do what I expect it to (be + # the spelling of an error instance in backquotes) + # + def __str__(self): + return self.value + +# +# complain and set error flag but don't stop +# +def TreesWhinge(issue): + sys.stderr.write(issue) + global error_occurred + error_occurred=1 + + +class Node: + def __init__(self, label): + self.tri = 0 + self.mother = None + self.daughters = None + self.next = None + self.tag = "" + self.label = label + +OUTPUT_DEFAULT = 0 # write output to command-line-specified file our sysout +OUTPUT_TEMP = 1 # write the next tree to a specified output file +OUTPUT_PERM = 2 # write all to a specified output file + +def parse_line(line, infile): + text = string.strip(line) + if text=='': + raise TreesError('Blank line in tree at line %d.'%infile.linenum) + white = line[:string.find(line,text[0])] + return len(white), text + + +def get_line(infile): + line = infile.readline() + while infile.nextline[:2]=='.-': + line = line + string.strip(infile.readline()[2:]) + if line=='': + raise TreesError('File ends during tree at line %d.'%infile.linenum) + return parse_line(line, infile) + + +# +# gets sub-trees whose first line has the same indentation as first param +# +def get_daughters(indent, text, infile, mother): + daughter, newindent, newtext = build_tree(indent, text, infile) + daughter.mother = mother + daughters = [daughter] + prevdaughter = daughter + while newindent==indent: + newdaughter, newindent, newtext = build_tree(newindent, newtext, infile) + newdaughter.mother = mother + prevdaughter.next = newdaughter + daughters.append(newdaughter) + prevdaughter=newdaughter + if newindent > indent: + raise TreesError('Indentation fault at line %d.'%infile.linenum) + return daughters, newindent, newtext + + +# +# pattern for option parsing +# +optpattern = re.compile("\s*(\S*)\s*(.*?)\s*$") + +# +# text is not supposed to be '.]' +# +def build_tree(indent, text, infile): + linenum = infile.linenum + textlist = re.split("[|]",text) + node = Node(textlist[0]) + dict = node.optdict = {} + for command in textlist[1:]: + matchcom = optpattern.match(command) + if matchcom: + comm = matchcom.group(1) + if not comm in [ + 'tag', # custom tag for the line + 'tri', # node has a triangle over it + 'none', # node has no line going to it + 'dot', # node line is dotted + 'dash', # node line is dashed + 'after', # something after the connection command + 'style', # style commands + 'dotted', # nice pstricks dots + 'connect', # custom connection command + 'width', # node is of set width + 'dtwidths',# widths of daughter nodes + ]: + TreesWhinge("Warning: unknown option '%s' near line %d\n"%(command,linenum)) + dict[comm] = matchcom.group(2) + if dict.has_key("tag"): + node.tag = dict["tag"] + else: + global tag_count + node.tag = "Z%d"%tag_count + tag_count=tag_count+1 + if dict.has_key("none"): + if dict.has_key("tri"): + TreesWhinge("Incompatible options 'none' and 'tri' near line %d (tri wins)\n"%linenum) + if dict.has_key("dash") or dict.has_key("dot") or dict.has_key("linestyle"): + TreesWhinge("Incompatible options 'none' and some line style near line %d (none wins)\n"%linenum) + + newindent, newtext = get_line(infile) + if newindent > indent: + node.daughters, newindent, newtext = get_daughters(newindent, newtext, infile, node) + return node, newindent, newtext + + +def write_tree(node, outfile, indent=0): + dict = node.optdict + lineoptions="" + if node.mother: + if dict.has_key('dash'): + line = "\\makedash{3pt}" + elif dict.has_key('dot'): + line = "\\makedash{1pt}" + else: + line = "" + if dict.has_key('dotted'): + lineoptions = lineoptions+"linestyle=dotted,linewidth=\\treedotwidth" + if dict.has_key('style'): + if lineoptions: + lineoptions = lineoptions+','+dict['style'] + else: + lineoptions = dict['style'] + if lineoptions: + lineoptions = "[%s]"%lineoptions + if dict.has_key('after'): + lineoptions = lineoptions+dict['after'] + if dict.has_key('tri'): + line = line+"\\nodetriangle{%s}{%s}%s%%\n"%(node.mother.tag, node.tag, lineoptions) + elif dict.has_key('none'): + if dict.has_key('after'): + line = dict['after'] + else: + if dict.has_key('connect'): + connect = dict['connect'] + else: + connect = "\\nodeconnect" + line = line+"%s{%s}{%s}%s"%(connect, node.mother.tag, node.tag, lineoptions) + else: + line = '' + if dict.has_key('width'): + width = '\\setnodewidth{%s}'%dict['width'] + elif node.mother!=None and node.mother.optdict.has_key('dtwidths'): + width = '\\setnodewidth{%s}'%node.mother.optdict['dtwidths'] + else: + width = "" + if node.daughters: + outfile.write("{%s\\ntnode{%s}{%s}{%s},\n"%(width,node.tag,node.label,line)) + for daughter in node.daughters: + write_tree(daughter, outfile, indent+2) + outfile.write('}') + else: + outfile.write("{%s\\tnode{%s}{%s}{%s}}"%(width,node.tag,node.label, line)) + if node.next: +# if node.mother.next: + outfile.write(",\n") + + +def process_tree(infile, outfile): + indent, text = get_line(infile) + if text[:2]=='.]': + return +# outfile.write('indent: %d; text: %s\n'%(indent, text)) + global tag_count + tag_count = 0 + tree, newindent, newtext = build_tree(indent, text, infile) + if newindent!=0: + raise TreesError('Indentation fault at line %d.'%infile.linenum) + if newtext!='.]': + raise TreesError('Bad tree end at line %d.'%infile.linenum) + outfile.write('%%% begin tree\n\\tree') + write_tree(tree, outfile) + outfile.write('%%\n%%end tree\n') + + +def make_folders(path): + folder, file = os.path.split(path) + folder = string.strip(folder) + if folder and not os.path.exists(folder): + os.makedirs(folder) + +def process_file(infile, outfile): + global error_occurred + error_occurred =0 + outfilemode = OUTPUT_DEFAULT + while 1: + line = infile.readline() + if line == '': + break; + if line[:3]=='.>>': + outfilemode = OUTPUT_PERM + line = string.strip(line[3:]) + make_folders(line) + outfile2 = outfile + outfile = open(line,'w') + elif line[:3] == '.<<': + outfilemode = OUTPUT_DEFAULT + elif line[:2] == '.>': + if outfilemode == OUTPUT_PERM: + sys.stderr.write("Warning: temp output directive after permanent at line %d"%infile.linenum) + else: + line = string.strip(line[2:]) + make_folders(line) + outfile2 = outfile + outfilemode = OUTPUT_TEMP + outfile = open(line,'w') + elif line[:2] == '.[': + try: + process_tree(infile, outfile) + except TreesError, error: + sys.stderr.write(error.value) + errfile=open(errfilename,'w') + errfile.write(error.value) + outfile.write('BAD TREE:\n %s'%error.value) + try: + if outfilemode == OUTPUT_TEMP and outfile2: + outfile = outfile2 + del outfile2 + except UnboundLocalError: + pass + else: + outfile.write(line) + + +if __name__=="__main__": + argv=sys.argv +# print 'cwd:'+os.getcwd() + if len(argv)<2:# run as filter + infile=sys.stdin + outfile=sys.stdout + errfilename = 'trees.err' +# errfile=open("trees.err","w") + else: + infile=open(argv[1]+'.txp','r') + outfile=open(argv[1]+'.tex','w') + errfilename = argv[1]+'.err' +# errfile=open(argv[1]+'.err','w') + + process_file(Source(infile), outfile) + if error_occurred: + sys.exit(1) + sys.stderr.write("trees ran without issues\n") + +# +# changelog +# +# v 3.1 Feb 28 2006 +# widths and dtwidths commands, for controlling width +# of nodes. +# +# v 3.0 Jan 30 2006 +# adjusted to write for pst-node +# name changed to lingtrees.py +# implement additional options for PSTricks +# +# v 2.2, Jan 18 2006 +# implemented none, dash and dot options from Chris Manning's version +# +# v 2.1, Dec 28 2005 +# .>, .>>, >> directives added for writing to files +# .- directive added for continuation of lines +# + -- cgit v1.2.3