ltoutput.dtx

Leslie Lamport, Frank Mittelbach, Chris Rowley

1995/11/10

1 Output Routine

1.1 Floats

The ‘2ekernel’ code ensures that a \usepackage{autoout1} is essentially ignored if a ‘full’ format is being used that has the autoload file mode already in the format.

1 ⟨defx⟩\begingroup
2 ⟨defx⟩\makeatletter
3 ⟨defx⟩\nfss@catcodes
4 ⟨2ekernel⟩\expandafter\let\csname ver@autoout1.sty\endcsname\fmtversion

5 ⟨∗2ekernel | autoload⟩

6 \message{output,}

****************************************

* OUTPUT * ****************************************

PAGE LAYOUT PARAMETERS

\topmargin : Extra space added to top of page. @twoside : boolean. T if two-sided printing

\oddsidemargin : IF @twoside = T

THEN extra space added to left of odd-numbered

pages. ELSE extra space added to left of all pages.

\evensidemargin : IF @twoside = T

THEN extra space added to left of

even-numbered

pages.

\headheight : height of head \headsep : separation between head and text \footskip : distance separation between baseline of last

line of text and baseline of foot.

Note difference between \footSKIP and \headSEP.

\textheight : height of text on page, excluding head and foot \textwidth : width of printing on page \columnsep : IF @twocolumn = T

THEN width of space between columns

\columnseprule : IF @twocolumn = T

THEN width of rule between columns (0 if none).

\columnwidth : IF @twocolumn = T

  THEN (\textwidth - \columnsep)/2
  ELSE \textwidth

It is set by the \twocolumn and

\onecolumn commands.

\@textbottom : Command executed at bottom of vbox holding text of

page (including figures). The \raggedbottom command almost \let's this to \vfil (actually sets it to \vskip \z@ plus.0001fil). Should have depth 0pt.

\@texttop : Command executed at top of vbox holding text of page (including figures). Used by letter style; can also be used to produce centered pages.

Let to \relax by \raggedbottom and
\flushbottom.

Page layout must initialize \@colht and \@colroom to \textheight.

PAGE STYLE PARAMETERS:

\floatsep : Space left between floats. \textfloatsep : Space between last top float or first bottom float

and the text.

\topfigrule : Command to place rule (or whatever) between floats at top of page and text. Executed in inner vertica mode right before the \textfloatsep skip separating the floats from the text. Must occupy zero vertical space. (See \footnoterule.)

\botfigrule  : Same as \topfigrule, but put after the

\textfloatsep skip separating text from the floats at bottom of page.

\intextsep : Space left on top and bottom of an in-text float. \dblfloatsep : Space between double-column floats. \dbltextfloatsep : Space between top double-column floats

and text.

\dblfigrule : Similar to \topfigrule, but for double-column floats.

\@fptop : Glue to go at top of float column – must be 0pt +

stretch

\@fpsep : Glue to go between floats in a float column. \@fpbot : Glue to go at bottom of float column

– must be 0pt + stretch

\@dblfptop, \@dblfpsep, \@dblfpbot

: Analogous for double-column float page in two-column format.

FOOTNOTES: As in PLAIN, footnotes use \insert\footins.

PAGE LAYOUT SWITCHES AND MACROS

@twocolumn : Boolean. T if two columns per page globally.

PAGE STYLE MACROS AND SWITCHES

\@oddhead : IF @twoside = T

THEN macro to generate head of

odd-numbered

pages. ELSE macro to generate head of all pages.

\@evenhead : IF @twoside = T

THEN macro to generate head of

even-numbered

pages.

\@oddfoot : IF @twoside = T

THEN macro to generate foot of

odd-numbered

pages. ELSE macro to generate foot of all pages.

\@evenfoot : IF @twoside = T

THEN macro to generate foot of

even-numbered

pages.

@specialpage : boolean. T if current page is to have a special

format.

\@specialstyle : If its value is foo then

IF @specialpage = T

THEN the command \ps@foo is executed to temporarily reset the page style parameters before composing the current page. This command should execute only \def's

and \edef's, making only local definitions.

FLOAT PLACEMENT PARAMETERS

The following parameters are set by the macro \@floatplacement.

When \@floatplacement is called,

\@colht is the height of the page or column being built. I.e.: * For single-column page it equals \textheight.

* For double-column page it equals \textheight - height

of double-column floats on page.

Note that some are set globally and some locally:

\@topnum :=G Maximum number of floats allowed on the top of a

column.

\@toproom :=G Maximum amount of top of column devoted to floats– excluding \textfloatsep separation below the floats and \floatsep separation between them. For two-column output, should be computed as a function

              of \@colht.
\@botnum, \@botroom

: Analogous to above.

\@colnum :=G Maximum number of floats allowed in a column,

including in-text floats.

\@textmin :=L Minimum amount of text (excluding footnotes) that

must appear on a text page.

%% 27 Sep 85 : made local to

                 %% \@addtocurcol and \@addtonextcol

It is now also used locally in processing double floats.

\@fpmin :=L Minimum height of floats in a float column.

The macro \@dblfloatplacement sets the following parameters.

\@dbltopnum :=G Maximum number of double-column floats allowed at

the top of a two-column page.

\@dbltoproom :=G Maximum height of double-column floats allowed at

top of two-column page.

\@fpmin :=L Minimum height of floats in a float column. It should also perform the following local assignments where necessary

– i.e., where the new value differs from the old one:

  \@fptop  :=L \@dblfptop
  \@fpsep  :=L \@dblfpsep
  \@fpbot  :=L \@dblfpbot

OUTPUT ROUTINE VARIABLES

\@colht : The total height of the current column. In single column style, it equals \textheight. In two-column style, it is \textheight minus the height of the double-column floats on the current page. MUST BE INITIALIZED TO

\textheight.

\@colroom : The height available in the current column for text and footnotes. It equals \@colht minus the height of all floats committed to the top and bottom of the current column.

\@textfloatsheight : The total height of in-text floats on the current page.

\footins : Footnote insertion number.

\@maxdepth : Saved value of TeX’s \maxdepth. Must be set when any routine sets \maxdepth.

CALLING THE OUTPUT ROUTINE ————————–

The output routine is called either by TeX’s normal page-breaking mechanism, or by a macro putting a penalty < or = -10000 in the output list. In the latter case, the penalty indicates why the output routine was called, using the following code.

penalty reason ——- ——

-10000  \pagebreak
 \newpage
-10001  \clearpage (\penalty -10000 \vbox{} \penalty -10001)

-10002 float insertion, called from horizontal mode -10003 float insertion, called from vertical mode. -10004 float insertion.

Note: A float or marginpar puts the following sequence in the output

list: (i) a penalty of -10004, (ii) a null \vbox (iii) a penalty of -10002 or -10003.

This solves two special problems:

1. If the float comes right after a \newpage or \clearpage, then the first penalty is ignored, but the second one invokes the output routine.

2. If there is a split footnote on the page, the second ’page’ puts out the rest of the footnote.

THE OUTPUT ROUTINE

——————

FUNCTIONS USED IN THE OUTPUT ROUTINE:

\@outputpage : Produces an output page with the contents of box \@outputbox as the text part.

Also sets \@colht :=G \textheight.

The page style is determined as follows.

IF @thispagestyle = true

  THEN use \thispagestyle style

ELSE use ordinary page style.

\@tryfcolumn\FLIST : Tries to form a float column composed of floats

from \FLIST (if nonempty) with the following parameters: \@colht : height of box \@fpmin : minimum height of floats in the box \@fpsep : interfloat space \@fptop : glue at top of box \@fpbot : glue at bottom of box.

If it succeeds, then it does the following: * \@outputbox :=L the composed float box.

* @fcolmade :=G true

* \FLIST :=G \FLIST - floats put in box

* \@freelist :=G \@freelist + floats put in box

If it fails, then:

* @fcolmade :=G false NOTE: BIT MUST BE A SINGLE TOKEN!

\@makefcolumn \FLIST : Same as \@tryfcolumn except that it

fails to make a float column only if \FLIST is empty. Otherwise, it makes a float column containing at least the first box in \FLIST, disregarding \@fpmin.

\@startcolumn :
Calls \@tryfcolumn\@deferlist. If \@tryfcolumn returns with

(globally set) @fcolmade = false, then:

* Globally sets \@toplist and \@botlist to floats from \@deferlist to go at top and bottom of column, deleting them from \@deferlist. It does this using \@colht as the total height, the page

  style parameters \@floatsep and \@textfloatsep, and

the float placement parameters \@topnum, \@toproom,

  \@botnum, \@botroom, \@colnum and \textfraction.

* Globally sets \@colroom to \@colht minus the height of the added floats.

\@startdblcolumn :
Calls \@tryfcolumn\@dbldeferlist{8}. If \@tryfcolumn returns

with (globally set) @fcolmade = false, then:

* Globally sets \@dbltoplist to floats from \@dbldeferlist to go at top and bottom of column, deleting them from \@dbldeferlist. It does this using \textheight as the total height, and the parameters \@dblfloatsep, etc.

* Globally sets \@colht to \textheight minus the height of the added floats.

\@combinefloats : Combines the text from box

\@outputbox with the floats from \@toplist and
\@botlist,

putting the new box in \@outputbox. It uses \floatsep and \textfloatsep for the appropriate separations. It puts the elements of \TOPLIST and \BOTLIST onto \@freelist, and makes those lists null.

\@makecol : Makes the contents of \box255 plus the accumulated footnotes, plus the floats in \@toplist and \@botlist, into a single column of height \@colht (unless the page height has been locally changed), which it puts into box \@outputbox. It puts boxes in \@midlist back

onto \@freelist and restores \maxdepth.

\@opcol : Outputs a column whose text is in box \@outputbox If @twocolumn = false, then it calls \@outputpage,

sets \@colht :=G \textheight, and calls
\@floatplacement.

If @twocolumn = true, then:

If @firstcolumn = true, then it puts box \@outputbox into \@leftcolumn and sets @firstcolumn :=G false.

If @firstcolumn = false, then it puts out the current two-column page, any possible two-column float pages, and determines \@dbltoplist for the next page.

USER COMMANDS THAT CALL OR AFFECT THE

OUTPUT ROUTINE —————————————————-

\newpage == BEGIN \par\vfil\penalty -10000 END

\clearpage == BEGIN \newpage

\write -1{} % Part of hack to make sure no

                    \vbox{}        % \write's get lost.
                    \penalty -10001

END

\cleardoublepage == BEGIN \clearpage

if @twoside = true and c@page is even

                            then \hbox{} \newpage fi

END

\twocolumn[BOX] : starts a new page, chnaging to twocolumn setting and puts BOX in a parbox of width \textwidth across the top. Useful for full-width titles for double-column pages. SURPRISE: The stretch from \@dbltextfloatsep will be inserted

between the BOX and the top of the two columns.

FLOAT-HANDLING MECHANISMS ————————-

The float environment obtains an insertion number B from the \@freelist (see below for a description of list manipulation), puts the float into box B and sets \count B to a FLOAT SPECIFIER. For a normal (not double-column) float, it then causes a page break in one of the following two ways:

- In outer hmode: \vadjust{\penalty -10002}

- In vmode : \penalty -10003. For a double-column float, it puts B onto the \@dbldeferlist. The float specifier has two components:

* A PLACEMENT SPECIFICATION, describing where the float may be placed.

* A TYPE, which is a power of two–e.g., figures might be

type 1 floats, tables type 2 floats, programs type 4 floats, etc. The float specifier is encoded as follows, where bit 0 is the least significant bit.

Bit Meaning

— ——-

0 1 iff the float may go where it appears in the text.

1 1 iff the float may go on the top of a page.

2 1 iff the float may go on the bottom of a page.

3 1 iff the float may go on a float page.

4 1 unless the PLACEMENT incluses a !

5 1 iff a type 1 float 6 1 iff a type 2 float etc.

A negative float specifier is used to indicate a marginal note.

MACROS AND DATA STRUCTURES FOR PROCESSING FLOATS ————————————————

A FLOAT LIST consisting of the floats in boxes \boxa ... \boxN has the form:

       \@elt \boxa ... \@elt \boxN

where \boxI is defined by

       \newinsert\boxI

Normally, \@elt is \let to \relax. A test can be performed on the entire float list by locally \def'ing \@elt appropriately and executing the list. This is a lot more efficient than looping through the list.

The following macros are used for manipulating float lists.

\@next \CS \LIST {NONEMPTY}{EMPTY} == %% NOTE: ASSUME

\@elt = \relax
  BEGIN assume that \LIST == \@elt \B1 ... \@elt \Bn

if n = 0 then EMPTY else \CS :=L \B1

                 \LIST :=G \@elt \B2 ... \@elt \Bn

NONEMPTY

fi END

\@bitor\NUM\LIST : Globally sets switch @test to the disjunction for all I of bit log2 \NUM of the float specifiers of all the floats in \LIST. I.e., @test is set to true iff there is at least one float in \LIST having bit log2 \NUM of its float specifier equal to 1.

