% \iffalse meta-comment % %% File: latex-lab-new-or-2.dtx % Copyright (C) 2022-2023 The LaTeX Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this % license or (at your option) any later version. The latest version % of this license is in the file % % https://www.latex-project.org/lppl.txt % % % The development version of the bundle can be found below % % https://github.com/latex3/latex2e/required/latex-lab % % for those people who are interested or want to report an issue. % \def\ltlabneworIIdate{2023-09-04} \def\ltlabneworIIversion{0.85c} %<*driver> \documentclass{l3doc} \EnableCrossrefs \CodelineIndex \begin{document} \DocInput{latex-lab-new-or-2.dtx} \end{document} % % % \fi % % % \title{The \texttt{latex-lab-testphase-new-or-2} code\thanks{}} % \author{Frank Mittelbach, \LaTeX{} Project} % % \date{v\ltlabneworIIversion\ \ltlabneworIIdate} % \maketitle % % \newcommand\fmi[1]{\begin{quote} TODO: \itshape #1\end{quote}} % \newcommand\NEW[1]{\marginpar{\mbox{}\hfill\fbox{New: #1}}} % \providecommand\pkg[1]{\texttt{#1}} % % \providecommand\hook[1]{\texttt{#1\DescribeHook[noprint]{#1}}} % \providecommand\socket[1]{\texttt{#1\DescribeSocket[noprint]{#1}}} % \providecommand\plug[1]{\texttt{#1\DescribePlug[noprint]{#1}}} % % \NewDocElement[printtype=\textit{socket},idxtype=socket,idxgroup=Sockets]{Socket}{socketdecl} % \NewDocElement[printtype=\textit{plug},idxtype=plug,idxgroup=Plugs]{Plug}{plugdecl} % \NewDocElement[printtype=\textit{hook},idxtype=hook,idxgroup=Hooks]{Hook}{hookdecl} % % % \begin{abstract} % This code implements changes to the output routine intended to be % moved in the \LaTeX{} kernel at some point in the future. % \end{abstract} % % % % % \section{Introduction} % % % \section{Hooks and replaceable code blocks} % % % \subsubsection{Replaceable code blocks (sockets)} % % To cater for different layouts with respect to text, footnotes, % and bottom-floats placements there are two sockets for % now. % \begin{description} % \item[\socket{@makecol/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. % % \item[Testing for existence of material] % % \DescribeMacro[noprint]{@if@footnotes@TF} % \DescribeMacro[noprint]{@if@bfloats@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@bfloats@TF} % (names are likely to change). % % \end{description} % % \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{floats-footnotes-space}] % % As before but the \cs{vfill} is at the bottom (page is % ragged bottom). % % \item[\plug{footnotes-space-floats}] % % As before but the \cs{vfill} is between footnotes and floats. % % \item[\plug{space-floats-footnotes}] % % Here the footnotes come 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 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. % % \item[\plug{footnotes-floats}] % % As the previous one but floats and footnotes are % swapped. This is the \LaTeX{} default, i.e., this plug is % assigned to the socket. % % \end{description} % %----------------------- % % \item[\socket{@makecol/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} % % \StopEventually{\setlength\IndexMin{200pt} \PrintIndex } % % % \section{The Implementation} % % \begin{macrocode} %<*package> % \end{macrocode} % % \subsection{File declaration} % \begin{macrocode} \ProvidesPackage{latex-lab-testphase-new-or-2} [\ltlabneworIIdate\space v\ltlabneworIIversion\space Changes to the output routine] % \end{macrocode} % % \subsection{\cs{@makecol} reimplementation} % % In order for other packages to prepend or append code to % \cs{@makecol} the generic command hooks % \texttt{cmd/@makecol/before} and \texttt{cmd/@makecol/after} can % be used, so for now there is nothing we need to do for this. % % % \begin{macro}{\@makecol} % \cs{@makecol} is shortened a lot, basically all the hardwired % code in the middle has moved into a socket. % \begin{macrocode} \def \@makecol {% % \end{macrocode} % Save away box 255 as \cs{@outputbox} to make it available for further adjustments. % \begin{macrocode} \setbox\@outputbox \box\@cclv % \end{macrocode} % 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} \@outputbox@removebskip % \end{macrocode} % Now a kernel hook for tagging. % \fmi{The name is likely to change and it probably will eventually % be replaced with a socket.} % \begin{macrocode} \@kernel@tagsupport@@makecol % \end{macrocode} % 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}. % \begin{macrocode} \let\@elt\relax \xdef\@freelist{\@freelist\@midlist}% \global \let \@midlist \@empty % \end{macrocode} % Here we have the configurable part. This socket is supposed to add floats, % footnotes and stretchable vertical space as appropriate to the \cs{@outputbox}. % \begin{macrocode} \UseSocket{@makecol/outputbox}% % \end{macrocode} % Then we deal with any \cs{enlargethispage} or run the normal code % to build a column. % \begin{macrocode} \ifvbox\@kludgeins \@make@specialcolbox \else \@make@normalcolbox \fi \global \maxdepth \@maxdepth } % \end{macrocode} % \end{macro} % % % \begin{macro}{\@outputbox@depth} % 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} % % \begin{macro}{\@make@normalcolbox} % Taken out of \cs{@makecol} for readability. % \begin{macrocode} \def \@make@normalcolbox {% \setbox\@outputbox \vbox to\@colht {% \@texttop \@outputbox@depth \dp\@outputbox \unvbox \@outputbox \vskip -\@outputbox@depth \@textbottom }% } % \end{macrocode} % \end{macro} % % % \begin{macro}{\@make@specialcolbox} % Make the colbox when \cs{enlargethispage} was used. % \begin{macrocode} \def \@make@specialcolbox {% \@outputbox@append {\vskip-\@outputbox@depth}% \@tempdima \@colht \ifdim \wd\@kludgeins>\z@ \advance \@tempdima -\ht\@outputbox \advance \@tempdima \pageshrink \setbox\@outputbox \vbox to \@colht {% \unvbox\@outputbox \vskip \@tempdima \@textbottom }% \else \advance \@tempdima -\ht\@kludgeins \setbox \@outputbox \vbox to \@colht {% \vbox to \@tempdima {% \unvbox\@outputbox \@textbottom}% \vss}% \fi {\setbox \@tempboxa \box \@kludgeins}% } % \end{macrocode} % \end{macro} % % % \begin{macro}{\@outputbox@removebskip} % % This is really a bug fix for the kernel but one we only % automatically make in new documents that are using \cs{DocumentMetadata}. % \fmi{may make optional for legacy docs} % 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} % We then append some negative glue at the end of \cs{@outputbox} % provided 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@ \vskip-\@tempskipa % \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 } % \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} % % % % \begin{macro}{\@kernel@before@cclv, % \@kernel@before@footins} % These two commands are internal kernel hooks intended for tagging % support in case that is active. They should not be altered by package code! % By default they do nothing (and % may have been defined already by \cs{DocumentMetadata}). % \fmi{The names might change and perhaps each of them is turned % into a socket named something like \socket{tagsupport/before/cclv} % or similar.} % \begin{macrocode} \providecommand\@kernel@before@cclv{} \providecommand\@kernel@before@footins{} % \end{macrocode} % \end{macro} % % % % % \subsection{The output routine configuration components} % % Here we provide the components that are used to define code for the % \socket{@makecol/outputbox} socket. % % % \begin{macro}{\@outputbox@append} % % 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{% % \if!\detokenize{#1}!\else \setbox\@outputbox \vbox {% \boxmaxdepth \@maxdepth \@outputbox@depth\dp\@outputbox % if needed in #1 \unvbox \@outputbox #1% }% % \fi } % \end{macrocode} % \end{macro} % % % % % % \begin{macro}{\@outputbox@appendfootnotes} % % 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} % First come two configuration points: what to do if we are in a split % footnote situation and a second one that does some manipulation % of the \cs{footins} box before it gets appended. % \fmi{The code for handling split footnotes will get revised as part of socket handling in the future} % \begin{macrocode} \@makecol@handlesplitfootnotes % \end{macrocode} % % \begin{macrocode} \UseSocket{@makecol/footnotes}% % \end{macrocode} % Then the footnotes are appended: % \begin{macrocode} \@outputbox@append{% \vskip \skip\footins % \end{macrocode} % This is a kernel hook for tagging. % \fmi{The name is likely to change and it probably will eventually % be replaced with a socket.} % \begin{macrocode} \@kernel@before@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 it % doesn't exist. % \begin{macrocode} \csname pdfcolfoot@current\endcsname \unvbox \footins \color@endgroup }% \fi } % \end{macrocode} % \end{macro} % % % % \begin{macro}{\@outputbox@attachfloats} % \begin{macro}{\@outputbox@attachtopfloats} % \begin{macro}{\@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. % \begin{macrocode} \let \@outputbox@attachfloats \@combinefloats % \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} % % % % % \begin{macro}{\@makecol@handlesplitfootnotes} % \begin{macro}{\@makecol@splitfootnotemessagehook} % This is only an early draft and doesn't do much. % Contains incomplete preparation for tagging commented out. % \fmi{Interfaces and code will change in the future} % \begin{macrocode} \def\@makecol@handlesplitfootnotes {% % \ifx\splitfootnote@continuation\@empty \else % \setbox\footins\vbox{\splitfootnote@continuation\unvbox\footins}% % \global\let\splitfootnote@continuation\@empty % \fi \ifnum\insertpenalties>\z@ \@makecol@splitfootnotemessagehook % \setbox\footins\vbox{\unvbox\footins --- END at split}% % \gdef\splitfootnote@continuation {--- START after split}% \fi } %\def\splitfootnote@continuation{} % \end{macrocode} % This could issue warning if split footnotes are encountered. % \begin{macrocode} \let \@makecol@splitfootnotemessagehook \@empty % \end{macrocode} % \end{macro} % \end{macro} % % % % \begin{socketdecl}{@makecol/footnote} % % 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{@makecol/footnotes}{0} % \end{macrocode} % \end{socketdecl} % % % % \fmi{Some temp interfaces until configuration points are available.} % % \begin{macro}{\@if@flushbottom@TF} % 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} % 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@bfloats@TF} % Test if bottom floats are around. % \begin{macrocode} \def\@if@bfloats@TF{% \ifx \@botlist\@empty \expandafter\@secondoftwo \else \expandafter\@firstoftwo \fi } % \end{macrocode} % \end{macro} % % % % \subsection{The \cs{@makecol} configuration} % % % \begin{socketdecl}{@makecol/outputbox} % We have one socket that is supposed to augment the \cs{@outputbox} % by attaching floats and footnotes with appropriate spacing. % % \begin{macrocode} \NewSocket{@makecol/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 {@makecol/outputbox}{space-footnotes-floats} {% \@if@footnotes@TF {\@outputbox@append{\vfill}}% {\@if@bfloats@TF {\@outputbox@append{\vfill}}% {\@outputbox@reinsertbskip}% }% \@outputbox@appendfootnotes \@outputbox@attachfloats } % \end{macrocode} % \end{plugdecl} % % \begin{plugdecl}{floats-footnotes-space} % As before but the \cs{vfill} is at the bottom (page is ragged % bottom). % \begin{macrocode} \NewSocketPlug {@makecol/outputbox}{floats-footnotes-space} {% \@outputbox@attachfloats \@if@footnotes@TF {\@outputbox@append{\vfill}}% {\@outputbox@reinsertbskip}% \@outputbox@appendfootnotes } % \end{macrocode} % \end{plugdecl} % % \begin{plugdecl}{footnotes-space-floats} % As before but the \cs{vfill} is between footnotes and floats. % \begin{macrocode} \NewSocketPlug {@makecol/outputbox}{footnotes-space-floats} {% \@outputbox@appendfootnotes \@if@bfloats@TF {\@outputbox@append{\vfill}}% {\@outputbox@reinsertbskip}% \@outputbox@attachfloats } % \end{macrocode} % \end{plugdecl} % % \begin{plugdecl}{space-floats-footnotes} % Here the footnotes come 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 {@makecol/outputbox}{space-floats-footnotes} {% \@if@footnotes@TF {\@outputbox@append{\vfill}}% {\@if@bfloats@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 {@makecol/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 {@makecol/outputbox}{footnotes-floats} {% \@outputbox@appendfootnotes \@outputbox@attachfloats \@outputbox@reinsertbskip } % \end{macrocode} % The \texttt{footnote-floats} plug is the default used by % \LaTeX{}; 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 {@makecol/outputbox}{footnotes-floats} % \end{macrocode} % \end{plugdecl} % % % % % % \section {Replacement for the \pkg{footmisc} package} % % The replacement for \pkg{footmisc}. If the new code is used, we must replace % the package if it is loaded by the user: % \begin{macrocode} \declare@file@substitution{footmisc.sty}{latex-lab-footmisc.ltx} % \end{macrocode} % % % % \section {Temp stuff that is related but should go to the kernel} % % This is the code from \texttt{latex-lab-footnotes.dtx}. % \begin{macrocode} \input{latex-lab-footnotes.ltx} % \end{macrocode} % % % \begin{macrocode} % % \end{macrocode} % % \Finale %