PDCOPUT5—an output routine for zines

Version 5.3, last changed pdc 1995–04–06

P. Damian Cugley

1. Introduction

This document describes pdcoput5.tex, a TEX definition file that defines an output routine for TEX documents. The complete text of the macros is reproduced, with brief descriptions of how to exploit them.

In fact, running plain TEX on the file pdcoput5.dtx generates a copy of the macros in a file called pdcoput5.tex in the current directory, as well as the printed documentation.* This should help ensure that the printed documentation matches the file it describes.

The name ends with ‘-5’ to distinguish this file from its predecessor (version 4.1.7), so that documents based on the old macros can still be printed.

1.1. Output routines In a TEX document, there is a special sequence of TEX commands called the output routine which controls the assembly of pages for output to the dvi file. Plain TEX comes with an output routine that handles simple documents (with footnotes and topinserts); LaTEX has a more complex output routine that has many extra features (margin paragraphs, LaTEX’s floats).

1.2. Background to this output routine I have been using TEX to typeset fanzines† for some years. Unfortunately, for magazine layouts, the ‘floating’ insertions provided by plain TEX and LaTEX do exactly the wrong thing—in a magazine, the designer wants to lay out the components of the page (illustrations, text, headings) exactly where he or she wants them, whereas the standard TEX formats are designed to let the formatter place components according to its own complex rules.

Originally I tried browbeating LaTEX into doing the zine layouts I wanted. I realized eventually that by the time I had redefined enough of LaTEX’s kernel to get the effects I wanted I would more or less have written everything from scratch. The sort of typesetting I wanted is so unlike what LaTEX is designed for that LaTEX was getting in the way.

Thus I developed a set of TEX definition files,‡ with an output routine that allowed a page to be peppered with inserts with the text flowing in between them (with a more restricted class of inserts than, say, a DTP program, but still flexible enough to be useful). The output routine also does multi-column text—in this respect it is very similar to

* The LaTEX 2e distribution uses files with the suffix dtx for similar purposes.

† The word fanzine comes from science fiction fans’ jargon: fan for amateur (in the sense of unpaid, not necessarily amateurish) + magazine. (They call professional magazines prozines.) Thus a fanzine (or zine for short) is a small magazine, often produced by photocopying or cheap printing by its editor. The word zine rhymes with scene not sign, and isn’t spelled with an apostrophe (unless you are the sort of person who spells phone, cello and bus with an apostrophe).

‡ We can ignore the intermediate stage, which involved writing a ‘user-friendly’ format in the style of LaTEX and Texinfo, with structures very different from plain TEX’s syntax. In the end I realized that a format that requires disguising or renaming plain TEX constructs makes using and modifying the macros harder, not easier, because the user has to understand the new conventions in addition to plain TEX syntax.

1–8 PDCOPUT5—an output routine for zines 5.3 1995–04–06

Figure 1 Page layout. This shows a page without the optional extra boxes. In this example, text columns each span two grid cells. The left-hand column has an illo (space for an illustration) with caption.

the multicol package in LaTEX 2e. The routine presented here has been rewritten from scratch a few times, each time shedding some cruft as I have a better understanding of TEX.

1.3. The layout model

The main part of the page (everything except the headline and footline) is called the body. The body is divided into a grid of cells. The cells are conceptually the framework on which page components like text columns and illustrations are hung. For example, text columns may span two cells. Figure 1 shows a simple layout. Fitting on the grid usually means the width of the object is N × gridwd + (N − 1) × colsep and its left edge is K × (gridwd + colsep) from the left edge of the page body.

The aim of using a grid layout is to combine flexibility with enough structure that the result is not a chaotic mess. The example grid is 5 cells wide, so that text columns can probably be 2 or 3 cells wide without being too narrow or too wide. Illustrations may be anything from 1 to 5 cells wide, or may bleed off the page.

2. File identification

