summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex-dev/base/ltoutput.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/latex-dev/base/ltoutput.dtx')
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltoutput.dtx1617
1 files changed, 1403 insertions, 214 deletions
diff --git a/Master/texmf-dist/source/latex-dev/base/ltoutput.dtx b/Master/texmf-dist/source/latex-dev/base/ltoutput.dtx
index f2ae4150a94..10269632a5e 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltoutput.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltoutput.dtx
@@ -1,6 +1,6 @@
% \iffalse meta-comment
%
-% Copyright (C) 1993-2024
+% Copyright (C) 1993-2025
% The LaTeX Project and any individual authors listed elsewhere
% in this file.
%
@@ -30,14 +30,14 @@
%%% From File: ltoutput.dtx
%<flafter>\ProvidesPackage{flafter}
%<fltrace>\ProvidesPackage{fltrace}
-%<flafter,fltrace> [2024/11/16 v1.4k
+%<flafter,fltrace> [2025/02/20 v1.4n
%<flafter> Standard LaTeX floats after reference (FMi)]
%<fltrace> Tracing LaTeX floats algorithm (FMi)]
%
%<*driver>
% \fi
\ProvidesFile{ltoutput.dtx}
- [2024/11/16 v1.4k LaTeX Kernel (Output Routine)]
+ [2025/02/20 v1.4n LaTeX Kernel (Output Routine)]
% \iffalse
\documentclass{ltxdoc}
\GetFileInfo{ltoutput.dtx}
@@ -46,13 +46,21 @@
\author{Leslie Lamport, Frank Mittelbach, Chris Rowley}
\begin{document}
\MaintainedByLaTeXTeam{latex}
- \maketitle
+ \maketitle \tableofcontents
\DocInput{\filename}
\end{document}
%</driver>
% \fi
%
%
+% \providecommand\hook[1]{\texttt{#1\DescribeHook[noprint]{#1}}}
+% \providecommand\socket[1]{\texttt{#1\DescribeSocket[noprint]{#1}}}
+% \providecommand\plug[1]{\texttt{#1\DescribePlug[noprint]{#1}}}
+%
+% \ProvideDocElement[printtype=\textit{socket},idxtype=socket,idxgroup=Sockets]{Socket}{socketdecl}
+% \ProvideDocElement[printtype=\textit{plug},idxtype=plug,idxgroup=Plugs]{Plug}{plugdecl}
+% \ProvideDocElement[printtype=\textit{hook},idxtype=hook,idxgroup=Hooks]{Hook}{hookdecl}
+%
%
% \iffalse
% LATEX VERSION 2e
@@ -125,26 +133,18 @@
% \def \ie {i.e.~}
% \def \eg {e.g.~}
%
-% \section{Output Routine}
+% \section{Output Routine and float handling}
%
-% \subsection{Floats}
%
-% The `2ekernel' code ensures that a |\usepackage{autoout1}| is
-% essentially ignored if a `full' format is being used that has
-% the autoload file mode already in the format.
% \begin{macrocode}
-%<defx>\begingroup
-%<defx>\makeatletter
-%<defx>\nfss@catcodes
-%<2ekernel>\expandafter\let\csname ver@autoout1.sty\endcsname\fmtversion
+%<*2ekernel>
+\message{output,}
% \end{macrocode}
%
+% \subsection{Historical notes on the algorithm and commands}
+%
%
% \begin{oldcomments}
-% \begin{macrocode}
-%<*2ekernel>
-\message{output,}
-% \end{macrocode}
% ****************************************
% * OUTPUT *
% ****************************************
@@ -644,9 +644,13 @@
% \nointerlineskip
% \hbox{\vrule height 0 width 0 depth \@pagedp}
% END
+% \end{oldcomments}
+%
+%
+%
+% \subsection{Core definitions}
%
% Floats and marginpars add a lot of dead cycles.
-% \end{oldcomments}
% \begin{macrocode}
\maxdeadcycles = 100
% \end{macrocode}
@@ -690,7 +694,10 @@
\fi}
% \end{macrocode}
%
-% DEFINITION OF FLOAT BOXES:
+%
+% \subsubsection{Definition of float boxes}
+%
+%
% \changes{v1.3a}{2015/09/205}
% {extended \cs{@freelist}}
% \begin{macrocode}
@@ -756,7 +763,11 @@
\gdef\@dbldeferlist{}
% \end{macrocode}
%
-% PAGE LAYOUT PARAMETERS
+%
+%
+% \subsubsection{Page layout parameters}
+%
+%
% \begin{macrocode}
\newdimen\topmargin
\newdimen\oddsidemargin
@@ -890,8 +901,12 @@
% \end{macro}
% \end{macro}
%
-% \begin{oldcomments}
-% INTERNAL REGISTERS
+%
+%
+%
+% \subsubsection{Internal registers}
+%
+%
%
% \begin{macrocode}
\newcount\@topnum
@@ -918,7 +933,11 @@
\def\@thehead{\@oddhead} % initialization
\def\@thefoot{\@oddfoot}
% \end{macrocode}
-% \end{oldcomments}
+%
+%
+%
+%
+% \subsubsection{Page break commands}
%
% \begin{macro}{\clearpage}
% \changes{v1.1r}{1995/10/11}{Added a check so that it does not lose
@@ -1213,6 +1232,241 @@
% \end{macro}
%
%
+%
+% \section{The \LaTeX{} output routine}
+%
+% \subsection{Hooks and replaceable code blocks}
+%
+% To support packages that want to augment aspects of the output
+% routine we offer a number of hooks (where several packages can
+% add code) as well as some sockets (that can only be changed by
+% one package or through options like those of the \pkg{footmisc}
+% package).
+%
+%
+% \subsubsection{Output routine hooks}
+%
+% \begin{description}
+%
+% \item[\hook{build/page/before}, \hook{build/page/after}]
+% These two hooks enable packages to prepend or append code to
+% the page processing in the output routine. They are
+% implemented as mirrored hooks.
+%
+% Technically, they are executed at the start and the end of the internal
+% \LaTeXe{} \cs{@outputpage} command, respectively.
+%
+%
+% \item[\hook{build/page/reset}]
+% Packages that set up special conventions for text in the main
+% galley (such as catcode changes, etc.)\ can use this hook to
+% undo these changes within the output routine, so that they
+% aren't applied to unrelated material, e.g., the text for
+% running header or footers.
+%
+% \item[\hook{build/column/before}, \hook{build/column/after}]
+% These two hooks enable packages to prepend or append code to
+% the column processing in the output routine. They are
+% implemented as mirrored hooks.
+%
+% Technically, they are executed at the start and the end of the internal
+% \LaTeXe{} \cs{@makecol} command, respectively.
+%
+% \end{description}
+%
+% \subsubsection{Replaceable code blocks (sockets)}
+%
+% To cater for different layouts with respect to text, footnotes,
+% and bottom-floats placements there are sockets for
+% now. They are sockets not hooks, because the overall layout can only be
+% controlled by one package, i.e., the last setting wins.
+%
+% \begin{description}
+% \item[\socket{build/column/outputbox} (0 arguments)]
+%
+% In code for this socket the \cs{@outputbox} (holding the
+% galley text for the current column or page) is augmented by
+% attaching floats and footnote areas together with appropriate
+% spacing.
+%
+% Prior to calling the socket the output routine has already
+% decided which floats go into which area and which get deferred.
+% Therefore, the assumption is that the code in the socket attaches all
+% areas that contain floats. If this is not done, then the order
+% of floats is likely to be screwed up unless unused floats
+% are moved to the defer list in an appropriate way (for now we
+% don't offer any interface for that scenario).
+%
+% Before the code in the socket is run, any existing glue at the bottom
+% of the \cs{@outputbox} is removed and stored in a safe
+% place. If needed, it can be reinserted with one of the helper
+% commands.
+%
+% To support setting this up the following helper commands are available:
+% \begin{description}
+% \item[\cs{@outputbox@append} (1 argument)]
+%
+% \DescribeMacro[noprint]{@outputbox@append}
+%
+% This general purpose command alters the \cs{@outputbox} box by
+% appending material to it.
+%
+% \item[\cs{@outputbox@appendfootnotes} (0 arguments)]
+%
+% \DescribeMacro[noprint]{@outputbox@appendfootnotes}
+%
+% This command appends the footnotes to the \cs{@outputbox} (if
+% there are any). If not, then it does nothing.
+%
+% \item[\cs{@outputbox@attachfloats} (0 arguments)]
+% \item[\cs{@outputbox@attachtopfloats} (0 arguments)]
+% \item[\cs{@outputbox@attachbottomfloats} (0 arguments)]
+%
+% \DescribeMacro[noprint]{@outputbox@attachfloats}
+% \DescribeMacro[noprint]{@outputbox@attachtopfloats}
+% \DescribeMacro[noprint]{@outputbox@attachbottomfloats}
+%
+% Attaching top and bottom floats can usually be done in one
+% go, but for special layouts we might want more control so we
+% provide also separate commands.
+%
+% \item[\cs{@outputbox@reinsertbskip} (0 arguments)]
+%
+% \DescribeMacro[noprint]{@outputbox@reinsertbskip}
+%
+% Reinsert the bottom skip of the \cs{@outputbox} that was
+% saved before in \cs{@makecol}.
+%
+% \item[Testing for existence of material]
+%
+% \DescribeMacro[noprint]{@if@footnotes@TF}
+% \DescribeMacro[noprint]{@if@bottomfloats@TF}
+%
+% There are a number of helpers to run conditional code
+% depending on whether or not there are footnotes or bottom
+% floats. They are \cs{@if@footnotes@TF} and
+% \cs{@if@bottomfloats@TF}
+% (names are likely to change).
+%
+% \end{description}
+%
+% \task{fmi}{Decide on names for these helper commands. We could keep
+% them similar to the above (because they are only supposed to be
+% used by a few packages). However, we could alternatively use
+% CamelCase names, under the assumption that classes may also
+% directly define a plug for the socket, instead of loading a
+% support package such as \pkg{footmisc} (or in addition
+% to). --- decide}
+%
+% This socket cannot be empty but needs appropriate code; a set
+% of suitable plugs for it are already given in the kernel. These
+% are
+% \begin{description}
+% \item[\plug{space-footnotes-floats}]
+%
+% After the galley text there is a vertical \cs{vfill}
+% followed by any footnotes followed by the bottom floats, if any.
+%
+% \item[\plug{footnotes-space-floats}]
+%
+% As before but the \cs{vfill} is between footnotes and floats.
+%
+% \item[\plug{floats-space-footnotes}]
+%
+% Floats are directly after the text, then a space and then
+% footnotes at the bottom.
+%
+% \item[\plug{space-floats-footnotes}]
+%
+% Both floats and footnotes are pushed to the bottom with
+% footnotes last.\footnote{There are two more permutations,
+% but neither of them has ever been requested so they aren't
+% set up by default --- doing that in a class would be trivial
+% though.}
+%
+% \item[\plug{floats-footnotes}]
+%
+% All excess space is distributed across the existing
+% glue on the page, e.g., within the text galley, the
+% separation between blocks, etc.
+% The order is text, floats, footnotes.
+%
+% \item[\plug{footnotes-floats}]
+%
+% As the previous one but floats and footnotes are
+% swapped. This is the \LaTeX{} default for newer document,
+% i.e., this plug is assigned to the socket when
+% \cs{DocumentMetadata} is used.
+%
+% \item[\plug{footnotes-floats-legacy}]
+%
+% As the previous one but \LaTeX{}'s bottom skip bug is not
+% corrected, i.e., in ragged bottom designs where footnotes
+% are supposed to be directly attached to the text, they suddenly
+% appear at the bottom of the page when the page is ended with
+% \cs{newpage} or \cs{clearpage}.
+% While this is clearly a bug, it was the case since the days
+% of \LaTeX~2.09; thus for
+% compatibility we continue to support this behavior.
+%
+% \end{description}
+%
+%
+% \item[\socket{build/column/footnotes} (0 arguments)]
+%
+% This socket is used to manipulate the footnote
+% material inside \cs{box}\cs{footins}. It if contains code, it
+% is supposed to do some processing of that box and then write
+% the result back into it (and nothing else!). By default it
+% does nothing, i.e., has the \plug{noop} assigned.
+%
+% If (short) footnotes are run as a paragraph this socket gets
+% the plug \plug{para} assigned which is defined elsewhere.
+%
+% \end{description}
+%
+% \subsubsection{Tagging sockets}
+%
+% The following sockets are used to implement tagging. They are used
+% via \cs{UseTaggingSocket} which turns them off when tagging is
+% disabled.
+% For each of them a \plug{default} plug is implemented that holds the tagging code.
+%
+% \begin{description}
+%
+% \item[\socket{build/column/outputbox} (0 arguments)]
+% This socket is used to add any missing tagging structures to the
+% \cs{@outputbox} box, if necessary.
+%
+% \item[\socket{build/column/footins} (0 arguments)]
+% This socket is used to add any missing tagging structures to
+% \cs{footins} box, if necessary.
+%
+% \item[\socket{build/page/header} (2 arguments)]
+%
+% This socket receives the content of the formatted page header
+% as its second argument and adds the necessary tagging around
+% it. The first argument is empty as no special setup is
+% necessary.
+%
+% \item[\socket{build/page/footer} (2 arguments)]
+%
+% This socket receives the content of the formatted page footer
+% as its second argument and adds the necessary tagging around
+% it. The first argument is empty as no special setup is
+% necessary.
+%
+% \end{description}
+%
+%
+%
+%
+%
+% \subsubsection{Output routine commands}
+%
+%
+%
+%
% \begin{macro}{\output}
% \changes{v1.0f}{1993/12/05}{Command changed}
% \begin{macro}{\@specialoutput}
@@ -1694,172 +1948,136 @@
% \end{macro}
%
%
+% \begin{macrocode}
+%<*2ekernel|latexrelease>
+%<latexrelease>\IncludeInRelease{2025/06/01}%
+%<latexrelease> {\@makecol}{\@makecol adding hooks/sockets}%
+% \end{macrocode}
+%
% \begin{macro}{\@makecol}
% \changes{v0.1c}{1993/11/23}{Command changed}
% \changes{v1.0b}{1993/11/29}{\cs{@makespecialcolbox} added}
-% We must rewrite this macro to allow for variations in page-makeup
-% required by changes in page-length.
-%
-% This uses a different macro if a special-length column is being
-% produced.
+% \changes{v1.4m}{2025/02/14}{Use sockets and hooks}
%
+% \cs{@makecol} is shortened a lot, basically all the hardwired
+% code in the middle has moved into a socket.
% \begin{macrocode}
-%<*2ekernel>
-\gdef \@makecol {%
- \ifvoid\footins
- \setbox\@outputbox \box\@cclv
- \else
- \setbox\@outputbox \vbox {%
+\def \@makecol {%
% \end{macrocode}
-% This |\boxmaxdepth| setting is to ensure that deep footnotes
-% do not overwrite the footer (on account of the negative skip
-% added later): it should use |\@maxdepth| otherwise the change is
-% pointless when there are footnotes.
-% \task{CAR}{Investigate providing an option to put the footnotes
-% below the bottom floats.}
-%
-% But see also its use when combining floats.
-% \changes{v1.0l}{1994/03/15}{\cs{maxdepth} changed to \cs{@maxdepth}}
+% A number of packages want to prepend code to \cs{@makecol}; this
+% is the hook for that:
% \begin{macrocode}
- \boxmaxdepth \@maxdepth
+ \UseHook {build/column/before}%
% \end{macrocode}
-%
-% \changes{v1.2e}{1999/01/06}{Added negative vskip, as when processing
-% outputbox below: suggested by Fred Bartlett pr/2892}
-% \changes{1.2i}{2000/07/12}{Removed negative vskip, as it gives
-% unacceptable results when the depth is large: pr/3189}
-% \changes{v1.2m}{2004/10/20}{Removed dead code}
-% \task{CAR}{As can be seen from the above two changes, getting a good
-% layout here is difficult: fix!}
+% Save away box 255 as \cs{@outputbox} to make it available for further adjustments.
% \begin{macrocode}
-% \@tempdima\dp\@cclv
- \unvbox \@cclv
-% \vskip-\@tempdima
- \vskip \skip\footins
+ \setbox\@outputbox \box\@cclv
% \end{macrocode}
-% \changes{v1.1a}{1994/10/31}
-% {(DPC/CAR) Colour resetting moved to here}
+% The only real addition is the next command which either does
+% nothing or removes an infinite glue from the bottom of the
+% \cs{@outputbox}.
% \begin{macrocode}
- \color@begingroup
- \normalcolor
- \footnoterule
- \unvbox \footins
- \color@endgroup
- }%
- \fi
+ \@outputbox@removebskip
+% \end{macrocode}
+% Now a kernel hook for tagging that adjusts the content of
+% \cs{@outputbox}, if necessary. At this point it just contains the material from
+% the galley.
+% \begin{macrocode}
+ \UseTaggingSocket{build/column/outputbox}%
% \end{macrocode}
-% The h floats have now been finally committed to this page so we
-% can reset their list. The top and bottom floats are then added
-% to the page.
+% When this code is run any ``here'' floats in the \cs{@outputbox}
+% are already handled, so we recycle their registers and put them
+% back to the \cs{@freelist}.
+% \changes{v1.0h}{1993/12/12}{defs changed to lets}
% \changes{v1.2k}{2003/12/16}{Ensure that \cs{@elt} has a defined
% state (pr/3586)}
% \begin{macrocode}
- \let\@elt\relax
- \xdef\@freelist{\@freelist\@midlist}%
+ \let\@elt\relax
+ \xdef\@freelist{\@freelist\@midlist}%
+ \global \let \@midlist \@empty
% \end{macrocode}
-% \changes{v1.0h}{1993/12/12}{defs changed to lets}
+% Here we have the configurable part. This socket is supposed to
+% add floats, footnotes and stretchable vertical space as
+% appropriate to the \cs{@outputbox}. It is used by packages such
+% as \pkg{footmisc} to implement different layout, e.g., footnotes
+% above or below bottom floats, etc.
% \begin{macrocode}
- \global \let \@midlist \@empty
- \@combinefloats
+ \UseSocket {build/column/outputbox}%
% \end{macrocode}
-% The variations start here in case |\enlargethispage| has
-% been used.
+% Then we deal with any \cs{enlargethispage} or run the normal code
+% to build a column.
% \begin{macrocode}
- \ifvbox\@kludgeins
- \@makespecialcolbox
- \else
+ \ifvbox\@kludgeins
+ \@make@specialcolbox
+ \else
+ \@make@normalcolbox
+ \fi
+ \global \maxdepth \@maxdepth
% \end{macrocode}
-% This extra reboxing is only needed to add the
-% |\@texttop| and |\@textbotttom| but this could be done earlier,
-% when the floats are added.
-%
-% The |\boxmaxdepth| resetting here will have no effect unless
-% |\@textbottom| ends with a box or rule. So is this (or possibly
-% |\@maxdepth|) the correct value?
-%
-% The |\vskip -\dimen@|
-% ensures that the visible depth of the box does not
-% affect the placement of anything on the page.
-% Thus very deep pages will overprint the footer; but these should
-% have been prevented by suitable settings of the maxdepths at
-% appropriate times.
+% Finally, another hook for external packages or classes that want
+% to augment or alter the output routine by appending to \cs{@makecol}.
+% \begin{macrocode}
+ \UseHook {build/column/after}%
+}
+% \end{macrocode}
+% \end{macro}
%
-% If |\@textbottom| ends with a box or rule of non-zero depth
-% then this skip adjustment should be done again after it.
+% \begin{macro}{\@outputbox@depth}
+% \changes{v1.4m}{2025/02/14}{Macro added}
+% We need to know the depth of \cs{@outputbox} once in a
+% while. Rather than using a temp dimen (as it was done in the
+% past), we give it a proper register.
+% \begin{macrocode}
+\newdimen\@outputbox@depth
+% \end{macrocode}
+% \end{macro}
%
-% I think that the final boxing of the main text page could have a
-% common ending which may make it simpler to see what is going on.
%
-% This needs further investigation, especially in the `special
-% case'.
-% \task{CAR}{Further investigation of makecol}
+% \begin{macro}{\@make@normalcolbox}
+% \changes{v1.4m}{2025/02/14}{Macro added}
+% Taken out of \cs{@makecol} for readability.
%
-% Also, the |\boxmaxdepth| setting here affects what happens within
-% |\@texttop| and |\@textbottom|, should it? Is it needed at all?
% \changes{v1.0l}{1994/03/15}{Removed boxmaxdepth setting.}
-%
-% RmS 91/10/22: Replaced |\dimen128| by |\dimen@|.
-%
% \begin{macrocode}
- \setbox\@outputbox \vbox to\@colht {%
-% \boxmaxdepth \maxdepth %??
+\def \@make@normalcolbox {%
+ \setbox\@outputbox \vbox to\@colht {%
\@texttop
- \dimen@ \dp\@outputbox
+ \@outputbox@depth \dp\@outputbox
\unvbox \@outputbox
- \vskip -\dimen@
- \@textbottom
- }%
- \fi
- \global \maxdepth \@maxdepth
-}
% \end{macrocode}
-% \end{macro}
+% The |\vskip -\@outputbox@depth@| ensures that the visible depth
+% of the box does not affect the placement of anything on the page.
+% Thus very deep pages will overprint the footer; but these should
+% have been prevented by suitable settings of the maxdepths at
+% appropriate times.
%
-% \begin{macro}{\@reinserts}
-% \changes{v1.0e}{1993/12/01}{Command added}
-% This is the code which reinserts the inserts. It puts them all
-% in one place; this can make some of them come out on the wrong
-% page.
-% It has been put into a separate macro to expedite experimentation.
+% If |\@textbottom| ends with a box or rule of non-zero depth then
+% this skip adjustment should be done again after it.
% \begin{macrocode}
-\gdef \@reinserts{%
- \ifvoid\footins\else\insert\footins{\unvbox\footins}\fi
- \ifvbox\@kludgeins\insert\@kludgeins
- {\unvbox\@kludgeins}\fi
+ \vskip -\@outputbox@depth
+ \@textbottom
+ }%
}
-%</2ekernel>
% \end{macrocode}
% \end{macro}
%
-%
-%
-% \begin{macro}{\@makespecialcolbox}
-% \changes{v1.0b}{1993/11/29}{Command added}
-% This implements certain variations in page-makeup.
+% \begin{macro}{\@make@specialcolbox}
+% \changes{v1.4m}{2025/02/14}{Macro added}
+% Make the colbox when \cs{enlargethispage} was used.
% \begin{macrocode}
-%<*2ekernel|fltrace>
-\gdef \@makespecialcolbox {%
+%</2ekernel|latexrelease>
+%<*2ekernel|latexrelease|fltrace>
+\def \@make@specialcolbox {%
%<*trace>
\fl@trace{Kludgeins ht \the\ht\@kludgeins\space
dp \the\dp\@kludgeins\space
wd \the\wd\@kludgeins}%
%</trace>
+ \@outputbox@append {\vskip-\@outputbox@depth}%
+ \@tempdima \@colht
% \end{macrocode}
-% First we find the natural height of the column.
%
-% See above for discussion of what is happening here.
-%
-% This needs further investigation, especially in this `special
-% case'.
-% \changes{v1.0k}{1994/02/08}{boxmaxdepth setting removed}
% \begin{macrocode}
- \setbox\@outputbox \vbox {%
- \@texttop
- \dimen@ \dp\@outputbox
- \unvbox\@outputbox
- \vskip-\dimen@
- }%
- \@tempdima \@colht
\ifdim \wd\@kludgeins>\z@
% \end{macrocode}
% Note that in this case (the *-version), the height of the
@@ -1889,10 +2107,6 @@
% space added to force shrinking.
% \task{CAR}{Further investigation of kludge-* space}
%
-% See above for a discussion of the |\boxmaxdepth| setting here.
-%
-% \changes{v1.0k}{1994/02/08}{boxmaxdepth setting added}
-% \changes{v1.0l}{1994/03/15}{Removed boxmaxdepth setting.}
% \begin{macrocode}
\advance \@tempdima -\ht\@outputbox
\advance \@tempdima \pageshrink
@@ -1903,7 +2117,6 @@
\fl@trace {Hence, space added: \the \@tempdima}%
%</trace>
\setbox\@outputbox \vbox to \@colht {%
-% \boxmaxdepth \maxdepth
\unvbox\@outputbox
\vskip \@tempdima
\@textbottom
@@ -1940,23 +2153,592 @@
\@textbottom}%
\vss}%
\fi
-% \end{macrocode}
-% Finally we need to explicitly make the insert box void.
-% \begin{macrocode}
{\setbox \@tempboxa \box \@kludgeins}%
%<*trace>
\fl@trace {kludgeins box made void}%
%</trace>
}
-%</2ekernel|fltrace>
+%</2ekernel|latexrelease|fltrace>
+%<*2ekernel|latexrelease>
% \end{macrocode}
% \end{macro}
%
+%
+%
+%
+% \begin{macro}{\@outputbox@removebskip}
+% \changes{v1.4m}{2025/02/14}{Macro added}
+% \changes{v1.4m}{2025/02/14}{Finally fix bottom skip bug (from 2.09)}
+%
+% This is really a bug fix for the kernel (from the 2.09 days) but
+% one we only make by default in new documents that are using
+% \cs{DocumentMetadata}. If \cs{raggedbottom} is in force,
+% footnotes get attached to the main galley at a distance of
+% \cs{footskip} on all pages except on those that are ended by
+% \cs{newpage} or \cs{clearpage} where the \cs{vfil} from
+% \cs{newpage} pushes the footnotes to the very bottom.
+%
+% This is kind of a weird difference to a page ending with
+% \cs{pagebreak}---in that case the page is also run
+% short, but the footnotes are not pushed to the bottom.
+%
+% In \pkg{footmisc} \cs{@outputbox@removebskip} is only applied when
+% \pkg{footmisc} is called with an option specifying the
+% footnote placement, i.e., not in the default case.
+% In new documents we apply it always.
+% \begin{macrocode}
+\def\@outputbox@removebskip{%
+% \end{macrocode}
+% We first test if we are in a \cs{raggedbottom} layout. If not we
+% do nothing, but we don't disable the code because
+% \cs{raggedbottom} may get used only for some parts of the
+% document.
+% \begin{macrocode}
+ \ifx\@textbottom\relax \else
+% \end{macrocode}
+% In some special circumstances the \cs{@outputbox} might be
+% void. As \cs{@outputbox@append} below would change this, we
+% better handle this case and leave it unchanged in this situation,
+% because otherwise we can't detect that situation any longer
+% (needed, for example, in \pkg{ftnright}).
+% \begin{macrocode}
+ \ifvoid \@outputbox
+ \global\let\@outputbox@reinsertbskip\relax
+ \else
+% \end{macrocode}
+% If not, we drop the final skip at the end of \cs{@outputbox}
+% provided there is one and it has a glue stretch
+% order of 1 or more (i.e., contains a \texttt{fil} or \texttt{fill} part).
+% \begin{macrocode}
+ \@outputbox@append{%
+ \@tempskipa\lastskip
+ \ifnum \gluestretchorder\@tempskipa>\z@
+ \unskip
+% \end{macrocode}
+%
+% \begin{macro}{\@outputbox@reinsertbskip}
+% We also record the value so that it can be reinserted
+% elsewhere. As we have to do this globally, we also need to
+% explicitly reset it if we don't find any such glue.
+% \begin{macrocode}
+ \xdef\@outputbox@reinsertbskip
+ {\noexpand\@outputbox@append{\vskip\the\@tempskipa}}%
+ \else
+ \global\let\@outputbox@reinsertbskip\relax
+ \fi
+ }%
+ \fi
+ \fi
+}
+% \end{macrocode}
+% We need a trivial top-level definition for
+% \cs{@outputbox@reinsertbskip} in case the first page has no
+% bottom glue and the command gets called.
+% \begin{macrocode}
+\let \@outputbox@reinsertbskip \relax
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+%
+%
+% \subsection{The output routine configuration components}
+%
+% Here we provide the comands that are used to define code for the
+% socket \socket{build/column/outputbox}. The all manipulate the
+% \cs{@outputbox} box in one way or another.
+%
+%
+% \begin{macro}{\@outputbox@append}
+% \changes{v1.4m}{2025/02/14}{Macro added}
+%
+% This general purpose command alters the \cs{@outputbox} box by
+% appending material to it. As this is a box typesetting operation
+% we make sure that the last line of the box reflects the true
+% depth of the last line (in case that is needed later). We also
+% expose the current depth of \cs{@outputbox} as
+% \cs{@outputbox@depth} before unboxing so that its value can be
+% used by \verb=#1= if wanted.
+% \begin{macrocode}
+\def\@outputbox@append #1{%
+ \setbox\@outputbox \vbox {%
+% \end{macrocode}
+% This |\boxmaxdepth| setting is to ensure that deep footnotes
+% do not overwrite the footer (on account of the negative skip
+% added later): it should use |\@maxdepth| otherwise the change is
+% pointless when there are footnotes.
+%
+% But see also its use when combining floats.
+% \changes{v1.0l}{1994/03/15}{\cs{maxdepth} changed to \cs{@maxdepth}}
+% \begin{macrocode}
+ \boxmaxdepth \@maxdepth
+ \@outputbox@depth\dp\@outputbox % if needed in #1
+ \unvbox \@outputbox
+ #1%
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%
+% \begin{macro}{\@outputbox@appendfootnotes}
+% \changes{v1.4m}{2025/02/14}{Macro added}
+%
+% This command appends the footnotes to the \cs{@outputbox} (if
+% there are any). If not, then it does nothing.
+% \begin{macrocode}
+\def\@outputbox@appendfootnotes {%
+ \ifvoid\footins \else
+% \end{macrocode}
+% Handling split footnotes need further work so this is for the
+% moment just a dummy that does nothing. It might vanish and get
+% replaced by a socket eventually.
+% \task{fmi}{The code for handling split footnotes will get revised as part
+% of socket handling in the future}
+% \begin{macrocode}
+ \@makecol@handlesplitfootnotes
+% \end{macrocode}
+%
+% The following socket can be used to manipulate the material in
+% \cs{footins} box, for example, if the footnotes are to be presented
+% all together in a single paragraph. By default it does nothing.
+% \begin{macrocode}
+ \UseSocket{build/column/footnotes}%
+% \end{macrocode}
+% Then the footnotes are appended:
+% \begin{macrocode}
+ \@outputbox@append{%
+ \vskip \skip\footins
+% \end{macrocode}
+% This is socket adjusts the tagging of the \cs{footins} box, if necessary.
+% \begin{macrocode}
+ \UseTaggingSocket{build/column/footins}%
+% \end{macrocode}
+%
+% \begin{macrocode}
+ \color@begingroup
+ \normalcolor
+ \footnoterule
+% \end{macrocode}
+% Support for \pkg{pdfcolfoot}, eventually this can go once color
+% is properly supported. The csname is constructed in case the command
+% is not defined, i.e., the package not loaded.
+% \task{fmi}{Fix when no longer needed}
+% \begin{macrocode}
+ \csname pdfcolfoot@current\endcsname
+ \unvbox \footins
+ \color@endgroup
+ }%
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\@makecol@handlesplitfootnotes}
+% For future extensions \ldots
+% \begin{macrocode}
+\let \@makecol@handlesplitfootnotes \@empty
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@outputbox@attachfloats}
+% \changes{v1.4m}{2025/02/14}{Macro added}
+% \begin{macro}{\@outputbox@attachtopfloats}
+% \changes{v1.4m}{2025/02/14}{Macro added}
+% \begin{macro}{\@outputbox@attachbottomfloats}
+% \changes{v1.4m}{2025/02/14}{Macro added}
+% Attaching top and bottom floats can usually be done in one go,
+% but for special layouts we might want more control so we provide
+% also separate commands.
+%
+% The next command was called \cs{@combinefloats} in the past.
+% \begin{macrocode}
+\def \@outputbox@attachfloats {%
+ \ifx \@toplist\@empty \else \@cflt \fi
+ \ifx \@botlist\@empty \else \@cflb \fi
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\def \@outputbox@attachtopfloats {%
+ \ifx \@toplist\@empty \else \@cflt \fi
+}
+\def \@outputbox@attachbottomfloats {%
+ \ifx \@botlist\@empty \else \@cflb \fi
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+% The next three conditionals might be useful when setting up running
+% headers and footers so perhaps they should be change to CamelCase
+% names. For now they are internal.
+%
+% \begin{macro}{\@if@flushbottom@TF}
+% \changes{v1.4m}{2025/02/14}{Macro added}
+% Test for \cs{flushbottom} (currently not used).
+% \begin{macrocode}
+\def\@if@flushbottom@TF{%
+ \ifx\@textbottom\relax
+ \expandafter\@firstoftwo
+ \else
+ \expandafter\@secondoftwo
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\@if@footnotes@TF}
+% \changes{v1.4m}{2025/02/14}{Macro added}
+% Test if footnotes are present on the current page.
+% \begin{macrocode}
+\def\@if@footnotes@TF{%
+ \ifvoid\footins
+ \expandafter\@secondoftwo
+ \else
+ \expandafter\@firstoftwo
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\@if@bottomfloats@TF}
+% \changes{v1.4m}{2025/02/14}{Macro added}
+% Test if bottom floats are around.
+% \begin{macrocode}
+\def\@if@bottomfloats@TF{%
+ \ifx \@botlist\@empty
+ \expandafter\@secondoftwo
+ \else
+ \expandafter\@firstoftwo
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%
+%
+%
+% \subsubsection{Configuration sockets}
+%
+% \changes{v1.4m}{2025/02/14}{Use sockets and hooks in OR}
+%
+% \begin{socketdecl}{build/column/outputbox}
+% \changes{v1.4m}{2025/02/14}{Socket added}
+% We have one socket that is supposed to augment the \cs{@outputbox}
+% by attaching floats and footnotes with appropriate spacing.
+% \begin{macrocode}
+\NewSocket{build/column/outputbox}{0}
+% \end{macrocode}
+% \end{socketdecl}
+%
+%
+% The following plugs are available for
+% this socket:
+%
+% \begin{plugdecl}{space-footnotes-floats}
+% After the galley text there is a vertical \cs{vfill} followed by
+% any footnotes followed by the bottom floats, if any.
+% \begin{macrocode}
+\NewSocketPlug {build/column/outputbox}{space-footnotes-floats} {%
+ \@if@footnotes@TF
+ {\@outputbox@append{\vfill}}%
+ {\@if@bottomfloats@TF
+ {\@outputbox@append{\vfill}}%
+ {\@outputbox@reinsertbskip}%
+ }%
+ \@outputbox@appendfootnotes
+ \@outputbox@attachfloats
+}
+% \end{macrocode}
+% \end{plugdecl}
+%
+% \begin{plugdecl}{footnotes-space-floats}
+% As before but the \cs{vfill} is between footnotes and floats.
+% \begin{macrocode}
+\NewSocketPlug {build/column/outputbox}{footnotes-space-floats} {%
+ \@outputbox@appendfootnotes
+ \@if@bottomfloats@TF
+ {\@outputbox@append{\vfill}}%
+ {\@outputbox@reinsertbskip}%
+ \@outputbox@attachfloats
+}
+% \end{macrocode}
+% \end{plugdecl}
+%
+% \begin{plugdecl}{floats-space-footnotes}
+% Floats immediately after the galley text and footnotes at the bottom.
+% \begin{macrocode}
+\NewSocketPlug {build/column/outputbox}{floats-space-footnotes} {%
+ \@outputbox@attachfloats
+ \@if@footnotes@TF
+ {\@outputbox@append{\vfill}}%
+ {\@outputbox@reinsertbskip}%
+ \@outputbox@appendfootnotes
+}
+% \end{macrocode}
+% \end{plugdecl}
+%
+% \begin{plugdecl}{space-floats-footnotes}
+% Both floats and footnotes are pushed to the bottom with
+% footnotes last.\footnote{There are two more
+% permutations, but neither of them has ever been requested so
+% they aren't set up by default --- doing that in a class
+% would be trivial though.}
+% \begin{macrocode}
+\NewSocketPlug {build/column/outputbox}{space-floats-footnotes} {%
+ \@if@footnotes@TF
+ {\@outputbox@append{\vfill}}%
+ {\@if@bottomfloats@TF
+ {\@outputbox@append{\vfill}}%
+ {\@outputbox@reinsertbskip}}%
+ \@outputbox@attachfloats
+ \@outputbox@appendfootnotes
+}
+% \end{macrocode}
+% \end{plugdecl}
+%
+%
+%
+% \begin{plugdecl}{floats-footnotes}
+% All excess space has to be distributed across the existing
+% glue on the page, e.g., within the text galley, the
+% separation between blocks, etc.
+% The order is text, floats, footnotes.
+% \begin{macrocode}
+\NewSocketPlug {build/column/outputbox}{floats-footnotes} {%
+ \@outputbox@attachfloats
+ \@outputbox@appendfootnotes
+% \end{macrocode}
+% We do reinsert the bottom skip from \cs{newpage} if it
+% was taken out earlier. This is, strictly speaking, not necessary
+% in most cases, but it is a \cs{vfil} while \cs{raggedbottom} is
+% only generating \verb=\vspace{0pt plus .0001fil}=, so if you have
+% several \cs{vfil} on the page before the \cs{newpage} you would
+% alter the space distribution if one is taken out.
+% \begin{macrocode}
+ \@outputbox@reinsertbskip
+}
+% \end{macrocode}
+%
+% \end{plugdecl}
+%
+% \begin{plugdecl}{footnotes-floats}
+% \begin{macrocode}
+\NewSocketPlug {build/column/outputbox}{footnotes-floats} {%
+ \@outputbox@appendfootnotes
+ \@outputbox@attachfloats
+ \@outputbox@reinsertbskip
+}
+% \end{macrocode}
+% The \texttt{footnote-floats} plug implements the layout used by
+% \LaTeX{} but with the bottom skip bug corrected. This will be
+% the default when \cs{DocumentMetadata} is used; it can be
+% overwritten either through \pkg{footmisc} or by assigning any of
+% the other plugs (or by coding yet another plug for the socket).
+% \end{plugdecl}
+%
+% \begin{plugdecl}{footnotes-floats-legacy}
+% This implements the 2.09 layout (including its bottom skip bug).
+% \begin{macrocode}
+\NewSocketPlug {build/column/outputbox}{footnotes-floats-legacy} {%
+% \end{macrocode}
+% In the legacy case we don't really want to take out the bottom
+% skip, but rather then altering \cs{@outputbox@removebskip} in
+% \cs{makecol} to do nothing, which we would then have to undo in
+% each other layout, we simply reinsert the dropped skip
+% immediately again.
+% \begin{macrocode}
+ \@outputbox@reinsertbskip
+ \@outputbox@appendfootnotes
+ \@outputbox@attachfloats
+}
+% \end{macrocode}
+% The \texttt{footnote-floats-legacy} plug is the default used by
+% \LaTeX{} when \cs{DocumentMetadata} is not used; it can be
+% overwritten
+% either through \pkg{footmisc} or
+% by assigning any of the other plugs (or by coding yet another
+% plug for the socket).
+% \begin{macrocode}
+\AssignSocketPlug {build/column/outputbox}{footnotes-floats-legacy}
+% \end{macrocode}
+% \end{plugdecl}
+%
+%
+%
+%
+% \begin{socketdecl}{build/column/footnotes}
+%
+% The socket allowing the manipulation of \cs{footins} box
+% (result needs to be moved back in there). Used when footnotes are
+% reformatted into a single paragraph by the
+% \texttt{para} option of \pkg{footmisc}. By default it does nothing.
+% \begin{macrocode}
+\NewSocket{build/column/footnotes}{0}
+% \end{macrocode}
+% \end{socketdecl}
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+% \begin{hookdecl}{build/page/before,
+% build/page/after}
+% \changes{v1.4m}{2025/02/14}{Hook added}
+% Hooks at the start and end of \cs{@outputpage} for use by packages.
+% \begin{macrocode}
+\NewMirroredHookPair{build/page/before}{build/page/after}
+% \end{macrocode}
+% \end{hookdecl}
+%
+%
+%
+% \begin{hookdecl}{build/page/reset}
+% \changes{v1.4m}{2025/02/14}{Hook added}
+% Hook in \cs{@outputpage} to reset special galley conventions
+% within the output routine.
+% \begin{macrocode}
+\NewHook {build/page/reset}
+% \end{macrocode}
+% \end{hookdecl}
+%
+%
+%
+% \begin{hookdecl}{build/column/before,build/column/after}
+% \changes{v1.4m}{2025/02/14}{Hook added}
+% Hooks at the start and end of \cs{@makecol} for use by packages.
+% \begin{macrocode}
+\NewMirroredHookPair{build/column/before}{build/column/after}
+% \end{macrocode}
+% \end{hookdecl}
+%
+%
+%
+% \begin{macrocode}
+%</2ekernel|latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%<latexrelease>\IncludeInRelease{0000/00/00}%
+%<latexrelease> {\@makecol}{\@makecol adding hooks/sockets}%
+%<latexrelease>
+%<latexrelease>\gdef \@makecol {%
+%<latexrelease> \ifvoid\footins
+%<latexrelease> \setbox\@outputbox \box\@cclv
+%<latexrelease> \else
+%<latexrelease> \setbox\@outputbox \vbox {%
+%<latexrelease> \boxmaxdepth \@maxdepth
+%<latexrelease> \unvbox \@cclv
+%<latexrelease> \vskip \skip\footins
+%<latexrelease> \color@begingroup
+%<latexrelease> \normalcolor
+%<latexrelease> \footnoterule
+%<latexrelease> \unvbox \footins
+%<latexrelease> \color@endgroup
+%<latexrelease> }%
+%<latexrelease> \fi
+%<latexrelease> \let\@elt\relax
+%<latexrelease> \xdef\@freelist{\@freelist\@midlist}%
+%<latexrelease> \global \let \@midlist \@empty
+%<latexrelease> \@combinefloats
+%<latexrelease> \ifvbox\@kludgeins
+%<latexrelease> \@makespecialcolbox
+%<latexrelease> \else
+%<latexrelease> \setbox\@outputbox \vbox to\@colht {%
+%<latexrelease> \@texttop
+%<latexrelease> \dimen@ \dp\@outputbox
+%<latexrelease> \unvbox \@outputbox
+%<latexrelease> \vskip -\dimen@
+%<latexrelease> \@textbottom
+%<latexrelease> }%
+%<latexrelease> \fi
+%<latexrelease> \global \maxdepth \@maxdepth
+%<latexrelease>}
+%<latexrelease>
+%<latexrelease>\gdef \@makespecialcolbox {%
+%<latexrelease> \setbox\@outputbox \vbox {%
+%<latexrelease> \@texttop
+%<latexrelease> \dimen@ \dp\@outputbox
+%<latexrelease> \unvbox\@outputbox
+%<latexrelease> \vskip-\dimen@
+%<latexrelease> }%
+%<latexrelease> \@tempdima \@colht
+%<latexrelease> \ifdim \wd\@kludgeins>\z@
+%<latexrelease> \advance \@tempdima -\ht\@outputbox
+%<latexrelease> \advance \@tempdima \pageshrink
+%<latexrelease> \setbox\@outputbox \vbox to \@colht {%
+%<latexrelease> \unvbox\@outputbox
+%<latexrelease> \vskip \@tempdima
+%<latexrelease> \@textbottom
+%<latexrelease> }%
+%<latexrelease> \else
+%<latexrelease> \advance \@tempdima -\ht\@kludgeins
+%<latexrelease> \setbox \@outputbox \vbox to \@colht {%
+%<latexrelease> \vbox to \@tempdima {%
+%<latexrelease> \unvbox\@outputbox
+%<latexrelease> \@textbottom}%
+%<latexrelease> \vss}%
+%<latexrelease> \fi
+%<latexrelease> {\setbox \@tempboxa \box \@kludgeins}%
+%<latexrelease>}
+%<latexrelease>
+%<latexrelease> \let \@make@normalcolbox \@undefined
+%<latexrelease> \let \@make@specialcolbox \@undefined
+%<latexrelease> \let \@outputbox@removebskip \@undefined
+%<latexrelease> \let \@outputbox@reinsertbskip \@undefined
+%<latexrelease>
+%<latexrelease> \let \@outputbox@append \@undefined
+%<latexrelease> \let \@outputbox@appendfootnotes \@undefined
+%<latexrelease> \let \@outputbox@attachfloats \@undefined
+%<latexrelease> \let \@outputbox@attachtopfloats \@undefined
+%<latexrelease> \let \@outputbox@attachbottomfloats \@undefined
+%<latexrelease>
+%<latexrelease> \let \@if@flushbottom@TF \@undefined
+%<latexrelease> \let \@if@footnotes@TF \@undefined
+%<latexrelease> \let \@if@bottomfloats@TF \@undefined
+%<latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%<*2ekernel>
+% \end{macrocode}
+%
+% \begin{macro}{\@reinserts}
+% \changes{v1.0e}{1993/12/01}{Command added}
+% This is the code which reinserts the inserts. It puts them all
+% in one place; this can make some of them come out on the wrong
+% page.
+% It has been put into a separate macro to expedite experimentation.
+% \begin{macrocode}
+\gdef \@reinserts{%
+ \ifvoid\footins\else\insert\footins{\unvbox\footins}\fi
+ \ifvbox\@kludgeins\insert\@kludgeins
+ {\unvbox\@kludgeins}\fi
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
% \begin{macro}{\@texttop}
% \begin{macro}{\@textbottom}
% These do nothing as a default.
% \begin{macrocode}
-%<*2ekernel>
\let \@texttop \relax
\let \@textbottom \relax
% \end{macrocode}
@@ -2028,7 +2810,8 @@
% {New, experimental, versions: need in-lining}
% \changes{v1.1s}{1995/11/10}{In-lined}
% \changes{v1.1w}{1996/09/21}{Added \cs{@parboxrestore} and made
-% consequent deletions: wait for the howls of protest}
+% consequent deletions: wait for the howls of protest}
+% \changes{v1.4m}{2025/02/14}{Hooks and sockets added}
%
% The |\color@hbox| hooks here are used to avoid putting just a
% colour special into an otherwise empty box (in a header or
@@ -2068,7 +2851,20 @@
%<latexrelease>\IncludeInRelease{2025/06/01}%
%<latexrelease> {\@outputpage}{Use new mark mechanism}%
%<*2ekernel|latexrelease>
-\def\@outputpage{%
+% \end{macrocode}
+% Temp definition to vanish again when something is offered by the backend:
+% \begin{macrocode}
+\protected \def \pdfannot@link@on@@ { \csname pdfannot_link_on:\endcsname }
+\protected \def \pdfannot@link@off@@ { \csname pdfannot_link_off:\endcsname }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\def \@outputpage {%
+% \end{macrocode}
+% We start with a hook available to packages that want to prepend
+% code to \cs{@outputpage}.
+% \begin{macrocode}
+ \UseHook {build/page/before}%
% \end{macrocode}
% The |\endgroup| is put in by |\aftergroup|.
% \begin{macrocode}
@@ -2078,7 +2874,12 @@
%
% First the stuff for the writes.
%
-% From here \ldots\ was in the command |\@writesetup|.
+% From here on was orginially in the command |\@writesetup|.
+%
+% The following defenition of \cs{protect} is the one active during
+% the \cs{write} statement that migrate out of the \cs{shipout}
+% box, so even though it is immediately changed below (inside
+% \cs{shipout} it still has to be here!
% \begin{macrocode}
\let \protect \noexpand
% \end{macrocode}
@@ -2146,16 +2947,29 @@
\@parboxrestore
% \end{macrocode}
% \ldots\ to here was in the command |\@writesetup|.
+%
+% Hook to allow adding resets local to the output routine processing, e.g.,
+% in \cs{write} or running headers/footers, for packages that set
+% up special conventions in the main galley that should not leak
+% into the page production just because a page break happens in the
+% middle of such an environment.
+% \begin{macrocode}
+ \UseHook {build/page/reset}%
+% \end{macrocode}
% \begin{macrocode}
\shipout \vbox{%
+% \end{macrocode}
+% Inside the \cs{shipout} box we have a different setting for \cs{protect}.
+% \begin{macrocode}
\set@typeset@protect
\aftergroup \endgroup
% \end{macrocode}
-% Correct? or just restore by ending the group?
+% Once the \cs{shipout} boxs ends \cs{protect} is again
+% \cs{noexpand} which is correct for any \cs{write} statements, but
+% once they are processed we want to get back to the following setting:
% \begin{macrocode}
\aftergroup \set@typeset@protect
% \end{macrocode}
-% This first bit has been moved inside the shipped out box.
%
% Now the setup inside the shipped out box; this should contain all
% the stuff that could only affect typesetting; other stuff may need
@@ -2164,13 +2978,18 @@
% From here \ldots\ was in the command |\@shipoutsetup|.
% \begin{macrocode}
\if@specialpage
- \global\@specialpagefalse\@nameuse{ps@\@specialstyle}%
+ \global \@specialpagefalse
+ \@nameuse {ps@\@specialstyle}%
\fi
\if@twoside
- \ifodd\count\z@ \let\@thehead\@oddhead \let\@thefoot\@oddfoot
- \let\@themargin\oddsidemargin
- \else \let\@thehead\@evenhead
- \let\@thefoot\@evenfoot \let\@themargin\evensidemargin
+ \ifodd\count\z@
+ \let \@thehead \@oddhead
+ \let \@thefoot \@oddfoot
+ \let \@themargin \oddsidemargin
+ \else
+ \let \@thehead \@evenhead
+ \let \@thefoot \@evenfoot
+ \let \@themargin \evensidemargin
\fi
\fi
% \end{macrocode}
@@ -2199,52 +3018,82 @@
% Reset these here (previously reset separately for head and foot)
% \changes{v1.2b}{1997/04/14}
% {Move \cs{label} and \cs{index} (from patch file)}
+% \changes{v1.4l}{2025/01/21}{Support extended syntax
+% for \cs{label}, \cs{index}, and \cs{glossary} (gh/311)}
+% \changes{v1.4m}{2025/01/23}
+% {Make \cs{label}, \cs{index} and \cs{glossary} truely invisible
+% when typesetting (gh/1638)}
% \begin{macrocode}
- \let\label\@gobble
- \let\index\@gobble
- \let\glossary\@gobble
+ \let \label \@gobble@with@sphack@om
+ \let \index \@gobble@with@sphack@som
+ \let \glossary \@gobble@with@sphack@om
% \end{macrocode}
%
% \begin{macrocode}
- \baselineskip\z@skip \lineskip\z@skip \lineskiplimit\z@
+ \baselineskip \z@skip
+ \lineskip \z@skip
+ \lineskiplimit \z@
% \end{macrocode}
% \ldots\ to here was in the command |\@shipoutsetup|.
% \begin{macrocode}
\@begindvi
\vskip \topmargin
\moveright\@themargin \vbox {%
- \setbox\@tempboxa \vbox to\headheight{%
+ \setbox\@tempboxa \vbox to\headheight {%
\vfil
- \color@hbox
- \normalcolor
- \hb@xt@\textwidth{\@thehead}%
- \color@endbox
% \end{macrocode}
-% 22 Feb 87
-% \begin{macrocode}
- }%
- \dp\@tempboxa \z@
- \box\@tempboxa
+% Tagging socket that receives the header in its second argument to
+% surround the header with appropriate tagging structures (first
+% argument is unused). If tagging is disabled it returns the
+% content of the second argument.
+% \begin{macrocode}
+ \pdfannot@link@off@@
+ \UseTaggingSocket{build/page/header}{}%
+ {
+ \color@hbox
+ \normalcolor
+ \hb@xt@ \textwidth {\@thehead }%
+ \color@endbox
+ }
+ \pdfannot@link@on@@
+ }
+ \dp \@tempboxa \z@
+ \box \@tempboxa
\vskip \headsep
- \box\@outputbox
+ \box \@outputbox
\baselineskip \footskip
- \color@hbox
- \normalcolor
- \hb@xt@\textwidth{\@thefoot}%
- \color@endbox
- }%
- }%
+% \end{macrocode}
+% Tagging socket that receives the footer in its second argument to
+% surround the footer with appropriate tagging structures (first
+% argument is unused). If tagging is disabled it returns the
+% content of the second argument.
+% \begin{macrocode}
+ \pdfannot@link@off@@
+ \UseTaggingSocket{build/page/footer}{}%
+ {
+ \color@hbox
+ \normalcolor
+ \hb@xt@ \textwidth {\@thefoot }%
+ \color@endbox
+ }
+ \pdfannot@link@on@@
+ }
+ }
% \end{macrocode}
% |\endgroup| now inserted by |\aftergroup|
%
% Restore |\if@newlist|
% \begin{macrocode}
- \global\let\if@newlist\@@if@newlist
+ \global \let \if@newlist \@@if@newlist
% \end{macrocode}
%
% \begin{macrocode}
\global \@colht \textheight
\stepcounter{page}%
+% \end{macrocode}
+% Another hook for packages that want to append material to \cs{@outputpage}.
+% \begin{macrocode}
+ \UseHook {build/page/after}%
}
%<latexrelease>\EndIncludeInRelease
% \end{macrocode}
@@ -2306,10 +3155,11 @@
%<latexrelease> \global \@colht \textheight
%<latexrelease> \stepcounter{page}%
% \end{macrocode}
-% It is now clear that this does something useful, thanks to Pieter
-% van Oostrum. It is needed because a float page is made without
-% using TeX's page-builder; thus the output routine is never called
-% so the marks are not updated.
+% It is now clear that this does something useful (in the old mark
+% mechanism), thanks to Pieter van Oostrum pointing this out. It
+% is needed because a float page is made without using TeX's
+% page-builder; thus the output routine is never called so the
+% marks are not updated.
% \begin{macrocode}
%<latexrelease> \let\firstmark\botmark
%<latexrelease>}
@@ -2401,7 +3251,26 @@
% \end{macrocode}
% \end{macro}
%
+%
+%
+%
+%
+%
+% \subsubsection{Dealing with floats}
+%
+%
+%
% \begin{macro}{\@combinefloats}
+% \changes{v1.4m}{2025/02/14}{Macro got a new name}
+% Old name for what is now called \cs{@outputbox@attachfloats};
+% kept to support legacy packages.
+% \begin{macrocode}
+\let \@combinefloats \@outputbox@attachfloats
+% \end{macrocode}
+% \end{macro}
+%
+%
+
% \begin{macro}{\@cflt}
% \changes{v1.0h}{1993/12/12}{name changed}
% \begin{macro}{\@cflb}
@@ -2411,14 +3280,6 @@
% moved there; this also agrees with the original pseudocode.
%
% \changes{v1.0h}{1993/12/12}{boxmaxdepth setting moved}
-% \begin{macrocode}
-\def \@combinefloats {%
-% \boxmaxdepth \maxdepth
- \ifx \@toplist\@empty \else \@cflt \fi
- \ifx \@botlist\@empty \else \@cflb \fi
-}
-% \end{macrocode}
-%
% \changes{v1.0h}{1993/12/12}{defs changed to lets}
% \begin{macrocode}
\def \@cflt{%
@@ -2458,7 +3319,7 @@
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
+%
%
% \begin{macro}{\@comflelt}
% \begin{macro}{\@comdblflelt}
@@ -2953,7 +3814,7 @@
%
% \changes{v1.2n}{2015/01/14}{float order in 2-column (latexrelease)}
% \begin{macrocode}
-%<latexrelease|fltrace|flafter>\IncludeInRelease{2015/01/01}%
+%<latexrelease|fltrace|flafter>\IncludeInRelease{2025/06/01}%
%<latexrelease|fltrace|flafter> {\@addtocurcol}{float order in 2-column}%
%<*2ekernel|latexrelease|fltrace|flafter>
\def \@addtocurcol {%
@@ -3001,6 +3862,13 @@
%</trace>
\fi
\advance \@reqcolroom \ht\@currbox
+% \end{macrocode}
+% We save the current value of \cs{@reqcolroom} so that we can
+% return to this value later, in case a test fails that may have added
+% something to it.
+% \changes{v1.4n}{2025/01/29}{Save current value of \cs{@reqcolroom} (gh/1645)}
+% \begin{macrocode}
+ \saved@reqcolroom \@reqcolroom
%<*trace>
\fl@trace{float size = \the \ht \@currbox (addtocurcol)}%
\fl@trace{colroom = \the \@colroom (addtocurcol)}%
@@ -3166,6 +4034,158 @@
}%
%</2ekernel|latexrelease|fltrace|flafter>
%<latexrelease|fltrace|flafter>\EndIncludeInRelease
+% \end{macrocode}
+% The rollback code is rather complicated as it has to account for
+% the fact that we roll back not just the kernel but also the
+% packages \pkg{flafter} and \pkg{fltrace}.
+% \begin{macrocode}
+%<latexrelease|fltrace|flafter>\IncludeInRelease{2015/01/01}%
+%<latexrelease|fltrace|flafter> {\@addtocurcol}{float order in 2-column}%
+%<latexrelease|fltrace|flafter>\def \@addtocurcol {%
+%<*trace>
+%<latexrelease|fltrace|flafter> \fl@trace{***Start addtocurcol}%
+%</trace>
+%<latexrelease|fltrace|flafter> \@insertfalse
+%<latexrelease|fltrace|flafter> \@setfloattypecounts
+%<latexrelease|fltrace|flafter> \ifnum \@fpstype=8
+%<*trace>
+%<latexrelease|fltrace|flafter> \fl@trace{fpstype !p only (addtocurcol): \the \@fpstype = 8?}%
+%</trace>
+%<latexrelease|fltrace|flafter> \else
+%<latexrelease|fltrace|flafter> \ifnum \@fpstype=24
+%<*trace>
+%<latexrelease|fltrace|flafter> \fl@trace{fpstype p only (addtocurcol): \the \@fpstype = 24?}%
+%</trace>
+%<latexrelease|fltrace|flafter> \else
+%<latexrelease|fltrace|flafter> \@flsettextmin
+%<*trace>
+%<latexrelease|fltrace|flafter> \fl@trace{textfloatsheight (before) = \the \@textfloatsheight}%
+%</trace>
+%<latexrelease|fltrace|flafter> \advance \@textmin \@textfloatsheight
+%<latexrelease|fltrace|flafter> \@reqcolroom \@pageht
+%<*trace>
+%<latexrelease|fltrace|flafter> \fl@trace{textmin + textfloatsheight: \the \@textmin}%
+%<latexrelease|fltrace|flafter> \fl@trace{page-so-far: \the \@reqcolroom}%
+%</trace>
+%<latexrelease|fltrace|flafter> \ifdim \@textmin>\@reqcolroom
+%<latexrelease|fltrace|flafter> \@reqcolroom \@textmin
+%<*trace>
+%<latexrelease|fltrace|flafter> \fl@trace{ORD? textmin being used}%
+%</trace>
+%<latexrelease|fltrace|flafter> \fi
+%<latexrelease|fltrace|flafter> \advance \@reqcolroom \ht\@currbox
+%<*trace>
+%<latexrelease|fltrace|flafter> \fl@trace{float size = \the \ht \@currbox (addtocurcol)}%
+%<latexrelease|fltrace|flafter> \fl@trace{colroom = \the \@colroom (addtocurcol)}%
+%<latexrelease|fltrace|flafter> \fl@trace{reqcolroom = \the \@reqcolroom (addtocurcol)}%
+%</trace>
+%<latexrelease|fltrace|flafter> \ifdim \@colroom>\@reqcolroom
+%<latexrelease|fltrace|flafter> \@flsetnum \@colnum
+%<latexrelease|fltrace|flafter> \ifnum \@colnum>\z@
+%<latexrelease|fltrace|flafter> \@bitor\@currtype\@deferlist
+%<latexrelease|fltrace|flafter> \@testwrongwidth\@currbox
+%<*trace>
+%<latexrelease|fltrace|flafter> \fl@trace{deferlist: \@deferlist: (addtocurcol-before)}%
+%</trace>
+%<latexrelease|fltrace|flafter> \if@test
+%<*trace>
+%<latexrelease|fltrace|flafter> \fl@trace{type already on list: defer (addtocurcol)}%
+%</trace>
+%<latexrelease|fltrace|flafter> \else
+%<latexrelease|fltrace|flafter> \@bitor\@currtype\@botlist
+%<*trace>
+%<latexrelease|fltrace|flafter> \fl@trace{botlist: \@botlist: (addtocurcol-before)}%
+%</trace>
+%<latexrelease|fltrace|flafter> \if@test
+%<*trace>
+%<latexrelease|fltrace|flafter> \fl@trace{type already on list: bot---sent to addtobot}%
+%</trace>
+%<latexrelease|fltrace|flafter> \@addtobot
+%<latexrelease|fltrace|flafter> \else
+%<*trace>
+%<latexrelease|fltrace|flafter> \fl@trace{fpstype \ifodd \@tempcnta OK \else not \fi
+%<latexrelease|fltrace|flafter> here: \the \@fpstype}%
+%</trace>
+%<latexrelease|fltrace|flafter> \ifodd \count\@currbox
+%<latexrelease|fltrace|flafter> \advance \@reqcolroom \intextsep
+%<latexrelease|fltrace|flafter> \ifdim \@colroom>\@reqcolroom
+%<latexrelease|fltrace|flafter> \global \advance \@colnum \m@ne
+%<latexrelease|fltrace|flafter> \global \advance \@textfloatsheight \ht\@currbox
+%<latexrelease|fltrace|flafter> \global \advance \@textfloatsheight 2\intextsep
+%<latexrelease|fltrace|flafter> \@cons \@midlist \@currbox
+%<*trace>
+%<latexrelease|fltrace|flafter> \fl@trace{***Success: here}%
+%<latexrelease|fltrace|flafter> \fl@trace{textfloatsheight (after-here) =
+%<latexrelease|fltrace|flafter> \the \@textfloatsheight}%
+%<latexrelease|fltrace|flafter> \fl@trace{colnum (after-here) = \the \@colnum}%
+%</trace>
+%<latexrelease|fltrace|flafter> \if@nobreak
+%<latexrelease|fltrace|flafter> \nobreak
+%<latexrelease|fltrace|flafter> \@nobreakfalse
+%<latexrelease|fltrace|flafter> \everypar{}%
+%<latexrelease|fltrace|flafter> \else
+%<latexrelease|fltrace|flafter> \addpenalty \interlinepenalty
+%<latexrelease|fltrace|flafter> \fi
+%<latexrelease|fltrace|flafter> \vskip \intextsep
+%<latexrelease|fltrace|flafter> \box\@currbox
+%<latexrelease|fltrace|flafter> \penalty\interlinepenalty
+%<latexrelease|fltrace|flafter> \vskip\intextsep
+%<latexrelease|fltrace|flafter> \ifnum\outputpenalty <-\@Mii \vskip -\parskip\fi
+%<latexrelease|fltrace|flafter> \outputpenalty \z@
+%<latexrelease|fltrace|flafter> \@inserttrue
+%<*trace>
+%<latexrelease|fltrace|flafter> \else
+%<latexrelease|fltrace|flafter> \fl@trace{Fail---no room at 2nd test of colroom
+%<latexrelease|fltrace|flafter> (addtocorcol \string\intextsep)}%
+%</trace>
+%<latexrelease|fltrace|flafter> \fi
+%<latexrelease|fltrace|flafter> \fi
+%<latexrelease|fltrace|flafter> \if@insert
+%<latexrelease|fltrace|flafter> \else
+%<*trace>
+%<fltrace|latexrelease> \fl@trace{not here: sent to addtotoporbot}%
+%</trace>
+%<fltrace|latexrelease> \@addtotoporbot
+%<*trace>
+%<flafter> \fl@trace{not here: sent to addtobot}%
+%</trace>
+%<flafter> \@addtobot
+%<latexrelease|fltrace|flafter> \fi
+%<latexrelease|fltrace|flafter> \fi
+%<latexrelease|fltrace|flafter> \fi
+%<*trace>
+%<latexrelease|fltrace|flafter> \else
+%<latexrelease|fltrace|flafter> \fl@trace{Fail: colnum = \the \@colnum:
+%<latexrelease|fltrace|flafter> fpstype \the \@fpstype=ORD?}%
+%<latexrelease|fltrace|flafter> \ifnum \@fpstype<\sixt@@n
+%<latexrelease|fltrace|flafter> \fl@trace{ERROR: BANG float not successful (addtocurcol)}%
+%<latexrelease|fltrace|flafter> \fi
+%</trace>
+%<latexrelease|fltrace|flafter> \fi
+%<*trace>
+%<latexrelease|fltrace|flafter> \else
+%<latexrelease|fltrace|flafter> \fl@trace{Fail---no room: fl box ht: \the \ht \@currbox
+%<latexrelease|fltrace|flafter> (addtocurcol)}%
+%</trace>
+%<latexrelease|fltrace|flafter> \fi
+%<latexrelease|fltrace|flafter> \fi
+%<latexrelease|fltrace|flafter> \fi
+%<latexrelease|fltrace|flafter> \if@insert
+%<latexrelease|fltrace|flafter> \else
+%<latexrelease|fltrace|flafter> \@resethfps
+%<*trace>
+%<latexrelease|fltrace|flafter> \fl@trace{put on deferlist (addtocurcol)}%
+%</trace>
+%<latexrelease|fltrace|flafter> \@cons\@deferlist\@currbox
+%<*trace>
+%<latexrelease|fltrace|flafter> \fl@trace{deferlist: \@deferlist: (addtocurcol-after)}%
+%</trace>
+%<latexrelease|fltrace|flafter> \fi
+%<latexrelease|fltrace|flafter>}%
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<latexrelease|fltrace|flafter>\EndIncludeInRelease
%<latexrelease|fltrace|flafter>\IncludeInRelease{0000/00/00}%
%<latexrelease|fltrace|flafter> {\@addtocurcol}{float order in 2-column}%
%<latexrelease|fltrace|flafter>\def \@addtocurcol {%
@@ -3398,7 +4418,7 @@
% \changes{v1.2n}{2015/01/14}{float order in 2-column (latexrelease)}
% \changes{v1.4b}{2017/12/17}{fix doc guards}
% \begin{macrocode}
-%<latexrelease|fltrace>\IncludeInRelease{2015/01/01}
+%<latexrelease|fltrace>\IncludeInRelease{2025/06/01}
%<latexrelease|fltrace> {\@addtonextcol}{float order in 2-column}%
%<*2ekernel|latexrelease|fltrace>
\def\@addtonextcol{%
@@ -3427,6 +4447,11 @@
\fl@trace{float size: \the \@reqcolroom (addtonextcol)}%
%</trace>
\advance \@reqcolroom \@textmin
+% \end{macrocode}
+%
+% \changes{v1.4n}{2025/01/29}{Save current value of \cs{@reqcolroom} (gh/1645)}
+% \begin{macrocode}
+ \saved@reqcolroom \@reqcolroom
%<*trace>
\fl@trace{colroom = \the \@colroom (addtonextcol)}%
\fl@trace{reqcolroom = \the \@reqcolroom (addtonextcol)}%
@@ -3486,6 +4511,92 @@
}%
%</2ekernel|latexrelease|fltrace>
%<latexrelease|fltrace>\EndIncludeInRelease
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<latexrelease|fltrace>\IncludeInRelease{2015/01/01}
+%<latexrelease|fltrace> {\@addtonextcol}{float order in 2-column}%
+%<latexrelease|fltrace>\def\@addtonextcol{%
+%<latexrelease|fltrace> \begingroup
+%<*trace>
+%<latexrelease|fltrace> \fl@trace{***Start addtonextcol}%
+%</trace>
+%<latexrelease|fltrace> \@insertfalse
+%<latexrelease|fltrace> \@setfloattypecounts
+%<latexrelease|fltrace> \ifnum \@fpstype=8
+%<*trace>
+%<latexrelease|fltrace> \fl@trace{fpstype not curcol: \the \@fpstype = 8?}%
+%</trace>
+%<latexrelease|fltrace> \else
+%<latexrelease|fltrace> \ifnum \@fpstype=24
+%<*trace>
+%<latexrelease|fltrace> \fl@trace{fpstype not curcol: \the \@fpstype = 24?}%
+%</trace>
+%<latexrelease|fltrace> \else
+%<latexrelease|fltrace> \@flsettextmin
+%<*trace>
+%<latexrelease|fltrace> \fl@trace{text-so-far: 0pt (top of col)}%
+%</trace>
+%<latexrelease|fltrace> \@reqcolroom \ht\@currbox
+%<*trace>
+%<latexrelease|fltrace> \fl@trace{float size: \the \@reqcolroom (addtonextcol)}%
+%</trace>
+%<latexrelease|fltrace> \advance \@reqcolroom \@textmin
+%<*trace>
+%<latexrelease|fltrace> \fl@trace{colroom = \the \@colroom (addtonextcol)}%
+%<latexrelease|fltrace> \fl@trace{reqcolroom = \the \@reqcolroom (addtonextcol)}%
+%</trace>
+%<latexrelease|fltrace> \ifdim \@colroom>\@reqcolroom
+%<latexrelease|fltrace> \@flsetnum \@colnum
+%<latexrelease|fltrace> \ifnum\@colnum>\z@
+%<latexrelease|fltrace> \@bitor\@currtype\@deferlist
+%<*trace>
+%<latexrelease|fltrace> \fl@trace{deferlist: \@deferlist: (addtonextcol-before)}%
+%</trace>
+%<latexrelease|fltrace> \@testwrongwidth\@currbox
+%<latexrelease|fltrace> \if@test
+%<*trace>
+%<latexrelease|fltrace> \fl@trace{type already on list: defer (addtonextcol)}%
+%</trace>
+%<latexrelease|fltrace> \else
+%<*trace>
+%<latexrelease|fltrace> \fl@trace{sent to addtotoporbot (addtonextcol)}%
+%</trace>
+%<latexrelease|fltrace> \@addtotoporbot
+%<latexrelease|fltrace> \fi
+%<latexrelease|fltrace> \fi
+%<*trace>
+%<latexrelease|fltrace> \else
+%<latexrelease|fltrace> \fl@trace{Fail---no room: fl box ht: \the \ht \@currbox
+%<latexrelease|fltrace> (addtonextcol)}%
+%</trace>
+%<latexrelease|fltrace> \fi
+%<latexrelease|fltrace> \fi
+%<latexrelease|fltrace> \fi
+%<latexrelease|fltrace> \if@insert
+%<latexrelease|fltrace> \else
+%<*trace>
+%<latexrelease|fltrace> \fl@trace{put back on deferlist (addtonextcol)}%
+%</trace>
+%<latexrelease|fltrace> \@cons\@deferlist\@currbox
+%<*trace>
+%<latexrelease|fltrace> \fl@trace{deferlist: \@deferlist: (addtonextcol-after)}%
+%</trace>
+%<latexrelease|fltrace> \fi
+%<*trace>
+%<latexrelease|fltrace> \fl@trace{End of addtonextcol -- locally counts:}%
+%<latexrelease|fltrace> \fl@trace{col: \the\@colnum. top: \the \@topnum. bot: \the \@botnum.}%
+%</trace>
+%<latexrelease|fltrace> \endgroup
+%<*trace>
+%<latexrelease|fltrace> \fl@trace{End of addtonextcol -- globally counts:}%
+%<latexrelease|fltrace> \fl@trace{col: \the\@colnum. top: \the \@topnum. bot: \the \@botnum.}%
+%</trace>
+%<latexrelease|fltrace>}%
+%<latexrelease|fltrace>\EndIncludeInRelease
+% \end{macrocode}
+%
+% \begin{macrocode}
%<latexrelease|fltrace>\IncludeInRelease{0000/00/00}%
%<latexrelease|fltrace> {\@addtonextcol}{float order in 2-column}%
%<latexrelease|fltrace>\def\@addtonextcol{%
@@ -3924,21 +5035,18 @@
% This part of the file is part of the implementation of the following
% two new commands for \LaTeX2e{}.
%
-%
-% \begin{verbatim}
+%\begin{verbatim}
% \enlargethispage{<dim>}
-% \end{verbatim}
-%
+%\end{verbatim}
% Adds |<dim>| to the height of the current column only. On the printed
% page the bottom of this column is extended downwards by exactly
% |<dim>| without having any effect on the placement of the footer; this
% may result in an overprinting.
%
-% \begin{verbatim}
+%\begin{verbatim}
% \enlargethispage*{<dim>}
-% \end{verbatim}
-%
-% Similar to |\enlargethispage| but it tries to squeeze the column to
+%\end{verbatim}
+%% Similar to |\enlargethispage| but it tries to squeeze the column to
% be printed in as small a space as possible, ie it uses any
% shrinkability in the column. If the column was not explicitly broken
% (\eg with |\pagebreak|) this may result in an overfull box message but
@@ -4317,12 +5425,29 @@
\newcount \@fpstype
\newdimen \@reqcolroom
\newdimen \@textfloatsheight
-%</2ekernel>
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
+%
+% \begin{macro}{\saved@reqcolroom}
+% Saved value of \cs{@reqcolroom}; this is needed when making several tests.
+% \begin{macrocode}
+%</2ekernel>
+%<*2ekernel|latexrelease>
+%<latexrelease>\IncludeInRelease{2025/06/01}%
+%<latexrelease> {\saved@reqcolroom}{float placement calculation}%
+\newdimen \saved@reqcolroom
+%</2ekernel|latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%<latexrelease>\IncludeInRelease{0000/00/00}%
+%<latexrelease> {\saved@reqcolroom}{float placement calculation}%
+%<latexrelease>\let \saved@reqcolroom \@undefined
+%<latexrelease>\EndIncludeInRelease
+% \end{macrocode}
+% \end{macro}
+%
% \begin{macro}{\@fpsadddefault}
% \changes{v1.0f}{1993/12/05}{Command added}
% Adds the default placement to what is already there.
@@ -4563,7 +5688,18 @@
% Sets |@tempswa| true if there is room for |\@currbox|.
%
% \begin{macrocode}
+%</2ekernel|fltrace>
+%<*2ekernel|fltrace|latexrelease>
+%<latexrelease|fltrace>\IncludeInRelease{2025/06/01}%
+%<latexrelease|fltrace> {\@flcheckspace}{float placement calculation}%
\def \@flcheckspace #1#2{%
+% \end{macrocode}
+% When this test is executed, the value of \cs{@reqcolroom} may
+% no longer be correct due to a previous test that altered it. We
+% therefore reset it to a value saved earlier.
+% \changes{v1.4n}{2025/01/29}{Reset current value of \cs{@reqcolroom} (gh/1645)}
+% \begin{macrocode}
+ \@reqcolroom \saved@reqcolroom
\advance \@reqcolroom
\ifx #2\@empty \textfloatsep \else \floatsep \fi
%<*trace>
@@ -4589,7 +5725,7 @@
\fl@trace{BANG float ignoring #1
(flcheckspace \string#1 \string#2):}%
\fl@trace{\@spaces #1 = \the #1. Ht float: \the \ht \@currbox
- BANG}%
+ \space BANG}%
%</trace>
\@tempswatrue
%<*trace>
@@ -4597,7 +5733,7 @@
\fl@trace{Fail---no room (flcheckspace \string#1 \string#2)
(fpstype \the \@fpstype=ORD?):}%
\fl@trace{\@spaces #1 = \the #1. Ht float: \the \ht \@currbox
- ORD?}%
+ \space ORD?}%
%</trace>
\fi
\fi
@@ -4608,7 +5744,60 @@
%</trace>
\fi
}
-%</2ekernel|fltrace>
+%</2ekernel|fltrace|latexrelease>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<latexrelease|fltrace>\EndIncludeInRelease
+%<latexrelease|fltrace>\IncludeInRelease{0000/00/00}%
+%<latexrelease|fltrace> {\@flcheckspace}{float placement calculation}%
+%<latexrelease|fltrace>
+%<latexrelease|fltrace>\def \@flcheckspace #1#2{%
+%<latexrelease|fltrace> \advance \@reqcolroom
+%<latexrelease|fltrace> \ifx #2\@empty \textfloatsep \else \floatsep \fi
+%<*trace>
+%<latexrelease|fltrace> \fl@trace{colroom = \the \@colroom
+%<latexrelease|fltrace> (flcheckspace \string#1 \string#2)}%
+%<latexrelease|fltrace> \fl@trace{reqcolroom = \the \@reqcolroom
+%<latexrelease|fltrace> (flcheckspace \string#1 \string#2)}%
+%</trace>
+%<latexrelease|fltrace> \ifdim \@colroom>\@reqcolroom
+%<latexrelease|fltrace> \ifdim #1>\ht\@currbox
+%<latexrelease|fltrace> \@tempswatrue
+%<*trace>
+%<latexrelease|fltrace> \fl@trace{Space OK: #1 = \the #1 > \the \ht \@currbox
+%<latexrelease|fltrace> (flcheckspace \string#1 \string#2)}%
+%</trace>
+%<latexrelease|fltrace> \else
+%<*trace>
+%<latexrelease|fltrace> \fl@trace{fpstype: \the \@fpstype
+%<latexrelease|fltrace> (flcheckspace \string#1 \string#2)}%
+%</trace>
+%<latexrelease|fltrace> \ifnum \@fpstype<\sixt@@n
+%<*trace>
+%<latexrelease|fltrace> \fl@trace{BANG float ignoring #1
+%<latexrelease|fltrace> (flcheckspace \string#1 \string#2):}%
+%<latexrelease|fltrace> \fl@trace{\@spaces #1 = \the #1. Ht float: \the \ht \@currbox
+%<latexrelease|fltrace> \space BANG}%
+%</trace>
+%<latexrelease|fltrace> \@tempswatrue
+%<*trace>
+%<latexrelease|fltrace> \else
+%<latexrelease|fltrace> \fl@trace{Fail---no room (flcheckspace \string#1 \string#2)
+%<latexrelease|fltrace> (fpstype \the \@fpstype=ORD?):}%
+%<latexrelease|fltrace> \fl@trace{\@spaces #1 = \the #1. Ht float: \the \ht \@currbox
+%<latexrelease|fltrace> \space ORD?}%
+%</trace>
+%<latexrelease|fltrace> \fi
+%<latexrelease|fltrace> \fi
+%<*trace>
+%<latexrelease|fltrace> \else
+%<latexrelease|fltrace> \fl@trace{Fail---no room at 2nd test of colroom
+%<latexrelease|fltrace> (flcheckspace \string#1 \string#2)}%
+%</trace>
+%<latexrelease|fltrace> \fi
+%<latexrelease|fltrace>}
+%<latexrelease|fltrace>\EndIncludeInRelease
% \end{macrocode}
% \end{macro}
%