Note: log2 [(\count I)/32] is the bit number corresponding to the type of float I. To see if there is any float in \LIST having the same type as float I, you run \@bitor with

\NUM = [(\count I)/32] * 32.

\@bitor\NUM\LIST ==

BEGIN @test :=G false

{ \@elt \CTR == if \NUM <> 0 then
        if \count\CTR / \NUM is odd

then @test := true fi fi

\LIST
}

END

\@cons\LIST\NUM : Globally sets \LIST := \LIST * \@elt \NUM
\@cons\LIST\NUM ==
BEGIN {  \@elt == \relax
\LIST :=G \LIST \@elt \NUM
}

BOX LISTS FOR FLOAT-PLACEMENT ALGORITHMS

\@freelist : List of empty boxes for placing new floats. \@toplist : List of floats to go at top of current column. \@midlist : List of floats in middle of current column. \@botlist : List of floats to go at bottom of current column. \@deferlist : List of floats to go after current column. \@dbltoplist : List of double-col. floats to go at top of current

page.

\@dbldeferlist : List of double-column floats to go on subsequent pages.

FLOAT-PLACEMENT ALGORITHMS

\@addtobot : Tries to put insert \@currbox on \@botlist.

Called only when:

* \ht BOX < \@colroom
* type of \@currbox not on \@deferlist
* \@colnum > 0

* @insert = false If it succeeds, then:

* sets @insert true

* decrements \@botroom by \ht BOX

* decrements \@botnum and \@colnum by 1 * decrements \@colroom by \ht BOX + either

\floatsep

or \textfloatsep, as appropriate.

* sets \maxdepth to 0pt

\@addtotoporbot : Tries to put insert \@currbox on \@toplist or
   \@botlist.

Called only under same conditions as \@addtobot. If it succeeds, then:

* sets @insert true

      * decrements \@toproom or \@botroom by \ht

BOX

* decrements \@colnum and either \@topnum or

        \@botnum by 1

* decrements \@colroom by \ht BOX +

\floatsep

or \textfloatsep, as appropriate.

\@addtocurcol : Tries to add \@currbox to current column, setting @insert true if it succeeds, false otherwise. It will add \@currbox to top only if bit 0 of \count \@currbox is 0, and to the bottom only if bit 0 = 0 or an earlier float of the same type is put on the bottom. If the float is put in the text, then

\penalty\interlinepenalty is put

right after the float, before the following \vskip,

and \outputpenalty :=L 0.

\@addtonextcol : Tries to add \@currbox to the next column, setting @insert true if it succeeds, false otherwise.

\@addtodblcol : Tries to add \@currbox to the next double-column page, adding it to \@dbltoplist if it succeeds and

\@dbldeferlist if it fails.

\@addmarginpar ==

BEGIN

if \@currlist nonempty
then remove \@marbox from \@currlist
add \@marbox and \@currbox to \@freelist

%% NOTE: \@currbox = left box

else LaTeX error: ? %% shouldn’t happen fi \@tempcnta := 1 %% 1 = right, -1 = left if @twocolumn = true

then if @firstcolumn = true

then \@tempcnta := -1

fi else if @mparswitch = true

then if count0 odd

                else \@tempcnta := -1

fi fi if @reversemargin = true

          then \@tempcnta := -\@tempcnta

fi fi

if \@tempcnta < 0 then \box\@marbox :=G \box\@currbox

fi

\@tempdima :=L maximum(\@mparbottom - \@pageht
                                      + ht of \@marbox, 0)

if \@tempdima > 0 then LaTeX warning: ’marginpar moved’ fi

\@mparbottom :=G \@pageht + \@tempdima + depth of \@marbox
                     + \marginparpush
\@tempdima :=L \@tempdima - ht of \@marbox
\box\@marbox :=G \box\@currbox
                           \vbox { \vskip \@tempdima
                                   \box\@marbox
                                  }

height of \@marbox :=G depth of \@marbox :=G 0

\kern -\@pagedp
\nointerlineskip
\hbox{ if @tempcnta > 0 then \hskip \columnwidth
                            \hskip \marginparsep
                       else \hskip -\marginparsep
                            \hskip -\marginparwidth

fi

       \box\@marbox \hss
     }
\nobreak
\nointerlineskip
\hbox{\vrule height 0 width 0 depth \@pagedp}

END

Floats and marginpars add a lot of dead cycles.

7 \maxdeadcycles = 100
8 \let\@elt\relax
9 \def\@next#1#2#3#4{\ifx#2\@empty #4\else
10 \expandafter\@xnext #2\@@#1#2#3\fi}
11 \def\@xnext \@elt #1#2\@@#3#4{\def#3{#1}\gdef#4{#2}}
12 \newif \if@test

13 \def\@bitor#1#2{\global\@testfalse {\let\@elt\@xbitor
14 \@tempcnta #1\relax #2}}

RmS 91/11/22: Added test for |\count#1 = 0|. Suggested by Chris Rowley.

15 \def\@xbitor #1{\@tempcntb \count#1
16 \ifnum \@tempcnta =\z@
17 \else
18  \divide\@tempcntb\@tempcnta
19  \ifodd\@tempcntb \global\@testtrue\fi
20 \fi}

DEFINITION OF FLOAT BOXES:

21 \newinsert\bx@A
22 \newinsert\bx@B
23 \newinsert\bx@C
24 \newinsert\bx@D
25 \newinsert\bx@E
26 \newinsert\bx@F
27 \newinsert\bx@G
28 \newinsert\bx@H
29 \newinsert\bx@I
30 \newinsert\bx@J
31 \newinsert\bx@K
32 \newinsert\bx@L
33 \newinsert\bx@M
34 \newinsert\bx@N
35 \newinsert\bx@O
36 \newinsert\bx@P
37 \newinsert\bx@Q
38 \newinsert\bx@R
39 \gdef\@freelist{\@elt\bx@A\@elt\bx@B\@elt\bx@C\@elt\bx@D\@elt\bx@E
40  \@elt\bx@F\@elt\bx@G\@elt\bx@H\@elt\bx@I\@elt\bx@J
41  \@elt\bx@K\@elt\bx@L\@elt\bx@M\@elt\bx@N
42  \@elt\bx@O\@elt\bx@P\@elt\bx@Q\@elt\bx@R}
43 \gdef\@toplist{}
44 \gdef\@botlist{}
45 \gdef\@midlist{}
46 \gdef\@currlist{}
47 \gdef\@deferlist{}
48 \gdef\@dbltoplist{}
49 \gdef\@dbldeferlist{}

PAGE LAYOUT PARAMETERS

50 \newdimen\topmargin
51 \newdimen\oddsidemargin
52 \newdimen\evensidemargin
53 \let\@themargin=\oddsidemargin

54 \newdimen\headheight
55 \newdimen\headsep
56 \newdimen\footskip
57 \newdimen\textheight
58 \newdimen\textwidth
59 \newdimen\columnwidth
60 \newdimen\columnsep
61 \newdimen\columnseprule
62 \newdimen\marginparwidth
63 \newdimen\marginparsep
64 \newdimen\marginparpush

\AtBeginDvi \@begindvibox We use a box register in which to put stuff that must appear before anything else

in the .dvi file.

The stuff in the box should not add any typeset material to the page when it is unboxed.

65 \newbox\@begindvibox
66 \def \AtBeginDvi #1{%
67 \global \setbox \@begindvibox
68  \vbox{\unvbox \@begindvibox #1}%

69 }

\@maxdepth This is not the right place to set this; it needs to be set in a class/style file when

\maxdepth is set.

Also, many settings to \maxdepth should be to \@maxdepth, probably?

70 \newdimen\@maxdepth
71 \@maxdepth = \maxdepth
\paperheight \paperwidth New \paper. . . registers.
72 \newdimen\paperheight
73 \newdimen\paperwidth
\if@insert \if@fcolmade \if@specialpage \if@firstcolumn \if@twocolumn \if@twoside \if@reversemarginpar \if@mparswitch \col@number Local switches first:
74 \newif \if@insert

These should definitely be global:

75 \newif \if@fcolmade
76 \newif \if@specialpage \@specialpagefalse

These should be global but are not always set globally in other files.

77 \newif \if@firstcolumn \@firstcolumntrue
78 \newif \if@twocolumn   \@twocolumnfalse

Not sure about these: two questions. Should things which must apply to a whole doument be local or global (they probably should be ‘preamble only’ commands)? Are these three such things?

79 \newif \if@twoside     \@twosidefalse
80 \newif \if@reversemargin \@reversemarginfalse
81 \newif \if@mparswitch  \@mparswitchfalse

This counter has been imported from ‘multicol’.

 82 \newcount \col@number
 83 \col@number \@ne

INTERNAL REGISTERS

 84 \newcount\@topnum
 85 \newdimen\@toproom
 86 \newcount\@dbltopnum
 87 \newdimen\@dbltoproom
 88 \newcount\@botnum
 89 \newdimen\@botroom
 90 \newcount\@colnum
 91 \newdimen\@textmin
 92 \newdimen\@fpmin
 93 \newdimen\@colht
 94 \newdimen\@colroom
 95 \newdimen\@pageht
 96 \newdimen\@pagedp
 97 \newdimen\@mparbottom \@mparbottom\z@
 98 \newcount\@currtype
 99 \newbox\@outputbox
100 \newbox\@leftcolumn
101 \newbox\@holdpg
102 \def\@thehead{\@oddhead} % initialization
103 \def\@thefoot{\@oddfoot}

\clearpage The tests at the beginning are an experimental attempt to avoid a completely empty page after a \twocolumn[...]. This prevents the text from the argument vanishing into a float box, never to be seen again. We hope that it does not produce wrong formatting in other cases.

104 \def\clearpage{%
105 \ifvmode
106  \ifnum \@dbltopnum =\m@ne
107  \ifdim \pagetotal <\topskip
108  \hbox{}
109  \fi
110  \fi
111 \fi
112 \newpage
113 \write\m@ne{}
114 \vbox{}
115 \penalty -\@Mi

116 }

\cleardoublepage
117 \def\cleardoublepage{\clearpage\if@twoside \ifodd\c@page\else
118  \hbox{}\newpage\if@twocolumn\hbox{}\newpage\fi\fi\fi}

119 ⟨/2ekernel | autoload⟩

\onecolumn

120 ⟨∗2ekernel | autoload | fltrace⟩

121 \def\onecolumn{%
122 \clearpage
123 \global\columnwidth\textwidth
124 \global\hsize\columnwidth
125 \global\linewidth\columnwidth
126 \global\@twocolumnfalse
127 \col@number \@ne
128 \@floatplacement}

\newpage \@emptycol It may be better to use an invisible rule rather than an empty box here.

129 \def \newpage {\par\vfil\penalty -\@M}
130 \def \@emptycol {\vbox{}\penalty -\@M}

\twocolumn \@topnewpage There are several bug fixes to the two-column stuff here.

