%%% %%% Macros to typeset Discourse Representation Structures (DRSs). %%% Based on DRS macros in covingtn.sty %%% %%% Written by Alexis Dimitriadis (a.dimitriadis at uu.nl) %%% %%% This package may be used, distributed and modified unter the terms of the %%% LaTeX Project Public License, either version 1.3 of this license or (at your %%% option) any later version. %%% %%% The latest version of the LaTeX Project Public License can be found at this URL: %%% http://www.latex-project.org/lppl.txt \ProvidesPackage {drs} [2010/06/10 typeset Discourse Representation Structures v. 1.1b] % REVISION HISTORY % % 2010/06/10 v. 1.1 Small modifications for compatibility with memoir and array.sty. % Thanks to Alan Munn and Antonio Fortin for reporting the problem. % Added robustness enhancements, pict2e support, and LPPL license. % % 2004/02/17 Corrected some typos in documentation % % 2000/06/15 v. 1.0 Original stable version %% This package draws Discourse Representation Structures (DRSs). It can draw %% embedded DRSs, if-then conditions and quantificational ``duplex %% conditions'' (with a properly scaled connecting diamond). Formatting %% parameters allow the user to control the appearance and placement of DRSs, %% and of DRS variables and conditions. % \drs typesets a DRS in box notation a la Kamp. % \drs* Same, but typeset as a ``partial'' drs (centered on the % baseline, and with no extra spacing above or below) % % Arguments: % 1. List of discourse variables % 2. List of conditions separated by \\ % % Example: \drs{X}{donkey(X)\\green(X)} % % Example: \drs{}{purple(X,Y)} (no variables line) % % Example: \drs{X} % {named(X,`Pedro') \\ % \drs{Y}{donkey(Y)\\owns(X,Y)}~~ % {\large $\Rightarrow$}~ % \drs{~}{feeds(X,Y)} % } % \ifdrs forms 2 DRSes joined with a big arrow. % Usually used for DRSes nested within another. % % Example: \ifdrs{X}{donkey(X)\\hungry(X)} % {~}{feeds(Pedro,X)} % \qdrs Form a ``duplex condition'' representing a quantifier. % % Example: \qdrs{}{man(x)}{every}{x}{y}{mother-of(x, y)\\ % loves(x, y)} % \negdrs forms a DRS preceded by the negation symbol. % % Example: \negdrs{X}{donkey(X)\\green(X)} % \sdrs like \drs but first argument is a sentence % to be displayed above the drs. % % Example: \sdrs{A donkey is green.}{X}{donkey(X)\\green(X)} % \alifdrs is like \ifdrs but shifted to the left so that an % embedded `if' structure will line up with ordinary % DRS conditions. % memoir-compatible definitions; if you use article.cls, \it and \rm also work \def\drsvarfont{\normalfont\itshape} % Font for variables \def\drscondfont{\normalfont\rmfamily} % Font for conditions \let\drsseparator=\hline % Separator between variables and conditions \let\drsalignment=c % Alignment of material in boxes (l/c/r) \let\drsboxalignh=c % Horizontal alignment of top-level DRS box in page \let\drsboxalignv=c % Vertical alignment (with the baseline: t/c/b) % \def\drsarraystretch{1} % undefined by default: value for \arraystretch \edef\drslinewidth{\the\arrayrulewidth} % Line thickness: Start with default for tabular \newcount\@drslevel \@drslevel=0 \def\drs@strut{{\large\strut}} % \drs* gives a ``partial DRS'' (treated as if it appears inside another DRS) % \drs begins a group that's ended by \@drs \newcommand{\drs}{\bgroup \@drs@set@align \@ifstar{\advance\@drslevel by 1 \relax} \relax \expandafter\@drs\@drs@cleanalign } % These contortions are required because memoir and array will not accept a macro % as a column alignment specifier. Simpler solutions would be possible if we KNEW whether % \drsalignment has been set with \def/renewcommand or with \let. Restricting the user is % ugly, so we \def a macro from what we're given. % \def\@drs@set@align{% \def\@drs@cleanalign{c}% a default, in case of bad values % \expandafter is needed in case \drsalignment was \def'ed; with \let, it's harmless \expandafter\ifx \drsalignment c\def\@drs@cleanalign{c}\fi \expandafter\ifx \drsalignment l\def\@drs@cleanalign{l}\fi \expandafter\ifx \drsalignment r\def\@drs@cleanalign{r}\fi } \newcommand{\@drs}[3] {\advance\@drslevel by 1 \relax \leavevmode \ifnum\@drslevel>1 \let\drsboxalignv=c% Embedded boxes should be centered on the baseline \else % Alignment options for top-level boxes only: \expandafter\ifx \drsboxalignh c\hbox{}\hfil \fi \fi % \expandafter is needed if \drsboxalignh was \def'ed; with \let, it's harmless \arrayrulewidth=\drslinewidth \@ifundefined{drsarraystretch} {} {\edef\arraystretch{\drsarraystretch}}% \begin{tabular}[\drsboxalignv]{|@{}r@{}|} \ifnum\@drslevel>1\noalign{\vskip 0.7ex}\fi %% ?? \hline \drscondfont {\begin{tabular}[b]{#1} % Do not allocate space for variables if none are given \def\@tempa{#2}\ifx\@tempa\empty \else \drs@strut \drsvarfont {\ignorespaces #2\strut\relax }\\ \drsseparator % Spacing is the same whether this is \hline or \relax \fi \drs@strut % extra space above and below (text) condition \strut % A failsafe, in case the user selected a large font \ignorespaces #3 % do not place \relax here! It confuses the next test % End line unless the user already did \ifvmode \else \\ \fi % (can't vspace here or the line will come out wrong) \end{tabular}}% \vrule height 0pt width 0pt depth \baselinestretch\dp\strutbox \drs@strut % extra space above and below (text) conditions \\[2pt] \hline \ifnum\@drslevel>1\noalign{\vskip 0.7ex}\fi % extra for embedded DRSs \end{tabular}\egroup} % close the \bgroup in \drs % Connect two DRSs with the middle argument (presumably a logical connective). % This is worth providing because centering would separate DRSs from the % connectives, unless everything is enclosed in an mbox as we do here. \newcommand\condrs[5] {\mbox{\let\drsboxalignv=c\drs{#1}{#2}{\large\ \ {#3}\ \ }\drs{#4}{#5}}} \newcommand{\ifdrs}[4]{\condrs{#1}{#2}{$\Rightarrow\!\,$}{#3}{#4}} \newcommand{\qdrs}[6] {\mbox{\let\drsboxalignv=c\drs{#1}{#2}\drsdiamond{#3}{#4}\drs{#5}{#6}}} \newcommand{\negdrs}[2] {\mbox{{\large $\neg$ }\drs{#1}{#2}~}} % offset by a ~ for better centering % like \ifdrs but shifted to the left so that an embedded `if' structure will % line up with ordinary DRS conditions. (Useful for left-aligned DRSs only). \newcommand{\alifdrs}[4] {\mbox{$\!\!\!$\ifdrs{#1}{#2}{#3}{#4}}} % A DRS with the associated sentence. \newcommand{\sdrs}[3] {\begin{tabular}{l} \mbox{\it #1} \\ ~ \\ \drs{#2}{#3} \end{tabular}} \newbox\@drsbox % Draw a diagonal square (diamond) containing a quantifier and variable. % % Ridiculously complicated diamond algorithm: fit the smallest diamond around % the _trapezoid_ enclosing a longer top line and a short variable at the % bottom. Special-case boxes with really, really wide top part. % % Syntax: \drsdiamond{quantifier}{variable} \newcommand{\drsdiamond}[2]{{% \setbox\@drsbox\hbox{\def\baselinestretch{1}\@currsize \begin{tabular}{@{}c@{}} \drscondfont {#1}\\\drsvarfont {~#2~\null}\end{tabular}}% % Compute the necessary dimensions \@tempcnta=\ht\@drsbox \relax \advance\@tempcnta by \dp\@drsbox \relax \edef\@H{\the\@tempcnta}% % height % \@tempcnta=\wd\@drsbox \edef\@boxdims{(\the\@tempcnta,\@H)}% % box dimensions \divide\@tempcnta by 2 \edef\@A{\the\@tempcnta}% % 1/2 top width % % Measure the bottom line separately so we can pretend we're a trapezoid \setbox\@tempboxa\hbox{ \drsvarfont{#2 }}% \@tempcnta=\wd\@tempboxa \divide\@tempcnta by 2 \edef\@B{\the\@tempcnta}% % 1/2 bottom row width % \@tempcnta=\@H \advance\@tempcnta by \@B \ifnum \@A > \@tempcnta % Angle is less than 45 degrees: center on top part % start over: measure just the top part \setbox\@tempboxa\hbox{\def\baselinestretch{1}\@currsize \begin{tabular}{@{}c@{}}\drscondfont{#1}\end{tabular}}% \@tempcnta=\ht\@tempboxa \advance\@tempcnta by \dp\@tempboxa \divide\@tempcnta by 2 \edef\@topH{\the\@tempcnta}% % HALF the height of the top part \advance\@tempcnta by \@A \edef\@D{\the\@tempcnta}% \advance\@tempcnta by -\@H \advance\@tempcnta by \@topH \edef\@boxcoords{(\@topH,\the\@tempcnta)}% \else % Angle over 45: diamond goes across all corners \advance \@tempcnta by \@A\relax \divide \@tempcnta by 2 \edef\@D{\the\@tempcnta}% \advance\@tempcnta by -\@A \edef\@boxcoords{(\the\@tempcnta,\@B)}% \fi % \@tempcnta=\@D \multiply\@tempcnta by 2 \edef\@twoD{\the\@tempcnta}% % \unitlength=1sp % ``scaled points,'' like the counter values \linethickness{\drslinewidth}% only effective if pict2e.sty is loaded % If eepic is loaded, match our lines to the DRS borders \@ifundefined{allinethickness}\relax{\allinethickness{\the\arrayrulewidth}}% \parbox[c]{\@twoD sp}{{\vskip 2pt% \begin{picture}(\@twoD,\@twoD) \put(0,\@D){\line(1,-1)\@D} \put(0,\@D){\line(1,1)\@D} \put(\@twoD,\@D){\line(-1,1)\@D} \put(\@twoD,\@D){\line(-1,-1)\@D} % change \makebox to \framebox to see the placement \expandafter\put\@boxcoords{\expandafter\makebox\@boxdims{\box\@drsbox}} \end{picture}\vskip 2pt}}}} % BETTER DOUBLE SPACING: by default, tall material can come arbitrarily close % to the previous line. Calling \drshacksetspace redefines setspace.sty % internals, causing it to adjust TeX formatting parameters that force a % portion of each line to stay empty. This really should be part of % setspace.sty. % setspace.sty redefines the footnotes, but they do not call setstretch, alas. % So the spacing will still be incorrect in footnotes. \def\drshacksetspace{\@ifundefined{setstretch}\relax {% % Ensure that HALF of the lineskip above the normal (singlespacing) value % will stay empty \def\adj@lineskip{% \@tempdima=\baselinestretch\baselineskip \advance\@tempdima by -\setspace@singlespace\baselineskip \divide\@tempdima by 2 \lineskiplimit=\@tempdima \lineskip=\lineskiplimit \ifdim\@tempdima=0pt \lineskip=1pt\fi}% % Arrange to recompute lineskip whenever spacing changes \renewcommand{\setstretch}[1] {\def\baselinestretch{##1}\@currsize\adj@lineskip}% % Now run setstretch in case it's already been invoked (at the preamble) \expandafter\expandafter \expandafter\setstretch\expandafter{\baselinestretch}}} \endinput