1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
% P L A C E I N S . T E X ver 2.0 Mar 3, 1995
%
% Insertions that keep their place.
%
% Copyright 1995 Donald Arseneau <asnd@triumf.ca>
% These macros may be freely used, transmitted, reproduced, or modified
% provided that this notice is left intact.
%
% This TeX file provides various mechanisms (for plain TeX and close
% relatives) to let insertions (footnotes, topins, pageins, etc.) float
% within their appropriate section, but to prevent them from intruding
% into the following section, even when sections do not normally begin
% a new page. (If your sections normally begin a new page, just use
% \supereject to flush out insertions.)
%
% Different combinations of insertions can be controlled with different
% commands:
%
% \par\penalty-20029
% If there are any insertions that will not fit on the current page,
% a \supereject is performed and the following text will continue at
% the top of a page after all insertions. If all insertions do fit
% on the current page, then the following text will continue
% immediately on this page.
% \par\penalty-20030
% Like above, except that if there are any footnotes at all on the
% current page, the section must begin on the next page. (This is so
% no footnote text from section 1 will appear beneath the beginning
% of section 2.)
% \par\penalty-10029
% If any insertions cannot fit on the current page, eject them, and
% then allow the following section to begin immediately on the same
% page as the last insert. If all insertions do fit on the current
% page, then the following text will continue immediately on this
% page.
% \barrier{\eject}{\topins}
% If there are any pageinserts or topinserts that do not fit on the
% current page, eject them, and then allow the following section to
% begin immediately on the same page as the last insert. Split
% footnotes or other insertions are allowed to intrude into the next
% section.
% \barrier{\supereject}{\topins}
% Like the \barrier command above, but if any inserts are ejected
% the following section will begin at the top of a new page (like
% \supereject).
% \barrier{...}{\footins}
% *** NOT ALLOWED *** You will get spurious space and footnote-rules
% at the bottom of pages!
% \barrier{...}{\margins}
% If you define other insertion classes, such as marginal notes, you
% can use \barrier for them too. But only if \skip\margins=0pt.
% You must also add any new insertion classes to the definition of
% \placerestoreoutput
%
% How to use: First, \input this file (of course!). Then, at the beginning
% of a new section, or at any boundary that insertions should not cross, put
% one of the commands listed above. Presumably, you will actually put these
% commands at the start of your own \section or \startsection macro; that is
% why they are non mnemonic!
%
% There is a slight chance that a footnote may be separated from its reference
% in the text after \penalty-xxxxx when there are no split insertions. (LaTeX
% has the same possibility at every float!)
\chardef\noplaceoutput\catcode`\@
\catcode`\@=11
\edef\zero@skip{\the\z@skip}
\def\barrier#1#2{\par\begingroup
\ifdim\skip#2>\z@{\newlinechar10\errhelp{\barrier#2may produce some spurious
extra material on the page, ^^J but I will try anyway.}\errmessage{Bad use
of \string\barrier}}%
\fi
\skip@\lastskip \edef\next{\the\skip@}\ifx\next\zero@skip\else\vskip-\skip@\fi
\penalty\z@ % update page parameters
\fam-\insertpenalties
\insert#2{\floatingpenalty\@ne}%
\ifx\next\zero@skip\else\vskip\skip@\fi
\advance\fam\insertpenalties % 0: no held; 1: held over
\expandafter\endgroup
\ifnum\fam=\@ne % then do eject
% \message{There are held-over \string#2 inserts; performing \string#1. }%
\ifdim\pagetotal<\topskip \leftline{}\kern-\topskip\fi % avoid empty list
{\dimen@\pagetotal \advance\dimen@\pagedepth
\ifdim\dimen@<\pagegoal\vfill\fi}%
#1\@barrier{#1}{#2}\else
% \message{There are no held-over \string#2 inserts. \space}%
\fi
}
\def\placeinsoutput{%
\ifnum\outputpenalty=-20030\relax % eject if any footnotes
\ifvoid\footins\else
\fam\insertpenalties \advance\fam\@ne \insertpenalties\fam
\fi \outputpenalty=-20029\relax
\fi
\ifnum\outputpenalty=-20029\relax % Check for `supereject' flag
\ifnum\insertpenalties>\z@ % something is being held over, must get it out
% \message{Forcing insertions on their own pages. \space}%
\ifvoid\footins \r@ggedbottomtrue \else \advance\skip\footins 0ptplus1fil\fi
\noplaceoutput % performs \supereject
\else % must rejoin seamlessly:
\placerestoreoutput
\fi
\else % check for other flag...
\ifnum\outputpenalty=-10028 % in the middle of ejecting
\ifnum\insertpenalties=\z@ \global\setbox\@cclv\vbox{}\fi
\outputpenalty=-10029
\fi
\ifnum\outputpenalty=-10029\relax % section start
\ifnum\insertpenalties>\z@ % something is being held over, must get it out
% \message{Forcing insertions. \space}%
\ifvoid\footins \r@ggedbottomtrue \else \advance\skip\footins 0ptplus1fil\fi
\noplaceoutput % performs \eject, perhaps repeatedly:
\leftline{}\kern-\topskip \penalty-10028\relax % (like \dosupereject)
\else % must rejoin seamlessly:
\placerestoreoutput
\fi
\else % just a regular page break
\noplaceoutput
\fi
\fi
}
% there is a slim chance that footnotes may lose their place.
\def\placerestoreoutput{%
\ifvoid\footins\else\insert\footins{\unvbox\footins}\fi
\ifvoid\topins\else\insert\topins{\unvbox\topins}\fi
% If you have other floating insertion classes, do the same here.
\unvbox\@cclv
}
\catcode`\@=\noplaceoutput
\edef\noplaceoutput{\the\output}
\output{\placeinsoutput}
|