ltspace.dtx

Johannes Braams  David Carlisle  Alan Jeffrey
Leslie Lamport  Frank Mittelbach  Chris Rowley

Rainer Schöpf

1995/12/05

1 Spacing

This section deals with spacing, and line- and page-breaking.

USER COMMANDS: \nopagebreak[i] : i = 0,...,4. Default argument = 4. Puts a penalty

into the vertical list output as follows: 0 : penalty = 0

                  1 : penalty = \@lowpenalty
                  2 : penalty = \@medpenalty
                  3 : penalty = \@highpenalty

4 : penalty = 10000

\pagebreak[i] : same as \nopagebreak except negatives of its penalty

\linebreak[i], \nolinebreak[i] : analogs of the above

\samepage : inhibits page breaking most places by setting the

following penalties to 10000

                   \interlinepenalty
                   \postdisplaypenalty
                   \interdisplaylinepenalty
                   \@beginparpenalty
                   \@endparpenalty
                   \@itempenalty
                   \@secpenalty
                   \interfootnotelinepenalty
\obeycr  : defines <CR> == \\\relax.

\restorecr : restores <CR> to its usual meaning.

\\ : initially defined to be \newline \\[LENGTH] : initially defined to be \vspace{LENGTH}\newline

             Note: \\* adds a \vadjust{\penalty 10000}

1 ⟨∗2ekernel⟩

 2 \message{spacing,}
\pagebreak
\nopagebreak
 3 \def\pagebreak{\@testopt{\@no@pgbk-}4}
 4 \def\nopagebreak{\@testopt\@no@pgbk4}
