\part Islands\\and the\\Output Routine\label{ISLANDS}\endpart




\chapter Packaging figures, tables, \dots, with captions\label{PI}\endchapter
\runningchapter{Packaging figures, tables, \dots\null}

The previous Parts have covered almost all the standard \lamstex\
constructions that involve *\label*'s (as well as  miscellaneous
constructions that don't).  But *\caption*'s, 
in a
\footnote{In version~*1* of \lamstex@, *\table* was used
to indicate a class of *\island*'s in the main file, and to
indicate a specific table construction in the ``tables'' file produced with
\lamstbl@; this implicit inconsistency became explicit in \muttontex@, where
the tables are specified within the main file.  Consequently, the *\table*
class of *\island*'s has
been renamed *\Table*. For consistency, *\figure* has likewise been renamed
*\Figure*, and then *\figureproofing* was renamed *\Figureproofing* (although
it does not act on *\Figure*'s  per se, but only on *\hbyw*'s).}
 *\Figure*, *\Table*, or the more
general *\island* construction, have been postponed to this Part, because
they interact so intimately with the *\output* routine.



\section{Preliminaries}
First we want to disable certain commands from *plain* \tex@, since they
would conflict with \lamstex's approach to these insertions:
\C**
\let\topinsert=\undefined
\let\midinsert=\undefined
\let\pageinsert=\undefined
**

Next, we deal with the rather simple matter of producing crop marks around
an *\hybw* or *\Hbyw*. We first need a flag for telling whether
*\Figureproofing* or *\noFigureproofing* is in force:
\C**
\newif\iffigproofing@
\def\Figureproofing{\figproofing@true}
\def\noFigureproofing{\figproofing@false}
**

The special *\Hbyw* construction is reduced to *\hbyw*, but also sets
a flag, to indicate that this *\hbyw* will need further processing later on:
\C**
\newif\ifHby@
\def\Hbyw#1{\global\Hby@true\hbyw\vsize{#1}}
**
The *\global* is needed because the later processing will occur after the
current group is completed.

An *\hbyw#1#2* is basically going to be
**
\vbox to#1{\hbox to#2{}\vfil}
**
(\tex\ allows *\hbox to#2{}* without an *\hfil* within the braces, but
the *\vfil* is necessary, since there is already something in the *\vbox*.)

We will actually use
\setbox0\hbox{\<left crop marks\>}
\setbox1\hbox{\<right crop marks\>}
**
\hbox{"box0
 \vbox to#1{\hbox to#2{}\vfil}
 "box1}
**
when crop marks are required, 
which we will produce by first adding the ones on the left side,
and then those on the right.


To produce the crops marks,
  we first store a horizontal rule 5~points wide (and default width *.4pt*)
in *\box0*, and declare its height to be *0pt*, so that it won't
interfere with anything else:
**
\setbox0=\vbox{\hrule \width5pt}\ht0=0pt
**
Now
**
\vbox to#1{\hrule \height5pt \width.4pt\vfil
  \hrule \height5pt \width.4pt}
**
gives the vertical parts of the left crops,
$$\vbox to.5in{\hrule \height5pt \width.4pt\vfil
  \hrule \height5pt \width.4pt}
$$
with the baseline at the bottom of this box.
To add in the horizontal parts, 
$$
\setbox0\vbox{\hrule \width5pt}\ht0=0pt
\vbox to.5in{\hrule \height5pt \width.4pt\vfil\hrule \height5pt \width.4pt}
 \kern-.4pt\rlap{\copy0}\raise.5in\hbox{\rlap{\copy0}}
$$
we move back the *.4pt* width of these
marks, and then *\rlap* a copy of *\box0*, containing the horizontal rule,
to give the bottom horizontal rule,
and also *\rlap* a copy that has been raised by the height *#1*, to
give the top one.
**
\vbox to#1{\hrule \height5pt \width.4pt\vfil\hrule 
             \height5pt \width.4pt}
\kern-.4pt\rlap{\copy0}\raise#1\hbox{\rlap{\copy0}}
**
A similar construction produces the crop marks on the right, using
*\llap* instead of *\rlap*:
**
\vbox to#1{\hrule \height5pt \width.4pt\vfil\hrule 
             \height5pt \width.4pt}
\kern-.4pt\llap{\copy0}\raise#1\hbox{\llap{\box0}}
**

Of course, we only want to add these crop marks when *\iffigproofing@*
is true. But we also don't want to add the crop marks if *\ifHby@* happens
to be true---in that case, the final height is to be determined later,
based on the height of the caption, and we will deal with the crop mark
problem later.\pagelabel{HBY}
\C**
\def\hbyw#1#2{%
 \hbox{%
  \ifHby@
  \else
"2
   \iffigproofing@
    \setbox0=\vbox{\hrule \width5pt}\ht0=0pt
    \vbox to#1{\hrule \height5pt \width.4pt\vfil\hrule 
      \height5pt \width.4pt}%
    \kern-.4pt\rlap{\copy0}\raise#1\hbox{\rlap{\copy0}}%
   \fi
  \fi
"2
  \vbox to#1{\hbox to#2{}\vfil}%
"2
  \ifHby@
"2
  \else
   \iffigproofing@
    \vbox to#1{\hrule \height5pt \width.4pt\vfil\hrule 
      \height5pt \width.4pt}%
    \kern-.4pt\llap{\copy0}\raise#1\hbox{\llap{\box0}}%
   \fi
  \fi}}
**


\section{Starting an \CS{island}}Next comes the general mechanism
whereby 
\setbox0\hbox{\<space or other material\>}
**
\island "box0 \caption{...} \endisland
**
packages the \<space or other material\> together with the caption into a
box. 

At first sight, *\island*'s and *\claim*'s seem to be quite similar,
 since they can
be
associated into different ``classes'', and since there is a *\newisland*
construction much like *\newclaim*.  But they 
 function somewhat differently,
since *\island*'s are not themselves numbered---% 
 it is the *\caption*'s on the *\island*'s that must be numbered
(and one uses *\caption""...""* to get a quoted number, 
etc.);  consequently, the *\claim* definitions cannot be mimicked
too directly.

\medskip
We begin by declaring the counter and control sequences associated to 	
general *\island*'s:
\C**
\newcount\island@C
\let\island@P=\empty
\let\island@Q=\empty
\def\island@S#1{#1\null.}
\let\island@N=\arabic
\def\island@F{\rm}
**
We add the *\null* in case *#1* ends with an upper-case
letter
 (compare page~\ref{ANULL}). 

Just as *\claim*'s have a *\claimclass@*, our *\island*'s will have  an
*\islandclass@*, which will be `*...*' when we use 
**
\island \c{...}
**
(or when we use something created by *\newisland* with this *\c{...}*), and
empty if we omit the *\c{...}*. 

Similarly, a construction  created with *\newisland*, say *\map*,
will define\linebreak
*\islandtype@* to be *\map*, analogous to *\claimtype@*, while an ordinary
 *\island* will
define *\islandtype@* to be *\island*.

Analogous to *\claim@@@P*, etc., we define
\C**
\def\island@@@P{\csname\exxx@\islandtype@ @P\endcsname}
"2
\def\island@@@Q{\csname\exxx@\islandtype@ @Q\endcsname}
"2
\def\island@@@S{\csname\exxx@\islandtype@ @S\endcsname}
"2
\def\island@@@N{\csname\exxx@\islandtype@ @N\endcsname}
"2
\def\island@@@F{\csname\exxx@\islandtype@ @F\endcsname}
**
while for *\island@@@C* we 
\C**
\def\island@@@C{\csname island@C\islandclass@\endcsname}
**

We want to give an error message if an *\island* is not used within some sort
of *\...place*, so we declare a flag
\C**
\newif\ifplace@
**
which such constructions can set true, and which each *\island* will
eventually set false. 
Moreover, we want a flag
\C**
\newif\ifisland@
**
which each *\island* will set true, so that constructions like *\Aplace{...}*
can give an error message if `*...*' is not some sort of *\island*.


If *\island* is used when *\ifplace@* is false, we will give an error
message. Otherwise, we will initialize *\islandclass@* to be empty and
*\islandtype@* to be *\island*, and then use a *\futurelet* to see if
a *\c* comes next:
\C**
\def\island{%
 \ifplace@
  \def\next@{\let\islandclass@=\empty
   \def\islandtype@{\island}%
   \futurelet\next\island@}%
 \else
  \long\def\next@##1\endisland{\Err@{\noexpand\island must
    be used after some type of \string\...place}}%
 \fi
 \next@}
**
Notice that when we give the error message, we also swallow the
whole *\island"allowbreak...."allowbreak\endisland* construction,
to eliminate confusion. The *\long* is required because the *\caption* before
the *\endisland* is allowed to contain a blank line. For the *\noexpand*, 
see section~\Sref{SACN}.