131 \def \twocolumn {%
132 \clearpage
133 \global\columnwidth\textwidth
134 \global\advance\columnwidth-\columnsep
135 \global\divide\columnwidth\tw@
136 \global\hsize\columnwidth
137 \global\linewidth\columnwidth
138 \global\@twocolumntrue
139 \global\@firstcolumntrue
140 \col@number \tw@

There is no reason to put a \@dblfloatplacement here since \@topnewpage ignores these settings. The \@floatplacement is needed in case this comes after some changes.

141 \@ifnextchar [\@topnewpage\@floatplacement

142 }

Note that here, getting a box from the freelist can assume success since this comes just after a \clearpage.

143 \long\def \@topnewpage [#1]{%
144 \@next\@currbox\@freelist{}{}%
145 \global \setbox\@currbox
146  \color@vbox
147  \normalcolor
148  \vbox {%
149  \hsize\textwidth
150  \@parboxrestore
151  \col@number \@ne
152  #1%
153  \vskip -\dbltextfloatsep

154 }%

155  \color@endbox

Added size test and warning message; perhaps we should use an error message.

156 \ifdim \ht\@currbox>\textheight
157  \ht\@currbox \textheight
158 \fi

This next line is not essential but it is more robust to make this value non-zero, in case of weird errors.

This next bit is what is needed from \@addtodblcol, plus some extra checks for error trapping.

159 \global \count\@currbox \tw@
160 \@tempdima -\ht\@currbox
161 \advance \@tempdima -\dbltextfloatsep
162 \global \advance \@colht \@tempdima
163 \ifx \@dbltoplist \@empty
164 \else
165  \@latexerr{Float(s) lost}\@ehb
166  \let \@dbltoplist \@empty
167 \fi
168 \@cons \@dbltoplist \@currbox

This setting of \@dbltopnum is used only to change the typesetting in

\@combinedblfloats.
169 \global \@dbltopnum \m@ne

170 ⟨∗trace⟩

171  \tr@ce{dbltopnum set to -1 (= \the \@dbltopnum) (topnewpage)}%

172 ⟨/trace⟩

At points such as this we need to check that there is still a minimal amount of room left on the page; this uses an arbitrary small value at present. If there is little room left we just force a page-break, OK? This has been extended to cope with having to produce two empty columns.

I now think that the cut-off point should be 3\baselineskip?

Since this happens only when there is nothing on the page but the ‘top-box’, the empty box should not cause any problem other than some overfull box messages, which is not entirely misleading.

Here we need two page-ends since both columns need to be empty.

173 \ifdim \@colht<3\baselineskip
174  \@latex@warning@no@line {Optional argument of \noexpand\twocolumn
175  too tall on page \thepage}%
176  \@emptycol
177  \if@firstcolumn
178  \else
179  \@emptycol
180  \fi
181 \else
182  \global \vsize \@colht
183  \global \@colroom \@colht
184  \@floatplacement
185 \fi

186 }

\output \@specialoutput This needs some small adjustments. We cannot guarantee that the float mechanism will interact correctly with this stuff, but that mecahnism does not always work properly with footnotes already.

RmS 91/09/29:

added reset of \par to the output routine. This avoids problems when the output routine is called within a list where \par may be a no-op.

187 \output {%
188 \let \par \@@par
189 \ifnum \outputpenalty<-\@M
190  \@specialoutput
191 \else
192  \@makecol
193  \@opcol
Moved to \@opcol: \@floatplacement.
194  \@startcolumn

This loop could be replaced by an \expandafter tail recursion in \@startcolumn.

195  \@whilesw \if@fcolmade \fi

196 {% 197 ⟨∗trace⟩

198  \tr@ce{PAGE: float \if@twocolumn column \else page \fi
199  completed}%

200 ⟨/trace⟩

201  \@opcol\@startcolumn}%
202 \fi
203 \ifnum \outputpenalty>-\@Miv

At points such as this we need to check that there is still a minimal amount of room left on the page; this uses an arbitrary small value at present. If there is little room left we just force a page-break, OK?

This bit is essential only if a float has just been processed so maybe it should be moved.

Since this happens only when there is nothing on the page but floats, the empty box should not cause any problem other than some overfull box messages, which is not entirely misleading.

204  \ifdim \@colroom<2\baselineskip
205  \@latex@warning@no@line {Text page \thepage\space
206  contains only floats}%
207  \@emptycol
208  \if@twocolumn
209  \if@firstcolumn
210  \else
211  \@emptycol
212  \fi
213  \fi
214  \else
215  \global \vsize \@colroom
216  \fi

217 \else
218  \global \vsize \maxdimen
219 \fi

220 } 221 ⟨/2ekernel | autoload | fltrace⟩

 CHANGES TO \@specialoutput:
 * \penalty\z@ changed to \penalty\interlinepenalty so \samepage

works properly with figure and table environments.

(Changed 23 Oct 86)

* Definition of \@specialoutput changed 26 Feb 88 so \@pageht and \@pagedp aren’t changed for a marginal note. (Change suggested by Chris Rowley.)

222 ⟨∗2ekernel | def1 | autoload | fltrace⟩

223 \gdef\@specialoutput{%
224 \ifnum \outputpenalty>-\@Mii
225  \@doclearpage
226 \else
227  \ifnum \outputpenalty<-\@Miii
228  \ifnum \outputpenalty<-\@MM \deadcycles \z@ \fi
229  \global \setbox\@holdpg \vbox {\unvbox\@cclv}%
230  \else

Note that \boxmaxdepth should not be set here since we wish to record the natural depth of the holdpg box.

This is changed so as to not lose anything, such as writes and marks, which may get into box 255 and should be returned to the list. This should only happen when the first penalty in the mechanism is discarded and therefore \@holdpg should always be void in this case. This can happen because a penalty is discarded whenever there is no box on the list.

   It was just: \setbox\@tempboxa \box \@cclv.

The last box which is removed is the box put there by the double-penalty mechanism. The \unskip then removes the \topskip which is put there since the box is the first on the page.

231  \global \setbox\@holdpg \vbox{%
232  \unvbox\@holdpg
233  \unvbox\@cclv

We must now remove the box added by the float mechanism and the \topskip glue therefore added above it by TEX.

234  \setbox\@tempboxa \lastbox
235  \unskip

236 }%

These two are needed as separate dimensions only by \@addmarginpar; for other purposes we put the whole size into \@pageht (see below).

237  \@pagedp \dp\@holdpg
238  \@pageht \ht\@holdpg

239  \unvbox \@holdpg
240  \@next\@currbox\@currlist{%
241  \ifnum \count\@currbox>\z@

Putting the whole size into \@pageht (see above).

242  \advance \@pageht \@pagedp
243  \ifvoid\footins \else
244  \advance \@pageht \ht\footins
245  \advance \@pageht \skip\footins
246  \advance \@pageht \dp\footins
247  \fi

248 ⟨∗2ekernel | def1⟩

249  \ifvbox \@kludgeins

We want to make the adjustment due to this insert only if the non-star form is used. The *-form will probably not work with floats, but maybe it still could make some adjustment here even so?

250  \ifdim \wd\@kludgeins=\z@
251  \advance \@pageht \ht\@kludgeins

252 ⟨∗trace⟩

253  \tr@ce {Extra size added: \the \ht\@kludgeins}%

254 ⟨/trace⟩

255  \fi
256  \fi

257 ⟨/2ekernel | def1⟩

This version puts the inserts back just before the additional material; it could be moved earlier, before unboxing the page-so-far. Neither is guaranteed not to put things on the wrong page. This version is similar to the original version.

258  \@reinserts
259  \@addtocurcol
260  \else
261  \@reinserts
262  \@addmarginpar
263  \fi
264  }\@latexbug

A 2e change: use \addpenalty instead of \penalty here. Some penalty is needed to create a potential break-point immediately after the reinerts (or the marginal). Otherwise there can be no possibility to break here and this can cause the reinserts or the marginal to appear on the next page (which is often incorrect).

265  \ifnum \outputpenalty<\z@
266  \if@nobreak
267  \else
268  \addpenalty \interlinepenalty
269  \fi
270  \fi
271  \fi
272 \fi

273 } 274 ⟨/2ekernel | def1 | autoload | fltrace⟩

\@doclearpage This is a very much an emergency action, just dumping everything: footnotes first

then floats. A more sophisticated version is needed.

Also, it puts any left-over non-boxes (writes, specials, etc.) back after any float pages created: this is a bug.

275 ⟨∗2ekernel | autoload⟩

276 \def \@doclearpage {%
277  \ifvoid\footins
278  \setbox\@tempboxa\vsplit\@cclv to\z@ \unvbox\@tempboxa
279  \setbox\@tempboxa\box\@cclv
280  \xdef\@deferlist{\@toplist\@botlist\@deferlist}%
281  \global \let \@toplist \@empty
282  \global \let \@botlist \@empty
283  \global \@colroom \@colht
284  \ifx \@currlist\@empty
285  \else
286  \@latexerr{Float(s) lost}\@ehb
287  \global \let \@currlist \@empty
288  \fi
289  \@makefcolumn\@deferlist
290  \@whilesw\if@fcolmade \fi{\@opcol\@makefcolumn\@deferlist}%
291  \if@twocolumn
292  \if@firstcolumn
293  \xdef\@dbldeferlist{\@dbltoplist\@dbldeferlist}%
294  \global \let \@dbltoplist \@empty
295  \global \@colht \textheight
296  \begingroup
297  \@dblfloatplacement
298  \@makefcolumn\@dbldeferlist
299  \@whilesw\if@fcolmade \fi{\@outputpage
300  \@makefcolumn\@dbldeferlist}%
301  \endgroup
302  \else
303  \vbox{}\clearpage
304  \fi
305  \fi
306  \else
307  \setbox\@cclv\vbox{\box\@cclv\vfil}%
308  \@makecol\@opcol
309  \clearpage
310  \fi

311 } 312 ⟨/2ekernel | autoload⟩

\@opcol Several changes in detail here.

313 ⟨∗2ekernel | autoload | fltrace⟩

314 \def \@opcol {%
315 \if@twocolumn
316  \@outputdblcol

317 \else
318  \@outputpage

319 ⟨∗trace⟩

320  \tr@ce{PAGE: one column (float? see above) page completed}%

321 ⟨/trace⟩

Not needed since it comes after \@outputpage:

322 %   \global\@colht\textheight
323 \fi

These do not need to be done every time \@opcol is used: they should be grouped together since they all need to be done at the end of the non-special output routine, or at the end of a clearpage one.

324 \global \@mparbottom \z@ \global \@textfloatsheight \z@
325 \@floatplacement

326 } 327 ⟨/2ekernel | autoload | fltrace⟩

\@makecol We must rewrite this macro to alllow for variations in page-makeup required by

changes in page-length.

This uses a different macro if a special-length column is being produced.

328 ⟨∗2ekernel | def1 | autoload⟩

329 \gdef \@makecol {%
330 \ifvoid\footins
331  \setbox\@outputbox \box\@cclv
332 \else
333  \setbox\@outputbox \vbox {%

This \boxmaxdepth setting is to ensure that deep footnotes do not overwrite the footer (on account of the negative skip added later): it should use \@maxdepth otherwise the chnage is pointless when there are footnotes.

But see also its use when combining floats.

334  \boxmaxdepth \@maxdepth
335  \unvbox \@cclv
336  \vskip \skip\footins
337  \color@begingroup
338  \normalcolor
339  \footnoterule
340  \unvbox \footins
341  \color@endgroup

342 }%

343 \fi

The h floats have now been finally committed to this page so we can reset their list. The top and bottom floats are then added to the page.

344 \xdef\@freelist{\@freelist\@midlist}%
345 \global \let \@midlist \@empty
346 \@combinefloats

The variations start here in case \enlargethispage has been used.

347 ⟨∗2ekernel | def1⟩

348 \ifvbox\@kludgeins
349  \@makespecialcolbox
350 \else

351 ⟨/2ekernel | def1⟩

This extra reboxing is only needed to add the \@texttop and \@textbotttom but this could be done earlier, when the floats are added.

The \boxmaxdepth resetting here will have no effect unless \@textbottom ends with a box or rule. So is this (or possibly \@maxdepth) the correct value?

The \vskip -\dimen@ ensures that the visible depth of the box does not affect the placement of anything on the page. Thus very deep pages will overprint the footer; but these should have been prevented by suitable settings of the maxdepths at appropriate times.

If \@textbottom ends with a box or rule of non-zero depth then this skip adjustemnt should be done again after it.

I think that the final boxing of the main text page could have a common ending which may make it simpler to see what is going on.

This needs further investigation, especially in the ‘special case’.

Also, the \boxmaxdepth setting here affects what happens wthin \@texttop and \@textbottom, should it? Is it needed at all?

RmS 91/10/22: Replaced \dimen128 by \dimen@.

352  \setbox\@outputbox \vbox to\@colht {%
353 %       \boxmaxdepth \maxdepth                   %??
354  \@texttop
355  \dimen@ \dp\@outputbox
356  \unvbox \@outputbox
357  \vskip -\dimen@
358  \@textbottom

359 }% 360 ⟨∗2ekernel | def1⟩

361 \fi

362 ⟨/2ekernel | def1⟩

363 \global \maxdepth \@maxdepth

364 } 365 ⟨/2ekernel | def1 | autoload⟩

\@reinserts This is the code which reinserts the inserts. It puts them all in one place; this can make some of them come out on the wrong page. It has been put into a separate macro to expidite experimentation.

366 ⟨∗2ekernel | def1 | autoload⟩

367 \gdef \@reinserts{%
368 \ifvoid\footins\else\insert\footins{\unvbox\footins}\fi
369 ⟨+2ekernel | def1⟩ \ifvbox\@kludgeins\insert\@kludgeins
370 ⟨+2ekernel | def1⟩  {\unvbox\@kludgeins}\fi

371 } 372 ⟨/2ekernel | def1 | autoload⟩

\@makespecialcolbox This implements certain variations in page-makeup.

373 ⟨∗2ekernel | def1 | fltrace⟩

374 \gdef \@makespecialcolbox {%

375 ⟨∗trace⟩

376 \tr@ce{Kludgeins ht \the\ht\@kludgeins\space
377  dp \the\dp\@kludgeins\space
378  wd \the\wd\@kludgeins}%

379 ⟨/trace⟩

First we find the natural height of the column.

See above for discussion of what is happening here.

This needs further investigation, especially in this ‘special case’.

380 \setbox\@outputbox \vbox {%
381  \@texttop
382  \dimen@ \dp\@outputbox
383  \unvbox\@outputbox
384  \vskip-\dimen@

385 }%

386 \@tempdima \@colht
387 \ifdim \wd\@kludgeins>\z@

Note that in this case (the *-version), the height of the \@kludgeins box is not used since its value is somewhat arbitrary: it need only be big enough to ensure that the page-break is not taken prematurely.

Here we calculate how much vertical space needs to be added in order to enable the column to fit into a box of size \@colht using the best information we have about the amount of shrink available (another thing which is known internally about a box, but cannot be accessed at the TEX level!).

This needs TEX3 otherwise \pageshrink is zero anyway; it may not be exactly the figure we wish as it is the total available from the all the material collected before the page-break decision is made. It will, we think, always be an overestimate of the actual shrink in the box; therefore this should always force the shortest possible column with the possibility of an overfull box.

This should work for bothe flush- and ragged-bottom setting since it makes the contents no smaller than the size (\@colht) of the box into which they are put.

Their should perhaps be an upper limit, of 0pt?, on the extra space added to force shrinking.

See above for a discussion of the \boxmaxdepth setting here.

388  \advance \@tempdima -\ht\@outputbox
389  \advance \@tempdima \pageshrink

390 ⟨∗trace⟩

391  \tr@ce {Natural ht of col: \the \ht\@outputbox}%
392  \tr@ce {\string \@colht: \the \@colht}%
393  \tr@ce {Pageshrink added: \the \pageshrink}%
394  \tr@ce {Hence, space added: \the \@tempdima}%

395 ⟨/trace⟩

396  \setbox\@outputbox \vbox to \@colht {%

397 %       \boxmaxdepth \maxdepth
398  \unvbox\@outputbox
399  \vskip \@tempdima
400  \@textbottom

401 }%

For the unstarred version, the final size of the page is precisely specified. Therefore, at least for the flush-bottom case, we need to ensure that, visually, it has this size exactly.

Thus we calculate this size and set the material in a box of this size, which is then put into a box of size \@colht with \vss at the bottom.

402 \else
403  \advance \@tempdima -\ht\@kludgeins

404 ⟨∗trace⟩

405  \tr@ce {Natural ht of col: \the \ht\@outputbox}%
406  \tr@ce {\string \@colht: \the \@colht}%
407  \tr@ce {Extra size added: -\the \ht \@kludgeins}%
408  \tr@ce {Hence, height of inner box: \the \@tempdima}%
409  \tr@ce {Max? pageshrink available: \the \pageshrink}%

410 ⟨/trace⟩

This type of final packaging could be done always; this may simplify all of this page-makeup.

It is not necessary to set \boxmaxdepth here since the \@outputbox ends with glue.

411  \setbox \@outputbox \vbox to \@colht {%
412  \vbox to \@tempdima {%
413  \unvbox\@outputbox
414  \@textbottom}%
415  \vss}%
416 \fi

Finally we need to explicitly make the insert box void.

417 {\setbox \@tempboxa \box \@kludgeins}%

418 } 419 ⟨/2ekernel | def1 | fltrace⟩

\@texttop \@textbottom These do nothing as a default.

420 ⟨∗2ekernel | autoload⟩

421 \let \@texttop \relax
422 \let \@textbottom \relax

\@resetactivechars \@activechar@info RmS 93/09/06: added hook to protect against certain active characters in the output routine. Default checks are for active space and end-of-line.

423 \def\@activechar@info #1{%
424  \@latex@info@no@line {Active #1 character found while
425  output routine is active
426  \MessageBreak
427  This may be a bug in a package file
428  you are using}%

429 }

