% \iffalse meta-comment
%
%% File: latex-lab-footnotes.dtx
% Copyright (C) 2022-2023 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
% license or (at your option) any later version.  The latest version
% of this license is in the file
%
%    https://www.latex-project.org/lppl.txt
%
%
% The development version of the bundle can be found below
%
%    https://github.com/latex3/latex2e/required/latex-lab
%
% for those people who are interested or want to report an issue.
%
\def\ltlabfootnotedate{2023-09-04}
\def\ltlabfootnoteversion{0.8c}

%<*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\DescribeHook[noprint]{#1}}}
% \providecommand\socket[1]{\texttt{#1\DescribeSocket[noprint]{#1}}}
% \providecommand\plug[1]{\texttt{#1\DescribePlug[noprint]{#1}}}
%
% \NewDocElement[printtype=\textit{socket},idxtype=socket,idxgroup=Sockets]{Socket}{socketdecl}
% \NewDocElement[printtype=\textit{hook},idxtype=hook,idxgroup=Hooks]{Hook}{hookdecl}
% \NewDocElement[printtype=\textit{plug},idxtype=plug,idxgroup=Plugs]{Plug}{plugdecl}
%
% \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 mutually exclusive). This is achieved by
%    providing a larger number of hooks (for areas where different
%    packages/classes can easily coexist with their adjustments) and a
%    number of sockets to which only one class or package
%    can write to successfully (in case of multiple changes 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 footnote setup should
%    use the interfaces provided here and not do it through the
%    legacy methods (though there is some support for the latter as
%    well, but it will not work in all 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 definitions
%    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{Sockets and hooks}
%
%    We use sockets for those parts that can be controlled only by one
%    package or by the kernel and hooks for places where it may be
%    possible that several packages or the document class adds code
%    (typically declarations such as font changes, etc.).
%
%    Note that sockets 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 footnote 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{Sockets}
%
%    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 for formatting the footnote mark in text}
%
%    The hooks to customize the marks in the text are the following:
%    \begin{description}
%    \item[\hook{fnmark/before}]
%
%      \DescribeHook[noprint]{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 necessarily 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}]
%
%      \DescribeHook[noprint]{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 a \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}]
%
%      \DescribeHook[noprint]{fnmark/begin}
%
%      This hook is executed directly in front of the typeset mark.
%      This is the place where \pkg{hyperref} would have added
%      part of its code, i.e., after the \cs{nobreak} mentioned above.
%      With the integration of hyperlinks in the tagging code
%      this hook may not be necessary at all.
%
%    \item[\hook{fnmark/end}]
%
%      \DescribeHook[noprint]{fnmark/end}
%
%      This hook is executed directly after the typeset mark. It is
%      used by \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}]
%
%      \DescribeHook[noprint]{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{Sockets}
%
%    To cater for different layout configurations there are four
%    sockets that can be set by a package or 
%    class but there should be only one per document setting them, i.e., if two packages/classes set them they are mutually
%    incompatible (or rather the last one wins most likely).
%    These are:
%    \begin{description}
%    \item[\socket{fntext/process} (1 argument)]
%
%      \DescribeSocket[noprint]{fntext/process}
%
%      This socket receives all material that is to be processed (or
%      stored) including color protection code and what have you.
%      The \plug{default} executes \cs{insert}\cs{footins}.
%
%      Available plugs are \plug{default}, \plug{side} (side notes), and \plug{mp} (minipage).
%
%
%    \item[\socket{fntext/make}  (1 argument)]
%
%      \DescribeSocket[noprint]{fntext/make}
%
%      This socket receives the \meta{text} as given in \cs{footnote}
%      or \cs{footnotetext} in the document and adds formatting
%      instructions to it.
%
%      The \plug{default} plug 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 it with \cs{insert} and this socket
%      allows running extra code to do that.
%
%      Available plugs are \plug{default} and \plug{para}.
%
%    \item[\socket{fntext/begin} (no argument)]
%
%      \DescribeSocket[noprint]{fntext/begin}
%
%      The socket is executed near the start of the
%      argument for the \socket{fntext/make} socket.
%      By \plug{default} it 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 as a single paragraph) and so with
%      this socket one can cancel the action or do something else
%      instead.
%
%      Available plugs are \plug{default} and \plug{noop}.
%
%
%    \item[\socket{fntext/end} (no argument)]
%
%      \DescribeSocket[noprint]{fntext/end}
%
%      This socket is executed at the very end of the argument passed
%      to socket \socket{fntext/make}.  By \plug{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 which is done
%      with the plug \plug{para}.
%
%      Available plugs are \plug{default}, \plug{para}, and
%      \plug{noop}.
%    \end{description}
%
%
%    All standard plugs for the socket \socket{fntext/make} run
%    \cs{@makefntext} and this command contains two further
%    sockets (unless it is overwritten by a legacy class):
%    \begin{description}
%    \item[\socket{fntext/mark} (0 arguments)]
%
%      \DescribeSocket[noprint]{fntext/mark}
%
%      This socket has no input arguments but uses \cs{@makefnmark} to
%      typeset the mark in front of the footnote text. Its
%      \plug{default} uses code that examines the value of
%      \cs{footnotemargin} and based on its setting typeset the mark
%      in different ways:
%      \begin{itemize}
%      \item positive: typeset the mark in a box of that size
%      \item zero: use \cs{llap} around the mark
%      \item negative: use \cs{llap} but with a box of the given size
%      negated inside
%      \item \texttt{-}\cs{maxdimen}: just use \cs{@makefnmark} 
%      \end{itemize}
%      For most cases this would be flexible enough, but if not then a
%      class can define its own plug to specify the placement of the mark.
%
%      Available plugs are \plug{default} and \plug{noop} (no mark is produced).
%
%
%    \item[\socket{fntext/text} (1 argument)]
%
%      \DescribeSocket[noprint]{fntext/text}
%
%      This socket manages the formatting of the footnote text
%      (presented as an argument) once the mark has been typeset.  In
%      all cases we can think of this formatting is better configured
%      via the available hooks described below, so the \plug{default}
%      just grabs the argument and processes it without any other
%      action. It is really only there to allow for some fancy stuff
%      that some design comes up with.
%
%      Available plugs are \plug{identity} (default) and \plug{noop}.
%
%    \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 for formatting the footnote text}
%
%    \begin{description}
%    \item[\hook{fntext/before}]
%
%      \DescribeHook[noprint]{fntext/before}
%
%      Executed at the very beginning of \cs{footnotetext}. Currently
%      there is one package (\pkg{linguex}) that
%      prepends material at this point.
%
%      This hook is paired with hook \hook{fnmark/after}.
%
%    \item[\hook{fntext}]
%
%      \DescribeHook[noprint]{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}]
%
%      \DescribeHook[noprint]{fntext/para}
%
%      After the font is set (after the previous hook), some 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 which can overwrite
%      the default. 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.
%
%      Note: the socket \socket{fntext/make} 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  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 other point.
%
%    \item[\hook{fntext/begin} \& \hook{fntext/end}]
%
%      \DescribeHook[noprint]{fntext/begin}
%      \DescribeHook[noprint]{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}]
%
%      \DescribeHook[noprint]{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{linguex}, have
%      code in that position.
%
%    \end{description}
%
%
%
%
% \subsubsection{Additional configuration possibilities}
%
%    The formatting of the footnote mark in front of the footnote
%    text 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 and hyperlinking support}
%
% \fmi{this section needs work (and probably csname changes)}
%
% Footnotes consist of a \emph{footnotemark} (short: mark) that is typically placed in the text
% as a superscript number like this\footnotemark[1], and a \emph{footnotetext}
% (short: note) that is placed at the bottom of the page.
% The \emph{footnotetext} normally repeats at the begin the mark as a visual clue.
%
% Tagging (and hyperlinking) has to connect the mark with the note.
% For the tagging code, we assume that every mark has exactly one associated note,
% and that every note is associated to at least one mark
% and can have more associated marks.
%
% The mark doesn't need to be visible, e.g. the typesetted
% mark\textsuperscript{1--3} denotes three marks, where the second is invisible.
% Tagging should produce here probably three \texttt{Lbl} structures
% (one without content), and an artifact for the range marker.
% If such a range is used, links can only point to the notes 1 and 3 and
% one has to suppress the linking for the second mark.
% This means that links and tagging are also related
% to the actual formatting of the footnote mark.
% In the following this problem is mostly ignored for now, but
% should not be forgotten and handled later.
%
% \subsection{Technical details for the tagging}
%
% The following sockets are set up for kernel use, when doing tagging:
% \begin{description}
%    \item[\socket{tagsupport/fnmark} (1 argument)]
%
%      \DescribeSocket[noprint]{tagsupport/fnmark}
%
%      \fmi{describe and decide on names}
%
%
%    \item[\socket{tagsupport/fntext/begin} (no argument)]
%
%      \DescribeSocket[noprint]{tagsupport/fntext/begin}
%
%
%    \item[\socket{tagsupport/fntext/end} (no argument)]
%
%      \DescribeSocket[noprint]{tagsupport/fntext/end}
%
%
%    \item[\socket{tagsupport/fntext/mark} (1 argument)]
%
%      \DescribeSocket[noprint]{tagsupport/fntext/mark}
%
%
%    \item[\socket{tagsupport/fntext/text} (1 argument)]
%
%      \DescribeSocket[noprint]{tagsupport/fntext/text}
%
%
% \end{description}
%
%
% The \emph{footnotemark} should create a \texttt{/Lbl} structure\footnote{to make it easier
% to identify the role we use \texttt{/footnotemark} which we rolemap to \texttt{/Lbl}} that should contain a \texttt{/Ref} entry pointing
% to the structure of the \emph{footnotetext}.
%
% The \emph{footnotetext} should create a \texttt{/FENote}\footnote{We tag it as \texttt{/footnote} and role map it.}
%  structure with a \texttt{/Ref}
% entry pointing to the structures of \emph{all} marks related to the note.
% The mark at the begin of the
% note is in a \texttt{/Lbl}\footnote{We tag it as \texttt{/footnotelabel}.}
% structure but has to fulfil no special requirements.
%
% Structure objects and the underlying properties used by the tagging
% code are initialized when the structure is opened. This means that one can not
% directly add data to a future structure
% but as structure objects are written at the end of the document it is
% possible to update \texttt{/Ref} entries in an end document hook.
%
%
% So tagging has to solve two problems:
% \begin{itemize}
% \item the mark and the footnote text must be surrounded by the correct structure
%  and marked content commands. This is not trivial
%  as there are various layouts (bottom, marginpar, minipage) and the tagging
%  from the automatic paratagging must be taken into account if one want to avoid
%  faulty nesting.
%
% \item It must detect which marks are related to which notes
%  so that it can setup the \texttt{/Ref} cross-references.
% \end{itemize}
%
%
% \subsection{Requirements for links}
%
% Links should go from the mark to the note. Sometimes it has been requested
% that links go back too, but as there
% can be more than one mark connected to a note it is not clear how to decide to which mark it should go.
% Using the keys from the PDF viewer to go back is normally better.
%
% Links are closely related to the references stored in the \texttt{/Ref}
% entry of a mark and so are handled in the code together with them.
% But there are subtle technical differences to take care of
% as links and destinations are whatsits and so must be created at the correct time.
%
% It should be possible to suppress the links both globally and locally.\footnote{
% Currently hyperref only offers the option to suppress the
% footnote links globally
% with the option \texttt{hyperfootnotes=false}. To suppress them locally
% only the \texttt{NoHyper} environment is provided.}
%
%
% \subsection{The algorithmus to connect marks and notes}
%
%
% The connection is made by comparing the value of \cs{@thefnmark}.
%
% The standard mark commands (\cs{footnotemark} and \cs{footnote})
% store the current value of \cs{@thefnmark}
% with their own structure number as a key in a property.
%
% A following \cs{footnotetext} compares its own \cs{@thefnmark} with the values in
% the prop. If there is a match it stores the structure numbers and removes the entries
% from the properties (so in a normal document the property will never contain more than
% a few entries).
%
% This works well as long as the \cs{footnotemark} commands are issued before the \cs{footnotetext} and
% as long as nothing unusual is done to \cs{@thefnmark}.
% It also works if a document uses more than one footnote series as long as they have distinct numbering
% systems, but in case a distinction is needed it is possible to define
% a new class with its own data structure and to switch locally to use this
% class. The following three commands are used for this.
%
% The default class uses the name \texttt{default}
%
% \begin{function}{\fnote_class_new:nn}
% \begin{syntax}
% \cs{fnote_class_new:nn}\Arg{name}\Arg{key/value option}
% \end{syntax}
%   This declaration sets up the needed data structure. Currently this only
%   consists of a property list which is used to store and manage the mark values.
%   There are no options yet.
% \end{function}
%
% \begin{function}{\fnote_mark_gput:nn,\fnote_mark_gput:no,\fnote_mark_gput:oo}
% \begin{syntax}
% \cs{fnote_mark_gput:nn}\Arg{mark}\Arg{class name}
% \end{syntax}
%   This command stores the current structure number as key and the \meta{mark} as
%   value in the property list associated with the \meta{class name}.
% \end{function}
%
% \begin{function}{\fnote_mark_gpop_all:nnN}
% \begin{syntax}
% \cs{fnote_mark_gpop_all:nnN}\Arg{mark}\Arg{class name}\meta{sequence}
% \end{syntax}
% This command stores all the keys/structure numbers whose value in the
% property list for \meta{class name} are equal to \meta{mark}
% into the sequence \meta{sequence} and then removes them from the property list. 
% The content of the sequence can then be
% used to create link targets and references.
% \end{function}
%
%
% \subsubsection{\cs{footref}}
%
% \cs{footref} use internally the same command to set the mark as \cs{footnotemark}, it only
% defines \cs{@thefnmark} differently. This \cs{@thefnmark} is not suitable for the method described
% above, as it contains a reference command it can't be used to match a note, also \cs{footref} can
% be used after the note has already been set. \cs{footref} disables therefore the automatic detection.
%
% Instead the \cs{label} command is 
% extended in the \cs{footnotetext} command to also store the structure number and \cs{footref} retrieves this
% number to setup the reference and the link.
%
% The structure related to the \cs{footref} is added to the end of the \texttt{/Ref} array of the note and so the
% \texttt{/Ref} array doesn't necessarly reflect the order of the marks in the document. It would probably
% be possible to change this, but it is not clear if it actually matters and so it worth the additional coding
% and processing.
%
% \subsubsection{\cs{footnotemark} after \cs{footnotetext}}
%
% The automatic detection doesn't work if a \cs{footnotemark} is issued after
% the \cs{footnotetext} it refers to. There will be no error, but neither the link nor
% the \texttt{/Ref} will connect both.
%
% The simple way to handle this is to use a label and \cs{footref}:
%
% \begin{verbatim}
% \footnotetext{\label{fn:a}text} ... \footref{fn:a}
% \end{verbatim}
%
% An alternative would be to extend the syntax of \cs{footnotemark} and
% \cs{footnotetext} to allow to add a label which can then be used.
% For example
%
% \begin{verbatim}
% \footnotetext[label=fn:a]{text} ... \footnotemark[label=fn:a]
% \end{verbatim}
%
% As both have already an optional argument, that requires the optional argument extension.
%
%
% \subsection{Links}
%
% The structure numbers detected for the \texttt{/Ref} are also used for links:
% even if tagging is not activated the tagging commands are defined through
% the \pkg{tagpdf-base} package
% and the structure commands increase the structure counter and this info can be used.
%
% A \cs{footnotetext} creates a bunch of destinations (in most cases this sums up to
% two destinations): one for every structure number in the \texttt{/Ref} (used as target
% by the mark commands) and one for the structure number of the footnotetest itself
% (used as target by \cs{footref}s commands).
%
% \subsection{Implementation details regarding tagging}
%
% \subsection{Handling the mark}
%
% The mark in the text is handled by assigning an appropriate
% plug to the socket \socket{tagsupport/fnmark}.
%  It takes one argument, \cs{@makefnmark}, the
% command which formats the mark, and surrounds it by link and tagging
% commands.  At the point where the socket is
% executed, \cs{@thefnmark} has already been defined and can be used to
% setup the reference detections.
%
%
% \subsection{Handling the footnotetext}
%
% The main part is done by assigning a different plug to socket \socket{tagsupport/fntext/begin}
% and \socket{tagsupport/fntext/end}
% surrounding the footnote text.
% These sockets are used to start and end the structure and
% attempt to detect to which mark the note is related.
%
% The actual typesetting of the note text is done by
% \cs{fnote_makefntext:n} (or its \LaTeXe{} name \cs{@makefntext}). In
% the new implementation this contains two further kernel sockets for tagging:
% \socket{tagsupport/fntext/mark} and
% \socket{tagsupport/fntext/text}. They get plugs assigned that add the
% tagging commands around note mark and note text.
%
% \subsection{Footnotes in minipages}
%
% In minipages the \cs{footnote} command uses a special marker
% (small italic letters by default) and puts the
% footnote text at the bottom of the box. The \cs{footnotemark}
% command uses the standard footnote counter and marker (and so typically
% creates a superscript number).
% It is meant to be used with a \cs{footnotetext} \emph{outside}
% the minipage to create a footnote mark which refers to a footnote text
% at the bottom of the page.
% This means to repeat a footnote marker in a minipage you should use the \cs{footref} command.
%
% Tagging works quite similar to normal footnotes if the new definition is used
% and if the minipage code is changed to use the new configuration point.
% The main problem here is currently the tagging of the minipage itself.
%
% \section{TODOs}
%
% \begin{itemize}
%
% \item Special formatting of footnote marks in the text, e.g. if ranges or commas are
% used require special care as they should normally mark up such text as artifacts and
% perhaps have to insert empty structures to represent an invisible mark. This must be coordinated
% with the relevant packages and classes.
%
% \item manyfoot doesn't work correctly and must be analyzed.
%
% \item \pkg{memoir} is not supported at all and errors when the code tries to patch
% \cs{@makefntext}.
% \end{itemize}
%
%  \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}
             [\ltlabfootnotedate\space v\ltlabfootnoteversion\space
               changes to the footnote interfaces]
