diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /info/digests/texline/no12/victor.tex |
Initial commit
Diffstat (limited to 'info/digests/texline/no12/victor.tex')
-rw-r--r-- | info/digests/texline/no12/victor.tex | 377 |
1 files changed, 377 insertions, 0 deletions
diff --git a/info/digests/texline/no12/victor.tex b/info/digests/texline/no12/victor.tex new file mode 100644 index 0000000000..8195e16d46 --- /dev/null +++ b/info/digests/texline/no12/victor.tex @@ -0,0 +1,377 @@ + +\chardef\busje=`\\ +\def\cs#1{{\tt\busje#1}} +%\newcommand{\whiteline}{\medskip\noindent} + +{\overfullrule0pt\everypar{\looseness0}\title{\bf A parskip scheme} +While I was working on the \LaTeX\ styles described +in Braams {\it et al\/}, it became apparent to me that lots of people are rather +fond of the sort of layout +that can be described as +\begintt +\parindent=0cm +\parskip=6pt % or other positive size +\endtt +Unfortunately, most of them realize this layout by no more sophisticated +means than simply inserting these two lines at the beginning +of the input. The drawback of such a simple action is +that all sorts of vertical spaces are augmented by the +\cs{parskip} when there is absolutely no need to, +or where it is positively unwanted. Examples of this +are the white space below section headings, +and the white space above and +below list environments in \LaTeX. + +In this article I will present an approach that unifies the +paragraph skip and the +white spaces surrounding various environments. +Since the macros given below make use of the \cs{everypar} +token list, this article may be seen as a sequel to +an earlier paper on an indentation scheme (Eijkhout, 1990), +which is based on a similar principle. +The \cs{everypar} parameter was explained there. + +\section{\cs{\ttit parskip}} +\TeX\ starts a paragraph when it switches from +vertical to horizontal mode. The vertical mode +may have been initiated by a \cs{par} (for instance +because of an empty line after a preceding paragraph) +or by a vertical skip command; the switch to horizontal +mode can be effected by, for example, a character +or a horizontal skip command (see the list in Knuth (1984, p283). +Immediately above the first line of the paragraph +\TeX\ will then add glue +of size \cs{parskip} +to the vertical list, unless this paragraph is +at the start of a vertical list, for instance at the +start of a vertical box or insertion item. + +Apparently, then, the \cs{parskip} parameter is very +simple to use. That this is only an apparent +simplicity becomes clear in a number of instances. + +For instance, unless precautions are taken, the white +space below headings is augmented by the paragraph skip. +Precautions against this are not particularly elegant: +the easiest solution is to include a +\begintt +\vskip-\parskip +\endtt +statement, to backspace the paragraph skip in advance. +Such an approach, however, is somewhat error-prone. +Vertical spacing will be messed up if what follows is not +a paragraph, but a display formula or a box. + +Similar considerations apply to the amounts of white space +that surround, for example, list environments, as in \LaTeX. + +\section{Paragraph skip: to be or not to be} +Ordinarily in plain \TeX\ and in \LaTeX\ the paragraph +skip is set to {\tt 0pt plus 1pt}, which gives pages some +`last resort' stretchability. However, even an amount of vertical +space as small as one point may become very +visible, and often without need (see for instance +the first page of the preface of the \TB). + +Furthermore, Stanley Morison (1936) states that not indenting +paragraphs is `decidedly an abject method'. +However, reading his intention instead of his words, +he is only concerned with the recognizability of the individual +paragraphs. The positive value of the paragraph skip is sufficient +to ensure this. If a layout is based on zero values for +both \cs{parindent} and \cs{parskip}, one may for instance +give the \cs{parfillskip} a positive natural width +to prevent last lines of a paragraph from almost, or completely, +lining up with the right margin. + +Neither Donald Knuth nor Leslie Lamport +seem to have given much thought to +the case where the paragraph skip has a positive natural width. +Leslie Lamport dismisses all potential difficulties with the remark +that `it is customary not to leave any extra space +between paragraphs' (Lamport, 1986, p94). + +\section{Environments and white lines} +Given that the paragraph skip appears to interact with +explicit vertical spacing in user macros, it may seem +like a good idea to find a unified approach to both. +In the rest of this article I will describe the implementation +of the following basic idea: {\em give the paragraph skip +the value zero whenever you do an explicit vertical skip}. + +For this paper I assume a context with some form of +environments. These are the assumptions that I make +about such environments: + +\item{$\bullet$} An environment is a portion of material that is vertically +separated from whatever is before and after it. Thus, according to +this definition, a portion of a paragraph cannot be an environment, +nor can an environment start or end in the middle of a paragraph. +\item{$\bullet$} An environment has associated with it three glue parameters: +to an environment {\tt foo} correspond \cs{fooStartskip} (glue +above the environment), \cs{fooParskip} (the paragraph skip +inside the environment), and the \cs{fooEndskip} (glue below +the environment). +\item{$\bullet$} At the outset of the environment +a +\begintt +\StartEnvironment{foo} +\endtt + statement +is executed; at the end of the environment a macro +\begintt +\EndEnvironment{foo} +\endtt + is executed. +These statements are assumed to +contain a \cs{begingroup} and \cs{endgroup} +respectively. + +\noindent +Such assumptions are sufficiently general for the macros +below to be adaptable to existing macro packages. +At first sight it would appear as if section headings +are not covered by the above points. However, there +is no argument against the start and end of an environment +occurring in the same macro. + +\section{Tools} +First I will present two auxiliary macros: \cs{csarg} +and \cs{vspace}. + +The command \cs{csarg} +is only needed inside other macros; it is meant to +enable constructs such as +\begintt +\csarg\vskip{#1Parskip} +\endtt +Its definition is +\begintt +\def\csarg#1#2{\expandafter + #1\csname#2\endcsname} +\endtt +By way of explanation of this macro, consider a simple example. +Let us assume that there exists a macro +\begintt +\def\startlist#1{ ... + \csarg\vskip{#1Startskip} + ...} +\endtt +The call +\begintt +\startlist{enumerate} +\endtt +will then lead to the following call to \cs{csarg}: +\begintt +\csarg\vskip{enumerateStartskip} +\endtt +This expands to +\begintt +\expandafter\vskip + \csname enumerateStartskip\endcsname +\endtt +Now the \cs{expandafter} forces \cs{csname} to be executed +before the \cs{vskip}, so the next step of the expansion +looks like +\begintt +\vskip\enumerateStartskip +\endtt +and this statement can simply be executed. + +Next I need a generalization of \cs{vskip}, which I will call \cs{vspace}: +a number of calls to \cs{vspace} should have the effect +that only the maximum argument is placed. +\begintt +\newskip\tempskipa +\def\vspace + #1{\tempskipa=#1\relax + \ifvmode\ifdim\tempskipa<\lastskip + \else\vskip-\lastskip + \vskip\tempskipa + \fi + \else \vskip\tempskipa\fi} +\endtt +This may need some explanation. By the assignment +|\tempskipa=#1| I allow the argument of \cs{vspace} to be +both a control sequence, for instance \cs{parskip}, +and a denotation, for instance {\tt 5pt plus 3pt}. +If one omits the assignment, the latter option would cause trouble +in the \cs{ifdim} test. + +The decision to keep the maximum value of the skip, instead of +always replacing the last skip, was motivated by phenomena +such as a display formula at the end of a list. If the +skip below the display is larger than the vertical glue +below the list (which may be zero), +the former should be retained entirely. +\looseness1 + +Note that this macro can insert vertical space of size +zero. This will for instance happen if it follows +a \cs{par} command at the end of a paragraph. +It is then called in vertical mode, +but the last item on the vertical list is a box +(the last line of the paragraph) instead of a +glue item. The parameter \cs{lastskip} will then be zero. + +\section{The environment macros} +In this section, I will give the implementation of the +macros \cs{StartEnvironment} and \cs{EndEnvironment}. + +There is a remarkable similarity between these two macros. +As I explained above, the basic idea is to have only explicit +spacing above and below the environment; thus, the value of \cs{parskip} +should then be zero both for the first paragraph in the +environment, and for the first paragraph that follows it. +Both macros should then + \item{$\bullet$} save the current value of the paragraph skip; + \item{$\bullet$} set the paragraph skip to zero; + \item{$\bullet$} give \TeX\ a signal that, somewhere in the near + future, the old value of \cs{parskip} is to be restored. + +\noindent For this I allocate a skip register and a conditional: +\begintt +\newskip\TempParskip +\newif\ifParskipNeedsRestoring +\endtt +The basic sequence for both macros is then +\begintt +\TempParskip=\parskip +\parskip=0cm\relax +\ParskipNeedsRestoringtrue +\endtt + +\noindent For both macros, however, this sequence needs to be +refined slightly. + +The paragraph skip to be `restored' at the start of the +environment is the specific value associated with that +environment. This gives us: +\begintt +\def\StartEnvironment + #1{\csarg\vspace{#1Startskip} + \begingroup %% make changes local + \csarg\TempParskip{#1Parskip} + \parskip=0cm\relax + \ParskipNeedsRestoringtrue} +\endtt +Note that the statement +\begintt +\csarg\TempParskip{#1parskip} +\endtt +denotes an assignment (without an optional equals sign) here. + +At the end of the environment we have to be more careful. +It may be the case that +the environment being ended was inside another +environment, and occurred +before the first paragraph inside +that environment. In that case the value of \cs{parskip} is zero, +and the proper value must still be restored. +Therefore, no further actions are required. + +We arrive at the following implementation: +\begintt +\def\EndEnvironment + #1{\csarg\vspace{#1Endskip} + \endgroup %% restore global values + \ifParskipNeedsRestoring + \else \TempParskip=\parskip + \parskip=0cm\relax + \ParskipNeedsRestoringtrue + \fi} +\endtt +Note that both macros start with a vertical skip. This prevents +the \cs{begingroup} and \cs{endgroup} statements from +occurring in a paragraph. + +On a side note: since these macros +are executed in vertical mode, I have not bothered to terminate +any lines with comment signs. Any spaces generated by +these macros are ignored in vertical mode. + +\section{Paragraph skip restoring} +So far, I have ignored one important question: +how exactly is restoring the paragraph skip implemented. +For this I use the \cs{everypar} token list. +Basically then, the idea is the same as in (Eijkhout, 1990): +the occurrence of a paragraph will automatically +have \TeX\ perform, through the insertion of the +\cs{everypar} tokens, the actions necessary for subsequent +paragraphs. +\begintt +\everypar= + {\ControlledIndentation + %see Tugboat 11, #3 + \ControlledParskip} +\def\ControlledParskip + {\ifParskipNeedsRestoring + \parskip=\TempParskip + \ParskipNeedsRestoringfalse + \fi} +\endtt +The cost of a controlled paragraph skip is then one conditional +per paragraph. Conceivably, this cost could even be reduced further +(to almost zero) by defining +\begintt +\def\CPS % Controlled Parskip + {\ifParskipNeedsRestoring + \parskip=\TempParskip + \ParskipNeedsRestoringfalse + \let\ControlledParskip=\relax + \fi} +\endtt +and including a statement +\begintt +\let\ControlledParskip=\CPS +\endtt +in both the \cs{StartEnvironment} and +\cs{EndEnvironment} macros, and at the start of the job (for instance +by including it in the macro package). +This approach, however, does not particularly +appeal to me. Too much `pushing the bit around'. + +\section{Conclusion} +The \cs{parskip} parameter is arguably the most tricky parameter of +\TeX. Its workings are very easy to describe, but in actual +practice difficulties arise. In this article I have +described how treatment of the paragraph skip can be integrated +with the glue above and below environments. +As in an earlier article on indentation, I use for this +the \cs{everypar} parameter as an essential tool. + +\section{Bibliography} +{\frenchspacing\parindent0pt\everypar{\hangindent20pt\hangafter1}\par +Johannes Braams, Victor Eijkhout \& Nico A.F.M. Poppelier, 1989, +The development of national \LaTeX\ styles, +TUGboat 10(3) (1989), pp401--406. + + +Victor Eijkhout, 1990, +An indentation scheme, TUGboat 11(4). + + +Donald Knuth, 1984, The \TeX book, +Addison-Wesley Publishing Company. + + + +Stanley Morison, 1936, First principles of typography, +Cambridge University Press. + + +Leslie Lamport, 1986, \LaTeX, a document preparation +system, Addison-Wesley Publishing Company. + +}} + +\author{Victor Eijkhout} +\endinput +Victor Eijkhout phone: +1 217 244-0047 + Center for Supercomputing Research and Development + University of Illinois at Urbana-Champaign + 305 Talbot laboratory + 104 South Wright street + Urbana, Illinois 61801-2932, USA + +home: 2503 W. Springfield Av, Apt. K-4, Champaign 61821, USA |