Do not put any spaces in this next bit!

430 \begingroup
431 \obeylines\obeyspaces%
432 \gdef\@resetactivechars{%
433 \def^^M{\@activechar@info{EOL}\space}%
434 \def {\@activechar@info{space}\space}}%
435 \endgroup

\@outputpage \@shipoutsetup \@writesetup The \color@hbox hooks here are used to avoid putting just a colour special into an otherwise empty box (in a header or footer). These boxes are often set to be completely empty and so adding a special produces a very underfull box message.

There has been extensive tidying up of the old code here; including the removal of a level of grouping.

The setting of \protect immediately before the \shipout is needed so that protected commands within \writes are handled correctly.

Within shipout’s vbox it is reset to its default value, \relax.

Resetting it to its default value after the shipout has been completed (and the contents of the writes have been expanded) must be done by use of \aftergroup. This is because it must have the value \relax before macros coming from other uses of \aftergroup within this box are expanded.

Putting this into the \aftergroup token list does not affect the definition used in expanding the \writes because the aftergroup token list is only constructed when popping the save-stack, it is not expanded until after the shipout is completed.

Question: should things from an \aftergroup within the shipped out box be executed in the environment set up for the writes, or after it finishes?

A lot of this code has been in-lined tp prevent mis-use of internal commands as hooks.