Macro files nowadays tend to start with a whole slew of header comments designed to be useful to people comign across the file in some archive and unaware of what it is for.

  1 % pdcoput5.dtx 5.3 1995/04/06 -- output routine for zines

2

  3 %%%@TeX-definition-file {
  4 %%% filename       = "$texmf/tex/plain/pdcmac/pdcoput5.tex",
  5 %%% version        = "5.3",
  6 %%% date           = "1995/04/06",
  7 %%% package        = "pdcmac 1.0",
  8 %%% author         = "P. Damian Cugley",

Figure 2 Page layout parameters. This page has with all the optional boxes (shown with dashed lines). One text column has a space left for artwork. Text columns are the same width as grid cells.

 9 %%% email          = "damian.cugley@comlab.ox.ac.uk",
10 %%% address        = "Oxford University Computing Laboratory,
11 %%%                   Parks Road, Oxford  OX1 3QD, UK",
12 %%% codetable      = "USASCII",
13 %%% keywords       = "TeX, plain TeX, macros",
14 %%% supported      = "Maybe",
15 %%% abstract       = "TeX output routine for magazine-style layout.
16 %%%                   This file was generated by running
17 %%%                   plain TeX on pdcoput5.dtx",
18 %%% copyright      = "Copyright (c) 1991-1995 P. Damian Cugley",
19 %%% copying        = "DO NOT DISTRIBUTE THIS FILE.
20 %%%                   Distribute pdcoput5.dtx only as part of the
21 %%%                   package it came in.",
22 %%% dependencies   = "",
23 %%% }

24

25 \message{5.3 <pdc 1995/04/06>}

26

3. Miscellaneous internal definitions

3.1. Scratch registers

These are one-token names for some handy non-global temporary registers (in plain TEX these are given names with @ in them; these definitions give them names I can use).

27 \countdef\counta=255
28 \dimendef\dimena=0 \dimendef\dimenb=2
29 \toksdef\toksa=0 \toksdef\toksb=2

I don’t use \dimen1 and \toks1 because they are supposed to be used only globally (as discussed in TEXbook Appendix B).

3.2. Queues These macros manipulate queues of instructions for the ouytput routine, represented as list macros of a form similar to those described in TEXbook Appendix D Section 2 (the parameters in different order).

Note All of these work by making assignments and so will not work in TEX’s

mouth. We can describe these briefly using letters like x to stand for elements (enclosed in

braces) and xs to stand for a list macro of xs. Each macr has a duplicate starting with ‘g-’ which does the same operation globally.

\qappend xs x — xs := xs + ⟨x⟩

30 \long\def\qappend#1#2{%
31  \toksa={\\{#2}}\toksb=\expandafter{#1}%
32  \xdef#1{\the\toksb\the\toksa}%

33 }

\qremove x xs — x, xs := hd(xs), tl(xs) (where xs = ⟨hd(xs)⟩ + tl(xs))

34 \def\qremove#1#2{%
35  \expandafter\glopoff#2\glopoff#1#2%

36 }

37 \long\def\glopoff\\#1#2\glopoff#3#4{%
38  \gdef#3{#1}\gdef#4{#2}%

39 }

4. Parameters

We collect here definitions for parameters that customizate the layout. In documents, many of these are set in using higher-level macros.

The abbreviations mg (margin), wd (width) and ht (height) are used a lot in dimen names.

4.1. Heights and depths The physical size of the paper is paperwd × paperwd. The area which will be filled with text columns is bodywd × bodyht. This area is divided in to a grid of cells each gridwd × gridht, with cells separated by colsep horizontally but butting vertically (there are n cells, so n × gridwd + (n − 1) × colsep = bodywd). Finally, colwd is the width of text columns (colwd = k × gridwd + (k − 1) × colsep) and colht is the height of text columns on the current page (it is equal to bodyht iff therte is no topbox or botbox).

40 \newdimen\paperwd \newdimen\paperht
41 \newdimen\bodywd \newdimen\bodyht
42 \newdimen\gridwd \newdimen\gridht
43 \newdimen\colwd \newdimen\colht