%    \end{macrocode}
%
% \subsection{code not fully handled yet}
%    \begin{macrocode}
%
% latex.ltx
% not looked at yet
% \@mpfootnotetext is probably no longer needed, or only to support other
% classes and package. See below about the minipage code.
%
% \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}}
% ========
% used by the minipage footnote code.
%
% \def\@mpfn{footnote}
% \def\thempfn{\thefootnote}
% =========
% this perhaps need some configuration options.
%
%\def\@makefnmark{\hbox{\@textsuperscript{\normalfont\@thefnmark}}}
%
% =========
%% alterations not covered:
%
% ./arabtex/afoot.sty  --- too different (and probably too old)
%
% =====
% alterations of footnotetext not covered:
%
% ./revtex4-1/revtex4-1.cls  ./revtex/ltxutil.sty ./revtex/revtex4-2.cls ... (need analysis)
% ./bigfoot/bigfoot.sty
%
% memoir needs checking too
%
% =====
%
% 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
%
%    \end{macrocode}
%-------------------------------------
%    \begin{macrocode}
\ExplSyntaxOn
%    \end{macrocode}
% \subsection{Temporary variables}
%    \begin{macrocode}
\prop_new:N \l_@@_tmpa_prop
\tl_new:N   \l_@@_tmpa_tl
%    \end{macrocode}
% \subsection{Public variables}
%
% A footnote mark will store its structure number (key) and the
% expanded \cs{@thefnmark} in this prop so
% that a following note can retrieve this info
% if needed. It is possible to use more than one footnote series (type)
% if needed (if different footnotes/note use the same
% numbering system).
% If this command is changed an accompanying property must be created
% \begin{NOTE}{UF}
% TODO: interface to create the property.\\
% TODO: check and decide about the name of the tl
% \end{NOTE}
% \begin{macro}{\l_fnote_type_tl}
%    \begin{macrocode}
\tl_new:N  \l_fnote_type_tl
\tl_set:Nn \l_fnote_type_tl {default}
%    \end{macrocode}
% \end{macro}
% It must be possible to suppress the hyperlinking, both locally
% and globally. hyperref's hyperfootnotes option should set the boolean.
% \begin{macro}{\l_fnote_link_bool}
%    \begin{macrocode}
\bool_new:N       \l_fnote_link_bool
\bool_set_true:N  \l_fnote_link_bool
%    \end{macrocode}
% \end{macro}
% A hyperlink should have an changeable link type. This can
% be e.g. used to change the color or the border.
% \begin{macro}{\l_fnote_link_type_tl}
%    \begin{macrocode}
\tl_new:N  \l_fnote_link_type_tl
\tl_set:Nn \l_fnote_link_type_tl {link}
%    \end{macrocode}
% \end{macro}
%
% \subsection{Internal variables}
%
% \begin{macro}{\l_@@_linktarget_tl}
%  This command stores the name of a linktarget/destination
%  when needed
%    \begin{macrocode}
\tl_new:N \l_@@_linktarget_tl
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\l_@@_currentlabel_tl}
% This command is used to pass a label name around.
%    \begin{macrocode}
\tl_new:N \l_@@_currentlabel_tl
%    \end{macrocode}
% \end{macro}

