|
| 1 | +% \iffalse meta-comment |
| 2 | +% |
| 3 | +% Copyright (C) 1993-2021 |
| 4 | +% |
| 5 | +% The LaTeX Project and any individual authors listed elsewhere |
| 6 | +% in this file. |
| 7 | +% |
| 8 | +% This file is part of the Standard LaTeX `Tools Bundle'. |
| 9 | +% ------------------------------------------------------- |
| 10 | +% |
| 11 | +% It may be distributed and/or modified under the |
| 12 | +% conditions of the LaTeX Project Public License, either version 1.3c |
| 13 | +% of this license or (at your option) any later version. |
| 14 | +% The latest version of this license is in |
| 15 | +% https://www.latex-project.org/lppl.txt |
| 16 | +% and version 1.3c or later is part of all distributions of LaTeX |
| 17 | +% version 2005/12/01 or later. |
| 18 | +% |
| 19 | +% The list of all files belonging to the LaTeX `Tools Bundle' is |
| 20 | +% given in the file `manifest.txt'. |
| 21 | +% |
| 22 | +% \fi |
| 23 | +% \iffalse |
| 24 | +%% File: afterpage.dtx Copyright (C) 1994 1994 1995 David Carlisle |
| 25 | +% |
| 26 | +%<package>\NeedsTeXFormat{LaTeX2e} |
| 27 | +%<package>\ProvidesPackage{afterpage} |
| 28 | +%<package> [2014/10/28 v1.08 After-Page Package (DPC)] |
| 29 | +% |
| 30 | +%<*driver> |
| 31 | +\documentclass{ltxdoc} |
| 32 | +\usepackage{afterpage} |
| 33 | +\GetFileInfo{afterpage.sty} |
| 34 | +\begin{document} |
| 35 | +\title{The \textsf{afterpage} package\thanks{This file |
| 36 | + has version number \fileversion, last |
| 37 | + revised \filedate.}} |
| 38 | +\author{David Carlisle} |
| 39 | +\date{\filedate} |
| 40 | +\MaintainedByLaTeXTeam{tools} |
| 41 | +\maketitle |
| 42 | +\DocInput{afterpage.dtx} |
| 43 | +\end{document} |
| 44 | +%</driver> |
| 45 | +% \fi |
| 46 | +% |
| 47 | +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 48 | +% |
| 49 | +% \changes{v1.00}{1993/01/25}{Initial version} |
| 50 | +% \changes{v1.05}{1993/07/14}{First public version} |
| 51 | +% \changes{v1.06}{1994/02/01}{Update for LaTeX2e} |
| 52 | +% \changes{v1.07}{1994/05/23}{Documentation Changes} |
| 53 | +% \changes{v1.08}{1995/10/27} |
| 54 | +% {Use \cs{par} not \cs{endgraf}, for tools/1579} |
| 55 | +% \changes{v1.08}{1995/10/27} |
| 56 | +% {Try and do something sensible with nested \cs{clearpage}, |
| 57 | +% for tools/1880} |
| 58 | +% \changes{v1.08}{1995/10/27} |
| 59 | +% {Try and do something sensible with footnotes, for tools/1884} |
| 60 | +% |
| 61 | +% |
| 62 | +% This package implements a command, |\afterpage|, that causes the |
| 63 | +% commands specified in its argument to be expanded after the current |
| 64 | +% page is output.\footnote{This is really a pre-release, to see whether |
| 65 | +% people like the idea of a command like this. This implementation is |
| 66 | +% \emph{not} particularly robust. This implementation does not work in |
| 67 | +% two column mode, and can get `confused' by \LaTeX's floating |
| 68 | +% environments.} |
| 69 | +% |
| 70 | +% \begin{enumerate} |
| 71 | +% \item Sometimes \LaTeX's float positioning mechanism gets overloaded, |
| 72 | +% and all floating |figure|s and |table|s drift to the end of the |
| 73 | +% document. One may flush out all the unprocessed floats by issuing a |
| 74 | +% |\clearpage| command, but this has the effect of making the current |
| 75 | +% page end prematurely. Now you can issue |\afterpage{\clearpage}| and |
| 76 | +% the current page will be filled up with text as usual, but then a |
| 77 | +% |\clearpage| command will flush out all the floats before the next |
| 78 | +% text page begins. |
| 79 | +% \item An earlier mechanism to help with float placement was the |
| 80 | +% optional argument |[H]| (meaning {\bf HERE!}) which was originally |
| 81 | +% added to the standard floating environments by |here.sty|, and is now |
| 82 | +% provided by |float.sty|. However some |[H]| users have commented that |
| 83 | +% they did not really mean `Here!' They actually wanted `Somewhere |
| 84 | +% close'. This can now be achieved by\\ |
| 85 | +% |\afterpage{\clearpage\begin{figure}[H] |\ldots |
| 86 | +% |\end{figure}}|\\ |
| 87 | +% This ensures that the figure is at the top of the next page. (The |
| 88 | +% |\clearpage| stops any other figures drifting past the |[H]| figure.) |
| 89 | +% \item Floating longtables. |longtable.sty| provides the |longtable| |
| 90 | +% environment, a multi-page version of |tabular|. Many |longtable| users |
| 91 | +% have told me that it is difficult to set the text surrounding the long |
| 92 | +% table, and that they wanted a `floating' version. As, presumably, |
| 93 | +% |longtable|s are long, they are probably too large to hold in memory, |
| 94 | +% and float in the way that the |table| environment is floated, however |
| 95 | +% if the table is in a separate file, say |ltfile.tex|, you can now |
| 96 | +% use one of:\\ |
| 97 | +% |\afterpage{\clearpage\input{ltfile}}|\\ |
| 98 | +% |\afterpage{\clearpage\input{ltfile}\clearpage}|.\\ |
| 99 | +% The first form lets text appear on the same page as the end of the |
| 100 | +% longtable, the second ensures that the surrounding text starts again |
| 101 | +% on a new page. |
| 102 | +% \end{enumerate} |
| 103 | +% |
| 104 | +% \StopEventually{} |
| 105 | +% |
| 106 | +% \begin{macrocode} |
| 107 | +%<*package> |
| 108 | +% \end{macrocode} |
| 109 | +% |
| 110 | +% \begin{macro}{\afterpage} |
| 111 | +% The token register used to save the old output routine. |
| 112 | +% \begin{macrocode} |
| 113 | +\newtoks\AP@output |
| 114 | +\global\AP@output\expandafter{\the\output} |
| 115 | +% \end{macrocode} |
| 116 | +% |
| 117 | +% A box register used to save any part of the next page which has |
| 118 | +% already been processed. |
| 119 | +% \begin{macrocode} |
| 120 | +\newbox\AP@partial |
| 121 | +% \end{macrocode} |
| 122 | +% |
| 123 | +% A box register used to save any footnote texts that are `tied' to |
| 124 | +% the text that gets saved in |\AP@partial|. |
| 125 | +% \begin{macrocode} |
| 126 | +\newbox\AP@footins |
| 127 | +% \end{macrocode} |
| 128 | +% |
| 129 | +% The following macro attempts to get safely into vertical mode, and |
| 130 | +% then invokes a special output routine to grab the current page into |
| 131 | +% |\AP@partial|. |
| 132 | +% \begin{macrocode} |
| 133 | +\def\AP@savetop{% |
| 134 | +% \end{macrocode} |
| 135 | +% Now begins a test to see what state we are in. |\AP@noindent| will |
| 136 | +% be defined so as to return to this state (well, almost!) after |
| 137 | +% afterpage has finished. |
| 138 | +% \begin{macrocode} |
| 139 | + \ifvmode |
| 140 | +% \end{macrocode} |
| 141 | +% Vertical mode. This is the simplest case, do nothing. |
| 142 | +% \begin{macrocode} |
| 143 | + \let\AP@noindent\empty |
| 144 | + \else\ifhmode |
| 145 | +% \end{macrocode} |
| 146 | +% Horizontal mode. |
| 147 | +% `Back out' into vertical mode, removing the indentation box as we go. |
| 148 | +% If in fact there was no indentation box, the output routine was |
| 149 | +% invoked by |\noindent| (what bad luck!) so we have to remember to |
| 150 | +% re-insert the |\noindent| before the paragraph is seen again. |
| 151 | +% |\everypar| tokens have already been inserted, so don't insert them |
| 152 | +% again. |
| 153 | +% \begin{macrocode} |
| 154 | + \setbox\z@\lastbox |
| 155 | + \edef\AP@noindent |
| 156 | + {{\everypar{}\ifvoid\z@\noindent\else\indent\fi}}% |
| 157 | + \par |
| 158 | + \else |
| 159 | +% \end{macrocode} |
| 160 | +% The remaining (even worse) possibility that the output routine |
| 161 | +% was triggered by the start of displaymath within a paragraph. |
| 162 | +% |
| 163 | +% Come out of displaymath with |$$|, then adjust the spacing (getting |
| 164 | +% into vmode at the same time). |\AP@noindent| will restart display math |
| 165 | +% later. |\everydisplay| tokens have already been inserted (they apply |
| 166 | +% to the math list that will be started by |\AP@noindent|, even though |
| 167 | +% they were triggered by the display math that was closed by the lines |
| 168 | +% below!). Save the values |\prevgraf| and |\predisplaysize| for use in |
| 169 | +% the re-started math list. |
| 170 | +% \begin{macrocode} |
| 171 | + \abovedisplayshortskip\z@\abovedisplayskip\z@ |
| 172 | + \belowdisplayshortskip\z@\belowdisplayskip\z@ |
| 173 | + \xdef\AP@disp{% |
| 174 | + \predisplaysize\the\predisplaysize |
| 175 | + \prevgraf\the\prevgraf\relax}% |
| 176 | + $$\vskip-\baselineskip\vskip-\parskip |
| 177 | + \edef\AP@noindent{% |
| 178 | +% \end{macrocode} |
| 179 | +% Do not insert |\everydisplay| tokens again. |
| 180 | +% \begin{macrocode} |
| 181 | + \toks@{\the\everydisplay}\everydisplay{}% |
| 182 | +% \end{macrocode} |
| 183 | +% Start displaymath mode with no spurious paragraph line above it. |
| 184 | +% Restore |\prevgraf| and |\predisplaysize|. Use |\aftergroup| to |
| 185 | +% restore the correct setting for |\everydisplay| after this display |
| 186 | +% has finished. |
| 187 | +% \begin{macrocode} |
| 188 | + {\everypar{}\noindent}$$\AP@disp\aftergroup\noexpand\AP@ed}% |
| 189 | + \fi\fi |
| 190 | +% \end{macrocode} |
| 191 | +% Now switch the output routine and remove everything from the current |
| 192 | +% page into the box |\AP@partial|. |
| 193 | +% \begin{macrocode} |
| 194 | + \begingroup |
| 195 | + \nointerlineskip\null |
| 196 | + \output{% |
| 197 | + \global\setbox\AP@partial\vbox{% |
| 198 | + \unvbox\@cclv |
| 199 | + \global\setbox\@ne\lastbox}% |
| 200 | +% \end{macrocode} |
| 201 | +% If the text that is saved in |\AP@partial| had footnotes, we'd |
| 202 | +% better grab them as well otherwise they may come out on a page |
| 203 | +% with the `afterpage' text, before the page that has the |
| 204 | +% footnote mark! (Added at v1.08.) |
| 205 | +% \begin{macrocode} |
| 206 | + \global\setbox\AP@footins\box\footins}% |
| 207 | +% \end{macrocode} |
| 208 | +% Having defined the output routine, trigger it\ldots |
| 209 | +% \begin{macrocode} |
| 210 | + \eject |
| 211 | + \endgroup} |
| 212 | +% \end{macrocode} |
| 213 | +% |
| 214 | +% |\AP@| stores all the commands that must be executed after the page |
| 215 | +% break. |
| 216 | +% \begin{macrocode} |
| 217 | +\let\AP@\relax |
| 218 | +% \end{macrocode} |
| 219 | +% |
| 220 | +% Restore the |\everydisplay| register. |\ignorespaces| prevents a space |
| 221 | +% or newline after |$$| creating rogue a indentation or paragraph. |
| 222 | +% \begin{macrocode} |
| 223 | +\def\AP@ed{\everydisplay\expandafter{\the\toks@}\ignorespaces} |
| 224 | +% \end{macrocode} |
| 225 | +% |
| 226 | +% Remove the current vertical list, insert the commands |\AP@| |
| 227 | +% at the top of the page, and then re-insert the saved text. |
| 228 | +% \begin{macrocode} |
| 229 | +\def\AP@@{% |
| 230 | + \AP@savetop |
| 231 | + \global\expandafter\let\expandafter\AP@\expandafter\relax\AP@ |
| 232 | + \par |
| 233 | +% \end{macrocode} |
| 234 | +% The text originally at the top of this page is now stored in the box |
| 235 | +% |\AP@partial|, including |\topskip| glue. Now we want to unbox |
| 236 | +% |\AP@partial|, placing the baseline of the first row |\baselineskip| |
| 237 | +% below the baseline of the last line coming from the afterpage text. |
| 238 | +% If we assumed nothing has too much height or depth (and |\topskip| is |
| 239 | +% rigid), it would be fairly trivial to position the contents of |
| 240 | +% |\AP@partial| so that the baseline of the first row was |
| 241 | +% |\baselineskip| below the last row just added. |
| 242 | +% |
| 243 | +% In this version, I thought it might be fun to try to exactly achieve |
| 244 | +% the |\baselineskip|--or--|\lineskip| calculation that \TeX\ normally |
| 245 | +% does internally. The call to |\addboxcontents| does the right thing |
| 246 | +% (I hope). |
| 247 | +% \begin{macrocode} |
| 248 | + \addboxcontents\AP@partial |
| 249 | +% \end{macrocode} |
| 250 | +% Now re-insert any footnote text. This may not be quite the right |
| 251 | +% place, as the text that has just been unboxed may break over a page |
| 252 | +% in its new position. Also it may not be the right number if the text |
| 253 | +% from |\afterpage| itself contains footnotes. Too bad! |
| 254 | +% \begin{macrocode} |
| 255 | + \ifvoid\AP@footins\else |
| 256 | + \insert\footins{\unvbox\AP@footins}\fi |
| 257 | +% \end{macrocode} |
| 258 | +% Now repair things if we started off in horizontal mode. |
| 259 | +% \begin{macrocode} |
| 260 | + \AP@noindent} |
| 261 | +% \end{macrocode} |
| 262 | +% |
| 263 | +% If |\AP@| is not |\relax| then the current page already has some |
| 264 | +% `afterpage' commands, so just add the new commands to the end of the |
| 265 | +% list. Otherwise save the commands in |\AP@|. (within a local group), |
| 266 | +% and switch the output routine. (The new output routine just calls the |
| 267 | +% old one if it is invoked by a \LaTeX{} float. |
| 268 | +% \begin{macrocode} |
| 269 | +\long\def\afterpage#1{% |
| 270 | + \ifx\AP@\relax |
| 271 | + \gdef\AP@{{#1\par}}% |
| 272 | + \global\output{% |
| 273 | + \the\AP@output |
| 274 | + \ifnum\outputpenalty>-\@Mi |
| 275 | + \global\output\expandafter{\the\AP@output}% |
| 276 | + \aftergroup\AP@@ |
| 277 | + \fi}% |
| 278 | + \else |
| 279 | + \expandafter\gdef\expandafter\AP@\expandafter{\AP@{#1\par}}% |
| 280 | + \fi} |
| 281 | +% \end{macrocode} |
| 282 | +% |
| 283 | +% If we have got to the end of the document or clearpage |
| 284 | +% just put the stuff out without any trickery. |
| 285 | +% \begin{macrocode} |
| 286 | +\let\AP@clearpage\clearpage |
| 287 | +\def\clearpage{% |
| 288 | + \ifx\AP@\relax |
| 289 | + \AP@clearpage |
| 290 | + \else |
| 291 | + \global\output\expandafter{\the\AP@output}% |
| 292 | + \AP@clearpage |
| 293 | +% \end{macrocode} |
| 294 | +% At this point (since v1.08) Need to clear |\AP@| \emph{before} |
| 295 | +% using its expansion, as otherwise hit an infinite loop. Sigh. |
| 296 | +% \begin{macrocode} |
| 297 | + \global\expandafter\let\expandafter\AP@\expandafter\relax |
| 298 | + \expandafter\expandafter\AP@ |
| 299 | + \fi} |
| 300 | +\let\AP@enddocument\enddocument |
| 301 | +\def\enddocument{% |
| 302 | + \ifx\AP@\relax\else |
| 303 | + \global\output\expandafter{\the\AP@output}% |
| 304 | + \AP@clearpage |
| 305 | + \global\expandafter\let\expandafter\AP@\expandafter\relax |
| 306 | + \expandafter\expandafter\AP@ |
| 307 | + \fi |
| 308 | + \AP@enddocument} |
| 309 | +% \end{macrocode} |
| 310 | +% \end{macro} |
| 311 | +% |
| 312 | +% \begin{macro}{\addboxcontents} |
| 313 | +% Given a vbox |#1|, add to the current vertical list such that the end |
| 314 | +% result is equivalent to the list that \TeX\ would have built had the |
| 315 | +% contents of |#1| (apart from any initial glue) been added individually |
| 316 | +% to the current list. |
| 317 | +
|
| 318 | +% So essentially, the problem is that of unboxing |#1|, but replacing |
| 319 | +% the glue at the top of |#1| with (something equivalent to) the |
| 320 | +% |\baselineskip| or |\lineskip| glue that \TeX\ would normally have |
| 321 | +% placed before the first box in |#1|. Also |\prevdepth| must be set at |
| 322 | +% the end. |
| 323 | +% \begin{macrocode} |
| 324 | +\def\addboxcontents#1{{% |
| 325 | +% \end{macrocode} |
| 326 | +% Perhaps I shouldn't use grouping here, as I probably don't really want |
| 327 | +% to save |#1|. If it is removed, |\splittopskip| and |\splitmaxdepth| |
| 328 | +% would need to be restored by hand. |
| 329 | +% |
| 330 | +% First replace any glue at the top by |\vskip 0pt|. |
| 331 | +% \begin{macrocode} |
| 332 | + \splittopskip\z@ |
| 333 | + \splitmaxdepth\maxdimen |
| 334 | + \setbox#1\vbox{\break\unvbox#1}% |
| 335 | + \setbox\z@\vsplit#1to\z@ |
| 336 | +% \end{macrocode} |
| 337 | +% Put the breakpoint back. |
| 338 | +% \begin{macrocode} |
| 339 | + \setbox#1\vbox{\break\unvbox#1}% |
| 340 | +% \end{macrocode} |
| 341 | +% Set |\skip@| to be height of |#1| (without top glue) |
| 342 | +% \begin{macrocode} |
| 343 | + \skip@\ht#1% |
| 344 | +% \end{macrocode} |
| 345 | +% Now make the first baseline of the first row be |\vsize| from the top. |
| 346 | +% (This assumes that the first row has height less than |\vsize|.) |
| 347 | +% \begin{macrocode} |
| 348 | + \splittopskip\vsize |
| 349 | + \setbox\z@\vsplit#1to\z@ |
| 350 | +% \end{macrocode} |
| 351 | +% Subtract the new height of |#1| from |\skip@|, and add back on |
| 352 | +% |\splittopskip|, so |\skip@| is now the height of the first row of |
| 353 | +% |#1| This may still be 0pt if (eg) a mark or whatsit is between the |
| 354 | +% top glue and the first box. Save (this height${}-{}$|\splittopskip|) |
| 355 | +% in |\skip\tw@|. |
| 356 | +% \begin{macrocode} |
| 357 | + \advance\skip@-\ht#1% |
| 358 | + \skip\tw@\skip@ |
| 359 | + \advance\skip@\splittopskip |
| 360 | +% \end{macrocode} |
| 361 | +% Now fake \TeX's |\baselineskip| calculation. |
| 362 | +% \begin{macrocode} |
| 363 | + \advance\skip@\prevdepth |
| 364 | + \advance\skip@-\baselineskip |
| 365 | + \advance\skip\tw@\ifdim-\skip@<\lineskiplimit\lineskip\else-\skip@\fi |
| 366 | +% \end{macrocode} |
| 367 | +% Finally add the glue. |
| 368 | +% \begin{macrocode} |
| 369 | + \vskip\skip\tw@ |
| 370 | +% \end{macrocode} |
| 371 | +% Now unbox the box, setting |\prevdepth| by hand, as |\unvbox| (unlike |
| 372 | +% |\box|) does not automatically set it. |
| 373 | +% \begin{macrocode} |
| 374 | + \global\dimen@i\dp#1% |
| 375 | + \unvbox#1}% |
| 376 | + \prevdepth\dimen@i} |
| 377 | +% \end{macrocode} |
| 378 | +% \end{macro} |
| 379 | +% |
| 380 | +% \begin{macrocode} |
| 381 | +%</package> |
| 382 | +% \end{macrocode} |
| 383 | +% |
| 384 | +% \Finale |
| 385 | +% |
0 commit comments