4.2. Margins and separators These margins measure from the edge of the paper as defined by \paperwd and \paperht. The inner margin (\innermg) is on the left on odd pages and on the right for even pages.

The bottom margin will be increased slightly later on to make

vsize = N × baselineskip + topskip .

44 \newdimen\topmg    \topmg=20mm
45 \newdimen\outermg  \outermg=20mm
46 \newdimen\innermg  \innermg=20mm
47 \newdimen\botmg    \botmg=27mm

Parameters for the distance between the baselines of the headline and the first line of text the corresponding distance for footlines.

48 \newskip\headlineskip  \headlineskip=10mm
49 \newskip\footlineskip  \footlineskip=10mm

The parameters \caprule and \capsep specify the separation between captions and the adjacent text column. The vertical displacement is capsep, with a horizontal rule of thickness caprule is drawn in the middle (set this to 0 pt to have no rule).

 50 \newdimen\caprule  \caprule=0.4pt
 51 \newskip\capsep    \capsep=5mm

The corresponding parameters for column separators—this time it is a vertical rule.

 52 \newdimen\colrule  \colrule=0.4pt
 53 \newdimen\colsep   \colsep=5mm

The number of text columns on a page.

 54 \newcount\ncols \ncols=1

4.3. Boxes

To switch the number of columns in mid page, the first text is run through the output routine and the resultant partial page is stored in \partialpage to be placed at the top of the next output.

 55 \newbox\partialpage

The special boxes \topbox and \botbox, if non-void, are placed at the top and bottom of the page, going inside the headline and footline but outside the body text area (which is reduced correspondingly). These are often useful in multi-column text to put titles that span the page.

 56 \newbox\topbox \newbox\botbox

These boxes, if not void, go at the left and right of the body text. The amount of space for columns of text is reduced by the width of the boxes.

 57 \newbox\leftbox \newbox\rightbox

The output routine is passed the current page contents in box 255.

 58 \chardef\pagebox=255

4.4. Hooks

These two list macros are used to override the output routine with customized layouts.

One item is removed from \pagelist to generate each page body (the page body is everything except the headline, footline, topbox, botbox amd partial page). If the list is empty, then the default action is ‘\makebody\pagebox’. The commands should make a box with width \bodywdm and heght \colht.

 59 \let\pagelist\empty

An item is removed from \collist each time a column is to be created by \makebody. Each item should be TEX commands that generate a box with width \colwd and height

\colht.
 60 \let\collist\empty

Finally, token registers that may be used to customize pages and captions. For example, \everypage is used in pdccmdoc.tex to create an empty \leftbox on each page.

 61 \newtoks\everypage
 62 \newtoks\everycaption

5. How to make one column

This is the default way to generate a column of text—this will normally be invoked k times if there are k columns.

A column is a vbox of height colht and width colwd. It contains, in order from top to bottom, an illustration (vertical mode material, normally white space for artwork to be pasted into), caption separator, text (from the page), caption separator, and bottom illustration. The illustrations are usually omitted. When there is no illustration, the caption separators are omitted too. The macro takes the following parameters:

#1 vertical mode material illustration at top of column
#2 ⟨8-bit number⟩  box to make middle out of
#3 vertical mode material illustration for bottom of column

To make baselines line up, capsep = baselineskip and the height of a top illustration must be N × baselineskip + topskip and of a bottom illustration must be N × baselineskip (\prevdepth is set to 0 pt at the start of the bottom illustration, so if it starts with a box, baselineskip glue will be inserted to make the baseline of the box align correctly.)