% \begin{macro}{\l_@@_currentrefs_seq}
% This sequence stores the list of reference of a note
%    \begin{macrocode}
\seq_new:N  \l_@@_currentrefs_seq
%    \end{macrocode}
% \end{macro}
%
% The connection between the mark(s) in the text and the note
% is either deduced automatically or done through an label.
% The default is automatic, but we must be able to suppress it. For this we use a boolean.
% \begin{macro}{\l_@@_autodetect_bool}
%    \begin{macrocode}
\bool_new:N       \l_@@_autodetect_bool
\bool_set_true:N  \l_@@_autodetect_bool
%    \end{macrocode}
% \end{macro}
% This is used to pass the structure number of the note around, e.g.
% to a label inside the note.
%    \begin{macrocode}
\tl_new:N  \l_@@_currentstruct_tl
\tl_set:Nn \l_@@_currentstruct_tl {1}
%    \end{macrocode}
%
%
% \subsection{Variants}
%
%    \begin{macrocode}
\cs_generate_variant:Nn \hook_gput_code:nnn{nne}
\cs_generate_variant:Nn \tag_struct_use:n {e}
%    \end{macrocode}
%
% \subsection{Updating \cs{@thefnmark}}
% \begin{macro}{\fnote_step_fnmark:nn}
% This command updates \cs{@thefnmark}. The first argument
% is an optional integer expression, the second a counter name.
% If the optional argument is not given it steps the counter.
%    \begin{macrocode}
\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:
    }
}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\fnote_set_fnmark:nn}
% This is similar to the previous command, but it doesn't step the
% counter but use the current value.
%    \begin{macrocode}
\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:
    }
}
%    \end{macrocode}
% \end{macro}
%
% \subsection{Hooks}
%
% \begin{hookdecl}{fnmark/before,fnmark/after,
%              fnmark,
%              fnmark/begin,fnmark/end}
%    Hooks in the footnotemark command.
%    \begin{macrocode}
\NewMirroredHookPair{fnmark/before}{fnmark/after}
\NewHook{fnmark}
\NewHook{fnmark/begin}
\NewHook{fnmark/end}
%    \end{macrocode}
% \end{hookdecl}
%
% \begin{hookdecl}{fntext/before,fntext/after,
%              fntext,
%              fntext/begin,fntext/end,fntext/para}
%     Hooks in the footnotetext command:
%    \begin{macrocode}
\NewMirroredHookPair{fntext/before}{fntext/after}
\NewHook{fntext}
\NewHook{fntext/para}
\NewHook{fntext/begin}
\NewHook{fntext/end}
%    \end{macrocode}
% \end{hookdecl}
%
% \subsection{Debugging code}
% the debugging code is just temporary
%
% For now we have debugging turned on by default
%    \begin{macrocode}
\bool_new:N        \g_fnote_debug_bool
\bool_gset_true:N  \g_fnote_debug_bool
%    \end{macrocode}
% We log the hooks in the footnote mark command, but only once
%    \begin{macrocode}
\cs_new_protected:Npn \@@_debug_footnotemark:
  {
    \bool_if:NT \g_fnote_debug_bool
       {
         \hook_log:n {fnmark/before}
         \hook_log:n {fnmark}
         \hook_log:n {fnmark/begin}
         \hook_log:n {fnmark/end}
         \hook_log:n {fnmark/after}
         \cs_gset_eq:NN \@@_debug_footnotemark: \prg_do_nothing:
       }
  }