436 \def\@outputpage{%
437 \begingroup           % the \endgroup is put in by \aftergroup

Now all the set-up stuff has been in-lined for Frank.

First the stuff for the writes.

From here … was in the command \@writesetup.

438 \let \protect \noexpand

RmS 93/08/19: Redefined accents to allow changes in font encoding; but exactly why was this needed?

The \catcode`\ = 10 was removed as it was considered useless (presumably because nothing gets tokenised during shipout).

This was put in as some error produced active spaces in a mark, I think.

Why was the hyphen reset?

439 \@resetactivechars
440 \let\-\@dischyph

With the new encoding setup the following line can use \let. It could also use the new internal commands?

441 \let\'\@acci\let\`\@accii\let\=\@acciii

442 \let\\\@normalcr

The was once inside the box.

443 \let\par\@@par          %% 15 Sep 87

… to here was in the command \@writesetup.

444 \shipout \vbox{%
445  \set@typeset@protect
446  \aftergroup \endgroup
447  \aftergroup \set@typeset@protect
448  % correct? or just restore by ending
449  % the group?

This first bit has been moved inside the shipped out box.

Now the setup inside the shipped out box; this should conatin all the stuff that could only affect typesetting; other stuff may need to be reset for the writes also.

From here … was in the command \@shipoutsetup.

450 \if@specialpage
451  \global\@specialpagefalse\@nameuse{ps@\@specialstyle}%
452 \fi
453 \if@twoside
454  \ifodd\count\z@ \let\@thehead\@oddhead \let\@thefoot\@oddfoot
455  \let\@themargin\oddsidemargin
456  \else \let\@thehead\@evenhead
457  \let\@thefoot\@evenfoot \let\@themargin\evensidemargin
458  \fi
459 \fi

The rest was always inside the box. RmS 91/08/15: aded this line:

460 \reset@font

RmS 93/08/06 Added \lineskiplimit=0pt to guard against it being nonzero: e.g. by \offinterlineskip being in effect.

There are probably lots of other things that may need resetting.

461 \normalsize
462 \baselineskip\z@skip \lineskip\z@skip \lineskiplimit\z@

… to here was in the command \@shipoutsetup.

463  \@begindvi
464  \vskip \topmargin
465  \moveright\@themargin \vbox {%
466  \setbox\@tempboxa \vbox to\headheight{%
467  \vfil
468  \color@hbox
469  \normalcolor
470  \hb@xt@\textwidth {%
471  \let \label \@gobble
472  \let \index \@gobble
473  \let \glossary \@gobble %% 21 Jun 91
474  \@thehead

475 }%

476  \color@endbox
477  }%                        %% 22 Feb 87
478  \dp\@tempboxa \z@
479  \box\@tempboxa
480  \vskip \headsep
481  \box\@outputbox
482  \baselineskip \footskip
483  \color@hbox
484  \normalcolor
485  \hb@xt@\textwidth{%
486  \let \label \@gobble
487  \let \index \@gobble      %% 22 Feb 87
488  \let \glossary \@gobble   %% 21 Jun 91
489  \@thefoot

490 }%

491  \color@endbox

492 }% 493 }%

494 %   \endgroup now inserted by \aftergroup
495 \global \@colht \textheight
496 \stepcounter{page}%

It is now clear that this does something useful, thanks to Piet van Oostrum. It is needed because a float page is made without using TeX’s page-builder; thus the output routine is never called so the marks are not updated.

497 \let\firstmark\botmark

498 }

\@begindvi This unboxes stuff that must appear before anything else in the .dvi file, then

returns that box register to the free list and cancels itself.

The stuff in the box should not add any typeset material to the page.

499 \def \@begindvi{%
500 \unvbox \@begindvibox
501 \global\let \@begindvi \@empty

502 }

\@combinefloats \@cflt \@cflb The \boxmaxdepth setting here was not made local to a box so was dangerous. It is needed only within the box made by \@cflt (and not normally even there), so it has been moved there; this also agrees with the original pseudcode.

503 \def \@combinefloats {%
504 %    \boxmaxdepth \maxdepth
505  \ifx \@toplist\@empty \else \@cflt \fi
506  \ifx \@botlist\@empty \else \@cflb \fi

507 }

508 \def \@cflt{%
509  \let \@elt \@comflelt
510  \setbox\@tempboxa \vbox{}%
511  \@toplist

512  \setbox\@outputbox \vbox{%
513  \boxmaxdepth \maxdepth
514  \unvbox\@tempboxa
515  \vskip -\floatsep
516  \topfigrule
517  \vskip \textfloatsep
518  \unvbox\@outputbox

519 }%

520  \let\@elt\relax
521  \xdef\@freelist{\@freelist\@toplist}%
522  \global\let\@toplist\@empty

523 }

524 \def \@cflb {%
525  \let\@elt\@comflelt
526  \setbox\@tempboxa \vbox{}%
527  \@botlist
528  \setbox\@outputbox \vbox{%
529  \unvbox\@outputbox
530  \vskip \textfloatsep
531  \botfigrule
532  \unvbox\@tempboxa
533  \vskip -\floatsep

534 }%

535  \let\@elt\relax
536  \xdef\@freelist{\@freelist\@botlist}%
537  \global \let \@botlist\@empty

538 }

\@comflelt
\@comdblflelt
\@combinedblfloats

539 \def\@comflelt#1{\setbox\@tempboxa
540  \vbox{\unvbox\@tempboxa\box #1\vskip\floatsep}}
541 \def\@comdblflelt#1{\setbox\@tempboxa
542  \vbox{\unvbox\@tempboxa\box #1\vskip\dblfloatsep}}
543 \def \@combinedblfloats{%
544 \ifx \@dbltoplist \@empty
545 \else
546  \setbox\@tempboxa \vbox{}%
547  \let \@elt \@comdblflelt
548  \@dbltoplist
549  \let \@elt \relax
550  \xdef \@freelist {\@freelist\@dbltoplist}%
551  \global\let \@dbltoplist \@empty
552  \setbox\@outputbox \vbox to\textheight

The setting of \boxmaxdepth here has no effect since the \@outputbox should already have depth zero. Even so, it would have no effect on the layout of the page.

553  {%\boxmaxdepth\maxdepth   %% probably not needed, CAR
554  \unvbox\@tempboxa\vskip-\dblfloatsep

Here we need different typesetting if the top float comes from \@topnewpage.

555  \ifnum \@dbltopnum>\m@ne
556  \dblfigrule
557  \fi
558  \vskip \dbltextfloatsep
559  \box\@outputbox

560 }%

561 \fi

562 } 563 ⟨/2ekernel | autoload⟩

\@startcolumn \@startdblcolumn We could combine (most of) these two into \@startcol <list>. Note that

\@xstartcol was only used once (i.e. in \@startcolumn); it has therefore been removed. This is not quite as efficient but it now has the same structure as

 \@startdblcolumn.

The empty-list test has been moved to \@tryfcolumn.

564 ⟨∗2ekernel | autoload | fltrace⟩

565 \def \@startcolumn {%
566 \global \@colroom \@colht
567 \@tryfcolumn \@deferlist
568 \if@fcolmade

569 ⟨∗trace⟩

570  \tr@ce{PAGE: float \if@twocolumn column \else page \fi
571  completed}%

572 ⟨/trace⟩

573 \else
574  \begingroup
575  \let \reserved@b \@deferlist
576  \global \let \@deferlist \@empty
577  \let \@elt \@scolelt
578  \reserved@b
579  \endgroup
580 \fi

581 }

This one does not need to set \@colht.

582 \def \@startdblcolumn {%

Not needed since this always comes after \@outputpage:

583 % \global \@colht \textheight
584 \@tryfcolumn \@dbldeferlist
585 \if@fcolmade

586 ⟨∗trace⟩

587  \tr@ce{PAGE: double float page completed}%

588 ⟨/trace⟩

589 \else
590  \begingroup
591  \let \reserved@b \@dbldeferlist

592  \global \let \@dbldeferlist \@empty
593  \let \@elt \@sdblcolelt
594  \reserved@b
595  \endgroup
596 \fi

597 }

\@tryfcolumn Now tests if its list is empty before any further exertion.

598 \def \@tryfcolumn #1{%
599 \global \@fcolmadefalse
600 \ifx #1\@empty
601 \else

602 ⟨∗trace⟩

603  \tr@ce{PAGE: try float \if@twocolumn column/page\else page\fi
604  ---\string #1}%
605  \tr@ce{----- \string #1: #1}%

606 ⟨/trace⟩

607  \xdef\@trylist{#1}%
608  \global \let \@failedlist \@empty
609  \begingroup
610  \let \@elt \@xtryfc \@trylist
611  \endgroup
612  \if@fcolmade
613  \@vtryfc #1%
614  \fi
615 \fi

616 } 617 ⟨/2ekernel | autoload | fltrace⟩

618 ⟨∗2ekernel | autoload⟩

619 \def\@scolelt#1{\def\@currbox{#1}\@addtonextcol}
620 \def\@sdblcolelt#1{\def\@currbox{#1}\@addtodblcol}
621 \def\@vtryfc #1{\global\setbox\@outputbox\vbox{}\let\@elt\@wtryfc
622  \@flsucceed \global\setbox\@outputbox
623  \vbox to\@colht{\vskip \@fptop
624  \vskip -\@fpsep \unvbox \@outputbox
625  \vskip \@fpbot}\let\@elt\relax
626  \xdef #1{\@failedlist\@flfail}%
627  \xdef\@freelist{\@freelist\@flsucceed}}

628 \def\@wtryfc #1{\global\setbox\@outputbox\vbox{\unvbox\@outputbox
629  \vskip\@fpsep\box #1}}
630 \def\@xtryfc #1{\@next\reserved@a\@trylist{}{}\@currtype
631 \count #1\divide\@currtype\@xxxii \multiply\@currtype\@xxxii
632 \@bitor \@currtype \@failedlist \@testfp #1\ifdim
633  \ht #1>\@colht \global\@testtrue\fi
634  \if@test \@cons\@failedlist #1\else \@ytryfc #1\fi}

635 \def\@ytryfc #1{\begingroup \gdef\@flsucceed{\@elt #1}%
636 \global\let\@flfail\@empty
637 \@tempdima\ht #1\let\@elt\@ztryfc \@trylist
638 \ifdim \@tempdima >\@fpmin
639  \global\@fcolmadetrue \else \@cons\@failedlist #1\fi
640 \endgroup \if@fcolmade \let\@elt\@gobble \fi}
641 \def\@ztryfc #1{\@tempcnta\count #1\divide\@tempcnta\@xxxii
642  \multiply\@tempcnta\@xxxii \@bitor \@tempcnta {\@failedlist
643  \@flfail}\@testfp #1\@tempdimb\@tempdima
644  \advance\@tempdimb\ht #1\advance
645  \@tempdimb\@fpsep \ifdim \@tempdimb >\@colht \global\@testtrue\fi
646  \if@test \@cons\@flfail #1\else
647  \@cons\@flsucceed #1\@tempdima\@tempdimb
648  \fi}

649 ⟨/2ekernel | autoload⟩

The major changes for float suppression and the changes to the float mechanism to make it conform to the documentation are in these next macros.

\@addtobot Lots of changes.

650 ⟨∗2ekernel | autoload | fltrace⟩

651 \def \@addtobot {%

652 ⟨∗trace⟩

653 \tr@ce{***Start addtobot}%

654 ⟨/trace⟩

655 \@getfpsbit 4\relax

656 ⟨∗trace⟩

657 \tr@ce{fpstype \ifodd \@tempcnta OK \else not \fi bot:
658  \the \@fpstype}%

659 ⟨/trace⟩

660 \ifodd \@tempcnta
661  \@flsetnum \@botnum
662  \ifnum \@botnum>\z@
663  \@tempswafalse
664  \@flcheckspace \@botroom \@botlist
665  \if@tempswa

This next line means that this page is produced with box 255 having depth zero, rather than the normal maxdepth: is this needed, useful?

666  \global \maxdepth \z@
667  \@flupdates \@botnum \@botroom \@botlist

668 ⟨∗trace⟩

669  \tr@ce{colroom (after-bot) = \the \@colroom}%
670  \tr@ce{colnum (after-bot) = \the \@colnum}%
671  \tr@ce{botnum (after-bot) = \the \@botnum}%
672  \tr@ce{***Success: bot}%

673 ⟨/trace⟩

674  \@inserttrue
675  \fi

676 ⟨∗trace⟩

677  \else
678  \tr@ce{Fail: botnum = \the \@botnum:
679  fpstype \the \@fpstype=ORD?}%
680  \ifnum \@fpstype<\sixt@@n
681  \tr@ce{ERROR: !b float not successful (addtobot)}%
682  \fi

683 ⟨/trace⟩

684  \fi
685 \fi

686 }

\@addtotoporbot Lots of changes.
687 \def \@addtotoporbot {%

688 ⟨∗trace⟩

689 \tr@ce{***Start addtotoporbot}%

690 ⟨/trace⟩

691 \@getfpsbit \tw@

692 ⟨∗trace⟩

693 \tr@ce{fpstype \ifodd \@tempcnta OK \else not \fi top:
694  \the \@fpstype}%

695 ⟨/trace⟩

696 \ifodd \@tempcnta
697  \@flsetnum \@topnum
698  \ifnum \@topnum>\z@
699  \@tempswafalse
700  \@flcheckspace \@toproom \@toplist
701  \if@tempswa
702  \@bitor\@currtype{\@midlist\@botlist}%

703 ⟨∗trace⟩

704  \tr@ce{(mid+bot)list: \@midlist, \@botlist:
705  (addtotoporbot-before)}%

706 ⟨/trace⟩

707  \if@test

708 ⟨∗trace⟩

709  \tr@ce{type already on list: mid or bot---sent to addtobot}%

710 ⟨/trace⟩

711  \else
712  \@flupdates \@topnum \@toproom \@toplist

713 ⟨∗trace⟩

714  \tr@ce{colroom (after-top) = \the \@colroom}%
715  \tr@ce{colnum (after-top) = \the \@colnum}%
716  \tr@ce{topnum (after-top) = \the \@topnum}%
717  \tr@ce{***Success: top}%

718 ⟨/trace⟩

719  \@inserttrue
720  \fi
721  \fi

722 ⟨∗trace⟩

723  \else

724  \tr@ce{Fail: topnum = \the \@topnum: fpstype
725  \the \@fpstype=ORD?}%
726  \ifnum \@fpstype<\sixt@@n
727  \tr@ce{ERROR: !t float not successful (addtotoporbot)}%
728  \fi

729 ⟨/trace⟩

730  \fi
731 \fi
732 \if@insert
733 \else

734 ⟨∗trace⟩

735  \tr@ce{sent to addtobot (addtotoporbot)}%

736 ⟨/trace⟩

737  \@addtobot
738 \fi

739 } 740 ⟨/2ekernel | autoload | fltrace⟩

\@addtocurcol Lots of changes.

741 ⟨∗2ekernel | autoload | fltrace | flafter⟩

742 \def \@addtocurcol {%

743 ⟨∗trace⟩

744 \tr@ce{***Start addtocurcol}%

745 ⟨/trace⟩

746 \@insertfalse
747 \@setfloattypecounts
748 \ifnum \@fpstype=8

749 ⟨∗trace⟩

750  \tr@ce{fpstype !p only (addtocurcol): \the \@fpstype = 8?}%

751 ⟨/trace⟩

752 \else
753  \ifnum \@fpstype=24

754 ⟨∗trace⟩

755  \tr@ce{fpstype p only (addtocurcol): \the \@fpstype = 24?}%

756 ⟨/trace⟩

757  \else
758  \@flsettextmin

This is a new adjustment which is quite a major change in functionality; but it implements the documentation. Note that \@reqcolroom will include the whole of the page-so-far, and hence includes \@textfloatsheight of floats, so before comparing it with \@textmin, we add this to \@textmin also.

759 ⟨∗trace⟩

760  \tr@ce{textfloatsheight (before) = \the \@textfloatsheight}%

761 ⟨/trace⟩

762  \advance \@textmin \@textfloatsheight
763  \@reqcolroom \@pageht

This line must be removed since \@specialoutput changed.

764 %       \advance \@reqcolroom \@pagedp

765 ⟨∗trace⟩

766  \tr@ce{textmin + textfloatsheight: \the \@textmin}%
767  \tr@ce{page-so-far: \the \@reqcolroom}%

768 ⟨/trace⟩

769  \ifdim \@textmin>\@reqcolroom
770  \@reqcolroom \@textmin

771 ⟨∗trace⟩

772  \tr@ce{ORD? textmin being used}%

773 ⟨/trace⟩

774  \fi
775  \advance \@reqcolroom \ht\@currbox

776 ⟨∗trace⟩

777  \tr@ce{float size = \the \ht \@currbox (addtocurcol)}%
778  \tr@ce{colroom = \the \@colroom (addtocurcol)}%
779  \tr@ce{reqcolroom = \the \@reqcolroom (addtocurcol)}%

780 ⟨/trace⟩

781  \ifdim \@colroom>\@reqcolroom
782  \@flsetnum \@colnum
783  \ifnum \@colnum>\z@
784  \@bitor\@currtype\@deferlist

785 ⟨∗trace⟩

786  \tr@ce{deferlist: \@deferlist: (addtocurcol-before)}%

787 ⟨/trace⟩

788  \if@test

789 ⟨∗trace⟩

790  \tr@ce{type already on list: defer (addtocurcol)}%

791 ⟨/trace⟩

792  \else
793  \@bitor\@currtype\@botlist

794 ⟨∗trace⟩

795  \tr@ce{botlist: \@botlist: (addtocurcol-before)}%

796 ⟨/trace⟩

797  \if@test

798 ⟨∗trace⟩

799  \tr@ce{type already on list: bot---sent to addtobot}%

800 ⟨/trace⟩

801  \@addtobot
802  \else

803 ⟨∗trace⟩

804  \tr@ce{fpstype \ifodd \@tempcnta OK \else not \fi
805  here: \the \@fpstype}%

806 ⟨/trace⟩

807  \ifodd \count\@currbox
808  \advance \@reqcolroom \intextsep
809  \ifdim \@colroom>\@reqcolroom
810  \global \advance \@colnum \m@ne
811  \global \advance \@textfloatsheight \ht\@currbox

This may sometimes give an overestimate.

812  \global \advance \@textfloatsheight 2\intextsep

813  \@cons \@midlist \@currbox

814 ⟨∗trace⟩

815  \tr@ce{***Success: here}%
816  \tr@ce{textfloatsheight (after-here) =
817  \the \@textfloatsheight}%
818  \tr@ce{colnum (after-here) = \the \@colnum}%

819 ⟨/trace⟩

    CHANGE TO \@addtocurcol:
    \penalty\z@ changed to \penalty\interlinepenalty so \samepage works

properly with figure and table environments. (Changed 23 Oct 86)

    There is also an \addpenalty\interlinepenalty above.

Since in 2e \samepage is no longer supported, these could be removed.

Although it is best to use \addvspace in case two h floats come together, this makes other spacing more difficult to adjust; whereas if a user specifies two h floats together then they can more easily get the spacing correct by ad hoc commands.

It is necessary to adjust for the addition of \parskip here in case the float is added betweeen paragraphs (i.e. when in vertical mode).

Typesetting starts here.

820  \if@nobreak
821  \else
822  \addpenalty \interlinepenalty
823  \fi
824  \vskip \intextsep
825  \box\@currbox
826  \penalty\interlinepenalty
827  \vskip\intextsep
828  \ifnum\outputpenalty <-\@Mii \vskip -\parskip\fi

Typesetting ends here.

829  \outputpenalty \z@
830  \@inserttrue

831 ⟨∗trace⟩

832  \else
833  \tr@ce{Fail---no room at 2nd test of colroom
834  (addtocorcol \string\intextsep)}%

835 ⟨/trace⟩

836  \fi
837  \fi
838  \if@insert
839  \else

840 ⟨∗2ekernel | autoload | fltrace⟩ 841 ⟨∗trace⟩

842  \tr@ce{not here: sent to addtotoporbot}%

843 ⟨/trace⟩

844  \@addtotoporbot

845 ⟨/2ekernel | autoload | fltrace⟩ 846 ⟨∗!2ekernel&!autoload&!fltrace⟩ 847 ⟨∗trace⟩

848  \tr@ce{not here: sent to addtobot}%

849 ⟨/trace⟩

850  \@addtobot

851 ⟨/!2ekernel&!autoload&!fltrace⟩

852  \fi
853  \fi
854  \fi

855 ⟨∗trace⟩

856  \else
857  \tr@ce{Fail: colnum = \the \@colnum:
858  fpstype \the \@fpstype=ORD?}%
859  \ifnum \@fpstype<\sixt@@n
860  \tr@ce{ERROR: BANG float not successful (addtocurcol)}%
861  \fi

862 ⟨/trace⟩

863  \fi

864 ⟨∗trace⟩

865  \else
866  \tr@ce{Fail---no room: fl box ht: \the \ht \@currbox
867  (addtocurcol)}%

868 ⟨/trace⟩

869  \fi
870  \fi
871 \fi
872 \if@insert
873 \else
874  \@resethfps

875 ⟨∗trace⟩

876  \tr@ce{put on deferlist (addtocurcol)}%

877 ⟨/trace⟩

878  \@cons\@deferlist\@currbox

879 ⟨∗trace⟩

880  \tr@ce{deferlist: \@deferlist: (addtocurcol-after)}%

881 ⟨/trace⟩

882 \fi

883 } 884 ⟨/2ekernel | autoload | fltrace | flafter⟩

\@addtonextcol Lots of changes.

885 ⟨∗2ekernel | autoload | fltrace⟩

886 \def\@addtonextcol{%
887 \begingroup

888 ⟨∗trace⟩

889 \tr@ce{***Start addtonextcol}%

890 ⟨/trace⟩

891 \@insertfalse
892 \@setfloattypecounts
893 \ifnum \@fpstype=8

894 ⟨∗trace⟩

895  \tr@ce{fpstype not curcol: \the \@fpstype = 8?}%

896 ⟨/trace⟩

897 \else
898  \ifnum \@fpstype=24

899 ⟨∗trace⟩

900  \tr@ce{fpstype not curcol: \the \@fpstype = 24?}%

901 ⟨/trace⟩

902  \else
903  \@flsettextmin

904 ⟨∗trace⟩

905  \tr@ce{text-so-far: 0pt (top of col)}%

906 ⟨/trace⟩

907  \@reqcolroom \ht\@currbox

908 ⟨∗trace⟩

909  \tr@ce{float size: \the \@reqcolroom (addtonextcol)}%

910 ⟨/trace⟩

911  \advance \@reqcolroom \@textmin

912 ⟨∗trace⟩

913  \tr@ce{colroom = \the \@colroom (addtonextcol)}%
914  \tr@ce{reqcolroom = \the \@reqcolroom (addtonextcol)}%

915 ⟨/trace⟩

916  \ifdim \@colroom>\@reqcolroom
917  \@flsetnum \@colnum
918  \ifnum\@colnum>\z@
919  \@bitor\@currtype\@deferlist

920 ⟨∗trace⟩

921  \tr@ce{deferlist: \@deferlist: (addtonextcol-before)}%

922 ⟨/trace⟩

923  \if@test

924 ⟨∗trace⟩

925  \tr@ce{type already on list: defer (addtonextcol)}%

926 ⟨/trace⟩

927  \else

928 ⟨∗trace⟩

929  \tr@ce{sent to addtotoporbot (addtonextcol)}%

930 ⟨/trace⟩

931  \@addtotoporbot
932  \fi
933  \fi

934 ⟨∗trace⟩

935  \else
936  \tr@ce{Fail---no room: fl box ht: \the \ht \@currbox
937  (addtonextcol)}%

938 ⟨/trace⟩

939  \fi
940  \fi
941 \fi
942 \if@insert
943 \else

944 ⟨∗trace⟩

945  \tr@ce{put back on deferlist (addtonextcol)}%

946 ⟨/trace⟩

947  \@cons\@deferlist\@currbox

948 ⟨∗trace⟩

949  \tr@ce{deferlist: \@deferlist: (addtonextcol-after)}%

950 ⟨/trace⟩

951 \fi

952 ⟨∗trace⟩

953 \tr@ce{End of addtonextcol -- locally counts:}%
954 \tr@ce{ col: \the \@colnum. top: \the \@topnum. bot: \the \@botnum.}%

955 ⟨/trace⟩

956 \endgroup

957 ⟨∗trace⟩

958 \tr@ce{End of addtonextcol -- globally counts:}%
959 \tr@ce{col: \the \@colnum. top: \the \@topnum. bot: \the \@botnum.}%

960 ⟨/trace⟩ 961 }

\@addtodblcol Lots of changes.

962 \def\@addtodblcol{%
963 \begingroup

964 ⟨∗trace⟩

965 \tr@ce{***Start addtodblcol}%

966 ⟨/trace⟩

967 \@insertfalse
968 \@setfloattypecounts
969 \@getfpsbit \tw@

970 ⟨∗trace⟩

971 \tr@ce{fpstype \ifodd \@tempcnta OK \else not \fi dbltop:
972  \the \@fpstype}%

973 ⟨/trace⟩

974 \ifodd\@tempcnta
975  \@flsetnum \@dbltopnum
976  \ifnum \@dbltopnum>\z@
977  \@tempswafalse
978  \ifdim \@dbltoproom>\ht\@currbox
979  \@tempswatrue

980 ⟨∗trace⟩

981  \tr@ce{Space OK: \@dbltoproom =
982  \the \@dbltoproom > \the \ht \@currbox
983  (dbltoproom)}%

984 ⟨/trace⟩

985  \else

986 ⟨∗trace⟩

987  \tr@ce{fpstype: \the \@fpstype (addtodblcol)}%

988 ⟨/trace⟩

989  \ifnum \@fpstype<\sixt@@n

990 ⟨∗trace⟩

991  \tr@ce{BANG float ignoring \@dbltoproom}%
992  \tr@ce{\@spaces \@dbltoproom = \the \@dbltoproom.
993  Ht float: \the \ht \@currbox-BANG}%

994 ⟨/trace⟩

Need to check that there is room on the page, using the local value of \@textmin to make the necessary adjustment to \@dbltoproom.

 995  \advance \@dbltoproom \@textmin

996 ⟨∗trace⟩

 997  \tr@ce{Local value of texmin: \the\@textmin}%
 998  \tr@ce{\@spaces space on page = \the \@dbltoproom.
 999  Ht float: \the \ht \@currbox-BANG}%

1000 ⟨/trace⟩

1001  \ifdim \@dbltoproom>\ht\@currbox
1002  \@tempswatrue

1003 ⟨∗trace⟩

1004  \tr@ce{Space OK BANG: space on page = \the \@dbltoproom >
1005  \the \ht \@currbox}%
1006  \else
1007  \tr@ce{fpstype: \the \@fpstype}%
1008  \tr@ce{Fail---no room dbltoproom-BANG?:}%
1009  \tr@ce{\@spaces space on page = \the \@dbltoproom.
1010  Ht float: \the \ht \@currbox}%

1011 ⟨/trace⟩ 1012 \fi

1013  \advance \@dbltoproom -\@textmin

1014 ⟨∗trace⟩

1015  \else
1016  \tr@ce{fpstype: \the \@fpstype}%
1017  \tr@ce{Fail---no room dbltoproom-ORD?:}%
1018  \tr@ce{\@spaces \@dbltoproom = \the \@dbltoproom.
1019  Ht float: \the \ht \@currbox}%

1020 ⟨/trace⟩ 1021 \fi 1022 \fi

1023  \if@tempswa
1024  \@bitor \@currtype \@dbldeferlist

1025 ⟨∗trace⟩

1026  \tr@ce{dbldeferlist: \@dbldeferlist: (before)}%

1027 ⟨/trace⟩

1028  \if@test

1029 ⟨∗trace⟩

1030  \tr@ce{type already on list: dbldefer}%

1031 ⟨/trace⟩

1032  \else
1033  \@tempdima -\ht\@currbox
1034  \advance\@tempdima
1035  -\ifx \@dbltoplist\@empty \dbltextfloatsep \else
1036  \dblfloatsep \fi
1037  \global \advance \@dbltoproom \@tempdima
1038  \global \advance \@colht \@tempdima
1039  \global \advance \@dbltopnum \m@ne
1040  \@cons \@dbltoplist \@currbox

1041 ⟨∗trace⟩

1042  \tr@ce{dbltopnum (after) = \the \@dbltopnum}%
1043  \tr@ce{***Success: dbltop}%

1044 ⟨/trace⟩

1045  \@inserttrue

1046 \fi 1047 \fi 1048 ⟨∗trace⟩

1049  \else
1050  \tr@ce{Fail: dbltopnum = \the \@dbltopnum: fpstype
1051  \the \@fpstype=ORD?}%
1052  \ifnum \@fpstype<\sixt@@n
1053  \tr@ce{ERROR: !t float not successful (addtodblcol)}%

1054 \fi 1055 ⟨/trace⟩ 1056 \fi 1057 \fi

1058 \if@insert
1059 \else

1060 ⟨∗trace⟩

1061  \tr@ce{put on dbldeferlist}%

1062 ⟨/trace⟩

1063  \@cons\@dbldeferlist\@currbox

1064 ⟨∗trace⟩

1065  \tr@ce{dbldeferlist: \@dbldeferlist: (after)}%

1066 ⟨/trace⟩ 1067 \fi 1068 ⟨∗trace⟩

1069 \tr@ce{End of addtodblcol -- locally count:}%
1070 \tr@ce{ dbltop: \the \@dbltopnum.}%

1071 ⟨/trace⟩

1072 \endgroup

1073 ⟨∗trace⟩

1074 \tr@ce{End of addtodblcol -- globally count:}%
1075 \tr@ce{dbltop: \the \@dbltopnum.}%

1076 ⟨/trace⟩ 1077 } 1078 ⟨/2ekernel | autoload | fltrace⟩

\@addmarginpar

1079 ⟨∗2ekernel | autoload⟩

1080 \def\@addmarginpar{\@next\@marbox\@currlist{\@cons\@freelist\@marbox
1081  \@cons\@freelist\@currbox}\@latexbug\@tempcnta\@ne
1082  \if@twocolumn
1083  \if@firstcolumn \@tempcnta\m@ne \fi
1084  \else
1085  \if@mparswitch
1086  \ifodd\c@page \else\@tempcnta\m@ne \fi

1087 \fi

1088  \if@reversemargin \@tempcnta -\@tempcnta \fi

1089 \fi

1090  \ifnum\@tempcnta <\z@  \global\setbox\@marbox\box\@currbox \fi
1091  \@tempdima\@mparbottom
1092  \advance\@tempdima -\@pageht
1093  \advance\@tempdima\ht\@marbox
1094  \ifdim\@tempdima >\z@
1095  \@latex@warning@no@line {Marginpar on page \thepage\space moved}%
1096  \else
1097  \@tempdima\z@

1098 \fi

1099  \global\@mparbottom\@pageht
1100  \global\advance\@mparbottom\@tempdima
1101  \global\advance\@mparbottom\dp\@marbox
1102  \global\advance\@mparbottom\marginparpush
1103  \advance\@tempdima -\ht\@marbox

Putting box movement inside the ‘marbox’:

1104  \global\setbox \@marbox
1105  \vbox {\vskip \@tempdima
1106  \box \@marbox}%
1107  \global \ht\@marbox \z@
1108  \global \dp\@marbox \z@

Sticking (rather than gluing:-) the ‘marbox’ to the line above, changed vskip to kern:

1109  \kern -\@pagedp
1110  \nointerlineskip
1111  \hb@xt@\columnwidth
1112  {\ifnum \@tempcnta >\z@
1113  \hskip\columnwidth \hskip\marginparsep
1114  \else
1115  \hskip -\marginparsep \hskip -\marginparwidth

1116 \fi

1117  \box\@marbox \hss}%

For this reason the following code can vanish:

      \nobreak             %% No longer needed.  CAR92/12
      \vskip -\@tempdima   %% No longer needed.  CAR92/12
1118  \nointerlineskip
1119  \hbox{\vrule \@height\z@ \@width\z@ \@depth\@pagedp}}

1120 ⟨/2ekernel | autoload⟩

1.1.1 Kludgeins

This part of the file is part of the implementation of the following two new commands for L^{A}TEX2e.

   \enlargethispage{<dim>}

Adds <dim> to the height of the current column only. On the printed page the bottom of this column is extended downwards by exactly <dim> without having any effect on the placement of the footer; this may result in an overprinting.

 \enlargethispage*{<dim>}

Similar to \enlargethispage but it tries to squeeze the column to be printed in as small a space as possible, ie it uses any shrinkability in the column. If the column was not explicitly broken (e.g. with \pagebreak) this may result in an overfull box message but execpt for this it will come out as expected (if you know what to expect).

The star form of this command is dedicated to Leslie Lamport, the other we need for ourselves (FMi, CAR).

\@kludgeins The insert which makes TEX do a lot of the necessary work. All we need to put into it is the amount by which the pagegoal should be changed.

1121 ⟨∗2ekernel | def1⟩

1122 \newinsert \@kludgeins
1123 \global\dimen\@kludgeins \maxdimen
1124 \global\count\@kludgeins 1000

1125 ⟨/2ekernel | def1⟩

\enlargethispage \enlargethispage* The user command.

1126 ⟨∗2ekernel | def1⟩

1127 \gdef \enlargethispage {%
1128 \@ifstar

1129 {% 1130 ⟨∗trace⟩

1131  \tr@ce{Enlarging page height * }%

1132 ⟨/trace⟩

1133  \@enlargepage{\hbox{\kern\p@}}}%

1134 {% 1135 ⟨∗trace⟩

1136  \tr@ce{Enlarging page height exactly---}%

1137 ⟨/trace⟩

1138  \@enlargepage\@empty}%

1139 } 1140 ⟨/2ekernel | def1⟩ 1141 ⟨∗autoload⟩

1142 \def\enlargethispage{\@autoload{out1}\enlargethispage}

1143 ⟨/autoload⟩

\@enlargepage This actually inserts the insert, after checking for extreme values of the change.

1144 ⟨∗2ekernel | def1⟩

1145 \gdef\@enlargepage#1#2{%

1146 ⟨∗trace⟩

1147 \tr@ce{\@spaces\@spaces by #2}%

1148 ⟨/trace⟩

1149 \@tempskipa#2\relax
1150 \ifdim \@tempskipa>.5\maxdimen
1151  \@latexerr{Suggested\space extra\space height\space
1152  (\the\@tempskipa)\space dangerously\space
1153  large}\@eha
1154 \else
1155  \ifdim \vsize<.5\maxdimen

1156 ⟨∗trace⟩

1157  \tr@ce {Kludgeins added--pagegoal before: \the\pagegoal}%

1158 ⟨/trace⟩

1159  \@bsphack
1160  \insert\@kludgeins{#1\vskip-\@tempskipa}%
1161  \@esphack

This next bit is for tracing only:

1162 ⟨∗trace⟩

1163  \ifvmode \par
1164  \tr@ce {Kludgeins added--pagegoal after: \the \pagegoal}%

1165 \fi 1166 ⟨/trace⟩

1167  \else
1168  \@latexerr{Page\space height\space already\space
1169  too\space large}\@eha

1170 \fi 1171 \fi 1172 } 1173 ⟨/2ekernel | def1⟩

1.1.2 Float control

This part implements controllable floats and other changes to the float mechanism.

It provides, at the doument level, the following command for inclusion in L^{A}TEX2e.

     \suppressfloats

This suppresses all further floats on the current page.

With an optional argument it suppresses only floats only in certain positions on the current page.

[t] suppresses only floats at the top of the page [b] suppresses only floats at the bottom of the page

It also enables the use of an extra specifier, !, in the location optional argument of a float. If this is present then, just for this particular float, whenever it is processed by the float mechanism the followinhg are ignored:

• all restrictions on the number of floats which can appear; • all explicit restrictions on the amount of space which should (not) be occu-

pied by floats and/or text.

The mechanism will still attempt to ensure that pages are not overfull.

These specifiers override, for the single float, the suppression commands described above.

In its current form, it also suplies a reasonably exhaustive, and somewhat baroque, means of tracing some aspects of the float mechanism.

More tracing.

\tr@ce \notrace \tracefloats \@traceval \tracefloatvals \@tracemessage Set-up tracing for floats independent of other tracing as it produces mega-output. Default is no tracing.

1174 ⟨∗trace⟩

1175 \def \@tracemessage #1{\typeout{LaTeX2e: #1}}
1176 \def \tracefloats{\let \tr@ce \@tracemessage}
1177 \def \notrace {\let \tr@ce \@gobble}
1178 \notrace
1179 \def \@traceval #1{\tr@ce{\string #1 = \the #1}}
1180 \def \tracefloatvals{%
1181 \@dblfloatplacement
1182 \@floatplacement
1183 \@traceval\@colnum
1184 \@traceval\@colroom
1185 \@traceval\@topnum
1186 \@traceval\@toproom
1187 \@traceval\@botnum
1188 \@traceval\@botroom
1189 \@traceval\@fpmin
1190 \tr@ce{\string\textfraction = \textfraction}%
1191 \@traceval\@dbltopnum
1192 \@traceval\@dbltoproom

1193 } 1194 ⟨/trace⟩ 1195 ⟨∗flafter⟩

1196 \providecommand\tr@ce[1]{}

1197 ⟨/flafter⟩

\suppressfloats \@flstop Float suppression commands: these set the relevant counter globally to zero. Thus they are overridden for a particular float by an ! specifier.

1198 ⟨∗2ekernel | autoload⟩

1199 \def \suppressfloats {%
1200 \@ifnextchar [%
1201  \@flstop
1202  {\global \@colnum \z@}%

1203 }

Maybe this should be a loop over #1?

1204 \def \@flstop [#1]{%
1205 \if t#1%

1206  \global \@topnum \z@

1207 \fi

1208 \if b#1%
1209  \global \@botnum \z@

1210 \fi 1211 }

Manipulation of float placement and type; both their strings and the corresponding count registers.

\@fpstype \@reqcolroom \@textfloatsheight First a new count register to go with \@currtype.

Then a new skip register, for information needed to remove the \@maxsep conservatism: it is possible that this could use a temporary register.

Finally a dimension register to hold the total height of in-text floats on the current page. This is needed to implement a major change in the functionality of \@addtocurcol which is, nevertheless, a bug fix. It is not local and therefore cannot be a temporary register.

1212 \newcount \@fpstype
1213 \newdimen \@reqcolroom
1214 \newdimen \@textfloatsheight

1215 ⟨/2ekernel | autoload⟩

\@fpsadddefault Adds the default placement to what is already there. Should not need to change this, but could do it as follows:

  \def \@fpsadddefault {%
     \@temptokena \expandafter\expandafter\expandafter
                  {\csname fps@\@captype \endcsname}%
     \edef \reserved@a {\the\@temptokena}%
     \@onelevel@sanitize \reserved@a
     \edef \@fps {\@fps\reserved@a}%
  }

1216 ⟨∗2ekernel | autoload | fltrace⟩

1217 \def \@fpsadddefault {%

1218 ⟨∗trace⟩

1219 \tr@ce{fps changed from: \@fps}%

1220 ⟨/trace⟩

1221 \edef \@fps {\@fps\csname fps@\@captype \endcsname}%
1222 \@latex@warning {%
1223  No positions in optional float specifier.\MessageBreak
1224  Default added (so using `\@fps')}%

1225 }