63 \newdimen\toptotal \newdimen\bottotal
64 \def\xxxmakecolumn#1#2#3#4#5{\xmakecolumn
65  {\ifdim#1=0pt\else \kern#1 \fi
66  \def\tmp{#2}\ifx\tmp\empty\else #2 \fi}
67  {#3}
68  {\def\tmp{#2}\ifx\tmp\empty\else #2 \fi
69  \ifdim#1=0pt\else \kern#1 \fi}%

70 }

71 \def\xmakecolumn#1#2#3{%
72  \vbox to \colht{

Calculate in \dimena how much of the text box will be needed once we have allowed for any illustrations, footnotes or topinserts:

73  \dimena\colht
74  \setbox0=\vbox{#1}\advance\dimena-\ht0
75  \ifdim\ht0>0pt
76  \advance\dimena-\capsep
77  \advance\dimena\topskip \advance\dimena-\baselineskip
78  \fi
79  \setbox4=\vbox{\prevdepth=0pt #3}%
80  \advance\dimena-\ht4
81  \ifdim\ht4>0pt \advance\dimena-\capsep \fi
82  \ifvoid\footins\else
83  \advance\dimena-\ht\footins
84  \advance\dimena-\skip\footins
85  \fi
86  \ifvoid\topins\else
87  \advance\dimena-\ht\topins
88  \advance\dimena-\skip\topins
89  \fi

Split that much text off the top of the box:

90  \splittopskip\topskip \splitmaxdepth\maxdepth
91  \setbox2=\vsplit#2to\dimena

Now to sandwich it all together.

92  \dimena=\ht0 \dimenb=\dp0 \unvbox0
93  \ifdim\dimena>0pt
94  \prevdepth=\dimenb
95  \capseparator
96  \dimena\baselineskip \advance\dimena-\topskip
97  \kern\dimena
98  \nointerlineskip
99  \fi
100  \ifvoid\topins\else \unvbox\topins \vskip\skip\topins \fi
101  \dimena\dp2
102  \ifvoid2 \vfil \else \unvbox2 \fi
103  \ifvoid\footins \else
104  \vskip\skip\footins \footnoterule
105  \dimena=\dp\footins \unvbox\footins
106  \fi

107  \ifdim\ht4>0pt
108  \prevdepth=\dimena
109  \capseparator \kern-\prevdepth \prevdepth0pt
110  \fi
111  \unvbox4

112 }% 113 }

The caption separator is in an hbox so that baselineskip glue will be added appropriately.

114 \def\capseparator{%
115  \hbox to \colwd{%
116  \dimena=0.5ex \advance\dimena-0.5\caprule
117  \dimenb=\dimena \advance\dimenb\caprule
118  \vrule height \dimenb depth-\dimena width\colwd

119 }% 120 }

Here’s a macro for making an illustration (blank space) with caption, suitable for top of page. #1 is the cation, #2 is vertical mode material commands to make the illustration (often this will be something like ‘\kernn\baselineskip’ to leave n lines of blank space). The whitespace between illustration and caption is adjusted to make the whole shebang line up.

121 \def\topillustration#1#2{%
122  \setbox0=\vbox{#2}%
123  \dimena\ht0 \dimenb\dp0 \unvbox0
124  \counta\dimena \divide\counta\baselineskip
125  \advance\dimena-\counta\baselineskip \advance\dimena-\topskip
126  \kern-\dimena \prevdepth\dimenb
127  \hsize=\colwd \vskip-\parskip \noindent#1\par

128 } Similar for bottom of column.

129 \def\botillustration#1#2{%
130  \setbox0\vbox{\hsize=\colwd \vskip-\parskip \prevdepth=0pt #1}
131  \setbox2=\vbox{\prevdepth=\dp0 #2}%
132  \dimena=\ht0 \advance\dimena\dp0 \advance\dimena\ht2
133  \unvbox0
134  \counta\dimena \divide\counta\baselineskip
135  \advance\dimena-\counta\baselineskip
136  \advance\dimena-\baselineskip
137  \kern-\dimena
138  \unvbox2

139 }

6. Making the page body hbox

The page body is everything except the footline, headline, topbox and botbox. It should be a box of height \bodywd (which is normally fixed) and height \colht (which is \bodyht minus the top and bot boxes).

The default macro for making the body is \makebody which takes as its parameter the box number (usually \pagebox). (This may be replaced by adding items to the list

macro \pagelist.)
140 \def\makebody#1{%
141  \hbox to \bodywd{%
142  \ifvoid\leftbox\else
143  \box\leftbox
144  \colseparator
145  \fi
146  \makecolumnfromcollist{#1}%
147  \counta\ncols
148  \loop \ifnum\counta>1
149  \colseparator
150  \makecolumnfromcollist{#1}%

151  \advance\counta -1
152  \repeat
153  \ifvoid\rightbox\else
154  \colseparator
155  \box\rightbox
156  \fi

157 }% 158 }

159 \def\colseparator{%
160  \hfil \vrule width\colrule depth0pt \hfil

161 }

The macro \makecolumnfromcollist is used to generate columns (which must be boxes of height \colht and width \colwd). It uses the next item on \collist if there is one, otherwise it just uses \xmakecolumn.

162 \def\makecolumnfromcollist#1{%
163  \ifx\collist\empty
164  \xmakecolumn{}{#1}{}%
165  \else
166  \qremove\temp\collist
167  \temp
168  \fi

169 }

170

7. Making a page vbox

The macro generates a new page—a vbox to be ‘shipped out’. The first page includes a papersize special; this is because if the macros used to change the paper size also generated the \special then there might be conflicting \specials which would confuse the printer driver. This way the paper size may be changed a few times before the first page.

The \colht register is set to the height of text columns on this page (which is bodyht minus the height of any partial page, top or bottom boxes).

171 \def\makepage{%
172  \vbox{
173  \papersizespecial
174  \colht\bodyht \advance\colht-\ht\partialpage
175  \advance\colht-\ht\topbox \advance\colht-\ht\botbox
176  \advance\colht-\dp\partialpage
177  \advance\colht-\dp\topbox
178  \the\everypage
179  \makeheadline \nointerlineskip
180  \box\partialpage \nointerlineskip
181  \box\topbox \nointerlineskip
182  \ifx\pagelist\empty
183  \makebody\pagebox
184  \else
185  \qremove\temp\pagelist
186  \temp
187  \fi
188  \unvbox\botbox
189  \makefootline

190 }% 191 }

The \makeheadline macro generates the headline in the form of vertical mode material with zero height. It is expanded after \everypage has been expanded, at the very top of the page’s vbox.

192 \def\makeheadline{
193  \vbox to 0pt {
194  \skip0=\topskip \advance\skip0-2\ht\strutbox
195  \advance\skip0-\headlineskip
196  \vskip\skip0

197  \hbox to \bodywd{\the\headline}
198  \vss

199 } 200 }

The footline is, naturally, generated with \makefootline. This time there is no requirement for it to be zero height. It is the last thing in the box being shipped out.

201 \def\makefootline{{
202  \baselineskip=\footlineskip
203  \hbox to \bodywd{\the\footline}

204 }}

The papersize special is specified in the manual for DVIPS. It specifies the physical size of the medium—and so must be multiplied by the current magnification.

205 \def\papersizespecial{{%
206  \dimena=0.001\paperwd \multiply\dimena\mag
207  \dimenb=0.001\paperht \multiply\dimenb\mag
208  \special{papersize=\the\dimena,\the\dimenb}%
209  \global\let\papersizespecial=\relax

210 }}

211

8. The output routine

The output routine sets \hoffset appropiately (subtracting 1′′ to allow for TEX’s peculiar origin point one inch from the top left of the page.

212 \def\pdcoutput{%
213  \ifodd\pageno \hoffset=\innermg \else \hoffset=\outermg \fi
214  \advance\hoffset-1 true in
215  \voffset=\topmg
216  \advance\voffset-1truein
217  \shipout\makepage \advancepageno
218  \ifnum\outputpenalty>-20000 \else \dosupereject \fi
219  \unvbox\pagebox

220 }

221 \output={\pdcoutput}

9. Specifying a grid

These macros for setting the paper size ought to be invoked after the base font and baseline skip have been set but before the numebr of columns is chosen.

9.1. Specifiying the paper size

This is a macro that might be used in documents. It takes two parameters, ⟨dimen⟩s for the width and height of the paper.

222 \def\setpaper#1#2{%
223  \paperwd=#1\relax
224  \paperht=#2\relax
225  \OPUTcalcbodywdht
226  \OPUTcalctopskip

227 }

Calculate the page body width \bodywd from the paper size and the size of the margins:

228 \def\OPUTcalcbodywdht{
229  \bodywd=\paperwd \advance\bodywd-\outermg \advance\bodywd-\innermg
230  \bodyht=\paperht \advance\bodyht-\topmg \advance\bodyht-\botmg
231  \OPUTcalctopskip

232 }

To avoid having to write ‘Aiv’ or ‘afour’ for specifying international standard A4 paper, I use an \ifcase.* This macro handles A0 to A5.

233 \def\setpaperA#1{
234  \ifcase#1
235  \setpaper{841mm}{1189mm}\or
236  \setpaper{594mm}{841mm}\or
237  \setpaper{420mm}{594mm}\or
238  \setpaper{297mm}{420mm}\or
239  \setpaper{210mm}{297mm}\or
240  \setpaper{148mm}{210mm}
241  \else
242  \errmessage{Dunno how big DIN A#1 paper is, sorry.}
243  \fi

244 }

9.2. Adjusting the body height and top skip Plain TEX sets \topskip to 10 pt, which means there is a gap between the top of the letters of the top line of text and the top of the pages’s vbox (i.e., vsize is measured from the baseline of the last line to a line topskip above the baseline of the first line). For magazinestyle setting, it is more usual to have topskip set to the cap-height of the font (assuming there are no strange tall characters in use).

To have an exactly N lines to a page,

bodyht = (N − 1) × baselineskip + topskip .

This macro increases the bottom margin in order to set bodyht to such a value.

245 \def\OPUTcalctopskip{
246  \setbox0=\hbox{AXbl()!gyJQ,}
247  \topskip=\ht0 \maxdepth=\dp0
248  \advance\bodyht-\topskip \divide\bodyht\baselineskip
249  \multiply\bodyht\baselineskip \advance\bodyht\topskip

250 }

Give this value for bodyht, we can set hsize and vsize according to the number of columns to a page. For N lines to a column, we need N × ncols lines to make a whole page, so

vsize = (ncols × N − 1) × baselineskip + topskip

= (bodyht + δ) × ncols − δ

where δ = baselineskip − topskip.

251 \def\OPUTcalchsizevsize{
252  \hsize=\colwd
253  \vsize=\bodyht
254  \advance\vsize-\topskip \advance\vsize\baselineskip
255  \multiply\vsize\ncols
256  \advance\vsize-\baselineskip \advance\vsize\topskip

257 }

9.3. Setting the number of columns Now some macros used in documents for setting the number of coumns. In the general case we have a grid of n cells with text columnns spanning k cells. This macro takes two number parameters, n and k. It sets \ncols to as many columns fit on the page.

colwd = k × gridwd + (k − 1) × colsep
ncols = ⌊n / k⌋

Often n is not a multiple of k, which leaves some grid cells ‘spare’ for illustrations or extra margins and so on.

* Note for Americans: A4 corresponds to American Letter size, and A3 to Ledger size.

258 \def\setnkgrid#1#2{%
259  \gridwd=\bodywd
260  \advance\gridwd-#1\colsep \advance\gridwd\colsep \divide\gridwd#1
261  \colwd#2\gridwd \advance\colwd#2\colsep \advance\colwd-\colsep
262  \ncols#1 \divide\ncols#2
263  \gridht=\baselineskip
264  \capsep=\gridht
265  \OPUTcalchsizevsize

266 }

For simpler layouts, we just set the number of columns and set the grid and column widths to be the same.

267 \def\setncolumns#1{%
268  \colwd=\bodywd
269  \advance\colwd-#1\colsep \advance\colwd\colsep \divide\colwd #1
270  \gridwd=\colwd
271  \ncols=#1
272  \OPUTcalchsizevsize

273 }

9.4. Setting default values We give all the parameters default values by assuming A4 paper and a single-column layout in TEX’s default fonts.

274 \setpaperA4
275 \setncolumns1

10. Routines for balanced columns

10.1. Balanced columns from a rigid vbox This is the routine discussed in TEXbook, Appendix D, Section 7 (pp. 396–397). It takes a rigid, regular vbox (rigid meaning there is no stretchable glue between lines, and regular meaning that baselines are all the same distance apart). Its parameters are

#1 ⟨8-bit number⟩ box to chop
#2 ⟨number⟩  how many columns to make ( > 0)
#3 ⟨dimen⟩  the value of \topskip for the box
#4 tokens  what to put between columns

the last parameter will usually be \hfil or \colseparator. Usually this command will be used like

                    \hbox to \bodywd{\rigidbalance...}
276 \newcount\RGDncols
277 \def\rigidbalance#1#2#3#4{%
278  \setbox0=\box#1\relax \RGDncols=#2\relax \toksa={#4}%
279  \begingroup\splittopskip#3\relax \vbadness=10000
280  \valign{##\vfil\cr \RGDdosplits}%
281  \endgroup

282 }

The helper function that produces the insides of the valign is recursive.

283 \def\RGDdosplits{
284  \dimena\ht0 \divide\dimena\RGDncols
285  \advance\dimena\splittopskip
286  \setbox1=\vsplit0 to\dimena
287  \unvbox1
288  \global\advance\RGDncols-1
289  \cr
290  \ifnum\RGDncols>0
291  \noalign{\the\toksa}
292  \RGDdosplits
293  \fi

294 } 10.2. Balance partial page

Occasionally it is useful to switch between different grids or numbers of columns within one page. This macro does this, creating a shorter-than-usual page body (including topbox and botbox) and then putting the result in \partialpage Its parameters are #1 the TEX code used to generate the text columns and #2 what to put between the partial page and the rest of the page.

295 \def\makepartialpage#1#2{
296  \maybepagebreak
297  \begingroup
298  \output{%
299  \message{[partial}
300  \setbox0=\vbox{\unvbox\pagebox}%
301  \global\setbox\partialpage\vbox{
302  \box\partialpage \nointerlineskip
303  \the\everypage
304  \box\topbox \nointerlineskip
305  \hbox to \bodywd{%
306  \ifvoid\leftbox\else
307  \box\leftbox \colseparator
308  \fi
309  #1%
310  \ifvoid\rightbox\else
311  \colseparator \box\rightbox
312  \fi
313  }% \nointerlineskip
314  \box\botbox

315 #2

316  \dimena\baselineskip \advance\dimena-\topskip
317  \kern\dimena

318 }%

319  \message{page]}

320 }

321  \eject
322  \endgroup

323 }

324 \def\rigidbalancepartialpage{
325  \makepartialpage{\rigidbalance0\ncols\topskip\colseparator}

326 }

Occasionally TEX might have just over a pageful of text when this command is used (since the page break calculations do not take into account the space subtracted by illustrations*). In this case we have to force out a complete page.

327 \def\maybepagebreak{%
328  \vskip0pt plus\baselineskip \penalty-100
329  \loop
330  \dimena\vsize \advance\dimena-\ncols\ht\partialpage
331  \advance\dimena-\ncols\ht\topbox
332  \advance\dimena-\ncols\ht\botbox
333  \ifdim\pagetotal>\dimena
334  \eject\null
335  \repeat

336 }

* This is probably a bug.