summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex-dev
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2022-03-16 21:01:50 +0000
committerKarl Berry <karl@freefriends.org>2022-03-16 21:01:50 +0000
commitedc4da5fa2ccf95dc2d8e78bd12c6532e6074098 (patch)
tree2cbeacd10abcd62cbf748f76a086d6dfb171b5d4 /Master/texmf-dist/source/latex-dev
parent68a75026205e8146e3f641432ffc7e569d4465f0 (diff)
latex-lab-dev (16mar22)
git-svn-id: svn://tug.org/texlive/trunk@62742 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex-dev')
-rw-r--r--Master/texmf-dist/source/latex-dev/latex-lab/documentmetadata-support.dtx4
-rw-r--r--Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-footnotes.dtx1822
-rw-r--r--Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-new-or.dtx545
-rw-r--r--Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-prototype.dtx827
-rw-r--r--Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-testphase.dtx17
-rw-r--r--Master/texmf-dist/source/latex-dev/latex-lab/latex-lab.ins (renamed from Master/texmf-dist/source/latex-dev/latex-lab/documentmetadata-support.ins)20
6 files changed, 3228 insertions, 7 deletions
diff --git a/Master/texmf-dist/source/latex-dev/latex-lab/documentmetadata-support.dtx b/Master/texmf-dist/source/latex-dev/latex-lab/documentmetadata-support.dtx
index 0c7a1d9d80a..7501de151f8 100644
--- a/Master/texmf-dist/source/latex-dev/latex-lab/documentmetadata-support.dtx
+++ b/Master/texmf-dist/source/latex-dev/latex-lab/documentmetadata-support.dtx
@@ -126,7 +126,7 @@
% removed or when the code is moved into the kernel.
% \begin{description}
% \item[\texttt{phase-I}]
-% This value loads code implementing the first phase of the project~\cite{blueprint}, i.e., it
+% This value loads code implementing the first phase of the project~\cite{blueprint}, i.e., it
% will load the tagpdf package. It will also activate tagging by issuing
% |\tagpdfsetup{activate,interwordspace}|. This phase
% is frozen.
@@ -336,9 +336,11 @@
{
\tl_gput_right:Nn\g_@@_testphase_tl
{
+ \AddToDocumentProperties [document]{testphase/#1}{loaded}
\file_if_exist_input:nF {#1-latex-lab-testphase.ltx}
{
\msg_warning:nnn{meta}{latex-lab-pkg-missing}{#1}
+ \AddToDocumentProperties [document]{testphase/#1}{missing}
}
}
}
diff --git a/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-footnotes.dtx b/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-footnotes.dtx
new file mode 100644
index 00000000000..330ae7b0cc8
--- /dev/null
+++ b/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-footnotes.dtx
@@ -0,0 +1,1822 @@
+% \iffalse meta-comment
+%
+%% File: latex-lab-footnotes.dtx
+% Copyright (C) 2022 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.
+%
+%<*driver>
+\documentclass{l3doc}
+\EnableCrossrefs
+\CodelineIndex
+\begin{document}
+ \DocInput{latex-lab-footnotes.dtx}
+\end{document}
+%</driver>
+%
+% \fi
+%
+%
+% \title{The \texttt{latex-lab-footnotes} code\thanks{}}
+% \author{Frank Mittelbach, \LaTeX{} Project}
+%
+% \maketitle
+%
+% \newcommand\fmi[1]{\begin{quote} TODO: \itshape #1\end{quote}}
+% \newcommand\NEW[1]{\marginpar{\mbox{}\hfill\fbox{New: #1}}}
+% \providecommand\class[1]{\texttt{#1.cls}}
+% \providecommand\pkg[1]{\texttt{#1}}
+% \providecommand\hook[1]{\texttt{#1}}
+%
+% \begin{abstract}
+% \emph{to be written}
+% \end{abstract}
+%
+% \tableofcontents
+%
+%
+% \section{Introduction}
+%
+% This code reimplements the footnote interfaces for \LaTeX{}
+% offering configurable methods for layout and functionality
+% adjustments that avoid overwriting each other when used in
+% classes as well as in packages (as far as possible --- obviously
+% some adjustments are mutally exclusive). This is achieved by
+% providing a a larger number of hooks (for areas where different
+% packages/classes can easily coexist with their adjustments) and a
+% number of configuration points to which only one class or package
+% can write to successfully (in case of multiple changes the the
+% last one wins). The latter are for special functionality, e.g.,
+% if footnote text is typeset as a single paragraph, it can't be configured
+% the same time to be typeset vertically with one footnote below
+% each other.
+%
+% The interfaces are set up to support tagged PDF, but in order
+% for this to work, all packages altering the fontnote setup should
+% use the inferfaces provided here and not do it through the
+% legacy methods (though there is some support for the latter as
+% well, but if will not work in a cases).
+%
+% \subsection{Configuration methods}
+%
+% Historically, the footnote setup in \LaTeX{} was done by
+% providing definitions for \cs{@makefnmark} (format the footnote
+% mark in running text and in front of the footnote text) and
+% \cs{@makefntext} (formatting the footnote text and placing a mark
+% in front of it).
+%
+% There was a default definition for \cs{@makefnmark} in the format
+% that was used by most document classes,
+% but \cs{@makefntext} had to be defined in the class itself because
+% the format didn't provide a default. As a result you will find
+% definitions for the latter in all document classes and defintions
+% for \cs{@makefnmark} only in very few.
+%
+% Furthermore, to enable special footnote layouts or provide
+% additional functionality a few packages (and a few classes)
+% overwrote other internal commands of \LaTeX's footnote
+% mechanism. The commands affected in this way are mainly
+% \cs{@footnotemark} and \cs{@footnotetext}. These overwrites could
+% not be used in combination, so either the packages/classes had to
+% be aware of being loaded together (which they sometimes did or
+% tried to) or they would fail by overwriting each other
+% unconditionally.
+%
+% The present rewrite is an attempt to improve this situation, but
+% of course, it will only work if all packages/classes make use of
+% the new interfaces. Fortunately, the number of problematical
+% packages altering these internal commands are fairly small so
+% arranging for updates is a realistic goal --- to achieve properly
+% tagged PDF it is a requirement.
+%
+%
+%
+% \section{Hooks and configuration points}
+%
+% Note: the configuration points do not have an interface mechanism
+% yet and all their names are temporary right now.
+% Also note that configuration points are of interest only to very
+% few specialized packages, mainly \pkg{footmisc}, and packages
+% providing similar functionality---the current documentation is
+% therefore fairly sketchy.
+%
+% In contrast the hooks are of interest to many classes to provide
+% their layout alterations in a way that it works smoothly with
+% other packages handling aspects of foonote formatting.
+%
+%
+% \subsection{Formatting the mark in the main text}
+%
+% This implements formatting the mark\footnote{Like this one.} and
+% its relation to surrounding text, e.g., if several marks appear
+% in the same place, etc.
+%
+%
+% \subsubsection{Configuration points}
+%
+% None: everything is implemented through a single definition for
+% \cs{@footnotemark} that offers a number of hooks that can be used
+% by packages to implement handling of multiple marks and the
+% formatting of marks.
+%
+%
+% \subsubsection{Hooks}
+%
+% The hooks to customize the marks in the text are the following:
+% \begin{description}
+% \item[\hook{fnmark/before}]
+%
+% Executed at the very beginning of \cs{footnotemark}. Currently
+% there are two packages (\pkg{bibarts} and \pkg{chextras}) that
+% prepend material at this point (not ncessarily correctly, e.g.,
+% they do not all check that they are in horizontal mode).
+%
+% This hook is paired with hook \hook{fnmark/after}.
+%
+% \item[\hook{fnmark}]
+%
+% Executed in horizontal mode and after the current space factor
+% has been saved away for reuse. This is where currently code for multiple
+% marks does its preparation (as done by \pkg{footmisc} and
+% others).
+%
+% The hook is only executed in hmode, i.e., not if the mark is
+% generated in math --- maybe that means the multiple handling
+% should happen later?
+%
+% After the hook \cs{nobreak} is executed, so any
+% ``material'' added in the hook is tied to the following mark
+% unless it contains its own permissible penalty.
+%
+% \item[\hook{fnmark/begin}]
+%
+% This hook is executed directly in front of the typeset mark.
+% This is the place where \pkg{hyperref} adds part of its code,
+% i.e., after the \cs{nobreak} mentioned above. With a closer
+% integration of \pkg{hyperref} this hook may not be necessary at
+% all.
+%
+% \item[\hook{fnmark/end}]
+%
+% This hook is executed directly after the typeset mark. It is
+% used by \pkg{hyperref}, \pkg{memhfixc}, \pkg{scrlttr2}, and
+% \pkg{footmisc}. Used, for example, to implement support for
+% multiple marks in succession.
+%
+% It is \emph{not} a reversed hook.
+%
+%
+% \item[\hook{fnmark/after}]
+%
+% This hook is executed at the very end of the \cs{footnotemark} command.
+%
+% It is a reversed hook to pair with \hook{fnmark/before}
+% \end{description}
+%
+%
+%
+%
+% \subsubsection{Additional configuration possibilities}
+%
+% The actual formatting is done through \cs{@makefnmark} --- no
+% special customization support for now.
+%
+%
+%
+% \subsection{Formatting the footnote text}
+%
+% This implements the formatting of the footnote text the way it
+% appears at the bottom of the page (default case), or possibly
+% elsewhere, e.g. in the margin.
+%
+% \subsubsection{Configuration points}
+%
+% To cater for different layout configurations there are four
+% configuration points which can be set only by one package or
+% class, if two packages/classes set them they are mutually
+% incompatible.
+% These are:
+% \begin{description}
+% \item[\cs{@footnotetext@cfgpoint} (1 argument)]
+%
+% This receives all material that is to be processed (or stored)
+% including color protection code and what have you. The default
+% definition is to run \cs{insert}\cs{footins}.
+%
+% \item[\cs{@footnotetext@cfgpointii} (1 argument)]
+%
+% The default definition runs \cs{@makefntext} which contains
+% various hooks for customization. For most scenarios this is
+% sufficient. However, when running all footnotes as a single
+% paragraph at the bottom, then each footnote needs to be
+% prepared prior to storing in the insert and this configuration
+% point allows running extra code to do that.
+%
+% \item[\cs{@footnotetext@cfgpointiii} (no argument)]
+%
+% By default this configuration point adds a strut to the
+% footnote material. so that consecutive footnotes are properly
+% spaced vertically. In some use cases this is not appropriate
+% (e.g., when running all footnotes s a single paragraph) and so
+% this configuration point can cancel the action or do something
+% else instead.
+%
+% The configuration point is executed near the start of the
+% argument for the configuration point
+% \cs{@footnotetext@cfgpointii}.
+%
+% \item[\cs{@footnotetext@cfgpointiv} (no argument)]
+%
+% This configuration point is executed at the very end of the
+% argument passed to \cs{@footnotetext@cfgpointii}.
+% By default it adds a final strut as long as we are still in
+% horizontal mode (i.e., processing the footnote text paragraph.
+% When running several footnotes in one paragraph some additional
+% material (some horizontal glue) needs adding at this point.
+%
+% \end{description}
+% The configuration point \cs{@footnotetext@cfgpointii} runs
+% \cs{@makefntext} and this command contains two further
+% configuration points (and a few hooks):
+% \begin{description}
+% \item[\cs{@makefntext@cfgpoint} (1 argument)]
+%
+% This configuration point receives the material to typeset the
+% footnote mark. By default, all it does is running \cs{indent}
+% to get a paragraph indentation (if one is set up---in most
+% layouts it is 0~points) and then typesets the mark, but in
+% some designs it executes more elaborate code.
+%
+% If tagging is produced this configuration point is also
+% responsible for surrounding the mark with the appropriate tags
+% marking the mark as an Lbl. It does this using the command \cs{tag@FELbl}.
+%
+% \item[\cs{@makefntext@cfgpointii} (1 argument)]
+%
+% This configuration point manages the formatting of the footnote
+% text once the mark has been typeset.
+%
+% If tagging is produced this configuration point is also
+% responsible for surrounding the mark with the appropriate tags
+% marking the mark as an MC of type FENote. It does this using
+% the command \cs{tag@FENote}.
+%
+% \end{description}
+%
+%
+% The above configuration points are sufficient to implement all
+% commonly used footnote layouts assuming L-R typesetting. For R-L
+% typesetting they or may or may not need some extension (though
+% that is not clear right now).
+%
+%
+%
+% \subsubsection{Hooks}
+%
+% \begin{description}
+% \item[\hook{fntext/before}]
+%
+% Executed at the very beginning of \cs{footnotetext}. Currently
+% there is on package (\pkg{linguex}) that
+% prepends material at this point.
+%
+% This hook is paired with hook \hook{fnmark/after}.
+%
+% \item[\hook{fntext}]
+%
+% Executed at the beginning of the material passed to the first
+% configuration point. Typically used to set any baseline
+% stretch for the footnote text, e.g., by \pkg{setspace},
+% \pkg{footmisc}, \class{uathesis} and others. Could be done in a
+% later hook but is a bit more efficient here.
+%
+% After the hook has run, the font is established, i.e., it can't
+% be used to set a different font size.
+%
+% \item[\hook{fntext/para}]
+%
+% After the font is set default paragraph parameters are set up
+% including \cs{interlinepenalty}, \cs{hsize}, \cs{parindent} and
+% a number of others, as some of them depend on the font
+% size. Then the \hook{fntext/para} is run. If one wants to
+% change the font size, it is probably necessary to reset these
+% other parameters too, e.g., \cs{parindent}, which can be done
+% here.
+%
+% The configuration point \cs{@footnotetext@cfgpointii} normally
+% runs the command \cs{@makefntext} or some code that eventually
+% runs this command, and this then produces the footnote mark (in
+% front of the footnote text) and the formatted footnote text. In
+% front of both the mark and the footnote text some classes have
+% placed paragraph parameter adjustments in their redefinition of
+% \cs{@makefntext}. However, there is no need to place it there
+% it could equally well go into the \hook{fntext/para} hook. We
+% therefore do not provide another hook at this point.
+%
+% \item[\hook{fntext/begin} \& \hook{fntext/end}]
+%
+% The footnote text itself is surrounded by the hooks
+% \hook{fntext/begin} and \hook{fntext/end}. The two hooks are
+% not paired as they are typically used independently.
+%
+% \item[\hook{fntext/after}]
+%
+% At the very end of \cs{footnotetext} we execute the hook
+% \hook{fntext/after} which is a reversed hook paired with
+% \hook{fntext/before}. Some packages, e.g., \pkg{linuex}, have
+% code in that position.
+%
+% \end{description}
+%
+%
+%
+%
+% \subsubsection{Additional configuration possibilities}
+%
+% The formatting of the footnote mark in front of the footnote
+% texts is influenced by the setting of the dimen parameter
+% \cs{footnotemargin}. By default its value is 1.8em in the current
+% text font (or \texttt{-}\cs{maxdimen} when the para option is
+% chosen). The following rules apply:
+% \begin{itemize}
+% \item
+%
+% If it has the value \texttt{-}\cs{maxdimen} then the mark is
+% generated by \cs{@makefnmark}.
+%
+% \item
+%
+% Otherwise, if the value is
+% negative then the mark is placed into an \cs{llap} left aligned
+% in a box of size \texttt{-}\cs{footnotemargin}.
+%
+% \item
+%
+% If the value is zero an \cs{llap} is used without an inner box.
+%
+% \item
+%
+% If the value is greater zero (but less than \cs{maxdimen}) the
+% mark is placed right aligned into a box of size
+% \cs{footnotemargin}.
+%
+% \item
+%
+% The value \cs{maxdimen} is used as a marker to indicate that
+% no value was given and that the default should be used,
+% i.e. 1.8em or \texttt{-}\cs{maxdimen} depending on the chosen
+% option.
+% \end{itemize}
+%
+%
+% \section{Tagging support}
+%
+% \emph{To be documented}
+%
+%
+%
+%
+% \MaybeStop{\setlength\IndexMin{200pt} \PrintIndex }
+%
+%
+% \section{The Implementation}
+%
+% All this is very rough and misses a lot of documentation.
+%
+% \begin{macrocode}
+%<*kernel>
+%<@@=fnote>
+% \end{macrocode}
+%
+% \subsection{File declaration}
+% \begin{macrocode}
+\ProvidesFile{latex-lab-footnotes.ltx}
+ [2022-03-10 v0.6a changes to the footnote interfaces]
+% \end{macrocode}
+%
+% \begin{macrocode}
+
+% latex.ltx
+
+ % not looked at yet
+
+\long\def\@mpfootnotetext#1{%
+ \global\setbox\@mpfootins\vbox{%
+ \unvbox\@mpfootins
+ \reset@font\footnotesize
+ \hsize\columnwidth
+ \@parboxrestore
+ \def\@currentcounter{mpfootnote}%
+ \protected@edef\@currentlabel
+ {\csname p@mpfootnote\endcsname\@thefnmark}%
+ \color@begingroup
+ \@makefntext{%
+ \rule\z@\footnotesep\ignorespaces#1\@finalstrut\strutbox}%
+ \par
+ \color@endgroup}}
+
+
+\def\@makefnmark{\hbox{\@textsuperscript{\normalfont\@thefnmark}}}
+
+
+
+\def\@mpfn{footnote}
+\def\thempfn{\thefootnote}
+
+
+
+%-------------------------------------
+
+
+\ExplSyntaxOn
+
+
+\cs_new_protected:Npn \fnote_step_fnmark:nn #1#2 {
+ \tl_if_novalue:nTF {#1}
+ {
+ \stepcounter {#2}
+ \protected@xdef \@thefnmark { \use:c { the#2 } }
+ }
+ {
+ \group_begin:
+% \end{macrocode}
+% Note that this is a local assignment even though \LaTeX{}
+% counters are normally globally changed. This is the way it was in
+% 2e and so far we haven't changed it. The alternative would be to
+% store the current value and restore it after \cs{@thefnmark} is
+% altered.
+% \begin{macrocode}
+ \int_set:cn { c@#2 }{ #1 }
+ \unrestored@protected@xdef \@thefnmark { \use:c { the#2 } }
+ \group_end:
+ }
+}
+
+\cs_new_protected:Npn \fnote_set_fnmark:nn #1#2 {
+ \tl_if_novalue:nTF {#1}
+ {
+ \protected@xdef \@thefnmark { \use:c { the#2 } }
+ }
+ {
+ \group_begin:
+ \int_set:cn { c@#2 }{ #1 }
+ \unrestored@protected@xdef \@thefnmark { \use:c { the#2 } }
+ \group_end:
+ }
+}
+
+%-------------------------------------
+
+% the debugging code is just temp
+\bool_new:N \g_fnote_debug_bool
+\bool_gset_true:N \g_fnote_debug_bool % for now we have debugging turned on by default
+
+%-------------------------------------
+
+
+
+\NewMirroredHookPair{fnmark/before}{fnmark/after}
+\NewHook{fnmark}
+\NewHook{fnmark/begin}
+\NewHook{fnmark/end}
+
+
+\cs_new:Npn \@@_debug_footnotemark: {
+ \bool_if:NT \g_fnote_debug_bool
+ {
+ \LogHook{fnmark/before}
+ \LogHook{fnmark}
+ \LogHook{fnmark/begin}
+ \LogHook{fnmark/end}
+ \LogHook{fnmark/after}
+ \cs_gset_eq:NN \@@_debug_footnotemark: \prg_do_nothing:
+ }
+}
+
+
+\cs_new_protected:Npn \fnote_footnotemark: {
+ \@@_debug_footnotemark:
+%-------
+% bibarts
+% chextras --- actually in the wrong place does an \unskip
+ \UseHook{fnmark/before}
+%-------
+ \leavevmode
+ \ifhmode
+ \edef\@x@sf{\the\spacefactor}
+%-------
+% bxjsja-minimal.def --- what they do could be done at ``bibarts''
+% (a bit less efficient)
+% memhfixc.sty
+% footmisc.sty
+ \UseHook{fnmark}
+%-------
+ \nobreak
+ \fi
+%-------
+% hyperref.sty
+ \UseHook{fnmark/begin}
+%-------
+ \@kernel@process@makefnmark
+ \@makefnmark
+%-------
+% \end{macrocode}
+% If a footnote mark is placed by its own then it should finish by
+% executing \hook{fnmark/end}, resetting the space factor, and
+% finishing with \hook{fnmark/after}. However, inf a complete
+% footnote these actions have to happen only after we have handled
+% the footnote text (e.g., by placing it into an \cs{insert}. In
+% such a situation \cs{_@@_footmark_finish:} below does nothing
+% and the action is carried out later.
+% \begin{macrocode}
+ \@@_footnotemark_finish:
+}
+
+
+\cs_new:Npn \@@_finish: {
+% hyperref.sty
+% memhfixc.sty --- could move fnmark/after
+% scrlttr2.cls --- could vanish if footmisc uses a hook
+% footmisc.sty
+ \UseHook{fnmark/end}
+%-------
+ \ifhmode
+ \spacefactor \@x@sf \relax
+ \fi
+%
+%-------
+ \UseHook{fnmark/after}
+%-------
+}
+
+
+\cs_new_eq:NN \@@_footnotemark_finish: \@@_finish:
+
+
+
+% Not a public config point but the kernel hook to add tagging
+\def \@kernel@process@makefnmark { }
+
+
+% alterations not covered:
+%
+% ./arabtex/afoot.sty --- too different (and probably too old)
+
+
+% Provide the name \LaTeXe{} is used to.
+
+\cs_set_eq:NN \@footnotemark \fnote_footnotemark:
+
+
+
+%-------------------------------------
+
+\NewMirroredHookPair{fntext/before}{fntext/after}
+\NewHook{fntext}
+\NewHook{fntext/para}
+\NewHook{fntext/begin}
+\NewHook{fntext/end}
+
+
+\cs_new:Npn \@@_debug_footnotetext: {
+ \bool_if:NT \g_fnote_debug_bool
+ {
+ \cs_log:N\@footnotetext@cfgpoint
+ \cs_log:N\@footnotetext@cfgpointii
+ \cs_log:N\@footnotetext@cfgpointiii
+ \cs_log:N\@footnotetext@cfgpointiv
+ \cs_log:N\@makefntext@cfgpoint
+ \cs_log:N\@makefntext@cfgpointii
+ \LogHook{fntext/before}
+ \LogHook{fntext}
+ \LogHook{fntext/para}
+ \LogHook{fntext/begin}
+ \LogHook{fntext/end}
+ \LogHook{fntext/after}
+% \end{macrocode}
+% Show the info only once (if at all).
+% \begin{macrocode}
+ \cs_gset_eq:NN \@@_debug_footnotetext: \prg_do_nothing:
+ }
+ }
+
+\cs_new_protected:Npn \fnote_footnotetext:n #1 {
+ \@@_debug_footnotetext:
+%-------
+% ./linguex/linguex.sty
+ \UseHook{fntext/before}
+%-------
+ \@kernel@process@footnotetext
+ \@footnotetext@cfgpoint { % config point
+%-------
+% resetting baselinestretch ... (could be done further down)
+% ./uafthesis/uafthesis.cls
+% ./setspace/setspace.sty
+% ./footmisc/footmisc.sty (normal)
+ \UseHook{fntext}
+%-------
+ \reset@font
+ \footnotesize
+%-------
+% some classes use a different font size, e.g.,
+% ./nrc/nrc1.cls ./nrc/nrc2.cls
+% but those could be done in fntext/para instead
+%-------
+% \end{macrocode}
+% In case of sidenotes the next settings are pointless, but as they
+% do not hurt (except for the \cs{hsize} setting) and are needed
+% for all other cases we make them here and overwrite them for side notes
+% \begin{macrocode}
+ \interlinepenalty\interfootnotelinepenalty
+ \splittopskip\footnotesep
+ \splitmaxdepth \dp\strutbox
+ \floatingpenalty \@MM
+ \hsize\columnwidth
+ \@parboxrestore
+ \parindent 1em % typical default used in \@makefntext moved up here
+ \def\@currentcounter{footnote}
+ \protected@edef \@currentlabel { \p@footnote \@thefnmark }
+%-------
+% for altering para parameters ...
+% code for resphilosophica came earlier but it could go here.
+% Has the advantage that one can also overwrite \cs{@currentcounter}
+% and \cs{@currentlabel} is that is necessary.
+%
+% ./resphilosophica/resphilosophica.cls
+ \UseHook{fntext/para}
+%-------
+ \color@begingroup
+%-------
+% fnpara wants to replace \@makefntext{...} and para and side option of footmisc etc too ...
+% so we make this a config point
+%-------
+ \@footnotetext@cfgpointii % config point
+ {
+%-------
+% ./resphilosophica/resphilosophica.cls
+%-------
+ \@footnotetext@cfgpointiii % config point
+%-------
+% bibarts
+% fnbreak.sty
+ \UseHook{fntext/begin}
+%-------
+ \ignorespaces
+ #1
+%-------
+% bibarts
+% fnbreak.sty
+ \UseHook{fntext/end}
+%-------
+ \@footnotetext@cfgpointiv % config point
+ }
+ \par
+ \color@endgroup
+ }
+%-------
+% ./linguex/linguex.sty
+ \UseHook{fntext/after}
+%-------
+}
+
+% default for config point (1 arg)
+\cs_new_protected:Npn \@footnotetext@cfgpoint { \insert\footins }
+
+% default for config point (1 arg)
+\cs_new_protected:Npn \@footnotetext@cfgpointii { \@makefntext }
+
+
+% default for config point (0 args)
+\cs_new_protected:Npn \@footnotetext@cfgpointiii { \rule\z@\footnotesep }
+
+% default for config point (0 args)
+\cs_new_protected:Npn \@footnotetext@cfgpointiv { \@finalstrut\strutbox }
+
+
+% kernel hook for tagging (2 args)
+\cs_new_protected:Npn \@kernel@process@footnotetext {}
+
+% Provide the name \LaTeXe{} is used to and do this unconditionally
+% (no patching of class code if any). This means that if a class provides it own
+% definition that gets lost and if necessary needs to be handled
+% with firstaid (or updating of the class.
+
+\AddToHook{begindocument}{
+ \cs_set_eq:NN \@footnotetext \fnote_footnotetext:n
+}
+
+% alterations not covered:
+%
+% ./revtex4-1/revtex4-1.cls ./revtex/ltxutil.sty ./revtex/revtex4-2.cls ... (need analysis)
+% ./bigfoot/bigfoot.sty
+
+
+
+% \footnotemargin is the logic implemented by footmisc. Perhaps we
+% don't want to do this like that in the kernel but for now I have
+% used this interface unchanged.
+
+
+\newdimen\footnotemargin
+\footnotemargin\maxdimen % no value given
+
+\AtBeginDocument{
+ \ifdim \footnotemargin=\maxdimen
+ \setlength\footnotemargin{1.8em}
+ \fi
+}
+
+
+\cs_new_protected:Npn \fnote_makefntext:n #1 {
+% \end{macrocode}
+% Some classes in their redefinition for \cs{@makefntext} have
+% places some paragraph parameters at this point, but those can
+% equally well go into the hook \hook{fntext/para}. We therefore do
+% not provide a further hook at this point.
+% \begin{macrocode}
+ \@makefntext@cfgpoint
+ {
+ \ifdim\footnotemargin>\z@
+ \hb@xt@ \footnotemargin{\hss\@makefnmark}
+ \else
+ \ifdim\footnotemargin=\z@
+ \llap{\@makefnmark}
+ \else
+ \ifdim\footnotemargin=-\maxdimen
+ \@makefnmark
+ \else
+ \llap{\hb@xt@ -\footnotemargin{\@makefnmark\hss}}
+ \fi
+ \fi
+ \fi
+ }
+ \@makefntext@cfgpointii
+ { #1 }
+}
+
+
+
+
+% default for config point (1 arg)
+\cs_new_protected:Npn \@makefntext@cfgpoint { \noindent }
+
+% default for config point (1 arg)
+\cs_new_protected:Npn \@makefntext@cfgpointii #1 { #1 }
+% \end{macrocode}
+%
+%
+%
+% If the definition for \cs{@makefntext} is that of the standard
+% classes then replace it with \cs{fnote_makefntext:n}, otherwise
+% try to patch the definition.
+%
+% Here is the the definition the way it is in
+% \texttt{classes.dtx}. Notice that (for saving space) there is no
+% space after \texttt{em} to terminate the assignment. We need to
+% mimic that, otherwise a test would return false even if the
+% definition has not been modified.
+%
+% \begin{macrocode}
+\newcommand\old@std@class@makefntext[1]{%
+ \parindent 1em%
+ \noindent
+ \hb@xt@1.8em{\hss\@makefnmark}#1}
+
+% \end{macrocode}
+% Here is the messy code for patching. Note that this is only there
+% to help classes along that aren't updated yet so it does some
+% minimal patching to hopefully add configuration points in the
+% right place.
+%
+% What it does is roughly the
+% following: It look for a definition of \cs{@makefntext} of the form
+%\begin{verbatim}
+% {AAA \hbox BBB { CCC } DDD #1 EEE }
+%\end{verbatim}
+% where ``BBB'' is something like \texttt{to 1em} or similar. It then
+% replaces that with
+%\begin{verbatim}
+% {AAA \@makefntext@cfgpoint{\hbox BBB { CCC }} DDD
+% \@makefntext@cfgpointii{#1} EEE }
+%\end{verbatim}
+% The patching is not very careful, i.e., it assumes there is only
+% one \verb=#1= in the replacement text and that a \cs{hbox} found
+% is the right one to patch. But that is enough to cater for all
+% definitions of \cs{@makefntext} out there in the TL distribution.
+%
+% If \cs{hbox} is not found it tries the same looking for
+% \cs{hb@xt@} which is what some classes use and if that is not
+% found either it assume that this is a version that uses
+% \cs{@makefnmark} without surrounding it in a box and if that
+% fails it gives up with an \cs{ERROR} (which needs to get a proper definition).
+% \begin{macrocode}
+
+\tl_new:N \l_@@_patch_tl
+\cs_new_eq:NN \@@_tmp:w \ERROR
+
+\cs_new_protected:Npn \@@_patch:
+ {
+ \tl_set:No \l_@@_patch_tl { \@makefntext { \@makefntext@cfgpointii{##1} } }
+ \tl_if_in:NnTF \l_@@_patch_tl { \hbox }
+ { \cs_set_eq:NN \@@_tmp:w \@@_patch_hbox:w }
+ {
+ \tl_if_in:NnTF \l_@@_patch_tl { \hb@xt@ }
+ { \cs_set_eq:NN \@@_tmp:w \@@_patch_hb@xt@:w }
+ {
+ \tl_if_in:NnTF \l_@@_patch_tl { \@makefnmark }
+ { \cs_set_eq:NN \@@_tmp:w \@@_patch_@makefnmark:w }
+ { \ERROR
+ \cs_set_eq:NN \@@_tmp:w \exp_stop_f: }
+ }
+ }
+ \tl_set:Nf \l_@@_patch_tl
+ { \exp_after:wN \@@_tmp:w \l_@@_patch_tl }
+ \cs_set:Npn \@@_tmp:w { \long \def \@makefntext ####1 }
+ \exp_after:wN \@@_tmp:w \exp_after:wN { \l_@@_patch_tl }
+ }
+% \end{macrocode}
+%
+% If \cs{@makefntext} contains \cs{hbox} then grab ``AAA'' as
+% \verb=#1= and ``BBB'' (up to the open \verb={=) and return it as
+%\begin{verbatim}
+% AAA \@makefntext@processX { \hbox BBB }
+%\end{verbatim}
+% \begin{macrocode}
+\cs_new:Npn \@@_patch_hbox:w #1 \hbox #2 #
+ { \exp_stop_f: #1 \@makefntext@processX { \hbox #2 } }
+% \end{macrocode}
+% Same for the other cases.
+% \begin{macrocode}
+\cs_new:Npn \@@_patch_hb@xt@:w #1 \hb@xt@ #2 #
+ { \exp_stop_f: #1 \@makefntext@processX { \hb@xt@ #2 } }
+\cs_new:Npn \@@_patch_@makefnmark:w #1 \@makefnmark
+ { \exp_stop_f: #1 \@makefntext@processX { \use:n } { \@makefnmark } }
+% \end{macrocode}
+%
+% The code provided by Bruno above expects 2 arguments but we need a
+% different structure so this is a simple reshuffling. Would be
+% better if we can patch the right structure in directly, but I'm
+% not a patch person, so this is the simple way out for now:
+%
+% \begin{macrocode}
+\cs_new:Npn \@makefntext@processX #1#2{\@makefntext@cfgpoint{#1{#2}}}
+% \end{macrocode}
+% At \verb=\begin{document}= check if the current definition is
+% that of the standard classes and if so replace it by
+% \cs{fnote_makefntext:n} otherwise try and patch the definition
+% using the approach above.
+% \begin{macrocode}
+
+\AddToHook{begindocument}{
+ \cs_if_eq:NNTF \@makefntext \old@std@class@makefntext
+ {
+ \cs_set_eq:NN \@makefntext \fnote_makefntext:n
+ }
+ {
+ \@@_patch:
+ }
+}
+
+
+% possibly add the following to check for multiple \hbox in
+% the definition:
+%
+% \seq_set_split:NnV \l_@@_patch_seq { \hbox } \l_@@_patch_tl
+% \int_compare:nT { \seq_count:N \l_@@_patch_seq } > 2 \ERROR
+%
+% \end{macrocode}
+%
+%
+%
+%
+% \subsection{Document-level commands}
+%
+% \begin{macrocode}
+
+\DeclareDocumentCommand\footnotetext {om} {
+ \fnote_set_fnmark:nn {#1} \@mpfn
+ \@footnotetext {#2}
+}
+
+
+%-------------------------------------
+
+
+\DeclareDocumentCommand\footnote {om} {
+ \fnote_step_fnmark:nn {#1} \@mpfn
+ \cs_set_eq:NN \@@_footnotemark_finish: \prg_do_nothing:
+ \@footnotemark
+ \cs_set_eq:NN \@@_footnotemark_finish: \@@_finish:
+ \@footnotetext {#2}
+ \@@_footnotemark_finish:
+}
+
+%-------------------------------------
+
+
+\DeclareDocumentCommand\footnotemark {o} {
+ \fnote_step_fnmark:nn {#1} { footnote }
+ \@footnotemark
+}
+
+
+%-------------------------------------
+
+\DeclareDocumentCommand\footref {m}{%
+ \begingroup
+ \unrestored@protected@xdef\@thefnmark{\ref{#1}}%
+ \endgroup
+ \@footnotemark
+}
+
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=>
+% \end{macrocode}
+%
+%
+%
+%
+%
+%
+% \subsection{Firstaid for packages and classes}
+%
+% \subsubsection{\pkg{setspace}}
+%
+% It should not overwrite it any longer but use a hook, so for now we
+% do just that here.
+% \begin{macrocode}
+\AddToHook{package/setspace/after}
+ {\let \@footnotetext \fnote_footnotetext:n
+ \AddToHook{fntext}[setspace]{\let\baselinestretch\setspace@singlespace}}
+% \end{macrocode}
+%
+%
+%
+%
+% \subsubsection{\pkg{hyperref}}
+%
+% Prevent hyperref from redefining footnote stuff --- this is a
+% temp solution.
+% \begin{macrocode}
+\AddToHook{package/hyperref/after}{
+ \let\H@@footnotetext\fnote_footnotetext:n
+ \let\H@@footnotemark\fnote_footnotemark:
+ \let \@footnotetext \fnote_footnotetext:n
+ \let \@footnotemark \fnote_footnotemark:
+}
+
+
+
+% \end{macrocode}
+%
+% \subsection{Stuff that needs cleanup and documentation}
+%
+% \begin{macrocode}
+
+
+%-------------------------------------
+
+% use of kerns to mark h-mode positions (unit sp)
+%
+% 1 = CJK
+% 2 = CJK
+% 3 = multiple footnotes (footmisc, koma, eledmac, tufte, memoir,
+% parnotes, sidenotes)
+% 3 = outer kern in letter spacing (letterspace)
+% 3 = beginning of list (examdesign.cls)
+% 4 = CJK pigin
+% 5 = CJK ruby
+
+% 1-4 = polyglossia for korean
+
+%-------------------------------------
+
+
+
+%-------------------------------------
+% Tagging
+%-------------------------------------
+
+% hyperref support only when loaded (improve integration)
+
+\newcounter{absfootnote}
+\AddToHook{fnmark/begin}{\stepcounter{absfootnote}} % too simple (fails with opt args)
+
+
+
+% this is rubbish and should be handled better:
+
+\cs_new_protected:Npn \tag_if_loaded:TF { \cs_if_exist:NTF \tag_struct_begin:n }
+
+
+
+\cs_new_protected:Npn \tag@FEMark #1 {
+ \tag_if_loaded:TF
+ {
+ \tag_mc_end_push:
+ \exp_args:Nx
+ \tag_struct_begin:n{tag=Lbl,ref=fn.\the\c@absfootnote}
+ \tag_mc_begin:n{tag=Lbl}
+ \IfPackageLoadedTF{hyperref}{ \hyper@linkstart
+ {link}{fn.\the\c@absfootnote} }{}
+ #1
+ \IfPackageLoadedTF{hyperref}{ \hyper@linkend }{}
+ \tag_mc_end:
+ \tag_struct_end:
+ \tag_mc_begin_pop:n{}
+ }
+ { #1 }
+}
+
+% to be done next round around:
+%
+% \the\c@absfootnote should be replaced directly by some command with default meaning
+% \the\c@absfootnote so that the actual reference can be changed from the outside.
+%
+% there are several instances that are curently hardwired.
+
+\cs_set_eq:NN \@kernel@process@makefnmark \tag@FEMark
+
+
+
+% kernel hook for tagging (2 args)
+\cs_set:Npn \@kernel@process@footnotetext #1#2 {
+ \tag_if_loaded:TF
+ {
+ \tag_mc_end_push:
+ \tag_struct_begin:n { tag=FENote,label=fn.\the\c@absfootnote }
+ #1 {#2}
+ \tag_struct_end:
+ \tag_mc_begin_pop:n{}
+ }
+ { #1 {#2} }
+}
+
+
+
+\cs_set:Npn \@makefntext@cfgpoint #1 {
+ \noindent
+ \cs_if_exist:NT \tag_struct_begin:n { \tag_mc_end_push: }
+ \tag@FELbl { #1 }
+}
+
+\cs_set:Npn \@makefntext@cfgpointii #1 {
+ \tag@FENote { #1 }
+ \cs_if_exist:NT \tag_struct_begin:n { \tag_mc_begin_pop:n{} }
+}
+
+
+
+
+\cs_new_protected:Npn \tag@FELbl #1 {
+ \tag_if_loaded:TF
+ {
+ % target should perhaps be raised ...
+ \IfPackageLoadedTF{hyperref}{ \hypertarget{fn.\the\c@absfootnote}{} }{}
+ %\tag_struct_begin:n { tag=FENote,label=fn.\the\c@absfootnote } %alternativ location for structure
+ \tag_struct_begin:n { tag=Lbl }
+ \tag_mc_begin:n { tag=Lbl }
+ #1
+ \tag_mc_end:
+ \tag_struct_end:
+ }
+ { #1 }
+}
+
+\cs_new_protected:Npn \tag@FENote #1 {
+ \tag_if_loaded:TF
+ {
+ \tag_mc_begin:n{tag=FENote}
+ #1
+ \tag_mc_end:
+ %\tag_struct_end: %alternative location for structure end but ends inside a P
+ }
+ { #1 }
+}
+
+%-------------------------------------
+
+
+\ExplSyntaxOff
+%</kernel>
+% \end{macrocode}
+%
+%
+% \section{Reimplementing the \pkg{footmisc} package}
+%
+% \begin{macrocode}
+%<*footmisc>
+%%
+%% Copyright (c) 1995-2011 Robin Fairbairns
+%% Copyright (c) 2018-2022 Robin Fairbairns, Frank Mittelbach
+%%
+%% This file is part of the `latex-lab Bundle'.
+%% --------------------------------------------
+%%
+%% It may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either version 1.3c
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%% https://www.latex-project.org/lppl.txt
+%% and version 1.3c or later is part of all distributions of LaTeX
+%% version 2008 or later.
+%%
+%% This work has the LPPL maintenance status 'maintained'.
+%%
+%%
+%% File: footmisc.dtx (C) Copyright 1995-2011 Robin Fairbairns
+%% (C) Copyright 2018-2022 Frank Mittelbach
+\NeedsTeXFormat{LaTeX2e}
+\providecommand\DeclareRelease[3]{}
+\providecommand\DeclareCurrentRelease[2]{}
+
+\DeclareRelease{v5}{2011-06-06}{footmisc-2011-06-06.sty}
+\DeclareCurrentRelease{}{2022-02-14}
+\ProvidesPackage{latex-lab-footmisc}%
+ [2022/03/08 v6.0d
+ a miscellany of footnote facilities -- latex-lab version%
+ ]
+
+\NeedsTeXFormat{LaTeX2e}[2020/10/01]
+\newtoks\FN@temptoken
+\providecommand\protected@writeaux{%
+ \protected@write\@auxout
+}
+\def\l@advance@macro{\@@dvance@macro\edef}
+\def\@@dvance@macro#1#2#3{\expandafter\@tempcnta#2\relax
+ \advance\@tempcnta#3\relax
+ #1#2{\the\@tempcnta}%
+}
+\let\@advance@macro\l@advance@macro
+\DeclareOption{symbol}{\renewcommand\thefootnote{\fnsymbol{footnote}}}
+\newif\ifFN@robust \FN@robustfalse
+\DeclareOption{symbol*}{%
+ \renewcommand\thefootnote{\@fnsymbol\c@footnote}%
+ \FN@robusttrue
+ \AtEndOfPackage{\setfnsymbol{lamport*-robust}}%
+}
+\newif\ifFN@para \FN@parafalse
+\DeclareOption{para}{%
+% \end{macrocode}
+% Options are executed in the order of declaration, thus no point in
+% checking for side option as footmisc did in the past
+% \begin{macrocode}
+% \PackageError{footmisc}{Option "\CurrentOption" incompatible with
+% option "side"}%
+% {I shall ignore "\CurrentOption"}%
+ \FN@paratrue
+ \setlength\footnotemargin{-\maxdimen} % default when para is used
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\DeclareOption{side}{\ifFN@para
+ \PackageError{footmisc}{Option "\CurrentOption" incompatible with
+ option "para"}%
+ {I shall ignore "\CurrentOption"}%
+ \else
+ \def\@footnotetext@cfgpoint {\marginpar}
+ \AddToHook{fntext/para}{%
+ \hsize\marginparwidth % correct the default \hsize
+ \footnotesep\z@ % don't add a default separation
+ }
+ \def\@footnotetext@cfgpointii {\@makefntext}
+ \def\@footnotetext@cfgpointiii {}
+ \def\@footnotetext@cfgpointiv {}
+ \fi
+}
+\let\footnotelayout\@empty
+\DeclareOption{ragged}{%
+ \@ifundefined{RaggedRight}%
+ {\renewcommand\footnotelayout{\linepenalty50 \raggedright}}%
+ {\renewcommand\footnotelayout{\linepenalty50 \RaggedRight}}%
+}
+\newif\ifFN@perpage
+\FN@perpagefalse
+\DeclareOption{perpage}{%
+ \FN@perpagetrue
+}
+\newif\ifFN@fixskip \FN@fixskipfalse
+
+\let\FN@bottomcases\thr@@
+\newif\ifFN@abovefloats \FN@abovefloatstrue
+\DeclareOption{bottom}{%
+ \let\FN@bottomcases\@ne
+ \FN@abovefloatsfalse
+ \FN@fixskiptrue
+}
+\DeclareOption{bottomfloats}{%
+ \let\FN@bottomcases\tw@
+ \FN@abovefloatstrue \FN@fixskiptrue
+}
+\DeclareOption{abovefloats}{\FN@abovefloatstrue \FN@fixskiptrue}
+\DeclareOption{belowfloats}{\FN@abovefloatsfalse \FN@fixskiptrue}
+\DeclareOption{marginal}{%
+ \footnotemargin-0.8em\relax
+}
+\DeclareOption{flushmargin}{%
+ \footnotemargin0pt\relax
+}
+\newif\ifFN@hangfoot \FN@hangfootfalse
+\DeclareOption{hang}{%
+ \FN@hangfoottrue
+}
+\newcommand*\hangfootparskip{0.5\baselineskip}
+\newcommand*\hangfootparindent{0em}%
+\DeclareOption{norule}{%
+ \renewcommand\footnoterule{}%
+ \advance\skip\footins 4\p@\@plus2\p@\relax
+}
+\DeclareOption{splitrule}{%
+ \gdef\split@prev{0}
+ \let\pagefootnoterule\footnoterule
+ \let\mpfootnoterule\footnoterule
+ \def\splitfootnoterule{\kern-3\p@ \hrule \kern2.6\p@}
+ \def\footnoterule{\relax
+ \ifx \@listdepth\@mplistdepth
+ \mpfootnoterule
+ \else
+ \ifnum\split@prev=\z@
+ \pagefootnoterule
+ \else
+ \splitfootnoterule
+ \fi
+ \xdef\split@prev{\the\insertpenalties}%
+ \fi
+ }%
+}
+\newif\ifFN@stablefootnote \FN@stablefootnotefalse
+\DeclareOption{stable}{\FN@stablefootnotetrue}
+\newif\ifFN@multiplefootnote \FN@multiplefootnotefalse
+\DeclareOption{multiple}{\FN@multiplefootnotetrue}
+\ProcessOptions
+% \end{macrocode}
+% This version of \pkg{footmisc} can assume that the new OR code is
+% already available, thus nothing needs loading at this
+% point. However, as long as we use this code also in a package
+% version that can be loaded by other package while we are in a
+% transition phase it is not clear whether not the kernel code is
+% already available for other packages.
+% \begin{macrocode}
+%\@ifundefined{@kernel@before@cclv}
+% {\input{latex-lab-new-or.ltx}}{}
+% \end{macrocode}
+%
+% Footnote box layout for para footnotes;
+% this would also be the hook to support dblfootnotes (from the
+% \texttt{dblfnote} package if we integrate that).
+% \begin{macrocode}
+\ifFN@para
+ \def\@makecol@cfgpointii {%
+ \global\setbox\footins\vbox{\FN@makefootnoteparagraph}%
+ }
+\fi
+% \end{macrocode}
+%
+% \begin{macrocode}
+\ifFN@fixskip
+ \def\@outputbox@removebskip{%
+ \ifx\@textbottom\relax \else
+ \@outputbox@append{%
+ \@tempskipa\lastskip
+ \ifnum \gluestretchorder\@tempskipa>\z@
+ \vskip-\@tempskipa
+ \xdef\@outputbox@reinsertbskip
+ {\noexpand\@outputbox@append{\vskip\the\@tempskipa}}%
+ \else
+ \global\let\@outputbox@reinsertbskip\relax
+ \fi
+ }%
+ \fi
+ }
+\let\@outputbox@reinsertbskip\relax
+\else
+ \let\@outputbox@removebskip \relax
+ \let\@outputbox@reinsertbskip\relax
+\fi
+% \end{macrocode}
+%
+%
+%
+% \begin{macrocode}
+\ifcase \FN@bottomcases\relax
+\ERROR
+\or
+ \ifFN@abovefloats
+ \def\@makecol@cfgpoint {%
+ \@if@footnotes@TF
+ {\@outputbox@append{\vfill}}%
+ {\@if@bfloats@TF{\@outputbox@append{\vfill}}%
+ {\@outputbox@reinsertbskip}}%
+ \@outputbox@appendfootnotes
+ \@outputbox@attachfloats
+ }
+ \else
+ \def\@makecol@cfgpoint {%
+ \@outputbox@attachfloats
+ \@if@footnotes@TF
+ {\@outputbox@append{\vfill}}%
+ {\@outputbox@reinsertbskip}%
+ \@outputbox@appendfootnotes
+ }
+ \fi
+\or
+ \ifFN@abovefloats
+ \def\@makecol@cfgpoint {%
+ \@outputbox@appendfootnotes
+ \@if@bfloats@TF
+ {\@outputbox@append{\vfill}}%
+ {\@outputbox@reinsertbskip}%
+ \@outputbox@attachfloats
+ }
+ \else
+ \def\@makecol@cfgpoint {%
+ \@if@footnotes@TF
+ {\@outputbox@append{\vfill}}%
+ {\@if@bfloats@TF{\@outputbox@append{\vfill}}%
+ {\@outputbox@reinsertbskip}}%
+ \@outputbox@attachfloats
+ \@outputbox@appendfootnotes
+ }
+ \fi
+\or
+ \ifFN@abovefloats
+ \def\@makecol@cfgpoint {%
+ \@outputbox@appendfootnotes
+ \@outputbox@attachfloats
+ \@outputbox@reinsertbskip
+ }
+ \else
+ \def\@makecol@cfgpoint {%
+ \@outputbox@attachfloats
+ \@outputbox@appendfootnotes
+ \@outputbox@reinsertbskip
+}
+ \fi
+\else
+\ERROR
+\fi
+
+% next can be dropped when cleaned up
+\newif\ifFN@setspace
+\@ifpackageloaded{setspace}%
+ {%
+ \FN@setspacetrue
+ \@ifclassloaded{memoir}%
+ {%
+ \AddToHook{fntext}{\let\baselinestretch\m@m@singlespace}%
+ \let\FN@baselinestretch\m@m@singlespace
+ }%
+ {%
+% \AddToHook{fntext}{\let\baselinestretch\setspace@singlespace}%
+ \let\FN@baselinestretch\setspace@singlespace
+ }%
+ }%
+ {%
+ \FN@setspacefalse
+ }
+
+
+
+\ifFN@para
+ \def\@footnotetext@cfgpoint {\insert\footins}
+
+ \long\def\@footnotetext@cfgpointii #1{%
+ \setbox\FN@tempboxa\hbox{\@makefntext{#1}}%
+ \dp\FN@tempboxa\z@
+ \ht\FN@tempboxa
+ \dimexpr\wd\FN@tempboxa *%
+ \footnotebaselineskip /\columnwidth\relax
+ \box\FN@tempboxa
+ }
+
+
+ \def\@footnotetext@cfgpointiii {}
+ \def\@footnotetext@cfgpointiv {% config point
+ \strut
+ \penalty-10\relax
+ \hskip\footglue
+ }
+\fi
+
+
+
+\ifFN@para
+ \let\FN@tempboxa\@tempboxa
+ \newbox\FN@tempboxb
+ \newbox\FN@tempboxc
+ \newskip\footglue \footglue=1em plus.3em minus.3em
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ \newdimen\footnotebaselineskip
+
+ % establish late:
+
+\AddToHook{begindocument/before} {%
+ {%
+ \footnotesize
+ \global\footnotebaselineskip=\normalbaselineskip
+ }%
+}
+% \end{macrocode}
+% The coding is based on David Kastrup's improvement to Don Knuth's
+% original implementation. You find in the \TeX{}book if you own
+% the latest edition.
+% \begin{macrocode}
+
+ \long\def\FN@makefootnoteparagraph{%
+ \FN@setfootnoteparawidth
+ \@parboxrestore
+ \baselineskip=\footnotebaselineskip
+ \unvbox\footins \FN@removehboxes
+ \RawParEnd
+ }
+ \def\FN@removehboxes{\setbox\FN@tempboxa\lastbox
+ \ifhbox\FN@tempboxa{\FN@removehboxes}%
+ \unhbox\FN@tempboxa
+ \else
+ \RawNoindent
+ \rule\z@\footnotesep
+ \fi
+ }
+\fi
+
+
+\@ifpackageloaded{multicol}
+ {\def\FN@setfootnoteparawidth
+ {\hsize\ifnum\doublecol@number>\@ne
+ \textwidth
+ \else \columnwidth \fi}}
+ {\def\FN@setfootnoteparawidth{\hsize\columnwidth}}
+
+\ifFN@perpage
+ \RequirePackage{perpage}
+ \MakePerPage{footnote}
+% \end{macrocode}
+% Fix a bug in perpage \ldots
+% \begin{macrocode}
+ \def\@stpelt#1{\global\csname c@#1\endcsname \m@ne
+ \stepcounter{#1}%
+ \pp@fix@MakePerPage{#1}%
+ }
+ \def\pp@fix@MakePerPage#1{%
+ \ifnum \value{#1}>\z@
+ \addtocounter{#1}\m@ne\fi
+ }
+% \end{macrocode}
+% The above code may look a bit odd: the \cs{stepcounter} sets the
+% counter to zero and then we alter it if it is not zero. The
+% reason is that \cs{stepcounter} resets other counters and when
+% perpage is loaded this results in updating counters on the reset
+% list to 1 (or to a higher starting value if \cs{MakePerPage} is
+% used with an optional argument, which is precisely the problem
+% here. By subtracting 1 in that case we set it back to 1 lower
+% than the starting value.
+%
+% But to make this fully work we also need to update a support
+% command in \pkg{perpage}:
+% \begin{macrocode}
+ \def\pp@cl@end@iii\stepcounter#1\pp@fix@MakePerPage#2{}
+\fi
+
+
+\ifFN@para
+
+% This can use the default interface, except that a negative value for
+% \footnotemargin makes little sense, so we test for this and warn if
+% necessary. But -\maxdimen is ok again, so would need to be a litte bit more elaborate.
+%
+
+%\AddToHook{fntext/para}{
+% \ifdim \footnotemargin >\z@ \else
+% \PackageWarningNoline{footmisc}{Option 'para' needs positive \noexpand\footnotemargin}%
+% \footnotemargin 1.8em\relax
+% \fi
+%}
+
+
+\AddToHook{fntext/begin}{\nobreak \hspace{.2em}}
+
+
+
+
+\else
+
+ \ifFN@hangfoot
+ \long\def\@makefntext#1{%
+ \bgroup
+ \setbox\@tempboxa\hbox{%
+ \ifdim\footnotemargin>\z@
+ \hb@xt@\footnotemargin{\@makefnmark\hss}%
+ \else
+ \@makefnmark
+ \fi
+ }%
+ \leftmargin\wd\@tempboxa
+ \rightmargin\z@
+ \linewidth \columnwidth
+ \advance \linewidth -\leftmargin
+ \parshape \@ne \leftmargin \linewidth
+ \footnotesize
+ \@setpar{{\@@par}}%
+ \leavevmode
+ \llap{\box\@tempboxa}%
+ \parskip\hangfootparskip\relax
+ \parindent\hangfootparindent\relax
+ \footnotelayout#1%
+ \par
+ \egroup
+ }
+
+ \else
+
+% This is now using the default interface:
+%
+% \long\def\@makefntext#1{%
+% \parindent1em
+% \noindent
+% \ifdim\footnotemargin>\z@
+% \hb@xt@ \footnotemargin{\hss\@makefnmark}%
+% \else
+% \ifdim\footnotemargin=\z@
+% \llap{\@makefnmark}%
+% \else
+% \llap{\hb@xt@ -\footnotemargin{\@makefnmark\hss}}%
+% \fi
+% \fi
+% \footnotelayout#1%
+% }
+
+ \fi
+\fi
+
+
+
+
+\ifFN@multiplefootnote
+ \providecommand*{\multiplefootnotemarker}{3sp}
+ \providecommand*{\multfootsep}{,}
+ \AddToHook{fnmark} {\FN@mf@check}
+ \AddToHook{fnmark/end} {\FN@mf@prepare}
+%
+ \def\FN@mf@prepare{%
+ \kern-\multiplefootnotemarker
+ \kern\multiplefootnotemarker\relax
+ }
+ \def\FN@mf@check{%
+ \ifdim\lastkern=\multiplefootnotemarker\relax
+%?? is that necessary or even correct ??
+ \edef\@x@sf{\the\spacefactor}%
+%?? shouldn't that be 2 unkerns ?? (none would also be ok)
+ \unkern % new
+ \unkern
+ \textsuperscript{\multfootsep}%
+ \spacefactor\@x@sf\relax
+ \fi
+ }
+\else
+ \let\FN@mf@prepare\relax
+\fi
+\ifFN@stablefootnote
+\let\FN@sf@@footnote\footnote
+\def\footnote{\ifx\protect\@typeset@protect
+ \expandafter\FN@sf@@footnote
+ \else
+ \expandafter\FN@sf@gobble@opt
+ \fi
+}
+\edef\FN@sf@gobble@opt{\noexpand\protect
+ \expandafter\noexpand\csname FN@sf@gobble@opt \endcsname}
+\expandafter\def\csname FN@sf@gobble@opt \endcsname{%
+ \@ifnextchar[%]
+ \FN@sf@gobble@twobracket
+ \@gobble
+}
+\def\FN@sf@gobble@twobracket[#1]#2{}
+\let\FN@sf@@footnotemark\footnotemark
+\def\footnotemark{\ifx\protect\@typeset@protect
+ \expandafter\FN@sf@@footnotemark
+ \else
+ \expandafter\FN@sf@gobble@optonly
+ \fi
+}
+\edef\FN@sf@gobble@optonly{\noexpand\protect
+ \expandafter\noexpand\csname FN@sf@gobble@optonly \endcsname}
+\expandafter\def\csname FN@sf@gobble@optonly \endcsname{%
+ \@ifnextchar[%]
+ \FN@sf@gobble@bracket
+ {}%
+}
+\def\FN@sf@gobble@bracket[#1]{}
+\fi
+\newcommand\setfnsymbol[1]{%
+ \@bsphack
+ \@ifundefined{FN@fnsymbol@#1}%
+ {%
+ \PackageError{footmisc}{Symbol style "#1" not known}%
+ \@eha
+ }{%
+ \expandafter\let\expandafter\@fnsymbol\csname
+ FN@fnsymbol@#1\endcsname
+ }%
+ \@esphack
+}
+\let\FN@fnsymbol@lamport\@fnsymbol
+\newif\if@tempswb
+\DeclareDocumentCommand\DefineFNsymbols {smO{text}m}{%
+ \expandafter\ifx\csname FN@fnsymbol@#2\endcsname\relax
+ \PackageInfo{footmisc}{Declaring symbol style #2}%
+ \else
+ \PackageWarning{footmisc}{Redeclaring symbol style #2}%
+ \fi
+ \toks@{}%
+ \def\@tempb{\end}%
+ \FN@build@symboldef#4\end
+ \def\@tempc{math}%
+ \def\@tempd{#3}%
+ \expandafter\xdef\csname FN@fnsymbol@#2\endcsname##1{%
+ \ifx\@tempc\@tempd
+ \noexpand\ensuremath
+ \else
+ \noexpand\nfss@text
+ \fi
+ {%
+ \noexpand\ifcase##1%
+ \the\toks@
+ \noexpand\else
+ \IfBooleanTF#1{\noexpand\@ctrerr}%
+ {\noexpand\FN@orange##1}%
+ \noexpand\fi
+ }%
+ }%
+}
+\def\FN@build@symboldef#1{%
+ \def\@tempa{#1}%
+ \ifx\@tempa\@tempb
+ \else
+ \toks@\expandafter{\the\toks@\or#1}%
+ \expandafter\FN@build@symboldef
+ \fi
+}
+\DeclareDocumentCommand\DefineFNsymbolsTM {smm}{%
+ \expandafter\ifx\csname FN@fnsymbol@#2\endcsname\relax
+ \PackageInfo{footmisc}{Declaring symbol style #2}%
+ \else
+ \PackageWarning{footmisc}{Redeclaring symbol style #2}%
+ \fi
+ \toks@{}%
+ \def\@tempb{\end}%
+ \FN@build@symboldefTM#3\end\@null
+ \expandafter\xdef\csname FN@fnsymbol@#2\endcsname##1{%
+ \noexpand\ifcase##1%
+ \the\toks@
+ \noexpand\else
+ \IfBooleanTF#1{\noexpand\@ctrerr}%
+ {\noexpand\FN@orange##1}%
+ \noexpand\fi
+ }%
+}
+\def\FN@build@symboldefTM#1#2{%
+ \def\@tempa{#1}%
+ \ifx\@tempa\@tempb
+ \else
+ \toks@\expandafter{\the\toks@\or\TextOrMath{#1}{#2}}%
+ \expandafter\FN@build@symboldefTM
+ \fi
+}
+\def\FN@orange#1{%
+ \ifFN@robust
+ \@arabic#1%
+ \@bsphack
+ \PackageInfo{footmisc}{Footnote number \number#1 out of range}%
+ \protect\@fnsymbol@orange
+ \@esphack
+ \else \@ctrerr \fi
+}
+\global\let\@diagnose@fnsymbol@orange\relax
+\AtEndDocument{\@diagnose@fnsymbol@orange}
+\def\@fnsymbol@orange{%
+ \gdef\@diagnose@fnsymbol@orange{%
+ \PackageWarningNoLine{footmisc}{Some footnote number(s)
+ were out of range
+ \MessageBreak
+ see log for details%
+ }%
+ }%
+}
+\DefineFNsymbolsTM{bringhurst}{%
+ \textasteriskcentered *%
+ \textdagger \dagger
+ \textdaggerdbl \ddagger
+ \textsection \mathsection
+ \textbardbl \|%
+ \textparagraph \mathparagraph
+}%
+\DefineFNsymbolsTM{chicago}{%
+ \textasteriskcentered *%
+ \textdagger \dagger
+ \textdaggerdbl \ddagger
+ \textsection \mathsection
+ \textbardbl \|%
+ \#\#%
+}%
+\DefineFNsymbolsTM{wiley}{%
+ \textasteriskcentered *%
+ {\textasteriskcentered\textasteriskcentered}{**}%
+ \textdagger \dagger
+ \textdaggerdbl \ddagger
+ \textsection \mathsection
+ \textparagraph \mathparagraph
+ \textbardbl \|%
+}%
+\DefineFNsymbolsTM{lamport-robust}{%
+ \textasteriskcentered *%
+ \textdagger \dagger
+ \textdaggerdbl \ddagger
+ \textsection \mathsection
+ \textparagraph \mathparagraph
+ \textbardbl \|%
+ {\textasteriskcentered\textasteriskcentered}{**}%
+ {\textdagger\textdagger}{\dagger\dagger}%
+ {\textdaggerdbl\textdaggerdbl}{\ddagger\ddagger}%
+}
+\DefineFNsymbolsTM*{lamport*}{%
+ \textasteriskcentered *%
+ \textdagger \dagger
+ \textdaggerdbl \ddagger
+ \textsection \mathsection
+ \textparagraph \mathparagraph
+ \textbardbl \|%
+ {\textasteriskcentered\textasteriskcentered}{**}%
+ {\textdagger\textdagger}{\dagger\dagger}%
+ {\textdaggerdbl\textdaggerdbl}{\ddagger\ddagger}%
+ {\textsection\textsection}{\mathsection\mathsection}%
+ {\textparagraph\textparagraph}{\mathparagraph\mathparagraph}%
+ {\textasteriskcentered\textasteriskcentered\textasteriskcentered}{***}%
+ {\textdagger\textdagger\textdagger}{\dagger\dagger\dagger}%
+ {\textdaggerdbl\textdaggerdbl\textdaggerdbl}{\ddagger\ddagger\ddagger}%
+ {\textsection\textsection\textsection}%%
+ {\mathsection\mathsection\mathsection}%
+ {\textparagraph\textparagraph\textparagraph}%%
+ {\mathparagraph\mathparagraph\mathparagraph}%
+}
+\setfnsymbol{lamport*}
+\DefineFNsymbolsTM{lamport*-robust}{%
+ \textasteriskcentered *%
+ \textdagger \dagger
+ \textdaggerdbl \ddagger
+ \textsection \mathsection
+ \textparagraph \mathparagraph
+ \textbardbl \|%
+ {\textasteriskcentered\textasteriskcentered}{**}%
+ {\textdagger\textdagger}{\dagger\dagger}%
+ {\textdaggerdbl\textdaggerdbl}{\ddagger\ddagger}%
+ {\textsection\textsection}{\mathsection\mathsection}%
+ {\textparagraph\textparagraph}{\mathparagraph\mathparagraph}%
+ {\textasteriskcentered\textasteriskcentered\textasteriskcentered}{***}%
+ {\textdagger\textdagger\textdagger}{\dagger\dagger\dagger}%
+ {\textdaggerdbl\textdaggerdbl\textdaggerdbl}{\ddagger\ddagger\ddagger}%
+ {\textsection\textsection\textsection}%%
+ {\mathsection\mathsection\mathsection}%
+ {\textparagraph\textparagraph\textparagraph}%%
+ {\mathparagraph\mathparagraph\mathparagraph}%
+}
+\newcommand\mpfootnotemark{%
+ \@ifnextchar[%
+ \@xmpfootnotemark
+ {%
+ \stepcounter\@mpfn
+ \protected@xdef\@thefnmark{\thempfn}%
+ \@footnotemark
+ }%
+}
+\def\@xmpfootnotemark[#1]{%
+ \begingroup
+ \csname c@\@mpfn\endcsname #1\relax
+ \unrestored@protected@xdef\@thefnmark{\thempfn}%
+ \endgroup
+ \@footnotemark
+}
+% \end{macrocode}
+% TEMP PATCHES FOR TESTING
+% \begin{macrocode}
+
+\endinput
+%</footmisc>
+% \end{macrocode}
+% \Finale
+%
diff --git a/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-new-or.dtx b/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-new-or.dtx
new file mode 100644
index 00000000000..08b58a72860
--- /dev/null
+++ b/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-new-or.dtx
@@ -0,0 +1,545 @@
+% \iffalse meta-comment
+%
+%% File: latex-lab-new-or.dtx
+% Copyright (C) 2022 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.
+%
+%<*driver>
+\documentclass{l3doc}
+\EnableCrossrefs
+\CodelineIndex
+\begin{document}
+ \DocInput{latex-lab-new-or.dtx}
+\end{document}
+%</driver>
+%
+% \fi
+%
+%
+% \title{The \texttt{latex-lab-new-or} code\thanks{}}
+% \author{Frank Mittelbach, \LaTeX{} Project}
+%
+% \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}}
+%
+% \begin{abstract}
+% \end{abstract}
+%
+% \section{Introduction}
+%
+% This code implements changes to the output routine.
+%
+%
+%
+%
+% \section{Hooks and configuration points}
+%
+% Note: the configuration points do not have an interface mechanism
+% yet and all their names are temporary right now.
+%
+%
+% \subsubsection{Configuration points}
+%
+% To cater for different layouts with respect to text, footnotes,
+% and bottom-floats placements there are two configuration points for
+% now.
+% \begin{description}
+% \item[\cs{@makecol@cfgpoint} (0 arguments)]
+%
+% In this configuration point 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. Before the code 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)]
+%
+% This general purpose command alters the \cs{@outputbox} box by
+% appending material to it.
+%
+% \item[\cs{@outputbox@appendfootnotes} (0 arguments)]
+%
+% 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)]
+%
+% 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)]
+%
+% Reinsert the bottom skip of the \cs{@outputbox} that was
+% saved before.
+%
+% \item[Testing for existence of material]
+%
+% 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}
+% This configuration point needs an appropriate definition; a
+% default is already given in the kernel.
+%
+% \item[\cs{@makecol@cfgpointii} (0 arguments)]
+%
+% This configuration point 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.
+%
+% \end{description}
+%
+% \StopEventually{\setlength\IndexMin{200pt} \PrintIndex }
+%
+%
+% \section{The Implementation}
+%
+% \begin{macrocode}
+%<*code>
+% \end{macrocode}
+%
+% \subsection{File declaration}
+% \begin{macrocode}
+\ProvidesFile{latex-lab-new-or.ltx}
+ [2022-03-09 v0.1b changes to the output routine]
+% \end{macrocode}
+% \subsection{\cs{@makecol} reimplementation}
+%
+% In order for other packages to prepend or append code to
+% \cs{@makecol}, they can use the generic command hooks
+% \texttt{cmd/@makecol/before} and \texttt{cmd/@makecol/after}, so
+% there is nothing we need to do here.
+%
+%
+% \begin{macro}{\@makecol}
+% \cs{@makecol} is shortened a lot, basically all the hardwired
+% code in the middle has moved into a configuration point.
+% \begin{macrocode}
+\def \@makecol {%
+ \@kernel@before@cclv
+ \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}
+% Any ``here'' floats in the \cs{@outputbox} are now 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.
+% \fmi{Interface to configuration points will change in the future}
+% \begin{macrocode}
+ \@makecol@cfgpoint
+% \end{macrocode}
+% The we deal with any \cs{enlargethispage} or run the normal code
+% to build a column.
+% \begin{macrocode}
+ \ifvbox\@kludgeins
+ \@makespecialcolbox
+ \else
+ \@makenormalcolbox
+ \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}{\@makenormalcolbox}
+% Taken out of \cs{@makecol} for readability.
+% \begin{macrocode}
+\def \@makenormalcolbox {%
+ \setbox\@outputbox \vbox to\@colht {%
+ \@texttop
+ \@outputbox@depth \dp\@outputbox
+ \unvbox \@outputbox
+ \vskip -\@outputbox@depth
+ \@textbottom
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\@makespecialcolbox}
+% Make the colbox when \cs{enlargethispage} was used.
+% \begin{macrocode}
+\def \@makespecialcolbox {%
+ \@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 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 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}
+% \begin{macro}{\@kernel@before@footins}
+% These two commands are internal kernel hooks intended for tagging
+% support in case that is active. By default they do nothing (and
+% may have been defined already by \cs{DocumentMetadata}).
+% \begin{macrocode}
+\providecommand\@kernel@before@cclv{}
+\providecommand\@kernel@before@footins{}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+%
+%
+% \subsection{The output routine configuration components}
+%
+% Here we provide the components that are used to define
+% \cs{@makecol@cfgpoint}.
+%
+%
+% \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{this code will get revised as part of CP handling in the future}
+% \begin{macrocode}
+ \@makecol@handlesplitfootnotes
+ \@makecol@cfgpointii
+% \end{macrocode}
+% Then the footnotes are appended:
+% \begin{macrocode}
+ \@outputbox@append{%
+ \vskip \skip\footins
+ \@kernel@before@footins
+ \color@begingroup
+ \normalcolor
+ \footnoterule
+% \end{macrocode}
+% Support for \pkg{pdfcolfoot}, eventually this can go once color
+% is properly supported.
+% \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{macro}{\@makecol@cfgpointii}
+%
+% Configuration point to support manipulation of footins box
+% (result needs to be moved back in there). Used by the
+% \texttt{para} option.
+% \fmi{Interface will change in the future}
+% \begin{macrocode}
+\let \@makecol@cfgpointii \@empty
+% \end{macrocode}
+%
+% \end{macro}
+%
+%
+%
+% \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{macro}{\@makecol@cfgpoint}
+%
+% Here is only the configuration for the default case for now,
+% others are provided by \pkg{footmisc}.
+%
+% \begin{macrocode}
+ \def\@makecol@cfgpoint {%
+ \@outputbox@appendfootnotes
+ \@outputbox@attachfloats
+% \end{macrocode}
+% We do, however, 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{macro}
+%
+%
+% \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}
+%
+% \begin{macrocode}
+\input{latex-lab-footnotes.ltx}
+% \end{macrocode}
+%
+%
+% \begin{macrocode}
+%</code>
+% \end{macrocode}
+%
+% \Finale
+%
diff --git a/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-prototype.dtx b/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-prototype.dtx
new file mode 100644
index 00000000000..090e6c91a4f
--- /dev/null
+++ b/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-prototype.dtx
@@ -0,0 +1,827 @@
+% \iffalse meta-comment
+%
+%% File: latex-lab-prototype.dtx
+%
+% Copyright (C) 1999 Frank Mittelbach, Chris Rowley, David Carlisle
+% (C) 2004-2010 Frank Mittelbach, The LaTeX Project
+% (C) 2011-2022 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
+%
+% This file is part of the "latex-lab bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex2e
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \textsf{latex-lab-prototype} package\\ Prototype document functions^^A
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2022-03-09}
+%
+% \maketitle
+%
+% \tableofcontents
+%
+% \bigskip
+%
+% \begin{documentation}
+%
+% There are three broad \enquote{layers} between putting down ideas into
+% a source file and ending up with a typeset document. These layers of
+% document writing are
+% \begin{enumerate}
+% \item authoring of the text with mark-up;
+% \item document layout design;
+% \item implementation (with \TeX{} programming) of the design.
+% \end{enumerate}
+% We write the text as an author, and we see the visual output of the design
+% after the document is generated; the \TeX{} implementation in the middle is
+% the glue between the two.
+%
+% \LaTeX{}'s greatest success has been to standardise a system of mark-up that
+% balances the trade-off between ease of reading and ease of writing to suit
+% almost all forms of technical writing. It's
+% other original strength was a good background in typographical design; while
+% the standard \LaTeXe{} classes look somewhat dated now in terms of their
+% visual design, their typography is generally sound. (Barring the occasional
+% minor faults.)
+%
+% However, \LaTeXe{} has always lacked a standard approach to customising
+% the visual design of a document. Changing the looks of the standard classes
+% involved either:
+% \begin{itemize}
+% \item Creating a new version of the implementation code of the class and
+% editing it.
+% \item Loading one of the many packages to customise certain elements of
+% the standard classes.
+% \item Loading a completely different document class, such as
+% \textsf{KOMA-Script} or \textsf{memoir}, that allows easy customisation.
+% \end{itemize}
+% All three of these approaches have their drawbacks and learning curves.
+%
+% The idea behind this module is to cleanly separate the three layers
+% introduced at the beginning of this section, so that document authors who
+% are not programmers can easily change the design of their documents.
+% The approach here also makes it easier for \LaTeX{} programmers to provide
+% their own customisations on top of a pre-existing class.
+%
+% \section{What is a document?}
+%
+% Besides the textual content of the words themselves, the source file
+% of a document contains mark-up elements that add structure to the
+% document. These elements include sectional divisions, figure/table
+% captions, lists of various sorts, theorems/proofs, and so on.
+% The list will be different for every document that can be written.
+%
+% Each element can be represented logically without worrying about the
+% formatting, with mark-up such as \cs{section}, \cs{caption},
+% |\begin{enumerate}| and so on. The output of each one of these
+% document elements will be a typeset representation of the information
+% marked up, and the visual arrangement and design of these elements
+% can vary widely in producing a variety of desired outcomes.
+%
+% For each type of document element, there may be design variations that
+% contain the same sort of information but present it in slightly
+% different ways. For example, the difference between a numbered and an
+% unnumbered section, \cs{section} and |\section*|, or the difference
+% between an itemised list or an enumerated list.
+%
+% There are three distinct layers in the definition of
+% \enquote{a document} at this level
+% \begin{enumerate}
+% \item semantic elements such as the ideas of sections and lists;
+% \item a set of design solutions for representing these elements
+% visually;
+% \item specific variations for these designs that represent the
+% elements in the document.
+% \end{enumerate}
+% In the parlance of the template system, these are called object types,
+% templates, and instances, and they are discussed below in sections
+% \ref{sec:objects}, \ref{sec:templates}, and~\ref{sec:instances},
+% respectively.
+%
+% By formally declaring documents to be composed of mark-up elements
+% grouped into objects, which are interpreted and typeset with a set of
+% templates, each of which has one or more instances with which to
+% compose each and every semantic unit of the text, we can cleanly
+% separate the components of document construction.
+%
+% \section{Object types}
+% \label{sec:objects}
+%
+% An \emph{object type} (sometimes just \enquote{object}) is an
+% abstract idea of a document element that takes a fixed number of
+% arguments corresponding to the information from the document author
+% that it is representing. A sectioning object, for example, might take
+% three inputs: \enquote{title}, \enquote{short title}, and
+% \enquote{label}.
+%
+% Any given document class will define which object types are to be
+% used in the document, and any template of a given object type can be
+% used to generate an instance for the object. (Of course, different
+% templates will produce different typeset representations, but the
+% underlying content will be the same.)
+%
+% \begin{function}{\prototype_declare_object:nn}
+% \begin{syntax}
+% \cs{prototype_declare_object:nn} \Arg{object type} \Arg{no.~of args}
+% \end{syntax}
+% This function defines an \meta{object type} taking
+% \meta{no.~of arguments}, where the \meta{object type} is an
+% abstraction as discussed above. For example,
+% \begin{verbatim}
+% \prototype_declare_object:nn { sectioning } { 3 }
+% \end{verbatim}
+% creates an object type \enquote{sectioning}, where each use of that
+% object type will need three arguments.
+%
+% While not formally verified the semantics of all arguments are part
+% of the object declaration and need to be carefully documented in
+% order to make the use of different templates for the same object
+% type meaningful.
+% \end{function}
+%
+% \section{Templates}
+% \label{sec:templates}
+%
+% A \emph{template} is a generalised design solution for representing
+% the information of a specified object type. Templates that do the same
+% thing, but in different ways, are grouped together by their object type
+% and given separate names. There are two important parts to a template:
+% \begin{itemize}
+% \item the parameters it takes to vary the design it is producing;
+% \item the implementation of the design.
+% \end{itemize}
+%
+% \begin{function}{\prototype_declare_template:nnnn}
+% \begin{syntax}
+% \cs{prototype_declare_template:nnnn}
+% ~~\Arg{object type} \Arg{template}
+% ~~\Arg{key definitions} \Arg{code}
+% \end{syntax}
+% A \meta{template} interface is declared for a particular
+% \meta{object type}. The interface itself is
+% defined by the \meta{key definitions}, which is itself a key--value list
+% using the same interface as \cs{keys_define:nn}. (The keys created
+% here \emph{are} managed \pkg{l3keys} in the tree
+% \texttt{prototype/\meta{object}/\meta{template}}). As described below,
+% the keys should be defined such that they can be set multiple times:
+% first to a default value, then to a specific value for an instance
+% and finally to a per-use override.
+%
+% The \meta{code} argument of \cs{template_declare_template:nnnn} is used
+% as the replacement text for the template when it is used, either
+% directly or as an instance. This may therefore accept arguments
+% |#1|, |#2|, \emph{etc}.~as detailed by the \meta{number of arguments}
+% taken by the object type. The template and instance key values (see
+% below) are assigned before the \meta{code} is inserted.
+% \end{function}
+%
+% \begin{function}{\prototype_declare_defaults:nnn}
+% \begin{syntax}
+% \cs{prototype_declare_template:nnnn}
+% ~~\Arg{object type} \Arg{template} \Arg{defaults}
+% \end{syntax}
+% Sets the default values for each \meta{key} in a \meta{template}. When
+% a template is used, these values are applied first \emph{before} those
+% set by \cs{prototype_use_template:nnn} or
+% \cs{prototype_declare_instance:nnnn}. If not default is given, the
+% prevailing state when the template is used will apply.
+% \end{function}
+%
+% \section{Instances}
+% \label{sec:instances}
+%
+% After a template is defined it still needs to be put to use. The
+% parameters that it expects need to be defined before it can be used in
+% a document. Every time a template has parameters given to it, an
+% \emph{instance} is created, and this is the code that ends up in the
+% document to perform the typesetting of whatever pieces of information
+% are input into it.
+%
+% For example, a template might say \enquote{here is a section with or
+% without a number that might be centred or left aligned and print its
+% contents in a certain font of a certain size, with a bit of a gap
+% before and after it} whereas an instance declares \enquote{this is a
+% section with a number, which is centred and set in $12\,\text{pt}$
+% italic with a $10\,\text{pt}$ skip before and a
+% $12\,\text{pt}$ skip after it}. Therefore, an instance is just a
+% frozen version of a template with specific settings as chosen by the
+% designer.
+%
+% \begin{function}{\prototype_declare_instance:nnnn}
+% \begin{syntax}
+% \cs{prototype_declare_instance:nnnn}
+% ~~\Arg{object type} \Arg{template} \Arg{instance} \Arg{parameters}
+% \end{syntax}
+% This function uses a \meta{template} for an \meta{object type}
+% to create an \meta{instance}. The \meta{instance} will be set
+% up using the \meta{parameters}, which will set some of the
+% \meta{keys} in the \meta{template}.
+%
+% As a practical example, consider an object type for document sections
+% (which might include chapters, parts, sections, \emph{etc}.), which
+% is called \texttt{sectioning}. One possible template for this
+% object type might be called \texttt{basic}, and one instance of this
+% template would be a numbered section. The instance declaration might
+% read:
+% \begin{verbatim}
+% \prototype_declare_instance:nnnn { sectioning } { basic } { section-num }
+% {
+% numbered = true ,
+% justification = center ,
+% font = \normalsize\itshape ,
+% before-skip = 10pt ,
+% after-skip = 12pt ,
+% }
+% \end{verbatim}
+% Of course, the key names here are entirely imaginary, but illustrate
+% the general idea of fixing some settings.
+% \end{function}
+%
+% \section{Document interface}
+%
+% After the instances have been chosen, document commands must be
+% declared to use those instances in the document.
+% \cs{prototype_use_instance:nn}
+% calls instances directly, and this command should be used internally
+% in document-level mark-up.
+%
+% \begin{function}{\prototype_use_instance:nn, \prototype_use_instance:nnn}
+% \begin{syntax}
+% \cs{prototype_use_instance:nn}
+% ~~\Arg{object type} \Arg{instance} \meta{arguments}
+% \cs{prototype_use_instance:nn}n
+% ~~\Arg{object type} \Arg{instance} \Arg{overrides} \meta{arguments}
+% \end{syntax}
+% Uses an \meta{instance} of the \meta{object type}, which will require
+% \meta{arguments} as determined by the number specified for the
+% \meta{object type}. The \meta{instance} must have been declared
+% before it can be used, otherwise an error is raised. The \texttt{nnn}
+% version allows for local overrides of the instance settings using the
+% additional keyval argument.
+% \end{function}
+%
+% \begin{function}{\prototype_use_template:nnnn}
+% \begin{syntax}
+% \cs{prototype_use_template:nnnn} \Arg{object type} \Arg{template}
+% ~~\Arg{settings} \meta{arguments}
+% \end{syntax}
+% Uses the \meta{template} of the specified \meta{object type},
+% applying the \meta{settings} and absorbing \meta{arguments} as
+% detailed by the \meta{object type} declaration. This in effect
+% is the same as creating an instance using
+% \cs{template_declare_instance:nnnn} and immediately using it with
+% \cs{template_use_instance:nnn}, but without the instance having any
+% further existence. It is therefore useful where a template needs to
+% be used once.
+% \end{function}
+%
+% \section{Showing template information}
+%
+% \begin{function}
+% {
+% \prototype_show_template_code:nn ,
+% \prototype_show_template_defaults:nn ,
+% \prototype_show_instance_values:nn
+% }
+% \begin{syntax}
+% \cs{prototype_show_template_code:nn} \Arg{object type} \Arg{template}
+% \cs{prototype_show_template_defaults:nn} \Arg{object type} \Arg{template}
+% \cs{prototype_show_instance_values:nn} \Arg{object type} \Arg{instance}
+% \end{syntax}
+% Show information about a declare template or instance for
+% debugging purposes.
+% \end{function}
+%
+% \section{Open questions and comparison with \pkg{xtemplate}}
+%
+% The approach here is modelled on that from \pkg{xtemplate}, but since it uses
+% \pkg{l3keys} rather than dedicated key handling, there are some differences.
+% There is also a simplification in that collections are not supported
+% (because we now think that they provided the wrong kind of abstraction).
+%
+% The various open questions, including those linked to \pkg{xtemplate}
+% concepts, are collected here.
+%
+% \subsection{Module name}
+%
+% This is currently open for ideas: traditionally \texttt{template} has
+% been used. This may link to the need for both templates and instances
+% (\emph{vide infra}).
+%
+% \subsection{Design-level names}
+%
+% These are currently not provided. That allows both this code and
+% \pkg{xtemplate} to be loaded in the same document. We will likely want
+% to decide on these names: they could for example include
+% \texttt{Prototype} or \texttt{Design}, or could use the existing
+% \pkg{xtemplate} if a compatibility approach can be designed.
+%
+% \subsection{Objects}
+%
+% Is this name clear? A possible alternative is `element'.
+%
+% \subsection{Efficiency and repetition of key setting}
+%
+% In the \pkg{xtemplate} implementation, keys values are stored in property
+% lists before being applied. This means that when creating an instance, the
+% template defaults can be replaced entirely by any instance values. In
+% contrast, the approach here simply precompiles all of the template defaults,
+% then appends the precompiled list from the instance. Some variables are
+% therefore set twice. More importantly, this means that arbitrary code
+% could be executed twice: authors need to be aware of this.
+%
+% \subsection{Key ordering}
+%
+% Linked to the previous idea, in \pkg{xtemplate} keys are set in the
+% order they are declared in the setup. In contrast, using \pkg{l3keys}
+% they are set in the order the keys are given in the input. Is this OK?
+%
+% \subsection{Setting defaults}
+%
+% The current approach requires setting the defaults separately from
+% the key creation. That means listing keys twice. However, it also
+% avoids further overloading of the keyval setup. Is this reasonable?
+%
+% \subsection{The need for templates and instances}
+%
+% In \pkg{xtemplate}, storing keys in a \texttt{prop} means that there
+% is a real efficiency when creating an instance. In contrast, using
+% precompiled keys here, creating a template and creating an instance
+% are almost identical. Could we drop the distinction? That would then
+% work well if we allowed instances to be derived from others: effectively
+% the same as instances from templates, but with a `flatter' approach.
+%
+% \subsection{Assignment of key values}
+%
+% The \pkg{xtemplate} approach uses \cs{AssignTemplateKeys} to
+% specify when keys are assigned. In contrast, here key assignment is
+% automatic. If you look over \TeX{} Live, the only places that
+% \cs{AssignTemplateKeys} is not the first thing in the code are in limited
+% use cases in \pkg{enotez} and \pkg{xgalley}. In both packages, that's because
+% they want to limit the scope of assignment. In \pkg{enotez} the key setting
+% is placed inside a group, whereas in \pkg{xgalley} there is a
+% save-and-restore approach as a group is not possible. Both of those use-cases
+% could be covered in other ways: it's a question of setting up the template
+% keys so they assign to an intermediate variable, then assigning those as
+% necessary to the live ones for these cases.
+%
+% The main reason for not using \cs{AssignTemplateKeys} is that the common
+% case doesn't need it. We could of course stick to an explicit-assignment
+% approach, or have two variants or template-creation, etc., where assignment
+% is manual in one of them.
+%
+% \subsection{Values from other keys}
+%
+% The \pkg{xtemplate} approach offers \cs{KeyValue} to pass the value of
+% one key as the default for another. That relies on the fact that key
+% setting is ordered (\emph{vide supra}). It also means that there is
+% some code to check for this as part of key setting: it's non-trivial
+% to support. The current \pkg{l3keys}-based code doesn't offer this.
+% Instead one could use for example meta keys. That is a different
+% interface and might occasionally be awkward. We can add some
+% \texttt{.store-value:n} property to allow a \cs{keys_value:nn} approach,
+% but without key ordering it might still not work in the same way.
+%
+% \subsection{The nature of debugging data}
+%
+% Due to the differences in data storage, the \pkg{xtemplate} method offers
+% a richer ability to debug template internals than the one here. We can look
+% at \emph{e.g.}\ tracking all keys for a template to make this easier.
+% It is worth noting that much of this data is really something that
+% should be part of the documentation anyway. Also, it would be trivial
+% to save the raw defaults and do the `hard' processing only if asked
+% to show the values (\emph{i.e.}\ using code similar to that in
+% \pkg{xtemplate}).
+%
+% \subsection{Collections}
+%
+% These are not implemented at all: we likely want a new approach to
+% contexts.
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{latex-lab-prototype} Implementation}
+%
+% \subsection{File declaration}
+% \begin{macrocode}
+%<*package>
+\ProvidesFile{latex-lab-prototype.sty}
+ [2022-03-09 v0.1b Experimental prototype document functions]
+%</package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*2ekernel>
+% \end{macrocode}
+%
+% \begin{macrocode}
+\ExplSyntaxOn
+% \end{macrocode}
+%
+% \subsection{\cs{keys_precompile:nnN}}
+%
+% \begin{macrocode}
+%<@@=keys>
+% \end{macrocode}
+%
+% This may not yet be available in \pkg{expl3} so we ensure it is set up
+% here: all temporary. We just redefine those internals that need it.
+% \begin{macrocode}
+\tl_if_exist:NF \l_@@_precompile_tl
+ {
+ \bool_new:N \l_@@_precompile_bool
+ \tl_new:N \l_@@_precompile_tl
+ }
+\cs_gset_protected:Npn \@@_precompile:n #1
+ {
+ \bool_if:NTF \l_@@_precompile_bool
+ { \tl_put_right:Nn \l_@@_precompile_tl }
+ { \use:n }
+ {#1}
+ }
+\cs_gset_protected:Npn \@@_bool_set:Nnnn #1#2#3#4
+ {
+ \bool_if_exist:NF #1 { \bool_new:N #1 }
+ \@@_choice_make:
+ \@@_cmd_set:nx { \l_keys_path_str / true }
+ { \exp_not:c { bool_ #2 set_ #3 :N } \exp_not:N #1 }
+ \@@_cmd_set:nx { \l_keys_path_str / false }
+ { \exp_not:c { bool_ #2 set_ #4 :N } \exp_not:N #1 }
+ \@@_cmd_set_direct:nn { \l_keys_path_str / unknown }
+ {
+ \msg_error:nnx { keys } { boolean-values-only }
+ \l_keys_key_str
+ }
+ \@@_default_set:n { true }
+ }
+\cs_gset_protected:Npn \@@_choice_make_aux:N #1
+ {
+ \cs_set_nopar:cpn { \c_@@_type_root_str \l_keys_path_str }
+ { choice }
+ \@@_cmd_set_direct:nn \l_keys_path_str { #1 {##1} }
+ \@@_cmd_set_direct:nn { \l_keys_path_str / unknown }
+ {
+ \msg_error:nnxx { keys } { choice-unknown }
+ \l_keys_path_str {##1}
+ }
+ }
+\cs_gset_protected:Npn \@@_cmd_set:nn #1#2
+ { \@@_cmd_set_direct:nn {#1} { \@@_precompile:n {#2} } }
+\cs_gset_protected:Npn \@@_cmd_set_direct:nn #1#2
+ { \cs_set_protected:cpn { \c_@@_code_root_str #1 } ##1 {#2} }
+\cs_gset_protected:Npn \@@_cs_set:NNpn #1#2#3#
+ {
+ \cs_set_protected:cpx { \c_@@_code_root_str \l_keys_path_str } ##1
+ {
+ \@@_precompile:n
+ { #1 \exp_not:N #2 \exp_not:n {#3} {##1} }
+ }
+ \use_none:n
+ }
+\cs_gset_protected:Npn \@@_meta_make:n #1
+ {
+ \exp_args:NVo \@@_cmd_set_direct:nn \l_keys_path_str
+ {
+ \exp_after:wN \keys_set:nn \exp_after:wN
+ { \l_@@_module_str } {#1}
+ }
+ }
+\cs_gset_protected:Npn \@@_meta_make:nn #1#2
+ {
+ \exp_args:NV \@@_cmd_set_direct:nn
+ \l_keys_path_str { \keys_set:nn {#1} {#2} }
+ }
+\cs_gset_protected:Npn \keys_precompile:nnN #1#2#3
+ {
+ \bool_set_true:N \l_@@_precompile_bool
+ \tl_clear:N \l_@@_precompile_tl
+ \keys_set:nn {#1} {#2}
+ \bool_set_false:N \l_@@_precompile_bool
+ \tl_set_eq:NN #3 \l_@@_precompile_tl
+ }
+\cs_gset_protected:Npn \@@_show:Nnn #1#2#3
+ {
+ #1 { keys } { show-key }
+ { \@@_trim_spaces:n { #2 / #3 } }
+ {
+ \keys_if_exist:nnT {#2} {#3}
+ {
+ \exp_args:Nnf \msg_show_item_unbraced:nn { code }
+ {
+ \exp_args:Ne \@@_show:n
+ {
+ \exp_args:Nc \cs_replacement_spec:N
+ {
+ \c_@@_code_root_str
+ \@@_trim_spaces:n { #2 / #3 }
+ }
+ }
+ }
+ }
+ }
+ { } { }
+ }
+\cs_gset:Npx \@@_show:n #1
+ {
+ \exp_not:N \@@_show:w
+ #1
+ \tl_to_str:n { \@@_precompile:n }
+ #1
+ \tl_to_str:n { \@@_precompile:n }
+ \exp_not:N \s_@@_stop
+ }
+\use:x
+ {
+ \cs_gset:Npn \exp_not:N \@@_show:w
+ ##1 \tl_to_str:n { \@@_precompile:n }
+ ##2 \tl_to_str:n { \@@_precompile:n }
+ ##3 \exp_not:N \s_@@_stop
+ }
+ {
+ \tl_if_blank:nTF {#2}
+ {#1}
+ { \@@_show:Nw #2 \s_@@_stop }
+ }
+\use:x
+ {
+ \cs_gset:Npn \exp_not:N \@@_show:Nw ##1##2
+ \c_right_brace_str \exp_not:N \s_@@_stop
+ }
+ {#2}
+% \end{macrocode}
+%
+% \subsection{Setup}
+%
+% \begin{macrocode}
+%<@@=prototype>
+% \end{macrocode}
+%
+% \begin{variable}{\l_@@_tmp_tl}
+% \begin{macrocode}
+\tl_new:N \l_@@_tmp_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Data structures}
+%
+% \begin{variable}{\l_@@_object_prop}
+% \begin{macrocode}
+\prop_new:N \l_@@_object_prop
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Creating objects}
+%
+% \begin{macro}{\prototype_declare_object:nn, \@@_declare_object:nn}
+% Although the object type is the \enquote{top level} of the template
+% system, it is actually very easy to implement. All that happens is that
+% the number of arguments required is recorded, indexed by the name of the
+% object type.
+% \begin{macrocode}
+\cs_new_protected:Npn \prototype_declare_object:nn #1#2
+ {
+ \exp_args:Nx \@@_declare_object:nn { \int_eval:n {#2} } {#1}
+ }
+\cs_new_protected:Npn \@@_declare_object:nn #1#2
+ {
+ \int_compare:nTF { 0 <= #1 <= 9 }
+ {
+ \msg_info:nnnn { prototype } { declare-object-type } {#2} {#1}
+ \prop_put:Nnn \l_@@_object_prop {#2} {#1}
+ }
+ { \msg_error:nnxx { prototype } { bad-number-of-arguments } {#2} {#1} }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Templates and instances}
+%
+% \begin{variable}{\l_@@_assignments_tl}
+% Used to insert the set keys.
+% \begin{macrocode}
+\tl_new:N \l_@@_assignments_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\prototype_declare_template:nnnn}
+% \begin{macro}{\prototype_declare_defaults:nnn}
+% Creating a template means defining the keys, storing the defaults and
+% creating the function. The defaults are done separately from the other
+% parts as that fits the \pkg{l3keys} pattern but also makes it easy to
+% alter that aspect without changing the core implementation.
+% \begin{macrocode}
+\cs_new_protected:Npn \prototype_declare_template:nnnn #1#2#3#4
+ {
+ \prop_get:NnNTF \l_@@_object_prop {#1} \l_@@_tmp_tl
+ {
+ \keys_define:nn { prototype / #1 / #2 } {#3}
+ \tl_clear_new:c { l_@@_defaults_ #1 _ #2 _tl }
+ \cs_generate_from_arg_count:cNnn
+ { @@_template_ #1 _ #2 :w }
+ \cs_set_protected:Npn
+ { \l_@@_tmp_tl }
+ {
+ \tl_use:N \l_@@_assignments_tl
+ #4
+ }
+ }
+ { \msg_error:nnn { prototype } { unknown-object-type } {#1} }
+ }
+\cs_new_protected:Npn \prototype_declare_defaults:nnn #1#2#3
+ {
+ \cs_if_exist:cTF { @@_template_ #1 _ #2 :w }
+ { \tl_set:cn { l_@@_defaults_ #1 _ #2 _tl } {#3} }
+ { \msg_error:nnn { prototype } { unknown-template } {#1} {#2} }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+\cs_generate_variant:Nn \keys_precompile:nnN { v , nv }
+% \end{macrocode}
+%
+% \begin{macro}{\prototype_use_template:nnn}
+% \begin{macro}{\prototype_declare_instance:nnnn}
+% \begin{macro}{\@@_declare_aux:nnnn}
+% Using a template and creating an instance are the same thing other
+% than the final step: using the template or storing the key settings.
+% We do not attempt to maximise efficiency in setting, rather we have
+% a clear approach in which the final assignments may have multiple
+% entries.
+% \begin{macrocode}
+\cs_new_protected:Npn \prototype_use_template:nnn #1#2#3
+ {
+ \@@_declare_aux:nnnn {#1} {#2} {#3}
+ { \use:c { @@_template_ #1 _ #2 :w } }
+ }
+\cs_new_protected:Npn \prototype_declare_instance:nnnn #1#2#3#4
+ {
+ \@@_declare_aux:nnnn {#1} {#2} {#4}
+ {
+ \tl_clear_new:c { l_@@_instance_ #1 _ #3 _pars_tl }
+ \tl_set_eq:cN { l_@@_instance_ #1 _ #3 _pars_tl }
+ \l_@@_assignments_tl
+ \tl_clear_new:c { l_@@_instance_ #1 _ #3 _template_tl }
+ \tl_set:cn { l_@@_instance_ #1 _ #3 _template_tl } {#2}
+ }
+ }
+\cs_new_protected:Npn \@@_declare_aux:nnnn #1#2#3#4
+ {
+ \cs_if_exist:cTF { @@_template_ #1 _ #2 :w }
+ {
+ \keys_precompile:nvN
+ { prototype / #1 / #2 }
+ { l_@@_defaults_ #1 _ #2 _tl }
+ \l_@@_assignments_tl
+ \keys_precompile:nnN { prototype / #1 / #2 } {#3} \l_@@_tmp_tl
+ \tl_put_right:NV \l_@@_assignments_tl \l_@@_tmp_tl
+ #4
+ }
+ { \msg_error:nnn { prototype } { unknown-template } {#1} {#2} }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\prototype_use_instance:nn}
+% \begin{macro}{\prototype_use_instance:nnn}
+% Recover the values and insert the code.
+% \begin{macrocode}
+\cs_new_protected:Npn \prototype_use_instance:nn #1#2
+ { \prototype_use_instance:nnn {#1} {#2} { } }
+\cs_new_protected:Npn \prototype_use_instance:nnn #1#2#3
+ {
+ \tl_if_exist:cTF { l_@@_instance_ #1 _ #2 _template_tl }
+ {
+ \tl_set_eq:Nc \l_@@_assignments_tl
+ { l_@@_instance_ #1 _ #2 _pars_tl }
+ \tl_if_blank:nF {#3}
+ {
+ \keys_precompile:vnN
+ {
+ prototype / #1 /
+ \tl_use:c { l_@@_instance_ #1 _ #2 _template_tl }
+ }
+ {#3}
+ \l_@@_tmp_tl
+ \tl_put_right:NV \l_@@_assignments_tl
+ \l_@@_tmp_tl
+ }
+ \use:c
+ {
+ @@_template_ #1 _
+ \tl_use:c { l_@@_instance_ #1 _ #2 _template_tl }
+ :w
+ }
+ }
+ { \msg_error:nnn { prototype } { unknown-instance } {#1} {#2} }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Showing information}
+%
+% \begin{macro}
+% {
+% \prototype_show_template_code:nn ,
+% \prototype_show_template_defaults:nn ,
+% \prototype_show_instance_values:nn
+% }
+% \begin{macrocode}
+\cs_new_protected:Npn \prototype_show_template_code:nn #1#2
+ {
+ \prop_if_in:NnTF \l_@@_object_prop {#1}
+ { \cs_show:c { @@_template_ #1 _ #2 :w } }
+ { \msg_error:nnn { prototype } { unknown-object-type } {#1} }
+ }
+\cs_new_protected:Npn \prototype_show_template_defaults:nn #1#2
+ {
+ \cs_if_exist:cTF { @@_template_ #1 _ #2 :w }
+ { \tl_show:c { l_@@_defaults_ #1 _ #2 _tl } }
+ { \msg_error:nnn { prototype } { unknown-template } {#1} {#2} }
+ }
+\cs_new_protected:Npn \prototype_show_instance_values:nn #1#2
+ {
+ \tl_if_exist:cTF { l_@@_instance_ #1 _ #2 _template_tl }
+ { \tl_show:c { l_@@_instance_ #1 _ #2 _pars_tl } }
+ { \msg_error:nnn { prototype } { unknown-instance } {#1} {#2} }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Messages}
+%
+% \begin{macrocode}
+\msg_new:nnnn { prototype } { bad-number-of-arguments }
+ { Bad~number~of~arguments~for~object~type~'#1'. }
+ {
+ An~object~may~accept~between~0~and~9~arguments.\\
+ You~asked~to~use~#2~arguments:~this~is~not~supported.
+ }
+\msg_new:nnnn { prototype } { unknown-instance }
+ { The~instance~'#2'~of~type~'#1'~is~unknown. }
+ {
+ You~have~asked~to~use~an~instance~'#2',~
+ but~this~has~not~been~created.
+ }
+\msg_new:nnnn { prototype } { unknown-object-type }
+ { The~object~type~'#1'~is~unknown. }
+ { An~object~type~needs~to~be~declared~prior~to~using~it. }
+\msg_new:nnnn { prototype } { unknown-template }
+ { The~template~'#2'~of~type~'#1'~is~unknown. }
+ {
+ No~interface~has~been~declared~for~a~template~
+ '#2'~of~object~type~'#1'.
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\msg_new:nnn { prototype } { declare-object-type }
+ { Declaring~object~type~'#1'~taking~#2~argument(s). }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\ExplSyntaxOff
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</2ekernel>
+% \end{macrocode}
+%
+% \end{implementation}
diff --git a/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-testphase.dtx b/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-testphase.dtx
index 670bbaf481d..d8d9c671c39 100644
--- a/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-testphase.dtx
+++ b/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-testphase.dtx
@@ -41,17 +41,26 @@
% \section{Introduction}
%
% This code implements small files which can be loaded with the |testphase|
-% key of \cs{DocumentMetadata}. Currently it only contains a
-% wrapper for \pkg{tagpdf}, but this will be extended to allow user to load
+% key of \cs{DocumentMetadata}. This will be extended to allow user to load
% well defined parts of the tagged PDF project.
-%
+% Currently the values |phase-I|, |phase-II| and |new-or| are provided.
+% |tagpdf| is an undocumented alias for |phase-II| which is kept for compability.
%
%
% \StopEventually{\setlength\IndexMin{200pt} \PrintIndex }
%
%
% \section{The Implementation}
-%
+% New output routine code is loaded in phase-II and new-or:
+% \begin{macrocode}
+%<*tagpdf|phase-II|new-or>
+\IfFileExists{latex-lab-testphase-new-or.sty}
+ {
+ \RequirePackage{latex-lab-testphase-new-or}
+ }
+ {}
+%</tagpdf|phase-II|new-or>
+% \end{macrocode}
% \begin{macrocode}
%<*tagpdf|phase-I|phase-II>
% \end{macrocode}
diff --git a/Master/texmf-dist/source/latex-dev/latex-lab/documentmetadata-support.ins b/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab.ins
index 431f88d8109..eb0b066af0e 100644
--- a/Master/texmf-dist/source/latex-dev/latex-lab/documentmetadata-support.ins
+++ b/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab.ins
@@ -35,7 +35,7 @@
This is a generated file.
-Copyright 2021 LaTeX Project
+Copyright 2021,2022 LaTeX Project
This file was generated from file(s) of the `LaTeX-lab Bundle'.
------------------------------------------------------------------------------------
@@ -64,8 +64,24 @@ where one can also log issues in case there are any.
\generate{\file{documentmetadata-support.ltx}{\from{documentmetadata-support.dtx}{code}}}
-\generate{\file{tagpdf-latex-lab-testphase.ltx}{\from{latex-lab-testphase.dtx}{tagpdf}}}
+% files that should be loadable with the testphase key should use the naming scheme
+% #1-latex-lab-testphase.ltx
\generate{\file{phase-I-latex-lab-testphase.ltx}{\from{latex-lab-testphase.dtx}{phase-I}}}
\generate{\file{phase-II-latex-lab-testphase.ltx}{\from{latex-lab-testphase.dtx}{phase-II}}}
+\generate{\file{tagpdf-latex-lab-testphase.ltx}{\from{latex-lab-testphase.dtx}{tagpdf}}}
+\generate{\file{new-or-latex-lab-testphase.ltx}{\from{latex-lab-testphase.dtx}{new-or}}}
+
+% support files (the new-or code is a private package to make life easier)
+
+\generate{\file{latex-lab-testphase-new-or.sty}{\from{latex-lab-new-or.dtx}{code}}}
+\generate{\file{latex-lab-footmisc.ltx}{\from{latex-lab-footnotes.dtx}{footmisc}}}
+\generate{\file{latex-lab-footnotes.ltx}{\from{latex-lab-footnotes.dtx}{kernel}}}
+
+% for \DocumentMetadata trials
+\generate{\file{prototype-latex-lab-testphase.ltx}{\from{latex-lab-prototype.dtx}{2ekernel}}}
+
+% for standalone trials
+\generate{\file{latex-lab-prototype.sty}{\from{latex-lab-prototype.dtx}{2ekernel}}}
+
\endbatchfile