If *\island* is followed by *\c* we will use *\island@c*. Otherwise
we will need yet another *\futurelet*, to see if the next token is a *{*,
since we want to give an error message if a suitable group
*{...}* for the ``caption prefix''
doesn't come next:
\C**
\def\island@{\ifx\next\c\let\next@=\island@c\else
 \def\next@{\futurelet\next\island@@}\fi\next@}
**

Here *\island@@* will call *\island@@@* if a  group
*{...}* does follow, but give an
error message otherwise:
\C**
\def\island@@{%
 \ifcat\bgroup\noexpand\next
  \let\next@=\island@@@
 \else
  \def\next@{\Err@{\noexpand\island must be followed by 
   a {prefix} for \string\caption's}}%
 \fi
 \next@}
**
(See section~\Sref{SACN} for the use of *\noexpand* in the error message.)

Finally, if we've made it this far without an error message,
i.e., if we've been scanning
**
\island {...}
**
then we will save `*...*'
 in *\captionprefix@*,  and start to store everything in a
box:
**
\global\setbox\islandbox@=\vbox\bgroup
**
Although the *\global* really isn't necessary here, some of our routines
will require *\global*, so we will use it in all cases.



We therefore first want to declare a new box *\islandbox@*.  Moreover, we
also want a new counter *\captioncount@*, which is quite different from 
*\island@C*: it records the number of *\caption*'s that occur within the
current *\island* (remember that an *\island* can have more than one
*\caption*):
\C**
\newbox\islandbox@
\newcount\captioncount@
"slip
\def\island@@@#1{\def\captionprefix@{#1}%
 \captioncount@=0
 \global\setbox\islandbox@=\vbox\bgroup}
**
The *\egroup* matching this *\bgroup* might be supplied by the
*\endisland*; in most cases, however, it will be supplied by a
*\caption*, which will then go on to store the *\caption*
 argument, and then combine
this properly with *\box\islandbox@*.


\medskip
Leaving these details aside for the moment,
let us now consider *\island@c*, which we obtain when we have
**
\island \c{...}
**
As we might expect from our experience with *\newclaim*, a construction
created by *\newisland* is going to lead us directly to *\island\c{...}*.
Since such constructions must also be used only within a suitable *\...place*
construction,
 this means that we  {\it must repeat our *\ifplace@* test}.

When *\ifplace@* is false, we again want to give an error message, but 
instead of the general message
**
\island must be used after some type of \...place
**
we want a more specific message mentioning our particular construction,
say *\map*, 
which has been recorded in *\islandtype@*. Moreover, as before, we want to
swallow the entire
**
\map ... \endmap
**
text. This requires much the same tomfoolery that we have engaged in before
(compare page~\ref{TOMF}).
If we
{\advance\litindent-40pt
**
\edef\next@{\long\def\noexpand\next@####1\expandafter
 \noexpand\csname end\exxx@\islandtype@\endcsname{\noexpand\Err@
   {\noexpand\noexpand\expandafter\noexpand\islandtype@ must be
    used after some type of \noexpand\string\noexpand\...place}}}
**
then} this *\edef* makes *\next@* mean
**
\long\def\next@##1\endmap{\Err@{\noexpand\map must be
  used in some type of \string\...place}}
**
Consequently, *\next@* executes this definition.  So calling *\next@*
 yet once again produces the error message,  swallowing the
*\map...\endmap* text in the process.

If 
*\island\c{...}*
is used when *\ifplace@* is true, we will define *\islandclass@* to be
`*...*'.
Then, similarly to *\claim*, we want 
to use 
**
\csname island@C...\endcsname
**
as the counter. So we will create this counter,
 using *\newcount@* (see section~\Sref{NEWNEW} and
page~\ref{NWNW}), and set it to~*0* if it does not already exist.
 Before proceeding further however, we now need yet another
*\futurelet* to check that this 
**
\island \c{...}
**
is followed by yet another group *{...}* to specify a  caption prefix;
in fact, we will need *\FNSS@*, to skip over any space after the *\c{...}*:
\C**
\def\island@c\c#1{%
 \ifplace@
 \def\next@{\def\islandclass@{#1}%
"2
  \expandafter\ifx\csname island@C#1\endcsname\relax
"2
  \expandafter\newcount@\csname island@C#1\endcsname
   \global\csname island@C#1\endcsname=0 \fi
  \FNSS@\island@c@}%
"2
 \else
 \def\next@{%
  \edef\next@{\def\noexpand\next@########1\expandafter
   \noexpand\csname end\expandafter\exxx@
    \islandtype@\endcsname
"2
    {\noexpand\Err@{\noexpand\noexpand\expandafter\noexpand
     \islandtype@ must be used in some type of 
     \noexpand\string\noexpand\...place}}}%
  \next@\next@}%
 \fi
 \next@}
**

Then *\island@c@* works analogously to the way *\island@@* worked before:
\C**
\def\island@c@{%
 \ifcat\bgroup\noexpand\next
  \let\next@=\island@c@@
 \else
  \def\next@{\Err@{\noexpand\island\string\c
    {\expandafter\string\islandclass@} must
    be followed by a {prefix} for \string\caption's}}%
 \fi
\next@}
"slip
\def\island@c@@#1{\def\captionprefix@{#1}%
 \captioncount@=0
 \global\setbox\islandbox@=\vbox\bgroup}
**

\section{Starting a \CS{caption}} 
As we are setting *\box\islandbox@* we will probably encounter a *\caption*,
which we have to consider next, before worrying about the *\endisland*.

First of all, we
\C**
\rightadd@\caption\to\nofrillslist@
**
since the default style adds a period at the end of the *\caption*
automatically, and we want to allow *\nopunct* to override this.

\small  This is a change from version~*1*:
Even though captions are often whole sentences, where it might seem normal
for the user to add the punctuation, it is preferable to require that
 this punctuation 
not appear in the input file, because it could create problems
in the *.tic* file, where the caption
might be followed by something like dot leaders.
\endsmall


Then we will need a box,
\C**
\newbox\captionbox@
**
 to store  *\caption*'s, and since we allow more than one *\caption* in an
*\island*, we will need another box,
\C**
\newbox\Captionbox@
**
to store the accumulated *\caption*'s.


A *\caption* will first be encountered within an *\island*, where we have
already begun
**
\global\setbox\islandbox@=\vbox\bgroup
**
and it will normally first supply the matching *\egroup* that will finish
 *\box\islandbox@*, before scanning its argument.  But we don't want
to add an *\egroup* if our *\caption* is simply a subsequent *\caption*
within the same *\island*. So we want something like
**
\def\caption{%
 \ifnum\captioncount@=0 
  \let\next@=\egroup
 \else
  \let\next@=\relax
 \fi
 \next@
 \advance\captioncount@ by 1
 . . .
**
But there is
 an extra detail to worry about: 
 If the *\caption* was
 preceded by *\nopunct*, then we have *\nopunct@true* after the
*\caption*, but this will then be hidden by the *\egroup*.	
  So we actually use
\C**
\def\caption{%
 \ifnum\captioncount@=0
"2
  \ifnopunct@
   \def\next@{\egroup\nopunct@true}%
"2
  \else
   \let\next@=\egroup
  \fi
"2
 \else
  \let\next@=\relax
 \fi
"2
 \next@
 \advance\captioncount@ by 1
 \futurelet\next\caption@}
**
Note that the *\captioncount@* is always set or advanced outside of the
various boxes that we build, so we don't need to use *\global* with it.
Note also that we didn't worry about *\nospace*. That's because this control
sequence, although allowed before *\caption*, won't have any effect
(in the default style, where
 nothing follows the final punctuation of a caption; if for some reason
a style did have a space after this punctuation,
 a slightly more complicated routine would be needed).


The *\futurelet* at the end of the definition
is needed to see whether *\caption* is followed by
a quoted number *""...""*, and
*\caption@* simply calls *\caption@q* when a quoted number follows, and
*\caption@@* in general:
\C**
\def\caption@{\ifx\next""\expandafter\caption@q\else
  \expandafter\caption@@\fi}
**

Here *\caption@q*  and *\caption@@* each first define
*\Thelabel@*, \dots, *\Thelabel@@@@*, and then call
**
\finishcaption@
**
where *\finishcaption@* will be defined in the next section.
All this is quite analogous to the situation for *\claim*. Since
*\caption*'s will be written to the *.tic* file, we also need some of
the subsidiary information that was 
added for *\HL* and *\hl*:  *\caption@q* will set 
 *\ifquoted@* to be true and define *\Qlabel@@@@*, while
 *\caption@@* will set it to be false,
 so that we can use the
*\QorThelabel@@@@* construction that was used for *\HL* and *\hl*:
\C**
\def\caption@q""#1""{\quoted@true
 {\noexpands@
"2
 \let\pre=\island@@@P \let\post=\island@@@Q
 \let\style=\island@@@S \let\numstyle=\island@@@N
"2
 \Qlabel@{#1}\let\style=\relax\xdef\Qpref@{#1}}%
 \finishcaption@}
"slip
\def\caption@@{\quoted@false
 \global\advance\island@@@C by 1
"2
 {\noexpands@
  \xdef\Thelabel@@@{\number\island@@@C}%
  \xdefThelabel@\island@@@N
"2  
  \xdef\Thelabel@@@@{\island@@@P\Thelabel@\island@@@Q}%
  \xdefThelabel@@\island@@@S
  \xdef\Thepref@{\Thelabel@@@@}}%
"2
 \finishcaption@}
**

\section{Formatting a \CS{caption}\label{FMTC}}
Analogous to *\claimformat@*, we want to have
 *\captionformat@*, to describe, in the very
simplest terms, how a caption should be formatted
**
\long\def\captionformat@#1#2#3{%
 #1 {\island@@@F#2} #3\punct@.}
**
Here *#1* will be the ``caption prefix'', *#2* will be the properly 
formatted caption number, and *#3* will be the argument of *\caption*.
We use *\long* because we allow *#3* to contain a blank line (the default
style doesn't treat new paragraphs in a *\caption* in any particularly
interesting way, but other styles might.) The `*\punct@.*' allows
a *\nopunct* before the *\caption* to eliminate the period (for a caption
that ends with a~! for example); a *\null* is not added here (compare
pages~\ref{QW3} and~ \ref{QW4}) since nothing follows the period.
A *\nospace* before a *\caption* will
have no effect, in the default style, but is allowed.


Unfortunately, the actual
formatting of a caption may be quite a complex affair.
In the default style,
 for example, if the caption can be set on a single line whose
 width is less than the width of *\box\islandbox@*,
 we center that line under
*\box\islandbox@*;
 otherwise, we set the caption as a paragraph whose width is the
same as that of *\box\islandbox@*.  In addition, when a single *\island* has
multiple *\caption*'s, we have the usual problem of stacking these paragraphs
on top of each other, so we will want to insert struts.

 Many, many, other arrangements might be
used; captions might be printed on the side of the figure, etc.
It is impossible to anticipate all the things that different style files
might do, but necessary modifications for other styles should be clear from a
careful study of the proceedings used throughout this chapter.

We begin by adding struts to the definition of *\captionformat@*:
\C**
\long\def\captionformat@#1#2#3{\rm\strut
 #1 {\island@@@F#2} #3\punct@.\strut}
**
In other styles, *\rm* might be
replaced by something like *\tenpoint*, so that the caption will be
in 10~point type no matter what the current font may be; the *\strut* should
follow, so that it will be the right size.  Of course, some styles might even
need different *\captionformat@*'s, for different sorts of *\island*'s.


Then we want to have
**
\widerthanisland@#1#2#3
**
to test whether *\captionformat@#1#2#3* produces an *\hbox* that is wider
than  *\box\islandbox@*, setting *\iftest@* to be true if it is wider, and
setting it to be
false otherwise. Basically, we want to
**
\setbox0=\hbox{\captionformat@{#1}{#2}{#3}}
**
and measure the width of  *\box0*.

 This fails, however, if
 the caption contains a displayed formula, like
**
$$\alpha=...$$
**
Indeed, in restricted horizontal mode *$$* simply stands for an
empty formula ({\it The \tex book}, page~287),
 so the *\alpha* is outside of math mode, and will give a
(mysterious) error message.  (It also fails if the caption contains
a *\linebreak*, although presumably this will only be put to avoid an
*Overfull \hbox* when the caption is longer than the island.)



So instead (compare page~\ref{BASICA})
we first
**
\setbox0=\vbox{\hsize=\maxdimen 
 \noindent@@\captionformat@{#1}{#2}{#3}%
 \par
 \setbox0=\lastbox}
**
where the inner *\setbox0=\lastbox* simply removes 
\footnote{Recall that *\lastbox*  removes the last box (something like
*\global\setbox1=\lastbox*  keeps the last box in *\box1* if we 
need it)\pagelabel{KLB}.}
 the last box in (the
main)~
*\box0*. (See Chapter~\ref{EVPAR} for the *\noindent@@*.)
If our caption argument *#3* consists of simple text, everything will have
been set on one line, which will be *\lastbox*, so
our final *\box0* will
 be empty, and
  therefore have width~*0pt* (compare the footnote on page~\ref{MAXD}).
In this case, we will simply set the same material in *\box\captionbox@*,
and set *\iftest@* to be true if the width of this box is greater than the
width of *\box\islandbox@* and false otherwise.

But if *#3* contains a displayed formula, or more than one paragraph of
text, or anything else that creates more than one line of text
(including perhaps,
so much text that it won't even fit on a line of length *\maxdimen*),
then there is still a line left after we eliminate *\lastbox*, so the
final
*\box0* does not have width~*0pt*. In this case,
we also want  *\iftest@*   to be
true, since we again want to reformat *#3* within a *\vbox* having the width
of *\box\islandbox@*.



After we have set a box for testing purposes, we must be careful to 
*\unlabel@* (section~\Sref{relax2}), to 
ignore any *\label*'s for future setting of~*#3*, 
for otherwise we will be using a \<label\> more than once
when we do the final setting.
We will also 
use *\noset* (section~\Sref{relax}), just in case *\Reset* or *\Offset*
appear.


We define our test by:
\C**
\long\def\widerthanisland@#1#2#3{%
 \test@true
 \setbox0=\vbox{\hsize=\maxdimen 
"2
  \noindent@@\captionformat@{#1}{#2}{#3}%
  \par\setbox0=\lastbox}%
"2
 \ifdim\wd0=0pt
  \setbox\captionbox@=\hbox{\noset@\unlabel@
   \captionformat@{#1}{#2}{#3}}%
  \ifdim\wd\captionbox@ > \wd\islandbox@\else\test@false\fi
 \fi}
**

Now we can define *\captionformat@@*, which does the actual formatting by:
\C**
\long\def\captionformat@@#1#2#3{%
 \widerthanisland@{#1}{#2}{#3}%
"2
 \iftest@
   \global\setbox\captionbox@=\vbox{\hsize=\wd\islandbox@
    \vskip-\parskip
    \noindent@@\noset@\unlabel@
     \captionformat@{#1}{#2}{#3}\par}%
"2
 \else
  \global\setbox\captionbox@=
   \hbox to\wd\islandbox@{\hfil\box\captionbox@\hfil}%
 \fi}
**
The *\vskip-\parskip* is used to eliminate any extra *\parskip* glue
before our *\noindent@@*'ed paragraph.


Finally, *\finishcaption@#1*, where *#1* will be the argument of 
*\caption*, 
first stores *#1* in *\entry@*,
**
\def\entry@{#1}
**
for writing to the *.tic* file later (section~\Sref{TICWRITE}),
and then
{\litindent=0pt takes care of  details like ignoring
initial and final spaces,
**
{\locallabel@
\captionformat@@{\expandafter\ignorespaces\captionprefix@\unskip}%
 {\ifx\thelabel@@\empty\unskip\else\thelabel@@\fi}%
 {\ignorespaces#1\unskip}}
**

If} there is only one *\caption* so far, our final
*\box\Captionbox@* will just be a *\vbox* containing *\box\captionbox@*:
**
\global\setbox\Captionbox@=\vbox{\box\captionbox@}%
**
(We do this so that *\box\Captionbox@* is always a *\vbox*; that way, we can
always *\unvbox\Captionbox@* when necessary.)


Otherwise, we want to create a new *\box\Captionbox@* by combining the old
*\box\Captionbox@* with *\box\captionbox@*
with
a *\smallskip* between them:
{\litindent=0pt 
**
\global\setbox\Captionbox@=\vbox{\unvbox\Captionbox@
 \smallskip\box\captionbox@}%
**
In addition to the *\smallskip*, *\strut*'s will give the proper line
spacing.} Note that the
*\unvbox*'ed *\Captionbox@* and *\box\captionbox@* will not have
any additional space added between them.
\footnote{{\it The \tex book}, page~282: ``The vertical list inside that
box is appended to the current vertical list, without changing it in
any way.'' {\it The \tex book\/} goes on to say that ``The value of
*\prevdepth* is not affected.''  That is, the value of *\prevdepth* after the
*\unvbox* is the value it had before the *\unvbox*, {\it not\/} the
depth of the last box produced by the *\unvbox*. This will be
important later \pagelabel{NEXG} (page~\ref{USEFN}).}



At this point we also want to add appropriate *\write\tic@*'s for writing
to the *.tic* file
(page~\ref{TICFILE}). Although it would seem reasonable to include these
*\write*'s
within *\box\Captionbox@*, 
\footnote{Note that, unlike *\insert*'s, which have an effect only if they
``migrate'' out to the main vertical list, *\write*'s will take place when
enclosed in boxes, no matter to what depth.}
  we will instead attach them to
*\box\islandbox@*, which will always appear on the same page as
the corresponding captions.  (At some preliminary stage of the macros,
 *\box\Captionbox@* was subjected to
further processing, which would have been complicated by the presence of
*\write*'s. That is no longer the case, so that the *\write*'s could be
included in *\box\Captionbox@*, but there's nothing wrong with the other
approach, and I didn't want to rewrite this part of the routines, with the
attendant risk of introducing some new bugs.)



We will define *\ticwrite@*, the appropriate collection of *\write\tic@*'s,
in section~\Sref{TICWRITE},
{\litindent=0pt and we will use
**
\ifnum\captioncount@=1
 \global\setbox\islandbox@=\vbox{\ticwrite@\vbox{\box\islandbox@}}%
 \global\setbox\Captionbox@=\vbox{\box\captionbox@}
\else
 \global\setbox\islandbox@=\vbox{\unvbox\islandbox@
  \setbox0=\lastbox
  \ticwrite@\box0 }
 \global\setbox\Captionbox@=\vbox{\unvbox\Captionbox@
  \smallskip\box\captionbox@}
\fi
**
Note} that when *\captioncount@* is~*1*, our new *\box\islandbox@* is
a *\vbox* containing *\ticwrite@* at top, and then the old
*\box\islandbox@* enclosed in another layer of *\vbox*'ing.  The reason
for this is that *\box\islandbox@* might contain more than one thing (in
particular, it might contain the *\write* for a *\pagelabel*), and we don't
want to uncover any of these layers when we *\unvbox\islandbox@* in the
next case, where *\captioncount@* is~*>1*.  In that latter case, the
**
\unvbox\islandbox@
\setbox0=\lastbox@
**
temporarily removes the old *\box\islandbox@* from the list, inserts
the *\ticwrite@* 
(after any *\write*'s that were inserted from previous
steps),\pagelabel{RECALL} 
and then puts back the old *\box\islandbox@*. This procedure keeps the
*\write*'s for multiple *\caption*'s in the correct order, and also keeps them
at the
top of the *\vbox*, so that if necessary we can always 
use *\lastbox* to examine the non-*\write* part.


  And after all that, we simply reset *\ifnopunct@* and *\ifnospace@*
to be false (we need to do this for *\ifnospace@*, even though *\nospace* has
no effect on a *\caption*,
 because *\nospace*
before a *\caption* will not give an error message, and will not
reset *\ifnospace@* to be false):
\C**
\long\def\finishcaption@#1{\def\entry@{#1}%
 {\locallabel@
 \captionformat@@
  {\expandafter\ignorespaces\captionprefix@\unskip}%
  {\ifx\thelabel@@\empty\unskip\else\thelabel@@\fi}%
  {\ignorespaces#1\unskip}}%
"2
 \ifnum\captioncount@=1
  \global\setbox\islandbox@
   =\vbox{\ticwrite@\vbox{\box\islandbox@}}%
  \global\setbox\Captionbox@=\vbox{\box\captionbox@}%
"2
 \else
  \global\setbox\islandbox@
   =\vbox{\unvbox\islandbox@
     \setbox0=\lastbox
     \ticwrite@\box0}%
"2
  \global\setbox\Captionbox@
"2
   =\vbox{\unvbox\Captionbox@
"2
    \smallskip
"2
    \box\captionbox@}%
 \fi
 \nopunct@false\nospace@false}
**

\section{\CS{ticwrite\@}\label{TICWRITE}}
Analogous to *\Sixtoc@*
(section~\Sref{WLTL}), we define the routine *\Sixtic@* by
\C**
\def\Sixtic@{\ifx\macdef@\empty\else
 \def\next@##1##2\next@{\def\macdef@{##1##2}}%
 \expandafter\next@\macdef@\next
 \edef\next@
  {\noexpand\six@\tic@\macdef@
  \space\space\space\space\space\space
  \space\space\space\space\space\space\noexpand\six@}%
 \next@\let\macdef@=\relax\fi}
**

When *\tocfile* has been specified, 
and the input file has something like
\setbox0\hbox{\<class\>}
\setbox2\hbox{\<caption prefix\>}
\setbox3\hbox{\<the caption\>}
**
\island \c{"copy0}{"copy2} . . . 
 \caption{"box3}
\endisland
**
we will want to write
\setbox3\hbox{\<the caption\>}
\setbox4\hbox{\<formatted caption number\>}
**
\island \c{"copy0}{"copy2}{"copy4}
 "box3
\Page ...
**
to the *.tic* file (with line breaks in \<the caption\>
after every sixth space).
	
If the file has  something like
\setbox3\hbox{\<the caption\>}
**
\Figure . . .  \caption{"copy3} \endFigure
**
using *\Figure* or *\Table*, or anything else created by *\newisland*,
then we want to write something like
**
\Figure {"copy4}
 "copy3
\Page ...
**
(Multiple *\caption*'s for a single *\island* will simply give rise
to multiple copies of such data, with the corresponding
 \<formatted caption number\>'s.)
We also want to have *\nopunct* appear before the *\island* or *\Figure*
or whatever, when it appears before the corresponding *\caption*.
Finally,
as with *\HL* and *\hl*, quoted numbers should appear with quotes also
(and *\style* should be allowed to appear within the
quotes).\pagelabel{SUB111} 


For the first line, we use the following code, resorting to the
standard\linebreak 
 *\expandafter\noexpand* trick (compare pages~\ref{EXNE} and~\ref{EXNE2}):
**
\def\next@{\island}
\edef\next@{\write\tic@{\ifnopunct@
 \noexpand\noexpand\noexpand\nopunct\fi
 \ifx\islandtype@\next@\noexpand\noexpand\noexpand\island
  \noexpand\string\noexpand\c{\islandclass@}
   {\captionprefix@}{\QorThelabel@@@@}}}
 \else 
  \noexpand\noexpand\expandafter\noexpand
  \islandtype@{\QorThelabel@@@@}}\fi}
 \next@
**
We use *\string\c* rather than *\noexpand\c*, because a space after *\c*
usually looks extraneous in the *.tic* file.
As with *\HLtoc@* and *\hltoc@*, this should all be done within a group
with *\noexpands@* and *\let\style=\relax*.


Next we use
**
\expandafter\unmacro@\meaning\entry@\unmacro@
\Sixtic@
**
to produce *\write*'s for the *\caption*, and finally we add the *\write* for
the page number:
\C**
\def\ticwrite@{%
 \iftoc@
  {\noexpands@\let\style=\relax
"2
  \def\next@{\island}%
  \edef\next@{\write\tic@{%
   \ifnopunct@\noexpand\noexpand\noexpand\nopunct\fi
"2
   \ifx\islandtype@\next@
    \noexpand\noexpand\noexpand\island
    \noexpand\string\noexpand\c{\islandclass@}%
    {\captionprefix@}{\QorThelabel@@@@}%
"2
   \else 
    \noexpand\noexpand\expandafter\noexpand
     \islandtype@{\QorThelabel@@@@}}\fi}%
  \next@}%
"2
  \expandafter\unmacro@\meaning\entry@\unmacro@
  \Sixtic@
  \write\tic@{\noexpand\Page{\number\pageno}{\page@N}%
   {\page@P}{\page@Q}^^J}%
 \fi}
**

For a style where *\captionformat@* involved *\addspace@*, so that\linebreak
*\nospace* before a *\caption* would have an effect, we would probably
want to add 
**
\ifnospace@\noexpand\noexpand\noexpand\nospace\fi
**
in the *\edef*.



\section{\CS{Htrim\@}}
A special procedure is needed to deal with an *\Hbyw*. This has been
temporarily set to a box
 of height *\vsize*, so that *\box\islandbox@* will also have this height.
The procedure
**
\Htrim@#1
**
is used 
with *#1* being the amount of space that we want to leave between 
the tall box and the caption, and is used only when *\ifHby@* is true:
**
\def\Htrim@#1{%
 \ifHby@
   . . . 
 \fi}
**
It is supposed to change *\box\islandbox@* to a box of
height
\Math
\hbox{*\vsize*}-\hbox{*#1*}-\hbox{height of the caption box},
\endMath
 so that this new box, together with
the caption box and *#1* space between them, will take up the
entire page.  In addition, if *\ifFigureproofing* is true, then we need to
put crop marks around this new *\box\islandbox@*.



So we start out by setting
**
\dimen@=\vsize
**
If there was a caption
we
**
\advance\dimen@ by -\ht\Captionbox@
\advance\dimen@ by -#1
**
Now we basically want to
**
\setbox\islandbox@=\vbox
 {\hbyw\dimen@{\wd\islandbox@}}
**
In order to allow crop marks around this box, however, we need to have
*\ifHby@* be false (page~\ref{HBY}).  But
 we'll need to know the value of *\ifHby@*
later on (page~\ref{IFHBY}~ff\.).
So we will set *\global\Hby@false* before we do this, and restore
*\global\Hby@true* afterwards (remember that this whole routine is
being done only when *\ifHby@* is true; we use *\global* assignments here
since they were necessary previously).

Before we actually
**
\global\setbox\islandbox@=\vbox   "8GLIS"8
 {\hbyw\dimen@{\wd\islandbox@}}}
**
 we must first extract any *\ticwrite*'s  that may have appeared in the
old\linebreak
*\box\islandbox@*, and make sure that they appear in the new one.
To do this,  we can first store *\wd\islandbox@*,
**
\dimen@ii=\wd\islandbox@
**
and then
**
\global\setbox\islandbox@=\vbox
 {\unvbox\islandbox@
  \setbox0=\lastbox
  \hbyw\dimen@\dimen@ii}
**
Recall (page~\ref{RECALL})
that the 
**
\unvbox\islandbox@\setbox0=\lastbox
**
 leaves the *\write*'s
at the top of *\box\islandbox@*, while deleting the other part.
Unfortunately, that's not quite adequate, because we will then loose any
*\pagelabel* information that may have been in *\box\islandbox@*.  So instead
we use
**
\global\setbox\islandbox@=\vbox
 {\unvbox\islandbox@
  \setbox0=\lastbox
  \vbox to0pt{\vss\box0}\nointerlineskip
  \hbyw\dimen@\dimen@ii}
**
Although no extra space is inserted before the *\vbox to0pt* (see the
footnote on page~\ref{NEXG}), we need *\nointerlineskip* to prevent extra
space between that box and the next *\hbyw*.

The complete code is:
\C**
\def\Htrim@#1{%
 \ifHby@
"2
  \dimen@=\vsize
  \ifnum\captioncount@=0
"2
  \else
   \advance\dimen@ by -\ht\Captionbox@
   \advance\dimen@ by -#1%
  \fi
"2
  \global\Hby@false
  \dimen@ii=\wd\islandbox@
"2
  \global\setbox\islandbox@=\vbox
   {\unvbox\islandbox@ \setbox0=\lastbox
   \vbox to0pt{\vss\box0}\nointerlineskip
   \hbyw\dimen@\dimen@ii}%
  \global\Hby@true
 \fi}
**



\section{Other accoutrements for \CS{endisland}}
The *\islandpairdata* and\linebreak
 *\islandtripledata* constructions
(section~\Sref{MNPI})
 essentially operate by temporarily creating *\islands* and  storing
*\box\islandbox@* in other places.  During such processes we want to abort
most of the additional operations of *\endisland*, so we need a flag
\C**
\newif\ifdata@
**
to tell us when we are performing such temporary maneuvers.


We also need a way of testing for the class of an *\island*, since this will
determine how the caption is attached to the *\island*; in the default
style, for example, an *\island* with class~ *T* (i.e., a *\Table*), has the
caption above, instead of below. The definition of *\iclasstest@* is
analogous to *\classtest@* for *\claim* (section~\Sref{MODC}):
\C**
\def\iclasstest@#1{\def\next@{#1}\ifx\next@\islandclass@
 \test@true\else\test@false\fi}
**
We don't bother with a corresponding *\itypetest@*, because the class of an
*\island* should be sufficient information: Unlike the situation for
*\claim*, where, for example, *\claim\c{T}{Theorem}* and *\claim\c{T}{Lemma}*
might be used so that Theorem's and Lemma's are numbered together, it's 
unlikely that any one would want Tables and Figures, or Maps and Plates to
share a common numbering.  Of course, a style file that did want to allow
such things could introduce a suitable *\itypetest@*.


\section{\CS{endisland}}
Finally, we are ready for *\endisland*. If there was no *\caption*, then it
must provide the *\egroup* that matches the *\bgroup* in *\island*,
**
\ifnum\captioncount@=0 \expandafter\egroup\fi
** 

Next come the instructions for putting the island and caption together,
which will {\it not\/} be done when we are simply collecting
data for constructions like *\islandpairdata*, etc.,
**
\ifdata@
\else
  . . . 
  . . .
\fi
**

  In the case of a table,
the default style leaves a *\bigskip*  between the caption and
the island, so we want to start with something like
**
\iclasstest@{T}
\iftest@
 \Htrim@\bigskipamount
**
Remember that *\Htrim@* operates only when we have an *\Hbyw*. In this case,
it makes *\box\islandbox@* just high enough so that its height plus the
height of *\box\Captionbox@* plus *\bigskipamount* is *\vsize*.

Actually, instead of *\bigskip*, we really want less space,
because the last line of the
caption above the table will have a depth of *3.5pt* (the depth of a strut).
So we really want something like
**
\skip@ = -3.5pt \advance\skip@ by \bigskipamount
\Htrim@\skip@
**
That way, we know exactly how much space we are getting: enough to 
make the baseline of the first line of the caption *12pt* plus
*\bigskipamount* below the *\island*.


We will actually use something like
**
"hskip-30pt{\rm\global\skip1 = -\dp\strutbox}\global\advance\skip1 by 
"hskip-30pt   \bigskipamount
"hskip-30pt\Htrim@{\skip1}
**
to remind other style files to insert something like *\tenpoint* for the
*\rm*, so that *\skip1* will have the proper value. We need *\skip1* 
because of the *\global* assignment.  Since it turns out that *\skip1* will
be used quite frequently, we will 
**
\skipdef\skipi@=1
**
so that we can use *\skipi@* to abbreviate *\skip1*.


Then we want
**
\global\setbox\islandbox@=\vbox
 {\ifnum\captioncount@=0 
  \else
   \box\Captionbox@
   \nointerlineskip
   \vskip\skipi@
  \fi
  \box\islandbox@}
**
In addition to the *\vskip\skipi@* that we provide,
 there would normally also be *\lineskip* glue
between the caption and *\box\islandbox@*; we use *\nointerlineskip* to
suppress this, so that there is just one glue between the two boxes.
\pagelabel{ONEGLUE}


The new *\box\islandbox@* will
eventually be taken apart by the *\output* routine (knowing that there is
just one glue between the two boxes makes this easier),\pagelabel{APART}
 and the pieces will be
put back on the
page in the proper way. In the default style, *\box\Captionbox@* and
(the original) *\box\islandbox@* will each be centered;
 at that time, the
*\vskip\skipi@* glue between them
will be able to stretch or shrink with the other glue on the
page. 


{\litindent=15pt
In the default style, all *\island*'s other than  *\Table*'s have their
captions below, with a *\medskip*  between them. In this case we actually
want to {\it increase\/} the *\medskip* by ~*3.5pt*, since the first line of
the caption has a strut of height~*8.5pt*:
**
\else
{\rm\global\skipi@ = \dp\strutbox}
 \global\advance\skipi@ by \medskipamount
"2
 \Htrim@\skipi@
"2
 \global\setbox\islandbox@=\vbox
  {\box\islandbox@
   \ifnum\captioncount@=0
"2
   \else
    \nointerlineskip
    \vskip\skipi@
    \box\Captionbox@
   \fi}
\fi
**
}%

The only thing left to do is to give an error message in case the final
*\box\islandbox@* ends up larger than *\vsize*, and reset the height of
*\box\islandbox@*
to *\vsize*.
  The message should be something like
\setbox0\hbox{etc.,}
**
\island is larger than page
\Figure is larger than page
"box0
**
when there are no captions, and
\setbox0\hbox{etc.,}
**
\island with \caption is larger than page
\Figure with \caption is larger than page
"box0
**
otherwise.

After all this (occurring within an *\ifdata@\else...\fi* region),
 we can reset *\Hby@false* and set *\island@true*, to give proper information
to *\Aplace*, etc.
  The complete code is:
\C**
\skipdef\skipi@=1
"slip
\def\endisland{%       "8EIROUTINE"8
 \ifnum\captioncount@=0 \expandafter\egroup\fi
"2
 \ifdata@
 \else
"2
  \iclasstest@{T}%
  \iftest@
   {\rm \global\skipi@ = -\dp\strutbox}%
   \global\advance\skipi@\bigskipamount
"2
   \Htrim@\skip@
   \global\setbox\islandbox@=\vbox
    {\ifnum\captioncount@=0 
     \else
      \box\Captionbox@
      \nointerlineskip
      \vskip\skipi@
     \fi
     \box\islandbox@}%
"2
  \else
   {\rm \global\skipi@ = \dp\strutbox}%
   \global\advance\skipi@ by \medskipamount
   \Htrim@\skipi@
"2
   \global\setbox\islandbox@=\vbox
    {\box\islandbox@
     \ifnum\captioncount@=0 
     \else
      \nointerlineskip
      \vskip\skipi@
      \box\Captionbox@
     \fi}%
"2
  \fi
"2
  \ifHby@    "8IFHBY"8
"2
  \else
   \dimen@=\ht\islandbox@ \advance\dimen@ by \dp\islandbox@
"2
   \ifdim\dimen@ > \vsize
    \def\next@{\island}%
    \Err@{%
     \ifx\Islandtype@\next@\noexpand\island\else
      \expandafter\noexpand\islandtype@\fi
"2
     \ifnum\captioncount@=0 \else 
       with \noexpand\caption\fi
     is larger than page}%
    \ht\islandbox@=\vsize 
"2 
   \fi
  \fi
 \fi
"2
 \global\Hby@false \island@true}
**



\section{\CS{newisland}}The
*\newisland* construction  is similar to *\newclaim*, but,
 as with *\NameHL* and *\Namehl*, we write the
information to the *.tic* file (and, as with
 *\newclaim*, we first make sure that *#1* hasn't already been defined).
As before, we use *\newcount@* (section~\Sref{NEWNEW} and page~\ref{NWNW}):
\C**
\def\newisland#1\c#2#3{\define#1{}%
 \iftoc@\immediate\write\tic@{\noexpand\newisland
   \noexpand#1\string\c{#2}{#3}^^J}\fi
"2
 \expandafter\def\csname\exstring@#1@S\endcsname{\island@S}%
"2
 \expandafter\def\csname\exstring@#1@N\endcsname{\island@N}%
"2
 \expandafter\def\csname\exstring@#1@P\endcsname{\island@P}%
"2
 \expandafter\def\csname\exstring@#1@Q\endcsname{\island@Q}%
"2
 \expandafter\def\csname\exstring@#1@F\endcsname{\island@F}%
"2
 \expandafter\def\csname end\exstring@#1\endcsname
  {\endisland}%
"2
 \expandafter
 \ifx\csname island@C#2\endcsname\relax
  \expandafter\newcount@\csname island@C#2\endcsname
  \global\csname island@C#2\endcsname=0
 \fi
"2
 \edef\next@{\noexpand\expandafter\noexpand\let\noexpand
  \csname\exstring@#1@C\noexpand\endcsname=
  \csname island@C#2\endcsname}%
 \next@
 \def#1{\def\islandtype@{#1}\island@c\c{#2}{#3}}}
**

\lamstex\ defines *\Figure* and *\Table* directly in terms of *\newisland*:
\C**
\newisland\Figure\c{F}{Figure}
\newisland\Table\c{T}{Table}
**


\section{Manipulating \CS{island}'s\label{MNPI}}
The constructions
 *\islandpairdata* and\linebreak
 *\islandtripledata*,  the basic constructions behind
*\Figurepair*, etc.,
store the *\island*'s and *\caption*'s from their arguments in appropriate
boxes, which we first declare:
\C**
\newbox\islandboxi
\newbox\islandboxii
\newbox\islandboxiii
\newbox\captionboxi
\newbox\captionboxii
\newbox\captionboxiii
**
(These boxes, as well as *\islandpairdata*, etc., have no *@*'s in them, so
that they will be accessible to the user.)


*\islandpairdata{...}{...}* is meant to be used  when each
*...* is some sort of *\island*
like
**
\Figure _ _ _ \endFigure
**
 Basically, we just want to
execute the first
 **
\Figure _ _ _ \endFigure
**
 without any *\...place*, and store *\box\islandbox@*
in *\box\islandboxi* and *\box\Captionbox@* in
*\box\captionboxi*, and similarly for  the second
**
\Figure _ _ _ \endFigure
**

  Since *\island*'s normally 
work only when *\ifplace@* is true, we will simply temporarily declare this
within a group. 
We will also set
 *\ifdata@* to be true to disable most of the  *\endisland* 
 routine.
\C**
\long\def\islandpairdata#1#2{%
 {\place@true \data@true 
 #1%
 \global\setbox\islandboxi=\box\islandbox@
 \global\setbox\captionboxi=\box\Captionbox@
 #2%
 \global\setbox\islandboxii=\box\islandbox@
 \global\setbox\captionboxii=\box\Captionbox@
 }}
**

The definition of *\islandpairbox* has been changed from version~*1* (which
appears on
 page~73 of the \lamstex~Manual). 
First of all, 
we have to allow for
pairs of *\island*'s neither of which has a *\caption*. Moreover, 
the *\medskip* should be modified as in *\endisland*. The biggest change,
however, is that instead of simply creating a *\vbox*, we instead
*\setbox\islandbox@* to this *\vbox*:
\C**
\long\def\islandpairbox#1#2{%
 \islandpairdata{#1}{#2}%
"2
 \dimen@=\ht\captionboxi
 \ifdim\ht\captionboxii > \dimen@
  \dimen@=\ht\captionboxii\fi
"2
 "9\ifdim\dimen@ > 0pt"9
  \ifdim\ht\captionboxi < \dimen@
   \global\setbox\captionboxi 
    =\vbox to\dimen@{\unvbox\captionboxi\vfil}\fi
"2
  \ifdim\ht\captionboxii < \dimen@
   \global\setbox\captionboxii
    =\vbox to\dimen@{\unvbox\captionboxii\vfil}\fi
 "9\fi"9
"2
 "9\global\setbox\islandbox@="9\vbox{\hbox to\hsize
  {\hfil\box\islandboxi\hfil\box\islandboxii\hfil}%
"2
 "9\ifdim\dimen@ > 0pt"9
  \nointerlineskip
  "9{\rm \global\skipi@=\dp\strutbox}"9
  "9\global\advance\skipi@ by \medskipamount"9
  "9\vskip\skipi@"9   
  \hbox to\hsize
   {\hfil\box\captionboxi\hfil\box\captionboxii\hfil}
 "9\fi"9}%
 }
**

Then *\Figurepair* is defined by
\C**
\def\Figurepair#1\and#2\endFigurepair{\island@true
 \islandpairbox{\Figure#1\endFigure}{\Figure#2\endFigure}}
**
Thus, *\Figurepair* produces the same effect
as if we had made an *\island* where the \<appropriate space\> is the
combination of the \<appropriate space\>'s for the two islands, and where
the caption is the combination of the captions for the two islands. 

In version~*1* the definition was somewhat different: *\Figurepair* 
treated the entire combination as a single new island without a caption.
The advantage of the new approach is that when our *\box\islandbox@* is
taken apart by the *\output* routine (page~\ref{APART}),
there will be *\vskip\skipi@* glue between the combined \<appropriate
space\>'s and the combined captions, which will again be able to stretch or
shrink with the other glue on the page.  In particular, if a
 *\Figure* and a *\Figurepair* appear on the same page, the space
before the caption will have stretched or shrunk by the same amount for each.


The definitions of *\islandparboxa*, to put the captions above the combined
spaces, and *\Tablepair*, which uses this, won't be given, since they are 
quite analogous.  Similarly, *\islandtripledata*, etc., follow quite
similarly.




\chapter An overview\\
Placing the packaged figures, tables, \dots
\endchapter
\runningchapter{An overview of the placement routines}


We come now to what is perhaps the most interesting part of \lamstex's
general document processing features---its handling of inserted Figures
and other *\island*'s.

Chapter 8 of the \lamstex\ Manual describes the default style's
 fairly rigorous set of rules for figure
placement.
Of course, 
innumerable different rules
 might be specified by a style designer,
so we certainly 
cannot claim to have anticipated all problems.

 In fact, as the Manual concedes
(pages~68 and~70),
although the current solution
will
probably be quite adequate in practice, it isn't ideal.
The aim of \lamstex's automatic placement mechanism is not to provide
perfection, but
to get as much mileage
as possible out of \tex's own *\insert* mechanism. 
Although the details of
the \lamstex\ constructions take up the next few chapters, they
 are fairly simple in concept;
a \tex pert intending to change the *\output* routine should not rush in,
but at least this is not a region where 
 \tex~\hbox{angels} fear to tread (a thorough 
understanding of pages~122@--125 of {\it The \tex book\/} is in order,
however). 




\section{\CS{place}}
Before we get to the interesting part,  we will consider the ``low level''
construction *\place*, used in a construction like
**
\place{\island ... \endisland}
**
to simply insert *\box\islandbox@* at  the current point in the file.

The *\place* construction begins by declaring *\place@true*, so that
the *\island*
 construction won't give an error message, 
and
*\island@false*, so *\ifisland@* will be true only if the argument of
*\place@* actually involves an *\island* of some sort:
**
\def\place#1{\place@true \island@false
 #1 . . .
**

The argument *#1*, presumably
*\island"allowbreak..."allowbreak\endisland*, will simply 
 create *\box\islandbox@* and set *\island@true*. So if *\ifisland@* is still
false, we will give an error message:
**
\Err@{Whoa ... there's no \string\Figure, \string\Table, 
 etc., here}
**
Otherwise, we will just
use
**
\box\islandbox@
**
to typeset the box at that point.

Then we will
  reset *\ifplace@*  to be false:
\C**
\def\place#1{\place@true\island@false
 #1%
 \ifisland@
  \box\islandbox@
 \else
  \Err@{Whoa ... there's no \string\Figure, \string\Table, 
   etc., here}%
 \fi
 \place@false} 
**


\section{Automatic placement}
Having gotten that out of the way, we are ready, willing, and able
 to tackle the automatic
placement routines.

Here is the general principal. Whenever something is
 *\...place*'d 
 it will simply be added to a certain insertion class;
for this purpose we might as well pre\"empt *plain* \tex's *\topins*
insertion class, since we have already disallowed its use for its original
purposes.       


Remember that for every insertion class, like *\topins*, there is 

\bullist

\item An
associated box, *\box\topins*, which is where the material from that
insertion class appears when a page has been completed and
 the *\output* routine is called. 

At that time, the height of
*\box255* may well 
be different than *\vsize*, since the  *\output* routine
is going to combine *\box255*  with the material in
 *\box\topins* (and possibly other
material), to make the box that \tex\ will *\shipout*.

In *plain* \tex@, material from
the *\footins* and *\topins* insertion classes are handled rather simply:
the *\pagecontents* macro simply *\unvbox*'es each of these boxes, keeping
everything in *\box\topins* at the top of the page, and everything in
*\box\footins* at the bottom.  But there is no need for such a restricted
approach: it's quite possible for the *\output* routine to extract various
pieces from *\box\topins*, putting some pieces at the top  and other pieces
at the bottom. Thus, some
figures in the *\topins* insertion class can just
as well be placed at the bottom of the page (hopefully, before the footnotes)
as at the top of the page.


\item An associated
counter *\count\topins*, which tells \tex\ what proportion of the 
height plus depth of *\box\topins* to subtract from *\vsize* in computing
the proper height for *\box255*.
In *plain* \tex@, *\count\topins=1000*, indicating that *\box255* should
leave room for the full height plus depth of *\box\topins*; this will
remain the same in \lamstex.

\item An associated dimension register, *\dimen\topins*, which indicates
the maximum size of *\box\topins* that will be allowed per page.

\item An associated glue register, *\skip\topins*, which indicates extra
space to leave blank in *\box255* if there happens to be anything in
*\box\topins*.
\endbullist
As we will soon see, *\dimen\topins* and *\skip\topins* are the keys to
making  *\topins* work for us.

\medskip
Notice that \tex's insertion mechanism already does most of the work we want:
boxes are added and withdrawn from any insertion class in a ``first in first
out'' manner; and \tex\ does all the calculations to make sure that
*\box255* is made sufficiently short to accommodate anything in the
insertion class.

Of course, we usually don't want \tex\ to allow more than two things in
*\topins* to appear per page.  But this can be controlled by
*\dimen\topins* (which can be set to any desired value at any time);
if *\dimen\topins* is the sum of the height plus depths of the first two
boxes in *\topins*, then \tex\ will allow only these two boxes to be added
to *\box\topins*.\pagelabel{INCDIMT}

There is also the question of the glue
 to be left below a figure at the
top of a page, which we will call *\belowtopfigskip*,
or 
above a figure at the bottom of the page, which we will call
*\abovebotfigskip*.  For the moment, let's pretend that
these two values are the same.  Then
before *\box\islandbox@* is *\insert*'ed into *\topins*, 
we will simply declare the height of *\box\islandbox@* to be greater than
it already is by the \<dimen\> part of *\abovebotfigskip*, and we 
will similarly increase *\dimen\topins* enough
to leave space for the \<dimen\> part of this glue.
Thus, when a box in *\box\topins* is returned to its proper height, there
will be room to add *\abovebotfigskip* glue.

 The only question is,
what should we do
when the two amounts  of glue that we want to leave
are different, as, for example, in the default style,
which has
**
\belowtopfigskip = 15pt plus 5pt minus 5pt
\abovebotfigskip = 18pt plus 6pt minus 6pt
**
Fortunately, *\skip\topins* allows us to deal with this: 
\list\item
We will be increasing
*\dimen\topins* by an additional *18pt* for each *\Aplace*.
\item But we will also set
\setbox0=\hbox{\<dimen\> part of }
**
\skip\topins = "box0\abovebotfigskip - \belowtopfigskip
             = -3pt  "8EXTRAS"8
**
\endlist
Then:
\bullist
\item
If no members of the insertion class
 appear on the page, all these quantities are irrelevant. 

\item
If just
one member of the insertion class
 appears (at top), then \tex\  leaves *-3pt* extra space for
it; i.e.,  *\box255* will be *3pt* {\it longer\/} than it should be
to allow the insertion plus *18pt* space to fit on a page.
Consequently, when we
add only *15pt* instead of the *18pt*, 
 everything will work out just right. 

\item If  one member of the insertion class
appears at the top and one (or more)
at the bottom, everything still works, because
\tex\ only leaves the *-3pt* extra space once. This properly adjusts
the top member
of the insertion class,
while the bottom member,
 with *18pt* glue above it, also works out right.
\endbullist
The analysis seems equally valid
 (and easier) if *\belowtopfigskip* is greater
than *\abovebotfigskip*; however, as we'll see at the end of section
~\Sref{FLOAT} and in section~
~\Sref{255TOO}, it really introduces quite different problems.

\section{Setting things up\label{STU}} 
First we declare the glues below figures at the
top of the page and above figures at the bottom of the page, and give them
their default values; at the same time, we introduce a \<dimen\>
 register for the
minimum amount of text to be allowed on a page that is otherwise filled with
figures:
\C**
\newskip\belowtopfigskip 
\belowtopfigskip=15pt plus 5pt minus5pt
\newskip\abovebotfigskip 
\abovebotfigskip=18pt plus 6pt minus6pt
\newdimen\minpagesize 
\minpagesize=5pc
**
To get *\skip\topins* to be the \<dimen\> part of $\hbox{*\belowtopfigskip*}
-\hbox{*\abovebotfigskip*}$, we use the following code
(compare page~\ref{ELIM}):
\C**
\dimen@=\belowtopfigskip 
\advance\dimen@ by -\abovebotfigskip
\skip\topins=\dimen@                  "8EXTRAS22"8
**
 (If a style file changes
*\belowtopfigskip* and *\abovebotfigskip*, these lines
should be repeated, to reset *\skip\topins* correctly.)


Initially, *\dimen\topins* will be *0pt*; it will be increased only as we
*\Aplace* things.
\C**
\dimen\topins=0pt
**

In order to set *\dimen\topins* correctly, we are going to have to keep track
of various things. In particular, we will use a counter
\C**
\newcount\topinscount@
**
to keep track of how many boxes still remain in the *\topins* insert.

\section{How \CS{Aplace} works} An extra layer of
 complications envelops \lamstex's automatic
placing mechanism because of the existence of so many different
varieties of *\...place*'s.  In order to get a better idea of the main
features, in this section we will consider a simpler style in which there is
only *\Aplace*, and we will also assume that *\Aplace* is being
used only in vertical mode. Code surrounded by dashed lines rather than solid
lines will be changed when we get to the final definitions later on.

\Pitem Each 
**
\Aplace{\island ... \endisland}
**
will essentially
**
\insert\topins\box\islandbox@
**
where *\box\islandbox@* is the completed box---containing both the *\island*
and its caption(s), which the *\island"allowbreak..."allowbreak\endisland*
creates---except that we will first increase the height of
*\box\islandbox@* by the \<dimen\> part of *\abovebotfigskip*, so that
\tex\ will be trying to leaving room for this box plus this amount of space.
\tex\ doesn't allow us to say
**
\advance\ht\islandbox@ by \abovebotfigskip
**
so we have to take a roundabout route and say
\Litbox0=**
\dimen@=\ht\islandbox@
\advance\dimen@ by \abovebotfigskip
\ht\islandbox@=\dimen@
**
$$\pagelabel{EXTRAS2}\vcenter{\box0} \tag"\style{\bf A}"$$

\pitem Then
we will
**
\advance\dimen@ by \dp\islandbox@
**
so that *\dimen@* is the height plus depth of *\box\islandbox@*, plus
the \<dimen\> part of *\abovebotfigskip*. The value of *\dimen@*
 is information that we are
going to store, whether or not we plan to
allow the *\Aplace*'d *\island* to appear in
*\box\topins*. 
Instead of keeping a list of these dimensions, it is simpler to
store empty *\hbox*'s of the corresponding width inside a *\vbox*,
which we call *\topinsdims@*; the routine for doing this will be
called *\storedim@*:
\C**
\newbox\topinsdims@
"slip
\def\storedim@{\global\setbox\topinsdims@
 =\vbox{\hbox to\dimen@{}%
  \unvbox\topinsdims@}}
**
Notice that we put the new information on the {\it top\/} of the *\vbox*.
\pagelabel{STOREDIM}
That is because it is easiest to get information by taking things off of the
{\it bottom\/} of the *\vbox*, with *\lastbox* (see the footnote on
page~\ref{KLB}).
Note also that no glue will be added between the *\hbox*'s (see the
footnote on page~\ref{NEXG}). 


\pitem
 Each time we encounter an *\Aplace*, we must decide whether or not
the corresponding 
\setbox0\hbox{,}
**
\box\islandbox@ "box0
**
which we have placed in the *\topins*
insertion class,
 should be allowed to appear in *\box\topins* at the next *\output* routine.


The default style uses
 the rule that there should be at most two *\island*'s per page.
Recall that *\topinscount@* is supposed to be the number of insertions
currently in the *\topins* insertion class.
So if
*\topinscount@* is greater than or equal to~*2*,
there are already at least two insertions waiting to go on the current page.
In this case, we   don't want to allow the current insertion
to appear in *\box\topins*. But if *\topinscount@* is less than~*2*,  so that
there is at most one insertion waiting to go on the current page, then we
do want to allow the current insertion to appear in *\box\topins* (of course,
it will then be up to \tex\ to decide whether there is actually room on the
page for this  insertion).


We initially have
**
\dimen\topins=0pt
**
This means that initially 
 no inserts will be placed in *\box\topins*
 during the *\output*  routine.
 If we decide to allow the current insertion to appear in *\box\topins*,
we need to communicate that decision to \tex@, as indicated on
page~\ref{INCDIMT},  by increasing
*\dimen\topins* by  *\dimen@*,
\setbox0\hbox{\<increase *\dimen\topins* appropriately\>}
**
\ifnum\topinscount@ > 1 \else 
 "box0 \fi
**
Again, we will need a roundabout route for increasing *\dimen\topins*,
**
\advance\dimen@ by\dimen\topins
\global\dimen\topins=\dimen@
**
We define a routine for doing this, *\advancedimtopins*, which
contains one more element,
\C**
\def\advancedimtopins@{%
 \ifnum\pageno=1
 \else
  \advance\dimen@ by \dimen\topins
  \global\dimen\topins=\dimen@
 \fi}
**
In other words, aside from any other considerations influencing our decision
as to whether or not an *\Aplace*'d *\island* should be allowed to appear in
*\box\topins*, it will never be allowed on page~*1*.

  Simple modifications of
*\advancedimtopins@*  allow numerous other style decisions.\pagelabel{MODADT}
  For example,
in the *book* style, each *\chapter* starts a new page and then
sets *\iffirstchapterpage@* to be true; then
in the definition of\linebreak *\advancedimtopins@*,
the clause 
**
\ifnumpageno=1
\else
**
is replaced by
**
\iffirstchapterpage@
\else
**
This prevents anything from appearing in *\box\topins* when the first page of
any *\chapter* is presented to the
*\output* routine.


\pitem  Once we have properly increased *\dimen\topins*, we can 
*\insert* our *\box\islandbox* into *\topins* (it is important to do the
*\insert* {\it after\/} taking care of *\dimen\topins*, because \tex\ decides
whether or not to move an *\insert* onto the current page at the time
the *\insert* is made).


\pitem
Finally, the counter *\topinscount@* is supposed to be the number of 
boxes currently in the *\topins* insertion class, so
each time an *\Aplace* occurs we need to
**
\global\advance\topinscount@ by 1
**
(it will be the duty of the *\output* routine to suitably {\it decrease\/}
*\topinscount@* by the number of *\island*'s that finally get placed on that
page).\pagelabel{AXXA}

 \medskip
For the actual definition, 
*\Aplace*, like *\place*, will begin by setting
 *\place@true* and *\island@false*, and 
end by
 resetting *\place@false*.
After calling the argument *#1* to set a box, and set *\ifisland@* to be
true, we give an error message if *\ifisland@* is still false,
**
\def\Aplace#1{\place@true \island@false
 #1%
 \ifisland@
   . . .
   . . .
 \else
  \Err@{Whoa ... there's no \string\Figure, \string\Table, 
   etc., here}
 \fi
 \place@false}
**

%\pagebreak

\Pitem
Assuming we don't give an error message, the first thing will be
**
\dimen@=\ht\islandbox@
\advance\dimen@ by \abovebotfigskip
\ht\islandbox@=\dimen@
**

%\pagebreak

\pitem This will be followed by
**
\advance\dimen@ by \dp\islandbox@
\storedim@
**

\pitem Next comes
**
\ifnum\topinscount@ > 1 \else \advancedimtopins@ \fi
**

\pitem Then we are ready to
**
\insert\topins{\penalty0 \splittopskip=0pt \floatingpenalty=0
  \box\islandbox@}
**
The *\penalty0* allows this insertion to be treated as a split insertion, and
thus float to the next page if it does not fit on this page ({\it The \tex
book}, pages~123@--124).
 Other penalties, like *plain* \tex's *\penalty200*, might
be used by style designers
to encourage \tex\ to keep the insertion on the same page.
 The *\splittopskip=0pt* insures that only *0pt*~ glue
precedes this split insertion; this is probably unnecessary, since
the inserted box is quite unlikely to be smaller than *\topskip*, but
there's no point taking chances, especially since at one point
(page~\ref{WHYSPLITZ})\pagelabel{SPLITZ} 
 it will be
crucial to know that this glue is indeed ~*0pt*.
 The
*\floatingpenatly=0* means that there will be no
extra page breaking penalties if later inserts are allowed to split also
(i.e., to appear on later pages); this is also not really necessary, since
*\floatingpenalty* has the default value~*0*.



\pitem
Finally, we
**
\global\advance\topinscount@ by 1
**



So our  definition is
\dashC**
\def\Aplace#1{\place@true \island@false  "8APLACE"8
 #1%
"2
 \ifisland@
  \dimen@=\ht\islandbox@
  \advance\dimen@ by \abovebotfigskip
  \ht\islandbox@=\dimen@
"2
  \advance\dimen@ by \dp\islandbox@
  \storedim@
"2
  \ifnum\topinscount@ > 1 \else \advancedimtopins@ \fi
"2
  \insert\topins{\penalty0 \splittopskip=0pt
   \floatingpenalty=0
   \box\islandbox@}% 
  \global\advance\topinscount@ by 1
"2
 \else
  \Err@{Whoa ... there's no \string\Figure, \string\Table, 
   etc., here}%
 \fi
 \place@false}  "8GDF2"8
**


\section{How the \CS{output} routine works}
Now let's consider what the *\ouput* routine must do. At the time that it is
invoked, *\box\topins* will contain zero, one, or two boxes, with all other
members of the insertion class still held over.  The boxes in *\box\topins*
occur in the order that they were *\insert*'ed,  i.e., the first *\insert*
produces the top box, the second *\insert* produces the box below it.
Unfortunately, that's  the exact reverse of the order we want, because
the only way that we can extract boxes from *\box\topins* is by means of
a construction like
**
\setbox0=\vbox{%
 \unvbox\topins
 \globally\setbox1=\lastbox}
**
which makes *\box1* be the bottom box.  In the case where *\box\topins* 
contains at most two boxes, this isn't really all that burdensome, but in the
general situation, where something like
*\AAplace* may have been used, the reverse 
order
becomes a true impediment.  So we will define a routine
**
\fliptopins@  "8FLIPT"8
**
that recreates *\box\topins* with the sub-boxes in reverse order.
At the same time, the number of boxes will be stored in a counter,
*\flipcount@*,
whose value will  be used later on.

{\bf(1)}
To begin, we set *\flipcount@* to ~*0*. Then we *\unvbox\topins* 
within another box, into which *\vskip1pt* is inserted at
the beginning, as a marker (compare page~\ref{VSMARK}).
 And within this box,
 in which *\box\topins* has already been destroyed, we
initialize the new *\box\topins*:
**
\def\fliptopins@{\global\flipcount@=0
 \setbox0=\vbox{%
  \vskip1pt
  \unvbox\topins
  \global\setbox\topins=\vbox{}
**

If *\box0*  looks like
\setbox1\hbox{\<box$_{\text1}$\>}
\setbox2\hbox{\<box$_{\text2}$\>}
\setbox3\hbox{\<box$_{\text3}$\>}
**
\vskip1pt
\penalty0
"box1
\penalty0
"box2
\penalty0
"box3
 . . .
**
then, as we start to take off  boxes and penalties from the bottom of
this list, *\lastskip* will be ~*1pt* when we have reached the top; at
any other point
 *\lastskip* will be~
*0pt*, since there is no other glue on the list.
So the procedure
**
\loop
 \ifdim\lastskip=0pt
  \global\advance\flipcount@ by 1
  \setbox0=\lastbox
  \global\setbox\topins=\vbox{\unvbox\topins\box0}
  \unpenalty
\repeat}
**
should set
*\flipcount@* to the number of boxes, and also
 reconstruct *\box\topins*, in the
reverse order.

But *\box0* can have a different structure also:
when a member of *\topins* has been deferred to a later page (i.e.,
split), *\box\topins* looks like
\setbox1\hbox{\<box$_{\text1}$\>}
\setbox2\hbox{\<box$_{\text2}$\>}
\setbox3\hbox{\<box$_{\text3}$\>}
**
\vskip0pt
"box1
\penalty0
"box2
\penalty0
"box3
 . . .
**
where the *\vskip0pt* is the *\splittopskip* glue, which we have made certain
will be~ *0pt* (page~\ref{SPLITZ}).\pagelabel{WHYSPLITZ}
So we have to use the more complicated 
**
\loop
 \test@false
"2
 \ifdim\lastskip=0pt 
  \unskip
"2
  \ifdim\lastskip=0pt
   \test@true
  \fi
 \fi
"2
 \iftest@ 
  \setbox0=\lastbox
  \global\setbox\topins=\vbox{\unvbox\topins\box0}
  \unpenalty
 \repeat}
**

We want to avoid all this rigamorole if *\box\topins* is void to begin with,
so our final definition is
\C**
\newcount\flipcount@
"slip
\def\fliptopins@{\global\flipcount@=0
 \ifvoid\topins\else
 \setbox0=\vbox{%
"2
  \vskip1pt
"2
  \unvbox\topins
"2
  \global\setbox\topins=\vbox{}%
"2
  \loop
   \test@false
"2
   \ifdim\lastskip=0pt
    \unskip 
    \ifdim\lastskip=0pt
     \test@true
    \fi
   \fi
"2
   \iftest@
   \global\advance\flipcount@ by 1
   \setbox0=\lastbox
   \global\setbox\topins=\vbox{\unvbox\topins\box0}%
   \unpenalty
  \repeat}%
 \fi}
**


{\bf(2)} After the *\output* routine has done
**
\fliptopins@
**
to get *\box\topins* properly set up,
it essentially  does
**
\shipout\vbox{\makeheadline\pagebody\makefootline}
**
just like the *plain* \tex\ *\output* routine.
As in *plain* \tex,  *\pagebody*  is not much more than
**
\vbox to\vsize{\boxmaxdepth=\maxdepth \pagecontents}
**
 Actually, the \lamstex\ *\pagebody* routine
is a little more complicated, because marginal notes for index entries are
attached at this point, but for now let's ignore that complication.

 *\pagecontents* is the routine where interesting things happen.
 In *plain* \tex@, *\pagecontents*  basically  stacks up
\setbox0\hbox{things in *\box\topins*}
\setbox1\hbox{contents of *\box255*}
\setbox2\hbox{things in *\box\footins*, preceded by footnote rule}
$$
\vbox{\halign{#\hfil\cr
 \box0 \cr
 \box1 \cr
 \box2 \cr}}
$$
But we need a more complicated routine, because if *\box\topins* contains
two boxes, we need to put the first box (i.e., the {\it bottom\/} box, since
we've already applied *\fliptopins@*)
 at the top of the page, with suitable space below it,
and the other box at the bottom.

\Evaluatenref{EXTRAS}\edef\thevalue{\Nref}%
\Evaluatenref{EXTRAS2}%
\ifnum\thevalue=\Nref \edef\theref{page \Nref}\else
  \edef\theref{pages\noexpand~\thevalue\ and\noexpand~\Nref}\fi


We start with
**
\def\pagecontents{%
 \ifnum\flipcount@ > 0
  \setbox\topins=\vbox{\unvbox\topins\global\setbox1=\lastbox}
**
to get the bottom box of *\box\topins* into *\box1*.

Then we want to take this *\box1* apart, to get the caption and island boxes
that constitute it, together with the glue between them,
**
\setbox0=\vbox{\unvbox1 
 \global\setbox1=\lastbox
 \global\skipi@=\lastskip
 \unskip
 \global\setbox3=\lastbox}
**
Here we use the fact that there is just one glue between the two boxes
(page~\ref{ONEGLUE}). 

Then we use
**
\centerline{\box3}
\nointerlineskip
\vskip\skipi@
\centerline{\box1}
\vskip\belowtopfigskip
**
to put everything back, with the island box and the caption box both
centered, and *\belowtopfigskip* following; the *\nointerlineskip* is
used to make certain that no extra glue creeps in.



The original *\box0*, appearing in *\box\topins*, had its height
artificially increased by *\abovebotfigskip*. But the individual pieces
of this box still have their correct heights, so the
**
\centerline{\box3}
\nointerlineskip
\vskip\skipi@ 
\centerline{\box1}
**
causes a net decrease of *\abovebotfigskip* in height, to which we have
then added a net increase of *\belowtopfigskip*.
As explained on \theref, \tex\ has already left exactly enough
space to allow
this change from\linebreak *\abovebotfigskip* to *\belowtopfigskip*, so 
it looks like everything should work out just right.  Actually, however, 
we will change the 
**
\vskip\belowtopfigskip
**
to
**
\ifdim\ht255 < \minpagesize \else
 \vskip\belowtopfigskip \fi
**
for reasons discussed in section~\Sref{WHATH}.





\small
If\pagelabel{NOCAP}
 our *\island* had no caption, then *\box1* would actually be
the *\hbyw*, or other material, *\skipi@* would be ~*0pt*, and *\box3* would
be void.  This makes no difference in the current situation, where all the
sub-boxes are treated the same,
but  other
styles might have to make explicit checks to
see whether *\box0* contained a caption or not.

\andsmall  It is even conceivable
that the style would need to know what class of *\island* was contained 
in *\box0*.  This information would probably best be recorded in a list like
the list *\AAlist@* discussed in sections~\Sref{AandAA}, \Sref{BPLACE},
and~\Sref{RSDTNS}.
\endsmall

Once we've taken care of figures at the top of the page we use
**
\ifdim\ht255 < \minpagesize \vfil \else \unvbox255 \fi
**
to print the text in *\box255*, unless there is too little to go on the page;
 then we finish  the definition off with a routine
 *\bottomfigs@*, which adds the figure at the bottom if *\box\topins*
still has a box left in it, after which we
 add the footnotes, just as in *plain*
\tex@:
\dashC**
\def\pagecontents{%     "8PAGECT"8
 \ifnum\flipcount@ > 0
"2	
  \setbox\topins=\vbox{\unvbox\topins
   \global\setbox1=\lastbox}%
"2
  \setbox0=\vbox{\unvbox1
   \global\setbox1=\lastbox
   \global\skipi@=\lastskip
   \unskip
   \global\setbox3=\lastbox}%
"2
  \centerline{\box3}\nointerlineskip
  \vskip\skipi@
  \centerline{\box1}%
"2
  \ifdim\ht255 < \minpagesize \else
   \vskip\belowtopfigskip \fi
 \fi
"2
 \ifdim\ht255 < \minpagesize \vfil \else \unvbox255 \fi
"2
 \bottomfigs@
 \ifvoid\footins\else
  \vskip\footins\footnoterule\unvbox\footins\fi}
"slip
\def\bottomfigs@{%   "8BFIGS"8
 \ifnum\flipcount@ > 1
"2
  \nointerlineskip
  \vskip\abovebotfigskip
"2
  \setbox0=\vbox{\unvbox\topins
   \setbox0=\lastbox
   \unvbox0 
   \global\setbox1=\lastbox
   \global\skipi@=\lastskip
   \unskip
   \global\setbox3=\lastbox}%
"2
  \centerline{\box3}\nointerlineskip
  \vskip\skipi@
  \centerline{\box1}%
 \fi}
**

Note that the *\nointerlineskip* at the very beginning of the definition
of *\bottomfigs@*
is quite essential:
  without it,
 extra glue would be added before the *\centerline{\box3}*.
Even extra *\lineskip* glue might not fit at this stage, but, in fact,
the glue might be bigger, 
because *\box3* could be empty (for example, an empty caption above
a table), in which case *\baselineskip* glue would be used!


\small
Since we went to the trouble of taking apart *\box\islandbox@*, in
order to allow the glue between the island and the caption to stretch
or shrink on the page, we might also want to take apart
*\box\Captionbox@*, so that 
 the glue between multiple
captions could also participate.


\andsmall 
When we have an *\island* at top, followed by
material from *\box255*,
**
 . . .
\centerline{\box1}
\vskip\belowtopfigskip
\unvbox255
 . . .
**
the first line of *\box255* will have glue above it determined by the value
of *\topskip*;
for example, in the default style there 
will usually be enough glue to make the height of the first line be~*10pt*.
So the space between the bottom of *\box1* and the baseline of this first
line will be $\hbox{*\belowtopfigskip*}+\hbox{\tt10pt}$.  If we were being
fussy, we might increase *\belowtopfigskip* by~ *2pt* to compensate for this.
However, even that wouldn't work precisely if *\box1* has some depth.


Probably none of this matters much when *\belowtopfigskip* is a fairly large
value, but a more precise routine could be made:
for  *\island*'s
like *\Figure*, with their
caption below, 
in the *\endisland* routine (page~\ref{EIROUTINE}) we could 
add
**
\kern-\prevdepth
**
after the *\box\Captionbox@* in the final *\vbox*
\endsmall



{\bf(3)} After the *\shipout*, we will use
**
\advancepageno
**
to advance the page number.


({\bf 4})
Now that  *\pagecontents* has properly arranged
the boxes in *\topins* on the page, the *\output* routine
 must set things up properly for
the next page.  First of all
**
\global\advance\topinscount@ by -\flipcount@
**
insures that
 *\topinscount@* will still represent the number of elements in the
*\topins* insertion class. Taking care of *\dimen\topins* requires more work.
 
\def\1#1{\hbox to#1pt{\leaders\hrule\hfil}}

At the time that the *\output* routine was called, *\dimen\topins* was
the height plus depth, plus extra *\abovebotfigskip* space, for the first
two boxes in the *\topins* insertion class. After the *\output* routine is
done, we have to reset *\dimen\topins* to the same quantity for the first two
boxes that remain in this class. 

 Remember that *\box\topinsdims@* is a
*\vbox* of empty *\hbox*'s
whose widths are the appropriate dimensions for the various boxes in the
*\topins* insertion class.
Since these boxes were added at the {\it top\/} (page~\ref{STOREDIM}), the
bottom box has the dimension for the first box in *\topins*, and so forth.
In order to keep our information current, we will remove
boxes from the  bottom, the number of boxes we remove being *\flipcount@*,
  and reset *\dimen\topins* to
the sum of the widths of the next two bottom
boxes: this will ensure that on the
next page, at most two of the next 
boxes in *\topins* will actually be allowed to
appear in *\box\topins*.

To do this, we first
**
\global\setbox\topinsdims@=
 \vbox{%
  \unvbox\topinsdims@
"2
  \count@=0
  \loop
   \ifnum\count@ < \flipcount@
    \setbox0=\lastbox
    \advance\count@ by 1
  \repeat
**
In other words, the new *\box\topinsdims@* will start out with all the boxes
originally in this box (from the *\unvbox\topinsdims@*); and then we will
use *\setbox0=\lastbox* the appropriate number of times to get rid of
 *\flipcount@* boxes at the bottom.

Before finishing off this box, we need to set *\dimen\topins*
to the  sum of the widths of the
next two bottom boxes. The only way we can get at these
widths is by using *\lastbox*; since we don't want to throw away these next
two boxes, however, we will store them in *\box1*, and
then *\unvbox1* before completing the box.  For purposes of
generalization later on, we will write this as a *\loop* also:
**
\dimen@=0pt
\count@=0
\setbox2=\vbox{}
"2
\loop
 \ifnum\count@ < 2
  \setbox0=\lastbox
  \advance\dimen@ by \wd0
  \setbox2=\vbox{\box0 \unvbox2}
  \advance\count@ by 1
 \repeat
"2
\unvbox2
\global\dimen\topins@=\dimen@
**


The whole routine will be called *\resetdimtopins@*:
\dashC**
\def\resetdimtopins@{%    "8RESETDT"8
 \global\advance\topinscount@ by -\flipcount@
"2
 \global\setbox\topinsdims@=
 \vbox{%
"2
  \unvbox\topinsdims@
  \count@=0
"2
  \loop
   \ifnum\count@ < \flipcount@ \setbox0=\lastbox
    \advance\count@ by 1
  \repeat
"2
  \dimen@=0pt
  \count@=0
  \setbox2=\vbox{}%
"2
  \loop
   \ifnum\count@ < 2
    \setbox0=\lastbox
    \advance\dimen@ by \wd0
    \setbox2=\vbox{\box0 \unvbox2}%
    \advance\count@ by 1
  \repeat
"2
  \unvbox2
  \global\dimen\topins=\dimen@}}
**



\medskip

We aren't
 going to formally define an *\output* routine for our specialized
style, saving for Chapter~\ref{OUTPUT} numerous additional details
(some discussed in the next section of this chapter).
But here is a summary of the main points:

\list \newfontstyle\list1\bf \item The \pagelabel{OUTLIST}
*\output* routine first uses *\fliptopins@* to get
*\box\topins* into the right order, computing *\flipcount@* in the process.

\item Then it ships out a *\vbox* whose main part is *\pagecontents*, which
we have already considered in detail.

\item
At this point, when any delayed *\write*'s have been done,
we can use 
**
\advancepageno  "8APRD"8
**
 to advance the page number.

\item
Then we use
**
\resetdimtopins@
**
to properly adjust *\topinscount@* and *\dimen\topins* for the next page.

\item\label{UNV255}\pagelabel{PUNV255} 
Unlike the *plain* routine, where *\box255* is always used up, our routine
will not use *\box255* if its height is less than *\minpagesize*.  So at
this point we use
**
\ifvoid 255 \else \unvbox255 \penalty\outputpenalty
**
This puts the material in *\box255* back on the top of the list, together
with whatever *\penalty* precedes it, since this was recorded in
*\outputpenalty* ({\it The \tex book}, pages~125 and~254).

\item Then we end, as in *plain* \tex@, with
**
\ifnum\outputpenalty > -20000 \else \dosupereject \fi
**
\endlist

\section{When insertions float\label{FLOAT}}
Although the theory behind our definition of *\Aplace* may seem fine, 
it has one annoying flaw that becomes particularly significant when we are
dealing with straight text, unrelieved by displayed formulas, or other
material that introduces shrink or stretch on the page.

To take a particular example, let us suppose that we have set
\setbox0\hbox{($=\hbox{39}\times\hbox{*12pt*}+\hbox{*10pt*}$)}
**
\parskip=0pt
\topskip=10pt
\baselineskip=12pt
\vsize=478pt "box0
**
so that exactly 40~lines of text will fit on a page, without any stretch or
shrink allowed between paragraphs. (Styles with such specifications usually
arrange for the heights of
any Chapter headings, etc., to be an integer 
multiple of *\baselineskip*.
 When illustrations are to be included, *\belowtopfigskip* and
*\abovebotfigskip* should probably have stretch and shrink at least
half of *\baselineskip*, unless care is taken to insure that the heights of
all *\island*'s, when added to these *\vskip*'s,
are also an integer number times *\baselineskip*. However, for purposes of
illustration, we will simply continue to use our default values
of *\belowtopfigskip* and *\abovebotfigskip*.)

Now suppose that near the bottom of page~2 we *\Aplace* something that
will not fit on that page, so that the *\insert* will split.  If
`*\showbox\topins*' is added to the *\output* routine, \pagelabel{SHOWBOX} 
then before page ~*[1]*
is shipped out,
the *.log* file
will contain the following information about *\box\topins* (which happens
to be *\box253*):
**
> \box253=void
**
But before page~*[2]* is shipped out, we will have
**
> \box253=
\vbox(0.0+0.0)x0.0
**
this *\vbox* being
the part that is split off from the 
**
\insert\topins{\penalty0 ... }
**

This might seem like an insignificant difference, but it's not:
Since \tex\ has added something (albeit something trivial)
to *\box\topins*, it has also allowed for *\skip\topins=-3pt* glue. If
`*\showbox255*' is added to the *\output* routine, then the log file will have
**
> \box255=
\vbox(481.0+...)x...
.\glue(\topskip) 
. . .
**
In other words, *\box255* is now *3pt*~{\it too high}.  In  our
particular
example, it will probably be an *Underfull* box. \tex\ doesn't
report *Underfull* boxes when *\box255* is packaged for use by the *\output*
routine ({\it The \tex book}, page~400), and when we *\unvbox255*,
everything will probably still turn out all right.

But if *\skip\topins* were as large as *12pt*, then we would definitely have
an extra line on our page.  Consequently, the *\output* routine will have
to take care to trim *\box255* down to the proper height, and anything left
over will have to be put back on the main vertical list at the end of
the *\output* routine. (Such a final step in the *\output* routine will
be needed for other reasons also; for example, when there are figures at both
the top and bottom of the page, and the space between is less than
*\minpagesize*, so that no text is allowed to appear on the page,
everything in *\box255* has to be put back).

Notice that if *\belowtopfigskip* were {\it greater\/} than
*\abovebotfigskip*, then our problem would be much more severe: In this case,
 *\box255*
would be {\it too short}, and there would be no way to rectify the situation.
This is discussed further in section~\Sref{255TOO}.





\nopunct\sectiong{What happens to an \CS{Hbyw}?\label{WHATH}}
  When we have
an *\island* involving an *\Hbyw*, the height of
*\box0* will have been increased so that it is
*18pt*
 larger than *\vsize*.
\tex\ has chosen *\box255* so that
\setbox5\hbox{height of *\box255*}
\setbox6\hbox{*\vsize*}
\setbox7\hbox{height of *\box0*}
\setbox8\hbox{*\vskip\topins*}
\Math
\align
 \copy6&=
 \copy5+\copy7+\copy8\\
&=\copy5+\copy6+\hbox{\tt18pt}-\hbox{\tt3pt}\\
 &=\copy5+\copy6+\hbox{\tt15pt}
\endalign
\endMath
So *\box255*
will be an empty box of height~ *-15pt* (see below for further elucidation),
which would make things come out just right
when it is added back in with the other material.
  But we won't be
adding the material from *\box255* in this situation, since its
height is less than *\minpagesize*; 
\footnote{When we *\unvbox255* at the end of the *\output* routine---%
see~(\ref{UNV255}) on page~\ref{PUNV255}, and page~\ref{PPUNV255}---%
to put unused material from *\box255*
 back at the top of the current page, the contents of such 
an empty box will simply disappear, since \tex\ discards such glue
at the top of the current page.}
consequently, if we were to add
*\vskip\belowtopfigskip* in this case, we would get an *Overfull* box that is
~*15pt* too high.
That is why we had to use 
**
\ifdim\ht255 < \minpagesize \else
 \vskip\belowtopfigskip \fi
**
In our final definition, page~\ref{FINALPC}, we will actually 
use more refined emendations.

\medskip


This apparently anomalous situation, where *\box255* has negative height,
more or less follows from
 the rules on page~123 of {\it The \tex book}.
The first time that an *\Hbyw* insertion is considered, it will be split,
according to {\bf Step 4}, at the *\penalty0*, leaving a box of 
height $\hbox{*\vsize*} + \hbox{\tt15pt}$.
 When the next page is made, this box will definitely
be added, at
{\bf Step~ 1}, which will decrease the *\pagegoal* {\it g\/} by this height,
so that it is now *-15pt*.\pagelabel{NEG255}

\medskip

Note that, as a consequence, an 
*\Hbyw*  will always appear at least
one page after it is *\Aplace*'ed, even if there is nothing else on the page
at the time.

\endsmall



\chapter \CS{Aplace}, \CS{AAplace} and \CS{Bplace}\label{AAB}\endchapter

We are now ready to consider the real definition of *\Aplace*, together
with *\AAplace* and *\Bplace*.  

Unlike *\Cplace*,
*\Mplace* and *\MXplace*, which can only be used between paragraphs, or in a
special *\Par...\endPar* region,
 *\Aplace*,
*\AAplace*, and *\Bplace* can be used directly within paragraphs.
Nevertheless, it is conceivable that the latter will also be used in a
*\Par...\endPar* region (probably because  some *\Cplace*, *\Mplace*, or
*\MXplace* is also being used in that region). So we first 
have to take care of
some preliminaries related to *\Par...\endPar* regions.

The \lamstex\ Manual states, on page~67, that blank lines within a
*\Par"allowbreak..."allowbreak\endPar* region will give an error message, and
this was indeed true in version~*1* of \lamstex@.  But there is really no
need for this, and the implementation was quite imperfect, so that feature
has been dropped in version~*2*.


\section{Figures, etc., within \CS{Par}{\tt...}\CS{endPar}}
First we need a flag to tell whether we are in such a paragraph,
a counter to tell how many times a *\...place* 
occurred within this paragraph, and a box in which to store the text of
such a paragraph:
\C**
\newif\ifPar@
\newcount\Parcount@
\newbox\Parbox@
**

The *\island*'s that are *\...place*'ed within such regions will be stored
in other boxes,
\C**
\expandafter\newbox\csname Parfigbox1\endcsname
\expandafter\newbox\csname Parfigbox2\endcsname
\expandafter\newbox\csname Parfigbox3\endcsname
\expandafter\newbox\csname Parfigbox4\endcsname
\expandafter\newbox\csname Parfigbox5\endcsname
**
Creating these boxes with *\csname"allowbreak..."allowbreak\endcsname*
 is easier and more
convenient than trying to make a  `*\Parfigbox*' macro with an argument.

It turns out that
we are also going to need \<dimen\> registers to store the depths of
various paragraphs:
\C**
\expandafter\newdimen\csname Parprev1\endcsname
\expandafter\newdimen\csname Parprev2\endcsname
\expandafter\newdimen\csname Parprev3\endcsname
\expandafter\newdimen\csname Parprev4\endcsname
\expandafter\newdimen\csname Parprev5\endcsname
\expandafter\newdimen\csname Parprev6\endcsname
**
We need six \<dimen\> registers because
`*\Parprev1*' will store the depth of the paragraph before
the *\Par...\endPar* region, `*\Parprev2*' will store the depth of the text
before the first *\island*, etc.\pagelabel{PARPREV}
As before (compare pages~\ref{QTS1}, \ref{QTS2}, \ref{QTS3}, and~\ref{QTS4}),
we use quotes around *\Parprev1* to indicate that it is a single control word.

In addition to all this, within each *\Par...\endPar* region we will be
keeping a list,
**
\Parlist@
**	
which will simply be
a list of letters.

The definition of *\Par* begins by
ending the previous paragraph, storing the depth of the last line of that
paragraph in `*\Parprev1*', setting *\ifPar@* to be true,
and initializing *\Parcount@* to be *1* and *\Parlist@* to
be empty:
**
\par
\csname Parprev1\endcsname=\prevdepth
\Par@true
\global\Parcount@=1
\global\let\Parlist@=\empty
**
Then we begin to set *\box\Parbox@*,
**
\setbox\Parbox@=\vbox\bgroup
**
We want this *\vbox* to begin with a *\break* for latter purposes
(section~\Sref{ENDPAR}).\pagelabel{NBREAK} Our whole definition is:
\C**
\def\Par{\par
 \csname Parprev1\endcsname=\prevdepth
 \global\Parcount@=1
 \Par@true\global\let\Parlist@=\empty
 \global\setbox\Parbox@=\vbox\bgroup\break}
**

The definition of *\endPar* will not be
given until section~\Sref{ENDPAR}.



\section{\CS{place\@}\label{place}}The constructions
*\Aplace*, *\AAplace*, and *\Bplace* have much in common, and they
are going to be 
defined in terms of a control sequence
*\place@#1#2* with a rather strange combinations of arguments:
\setbox0\hbox{will be defined in terms of}
**
\Aplace   "copy0  \place@ a\Aplace@
\AAplace  "copy0  \place@ A\AAplace@
\Bplace   "copy0  \place@ b\Bplace@
 . . .
**
Here the first argument is simply a convenient single character
 marker, whose role will eventually become clear;
 the second argument, *\Aplace@*, *\AAplace@*, or *\Bplace@*,
will then do the main work.

As an example of how this is going to work out, let's consider  the
definition of *\Aplace*, which will actually come later:
**
\def\Aplace#1{\prevanish@
 \place@true \island@false
 #1%
 \place@ a\Aplace@
 \postvanish@}
**
where we begin with *\prevanish@* and end with
*\postvanish@* to make the *\Aplace* invisible.

The definition of *\place@* will be of the form
**
\def\place@#1#2{%
 \ifisland@
"2
  . . .
 \else
 \Err@{Whoa ... there's no \string\Figure, 
   \string\Table, etc., here}
 \fi
 \place@false}
**
to produce an error message if the  argument of *\Aplace*
didn't involves some sort of *\island*.

If we are in vertical mode, we will just call argument *#2*, but
in horizontal mode we call *\vadjust{#2}*. For example,
we will call
*\Aplace@* 
when we are using *\Aplace* in vertical mode and
**
\vadjust{\Aplace@}
**
in horizontal mode.

So far we haven't even mentioned argument *#1*. And, quite concomitantly,
we haven't mentioned what happens if we happen to be in a *\Par...\endPar*
In this case, we want to globally set the box `*\Parfigbox1*' to be\linebreak
*\box\islandbox@* if this is the first *\...place@*, or globally set the box
`*\Parfigbox2*' to *\box\islandbox@*
if it is the second, etc. We will keep track of which
*\...place@* we are at with the counter
*\Parcount@*, which was set to~*1*
by the *\Par*, and which will be increased with each *\...place*. So 
the box we want to be setting is
**
\csname Parfigbox\number\Parcount@\endsname
**
and to globally set this box to *\box\islandbox@* we need to {\litindent=0pt
say
**
\expandafter\expandafter\expandafter
 \global\expandafter\setbox
 \csname Parfigbox\number\Parcount@\endcsname=\box\islandbox@
**
 followed by}
**
\global\advance\Parcount@ by 1
** to keep the
*\Parcount@* counter accurate.

 And, finally, here is where argument
*#1* comes in.  When it comes time to properly tear apart *\box\Parbox@*,
we will need to know what sort of *\...place*'s produced the various
*\Parfigbox*'s.  We keep this information in the list *\Parlist@*,
which, for example, will be `*abaAb*' when our 
*\Par"allowbreak..."allowbreak\endPar* region contains the sequence
**
\Aplace
\Bplace
\Aplace
\AApalce
\Bplace
**
Each time we *\place@*, we will simply
add the marker, argument *#1*, at the right of *\Parlist@*, 
**
\xdef\Parlist@{\Parlist@#1}
**
The only other detail is that an error message should be produced if
more than five *\...place*'s appear in the *\Par...\endPar* region.
Here is the complete code:
\C**
\def\place@#1#2{%
 \ifisland@
  \ifhmode
"2
   \ifPar@
"2  
    \ifnum\Parcount@ > 5
     \Err@{Only 5 \string\place's allowed per 
      \string\Par...\noexpand\endPar paragraph}%
"2
    \else
     \expandafter\expandafter\expandafter
      \global\expandafter\setbox
       \csname Parfigbox\number\Parcount@\endcsname
        =\box\islandbox@
"2
     \global\advance\Parcount@ by 1 
     \xdef\Parlist@{\Parlist@#1}%
"2
    \fi
"2
   \else
    \vadjust{#2}%
   \fi
"2
  \else
   #2%
  \fi
"2
 \else
  \Err@{Whoa ... there's no \string\Figure, 
   \string\Table, etc., here}%
 \fi
 \place@false}
**
 
\section{\CS{Aplace} and \CS{AAplace}\label{AandAA}}
As we have already indicated, *\Aplace* is defined directly in terms of
*\place@*,
\C**
\long\def\Aplace#1{\prevanish@ \place@true \island@false
 #1%
 \place@ a\Aplace@
 \postvanish@}
**
so that it calls *\Aplace@*. The *\long* is needed since *#1* can contain
a *\caption* with blank lines.

The definition of *\Aplace@* will then involve most of the preliminary 
definition of *\Aplace* on page~\ref{APLACE}:
**
 \dimen@=\ht\islandbox@
 \advance\dimen@ by \abovebotfigskip
 \ht\islandbox@=\dimen@
"2
 \advance\dimen@ by \dp\islandbox@
 \storedim@
"2
 \ifnum\topinscount@ > 1 \else \advancedimtopins@ \fi
"2
 \insert\topins{\penalty0 \splittopskip=0pt
  \floatingpenalty=0
  \box\islandbox@}
 \global\advance\topinscount@ by 1
**


But *Aplace@* is going to be more complicated, for several reasons.
First of all, we are going to define *\AAplace* indirectly in terms
of *\Aplace@* by using a flag *\ifAA@*:
\C**
\long\def\AAplace#1{\prevanish@ \place@true \island@false
 #1%
 \place@ A\AAplace@
 \postvanish@}
"slip
\newif\ifAA@
"slip
\def\AAplace@{\AA@true\Aplace@\AA@false}
**
Even if we weren't going to use this approach, we would still
 need  a way of knowing whether a box in the
*\topins* insertion class was produced with *\Aplace* or *\Bplace* on
the one hand, or by *\AAplace* on the other hand.  We will keep this
information in a  list *\AAlist@*, initially defined to be empty,
with *0*~ representing the *\Aplace* or *\Bplace* case, and
*1*~representing  the *\AAplace* case. When *\ifAA@* is true, so that
we considering an *\AAplace*, we will add~*1* to the end of this list,
otherwise we will add~*0*. Moreover, in the *\AAplace* case,
 we always want to
call the *\advancedimtopins@* routine, no matter what value
*\topinscount@* has, since *\AAplace*'s are supposed to allow any number
of *\island*'s per page.

Finally, we want the definition of *\Aplace@* to begin with an *\allowbreak*,
because this may help \tex\ check whether the insertion fits. 

\small Reason:
When a *\vadjust{\Aplace@}* occurs within a paragraph, the main vertical
list will have something like
\setbox0\hbox{*\hbox{*line {\it L}$_{\text1}$ of text*}*}
\setbox1\hbox{*\hbox{*line {\it L}$_{\text2}$ of text*}*}
\setbox2\hbox{*\baselineskip* glue}
**
"box0
\Aplace@
"box2
"box1
**
Suppose that the line {\it L}$_{\text1}$ won't fit on the page, so that \tex\
will break the page before this line, which will be at, or near, the top of
the next page.  \tex\ computes the page total {\it t\/} at line
{\it L}$_{\text1}$ {\it after\/} a penalty or glue that follows this line
({\it The \tex book}, page~133, lines~17@--18).  Consequently, if the
*\Aplace@* contains no penalty or glue, \tex\ will read the *\Aplace@*
before it knows that line {\it L}$_{\text1}$ must go on the next page;
thus, it will conclude that the insertion doesn't fit (near the bottom of
the current page), instead of concluding that it does fit (near the
top of the next page).  The *\allowbreak* causes \tex\ to compute the page
total {\it t\/} before it sees the *\Aplace@*, so that it will realize in
time that the line doesn't fit. (The procedure isn't foolproof, however; 
even if line {\it L}$_{\text1}$ does fit, \tex\ may end up breaking before
this line if a break point with smaller cost occurred earlier).
\endsmall

The full definition of *\Aplace@* is:
\C**
\let\AAlist@=\empty
"slip
\def\Aplace@{\allowbreak
"2
 \dimen@=\ht\islandbox@
 \advance\dimen@ by \abovebotfigskip
 \ht\islandbox@=\dimen@
"2
 \advance\dimen@ by \dp\islandbox@
 \storedim@
"2
 \ifAA@
  \xdef\AAlist@{\AAlist@1}%
  \advancedimtopins@
"2
 \else
  \xdef\AAlist@{\AAlist@0}%
  \ifnum\topinscount@>1 \else \advancedimtopins@ \fi
 \fi
"2
 \insert\topins{\penalty0 \splittopskip=0pt
  \floatingpenalty=0
  \box\islandbox@}%
 \global\advance\topinscount@ by 1 }
**

\section{\CS{Bplace}\label{BPLACE}}
 The definition of *\Bplace* is analogous to that for
*\Aplace*:
\C**
\long\def\Bplace#1{\prevanish@ \place@true \island@false
 #1%
 \place@ b\Bplace@
 \postvanish@}
**
with all the work going into the definition of *\Bplace@*.

A *\Bplace* is supposed to force an *\island* to the bottom of the
page if it would normally go at the top of the current page.  In other words
**
\ifnum\topinscount@=0
**
we need to force the *\island* to the bottom of the page.
To do this, we will basically first 
*\Aplace* an island consisting of an empty box
**
\vbox to -\belowtopfigskip{}
**
of negative height *-\belowtopfigskip*,
so that 
 when this island is followed by *\vskip\belowtopfigskip* we will be back at
the top of the page. We actually want to our island to be a box of the form
**
\vbox{\vbox to -\belowtopfigskip{}}
**
so that it can be taken apart, like any other 
*\box\islandbox@*, with our *\unvbox*'ing mechanism,
so we start with
**
\setbox0=\vbox{\vbox to -\belowtopfigskip{}}
**
The next steps,
**
\dimen@=\ht0
\advance\dimen@ by \abovebotfigskip
**
set *\dimen@* to $\hbox{*\abovebotfigskip*}-\hbox{*\belowtopfgiskip*}$, and
are thus equivalent to
\setbox0\hbox{(c.f\. page \ref{EXTRAS22})}
**
\dimen@=-\skip\topins  "box0
**
after which we want to set
**
\ht0=\dimen@
** 
and then
**
\storedim@
\advancedimtopins@
\insert\topins{\box0}
\global\advance\topinscount@ by 1
**
as well as 
**
\xdef\AAlist@{\AAlist@0}
**

This should  then be followed by the instructions for *\Aplace*'ing the
\linebreak
*\box\islandbox@* that we want to force to the bottom:
\C**
\def\Bplace@{\allowbreak
 \ifnum\topinscount@=0
  \setbox0=\vbox{\vbox to -\belowtopfigskip{}}%
"2
  \dimen@=-\skip\topins
  \ht0 =\dimen@
  \storedim@
"2
  \advancedimtopins@
"2
  \insert\topins{\box0}%
  \global\advance\topinscount@ by 1
  \xdef\AAlist@{\AAlist@0}%
 \fi
"2
 \dimen@=\ht\islandbox@
 \advance\dimen@ by \abovebotfigskip
 \ht\islandbox@=\dimen@
"2
 \advance\dimen@ by \dp\islandbox@
 \storedim@
"2
 \xdef\AAlist@{\AAlist@0}%
"2
 \ifnum\topinscount@>1 \else \advancedimtopins@ \fi
"2
 \insert\topins{\penalty0 \splittopskip=0pt 
  \floatingpenalty=0
  \box\islandbox@}%
 \global\advance\topinscount@ by 1 }
**

\section{Changing \CS{pagecontents}\label{CPCT}}Our
 definition of *\Bplace* forces the first
change in our preliminary definition of *\pagecontents* (page~\ref{PAGECT}).
Recall that we first
**
\setbox\topins=\vbox{\unvbox\topins
 \global\setbox1=\lastbox}
**
so that *\box1* now contains the material we want to put on top, and then
took *\box1* apart with
**
\setbox0=\vbox{\unvbox1   "8BREAKISLAND"8
 \global\setbox1=\lastbox
"2
 \global\skipi@=\lastskip
 \unskip
 \global\setbox3=\lastbox}
**
In the case where *\box1* is
**
\vbox{\vbox to -\belowtopfigskip{}}
**
the new
*\box1* will be *\vbox to -\belowtopfigksip{}*, while *\skipi@* will be ~*0pt*
and *\box3* will be empty (compare the small print remark on
page~\ref{NOCAP}). 
 The problem now is that when we add the combination
**
\centerline{\box3}
\nointerlineskip
\vskip\skipi@
\centerline{\box1}
**
the last *\hbox*,
\setbox0\hbox{$=(\,\hbox{*\hbox to\hsize{...}*}\,)$}
**
\centerline{\box1}"box0
**
 will not have the negative height *-\belowtopfigskip*
that we want it to have:
 an *\hbox* never has negative height or depth ({\it The
\tex book}, page~77). So we must change this to
**
\centerline{\box3}  "8PRINTISLAND"8
\nointerlineskip
\vskip\skipi@
\ifdim\ht1 < 0pt \box1 \else \centerline{\box1}\fi
**

\section{\CS{breakisland\@} and \CS{printisland\@}}
The construction by which we just took apart *\box1*
 will appear several times, so we introduce the abbreviation
\C**
\def\breakisland@{\global\setbox1=\lastbox
 \global\skipi@=\lastskip
 \unskip
 \global\setbox3=\lastbox}%
**

Similarly, for the combination that puts the *\island* back on the page
we introduce the abbreviation
\C**
\def\printisland@{\centerline{\box3}%
 \nobreak
 \nointerlineskip
 \vskip\skipi@
 \ifdim\ht1 < 0pt \box1 \else \centerline{\box1}\fi}
**
Of course, the final *\ifdim...\fi* clause will normally be equivalent
 to *\centerline{\box1}*, and will be operative only when our macros
have created a *\box1* of negative height.
  Similarly, although
the added *\nobreak* will sometimes be needed (page~\ref{NIREQ}),
 at other times it will 
be superfluous.

\small For other styles, which treat *\island*'s differently, a completely
different\linebreak
 *\printisland@* routine might be in order; in such cases *\endisland* may
combine *\box\islandbox@* and *\box\Captionbox@* in an entirely different
way.
\endsmall

\section{\CS{bottomfigs\@}}
The possibility of *\AAplace*'s, and thus
more than two *\island*'s per page, forces us to change the preliminary
version of *\bottomfigs@* (page~\ref{BFIGS}) to a loop. We also use the
newly defined routines
*\breakisland@* and *\printisland@* in the definition.
\C**
\def\bottomfigs@{%
 \count@=1
"2
 \loop
  \ifnum\count@ < \flipcount@
  \nointerlineskip
  \vskip\abovebotfigskip
"2
  \setbox\topins=\vbox{\unvbox\topins\setbox0=\lastbox
   \unvbox0 
   \breakisland@}%
  \printisland@
"2
  \advance\count@ by 1 
  \repeat}
**
 As we will see
later (page~\ref{NEGB}), there may be occasions during the use
of this *\bottomfigs@*
routine when the *\box1* 
in the *\printisland@* routine
has negative height.\pagelabel{USENEGB}


\section{\CS{resetdimtopins\@}\label{RSDTNS}} 
We also have to change the definition of the routine
*\resetdimtopins@*.
Recall that at the time *\resetdimtopins@* is called, *\box\topinsdims@*
will be a *\vbox* of the form
\setbox1\hbox{\<dimen$_{\text{1}}$\>}
\setbox2\hbox{\<dimen$_{\text{2}}$\>}
\setbox3\hbox{\<dimen$_{\text{3}}$\>}
**
. . . 
\hbox to "box3{}
\hbox to "box2{}
\hbox to "box1{}
**
where \<dimen$_{\text{1}}$\> is the width of the first box that was still
in the *\topins* insertion class just before this page was made, 
\<dimen$_{\text 2}$\> is the width of the second such box, etc.  Of these
boxes in the *\topins* insertion class, *\flipcount@* actually appeared in
*\box\topins*, and were thus put on the page; the first thing we do is to
 diminish *\topinscount@* by *\flipcount@*, so that *\topinscount@* is
then
the number of boxes still in the insertion class.

At this time, the list *\AAlist@* (of *0*'s and *1*'s) will have as many
members as *\box\topinsdims@*.
As we perform the next step,
**
\global\setbox\topinsdims@=\vbox{%
 \unvbox\topinsdims@
 \count@=0
 \loop
  \ifnum\count@ < \flipcount@ \setbox0=\lastbox
   \advance\count@ by 1
 \repeat
**
which removes the bottom *\flipcount@* boxes from *\box\topinsdims@*,
 we are also going to want to remove the first *\flipcount@* members from
(the left end of) *\AAlist@*.  To do this, we use
**
\global\setbox\topinsdims@=\vbox{%
 \unvbox\topinsdims@
"2
 \count@=0
 "9\def\next@##1##2\next@{\gdef\AAlist@{##2}}"9
"2
 \loop
  \ifnum\count@ < \flipcount@ \setbox0=\lastbox
  "9\expandafter\next@\AAlist@\next@"9
   \advance\count@ by 1
  \repeat
**

The next *\loop* in the definition, 
**
\loop
 \ifnum\count@ < 2
 \setbox0=\lastbox
 \advance\dimen@ by \wd0
 \setbox2=\vbox{\box0 \unvbox2}
 \advance\count@ by 1
\repeat
**
requires more modifications. After the second iteration of the *\loop*,
we want to continue as long as the boxes we encounter correspond to
*\AAplace*'d material. To determine whether that is the case, we 
**
\edef\nextiii@{\AAlist@}
\def\next@##1##2\next@{\def\nextii@{##1}\def\nextiii@{##2}}
**
so that *\expandafter\next@\nextiii@\next* defines *\nextii@* to be
the next element of *\AAlist@*, and  removes it from the copy *\nextiii@*
of *\AAlist@* (we use a copy because we don't want these
elements to be removed
 once the *\vbox* is finished).

Our *\loop* will iterate at least two times and at
most *\topinscount@* times. For values of *\count@* in between,
we continue the iteration only when *\nextii@* is~*1*:
**
\loop
 \test@false
 \ifnum\count@ < \topinscount@
  \expandafter\next@\nextiii@\next@
"2
  \ifnum\count@ < 2
   \test@true
"2
  \else
   \if\nextii@ 1\test@true\fi
  \fi
 \fi
"2
 \iftest@
  \setbox0=\lastbox
  \advance\dimen@ by \wd0
  \setbox2=\vbox{\box0 \unvbox2}%
  \advance\count@ by 1
 \repeat
**
	
Thus, our whole (and final) definition is:
\C**
\def\resetdimtopins@{%
 \global\advance\topinscount@ by -\flipcount@
"2
 \global\setbox\topinsdims@=\vbox
  {\unvbox\topinsdims@
"2
   \count@=0
   \def\next@##1##2\next@{\gdef\AAlist@{##2}}%
"2
   \loop
    \ifnum\count@ < \flipcount@ \setbox0=\lastbox
    \expandafter\next@\AAlist@\next@
    \advance\count@ by 1
    \repeat
"2
   \dimen@=0pt
   \count@=0
"2
   \setbox2=\vbox{}%
   \edef\nextiii@{\AAlist@}%
   \def\next@##1##2\next@{\def\nextii@{##1}%
    	 \def\nextiii@{##2}}%
"2
   \loop
    \test@false
"2
    \ifnum\count@ < \topinscount@
     \expandafter\next@\nextiii@\next@
"2
     \ifnum\count@ < 2
      \test@true
     \else
      \if\nextii@ 1\test@true\fi
     \fi
    \fi
"2
    \iftest@
     \setbox0=\lastbox
     \advance\dimen@ by \wd0
     \setbox2=\vbox{\box0 \unvbox2}%
     \advance\count@ by 1
    \repeat
"2
    \unvbox2
    \global\dimen\topins=\dimen@}}
**


\chapter \CS{Cplace}, \CS{Mplace}, and \CS{MXplace}\endchapter
Next we consider the variants *\Cplace*, *\Mplace*, and *\MXplace*, which
must  be used  between paragraphs, or in the special 
 *\Par"allowbreak..."allowbreak\endPar* construction.

\section{\CS{Place\@}\label{PLACE}}
 Just as *\Aplace*, *\AAplace*, and *\Bplace* are
defined in terms of *\place@*, the *\Cplace*, *\Mplace*, *\MXplace*
constructions are defined in terms of *\Place@*. This is similar to
*\place@*, except that 
(1)~in horizontal mode 
if we are not in a *\Par"allowbreak..."allowbreak\endPar* region, we will
give an error message rather than using a *\vadjust*, and (2)~if we are
in a *\Par"allowbreak..."allowbreak\endPar* region we will
add a *\vadjust{\break}*:
\C**
\def\Place@#1#2{%
 \ifisland@
"2
  \ifhmode
"2
  \ifPar@
   \ifnum\Parcount@ > 5
     \Err@{Only 5 \string\place's allowed per 
       \string\Par...\noexpand\endPar paragraph}%
"2
   \else
    \expandafter\expandafter\expandafter
     \global\expandafter\setbox
     \csname Parfigbox\number\Parcount@\endcsname
     =\box\islandbox@
"2
    \global\advance\Parcount@ by 1 
"2
    \xdef\Parlist@{\Parlist@#1}%
    \vadjust{\break}%
"2
   \fi
"2
  \else
   \Err@{\noexpand#2allowed only in a 
    \string\Par...\noexpand\endPar paragraph}%
  \fi
"2  
  \else
   #2%
  \fi
"2
 \else
  \Err@{Whoa ... there's no \string\Figure, \string\Table,
   etc., here}%
 \fi
 \place@false}
**
Note that the *\vadjust{\break}*
occurs 
within the *\box\Parbox@* that we are setting;
it will be used (in section~\Sref{ENDPAR}) when we pull the
box apart.

\section{\CS{Cplace\@}}We first declare a new flag and a new \<dimen\>
register: 
\C**
\newif\ifC@
\newdimen\Cdim@
**
The definition of *\Cplace* is analogous to all the
previous *\...place*'s,
\C**
\long\def\Cplace#1{\prevanish@ \place@true \island@false
 #1%
 \Place@ c\Cplace@
 \postvanish@}
**
leaving all the work to *\Cplace@*.

*\Cplace@* basically just calls *\Aplace@*, except that when *\topinscount@*
is ~*0*, so that there are no insertions waiting to go on the page, it sets
the flag *\ifC@* to be true, and the \<dimen\> *\Cdim@* to *\pagetotal*; this
information will then be used by the *\output* routine.
\C**
\def\Cplace@{\allowbreak
 \ifnum\topinscount@ > 0
 \else
  \global\C@true
  \global\Cdim@=\pagetotal
 \fi
 \Aplace@}
**
Here we start with *\allowbreak*, even though this occurs in the *\Aplace@*,
because it might give \tex\ the opportunity to call the *\output* routine,
which will reset *\topinscount@*.

\section{\CS{Mplace\@} and \CS{MXplace\@}} 
The 
*\Mplace* and *\MXplace* constructions are going to be defined
together, much like *\Aplace* and *\AAplace*. First we define
\C**
\long\def\Mplace#1{\prevanish@ \place@true \island@false
 #1%
 \Place@ m\Mplace@
 \postvanish@}
**
so that the work goes into defining *\Mplace@*.

Similarly, we define
\C**
\long\def\MXplace#1{\prevanish@ \place@true \island@false
 #1%
 \Place@ M\MXplace@
 \postvanish@}
**
where we define *\MXplace@* in terms of *\Mplace@* and a flag:
\C**
\newif\ifMX@
\def\MXplace@{\MX@true\Mplace@\MX@false}
**

The definition of *\Mplace@* begins with *\allowbreak*,
**
\def\Mplace@{\allowbreak . . .
**
just as with other *\...place*'s. Then, however, it is quite different, 
because we must calculate whether or not *\box\islandbox@* 
will fit on the current page, together with *\abovebotfigskip* glue
above it (there is no need to consider the glue below the box, since it is
allowed to disappear at a page break). Actually,
*\abovebotfigskip* is merely supposed to be the minimum amount of glue
before the box: if *\lastskip* is less than *\abovebotfigskip*, then
we will *\unskip* before adding this glue, and if *\lastskip* is
equal or greater to *\abovebotfigskip*, we will do nothing. Moreover,
this glue will disappear if there is nothing else on the current page.

We begin with
**
\dimen@=\ht\islandbox@
\advance\dimen@ by \dp\islandbox@
\ifdim\pagetotal=0pt
\else
 \ifdim \lastskip < \abovebotfigskip
  \advance\dimen@ by \abovebotfigskip
  \advance\dimen@ by -\lastskip
 \fi
\fi
**
so that *\dimen@* is the amount of space required for the box.

Then we
**
\advance\dimen@ by \pagetotal
**
and use the test
**
\ifdim\dimen@ > \pagegoal
**

If this test is true, then there is {\it not\/} enough space for the
box, so we use
**
\Aplace@
**
to convert the *\Mplace* to an *\Aplace*.

On the other hand, when the test
**
\ifdim\dimen@ > \pagegoal
**
is false, so that *\box\islandbox@* {\it does\/} fit,
we basically want to treat the *\Mplace* like a *\place*, except for
adding the requisite space:
**
\nointerlineskip
\ifdim\lastskip < \abovebotfigskip
 \removelastskip
 \vskip\abovebotfigskip
\fi
\setbox0=\vbox{\unvbox\islandbox@
 \breakisland@}
\printisland@
**
Unlike the situation for *\bottomfigs@*, which simply adds things
to the\linebreak *\vbox* created by *\pagebody*,
the *\nobreak* appearing in the definition of\linebreak
 *\printisland@* is required here,\pagelabel{NIREQ}
when we are simply contributing things to the main vertical list. 

Now we have to make sure
that no later *\Aplace* will end up at the top of this page, and hence out of
order. We handle this in much the same way as *\Bplace*, by essentially
*\Aplace*'ing a box of height *-\belowtopfigskip* if
*\topinscount@* is~*0*:
**
\ifnum\topinscount@=0
 \setbox0=\vbox{\vbox to-\belowtopfigskip{}}
 \dimen@ = -\skip\topins
 \ht0 = \dimen@
 \storedim@
 \advancedimtopins@
 \insert\topins{\box0}
 \global\advance\topinscount@ by 1
 \xdef\AAlist@{\AAlist0}
\fi
**

Finally, suppose that *\ifMX@* is true. 
Then  we are considering an *\MXplace*, which means that we want to
prohibit an *\island* from appearing at the bottom of the page.
To do this, we essentially want to *\Aplace* a box of height
*-\abovebotfigskip*  if *\topinscount@* is~*1*.
(This box of negative height will be contributed to the page by
*\bottomfigs@*,\pagelabel{NEGB} a circumstance alluded to on
page~\ref{USENEGB}.)  

So we start with
**
\setbox0=\vbox{\vbox to-\abovebotfigskip{}}
**
In this case, making the height of *\box0* bigger by *\abovebotfigskip*
is just the same as making it *0pt*, and we set *\dimen@* to this value
before the *\storedim@*:
**
\ht0=0pt
\dimen@=0pt
\storedim@
\advancedimtopins@
\insert\topins{\box0}
\global\advance\topinscount@ by 1
\xdef\AAlist@{\AAlist@0}
**

And after all that, we add 
**
\nointerlineskip
\vskip\belowtopfigskip
**
below our *\Mplace*'d *\island*:
\C**
\def\Mplace@{\allowbreak
"2
 \dimen@=\ht\islandbox@
 \advance\dimen@ by \dp\islandbox@
"2
 \ifdim\pagetotal=0pt \else
  \ifdim\lastskip < \abovebotfigskip
   \advance\dimen@ by \abovebotfigskip
   \advance\dimen@ by -\lastskip
  \fi
 \fi
"2
 \advance\dimen@ by \pagetotal
"2
 \ifdim\dimen@ > \pagegoal
  \Aplace@
"2
 \else
  \nointerlineskip
  \ifdim\lastskip < \abovebotfigskip
   \removelastskip
   \vskip\abovebotfigskip
  \fi
"2
  \setbox0=\vbox{\unvbox\islandbox@
   \breakisland@}%
"2
  \printisland@
"2
  \ifnum\topinscount@=0
   \setbox0=\vbox{\vbox to-\belowtopfigskip{}}%
"2
   \dimen@=-\skip\topins
   \ht0=\dimen@
"2
   \storedim@
   \advancedimtopins@
"2
   \insert\topins{\box0}%
   \global\advance\topinscount@ by 1
   \xdef\AAlist@{\AAlist@0}%
  \fi
"2
  \ifMX@
   \ifnum\topinscount@=1
"2
    \setbox0=\vbox{\vbox to-\abovebotfigskip{}}%
    \ht0=0pt
"2
    \dimen@=0pt
    \storedim@
"2
    \advancedimtopins@
    \insert\topins{\box0}%
    \global\advance\topinscount@ by 1
    \xdef\AAlist@{\AAlist@0}%
   \fi
  \fi  
  \nointerlineskip
  \vskip\belowtopfigskip
 \fi}
**



\section{\CS{endPar}\label{ENDPAR}}
An *\Aplace*, *\AAplace*, or *\Bplace*  within a
*\Par"allowbreak..."allowbreak\endPar* region simply stores
the corresponding *\box\islandbox@* in 
some
`*\Parfigbox*\,{\it n}' and the letter *a*, *A*, or *b* in *\Parlist@*
(section~\Sref{place}), while a *\Cplace*, *\Mplace*, or *\MXplace*
stores the  *\box\islandbox@*, and the letter *c*, *m* or
*M*, and
also adds a *\vadjust{\break}* within the *\box\Parbox@* that
we are setting (section~\Sref{PLACE}). 

When we get to the *\endPar* that matches the *\Par*, we will
 first
supply the *\egroup* that ends the setting of *\box\Parbox@*,
**
\def\endPar{\egroup . . .
**
The remaining task is to take the material in *\box\Parbox@* and restructure
it as if all the *\Cplace*'s, *\Mplace*'s and *\MXplace*'s actually
occurred between paragraphs.  The idea is to use *\vsplit* to take
*\box\Parbox@* apart, splitting it after the lines where *\vadjust{\break}*'s
were added at these *\...place*'s, and treat the pieces as separate
paragraphs.  The pieces into which we split *\box\Parbox* will be
stored in new boxes that we declare:
\C**
\expandafter\newbox\csname Parbox1\endcsname
\expandafter\newbox\csname Parbox2\endcsname
\expandafter\newbox\csname Parbox3\endcsname
\expandafter\newbox\csname Parbox4\endcsname
\expandafter\newbox\csname Parbox5\endcsname
**

To split *\box\Parbox@*, we use a *\loop*,
**
\count@=1
\loop
 \ifnum\count@ < \Parcount@
**

This *\loop* will be enclosed in a group where we have set
**
\vfuzz=\maxdimen \vbadness=10000 
**
so that *Overfull* and *Underfull* *\vbox*'es will not be reported. In this
group we
will also
set *\splitmaxdepth* to *\maxdimen*, since we already
know where our boxes
will split, and don't want to impose any extraneous
constraints on their
 depths, and we will
set *\splittopskip=\ht\strutbox*, so that in essence a strut will have been
added at the beginning of each box.\pagelabel{VFUZZ}

Before beginning the *\loop*, we will
**
\setbox0=\vsplit\Parbox@ to\ht\Parbox@
**
Because of the *\break* at the beginning of *\box\Parbox@*
(page~\ref{NBREAK}), this simply splits off the *\break* and the following
*\parskip* glue  into *\box0* (which will not be used),
so that the remaining *\box\Parbox@* doesn't begin with extraneous glue.

Now we will continue to 
**
\vsplit\Parbox@ to \ht\Parbox@
**
storing the results in `*\Parbox1*', `*\Parbox2*', \dots.
The *\vadjust{\break}*'s that we inserted by *\Cplace*, *\Mplace*, or
*\MXplace* will force these new (\,*Underfull*) boxes to end after the line
in which this *\...place*'s appeared.


  At the same time,
we want to store the depth of `*\Parbox1*' in the \<dimen\> register
`*\Parprev2*', the depth of `*\Parbox2*' in `*\Parprev3*', \dots\ (recall,
page~\ref{PARPREV}, that `*\Parprev1*' is used to store the depth of the
line before the *\Par* begins):
**
\loop
 \ifnum\count@ < \Parcount@
 \expandafter\expandafter\expandafter\global
  \expandafter\setbox
   \csname Parbox\number\count@\endcsname
    =\vsplit\Parbox@ to \ht\Parbox@
 \count@@=\count@ \advance\count@@ by 1
 \global\csname Parprev\number\count@@\endcsname
  =\dp\csname Parbox\number\count@\endcsname
 \advance\count@ by 1
 \repeat
**
When this *\loop* is over, *\box\Parbox@* will contain the text after the
line containing the
last *\...place* (or will be void if there was no such text). Even though
we need to *\global\setbox*`*\Parbox*\,{\it n}', the *\vsplit* operation
defines the remainder of the split
*\box\Parbox@* globally,
so the final *\box\Parbox@* will persist after the end of the
\pagelabel{PERSIST} 
group.
\footnote{This
 does not seem to be stated explicitly anywhere in {\it The \tex book},
though page~259 deals with related matters.}


Having finished with this, we now insert the *\parskip* glue, and get ready
for another *\loop* to put things back:
**
\vskip\parskip
\count@=1
**

For this loop we
{\advance\litindent-20pt first define a routine
**
\def\nextv@##1##2\nextv@{\def\next@{##1}\gdef\Parlist@{##2}}
**
that} extracts the first letter from *\Parlist@* and stores it in *\next@*.
\footnote{We chose *\nextv@*, which appears nowhere else in \lamstex\ except
in the definition of *\root*,
to make certain that this will not be redefined by any of the routines to
follow.}

Our *\loop* has several stages:
\list
\item We begin 
**
\loop
 \ifnum\count@ < \Parcount@
  \dimen@=\csname Parprev\number\count@\endcsname
  \advance\dimen@ by \ht\strutbox
  \ifdim\dimen@ < \baselineskip
   \advance\dimen@ by -\baselineskip \vskip -\dimen@
  \else
   \vskip\lineskip
  \fi
**	
Thus, we first
set *\dimen@* to be the depth of the previous line plus the height
of a strut, which will be the height of the first line of the next piece of
text (unless this contains some extra tall symbol). If *\dimen@* is less than
*\baselineskip*, then we want to insert
\setbox0\hbox{*\baselineskip*}
\setbox1\hbox{*\dimen@*}
$$
\box0-\box1
$$
extra glue, or equivalently,
\setbox0\hbox{*\baselineskip*}
\setbox1\hbox{*\dimen@*}
$$
-(\box1-\box0)
$$
hence the code
**
\advance\dimen@ by -\baselineskip \vskip -\dimen@
**
Otherwise, the two lines are already too far apart for *\baselineskip* glue
to be used, so we just add the *\lineskip* glue.

\item
Next we
**
\unvbox\csname Parbox\number\count@\endcsname
**
to put the next part of the text on the vertical list; recall 
(see the footnote on page~\ref{NEXG}), that no extra space is added before
or after this material, and that its depth does not influence *\prevdepth*,
which is why we have stored the various depths in registers, and have
added the extra space between these various pieces by hand.\pagelabel{USEFN}

\item The next step is to deal with the corresponding *\...place*'d
material, stored in 
**
\box\csname Parfigbox\number\count@\endcsname
**
We first move this material into *\box\islandbox@*,
**
\global\setbox\islandbox@
 =\box\csname Parfigbox\number\count@\endcsname
**
and then use 
**
\expandafter\nextv@\Parlist@\nextv@
**
so that *\next@* will have the value 
\setbox6\hbox{\ \ if the material was *\...place*'d with\ \ }
\Math
\vbox{\halign{#\hfil&\copy6 #\hfil\cr
*a*&*\Aplace*\cr
*A*&*\AAplace*\cr
*b*&*\Bplace*\cr
*c*&*\Cplace*\cr
*m*&*\mplace*\cr
*M*&*\Mplace*\cr}}\endMath
Then we simply pretend that we are performing the corresponding *\...place*
on *\box\islandbox@* at this point (where we are in vertical mode):
**
\if a\next@\Aplace@\else
\if A\next@\AAplace@\else
\if b\next@\Bplace@\else
\if c\next@\Cplace@\else
\if m\next@\Mplace@\else
\if M\next@\MXplace@\fi\fi\fi\fi\fi\fi
**
 After all this is done we can reset *\ifPar@* to be false.

\item
If the *\Par"allowbreak..."allowbreak\endPar* region happened to end with
some sort of *\...place*, our final
*\box\Parbox@* will be void, and we want to set
**
\prevdepth=\csname Parpev\number\count@\endcsname
**
so that *\prevdepth* has the value for the last line of the last piece of
text that was *\unvbox*'ed.

Otherwise, we first have to add glue before this final piece, as before,
**
\dimen@=\csname Parprev\number\count@\endcsname
\advance\dimen@ by \ht\strutbox
\ifdim\dimen@ < \baselineskip
 \advance\dimen@ by -\baselineskip \vskip -\dimen@
\else
 \vskip\lineskip
\fi
** 
and then store the depth of this remaining *\box\Parbox@* before
*\unvbox*'ing it, so that we can finally set *\prevdepth* to that depth:
**
\dimen@=\dp\Parbox@
\unvbox\Parbox@
\prevdepth=\dimen@
**
\endlist

Our whole definition reads:
\C**
\def\endPar{\egroup
"2
 \count@=1
"2
 {\vbadness=10000 \vfuzz=\maxdimen
 \splitmaxdepth=\maxdimen \splittopskip=\ht\strutbox
"2
 \setbox0=\vsplit\Parbox@ to\ht\Parbox@
"2
 \loop
  \ifnum\count@ < \Parcount@
  \expandafter\expandafter\expandafter\global
   \expandafter\setbox
    \csname Parbox\number\count@\endcsname
    =\vsplit\Parbox@ to\ht\Parbox@
"2
  \count@@=\count@ \advance\count@@ by 1
  \global\csname Parprev\number\count@@\endcsname
   =\dp\csname Parbox\number\count@\endcsname
"2
  \advance\count@ by 1
  \repeat}%
"2
 \vskip\parskip
 \count@=1
"2
 \def\nextv@##1##2\nextv@{\def\next@{##1}%
  \gdef\Parlist@{##2}}%
 \loop
  \ifnum\count@ < \Parcount@
"2
   \dimen@=\csname Parprev\number\count@\endcsname
   \advance\dimen@ by \ht\strutbox
"2
   \ifdim\dimen@ < \baselineskip
    \advance\dimen@ by -\baselineskip \vskip -\dimen@
   \else
    \vskip\lineskip
   \fi
"2
   \unvbox\csname Parbox\number\count@\endcsname
"2  
   \global\setbox\islandbox@
    =\box\csname Parfigbox\number\count@\endcsname
   \expandafter\nextv@\Parlist@\nextv@
"2
   \if a\next@\Aplace@\else
   \if A\next@\AAplace@\else
"2
   \if b\next@\Bplace@\else
   \if c\next@\Cplace@\else
"2
   \if m\next@\Mplace@\else
   \if M\next@\MXplace@\fi\fi\fi\fi\fi\fi
"2
  \advance\count@ by 1
  \repeat
"2
 \global\Par@false
"2
 \ifvoid\Parbox@
  \prevdepth=\csname Parprev\number\count@\endcsname
"2
 \else
  \dimen@=\csname Parprev\number\count@\endcsname
  \advance\dimen@ by \ht\strutbox
"2
  \ifdim\dimen@ < \baselineskip
    \advance\dimen@ by -\baselineskip \vskip -\dimen@
"2
  \else
    \vskip\lineskip
  \fi
"2
  \dimen@=\dp\Parbox@
  \unvbox\Parbox@
  \prevdepth=\dimen@
 \fi}
**




\chapter The \CS{output} routine\\
 Ta-ran-ta-ra! Ta-ran-ta-ra! Ta-ran-ta-ra!\label{OUTPUT}\endchapter
\runningchapter{The \CS{output} routine}



The \lamstex\ default
*\output* routine mimics as closely as possible the *plain*
\tex\ *\output* routine, defined in terms of *\makeheadline*, *\pagebody*,
*\makefootline*, etc.


To begin with, we  redefine *\folio* to reflect \lamstex's
approach to page numbers (and numbering in general):
\C**
\def\folio{{\page@F
 \page@S{\page@P\pag@N{\number\page@C}\page@Q}}
**
Since we are not using negative values of *\pageno* to indicate
roman numerals,
we might as well also simplify the definition of *\advancepageno*:
\C**
\def\advancepageno{\global\advance\pageno by 1 }
**

\section{\CS{plainoutput}\label{SO}}
Since *plain* \tex\ sets *\output={\plainoutput}*, our new *\output* routine
will be specified by modifying *\plainoutput*, which is defined
 in *plain* \tex\ by
**
\def\plainoutput{\shipout\vbox{\makeheadline
 \pagebody\makefootline}
 \advancepagno
 \ifnum\outputpenalty > -20000 \else\dosupereject\fi}
** 

We will need a new flag
**
\newif\ifspecialsplit@
**
which should be set true when *\box\topins* is 
**
\vbox(0.0+0.0)x0.0
**
because of a split floating insertion (section~\Sref{FLOAT}). 
At the very beginning of the definition of *\plainoutput* (even before
the *\fliptopins@*), we will use the code
**
\specialsplit@false
 \ifvoid\topins\else\ifdim\ht\topins=0pt
  \specialsplit@true
 \fi\fi
**
to set *\ifspecialsplit@* to be true only if *\box\topins* has
height *0pt*, but isn't void (the latter test must be made explicitly because
a void *\box\topins* will also satisfy the
condition *\ifdim\ht\topins=0pt*), and thus
 precisely when (section~\Sref{FLOAT})
our *\box255* is too high by *-\skip\topins* ($={}$*3pt*), in which case
we will eventually have to prune down *\box255*. 

Remember that we are going to be using code like
**
\ifdim\ht255 < \minpagesize \else\unvbox255 \fi
**
so that we  are
not going to *\unvbox255* at all when the test 
\Math
\hbox{*\ht255*} < \hbox{*\minpagesize*}
\endMath
is true. But when *\ifspecialsplit@* is true, we really want the test
\Math
\hbox{*\ht255*} < \hbox{*\minpagesize*} - \hbox{*\skip\topins*}
\endMath

({\bf0})
To achieve this, we will simply use 
**
\specialsplit@false
 \ifvoid\topins\else\ifdim\ht\topins=0pt
  \specialsplit@true
  \advance\minpagesize by -\skip\topins
 \fi\fi
**
(*\minpagesize* will be restored to its usual value at the end of 
the *\output* routine, since
\tex\ implicitly encloses the *\output* routine within a group.)

After this step, we follow the procedure outlined on page~\ref{OUTLIST}:

\medskip

({\bf1})
We use *\fliptopins@*, to prepare
*\box\topins* for use by\linebreak *\pagecontents*, which
will take care of properly positioning any *\island*'s that have shown up in
*\box\topins*. 

({\bf2}) Instead of *plain* \tex's direct
*\shipout*,
we will 
declare a new box
**
\newbox\outbox@
**
and also
**
\let\shipout@=\shipout
**
and then
**
\setbox\outbox@=\vbox{\makeheadline\pagebody\makefootline}
{\noexpands@\let\style=\relax
\shipout@\box\outbox@}
**
The *\noexpands@* and *\let\style=\relax*
are necessary before the\linebreak
 *\shipout@* because various
*\write*'s in *\pagebody* will contain page numbering control sequences,
whose expansion we want to prohibit (compare pages~\ref{SUB1} and
\ref{SUB99}), and they might also contain *\style*
(pages~\ref{SUB11} and ~\ref{SUB111}). 

\small 
The only reason for this approach is that it
 makes the *\output*
routine easier to modify in certain ways.  For example, if we want
a  style file
that produces
``crop marks'' around the completed pages (as was done for the
\lamstex~Manual, and for this manual), instead of redefining *\plainoutput*,
we just have to define a suitable
routine
**
\def\crop#1{\vbox{ ... #1 ... }}
**
which puts crop marks around a box *#1*, and then 
**
\def\shipout@{\shipout\crop{\box\outbox@}}
**
\endsmall

({\bf3})--({\bf6}) Then come\pagelabel{PPUNV255}
**
\advancepageno
\resetdimtopins@
\ifvoid 255 \else \unvbox255 \penalty\outputpenalty
\ifnum\outputpenalty > -20000 \else \dosupereject \fi
**

The whole definition is:
\C**
\newif\ifspecialsplit@
\newbox\outbox@
\let\shipout@=\shipout
"slip
\def\plainoutput{\specialsplit@false  "8DEFPLOUT"8
 \ifvoid\topins\else
  \ifdim\ht\topins=0pt
   \specialsplit@true
   \advance\minpagesize by -\skip\topins
 \fi\fi
 \fliptopins@
 \setbox\outbox@=\vbox{\makeheadline
  \pagebody\makefootline}%
 {\noexpands@ \let\style=\relax
 \shipout@\box\outbox@}%
 \advancepageno
 \resetdimtopins@
 \ifvoid 255 \else \unvbox 255 \penalty\outputpenalty \fi
 \ifnum\outputpenalty > -20000 \else \dosupereject \fi}
**
Notice that the *\noexpands@...\shipout@* occurs after 
*\box\outbox@* is set, so any font control sequences in *\headline* or
*\footline* will not be *\relax* at that time. 
\footnote{This is a somewhat unnecessary
precaution,  since *\headline* and *\footline* normally contain things
like *\tenrm* or *\tenit*, rather than *\rm* or *\it*, which
may have different values if a different pointsize command
 is currently in effect; but *\tenpoint* or *\tenpoint\it* would
be equally valid.}
We also put the *\noexpands@...\shipout@*
inside a group.  In this
particular definition, that extra group is irrelevant, but it would be
important if the *\output* routine were modified to add additional material
at the top of the next page, before the *\unvbox255* material.
For example, in the index,  continuation lines
are added containing `*{\it continued\/}* (see page~\ref{CONLINES}),
 and we don't want *\it* to
be *\relax* when these lines are added.\pagelabel{SHIPOUTGROUP}




\section{\CS{pagebody}}
The default \lamstex\ style keeps *\makeheadline* and *\makefootline*
the same as in *plain*~
\tex@, and *\pagebody* is the same except that any index entries placed
in the *\margin@* insertion class, for proofing, are placed at the side:
\C**
\def\pagebody{\vbox to\vsize{\boxmaxdepth=\maxdepth
 \ifvoid\margin@
"2
 \else
"2
  \rlap{\kern\hsize\vbox to0pt{\kern4pt\box\margin@\vss}}%
 \fi
 \pagecontents}
**
The *\kern\hsize* moves the entries over to the right side of the page,
the *\rlap* allows them to stick into the right margin, the *\vbox to0pt*
allows them to be arbitrarily long, 
and the *\kern4pt*, chosen empirically,
starts the entries slightly below the top line, to look better.


\section{\CS{pagecontents}\label{PAGECT2}}
 The only thing left to define is *\pagecontents*,
for which we have given a preliminary definition on page~\ref{PAGECT},
with the modification of section~\Sref{CPCT}.

We will need one final flag
\C**
\newif\ifonlytop@
**
which will be set true when the only thing on the page is a figure on top.

The definition of *\pagecontents* begins
**
\def\pagecontents{\onlytop@false
 \ifdim\ht255 < \minpagesize
  \ifnum\flipcount@ < 2
   \ifvoid\footins
    \onlytop@true
 \fi\fi\fi
**
Thus, we set *\onlytop@true* only when three conditions all hold:
(1)~*\ht255* is less than *\minpagesize*, so that we will not 
*\unvbox255* after the top figure;
 (2)~*\flipcount@* is less than~*2*, so that there are
no figures to go after the one on top;
 (3)~*\box\footins* is void, so that there are
no footnotes to go after the figure on top either.


The main change in *\pagecontents* 
is that
 special work may be needed if *\flipcount@* has the
value~*1* and *\ifC@* is true, so that there is just one *\island* in
*\box\topins* and it was *\Cplace*'d; in this case, *\Cdim@* has the value
of *\pagetotal* at the time of the *\Cplace*, so that *\Cdim@* is the amount
of text preceding the *\Cplace*.  We will want
to change the placement of this *\island* from top to bottom if
 *\Cdim@* is greater than half 
*\ht255* (i.e., if the *\island* appears in the lower half of the page).
To test for this we use
**
\test@false
\ifC@
"2
 \ifnum\flipcount@=1
  \global\multiply\Cdim@ by 2
"2
  \ifdim\Cdim@ > \ht255
   \test@true
  \fi
 \fi
\fi
\global\C@false
**
(taking the opportunity to reset *\ifC@* as soon as the test has been made).


({\bf a}) When *\iftest@* is true, we basically 
want to put the *\island* below the rest of
the page instead of at the top,
**
\iftest@
 \unvbox255
 \setbox\topins=\vbox{\unvbox\topins
  \global\setbox0=\lastbox}
 \setbox0=\vbox{\unvbox0
  \breakisland@}
  \nointerlineskip
  \vskip\abovebotfigskip
  \printisland@
**

But this doesn't quite work, since there is really just enough space for
the
*\vskip\belowtopfigskip*, not for the *\vskip\abovebotfigskip* (which might 
differ considerably in some styles).

 So we will first 
set
**
\dimen@=\ht 255
\advance\dimen@ by \skip\topins
**
so that *\dimen@* is *\ht255* plus the difference in the space we are going
to add (page~\ref{EXTRAS22}), and then replace *\unvbox 255* with
**
\setbox1=\vsplit 255 to \dimen@
\unvbox1
**
(anything remaining in *\box255* will be put back on the main vertical list
later). During the
*\vsplit* we want to set *\vfuzz=\maxdimen*, *\vbadness=10000*,
*\splitmaxdeth=\maxdepth*, and
*\splittopskip=\topskip*, as in the definition of *\endPar*
(page~\ref{VFUZZ}): 
**
{\vfuzz=\maxdimen \vbadness=10000
 \splitmaxdepth=\maxdepth \splittopskip=\topskip
 \setbox1=\vsplit 255 to \dimen@
 \unvbox1}
**
The new value of *\box255* will persist after the end of the group
(see page~\ref{PERSIST}).


\small 
If *\skip\topins* is negative, i.e.,
if *\belowtopfigskip* is greater than\linebreak *\abovebotfigskip*, our
*\vsplit* simply gives the original *\box255*, and we just have to hope
that the glue can stretch enough to make up the difference.
Compare section~\Sref{255TOO}.
\endsmall

And then, having put the proper amount of *\box255* at the top of the page,
we add the *\island* in *\box\topins*, with the proper amount of
space above it:
**
\setbox\topins=\vbox{\unvbox\topins
 \global\setbox0=\lastbox}
\setbox0=\vbox{\unvbox0
 \breakisland@}
\nointerlineskip
\vskip\abovebotfigskip
\printisland@   
**

({\bf b})
When *\iftest@* is false (the usual case), we simply put the first *\island*
in *\box\topins*, if any, at the top,
**
\ifnum\flipcount@ > 0
 \setbox\topins=\vbox{\unvbox\topins
  \global\setbox0=\lastbox}%
 \setbox0=\vbox{\unvbox0
  \breakisland@}%
 \printisland@
**
Normally, this should be followed by *\belowtopfigskip*.  But we don't
want to do that if nothing else goes on the page,
 because the figure may be too large to allow *\belowtopfigskip*
glue below it. Instead we use
**
\ifonlytop@ 
 \kern-\prevdepth \vfill 
\else 
 \vskip\belowtopfigskip 
\fi
**
The  *\kern-\prevdepth* is inserted  for the following reason.\pagelabel{KMPR}
\footnote{Compare
the `*\ifr@ggedbottom\kern-\dimen@\vfil\fi*' in the *plain* \tex\ definition
of *\pagecontents* ({\it The \tex book}, page~364).}
We might have an island 
 whose height is less than or equal to *\vsize*, but
whose height plus
depth  exceeds *\vsize*.  Since *\pagecontents* will become
\setbox0\hbox{\<the top *\island*\>}
**
\vbox to\vsize{"box0 \vfill}
**
this will give an *Overfull \vbox* (without the *\vfill* we wouldn't have
this problem, because the depth of the *\island* would just become
the depth of the *\vbox to\vsize*). The `*\kern-\prevdepth*' eliminates
this extra depth, so that *\vfill* can safely be added.

Our preliminary definition of *\pagecontents* then had
**
\ifdim\ht255 < \minpagesize \vfill \else \unvbox255 \fi
**
but now we will have to prune down  *\box255* when *\ifspecialsplit@*
is true.
This is similar to the routine
used for a *\Cplace*:
**
\ifspecialsplit@                    "8DOSPECSPLIT"8
 {\vfuzz=\maxdimen \vbadness=10000
 \splitmaxdepth=\maxdepth \splittopskip=\topskip
 \dimen@ii=\ht255 \advance\dimen@ii by \skip\topins
 \setbox1=\vsplit255 to\dimen@ii
 \unvbox1}% 
\else
 \unvbox255
\fi
**

We might as well also replace the
**
\ifdim\ht255 < \minpagesize
 \vfill
**
with
**
\ifdim\ht255 < \minpagesize
 \ifonlytop@ \else \vfill \fi
**
so that a page containing a single large figure will have *\vfill* below
it rather than two *\vfill*'s (this just might make a difference if some one
were trying to reposition things).

Finally, having taken care of the text,
 we just have to add *\bottomfigs@*, and the footnote material, if
any: 
\C**
\def\pagecontents{\onlytop@false  "8FINALPC"8
 \ifdim\ht255 <\minpagesize
  \ifnum\flipcount@ < 2
   \ifvoid\footins
    \onlytop@true
 \fi\fi\fi
"2
 \test@false
"2
 \ifC@
  \ifnum\flipcount@=1
   \global\multiply\Cdim@ by 2
   \ifdim\Cdim@ > \ht255
    \test@true
   \fi
  \fi
 \fi
"2
 \global\C@false
"2
 \iftest@
  \dimen@=\ht255
  \advance\dimen@ by \skip\topins
"2
  {\vfuzz=\maxdimen \vbadness=10000
  \splitmaxdepth=\maxdepth \splittopskip=\topskip
  \setbox0=\vsplit255 to\dimen@
  \unvbox0}%
"2
  \global\setbox\topins=\vbox{\unvbox\topins
   \global\setbox1=\lastbox}%
  \setbox0=\vbox{\unvbox1
   \breakisland@}%
"2
  \nointerlineskip
  \vskip\abovebotfigskip
  \printisland@   
"2
 \else
  \ifnum\flipcount@ > 0
"2
   \global\setbox\topins=\vbox{\unvbox\topins
    \global\setbox1=\lastbox}%
   \setbox0=\vbox{\unvbox1
    \breakisland@}%
   \printisland@
"2
   \ifonlytop@ \kern-\prevdepth \vfil
    \else \vskip\belowtopfigskip \fi
  \fi  
 \fi
"2
 \ifdim\ht255 < \minpagesize
  \ifonlytop@ \else \vfill \fi
"2
 \else
"2
  \ifspecialsplit@
   {\vfuzz=\maxdimen \vbadness=10000
   \splitmaxdepth=\maxdepth \splittopskip=\topskip
   \dimen@ii=\ht255 \advance\dimen@ii by \skip\topins
   \setbox0=\vsplit255 to\dimen@ii
   \unvbox0}% 
"2
  \else
   \unvbox255
  \fi
 \fi
 \bottomfigs@
 \ifvoid\footins\else
  \vskip\skip\footins\footnoterule\unvbox\footins\fi}
**

\small When *\vskip\topins* is small we might elect simply to forget about
the flag\linebreak
*\ifspecialsplit@*, and always *\unvbox255* when its height
is greater than or equal to *\minpagesize*.
  Only very very rarely would we encounter difficulties, and these
could always be fixed by hand---after all, nothing is perfect (compare
section~\ref{FWARN}).
\endsmall

\nopunct\section{And we are done!\label{DONE}}This 
finishes off everything concerned with
the first part
 of the \lamstex~Manual, except for front and back matter, which are
dealt with in Part~\ref{FBM}@.  
Commutative diagrams  are dealt with in Volume~II@, but all that
material could just as well be considered as separate files that we could
*\input*. And all the material for tables,
except for a few things like *\paste* and *\measuretable* are actually 
in a separate file (except in \muttontex); these are also dealt with
in Volume~II@.
So let us now skip to the very end of the *lamstex.tex* file.

First, we introduce the more formal *\enddocument* as a synonym for *\bye*:
\C**
\let\enddocument=\bye
**

Then, since we have no *\new...* constructions to use, we restore
*\alloc@* to its original *plain* meaning (see page~\ref{NEWALLOC2}),
 so that any further uses of
the *\new...* constructions will write to the *.log* file:
\C**
\def\alloc@#1#2#3#4#5{\global\advance\count1#1by\@ne
 \ch@ck#1#4#2\allocationnumber=\count1#1
 \global#3#5=\allocationnumber
 \wlog{\string#5=\string#2\the\allocationnumber}}
**

And finally, we make *@* active:
\C**
\catcode`\@=\active
**

\sectiong{When \CS{box255} is too small\label{255TOO}}
At the end of section~\Sref{FLOAT}, we mentioned the fact that *\box255* will
be too small, rather than too big, when *\belowtopfigskip* is greater than
*\abovebotfigskip*, so the splitting maneuvers used in defining
*\pagecontents* won't do us any good.

Fortunately, that situation
is unlikely to occur, since good style design calls
for more space to be left above constructions than below them. (This holds for
headers also; they look better when the space above exceeds the space below,
something that more \tex\ style file designers should bear in mind.)

I don't see any easy way to deal with the problem of a style
that chooses  a value of *\belowtopfigskip* greater than
*\abovebotfigskip*. The best I can suggest in that case is the following.

First of all, *\Aplace* will also have to be disallowed within paragraphs
(except for special *\Par"allowbreak..."allowbreak\endPar* regions, which
reduce back to use between paragraphs).  Then, when we *\Aplace* an
*\island* we would make a special check
 if *\topinscount@* is ~*0* (so that this is the first *\island* to be 
considered for the page).
In this case,  we would use the same
calculations as for *\Mplace*, to see if the *\island* will fit.  If it
does fit,
we would simply insert it (essentially converting the *\Aplace* to an
*\Mplace*).  If it doesn't fit, so that it will have to float, we would set
**
\skip\topins=0pt
**
so that *\box255* for this page will have just the right size.  Finally, we 
would add
\setbox0\hbox{\<original value of *\skip\topins*\>}
**
\global\skip\topins="box0
**
at the end of the *\output* routine.
\endsmall

\sectiong{The endgame}Although the *\dosupereject*'s in the *\output* routine
ensure that all *\Aplace*'d material will eventually make its way onto the
 page,
some of this material may have to be printed 
after all the other
 text, with the final pages consisting entirely of *\island*'s.
 These *\island*'s will still be
allocated only two to a page,
so it will probably be necessary to change
some of the final *\Aplace*'s to *\Mplace*'s or *\AAplace*'s in order
to improve the appearance of
these final pages.

There doesn't seem to be any easy way to have \lamstex\ do this
automatically. We might try to change *\dimen\topins* to *\vsize*
when we have run out of text (i.e., when it is no longer true that
\hbox{*\outputpenalty > -20000*}),
 but this change would be made too late---after \tex\ has
already decided not to include some members of the  *\topins* insertion class
in *\box\topins*, since that decision is made at the time of the *\insert*.

One possibility is to have a box, say *\box\remainingplaces@*,
in which we store  copies of all the *\...place*'d *\islands*,
eliminating copies as *\pagecontents* uses up boxes in *\box\topins*.
  Then, when we run out of text, we
would change *\pagecontents* so that it ignores *\box\topins*, and
instead takes things from
*\box\remainingplaces@*, putting as many on the page as will fit. At this
stage we would change the definition of *\dosupereject*  from
**
\ifnum\insertpenalties > 0 
 \line{}\kern-\topskip\nobreak\vfill\supereject\fi
**
to
**
\ifvoid\remainingplaces@ \else
 \line{}\kern-\topskip\nobreak\vfill\supereject\fi
**
\endsmall

\sectiong{The endgame once again\label{FLUSHSEC}}
In addition, there is one minor defect that is encountered even in *plain*
\tex@. The *plain* \tex\ file
**
     \vsize=22pt
     \hsize=2in
     \raggedright

     Here is some stuff, taking up more than a line.

     \pageinsert \hbox{A}\vfil\hbox{B}\endinsert

     \bye
**
will produce {\it three\/} pages of output:  The text will all occur 
on page~1;
the 
**
\vbox to\vsize{\hbox{A}\vfil\hbox{B}}
**
will take up page~2; and page~3  will be 
{\it blank\/} (except for the page number).


If we add
**
      \def\plainoutput{%
      \showbox255 \showbox\topins \showthe\outputpenalty 
      \shipout\vbox{\makeheadline\pagebody\makefootline}%
      \advancepageno 
      \ifnum\outputpenalty>-20000 \else\dosupereject\fi}
**
at the beginning of this file (compare page~\ref{SHOWBOX}),
 the *.log* file will show that before page~*[1]* is shipped out
*\box255* contains the text,
*\box\topins*  is
**
> \box253=
\vbox(0.0+0.0)x0.0
**
(because of the split insert)
and  the *\outputpenalty* is *10000* (set by \tex\ because the chosen
breakpoint for the page was not a penalty item).


Before page~*[2]* is shipped out, *\box255* will be an empty box, 
while *\box\topins* will now be the *\vbox to\vsize{\hbox{A}\vfil\hbox{B}}*
(and the value of *\outputpenalty* will still be *10000*).

Finally, before page~*[3]* is shipped out, we will have
\Litbox0=**
> \box255=
\vbox(22.0+0.0)x144.54, glue set 12.0fill
.\glue(\topskip) 10.0
.\hbox(0.0+0.0)x144.54
.\glue 0.0 plus 1.0fill
**
$$
\vcenter{\box0} \tag"\style{\bf A}"
$$
and *\outputpenalty* will be
*-1073741824* ($={}$*-'10000000000*). 
As explained in {\it The \tex book}, page~264,
\tex\ inserted the equivalent of
**
\line{} \vfill \penalty -'1000000000  "8WEIRDPEN"8
**
into the main vertical list when it saw the *\end* from the *\bye*
(apparently because this *\end* was seen before the text had been output,
though I don't understand the details).

The \lamstex\ file
**
     \vsize=22pt
     \hsize=2in
     \raggedright

     \minpagesize=22pt
     \Figureproofing

     Here is some stuff, taking up more than a line.

     \Aplace{\Figure \Hbyw{1in} \endFigure}

     \bye
**
will also produce a blank third page,
\footnote{If we left *\minpagesize* at~*5pc* we'd get infinitely
many pages!} 
 although the *.log* file will tell a
somewhat different story if we add the appropriate *\show*'s to
the definition of *\plainoutput* in
*lamstex.tex*. 

Before page *[1]* is shipped out, *\outputpenalty* will be *-20000*
(presumably from a *\dosupereject*).

 Before page~*[2]* is shipped out,
*\box255* will be
**
\vbox(-15.0+0.0)x0.0
**
(see page~\ref{NEG255}), and *\outputpenalty* will again be *-20000*.



Before page~*[3]* is shipped out, *\outputpenalty* will again
be *-20000*, and we will have
\Litbox0=**
> \box255=
\vbox(22.0+0.0)x144.54, glue set 22.0fill
.\glue(\topskip) 10.0
.\hbox(0.0+0.0)x144.54
.\kern -10.0
.\penalty 10000
.\glue 0.0 plus 1.0fill
**
$$
\vcenter{\box0}\tag"\style{\bf B}"
$$
This *\vbox*, somewhat different from ({\bf A}), has come from the material
inserted by *\dosupereject*.

 [With some choices of \tex\ parameters, the *plain* \tex\ file
may cause a page break to be
 taken before the *\pageinsert* is seen, so that we
might end up with ({\bf B)} instead of ({\bf A}).]

\medskip

Such empty pages present a formidable problem if they occur at the end of
a book chapter, rather than at the end of a complete document, since they can
cause the next chapter to begin with the wrong page number.
For such situations we can add a check for empty pages.  For example,
at the beginning of the \lamstex\ definition of *\plainoutput* we can
test if *\box\footins* is void and
*\box\topins* is either void or has height ~*0pt*,
and if so we can then add
**
\setbox0=\vbox{\unvcopy255 \unskip}
 \ifdim\ht0=0pt
  \global\advance\pageno by -1
 \fi
**
so that the blank page ({\bf B})
would simply have the same page number as the previous
page. 

Since we might encounter the *plain* \tex\ situation ({\bf A})
also, the more
complex test
**
\setbox0=\vbox{\unvcopy255   "8BPGTEST"8
 \unskip \unpenalty \unkern
 \global\setbox1=\lastbox
 \unskip}
 \ifdim\ht0=0pt \ifdim\ht1=0pt 
  \global\advance\pageno by -1
 \fi\fi
**
is actually required.

Of course, this test is memory-intensive, since we essentially have
to keep two copies of *\box255* in memory at once.
The book style (Chapter~\ref{BOOKSTYLE}) allows the user to 
type
 *\FlushedFigs* when this test is appropriate, 
  but to avoid the test with *\NoFlushedFigs*.\pagelabel{FLUSHFIGS}

\endsmall

\sectiong{The endgame once again}  \endsmall
\sectiong{The endgame once again} \endsmall
\sectiong{The endgame once again} \endsmall
\sectiong{The endgame once again} \endsmall
\sectiong{The endgame once again} \endsmall
 
\tenrm
\setbox0\hbox{*.  .  .*}
\line{\hskip60pt\box0 \hfil}
\bigskip
\flushpar
Finally, let's hope that our *\output* routine doesn't allow this to happen!

\bigskip

\sectiongg{A final warning\label{FWARN}} 
With all the subtleties involved in the \lamstex\ *\output*
routine, it should perhaps be mentioned that sometimes even the *plain*
\tex\
 *\output* routine
will produce incorrect results. 
 On page~\ref{SGG},
 the page might have been
broken before the final
\bigskip
\noindent \hskip35pt where
$$\align
 \hbox{V}_{\text1}&=
 \hbox{value of {\tt\bs ref\lcurly}\<label\>{\tt\rcurly}}\\
 \hbox{V}_{\text2}&=
 \hbox{value of {\tt\bs Ref\lcurly}\<label\>{\tt\rcurly}}\\
 \hbox{V}_{\text3}&=
 \hbox{value of {\tt\bs nref\lcurly}\<label\>{\tt\rcurly}}\\
 \hbox{V}_{\text4}&=
 \hbox{value of {\tt\bs pref\lcurly}\<label\>{\tt\rcurly}}
\endalign
$$
\bigskip
\noindent with a badness of only *295*.  But \tex\ included this material
on the page, and then reported 
{\litindent0pt an
\setbox0\hbox{\,\,\bf!!}
**
Overfull \vbox (0.22726pt too high) while \output is active"box0
**
I must have printed thousands, if not tens of thousands, of}
 pages of \tex\ output before I ever
encountered this problem, 
but it can occur, so you might want to know what happened.

\medbreak
The footnote on the page has a height of *57.5pt* and a depth of *2.5pt*,
and,
as in *plain* \tex, *\skip\footins* was *12pt plus4pt minus4pt*. The thick
footnote rule contributed no extra space  [in *plain* \tex@, 
 *\footnoterule* is
**
\kern-3pt
\hrule width2truein \kern2.6pt
**
for a total height of *0pt*, and in this manual it was
**
\kern-3pt
\hrule height1pt width 2truein
\kern2pt
**
again having a total height of *0pt*].

At the time the footnote was considered, in the middle of the page, \tex\
carefully checked that the height plus depth of the footnote, plus the height
plus depth of the page so far, plus *\skip\footins*, was less than the page
goal, which was the *\vsize* of *480pt*.  Since this was true, so that
the
insert fit, the goal {\it
g\/} for the page was reduced by *72pt* [the height plus depth of the
footnote plus the \<dimen\> part of *\skip\footins*], to *408pt*.
 (The stretch and
shrink part of *\skip\topins* was added to the page total~ {\it t\/}).


 After that, \tex\ considered the
page total {\it t\/} each time it encountered a possible break point;
this page total reflects only the {\it height\/} of the material so far,
not its depth.
  At the
point where the page was finally broken, \tex\ calculated that
**
t=444.72726 plus 35.0 minus 37.0  g=408.0 
**
with a badness of *97*.
The `*minus 37.0*' meant that the page total could be shrunk down to
*407.72726*,
which seems to allow just enough room for the footnote in *\pagebody*:
\Math
\align
\hbox{*407.72726pt*}+\hbox{*12pt*}+\hbox{*60pt*}&=\hbox{*479.72726pt*}\\
 &<\hbox{*480pt*}\endalign
\endMath
But there are two flaws in this calculation:
\list
\item In the first place, when we make *\pagebody*, which is a 
*\vbox to\vsize*, the depth *2.5pt* of the footnote at the bottom of 
the box is irrelevant, since
it does not contribute to the height of the box.  Thus, we seem to have
an extra *2.5pt* of breathing room.
\item Unfortunately, the depth  of *\box255*, which no longer appears
at the bottom of the *\vbox to\vsize*, is {\it not\/} irrelevant, and must
be added in.
\endlist
It happens that the depth of the display at the bottom of page~\ref{SGG}
is *3pt* (there is a strut of depth ~*3pt* inserted into each line
of \amstex's *\align*, which was
used for the display). Consequently, the height of *\pagebody* is 
\Math
\hbox{*407.72726pt*}+\hbox{*3pt*}+\hbox{*12pt*}+\hbox{*57.5pt*}
  =\hbox{*480.22726pt*}
\endMath
leading to the\ \  *Overfull \vbox (0.22726pt too high)*.

\medskip

(You can easily simulate this phenomenon with the *plain* \tex\ file
**
\vsize=480pt
\topskip=0pt
\insert\footins{\hbox{\vrule height 57.5pt 
  depth 2.5pt width 0pt}}                  %% the ``footnote''
\hbox{}
\nointerlineskip
\vskip0pt minus34pt                        %% the shrink
\hbox{\vrule 
 height 444.72726pt depth 3pt width 0pt}   %% the ``text''
\bye
**
which gives a single page with
an\ \  *Overfull \vbox*, instead of two pages with
 a seriously\ \ *Underfull \vbox*
 on the first page. However, the two-page output will occur
once the depth of the ``text'' exceeds *4pt*,
the value of *\maxdepth*.)

\medskip

\noindent
Moral: In theory,
the *\output* routine really ought to examine the depth of
*\box255*
 before blithely
*\unvbox*'ing it, because it might prove
necessary to prune down *\box255*, just
as we 
did when *\ifspecialsplit@* was true (page~\ref{DOSPECSPLIT}). In practice,
this refinement is probably just a terrible waste of time. It might
become important when there is almost no stretch or shrink on a page (though
one would presume that *\vskip\footins* would  need to have some
stretch and shrink in such cases).
\endsmall