\@setfloattypecounts Sets counters \@fpstype and \@currtype.
    BANG == bit4 of \count\@currbox = 0.
1226 \def \@setfloattypecounts {%
1227 \@currtype \count\@currbox

1228 \@fpstype \count\@currbox
1229 \divide\@currtype\@xxxii \multiply\@currtype\@xxxii
1230 \advance \@fpstype -\@currtype

1231 ⟨∗trace⟩

1232 \tr@ce{(mod 32) fpstype: \the \@fpstype}%
1233 \tr@ce{(mult of 32) currtype: \the \@currtype}%
1234 % Tracing only: but some should be changed into real errors/warnings?
1235 \ifnum \@fpstype<\sixt@@n
1236  \ifnum \@fpstype=\z@
1237  \tr@ce{ERROR: no PLACEMENT, fpstype = \the \@fpstype = 0?}%

1238 \fi

1239  \ifnum \@fpstype=\@ne
1240  \tr@ce{WARNING: only h, fpstype = \the \@fpstype = 1?}%

1241 \fi

1242  \tr@ce{BANG float}%
1243 \else
1244  \ifnum \@fpstype=\sixt@@n
1245  \tr@ce{ERROR: no PLACEMENT, fpstype = \the \@fpstype = 16?}%

1246 \fi

1247  \ifnum \@fpstype=17
1248  \tr@ce{WARNING: only h, fpstype = \the \@fpstype = 17?}%

1249 \fi

1250  \tr@ce{ORD float}%

1251 \fi 1252 ⟨/trace⟩ 1253 } 1254 ⟨/2ekernel | autoload | fltrace⟩