\@no@pgbk
 5 \def\@no@pgbk#1[#2]{\ifvmode \penalty #1\@getpen{#2}\else
 6 \@bsphack\vadjust{\penalty #1\@getpen{#2}}\@esphack\fi}
\nolinebreak
\@nolnbk
 7 \def\nolinebreak{\@testopt\@nolnbk4}
 8 \def\@nolnbk[#1]{\ifvmode \@nolnerr\else \@tempskipa\lastskip
 9  \unskip \penalty \@getpen{#1}\ifdim \@tempskipa >\z@
10  \hskip\@tempskipa\ignorespaces\fi\fi}
\linebreak \@lnbk
11 \def\linebreak{\@testopt\@lnbk4}
12 \def\@lnbk[#1]{\ifvmode \@nolnerr\else
13  \unskip\penalty -\@getpen{#1}\fi}
\samepage
14 \def\samepage{\interlinepenalty\@M
15 \postdisplaypenalty\@M
16 \interdisplaylinepenalty\@M
17 \@beginparpenalty\@M
18 \@endparpenalty\@M
19 \@itempenalty\@M
20 \@secpenalty\@M
21 \interfootnotelinepenalty\@M}

\newline \nobreak added to \newline to prevent null lines when \newline ends an overfull line. Change made 24 May 89 as suggested by Frank Mittelbach and Rainer Schöpf

22 \def\newline{\ifvmode \@nolnerr \else
23  \unskip\nobreak\hfil\break\fi}

\\ \@normalcr The internal definition of the ‘normal’ definition of \\.

24 \DeclareRobustCommand\\{%
25 \@ifstar
26  {\vadjust{\penalty\@M}\@xnewline}%
27  \@xnewline}
28 \expandafter\let\expandafter\@normalcr
29  \csname\expandafter\@gobble\string\\ \endcsname
\@xnewline
30 \def\@xnewline{\@ifnextchar[\@newline\newline}

\@newline
31 \def\@newline[#1]{\ifhmode\unskip\fi\vspace{#1}\newline}
\@getpen
32 \def\@getpen#1{\ifcase #1 \z@ \or \@lowpenalty\or
33  \@medpenalty \or \@highpenalty
34  \else \@M \fi}

@nobreak : Switch used to avoid page breaks caused by \label after a section heading, etc. It should be GLOBALLY set true after the \nobreak and GLOBALLY set false by the next invocation of

 \everypar.

Commands that reset \everypar should globally set it false if appropriate.

35 \newif\if@nobreak \@nobreakfalse
\@bsphack ... \@esphack

used by macros such as \index and \begin{@float} ... \end{@float} that want to be invisible – i.e., not leave any extra space when used in the middle of text. Such a macro should begin with \@bsphack and end with \@esphack The macro in question should not create any text, nor change the mode.

\@Esphack is a variant of \@esphack that sets the @ignore switch to true (as \@esphack used to do previously). This is currently used only for float and similar environments.

36 \newdimen\@savsk
37 \newcount\@savsf

\@bsphack \@esphack These are generalised hacks which attempt to do sensible things when ‘invisible

commands’ appear in vmode too.

They need to cope with space in both hmode (plus spacefactor) and vmode, and also cope with breaks etc. In vmode this means ensuring that any following \addvspace, etc sees the correct glue in \lastskip.

In fact, these improved versions should be used for other cases of ‘whatsits, thingies etc’ which should be invisible. They are only for commands, not environments (see notes on \@Esphack).

BTW, anyone know why the standard hacks are surrounded by \ifmmode\else rather than simply \ifhmode?

And are there any cases where saving the spacefactor is essential? I have some extensions where it is, but it does not appear to be so in the standard uses.

38 %\def \@bsphack{%
39 %  \relax \ifvmode

40 %    \@savsk \lastskip
41 %    \ifdim \lastskip=\z@
42 %    \else
43 %      \vskip -\lastskip
44 %    \fi
45 %  \else
46 %    \ifhmode
47 %      \@savsk \lastskip
48 %      \@savsf \spacefactor
49 %    \fi
50 %  \fi
51 %}

I think that, in vmode, it is the safest to put in a \nobreak immediately after such things since writes, inserts etc followed by glue give valid breakpoints and, in general, it is possible to create breaks but impossible to destroy them.

52 %\def \@esphack{%
53 %   \relax \ifvmode
54 %     \nobreak
55 %     \ifdim \@savsk=\z@
56 %     \else
57 %       \vskip\@savsk
58 %     \fi
59 %   \else
60 %     \ifhmode
61 %       \spacefactor \@savsf
62 %       \ifdim \@savsk>\z@
63 %         \ignorespaces
64 %       \fi
65 %     \fi
66 %   \fi
67 %}

For the moment we are going to ignore the vertical versions until they are correct.

68 \def \@bsphack{%
69 \relax \ifhmode
70  \@savsk \lastskip
71  \@savsf \spacefactor
72 \fi

73 }

74 \def \@esphack{%
75  \relax \ifhmode
76  \spacefactor \@savsf
77  \ifdim \@savsk>\z@
78  \ignorespaces
79  \fi
80  \fi

81 }

82 \def \@Esphack{%
83  \relax \ifhmode

84  \spacefactor \@savsf
85  \ifdim \@savsk>\z@
86  \global\@ignoretrue
87  \ignorespaces
88  \fi
89  \fi

90 }

\@vbsphack Another variant which is useful for invisible things which should not live in vmode

(this is how some people feel about marginals).

If it occurs in vmode then it enters hmode and ensures that \@savsk is nonzero so that the \ignorespaces is put in later. It is not used at present.

91 % \def \@vbsphack{ %
92 %    \relax \ifvmode
93 %      \leavevmode
94 %      \@savsk 1sp
95 %      \@savsf \spacefactor
96 %    \else
97 %      \ifhmode
98 %        \@savsk \lastskip
99 %        \@savsf \spacefactor
100 %      \fi
101 %    \fi

102 % }

1.1 Vertical spacing

LaTeX supports the PLAIN TeX commands \smallskip, \medskip and

\bigskip.

However, it redefines them using \vspace instead of \vskip.

Extra vertical space is added by the command command

\addvspace{SKIP},

which adds a vertical skip of SKIP to the document. The sequence

        \addvspace{S1} \addvspace{S2}

is equivalent to

\addvspace{maximum of S1, S2}.

\addvspace should be used only in vertical mode, and gives an error if it’s not. The \addvspace command does NOT add vertical space if @minipage = T. The minipage environment uses this to inhibit the addition of extra vertical space at the beginning.

Penalties are put into the vertical list with the \addpenalty{PENALTY} command. It works properly when \addpenalty and \addvspace commands are mixed.

The @nobreak switch is set true used when in vertical mode and no page break should occur. (Right now, it is used only by the section heading commands to inhibit page breaking after a heading.)

  \addvspace{SKIP} ==

BEGIN if vmode

then if @minipage

             else if \lastskip =0

then \vskip SKIP

                     else if \lastskip < SKIP
                              then \vskip -\lastskip
                                    \vskip SKIP

else if SKIP < 0 and \lastskip >= 0

                                     then \vskip -\lastskip
                                          \vskip \lastskip + SKIP

fi  fi  fi  fi

else useful error message (CAR). fi END

103 \def\@xaddvskip{\ifdim \lastskip <\@tempskipb\vskip-\lastskip\vskip
104  \@tempskipb
105  \else  \ifdim \@tempskipb<\z@
106  \ifdim \lastskip <\z@
107  \else \advance\@tempskipb\lastskip
108  \vskip -\lastskip \vskip \@tempskipb
109  \fi\fi\fi}
\addvspace
110 \def\addvspace#1{%
111 \ifvmode
112  \if@minipage\else
113  \ifdim \lastskip =\z@
114  \vskip #1\relax
115  \else
116  \@tempskipb#1\relax
117  \@xaddvskip
118  \fi
119  \fi
120 \else
121  \@noitemerr
122 \fi

123 }

\addpenalty
124 \def\addpenalty#1{%
125 \ifvmode
126  \if@minipage
127  \else
128  \if@nobreak
129  \else
130  \ifdim\lastskip=\z@
131  \penalty#1\relax
132  \else
133  \@tempskipb\lastskip
134  \vskip -\lastskip
135  \penalty#1%
136  \vskip\@tempskipb
137  \fi
138  \fi
139  \fi
140 \else
141  \@noitemerr
142 \fi

143 }

\vspace \@vspace \@vspacer The new code for these commands depends on the following facts:

• The value of prevdepth is changed only when a box or rule is created and added to a vertical list;

• The value of prevdepth is used only when a box is created and added to a vertical list;

• The value of prevdepth is always local to the building of one vertical list.

144 \def\vspace{\@ifstar\@vspacer\@vspace}
145 \def\@vspace #1{%
146 \ifvmode
147  \vskip #1
148  \vskip\z@skip
149 \else
150  \@bsphack
151  \vadjust{\@restorepar
152  \vskip #1
153  \vskip\z@skip

154 }%

155  \@esphack
156 \fi

157 }

158 \def\@vspacer #1{%
159 \ifvmode
160  \dimen@\prevdepth
161  \hrule \@height\z@
162  \nobreak

163  \vskip #1
164  \vskip\z@skip
165  \prevdepth\dimen@
166 \else
167  \@bsphack
168  \vadjust{\@restorepar
169  \hrule \@height\z@
170  \nobreak
171  \vskip #1
172  \vskip\z@skip

173 }%

174  \@esphack
175 \fi

176 }

\smallskip \medskip \bigskip
177 \def\smallskip{\vspace\smallskipamount}
178 \def\medskip{\vspace\medskipamount}
179 \def\bigskip{\vspace\bigskipamount}
\smallskipamount
\medskipamount
\bigskipamount

180 \newskip\smallskipamount \smallskipamount=3pt plus 1pt minus 1pt
181 \newskip\medskipamount   \medskipamount  =6pt plus 2pt minus 2pt
182 \newskip\bigskipamount   \bigskipamount =12pt plus 4pt minus 4pt

1.2 Horizontal space

\nobreakspace This is a robust command that produces a horizontal space at which, in paragraphmode, a line-break is not possible. We then define an active ~ to expand to it since this is the documented behaviour of ~. One reason for introducing this is that some 8-bit input encodings have a slot for such a space and we do not want to use active characters as the L^{A}TEX internal commands.

The braces in the definition of ~ are needed to ensure that a following space is preserved when reading to/from internal files.

183 \DeclareRobustCommand{\nobreakspace}{%
184 \leavevmode\nobreak\ }
185 \catcode `\~=13
186 \def~{\nobreakspace{}}

\, Used in paragraph mode produces a \thinspace. It has the ordinary definition in math mode. Useful for quotes inside quotes, as in ``\,`Foo', he said.''

187 \DeclareRobustCommand{\,}{%
188 \relax\ifmmode\mskip\thinmuskip\else\thinspace\fi

189 }

\@ Placed before a ’.’, makes it a sentence-ending period. Does the right thing for other punctuation marks as well. Does this by setting spacefactor to 1000.

190 \def\@{\spacefactor\@m}

\hspace
191 \DeclareRobustCommand\hspace{\@ifstar\@hspacer\@hspace}
\@hspace
192 \def\@hspace#1{\hskip #1\relax}
\@hspacer
193 \def\@hspacer#1{\vrule \@width\z@\nobreak
194  \hskip #1\hskip \z@skip}
195  % extra \hskip 0pt added 12/17/85 to guard
196  % against a following \unskip
197  % \relax added 13 Oct 88 for usual TeX lossage
198  % replaced both changes by \hskip\z@skip 27 Nov 91
\fill
199 \newskip\fill
200 \fill = 0pt plus 1fill
\stretch
201 \def\stretch#1{\z@ \@plus #1fill\relax}
\thinspace
\negthinspace
\enspace

202 \def\thinspace{\kern .16667em }
203 \def\negthinspace{\kern-.16667em }
204 \def\enspace{\kern.5em }
\enskip \quad \qquad
205 \def\enskip{\hskip.5em\relax}
206 \def\quad{\hskip1em\relax}
207 \def\qquad{\hskip2em\relax}

The following definitions will probably get deleted or moved to compatibility mode soon.

208 {\catcode`\^^M=13 \gdef\obeycr{\catcode`\^^M13 \def^^M{\\\relax}%
209  \@gobblecr}%
210 {\catcode`\^^M=13 \gdef\@gobblecr{\@ifnextchar
211 \@gobble\ignorespaces}}
212 \gdef\restorecr{\catcode`\^^M5 }}

213 ⟨/2ekernel⟩