%    \end{macrocode}
% Similar for the footnotetext
%    \begin{macrocode}
\cs_new_protected:Npn \@@_debug_footnotetext:
  {
    \bool_if:NT \g_fnote_debug_bool
       {
         \socket_log:n {fntext/process}
         \socket_log:n {fntext/make}
         \socket_log:n {fntext/begin}
         \socket_log:n {fntext/end}
%    \end{macrocode}
%
%    \begin{macrocode}
         \socket_log:n {fntext/mark}
         \socket_log:n {fntext/text}
%    \end{macrocode}
%
%    \begin{macrocode}
         \socket_log:n {tagsupport/fnmark}
         \socket_log:n {tagsupport/fntext/begin}
         \socket_log:n {tagsupport/fntext/end}
         \socket_log:n {tagsupport/fntext/mark}
         \socket_log:n {tagsupport/fntext/text}
%    \end{macrocode}
%
%    \begin{macrocode}
         \hook_log:n {fntext/before}
         \hook_log:n {fntext}
         \hook_log:n {fntext/para}
         \hook_log:n {fntext/begin}
         \hook_log:n {fntext/end}
         \hook_log:n {fntext/after}
%    \end{macrocode}
%    Show the info only once (if at all).
%    \begin{macrocode}
         \cs_gset_eq:NN \@@_debug_footnotetext: \prg_do_nothing:
       }
  }
%    \end{macrocode}
%
% \subsection{The new \cs{@footnotemark} command}
% \begin{macro}{\fnote_footnotemark:}
% This is the main command which will replace \cs{@footnotemark}.
%    \begin{macrocode}
\cs_new_protected:Npn \fnote_footnotemark: {
  \@@_debug_footnotemark:
%-------
% bibarts
% chextras  --- actually in the wrong place does an \unskip
  \hook_use:n {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
    \hook_use:n {fnmark}
%-------
    \nobreak
  \fi
%-------
% hyperref.sty
  \hook_use:n {fnmark/begin}
%-------
%    \end{macrocode}
%    The kernel socket for tagging. It picks up \cs{@makefnmark} as its
%    argument and if tagging is not active it contains the \plug{identity} plug.
%    \begin{macrocode}
  \socket_use:nn {tagsupport/fnmark} \@makefnmark
%-------
%    \end{macrocode}
%    If a footnote mark is placed by its own then it should finish by
%    executing the hook \hook{fnmark/end}, resetting the space  factor, and
%    finishing with the  hook \hook{fnmark/after}. However, in 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:
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@@_footnotemark_default_finish:,\@@_footnotemark_finish:}
%    The default definition for \cs{@@_footnotemark_finish:} is called \cs{@@_footnotemark_default_finish:}
%    \begin{macrocode}
\cs_new_protected:Npn \@@_footnotemark_default_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}
%-------
}
%    \end{macrocode}
%
%    \begin{macrocode}
\cs_new_eq:NN \@@_footnotemark_finish: \@@_footnotemark_default_finish:
%    \end{macrocode}
% \end{macro}
%
% \begin{socketdecl}{tagsupport/fnmark}
%    Not a public socket but reserved for  tagging. By
%    default it contains \plug{identity} and is reassigned if tagging is active.
%    \begin{macrocode}
\NewSocket{tagsupport/fnmark}{1}
%    \end{macrocode}
% \end{socketdecl}
%
% \begin{macro}{\@footnotemark}
%    Here we provide the traditional \LaTeXe{} name in case it is directly used
%    in some legacy class.
%    \begin{macrocode}
\cs_set_eq:NN  \@footnotemark \fnote_footnotemark:
%    \end{macrocode}
% \end{macro}
%
%
% \subsection{The new \cs{@footnotetext} command}
%
%
% \begin{macro}{\fnote_footnotetext:n}
%    \begin{macrocode}
\cs_new_protected:Npn \fnote_footnotetext:n #1 {
  \@@_debug_footnotetext:
%-------
% ./linguex/linguex.sty
  \hook_use:n {fntext/before}
%-------
%    \end{macrocode}
%    Execute a kernel socket for tagging.
%    \begin{macrocode}
  \socket_use:n {tagsupport/fntext/begin}
%    \end{macrocode}
%
%    \begin{macrocode}
  \socket_use:nn {fntext/process}
    {
%-------
% resetting baselinestretch ... (could be done further down)
% ./uafthesis/uafthesis.cls
% ./setspace/setspace.sty
% ./footmisc/footmisc.sty (normal)
    \hook_use:n {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
    \hook_use:n {fntext/para}
%-------
    \color@begingroup
%-------
% fnpara wants to replace \@makefntext{...} and para and side
% option of footmisc etc too ...
% so we make this a socket, because only one action can be active:
%-------
      \socket_use:nn {fntext/make}
        {
%-------
% ./resphilosophica/resphilosophica.cls
%-------
          \socket_use:n {fntext/begin}%
%-------
% bibarts
% fnbreak.sty
          \hook_use:n {fntext/begin}
%-------
          \ignorespaces
          #1
%-------
% bibarts
% fnbreak.sty
          \hook_use:n {fntext/end}
%-------
%    \end{macrocode}
%    The socket code (by default adding a strut) has to come
%    \emph{after} everything added into the hook above.
%    \begin{macrocode}
          \socket_use:n {fntext/end}
        }
      \par
    \color@endgroup
  }
%-------
%    \end{macrocode}
%    The corresponding kernel hook that ends the tagging structure if
%    tagging is active.
%    \begin{macrocode}
  \socket_use:n{tagsupport/fntext/end}
%-------
% ./linguex/linguex.sty
  \hook_use:n {fntext/after}
%-------
}
%    \end{macrocode}
% \end{macro}
%
% \begin{socketdecl}{fntext/process}
%
%    \begin{macrocode}
\NewSocket    {fntext/process}{1}
\NewSocketPlug{fntext/process}{default}{ \insert\footins {#1} }
\NewSocketPlug{fntext/process}{side}   { \marginpar {#1} }
%    \end{macrocode}
%    
%    \begin{macrocode}
\AssignSocketPlug{fntext/process}{default}
%    \end{macrocode}
% \end{socketdecl}
%
%
%
% \begin{socketdecl}{fntext/make}
%    This socket receives the \meta{text} from the \cs{footnote} or
%    \cs{footnotetext} and formats it.
%    \begin{macrocode}
\NewSocket    {fntext/make}{1}
\NewSocketPlug{fntext/make}{default}{ \@makefntext {#1} }
%    \end{macrocode}
%    When running several footnotes together as a paragraph some
%    additional work is necessary to unbox the individual footnotes
%    recursively (see \TeX{}book algorithm in appendix~D).
%    \begin{macrocode}
\NewSocketPlug{fntext/make}{para}
{
  \setbox\FN@tempboxa\hbox{\@makefntext{#1}}%
  \dp\FN@tempboxa\z@
  \ht\FN@tempboxa
  \dimexpr\wd\FN@tempboxa *%
             \footnotebaselineskip /\columnwidth\relax
  \box\FN@tempboxa
}
%    \end{macrocode}
%
%    \begin{macrocode}
\AssignSocketPlug{fntext/make}{default}
%    \end{macrocode}
% \end{socketdecl}
%
% \begin{socketdecl}{fntext/begin}
%    By default adds a strut at the start of the footnote text.
%    \begin{macrocode}
\NewSocket    {fntext/begin}{0}
\NewSocketPlug{fntext/begin}{default}{ \rule\z@\footnotesep }
%    \end{macrocode}
%
%    \begin{macrocode}
\AssignSocketPlug{fntext/begin}{default}
%    \end{macrocode}
% \end{socketdecl}
%
% \begin{socketdecl}{fntext/end}
%    By default adds a strut at the end of the footnote text unless we
%    are no longer in hmode.
%    \begin{macrocode}
\NewSocket    {fntext/end}{0}
\NewSocketPlug{fntext/end}{default}{ \@finalstrut\strutbox }
%    \end{macrocode}
%    When running several footnotes together as a paragraph some
%    additional glue has to be added between them.
%    \begin{macrocode}
\NewSocketPlug{fntext/end}{para}
  {%
           \strut
           \penalty-10\relax
           \hskip\footglue
  }
%    \end{macrocode}
%
%    \begin{macrocode}
\AssignSocketPlug{fntext/end}{default}
%    \end{macrocode}
% \end{socketdecl}
%
% \begin{socketdecl}{tagsupport/fntext/begin,tagsupport/fntext/end}
%    Kernel sockets for tagging.
%    \begin{macrocode}
\NewSocket{tagsupport/fntext/begin}{0}
\NewSocket{tagsupport/fntext/end}{0}
%    \end{macrocode}
% \end{socketdecl}
%
% 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).
%    \begin{macrocode}
\AddToHook{begindocument}
  {
    \cs_set_eq:NN \@footnotetext \fnote_footnotetext:n
  }
%    \end{macrocode}
%
%
%
%
% \subsection{The new \cs{@makefntext} command}
%
% \cs{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.
%    \begin{macrocode}
\newdimen\footnotemargin
\footnotemargin\maxdimen         % no value given

\AtBeginDocument
  {
    \ifdim \footnotemargin=\maxdimen
      \setlength\footnotemargin{1.8em}
    \fi
  }
%    \end{macrocode}
%
%
%
% 
% \begin{macro}{\fnote_makefntext:n}
%    \begin{macrocode}
\cs_new_protected:Npn \fnote_makefntext:n #1 {
%    \end{macrocode}
%    Some classes in their redefinition for \cs{@makefntext} have
%    placed 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}
  \noindent
%    \end{macrocode}
%    
%    \begin{macrocode}
  \socket_use:nn {tagsupport/fntext/mark} { \socket_use:n  {fntext/mark} } 
  \socket_use:nn {tagsupport/fntext/text} { \socket_use:nn {fntext/text}{#1} } 
}
%    \end{macrocode}
% \end{macro}
%
% \begin{socketdecl}{fntext/mark}
%    A socket to typeset the mark at the start of a footnote.
%    \begin{macrocode}
\NewSocket    {fntext/mark}{0}
%    \end{macrocode}
%    The \plug{default} plug implements the logic introduced with the
%    \pkg{footmisc} package.
%    \begin{macrocode}
\NewSocketPlug{fntext/mark}{default}{
   \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
}
%    \end{macrocode}
%
%    \begin{macrocode}
\AssignSocketPlug{fntext/mark}{default}
%    \end{macrocode}
% \end{socketdecl}
%
% \begin{socketdecl}{fntext/text}
%    By default this socket does nothing special and simply processes
%    its argument as provided.
%    \begin{macrocode}
\NewSocket    {fntext/text}{1}
%    \end{macrocode}
% \end{socketdecl}
%
%
%
% \begin{socketdecl}{tagsupport/fntext/mark,tagsupport/fntext/text}
%    Not a public socket but reserved for  tagging. By
%    default it contains \plug{identity} and is reassigned if tagging is active.
%    \begin{macrocode}
\NewSocket{tagsupport/fntext/mark}{1}
\NewSocket{tagsupport/fntext/text}{1}
%    \end{macrocode}
% \end{socketdecl}
%
%
%
% \subsubsection{Making documents use the new \cs{@makefntext}}
%
%  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 used in the class.
%
%  Here is 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{macro}{\old@std@class@makefntext}
%    \begin{macrocode}
\newcommand\old@std@class@makefntext[1]{%
    \parindent 1em%
    \noindent
    \hb@xt@1.8em{\hss\@makefnmark}#1}
%    \end{macrocode}
% \end{macro}
%
%    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 kernel configuration hooks in the
%    right place while otherwise leaving the legacy code alone. An
%    updated class would not redefine \cs{@makefntext} but simply add
%    appropriate code to the provided hooks.
%
%    What it does is roughly the
%    following: It looks 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 \UseSocket{tagsupport/fntext/mark}{\hbox BBB { CCC }} DDD
%       \UseSocket{tagsupport/fntext/text}{#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 the first \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 { \UseSocket{tagsupport/fntext/text}{##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 \texttt{\{})  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{\UseSocket{tagsupport/fntext/mark}{#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
%    made by some class or package
%    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{macro}{\footnotetext}
%    \begin{macrocode}
\DeclareDocumentCommand\footnotetext {o+m}
  {
    \fnote_set_fnmark:nn {#1} \@mpfn
    \@footnotetext {#2}
  }
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\footnote}
%    \begin{macrocode}
\DeclareDocumentCommand\footnote {o+m}
  {
    \fnote_step_fnmark:nn {#1} \@mpfn
    \cs_set_eq:NN \@@_footnotemark_finish: \prg_do_nothing:
    \@footnotemark
    \cs_set_eq:NN \@@_footnotemark_finish: \@@_footnotemark_default_finish:
    \@footnotetext {#2}
    \@@_footnotemark_finish:
  }
%    \end{macrocode}
% \end{macro}
%

% \begin{macro}{\footnotemark}
%    \begin{macrocode}
\DeclareDocumentCommand\footnotemark {o}
  {
    \fnote_step_fnmark:nn {#1} { footnote }
    \@footnotemark
  }
%    \end{macrocode}
% \end{macro}

% \begin{macro}{\footref}
% \cs{footref} used the starred \cs{ref} in \cs{@thefnmark}
% as the linking is handled by the tagging code inside
% the \cs{@footnotemark}.
% \cs{footref} should not try to link to its related
% note automatically but should instead use the label.
% This is passed to \cs{@footnotemark} through
% \cs{l__fnote_currentlabel_tl}.
%
%    \begin{macrocode}
\DeclareDocumentCommand\footref {m}
  {
    \begingroup
      \unrestored@protected@xdef\@thefnmark{\ref*{#1}}%
    \endgroup
    \bool_set_false:N  \l_@@_autodetect_bool
    \tl_set:Nn \l_@@_currentlabel_tl {#1}
    \@footnotemark
    \bool_set_true:N  \l_@@_autodetect_bool
  }
%    \end{macrocode}
% \end{macro}
%
%
% \subsection{Firstaid for packages and classes}
%
% \subsection{Kernel patches}
% Tagging of footnotes in minipages require a change in the minipage commands
% We define at first a local configuration command for minipage footnotes.
%
%    \begin{macrocode}
\NewSocketPlug{fntext/process}{mp}
 {
   \global\setbox\@mpfootins\vbox{%
    \unvbox\@mpfootins
    #1
    }
 }
%    \end{macrocode}
%
% \subsubsection{\pkg{memoir}}
% The \pkg{memoir} class redefines various internal commands to inject its
% hooks and addtional code. The following reinstates the kernel command and
% so probably breaks various options of \pkg{memoir}, but without the
% changes it errors anyway. The \pkg{footmisc} package should be used to change
% for example to para footnotes.
%
%    \begin{macrocode}
\AddToHook{class/memoir/before}
  { \let\new@std@class@makecol\@makecol }
\AddToHook{class/memoir/after}
  {
    \cs_set_eq:NN  \@footnotemark \fnote_footnotemark:
    \cs_set_eq:NN  \@makefntext\old@std@class@makefntext
    \cs_set_eq:NN  \@makecol\new@std@class@makecol
  }
%    \end{macrocode}
%
% \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}}
%
%  hyperref has a hook which allows to disable its footnote
%  related patches. As we will handle links directly in the code
%  this is used.
%
%    \begin{macrocode}
\def\hyper@nopatch@footnote{}
%    \end{macrocode}
% We use the hyperref commands for now for links. To avoid
% to have to test for hyperref we provide dummies.
% TODO consider to use specials to get similar spacing.
%    \begin{macrocode}
\AtBeginDocument
  {
   \providecommand\hyper@linkstart{\@gobbletwo}
   \providecommand\hyper@linkend{\@empty}
  }
%    \end{macrocode}
%
% It must be possible to suppress the hyperlinking, both locally
% and globally. hyperref should set the boolean \cs{l_fnote_link_bool}.
% For now we test for the hyperref boolean (so it can be suppressed only globally).
%    \begin{macrocode}
\AtBeginDocument
 {
   \@ifpackageloaded{hyperref}
     {
       \legacy_if:nF{Hy@hyperfootnotes}{\bool_set_false:N \l_fnote_link_bool}
     }
     {
       \bool_set_false:N \l_fnote_link_bool
     }
 }
%    \end{macrocode}
%
% \subsection{Tagging and hyperlink code}
% \subsubsection{Rolemap for structure tags}
% We use role-mapping to get more speaking names
% in the PDF and so ease debugging. These names are already
% provided by tagpdf directly.
%
% \subsubsection{Extending the label system}
% For \cs{footref} and (perhaps later for labeled footnotes)
% we must extend the label system.
% Beside the normal values we also need the structure number of the note.
% We use the inbuild label hook
% At first we define a suitable attribute, it uses as value the structure
% number of the note as stored in \cs{l__fnote_currentstruct_tl}
%    \begin{macrocode}
\property_new:nnnn {fnote/struct}{now}{1}{\l_@@_currentstruct_tl}
%    \end{macrocode}
%
% We add a hook to the label hook. By default it does nothing
% \begin{macro}{\@@_label_hook:e}
%    \begin{macrocode}
\cs_new_protected:Npn \@@_label_hook:e #1 {}
\AddToHookWithArguments{label}{ \@@_label_hook:e{#1}}
%    \end{macrocode}
% \end{macro}
% Inside a footnotetext we change the hook to store the structure number too.
% The name of label is provided as argument in the label hook.
%    \begin{macrocode}
\AddToHook{fntext/begin}
 {
   \cs_set_protected:Npn \@@_label_hook:e #1
    {
      \property_record:ee {@@/#1} {fnote/struct}
    }
 }
%    \end{macrocode}
%
% \subsubsection{Storing and retrieving reference data}
% To establish the connection between a mark and a note
% the mark has to store its representation, and the
% note has to analyse the stored representations to get
% the structure numbers of its mark. This is done
% with the public function to allow similar systems (e.g.
% tabular notes, other footnote series) to make use of this.
%
%
% \begin{macro}{\fnote_class_new:nn}
% This sets up a new footnote type, the first argument
% is the name, the second is meant for options. Currently
% it does nothing at all.
% It is not necessary to setup every footnote like
% command as its own type!
%
%    \begin{macrocode}
\cs_new_protected:Npn \fnote_class_new:nn #1 #2 % #1 name, #2 options
 {
   \prop_new:c { g_@@_currentmarks_ #1 _prop }
 }

\fnote_class_new:nn {default}{}
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\fnote_mark_gput:nn}
% This commands takes as argument the representation of the mark,
% e.g., \cs{@thefnmark} and the type (typically default should work).
%    \begin{macrocode}
\cs_new_protected:Npn \fnote_mark_gput:nn #1 #2 % #1 the representation of the mark, #2 type
 {
   \prop_gput:cen { g_@@_currentmarks_ #2 _prop }
     { \tag_get:n{struct_num} }
     { #1 }
 }

\cs_generate_variant:Nn \fnote_mark_gput:nn {no,oo}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fnote_mark_gpop_all:nnN}
% This commands takes as argument the representation of the mark
% (e.g. the content of\cs{@thefnmark}), the class (typically |default| should work)
% and a sequence into which every structure number in the property
% is stored that has the same value as the mark. The sequence is cleared first.
%    \begin{macrocode}
\cs_new_protected:Npn \fnote_mark_gpop_all:nnN #1 #2 #3
  {
    \seq_clear:N #3
    \prop_set_eq:Nc     \l_@@_tmpa_prop { g_@@_currentmarks_ #2 _prop }
    \prop_map_inline:Nn \l_@@_tmpa_prop
      {
        \tl_if_eq:nnT {#1} { ##2 }
          {
%    \end{macrocode}
% store the key (the structure number) in the seq
%    \begin{macrocode}
            \seq_put_right:Nn #3 { ##1 }
%    \end{macrocode}
% remove entry as used from the global prop
%    \begin{macrocode}
            \prop_gremove:cn { g_@@_currentmarks_ #2 _prop } {##1}
          }
      }
  }
\cs_generate_variant:Nn\fnote_mark_gpop_all:nnN  {ooN}
%    \end{macrocode}
% \end{macro}
%
%
%
%
% \subsubsection{Enabling tagging and links for the mark command}
%
%
% \begin{plugdecl}{FEMark}
%
%    To handle the mark in the text, we define a special plug for
%    the socket \socket{tagsupport/fnmark} that receives
%    \cs{@makefntext} as its argument.  At this time \cs{@thefnmark}
%    is already set.
%
%    \begin{macrocode}
\NewSocketPlug{tagsupport/fnmark}{FEMark}
  {
%    \end{macrocode}
%    End an open mc and start the structure.
%    \begin{macrocode}
    \tag_mc_end_push:
    \tag_struct_begin:n { tag=footnotemark }
%    \end{macrocode}
%  The associated note is either auto detected
%  or given by the user.
%    \begin{macrocode}
     \bool_if:NTF \l_@@_autodetect_bool
      {
%    \end{macrocode}
%    For the auto detecting we store the structure number
%    and \cs{@thefnmark} inside a prop and set
%    the target name of the link to the current structure number.
%    TODO: this should be usable for other footnote types
%    which means the name of the prop shouldn't be fix.
%    \begin{macrocode}
        \fnote_mark_gput:oo {\@thefnmark}{\l_fnote_type_tl}
        \tl_set:Ne \l_@@_linktarget_tl {footnote*.\tag_get:n{struct_num}}
      }
%    \end{macrocode}
%  If there is no autodetecting we need some id,
%  currently it is called \cs{l__fnote_currentlabel_tl}.
%  the Ref is set by looking at the label value.
%  We must also add the current structure number to the \ref of the FEnote.
%  Both must be delayed as we don't know if the objects of the FEnote and the mark
%  have already been created.
%    \begin{macrocode}
      {
        \hook_gput_code:nne {tagpdf/finish/before} {tagpdf/footnote}
         {
           \exp_not:N\fnote_gput_refs:ee
            { \tag_get:n{struct_num} }
            { \property_ref:ee{ @@/\l_@@_currentlabel_tl } {fnote/struct} }
         }
%    \end{macrocode}
%    in this case we set the name of the linktarget in the note
%    to the structure number of the text mark.
%    \begin{macrocode}
        \tl_set:Ne \l_@@_linktarget_tl {footnote*.\property_ref:ee {@@/\l_@@_currentlabel_tl} {fnote/struct}}
      }
%    \end{macrocode}
% And now the actual content
%    \begin{macrocode}
     \tag_mc_begin:n{tag=Lbl}
     %
     \bool_if:NTF \l_fnote_link_bool
      {
        \exp_args:No
           \hyper@linkstart
           { \l_fnote_link_type_tl }
           { \l_@@_linktarget_tl }
           #1
           \hyper@linkend
      }
      { #1 }
    \tag_mc_end:
    \tag_struct_end:
    \tag_mc_begin_pop:n{}
   }
%    \end{macrocode}
% At last assign the plug:
%    \begin{macrocode}
\AssignSocketPlug{tagsupport/fnmark}{FEMark}
%    \end{macrocode}
% \end{plugdecl}
%
%
%
%
% \subsubsection{The footnote text}

% We need a public command to append values to the Ref keys
% \begin{macro}{\@@_gput_ref:nn,\fnote_gput_refs:nn,\fnote_gput_refs:ee}
%    \begin{macrocode}
\cs_new_protected:Npn \@@_gput_ref:nn #1 #2 %#1 the structure number receiving the ref #2
  {
    \tag_if_active:T
      {
        \tag_struct_gput:nne {#1}{ref}{\tag_struct_object_ref:e { #2 }}
      }
  }
\cs_new_protected:Npn \fnote_gput_refs:nn #1 #2 % pair of numbers
  {
    \@@_gput_ref:nn {#1}{#2}
    \@@_gput_ref:nn {#2}{#1}
  }
\cs_generate_variant:Nn \fnote_gput_refs:nn {ee}
%    \end{macrocode}
% \end{macro}
%
%    \begin{macrocode}
\tl_new:N \l_@@_dflt_struct_tl
\tl_set:Nn \l_@@_dflt_struct_tl {1}
%    \end{macrocode}
% kernel hooks for taggin
% this sets the structure around the whole text
%
%
% \begin{plugdecl}{FENote}
%    \begin{macrocode}
\NewSocketPlug{tagsupport/fntext/begin}{FENote}
  {
    \tag_mc_end_push:
%    \end{macrocode}
% test if a footnote is allowed, if not move up to the document structure.
%    \begin{macrocode}
    \tag_check_child:nnTF {FENote}{pdf2}
      { 
        \tag_struct_begin:n { tag=footnote }
      }
      {  
        \tag_struct_begin:n { tag=footnote,parent=\l_@@_dflt_struct_tl }
      }  
%    \end{macrocode}
% Store the current structure number for labels.
%    \begin{macrocode}
    \tl_set:Ne \l_@@_currentstruct_tl { \tag_get:n{struct_num} }
%    \end{macrocode}
% We want to move the label structure here. So we provide a container
% It number is |\l__fnote_currentstruct_tl| plus 1.
%    \begin{macrocode}
    \tag_struct_begin:n { tag=footnotelabel }\tag_struct_end:
%    \end{macrocode}
% after we have opened the structure we can use the structure number to
% try to detect the connected marks. As with the marks we assume that sometimes
% no auto detection is done.
%    \begin{macrocode}
    \bool_if:NTF \l_@@_autodetect_bool
      {
%    \end{macrocode}
% find open marks with identical \cs{@thefnmark}
%    \begin{macrocode}
        \fnote_mark_gpop_all:ooN { \@thefnmark }{ \l_fnote_type_tl } \l_@@_currentrefs_seq
%    \end{macrocode}
% Then we store the object numbers of the marks in the /Ref of the FENote structure:
% and the number of the FEnote into the marks structure:
%    \begin{macrocode}
       \seq_map_inline:Nn \l_@@_currentrefs_seq
         {
           \fnote_gput_refs:ee {##1}{ \l_@@_currentstruct_tl }
         }
      }
%    \end{macrocode}
% If no auto detection is done
% \begin{NOTE}{UF}
% TODO: decide what to do here: some label in the optional argument?
% or refer to \cs{footref}
% \end{NOTE}
%    \begin{macrocode}
      {%no auto

      }
  }
%    \end{macrocode}
% This finish the setup of the tagging structure.
% \end{plugdecl}



% Now we process the text. The destinations for the links are set with the label
% so that we can be sure that we are in hmode.
%    \begin{macrocode}
\NewSocketPlug{tagsupport/fntext/end}{FENote}
  {
    \tag_struct_end:
    \tag_mc_begin_pop:n{}
  }
%    \end{macrocode}
% At last assign the plugs:
%    \begin{macrocode}
\AssignSocketPlug{tagsupport/fntext/begin}{FENote}  
\AssignSocketPlug{tagsupport/fntext/end}{FENote}  
%    \end{macrocode}
%
% The kernel socket \socket{tagsupport/fntext/mark} is  responsible for
% tagging the mark in the note. We use it to surround
% the mark with the needed tagging commands.
%
% TODO check if additional kernel configuration points are needed.
% If yes, what about the paragraph start and the paratagging??
%
%
%
%^^A      If tagging is produced this configuration point is also
%^^A      responsible for surrounding the mark with the appropriate tags
%^^A      marking the mark as an Lbl. It does this using the 
%^^A      \socket{tagsupport/fntext/mark} socket.
%
% \begin{plugdecl}{FENoteLbl}
%    This plug creates the label in the note on the bottom.
%    It also adds link targets for the hyperlinking.
%    \begin{macrocode}
\NewSocketPlug{tagsupport/fntext/mark}{FENoteLbl}
  {
    \tag_mc_end_push:
%    \end{macrocode}
%     We create a link target for every related mark. The name is
%    \texttt{footnote*} \meta{structure number of the mark}. We also add a link
%    target for the current structure (for \cs{footref}).
%    \begin{macrocode}
     %\seq_show:N\l_@@_currentrefs_seq
     \seq_map_inline:Nn\l_@@_currentrefs_seq {\MakeLinkTarget*{footnote*.##1}}
     \MakeLinkTarget*{footnote*.\l_@@_currentstruct_tl}
%    \end{macrocode}
%    Now we add the tagging commands. We move the structure of the label to
%    to the container at the begin of the note.
% \begin{NOTE}{UF}
%   Check if the NonStruct is really needed. Perhaps we can simply move the mc.
% \end{NOTE}
%    \begin{macrocode}
     \tag_struct_begin:n { tag=NonStruct,parent=\l_@@_currentstruct_tl +1 }
      \tag_mc_begin:n { tag=Lbl }
       #1
      \tag_mc_end:
     \tag_struct_end:
    \tag_mc_begin_pop:n{}
  }
%    \end{macrocode}
%
%    \begin{macrocode}
\AssignSocketPlug{tagsupport/fntext/mark}{FENoteLbl}
%    \end{macrocode}
% \end{plugdecl}
%
%
%^^A      If tagging is produced this configuration point is also
%^^A      responsible for surrounding the mark with the appropriate tags
%^^A      marking the mark as an MC of type FENote. It does this using
%^^A      the socket \socket{tagsupport/fntext/text}.
%
% \begin{plugdecl}{FENotetext}
%
%    This plug is for the kernel socket \socket{tagsupport/fntext/text} 
%    around the actual note text when doing tagging.
%    Currently it only adds an MC chunk.
%
% TODO Should it set a mc or could it rely on the content?
%    \begin{macrocode}
\NewSocketPlug{tagsupport/fntext/text}{FENotetext}
  {
    \tag_mc_end_push:
    \tag_mc_begin:n{}
    #1
    \tag_mc_end:
    \tag_mc_begin_pop:n{}
  }
%    \end{macrocode}
%
%    \begin{macrocode}
\AssignSocketPlug{tagsupport/fntext/text}{FENotetext}
%    \end{macrocode}
% \end{plugdecl}
%-------------------------------------

%    \begin{macrocode}
\ExplSyntaxOff
%</kernel>
%    \end{macrocode}
%    \begin{macrocode}
%<@@=>
%    \end{macrocode}
%
% \section{Reimplementing the \pkg{footmisc} package}
%
%    \begin{macrocode}
%<*footmisc>
%%
%% Copyright (c) 1995-2011 Robin Fairbairns
%% Copyright (c) 2018-2023 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'.
%%
\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
    \AddToHook{fntext/para}{%
      \hsize\marginparwidth     % correct the default \hsize
      \footnotesep\z@           % don't add a default separation
    }
    \AssignSocketPlug{fntext/process}{side}
%   \AssignSocketPlug{fntext/make}{default}
    \AssignSocketPlug{fntext/begin}{noop}
    \AssignSocketPlug{fntext/end}{noop}
  \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}
%
%    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
  \NewSocketPlug{@makecol/footnotes}{para}{%
     \global\setbox\footins\vbox{\FN@makefootnoteparagraph}%
    }
  \AssignSocketPlug{@makecol/footnotes}{para}
\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 %1
  \ifFN@abovefloats
    \AssignSocketPlug {@makecol/outputbox}{space-footnotes-floats}
  \else
    \AssignSocketPlug {@makecol/outputbox}{floats-footnotes-space}
  \fi
\or %2
  \ifFN@abovefloats
    \AssignSocketPlug {@makecol/outputbox}{footnotes-space-floats}
  \else
    \AssignSocketPlug {@makecol/outputbox}{space-floats-footnotes}
  \fi
\or %3
  \ifFN@abovefloats
    \AssignSocketPlug {@makecol/outputbox}{footnotes-floats}
  \else
    \AssignSocketPlug {@makecol/outputbox}{floats-footnotes}
  \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

% \AssignSocketPlug{fntext/process}{default}
  \AssignSocketPlug{fntext/make}{para}
  \AssignSocketPlug{fntext/begin}{noop}
  \AssignSocketPlug{fntext/end}{para}
  
\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}
%    \end{macrocode}
%    
% We tag the separator as artifact
% \fmi{why is this done with \cs{providecommand}?}
%    \begin{macrocode}
  \ExplSyntaxOn
  \providecommand*{\multfootsep}{\tag_mc_end_push:\tag_mc_begin:n{artifact},\tag_mc_end:\tag_mc_begin_pop:n{}}
  \ExplSyntaxOff
  \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
%