Macros for getting, testing and setting bits of the fps.

\@getfpsbit Sets \@tempcnta to required bit of \count\@currbox.

1255 ⟨∗2ekernel | autoload⟩

1256 \def \@getfpsbit {%
1257 \@boxfpsbit \@currbox

1258 }

\@boxfpsbit Used above.
1259 \def \@boxfpsbit #1#2{%
1260 \@tempcnta \count#1%
1261 \divide \@tempcnta #2\relax

1262 }

\@testfp New definition of the float page test.

1263 \def \@testfp #1{%
1264 \@boxfpsbit #18\relax % Really `#1 8' for human readers!
1265 \ifodd \@tempcnta
1266 \else
1267  \global \@testtrue

1268 \fi 1269 }

\@setfpsbit Sets required bit of \@tempcnta (to 1).

1270 \def \@setfpsbit #1{%
1271 \@tempcntb \@tempcnta
1272 \divide \@tempcntb #1\relax
1273 \ifodd \@tempcntb
1274 \else
1275  \advance \@tempcnta #1\relax

1276 \fi 1277 } 1278 ⟨/2ekernel | autoload⟩

\@resethfps Globally adds t as a possible location for an h or !h only placement: this must be

done using the count.

Although it will leave \@fpstype set to 17 even if it was originally 1, this does not matter since it is the last thing in \@addtocurcol.

1279 ⟨∗2ekernel | autoload | fltrace⟩

