diff options
Diffstat (limited to 'info/digests/texhax/txh/relate.txh')
-rw-r--r-- | info/digests/texhax/txh/relate.txh | 288 |
1 files changed, 288 insertions, 0 deletions
diff --git a/info/digests/texhax/txh/relate.txh b/info/digests/texhax/txh/relate.txh new file mode 100644 index 0000000000..52fdc9bb84 --- /dev/null +++ b/info/digests/texhax/txh/relate.txh @@ -0,0 +1,288 @@ +21-Dec-87 09:30:52-PST,12519;000000000000 +Return-Path: <@RELAY.CS.NET:phcalamai@water.waterloo.edu> +From: "Paul H. Calamai" <phcalamai%water.waterloo.edu@RELAY.CS.NET> +Subject: Re: LaTeX list environment question + +Steve Buyske <ST401266%BROWNVM.BITNET@forsythe.stanford.edu>: +> +> +> I would like to make a construct a list environment so that I can +> have labels that might require two line. Something like +> +> Professional Something silly, something else silly, some more +> Associations: silly things, and so on. +> +> If I put the label in a \parbox, no matter how I fiddle around, I get +> something like: +> +> Professional Something silly, something else silly, some more +> Associations: +> silly things, and so on. +> +> with an ugly extra line. Can anyone give me some advice? +> +> My apologies if this is an easy question, but I'm new to LaTeX and +> desperate to get my C.V. done. +> +Here is a tex file that will do what you want: + + +% relate_macros.tex 1987 Jun 10 E. Ledoux +% Instructions for use are located at the end of this file. +% +\makeatletter +% +\newdimen\relateleft \relateleft=\leftmargin % space before label +\newdimen\relateright \relateright=\leftmargin % min. space after label +\newbox\RELbox \newcount\RELcount \RELcount\z@ +\newdimen\RELoldmax \newdimen\RELnewmax +% +\def\relate{\@ifnextchar [{\RELcontd}{\global\advance\RELcount\@ne +\expandafter\RELcontd\expandafter [\romannumeral \the\RELcount]}}% +% +\def\RELcontd[#1]{\def\RELlabel{#1}% +\expandafter\let\expandafter\RELmax\csname RELold@#1\endcsname +\ifx\RELmax\relax \RELoldmax0.20\hsize \else \RELoldmax\RELmax \fi +\list{}{\labelwidth\RELoldmax \itemindent\z@ \leftmargin\RELoldmax +\advance\leftmargin\relateleft \advance\leftmargin\relateright +\let\makelabel\RELmakelabel}}% +% +\def\RELmakelabel#1{\@ifundefined{RELnew@\RELlabel}{\RELnewmax\z@}% +{\expandafter\RELnewmax\csname RELnew@\RELlabel\endcsname}% +\setbox\RELbox\hbox{\vtop to0pt{\let\\\cr \halign{##\hfil\cr#1\cr} \vss}}% +\ifdim\wd\RELbox>\RELnewmax \RELnewmax\wd\RELbox\fi +\expandafter\xdef\csname RELnew@\RELlabel\endcsname{\the\RELnewmax}% +\hskip\labelsep \hskip-\relateright \hbox to\z@{\box\RELbox\hss}\hfill}% +% +\def\endrelate{\toks\z@\expandafter{\csname RELold@\RELlabel\endcsname}% +\immediate\write\@auxout{\gdef\the\toks0{\csname RELnew@\RELlabel\endcsname}}% +\endlist}% +% +\makeatother +\endinput + + + HOW TO USE IT + +This LaTeX macro file defines a "relate" environment, which is basically +a more intelligent "description" environment. To use it, place + \input {path}relate +somewhere before \begin{document}. + +Here's an example of relate environment usage: + + \begin{relate} + \item[Spot] Spot is a dog. See Spot run. + \item[Spock] Spock is a Vulcan. See Spock think. + \item[Cigarette\\Smoke] + Smoke is a health hazard. + The Surgeon General recommends ... smoked. + \end{relate} + +This produces output that looks like this: + + | preceding text | + +-----------------------------------------------------------+ + + Spot Spot is a dog. See Spot run. + + Spock Spock is a Vulcan. See Spock think. + + Cigarette Smoke is a health hazard. The + Smoke Surgeon General .................... + ........ smoked. + |<---->| |<---->| + \relateleft \relateright + + |<---- left margin ---->| + +The relate environment behaves very much like the description environment +except: + + 1. \item labels may be multi-line. For example, \item[Cigarette\\Smoke] + produces a two-line label, with "Cigarette" on one line and "Smoke" + on the following line. [BUG: You get strange output if your label + has more lines than the associated text.] + + 2. Labels don't intrude into the text, like long labels do in the + description environment. Relate automatically calculates the width of + the widest label in a relate environment and adjusts the "left margin" + of the text appropriately. This is done using the .aux file, similar + to LaTeX section, page number etc. references, so margins will not + be correct until the second LaTeX run after a change to a label is made. + + \relateleft and \relateright are horizontal space parameters; + the left margin for a relate environment will be equal to + \relateleft + maximum-width + \relateright + where maximum-width is the width of the widest label. + The default value of both \relateleft and \relateright is \leftmargin + (about 25 points when using 10-point fonts). + \relateleft and \relateright can be changed using \setlength, eg. + \setlength{\relateleft}{0.5in} + \setlength{\relateright}{0.3in} + This can be done immediately after \input-ing relate_macros. + +Normally, each relate environment is autonomous in the sense that only +labels in that environment determine the left margin for that environment. +However, different relate environments within the same document can be "linked" +so that they have the same left margin. For example, + + ... + \begin{relate}[apple] + \item[anything] ... + ... + \end{relate} + ... + \begin{relate}[apple] + \item[whatever] ... + ... + \end{relate} + ... + +The left margins in these two relate environments will be the same because +they were "linked" by placing the same "label" ("apple" in this example) +in square brackets after \begin{relate}. You can link any number of +relate environments in the same document; they need not be adjacent. +Labels should consist entirely of lower and uppercase letters. + +If you get strange margins when using relate, just re-latex your document. +The left margins will be recalculated and should be correct on the second run. + +By the way, you can nest relates within one another and within other +list environments as well. + + + HOW IT WORKS + +relate_macros.tex is described below: + + \makeatletter + +This allows '@' to be used in control sequences, plus allows access to +the efficient \z@ (zero), \@ne (one), and other TeX and LaTeX hacks. + + \newdimen\relateleft \relateleft=\leftmargin % space before label + \newdimen\relateright \relateright=\labelsep % min. space after label + +Defines and sets the default values of \relateleft and \relateright. + + \newbox\RELbox \newcount\RELcount \RELcount\z@ + \newdimen\RELoldmax \newdimen\RELnewmax + +\RELbox temporarily holds a label so that it can be measured. + +\RELoldmax will hold the width of the widest label for this (and similarly +labelled) enviroments as calculated in the last run, for the duration of +each relate environment. Similarly, \RELnewmax holds the width of the +widest label for this (and similarly labelled) relate environments as +calculated in this run, but \RELnewmax is updated from \RELnew@xxx +and stored to \RELnew@xxx at every \item in the environment (see below). + +For a relate environment labelled, say, "apple", a global control sequence +named \RELnew@apple will be used to keep track of the width of the widest +label of all "apple" relate environments. Inside each "apple" env. \item, +\RELnew@apple is copied to \RELnewmax. \RELnewmax is updated if necessary +as the width of each label is computed. When the \item ends, \RELnewmax +is copied back to \RELnew@apple, in case there are more "apple" environments. +When the entire environment ends, a line like: + \gdef \RELold@apple {28.74pt} +is written to the .aux file, where 28.74pt would be the value of \RELnewmax, +the width of the widest label so far encountered in this and previous +relate environments. + +At the beginning of every run (at \begin{document}, in fact), the .aux +file is \input automatically by LaTeX. Assuming the previous run contained +several relate environments labelled "apple", \RELold@apple will be defined +(and redefined by each "apple" environment in the previous run) to be +the width of the widest label in all "apple" environments in the previous +run. Assuming no labels changed since then, this value will be the correct +maximum label width. (If this is the first run, \RELold@apple is not defined +and the arbitrary value of 0.20\hsize, one third the width of the page, +is used instead.) In each "apple" relate environment, \RELold@apple is +copied to \RELoldmax, which is used to position labels within a left margin +of width \relateleft + \RELoldmax + \relateright. + + \def\relate{\@ifnextchar [{\RELcontd}{\global\advance\RELcount\@ne + \expandafter\RELcontd\expandafter [\romannumeral \the\RELcount]}}% + +\RELcount is a counter used to create unique relate environment labels +for when the user doesn't supply one (like "apple" in the above example). +\begin{relate} simply invokes \relate; if an argument in square brackets +is present (eg. [apple]), then \RELcontd ("relate continued") is called +with that argument. Otherwise, \RELcount is incremented and a unique +label is formed by converting the value of \RELcount to lowercase roman +numerals (ie. "i", "ii", "iii", "iv", ...). + + \def\RELcontd[#1]{\gdef\RELlabel{#1}% + +\RELlabel holds the environment label for use by \endrelate. + + \expandafter\let\expandafter\RELmax\csname RELold@#1\endcsname + \ifx\RELmax\relax \RELoldmax0.20\hsize \else \RELoldmax\RELmax \fi + +If \RELold@apple (assuming "apple" relate environment label) has been +defined (presumably in the .aux file), set \RELoldmax to that value, +otherwise set \RELoldmax to the arbitrary value of 0.20\hsize. + + \@ifundefined{RELnew@#1}{\global\RELnewmax\z@}% + {\expandafter\global\expandafter\RELnewmax\csname RELnew@#1\endcsname}% + +If \RELnew@apple has been defined, then set \RELnewmax to that value, +otherwise set \RELnewmax to zero. + + \list{}{\labelwidth\RELoldmax \itemindent\z@ \leftmargin\RELoldmax + \advance\leftmargin\relateleft \advance\leftmargin\relateright + \let\makelabel\RELmakelabel}}% + +Start a \list. Set \labelwidth to zero; labels will really have zero width +anyway. Set the \leftmargin to \RELoldmax + \relateleft + \relateright. +(This is LaTeX's idea of left margin; see p. 113 in the LaTeX manual.) +Set \labelwidth to the maximum label width -- the label will be right- +justified within a box of this width by \RELmakelabel. +\RELmakelabel will be used to make labels. + + \def\RELmakelabel#1{\@ifundefined{RELnew@\RELlabel}{\RELnewmax\z@}% + {\expandafter\RELnewmax\csname RELnew@\RELlabel\endcsname}% + +If \RELnew@apple is undefined, define \RELnewmax as zero, otherwise +define it as the value of \RELnew@apple. \RELnewmax is a \dimen variable +which is only (effectively) active for the duration of an \item. + + \setbox\RELbox\hbox{\vtop to0pt{\let\\\cr \halign{##\hfil\cr#1\cr} \vss}}% + +Typeset the label in the horizonal box register \RELbox. The \halign +(with \\ defined as \cr) allows multiple \\-separated lines in the label. +\vtop to0pt and \vss make LaTeX think that this is a one-line box, +regardless of the actual number of lines. + + \ifdim\wd\RELbox>\RELnewmax \RELnewmax\wd\RELbox\fi + \expandafter\xdef\csname RELnew@\RELlabel\endcsname{\the\RELnewmax}% + +If the width of \RELbox is greater than the current maximum label width, +increase \RELnewmax appropriately. Then, store the new maximum label +width back into \RELnew@apple for use by the next \RELmakelabel. + + \hskip\labelsep \hskip-\relateright \hbox to\z@{\box\RELbox\hss}\hfill}% + +Print the left edge of the label at distance \relateright - \labelsep from +the left edge of the text. + + \def\endrelate{\toks\z@\expandafter{\csname RELold@\RELlabel\endcsname}% + \immediate\write\@auxout{\gdef\the\toks0{\csname RELnew@\RELlabel\endcsname}}% + \endlist}% + +Finish the relate environment. \endrelate is called by \end{relate}. +Write a line to the .aux file of the form + \gdef \RELold@apple {28.74pt} +as explained above. + + \makeatother + \endinput + +That's all, folks! + + +% 1987 Jun 10 E. Ledoux Creation +% 1987 Jun 12 E. Ledoux Fixed problem with nested relate env's + +------- |