\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