1280 \def \@resethfps {%
1281 \let\reserved@a\@empty
1282 \ifnum \@fpstype=\@ne
1283  \def \reserved@a {!}%
1284  \@fpstype 17

1285 \fi

1286 \ifnum \@fpstype=17
1287  \global \advance \count\@currbox \tw@
1288  \@latex@warning@no@line {%
1289  `\reserved@a h' float specifier changed to `\reserved@a ht'}%

1290 ⟨∗trace⟩

1291  \tr@ce{%
1292  `t' added to `\reserved@a h'- new Count: \the \count\@currbox}%

1293 ⟨/trace⟩ 1294 \fi 1295 }

Special stuff for BANG floats.

\@flsetnum Ignores any zero float counter value in case BANG.

It uses a local assignment to the normally global counter: a bit naughty, perhaps?

These assgnments are safe so long as the counter involved is only consulted once (i.e. only for the ‘bang float’) with the changed value. This is the case within \@addtocurcol because it is used only once within a call of the output routine (which forms a group).

For \@addtonextcol this is achieved by putting a group around its code; this is needed because it is called (by \@startcolumn) for each float which was on the deferlist. Almost identical considerations pertain to \@addtodblcol. There may be more efficient ways to handle this, but the group seems to be the simplest.

1296 \def \@flsetnum #1{%

1297 ⟨∗trace⟩

1298 \tr@ce{fpstype: \the \@fpstype (flsetnum \string#1)}%

1299 ⟨/trace⟩

1300 \ifnum \@fpstype<\sixt@@n
1301  \ifnum #1=\z@

1302 ⟨∗trace⟩

1303  \tr@ce{BANG float resetting \string#1 to 1}%

1304 ⟨/trace⟩

1305  #1\@ne

1306 \fi 1307 \fi 1308 ⟨∗trace⟩

1309 \tr@ce{#1 (before) = \the #1}%

1310 ⟨/trace⟩ 1311 }

\@flsettextmin This ignores \textfraction space restriction in case BANG.

1312 \def \@flsettextmin {%

1313 ⟨∗trace⟩

1314 \tr@ce{fpstype: \the \@fpstype (flsettextmin)}%

1315 ⟨/trace⟩

1316 \ifnum \@fpstype<\sixt@@n

1317 ⟨∗trace⟩

1318  \tr@ce{BANG ignoring textmin}%

1319 ⟨/trace⟩

1320  \@textmin \z@
1321 \else
1322  \@textmin \textfraction\@colht

1323 ⟨∗trace⟩

1324  \tr@ce{ORD textmin = \the \@textmin}%

1325 ⟨/trace⟩ 1326 \fi 1327 }

\@flcheckspace This ignores space restriction in case BANG; this is still slightly conervative since it does not allow for the fact that, if there is no text in the column then \textfloatsep is not needed. Sets @tempswa true if there is room for \@currbox.

1328 \def \@flcheckspace #1#2{%
1329 \advance \@reqcolroom
1330  \ifx #2\@empty \textfloatsep \else \floatsep \fi

1331 ⟨∗trace⟩

1332 \tr@ce{colroom = \the \@colroom (flcheckspace \string#1 \string#2)}%
1333 \tr@ce{reqcolroom = \the \@reqcolroom
1334  (flcheckspace \string#1 \string#2)}%

1335 ⟨/trace⟩

1336 \ifdim \@colroom>\@reqcolroom
1337  \ifdim #1>\ht\@currbox
1338  \@tempswatrue

1339 ⟨∗trace⟩

1340  \tr@ce{Space OK: #1 = \the #1 > \the \ht \@currbox

1341  (flcheckspace \string#1 \string#2)}%

1342 ⟨/trace⟩

1343  \else

1344 ⟨∗trace⟩

1345  \tr@ce{fpstype: \the \@fpstype
1346  (flcheckspace \string#1 \string#2)}%

1347 ⟨/trace⟩

1348  \ifnum \@fpstype<\sixt@@n

1349 ⟨∗trace⟩

1350  \tr@ce{BANG float ignoring #1
1351  (flcheckspace \string#1 \string#2):}%
1352  \tr@ce{\@spaces #1 = \the #1.  Ht float: \the \ht \@currbox
1353  BANG}%

1354 ⟨/trace⟩

1355  \@tempswatrue

1356 ⟨∗trace⟩

1357  \else
1358  \tr@ce{Fail---no room (flcheckspace \string#1 \string#2)
1359  (fpstype \the \@fpstype=ORD?):}%
1360  \tr@ce{\@spaces #1 = \the #1.  Ht float: \the \ht \@currbox
1361  ORD?}%

1362 ⟨/trace⟩ 1363 \fi 1364 \fi 1365 ⟨∗trace⟩

1366 \else
1367  \tr@ce{Fail---no room at 2nd test of colroom
1368  (flcheckspace \string#1 \string#2)}%

1369 ⟨/trace⟩ 1370 \fi 1371 } 1372 ⟨/2ekernel | autoload | fltrace⟩

\@flupdates This updates everything when a float is placed.

1373 ⟨∗2ekernel | autoload⟩

1374 \def \@flupdates #1#2#3{%
1375 \global \advance #1\m@ne
1376 \global \advance \@colnum \m@ne
1377 \@tempdima -\ht\@currbox
1378 \advance \@tempdima
1379  -\ifx #3\@empty \textfloatsep \else \floatsep \fi
1380 \global \advance #2\@tempdima
1381 \global \advance \@colroom \@tempdima
1382 \@cons #3\@currbox

1383 } 1384 ⟨/2ekernel | autoload⟩

Interesting facts about float mechanisms past and present, together with a summary of various features, some unresolved:

1. The value \textfraction does not affect the processing of doublecol floats: this seems sensible, but should be documented.

2. \twocolumn floatplacement was wrong: dbl not needed, ord needed.

3. \@floatplacement was not called after \@startdblcol or \@topnewpage.

This has been changed; it is clearly a bug fix.

4. The use \@topnewpage when \dblfigrule is non-trivial produced a rule in the wrong place. This has been fixed by not using \dblfigrule when processing the ‘float’ from \@topnewpage.

5. If the specifier was just h and the float could not be put here, it went on the deferlist and stayed there until a clearpage. It now gets changed to a ‘th’: this is only an error-recovery action, putting just h or !h should be deprecated.

6. \@dblmaxsep was ‘the maximum of \dblfloatsep and \dbltexfloatsep’.

But it was never used! Now gone completely, like \@maxsep.

7. After an h float is put on a page, it was counted as text when applying the \textfraction test; this is possibly too big a change although it is a bug fix?

8. Two consecutive h floats are separated by twice \intextsep: this could be changed to one by use of \addvspace, OK? Note that it would also mean that less space is put in if an h float immediaiely follows other spaces. This is also possibly too big a change, at least for compatibility mode? Or it may be simply wrong! It has not been changed.

9. Now \@addtocurcol checks first for just p fps. I think that this is an increase in efficiency, but maybe the coding should be made even more efficient.

10. \@tryfcolumn now tests if the list is empty first, otherwise lots of wasted time! Thus this test has been removed from \@startcolumn. As Frank pointed out, this makes \@startcolumn less efficient. But it is now the same as \@startdblcolumn: I can see no reason why they should be different, but which is best?

11. Why is \@colroom set in \@doclearpage?

12. Footnotes. Check what \clearpage does when footnotes are left over. Footnotes are not put on float pages and, also, \@addtonextcol ignores the existence of held-over footnotes in deciding what floats can go on the page. Not changed.

13. \clearpage can still lose non-boxes, at least when floats are involved. It also moves some to the ‘wrong page’, but this may be a coding problem.

14. The ! option makes it necessary to check in \output that there is enough room left on the page after adding a float. (This would have been necessary anyway if anyone set \@textmin too close to zero! A similar danger existed also if the text in a \twocolumn[text] entity gets too large.) The current implementation of this also makes the normal case a little less efficient, OK? Not enough room means, at present, less than \baselineskip, with a warning: is this OK? Should it be made generic (another parameter)?

15. There are four possibilities for supporting this:

\twocolumn[\maketitle more text]

One is to change \maketitle slightly to allow this. Another is to change \@topnewpage so that more than one \twocolumn[] command is allowed; in this case \maketitle\twoclumn[more text] will work. The former is more robust from the user’s viewpoint, but makes the code for \maketitle rather ad hoc (maybe it is already?). Another is to misuse the global twocolumn flag locally within \@topnewpage. Yet another is to move the column count register from the multicol package into the kernel. This has beeen done.

16. Where should the reinserts be put to maximise the probability that footmotes come out on the correct page? Or should we go for as much comaptibility as psossible (but see next item)?

17. Should we continue to support (as much as possible) \samepage? Some of its intended functionality is now advertised as being provided by \enlargethispage. Use of either is likely to result in wrongly placed footnotes, marginals, etc. Which should have priority: obeying the pagination instructions, or correct placement of notes/marginalia?

18. Is the adjustment of space to cause shrinking in the kludge-* case correct? Should it be limited to 0pt?

19. Is the setting of \boxmaxdepth in makecol and friends needed? It only has any effect if \@textbottom ends with a box or rule, in which case the vskip to allow for its depth should also be added. If it is kept, it should probably be the last thing in the box. It has now been removed. It would perhaps be better to document that \@textbottom and \@texttop must have natural height 0pt.

20. I cannot see why the vskip adjustement for the depth is needed if boxmaxdepth is used to ensure that there is never a too deep box.

21. The value of \boxmaxdepth should be explicitly set whenever necessary: it is too risky to assume that it has any particular value. Care is needed in deciding what to set it to. It is interesting to note that the value of \boxmaxdepth is unique in being read before the local settings for the box group are reset; all other parameter settings which affect the box construction use their values outside the box group.

22. Should \@maxdepth store the setting of \maxdepth from lplain? Or should we provide a proper interface to class files for setting these?

An analysis of various other macros.

\@opcol should do \@floatplacement, but where? Right at the end, since it always occurs at the start of a column.

   \def\@opcol{%
     % Why is this done first?
     \global \@mparbottom \z@
     \if@twocolumn
       \@outputdblcol
     \else
       \@outputpage
       % This is not needed since it is done at the end of
       %   |\@outputpage|:
       \global \@colht \textheight
     \fi}

Only tracing has been added to these.

1385 ⟨∗2ekernel | autoload | fltrace⟩

1386 \def\@makefcolumn #1{%
1387 \begingroup
1388  \@fpmin \z@
1389  \let \@testfp \@gobble
1390  \@tryfcolumn #1%
1391 \endgroup

1392 ⟨∗trace⟩

1393 \if@fcolmade
1394  \tr@ce{PAGE: in \string\clearpage \if@twocolumn ---twocolumn\fi---}%
1395  \tr@ce{----- float column/page completed from \string#1}%

1396 \fi 1397 ⟨/trace⟩ 1398 }

This will line up the last baselines in the two columns provided they are constructed in the normal way: i.e. ending in a skip of minus the original depth, with \@textbottom adding nothing.

Thus again it is essential for \@textbottom to have depth 0pt.

1399 \def\@outputdblcol{%
1400 \if@firstcolumn
1401  \global \@firstcolumnfalse
1402  \global \setbox\@leftcolumn \box\@outputbox

1403 ⟨∗trace⟩

1404  \tr@ce{PAGE: first column boxed}%

1405 ⟨/trace⟩

1406 \else
1407  \global \@firstcolumntrue
1408  \setbox\@outputbox \vbox {%

1409  \hb@xt@\textwidth {%
1410  \hb@xt@\columnwidth {%
1411  \box\@leftcolumn \hss}%
1412  \hfil
1413  \vrule \@width\columnseprule
1414  \hfil
1415  \hb@xt@\columnwidth {%
1416  \box\@outputbox \hss}%

1417 }% 1418 }% 1419 ⟨∗trace⟩

1420  \tr@ce{PAGE: second column also boxed}%

1421 ⟨/trace⟩

1422  \@combinedblfloats
1423  \@outputpage

1424 ⟨∗trace⟩

1425  \tr@ce{PAGE: two column page completed}%

1426 ⟨/trace⟩

1427  \begingroup
1428  \@dblfloatplacement
1429  \@startdblcolumn

This loop could be replaced by an \expandafter tail recursion in

  \@startdblcolumn.
1430  \@whilesw\if@fcolmade \fi
1431  {\@outputpage

1432 ⟨∗trace⟩

1433  \tr@ce{PAGE: double float page completed}%

1434 ⟨/trace⟩

1435  \@startdblcolumn}%
1436  \endgroup

1437 \fi 1438 } 1439 ⟨/2ekernel | autoload | fltrace⟩

1.1.3 Float placement parameters

The main purpose of this section is to ensure that all the float-placement parameters which need to be set in a class file or package have been declared. It also describes their use and sets values for them which are reasonable for typical douments using US letter or A4 sized paper.

Limits for the placement of floating objects

\c@topnumber This counter holds the maximum number of floats that can appear at the top of a text page or column.

1440 ⟨∗2ekernel | autoload⟩

1441 \newcount\c@topnumber
1442 \setcounter{topnumber}{2}

\topfraction This macro holds the maximum proportion (as a decimal number) of a text page or column that can be occupied by floats at the top.

1443 \newcommand\topfraction{.7}

\c@bottomnumber This counter holds the maximum number of floats that can appear at the bottom of a text page or column.

1444 \newcount\c@bottomnumber
1445 \setcounter{bottomnumber}{1}

\bottomfraction This macro holds the maximum proportion (as a decimal number) of a text page or column that can be occupied by floats at the bottom.

1446 \newcommand\bottomfraction{.3}

\c@totalnumber This counter holds the maximum number of floats that can appear on any text page or column.

1447 \newcount\c@totalnumber
1448 \setcounter{totalnumber}{3}

\textfraction This macro holds the minimum proportion (as a decimal number) of a text page or column that must be occupied by text.

1449 \newcommand\textfraction{.2}

\floatpagefraction This macro holds the minimum proportion (as a decimal number) of a page or column that must be occupied by floating objects before a ‘float page’ is produced.

1450 \newcommand\floatpagefraction{.5}

\c@dbltopnumber This counter holds the maximum number of double-column floats that can appear on the top of a two-column text page.

1451 \newcount\c@dbltopnumber
1452 \setcounter{dbltopnumber}{2}

\dbltopfraction This macro holds the maximum proportion (as a decimal number) of a two-column text page that can be occupied by double-column floats at the top.

1453 \newcommand\dbltopfraction{.7}

\dblfloatpagefraction This macro holds the minimum proportion (as a decimal number) of a page that must be occupied by double-column floating objects before a ‘double-column float page’ is produced.

1454 \newcommand\dblfloatpagefraction{.5}

Floats on a text page

\floatsep \textfloatsep \intextsep When a floating object is placed on a page with text, these parameters control the seperation between the float and the other objects on the page. These parameters are used for both one-column mode and single-column floats in two-column mode. They are all rubber lengths.

\floatsep is the space between adjacent floats that are placed at the top or bottom of the text page or column.

\textfloatsep is the space between the main text and floats at the top or bottom of the page or column.

\intextsep is the space between in-text floats and the text.

1455 \newskip\floatsep
1456 \newskip\textfloatsep
1457 \newskip\intextsep
1458 \setlength\floatsep    {12\p@ \@plus 2\p@ \@minus 2\p@}
1459 \setlength\textfloatsep{20\p@ \@plus 2\p@ \@minus 4\p@}
1460 \setlength\intextsep   {12\p@ \@plus 2\p@ \@minus 2\p@}

\dblfloatsep \dbltextfloatsep When double-column floats (floating objects that span the whole \textwidth) are placed at the top of a text page in two-column mode, the separation between the float and the text is controlled by \dblfloatsep and \dbltextfloatsep. They are rubber lengths.

\dblfloatsep is the space between adjacent double-column floats placed at the top of the text page.

\dbltextfloatsep is the space between the main text and double-column floats at the top of the page.

1461 \newskip\dblfloatsep
1462 \newskip\dbltextfloatsep
1463 \setlength\dblfloatsep    {12\p@ \@plus 2\p@ \@minus 2\p@}
1464 \setlength\dbltextfloatsep{20\p@ \@plus 2\p@ \@minus 4\p@}

Floats on their own page or column

\@fptop \@fpsep \@fpbot When floating objects are placed on a seperate page or column, called a ‘float page’, the layout of the page is controlled by these parameters, which are rubber lengths.

At the top of the page \@fptop is inserted; typically this supplies some stretchable whitespace. At the bottom of the page \@fpbot ais inserted. Between adjacent floats \@fpsep is inserted.

These paramaters are used for all floating objects on a ‘float page’ in onecolumn mode, and for single-column floats in two-column mode.

Note that at least one of the two parameters \@fptop and \@fpbot should contain a plus ...fil so as to fill the remaining empty space.

1465 \newskip\@fptop
1466 \newskip\@fpsep
1467 \newskip\@fpbot
1468 \setlength\@fptop{0\p@ \@plus 1fil}
1469 \setlength\@fpsep{8\p@ \@plus 2fil}
1470 \setlength\@fpbot{0\p@ \@plus 1fil}

\@dblfptop \@dblfpsep \@dblfpbot Double-column ‘float pages’ in two-column mode use similar parameters.

1471 \newskip\@dblfptop
1472 \newskip\@dblfpsep

1473 \newskip\@dblfpbot
1474 \setlength\@dblfptop{0\p@ \@plus 1fil}
1475 \setlength\@dblfpsep{8\p@ \@plus 2fil}
1476 \setlength\@dblfpbot{0\p@ \@plus 1fil}

\topfigrule \botfigrule \dblfigrule The macros can be used to put in rules between floats and text; whatever they insert should be vertical mode material which takes up zero space.

1477 \let\topfigrule=\relax
1478 \let\botfigrule=\relax
1479 \let\dblfigrule=\relax

1480 ⟨/2ekernel | autoload⟩