% \iffalse meta-comment
%
%% File: latex-lab-sec-template.dtx
%
% Copyright (C) 2026 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 latex-lab bundle is developed in the LaTeX2e GitHub.
% Issues may be reported at
%
%    https://github.com/latex3/latex2e/issues
%
\def\ltlabsecIIdate{2026-09-14}
\def\ltlabsecIIversion{0.9o}
%<*driver>
\DocumentMetadata{tagging=on,pdfstandard=ua-2}

\documentclass[kernel]{l3in2edoc}


\usepackage{amstext}
\usepackage{xcolor}

\EnableCrossrefs
\CodelineIndex

\usepackage{todonotes}

\begin{document}
  \DocInput{latex-lab-sec-template.dtx}
\end{document}
%</driver>
%
% \fi
%
%
% \newcommand\key[1]{\texttt{#1}}
% \newcommand\keyvalue[1]{\texttt{#1}}
%
% % \newcommand\insttype[1]{\texttt{#1}}
% % \newcommand\instname[1]{\texttt{#1}}

%
% \NewDocumentCommand\fmi{sO{}m}
%   {\IfBooleanTF{#1}{\todo[inline,#2]{#3}}^^A
%                    {\todo[#2]{#3}}}
%
% \NewDocumentCommand\ufi{sO{}m}
%   {\IfBooleanTF{#1}{\todo[inline,#2]{UFi:#3}}^^A
%                    {\todo[#2]{UFi:#3}}}
%
%
% \title{Reimplementation of \LaTeXe{}'s heading commands using templates}
% \author{\LaTeX{} Project\thanks{Initial implementation by Frank Mittelbach.}}
% \date{v\ltlabsecIIversion\ \ltlabsecIIdate}
%
% \maketitle
%
%
%
% \begin{abstract}
% \end{abstract}
%
%
% \tableofcontents
% \medskip
%
%
% \begin{documentation}
%
%
%
% \section{Introduction}
%    This module reimplements tagging aware heading commands with templates.
%    The new implementation is used automatically if \cs{DocumentMetadata} is used
%    and replaces patches and redefinitions done in the \texttt{latex-lab-sec}.
%    In a later step both modules will be merged.
%
%    Most of the documentation is of interest only for class and package authors
%    who want to setup their own heading commands but the new implementation changes
%    also the user interface. This is documented first.
%
% \section{Changes to the user interface}
%
%     \subsection{New user commands}
%     \DescribeMacro\theheading
%     This command expands inside a heading to the current number.
%
%     \DescribeMacro\partmark
%     This replaces the fix \verb+\markboth{}{}+ or similar in the standard \cs{part}
%    definition.
%
%
%    \subsection{The optional argument}
%    The standard heading commands (re)defined by this module use the standard 2e syntax, e.g.,
% \begin{verbatim}
%   \section[toc]{title}
% \end{verbatim}
%    The star-form \verb+\section*{Title}+
%    stops the numbering, toc, bookmark and running header
%    as it was the way for the last 30-odd years.
%    New is that the optional argument is handled as a key/val list if an equal sign at the outer level
%    is detected, otherwise the argument is taken to be the value of the key \key{shorttitle}
%    and passed to the table of contents, the running headers, the bookmarks and used
%    with \cs{nameref}. Note that this means, that
%    \begin{verbatim}
%    \section*[Title]{Title}
%    \end{verbatim}
%    will create a toc entry and a bookmark!
%
%    The following keys can be used
%    \begin{description}
%    
%      \item[\key{toc}]
%
%        This sets the text for the table of
%        contents. It also forces that the entry is created. So
%      \begin{verbatim}
%      \section*[toc=Introduction]{Introduction to this document}
%      \end{verbatim}
%        will create an unnumbered entry \enquote{Introduction} in the
%        table of contents.  An empty value (i.e., \texttt{toc=}) will
%        suppress the toc entry.
%
%      \item[\key{running}]
%
%        This sets the text for the running header and forces the use
%        of the mark command, so even with a starred section the
%        running header will be updated.  An empty value will suppress
%        the call of the mark commands, so a header from a
%        previous section will prevail.
%
%      \item[\key{bookmark}]
%
%        This sets the text for the bookmarks (the PDF outline) if,
%        e.g., hyperref is loaded. As with the previous keys an empty
%        value suppresses the bookmark entry.
%
%      \item[\key{nameref}]
%
%        This allows to set the text used for a cross reference
%        with \cs{nameref}.
%
%      \item[\key{label}]
%
%        This sets a label, so it is an alternative to using a
%        \cs{label} command.
%
%      \item[\key{subtitle}, \key{quote}]
%
%        These keys will allow to pass a subtitle and a quote to the
%        underlying code, but currently they are not yet used by the
%        implementations of the standard \LaTeX{} heading commands.
%
%      \item[\key{shorttitle}]
%
%        This is the key which is used if the optional argument is not
%        of key/val form. So,
%      \begin{verbatim}
%      \section[short]{long title}
%      \end{verbatim}
%        is the same as
%      \begin{verbatim}
%      \section[shortitle=short]{long title}
%      \end{verbatim}
%        The key sets the toc, running, bookmark and nameref text.  If
%        \key{shorttitle} is used together with any of the individual
%        keys (\key{toc}, \key{running}, \key{bookmark},
%        \key{nameref}) then they overwrite the default value provided
%        by \key{shorttitle}.
%
%      \item[\key{numbered}, \key{unnumbered}]
%
%        This allow to control the numbering without stopping toc,
%        running head or bookmarks as it would happen with the starred
%        version of the heading command.
%
%      \item[template keys]
%
%        Any other key present is assumed to be a key that should be
%        passed to the heading instance to overwrite some of its
%        settings. So, e.g.,
%      \begin{verbatim}
%      \section[placement=top,number-format=\fbox{\theheading}]{Title}
%      \end{verbatim}
%        will force the section to start a new page and put the number
%        into an \cs{fbox}.  For a list of supported keys, check the
%        following parts of the documentation.
%    \end{description}
%
%    \subsection{Class support}
%
%    The module redefines all heading commands of the three standard
%    classes, \pkg{article}, \pkg{report} and \pkg{book}, to use the
%    new implementation.
%
%    Heading commands of other classes that are defined with
%    \cs{@startsection} are supported (with some restrictions) through
%    a compatibility layer described in the next section.
%
%    The heading commands \cs{part} and \cs{chapter} are typically
%    defined with \cs{secdef} and the internal commands \cs{@part} and
%    \cs{@chapter}. The module redefines \cs{secdef} to use the
%    standard instances for these commands---this adds tagging support
%    but \emph{changes the layout} until the class provides its own
%    instances.
%
%    Heading commands in other classes defined with \cs{secdef} will
%    likely error as the code has no real chance to know how to handle
%    such a heading.
%
%    Heading commands which use neither \cs{@startsection} nor
%    \cs{secdef} (e.g, the \cs{chapter} command of \pkg{memoir}, or
%    the heading commands of \pkg{KOMA} classes) are not changed by
%    this module and so will not be tagged correctly unless they add
%    explicit tagging support.
%
%    For the AMS-classes, \texttt{latex-lab-firstaid} contains
%    instances for \cs{part}, \cs{chapter}, \cs{section}, and all
%    other headings used by these classes. The current set of
%    instances is now assumed to reproduce the original
%    layout. Setting them up revealed a number of interesting
%    differences between these classes---not all of them intentional
%    (I think).
%
%
%
%    \subsection{Changing heading commands}\label{sec:startsection}
%
%    It is possible to change heading commands by editing the instance
%    they use.  E.g., in the standard classes one could frame every
%    heading number with
%    \begin{verbatim}
%    \EditInstance{heading}{section}
%      {number-format=\fbox{\theheading}}
%    \end{verbatim}
%    The name of the instance (here \texttt{section}) is the same as
%    the heading command.
%
%    To support other classes which still setup their heading commands
%    with \cs{@startsection} the code has a legacy compatibility
%    layer: the \cs{@startsection} command has been redefined to setup
%    instances on-the-fly at the first use of a heading command. These
%    instances have names using the the first argument of
%    \cs{@startsection} with an attached \texttt{-@startsection}.  As
%    they are created on-the-fly these internal instances can be only
%    edited \emph{after} the first use of the heading command or by
%    declaring (instead of editing) an instance with this name in the
%    preamble. Also as the names of the instances are built from the
%    first argument of \cs{@startsection} it is not possible to define
%    two different heading commands of the same level with
%    \cs{@startsection} as that would require two instances with
%    different names. The next section describes how to lift this
%    restriction by converting such sectioning commands to use the
%    new interfaces.
%
% \subsection[label=sec:convert]
%    {Converting heading commands defined with \cs{@startsection}}
%
%    To convert a heading command defined with \cs{@startsection} to
%    the new interface, suitable instances must be declared. The same
%    needs to happen if one wants to alter the layout of a heading
%    that was defined with \cs{@startsection} in the document
%    preamble.  How this can be done is demonstrated here with the
%    \cs{section} command of the \pkg{ltugboat} class.
%
% \subsubsection{Step 1: Getting the template name and the instance values}
%
%    The sectioning commands use two template \emph{types},
%    \insttype{heading} and \insttype{headformat}.
%    Compile the following document
%
% \begin{verbatim}
% \DocumentMetadata{}
% \documentclass{ltugboat}
%
% \begin{document}
%
% \section{test} % <--- needed so that the instances get defined
% \ShowInstanceValues{heading}{section-@startsection}
% \ShowInstanceValues{headformat}{section-@startsection}
%
% \end{document}
% \end{verbatim}
%
% This will show the instance values in the log-file:
% \begin{verbatim}
% The instance 'section-@startsection' of type 'heading' has values:
% >  level  =>  1
% >  force-unnumbered  =>  false
% >  placement  =>  normal
% >  column-spanning  =>  false
% >  mark-cmd  =>  \sectionmark {##1}
% >  para-indent  =>  false
% >  before-vspace  =>  8.0pt plus 2.0pt minus 2.0pt
% >  penalty  =>  \c_max_int 
% >  after-penalty-vspace  =>  0pt
% >  after-vspace  =>  4.0pt
% >  start-code  =>  
% >  final-code  =>  
% >  prefix  =>  \NoValue 
% >  punct  =>  
% >  heading-decls  =>  \tubsecfmt 
% >  prefix-decls  =>  
% >  number-decls  =>  
% >  title-decls  =>  
% >  subtitle-decls  =>  
% >  quote-decls  =>  
% >  heading-format  =>  ##1
% >  prefix-format  =>  ##1
% >  number-format  =>  ##1
% >  punct-format  =>  ##1
% >  title-format  =>  \use:n {##1} \par
% >  subtitle-format  =>  ##1
% >  quote-format  =>  ##1
% >  number-tag  =>  heading-number
% >  headformat-instance  =>  section-@startsection
% >  contents-extra  =>  
% >  name  =>  section
% >  from template  =>  display.
%
% The instance 'section-@startsection' of type 'headformat' has values:
% >  heading-indent  =>  0pt
% >  order-hang  =>  prefix,separator-a,?,number,punct,separator-b,?
% >  order  =>  title,separator-c,subtitle
% >  separator-a  =>  \nobreakspace 
% >  separator-b  =>  \hspace {1em}
% >  separator-c  =>  \ 
% >  separator-d  =>  
% >  from template  =>  hang.
% \end{verbatim}
%
% \subsubsection{Step 2: Get the default template values}
%
%    The last line in both lists show after the \texttt{from template}
%    the names of the templates of each type. That can be used to get
%    the default values of these templates.  Compile the following
%    document:
% \begin{verbatim}
% \DocumentMetadata{}
% \documentclass{ltugboat}
%
% \begin{document}
% \ShowTemplateDefaults{heading}{display}
% \ShowTemplateDefaults{headformat}{hang}
% \end{document}
% \end{verbatim}
%
% This gives in the log and terminal:
% \begin{verbatim}
% The template 'display' of type 'heading' has default values:
% >  level  =>  0
% >  force-unnumbered  =>  false
% >  placement  =>  normal
% >  column-spanning  =>  false
% >  mark-cmd  =>  
% >  para-indent  =>  false
% >  before-vspace  =>  0pt
% >  penalty  =>  \c_max_int 
% >  after-penalty-vspace  =>  0pt
% >  after-vspace  =>  0pt
% >  start-code  =>  
% >  final-code  =>  
% >  prefix  =>  \NoValue 
% >  punct  =>  
% >  heading-decls  =>  \normalfont 
% >  prefix-decls  =>  
% >  number-decls  =>  
% >  title-decls  =>  
% >  subtitle-decls  =>  
% >  quote-decls  =>  
% >  heading-format  =>  ##1
% >  prefix-format  =>  ##1
% >  number-format  =>  ##1
% >  punct-format  =>  ##1
% >  title-format  =>  ##1\par 
% >  subtitle-format  =>  ##1
% >  quote-format  =>  ##1
% >  number-tag  =>  heading-number
% >  headformat-instance  =>  std
% >  contents-extra  =>   .
% 
% The template 'hang' of type 'headformat' has default values:
% >  heading-indent  =>  0pt
% >  order-hang  =>  prefix,separator-a,?,number,punct,separator-b,?
% >  order  =>  title,separator-c,subtitle
% >  separator-a  =>  \nobreakspace 
% >  separator-b  =>  \hspace {1em}
% >  separator-c  =>  \ 
% >  separator-d  =>  .
% \end{verbatim}
%
% \subsubsection{Step 3: Declare the instances}
%
%    By comparing the instance values with the default values one can
%    see which values should be changed in the instance. The names of
%    the new instances can be freely chosen; best practice is to use
%    the name of the heading command (without a backslash).
%
%    This leads then to these declarations:
% \begin{verbatim}
% \DeclareInstance{heading}{section}{display}
%  {
%    level               = 1,
%    mark-cmd            = \sectionmark{#1},  % remove second hash
%    before-vspace       = 8.0pt plus 2.0pt minus 2.0pt,
%    after-vspace        = 4.0pt,
%    heading-decls       = \tubsecfmt,
%    headformat-instance = section,           % new name
%  }
% \end{verbatim}
%    The value for key \key{title-format} seems to have changed as
%    well but \verb=\use:n {##1} \par= is really only a fancy way to
%    write \verb=##1 \par= so we can keep the default.
%    Note, however, that the \verb=##1= have to replaced by \verb=#1=
%    when you reenter them.
%
%    In case of the \insttype{headformat} instance only default values
%    have been used so all that is necessary is:
% \begin{verbatim}
% \DeclareInstance{headformat}{section}{hang}{}
% \end{verbatim}
%
%    Of course, if you do not want to rely on default values you can (for
%    clarity) specify all keys and their values in these instances.
%
%
% \subsubsection{Step 4 Redefine the \cs{section} command}
%
%    Finally, the heading command should be defined to use the new
%    interface:
% \begin{verbatim}
% \DeclareDocumentCommand \section {s ={shorttitle}o m}
%      { \ParseLaTeXeHeading {section} {#1} {#2} {#3} }
% \end{verbatim}
%    What \cs{ParseLaTeXeHeading} does is explained in the next
%    section.
%
%
% \section{Setting up \LaTeXe{} heading commands in classes}
%
%    Heading commands are managed by defining an instance of a
%    \insttype{heading} template which is then used in
%    \cs{ParseLaTeXeHeading}, e.g.,
% \begin{verbatim}
%   \DeclareDocumentCommand \part {s ={shorttitle}o m}
%       { \ParseLaTeXeHeading {part} {#1} {#2} {#3} }
% \end{verbatim}
%    The name of the \insttype{heading} instance is given in the first
%    argument of \cs{ParseLaTeXeHeading} and it is recommended that
%    classes use the same name as the heading command, to make it
%    easier for users to identify the instance to edit if they want to
%    adjust the layout of the heading. Examples of instances that mimic the behavior
%    of the heading commands in the standard classes can be found
%    below. Section~\ref{sec:convert} shows how to get instances from
%    commands previously defined with \cs{@startsection}.
%
%    Legacy setup using \cs{@startsection} remains supported albeit
%    not that performant and with some restrictions for the users, see
%    section \ref{sec:startsection} above and in the documentation
%    below.
%
%    In contrast, \cs{secdef} is only rudimentarily supported. It
%    delegates the layout to two commands which can contain arbitrary
%    code (usually hardwired) so that there is no realistic chance to
%    automatically take this apart and figure out what values should
%    be used for what template parameters. We therefore redefine
%    \cs{secdef} and map the standard commands \cs{part} and
%    \cs{chapter} to the standard instance and error if other uses are
%    detected.  Classes using \cs{secdef} should setup suitable
%    instances that mimic their current layout, an example can be
%    found for the ams-classes in \texttt{latex-lab-firstaid.dtx}.
%
%
% \section{Open points}
%
% \begin{itemize}
% \item
%
%    There is no good interface yet to change e.g. the font family of
%    all heading commands in one go.
%    
% \item
%
%    Support for \pkg{titlesec}, see section \ref{sec:titlesec}.
%    
% \end{itemize}
%
%
%
%
%
% \section{Template types and templates for headings}
%
%    The template(s) for headings expect(s) a large number of
%    positional arguments containing document user data. The
%    document-level command, e.g., \cs{section}, may not offer all of
%    them directly, but may do so via a key value interface or not at
%    all. If no interface is provided then the template is passed
%    \cs{NoNalue}. If it is offered via a key value interface, the
%    template receives whatever is set by the user (and \cs{NoNalue}
%    otherwise).
%
%    In my initial implementation I had only the main data as
%    positional arguments, but I came to the conclusion that this
%    scheme here is better going forward.
%
% \subsection{Template types}
%
%    The template type \insttype{heading} has 10 data arguments, which
%    is more than can be specified as positional arguments. For that
%    reason argument \#9 holds 2 brace groups. The alternative would
%    be to specify such arguments as keys, but for a number of reasons
%    I think the approach to put seldom used data arguments all
%    in the last positional argument is actually better (besides being
%    faster).
%
% \begin{TemplateInterfaceDescription}{heading}
%    \TemplateArgument{1}{key/value list to alter the default heading parameters}
%    \TemplateArgument{2}{unnumbered heading?}
%    \TemplateArgument{3}{main title of the heading}
%    \TemplateArgument{4}{toc title}
%    \TemplateArgument{5}{running title}
%    \TemplateArgument{6}{bookmark title}
%    \TemplateArgument{7}{nameref text}
%    \TemplateArgument{8}{label for the heading in the form \cs{label}\{\meta{string}\}}
%    \TemplateArgument{9}{\{ sub title \} \{ quotation \}}
%    \TemplateSemantics
%    
%    Handles the layout and processing aspects of a heading. This
%    includes doing all the work necessary for tagging.
%
%    Whether or not the heading is numbered is governed through a
%    boolean, expecting the result of an \texttt{s} specification of
%    \cs{NewDocumentCommand} or equivalent, i.e., expects
%    \cs{BooleanTrue} or \cs{BooleanFalse}.
%
%    If the title data is also used for bookmarks, toc, running
%    header, and cross references then it has to be given several times which
%    can be arranged for by the parsing interface command that calls
%    the template instance.
%
%    If the bookmark, toc, or running argument is set to
%    \enquote{empty} then the bookmark, toc or running header should
%    be suppressed by the template. This enables the user on document
%    level to explicitly specify, for example, \texttt{[bookmark=]} to
%    suppress the bookmark.
%
%    The \texttt{nameref} argument is not expected to be empty. Its value
%    should always be used as given if named references are to be
%    generated.
%
%    The label argument either holds a \cs{label} command as provided
%    by the user (or several, see implementation of
%    \cs{ParseLaTeXeHeading}) or it is empty. I.e., it can be directly
%    executed by a template at the right point where the reference
%    counter (if any) has been set up without the need to check its
%    content.
%
%    Argument \#9 holds further user data (in brace groups) which are
%    seldom implemented, but if they are the data is available in a
%    positional argument, which then needs to be taken apart using
%    \cs{@firstoftwo} (for subtitle) or \cs{@secondoftwo} (for a
%    quotation). If no data is provided then \cs{NoValue} is used to
%    indicate that.
%
% \end{TemplateInterfaceDescription}
%
%
% \changes{0.9g}{2026-05-24}{Add 'fixed prefix text' as a further
%    argument to the headformat template type}
%
% \begin{TemplateInterfaceDescription}{headformat}
%    \TemplateArgument{1}{key/value list to alter the default headformat parameters}
%    \TemplateArgument{2}{fixed prefix text}
%    \TemplateArgument{3}{formatted heading number}
%    \TemplateArgument{4}{main title of the heading}
%    \TemplateArgument{5}{subtitle}
%    \TemplateArgument{6}{quotation}
%    \TemplateSemantics
%
%    Handles the layout of just the heading label (prefix and number),
%    main title, subtitle, and quotation but not the spatial relation
%    to previous and following text.
%
%    Whether or not the heading is numbered is governed through a
%    boolean, e.g., result of an \texttt{s} specification in
%    \cs{NewDocumentCommand} or equivalent.
%
%    If there is no prefix, number, subtitle or quotation then this is indicated
%    with \cs{NoValue}.
%
%    The templates are currently
%    implemented to mimic \LaTeXe{} behavior so if a
%    \insttype{heading} template should not number a heading it calls
%    a \insttype{headformat} template with both prefix and number set
%    to \cs{NoValue}.
%
%    The \meta{subtitle} and \meta{quotation} are always
%    ignored by the currently defined templates but that will probably
%    change soon, either by extending them or by providing additional
%    ones that support these mandatory argument.
%
% \end{TemplateInterfaceDescription}
%
%
%
% \subsection{Templates}
%
%
% \subsubsection{Templates of type \insttype{heading}}
%
%
%    There are quite a number of keys that are expected to be
%    recognized by all heading templates (though they may choose not
%    to make use of them). These are listed below instead of being
%    repeated on the actual templates.
%
%    All other keys are either attached to the \insttype{heading} or
%    to the \insttype{headformat} templates. Those that typically vary
%    from heading instance to the next (e.g., \key{heading-decls}) are
%    all declared in the \insttype{heading} templates even if they are
%    actually only used within \insttype{headformat} templates. In
%    other words, \insttype{headformat} templates have a number of
%    implicit variables that they expect to be set.\footnote{Maybe
%    questionable}
%
% \changes{0.9h}{2026-07-04}{Support a \texttt{force-unnumbered} key
%    (tagging/1473)}
%
% \begin{TemplateDescription}{heading}{\meta{all}}
%
% \changes{0.9h}{2026-06-21}{Support \texttt{column-spanning} key (tagging/1436)}
%
%  \TemplateKey{name}{tokenlist}
%              {Referenceable name of the heading instance. String that
%               is acceptable in csnames for use in building counter
%               names, etc.}{}
%  \TemplateKey{parent-name}{tokenlist}
%              {Name of the next higher heading instance. If not
%               given, then the internal heading level of the heading
%               instance is set to \texttt{0} --- not yet
%               implemented/may vanish}{}
%  \TemplateKey{reset-counter}{tokenlist}
%              {Name of the heading instance that should reset the
%               numbering of this heading level (if any) --- not yet
%               implemented/may vanish}{}
%  \TemplateKey{level}{integer}
%              {Sets the internal heading-level rather than deducing
%               it from \key{parent-name}. Can be used to specify the
%               top-level heading if not \texttt{0}, or all headings
%               in legacy implementations, e.g., through \cs{@startsection}}{}
%
%  \TemplateKey{force-unnumbered}{boolean}
%              {This heading is never numbered, even if explicitly requested
%               in the optional argument to the heading. If
%               \texttt{false} then numbering is determined in the normal
%               way (through \texttt{secnumdepth}, \texttt{*}, or a
%               setting in the optional argument to the heading).}{false}
%
%  \TemplateKey{placement}{choice}
%              {Set the heading placement, i.e., the behavior of the
%               heading with respect to page breaks. Allowed values
%               are
%               \texttt{page} (heading forms a page if its own),
%               \texttt{top} (heading starts a new page),
%               \texttt{normal} (heading can appear anywhere on the
%               page),
%               \texttt{ragged} (like \texttt{normal} but if a
%               page break is taken before the heading then the
%               previous page is set ragged and not stretched).
%               Further possibilities might be
%               \texttt{rectopage} and \texttt{rectotop} if we
%               implement that.}{\texttt{normal}}
%
%  \TemplateKey{start-code}{tokenlist}
%              {Default value is set by the \key{placement}
%    key. Executed before the heading starts, so can issue, for
%    example, a \cs{clearpage}}
%              {}
%
%  \TemplateKey{final-code}{tokenlist}
%              {Default value is set by the \key{placement}
%    key. Executed after the heading is typeset. Can set up code for
%    putting the heading on a page by its own, or arrange for
%    paragraph handling of a following paragraph, etc.}
%              {}
%
%
%  \TemplateKey{column-spanning}{boolean}
%              {If true produces a heading that spans columns in
%               \texttt{twocolumn} typesetting.  Requires
%               \key{placement} \texttt{=} \keyvalue{top} (and adjusts
%               if necessary) and only has an effect
%               if the columns are produced via the \texttt{twocolumn}
%               class option and not when using \env{multicol}. This
%               might get extended when we refactor the OR handling.}{false}
%
%  \TemplateKey{prefix}{tokenlist}
%              {A fixed string, such as \enquote{Chapter}, that can be
%               used together with the number (if any) to form a
%               \enquote{heading label}. Usage and placement is up to
%               the template, so it could be placed after the number
%               by the template (in which case it isn't really a
%               prefix).} {\cs{NoValue}}
%
%  \TemplateKey{punct}{tokenlist}
%              {A fixed string to be added to the end of the heading
%               number, i.e., it shows up in on the heading but not
%               in cross-references.} {\meta{empty}}
%
%  \TemplateKey{mark-cmd}{function(1)}
%              {Function that receives the \meta{running} argument and
%               creates a suitable mark insertion}
%              {\texttt\textbackslash\meta{name}\texttt{mark}}
%
%    \TemplateSemantics
%
%    The above keys should be implemented by all heading templates.
%
%    At the moment I have retained the \LaTeXe{} interfaces for marks,
%    e.g., one has to set up \cs{chaptermark}, \cs{sectionmark},
%    etc.\ but I'm not sure this should stay (even though it is
%    certainly simpler from a compatibility perspective).
%
%    All templates should set up \cs{theheading} to correspond to
%    \cs{the\meta{name}}.
% \end{TemplateDescription}
%
%
% \begin{TemplateDescription}{heading}{display}
%
%  \TemplateKey{para-indent}{boolean}
%              {Should the paragraph after the heading be indented?}
%              {false}
%
%  \TemplateKey{before-vspace}{skip}
%              {Vertical space before the heading if there is no page
%               or column break. If there is one it vanishes.
%               In particular this means it will not be used in the
%              heading \texttt{placement}s \texttt{page} or \texttt{top}}
%              {0pt}
%
%  \TemplateKey{penalty}{integer}
%              {Penalty to break before the heading. The default
%    (\TeX's largest integer) indicates that no penalty was set in
%    which case \cs{@secpenalty} is used (to support the \LaTeXe{} interface).}
%              {\number\maxdimen}
%
%  \TemplateKey{after-penalty-vspace}{skip}
%              {Vertical space before the heading but after the
%    penalty for the heading. If the penalty results in a page or
%    column break, this space remains at the top of the page}
%              {0pt}
%
%  \TemplateKey{after-vspace}{skip}
%              {Vertical space after the heading}
%              {0pt}
%
%  \TemplateKey{heading-decls}{tokenlist}
%              {Declarations (such as font or color settings) applied
%               to all heading elements, i.e., number, title,
%               subtitle, and quotation, if present.
%               Note that color commands (unless \pkg{luacolor} is used)
%               introduce a break point before the heading and therefore one should either
%               surround color commands with \cs{SaveLastSkip} and \cs{RestoreLastSkip} or
%               to use the keys \texttt{prefix-decls}, \texttt{number-decls},
%               \texttt{title-decls}, etc.\ instead.}
%              {\cs{normalfont}}
%
%  \TemplateKey{prefix-decls}{tokenlist}
%              {Declarations (such as font or color settings) applied
%               to the heading prefix, overwriting the setting
%               of \key{heading-decls}.}
%              {\meta{empty}}
%
%  \TemplateKey{number-decls}{tokenlist}
%              {Declarations (such as font or color settings) applied
%               to the heading  number, overwriting the setting
%               of \key{heading-decls}.}
%              {\meta{empty}}
%
%  \TemplateKey{title-decls}{tokenlist}
%              {Declarations (such as font or color settings) applied
%               to the heading  title, overwriting the setting
%               of \key{heading-decls}.}
%              {\meta{empty}}
%
%  \TemplateKey{subtitle-decls}{tokenlist}
%              {Declarations (such as font or color settings) applied
%               to the heading  subtitle, overwriting the setting
%               of \key{heading-decls}.}
%              {\meta{empty}}
%
%  \TemplateKey{quote-decls}{tokenlist}
%              {Declarations (such as font or color settings) applied
%               to the heading  quote, overwriting the setting
%               of \key{heading-decls}.}
%              {\meta{empty}}
%
%  \TemplateKey{heading-format}{function(1)}
%              {Code that receives the whole heading as an argument.}
%              {\#1}
%  \TemplateKey{prefix-format}{function(1)}
%              {Code that receives the prefix string as an argument.}
%              {\#1}
%  \TemplateKey{number-format}{function(1)}
%              {Code that receives the number string as an argument.}
%              {\#1}
%  \TemplateKey{punct-format}{function(1)}
%              {Code that receives the punctuation string as an argument.}
%              {\#1}
%  \TemplateKey{title-format}{function(1)}
%              {Code that receives the title string as an argument.
%               By default it ends in \cs{par} so that \cs{baselineskip}
%               changes in the settings (e.g., in \key{title-decls})
%               are applied}
%              {\#1 \cs{par}}
%  \TemplateKey{subtitle-format}{function(1)}
%              {Code that receives the subtitle string as an argument.}
%              {\#1}
%  \TemplateKey{quote-format}{function(1)}
%              {Code that receives the quote string as an argument.}
%              {\#1}
%  \TemplateKey{number-tag}{tokenlist}
%              {Name of the tag to put around the number (empty means
%               no tag).}
%              {heading-number}
%
%  \TemplateKey{headformat-instance}{instance}
%              {Template instances of type \insttype{headformat}}
%              {std}
%  \TemplateKey{contents-extra}{tokenlist}
%              {Code containing \cs{addcontents} calls to write to
%               files like \texttt{.lot} or \texttt{.lot}}
%              {\meta{empty}}
%
%
%    \TemplateSemantics
%
%    The key \key{heading-decls} determines the overall
%    \cs{baselineskip} used in the heading. Font changes in individual
%    declarations do not have that effect, because they are all
%    executed in groups and if if all elements are within the same
%    paragraph then the final \cs{par} after the heading comes too
%    late. If you want that the font setting for a specific key, e.g.,
%    \key{title}, depends on the font setting in \key{title-decls} you
%    have to ensure that a \cs{par} happens within \key{title-format}
%    key, e.g., \key{title-format}\texttt{=\#1\cs{par}} (which is what
%    happens in the default value of \key{title-format}).
% \end{TemplateDescription}
%
%
%
%
% \begin{TemplateDescription}{heading}{runin}
%
%  \TemplateKey{before-vspace}{skip}
%              {Vertical space before the heading if there is no page
%               or column break. If there is one it vanishes.}
%              {0pt}
%
%  \TemplateKey{penalty}{integer}
%              {Penalty to break before the heading. The default
%    (\TeX's largest integer) indicates that no penalty was set in
%    which case \cs{@secpenalty} is used.}
%              {\number\maxdimen}
%
%  \TemplateKey{after-penalty-vspace}{skip}
%              {Vertical space before the heading but after the
%    penalty for the heading. If the penalty results in a page or
%    column break, this space remains at the top of the page. It is
%    also applied if the heading is a \texttt{page} or \texttt{top} heading.}
%              {0pt}
%
%  \TemplateKey{after-hspace}{skip}
%              {Horizontal space after the heading.}{0pt}
%
%  \TemplateKey{heading-decls}{tokenlist}
%              {Declarations (such as font or color settings) applied
%               to all heading elements, i.e., number, title,
%               subtitle, and quotation, if present.
%               Note that color commands (unless \pkg{luacolor} is used)
%               introduce a break point before the heading and therefore one should either
%               surround color commands with \cs{SaveLastSkip} and \cs{RestoreLastSkip} or
%               to use the keys \texttt{prefix-decls}, \texttt{number-decls},
%               \texttt{title-decls}, etc.\ instead.}
%              {\cs{normalfont}}
%
%  \TemplateKey{prefix-decls}{tokenlist}
%              {Declarations (such as font or color settings) applied
%               to the heading prefix, overwriting the setting
%               of \key{heading-decls}.}
%              {\meta{empty}}
%
%  \TemplateKey{number-decls}{tokenlist}
%              {Declarations (such as font or color settings) applied
%               to the heading  number, overwriting the setting
%               of \key{heading-decls}.}
%              {\meta{empty}}
%
%  \TemplateKey{title-decls}{tokenlist}
%              {Declarations (such as font or color settings) applied
%               to the heading  title, overwriting the setting
%               of \key{heading-decls}.}
%              {\meta{empty}}
%
%  \TemplateKey{subtitle-decls}{tokenlist}
%              {Declarations (such as font or color settings) applied
%               to the heading  subtitle, overwriting the setting
%               of \key{heading-decls}.}
%              {\meta{empty}}
%
%  \TemplateKey{quote-decls}{tokenlist}
%              {Declarations (such as font or color settings) applied
%               to the heading  quote, overwriting the setting
%               of \key{heading-decls}.}
%              {\meta{empty}}
%
%  \TemplateKey{heading-format}{function(1)}
%              {Code that receives the whole heading as an argument.}
%              {\#1}
%  \TemplateKey{prefix-format}{function(1)}
%              {Code that receives the prefix string as an argument.}
%              {\#1}
%  \TemplateKey{number-format}{function(1)}
%              {Code that receives the number string as an argument.}
%              {\#1}
%  \TemplateKey{punct-format}{function(1)}
%              {Code that receives the punctuation string as an argument.}
%              {\#1}
%  \TemplateKey{title-format}{function(1)}
%              {Code that receives the title string as an argument.
%               Since this is a runin heading we should remain in
%               horizontal mode so the default does not include a
%               \cs{par}.}
%              {\#1}
%  \TemplateKey{subtitle-format}{function(1)}
%              {Code that receives the subtitle string as an argument.}
%              {\#1}
%  \TemplateKey{quote-format}{function(1)}
%              {Code that receives the quote string as an argument.}
%              {\#1}
%  \TemplateKey{number-tag}{tokenlist}
%              {Name of the tag to put around the number (empty means
%               no tag).}
%              {heading-number}
%
%  \TemplateKey{headformat-instance}{instance}
%              {Template instances of type \insttype{headformat}}
%              {std}
%  \TemplateKey{contents-extra}{tokenlist}
%              {Code containing \cs{addcontents} calls to write to
%               files like \texttt{.lot} or \texttt{.lot}}
%              {\meta{empty}}
%
%    \TemplateSemantics
%
%    The runin template is fairly similar to the display one. Main
%    differences are due to the fact that we stay in horizontal mode
%    at the end of the heading so that we have \key{after-hspace}
%    instead of \key{after-vspace} and we do not have a \cs{par}
%    inside \key{title-format}.
%
% \end{TemplateDescription}
%
%
%
%
% \subsubsection{Templates of type \insttype{headformat}}
%
%    The \insttype{headformat} templates deal with positioning prefix,
%    number, punct, title, subtitle and quote. If the heading is unnumbered
%    then prefix, number and punct are expected to be \cs{NoValue} (this
%    is arranged in the calling \insttype{heading} template).
%
%    Tagging is taken care of in the calling template as well, all the
%    the \insttype{headformat} templates do is  opening and closing
%    MCs as necessary.
%
%    The templates make use of the generic order key mechanism.
%
%
% \begin{TemplateDescription}{headformat}{display}
%
%  \TemplateKey{heading-indent}{dimen}
%              {Horizontal space before the heading (shifting it to
%               the right in a LR typesetting context)}
%              {0pt}
%
%  \TemplateKey{order}{commalist}
%              {Order of elements that form the heading. Some of the
%               separators are dropped if the previous element is
%               \cs{NoValue}, e.g., \key{separator-a} and
%               \key{separator-b}.
%               The key{quote} key is currently ignored.}
%              {prefix, separator-a, ?, number, punct, separator-b, ?,
%               title, separator-c, subtitle}
%
%  \TemplateKey{separator-a}{tokenlist}
%              {By default the separation between \key{prefix} and
%               \key{number}.}
%              {\cs{nobreakspace}}
%
%  \TemplateKey{separator-b}{tokenlist}
%              {By default the separation between \key{punct} and
%               \key{title}. The default starts a new line with extra
%               vertical space.}
%              {\cs{par} \cs{nobreak} \cs{vspace}\{20pt\}}
%
%  \TemplateKey{separator-c}{tokenlist}
%              {By default the separation between \key{title} and
%               \key{subtitle}.}
%              {\cs{ }}
%
%  \TemplateKey{separator-d}{tokenlist}
%              {By default not used.}
%              {\meta{empty}}
%
%
%    \TemplateSemantics
%
%    Implements a heading layout where number and title are vertically
%    separated. It is what \LaTeX{} always used by default for
%    \cs{chapter} and \cs{part}.
%
%    This template can be called from the \insttype{heading}
%    \instname{display} template. It is not suitable for use with the
%    \instname{runin} template.
%
% \end{TemplateDescription}
%
%
% \begin{TemplateDescription}{headformat}{hang}
%
%  \TemplateKey{heading-indent}{dimen}
%              {Horizontal space before the heading (shifting it to
%               the right in a LR typesetting context)}
%              {0pt}
%
%  \TemplateKey{order-hang}{commalist}
%              {Order of elements of the heading that are used to form
%               the hanging indentation (and are placed in that
%               space).} 
%              {prefix, separator-a, ?, number, punct, separator-b, ?}
%
%  \TemplateKey{order}{commalist}
%              {Order of remaining headings elements.
%               The key{quote} key is currently not used.}
%              {title, separator-c, subtitle}
%
%  \TemplateKey{separator-a}{tokenlist}
%              {By default the separation between \key{prefix} and
%               \key{number}.}
%              {\cs{nobreakspace}}
%
%  \TemplateKey{separator-b}{tokenlist}
%              {By default the horizontal separation after \key{punct} still
%               being counted in the hanging indentation}
%              {\cs{hspace}\{1em\}}
%
%  \TemplateKey{separator-c}{tokenlist}
%              {By default the separation between \key{title} and
%               \key{subtitle}.}
%              {\cs{ }}
%
%  \TemplateKey{separator-d}{tokenlist}
%              {By default not used.}
%              {\meta{empty}}
%
%
%    \TemplateSemantics
%
%    Implements a heading layout where number and title start on the
%    same line and the title is hanging off from  that if the title
%    has more than one line. It is what \LaTeX{} always used by
%    default for \cs{section}, \cs{subsection}, and
%    \cs{subsubsection}.
%
%    This template can be called from the \insttype{heading}
%    \instname{display} template. It is not suitable for use with the
%    \instname{runin} template.
%
% \end{TemplateDescription}
%
%
% \begin{TemplateDescription}{headformat}{runin}
%
%  \TemplateKey{heading-indent}{dimen}
%              {Horizontal space before the heading (shifting it to
%               the right in a LR typesetting context)}
%              {0pt}
%
%  \TemplateKey{order}{commalist}
%              {Order of elements that form the heading. Some of the
%               separators are dropped if the previous element is
%               \cs{NoValue}, e.g., \key{separator-a} and
%               \key{separator-b}.
%               The key{quote} key is currently ignored.}
%              {prefix, separator-a, ?, number, punct, separator-b, ?,
%               title, separator-c, subtitle}
%
%  \TemplateKey{separator-a}{tokenlist}
%              {By default the separation between \key{prefix} and
%               \key{number}.}
%              {\cs{nobreakspace}}
%
%  \TemplateKey{separator-b}{tokenlist}
%              {By default the separation between \key{punct} and
%               \key{title}. The default starts a new line with extra
%               vertical space.}
%              {\cs{hspace}\{1em\}}
%
%  \TemplateKey{separator-c}{tokenlist}
%              {By default the separation between \key{title} and
%               \key{subtitle}.}
%              {\cs{ }}
%
%  \TemplateKey{separator-d}{tokenlist}
%              {By default not used.}
%              {\meta{empty}}
%
%
%    \TemplateSemantics
%
%    Implements a heading layout where text after the heading
%    continues on the same line as the heading. It is what \LaTeX{}
%    always used by default for 
%    \cs{paragraph} and \cs{subparagraph}.
%
%    This template is intended to be used  with the \insttype{heading}
%    \instname{runin} template (but could perhaps also be used with
%    \instname{display}).
% \end{TemplateDescription}
%
%
%
% \subsection{Default instances}
%
%    These instances are set up to mimic the design of the standard
%    \LaTeX{} classes. For other classes they could be adjusted by
%    changing the instance values and/or by basing them on a different
%    template.
%
% \subsubsection{Instances of \insttype{heading} templates}
%
% \begin{description}
%
% \item[\texttt{part} (instance of \texttt{display} template)] Used for the
%    \cs{part} command.
%
% \item[\texttt{chapter} (instance of \texttt{display} template)] Used for the
%    \cs{chapter} command.
%
% \item[\texttt{section} (instance of \texttt{display} template)] Used for the
%    \cs{section} command.
%
% \item[\texttt{subsection} (instance of \texttt{display} template)] Used for
%    the \cs{subsection} command.
%
% \item[\texttt{subsubsection} (instance of \texttt{display} template)] Used for
%    the \cs{subsubsection} command.
%
% \item[\texttt{paragraph} (instance of \texttt{runin} template)] Used for the
%    \cs{paragraph} command.
%
% \item[\texttt{subparagraph} (instance of \texttt{runin} template)] Used for
%    the \cs{subparagraph} command.
%
% \end{description}
%
%
% \subsubsection{Instances of \insttype{headformat} templates}
%
% \begin{description}
%
% \item[\texttt{part} (instance of \texttt{display} template)] Used in
%    \insttype{heading} instance for \cs{part}.
%
% \item[\texttt{chapter} (instance of \texttt{display} template)] Used in
%    \insttype{heading} instance for \cs{chapter}. By default identical
%    to the one used for \cs{part}.
%
% \item[\texttt{std} (instance of \insttype{hang} template)] Used as
%    default in the heading template if nothing else is specified.
%
% \item[\texttt{section} (instance of \insttype{hang} template)] Used in
%    \insttype{heading} instance for \cs{section}. By default identical
%    to the \texttt{std} instance.
%
% \item[\texttt{subsection} (instance of \insttype{hang} template)] Used in
%    \insttype{heading} instance for \cs{subsection}. By default identical
%    to the \texttt{std} instance.
%
% \item[\texttt{subsubsection} (instance of \insttype{hang} template)] Used in
%    \insttype{heading} instance for \cs{subsubsection}. By default identical
%    to the \texttt{std} instance.
%
% \item[\texttt{paragraph} (instance of \texttt{runin} template)] Used in
%    \insttype{heading} instance for \cs{paragraph}.
%
% \item[\texttt{subparagraph} (instance of \texttt{runin} template)] Used in
%    \insttype{heading} instance for \cs{subparagraph}.
%
% \end{description}
%
%
%
%
% \subsection{Use of templates from the 2026-06-01 release of \LaTeX{}}
%
%    In the first heading implementation using templates we provided a
%    number of somewhat restricted templates that covered the default
%    layouts of standard \LaTeX{} classes but not much beyond this.
%
%    For the 2026-11-01 release we have replaced them with more
%    general templates described above that use  the general order key
%    mechanism. As a side effect the new templates have some
%    additional keys and some keys used in the templates of first
%    implementation got dropped.
%
%    For the next couple of releases we will keep the original
%    templates available (only renamed to
%    \meta{name}\texttt{-v1}).  Eventually, we want to drop the
%    \texttt{-v1} versions but for the next couple of releases we
%    provide them alongside the new more flexible templates, so that
%    there is no need to transitioning to the new 
%    templates in a rush.
%
%    If you have defined instances using the first template version
%    then you can (for now) continue to use them simply by changing
%    the template names in your instance declarations from \meta{name}
%    to \meta{name}\texttt{-v1}, e.g., you have to change from
%\begin{verbatim}
%  \DeclareInstance{heading}   {chapter}{display} { ... }
%  \DeclareInstance{headformat}{chapter}{display} { ... }
%
%  \DeclareInstance{heading}   {section}{hang} { ... }
%  \DeclareInstance{headformat}{section}{hang} { ... }
%  ...
%\end{verbatim}
%    to 
%\begin{verbatim}
%  \DeclareInstance{heading}   {chapter}{display-v1} { ... }
%  \DeclareInstance{headformat}{chapter}{display-v1} { ... }
%
%  \DeclareInstance{heading}   {section}{hang-v1} { ... }
%  \DeclareInstance{headformat}{section}{hang-v1} { ... }
%  ...
%\end{verbatim}
%    No other changes are necessary for now. However, going forward
%    you should switch to the extended templates because the
%    \texttt{-v1} templates will eventually be dropped. 
%
%    Switching mainly means stopping the use of the keys
%    \key{prefix-number-sep} and \key{number-title-sep} because they
%    have been replaced with the more general \key{separator-a},
%    \key{separator-b}, \ldots\  keys.\footnote{There are some more
%    changes in the keys, but it is less likely that they have been
%    used. If necessary, compare the documentation for the old and the
%    new templates to find out what else needs adjusting.}
%
%    The template documentation for these deprecated templates is
%    available as part of Appendix~\ref{appendix:a} in case you need
%    to consult it in order to update your template instance
%    declarations to use the new templates. Please do not use these
%    templates for new work, as they will eventually get removed.
%
%
%
%
% \section{Support for legacy classes and packages}
%
% \subsection{Support classes based on legacy \LaTeXe{} interfaces}
%
% \DescribeMacro\@startsection
%    The \cs{@startsection} command has the following syntax:
% \begin{verbatim}
%  \@startsection{name}{level}{indent}{beforeskip}{afterskip}{style}
% \end{verbatim}
%    with a special logic that the sign of \meta{beforeskip} determines
%    display or runin heading and that of \meta{afterskip} whether or
%    not the next paragraph is indented.
%
%    All arguments can be cleanly mapped to \insttype{heading} and
%    \insttype{headformat} templates. Thus, if encountered suitable
%    instances are automatically declared unless they already exist.
%
%
%
% \DescribeMacro\secdef
%    In contrast, \cs{secdef} only does the parsing and delegates the
%    layout to two commands which can contain arbitrary code (usually
%    hardwired) so that there is no realistic chance to take this
%    apart and figure out what values should be used for what template
%    parameters.
%
%    We therefore do not attempt to model this, but instead just use
%    the standard layout from \LaTeX's standard classes for
%    \cs{chapter} and \cs{part} if we can identify that the \cs{secdef}
%    is used to define one of these.
%
%    Maybe we can try at some stage to get some static analysis tool
%    going.
%
%
% \subsection[label=sec:titlesec]{Support for the \pkg{titlesec} package interfaces}
%  TODO
%
% \noindent
% \DescribeMacro\titleformat
% The \cs{titleformat} declaration has the following syntax:
% \begin{verbatim}
%  \titleformat{cmd}[shape]{format}{label}{sep}{before-code}[after-code]
% \end{verbatim}
%
% \noindent
% \DescribeMacro\titlespacing
% The \cs{titlespacing} declaration has the following syntax:
% \begin{verbatim}
%  \titlespacing*{cmd}{left-sep}{before-vspace}{after-vspace}[right-sep]
% \end{verbatim}
%
% \section{Support for links}
%
% All heading commands (numbered and unnumbered) should contain support for
% active links directly. hyperref does not patch the new heading commands!
% As \cs{refstepcounter} is not used there is no automatic target.
%
% This means that all definitions should contain at an appropriate place
% a \cs{MakeLinkTarget} command. Typically numbered heading commands will use
% \verb+\MakeLinkTarget{+\meta{counter}\verb+}+ while unnumbered heading commands
% use \verb+\MakeLinkTarget[+\meta{counter}\verb+]{}+.
%
% The definition must take care that the target is not separated from the heading
% by a page break. It also should not affect spacing.
% The target should be placed so that a jump to the target gives
% a satisfying user experience, in most cases the best places is at the left margin
% a bit above the heading.
%
% The targets create also structure destinations that
% are used by the tagging code. It is therefore important that the targets
% are in the right place in relation to the tagging commands.
%
% \section{Bookmarks}
%
% Bookmarks are created by the \cs{addcontentsline} command, more precisely in the
% new latex-lab toc code a hook with arguments is inserted at the begin of the command
% which contains the command that creates the bookmark. The arguments of \cs{addcontentsline}
% and so also of the hook are the type of the toc,
% the level name and the (short-)title of the heading. To pass a differing
% bookmark text the code uses \cs{texorpdfstring} in the \cs{addcontentsline}.
% \ufi{check if this is still the implementation ...}
% \section{Tagging support}
%
% Tagging of heading commands has to do two tasks:
%  \begin{itemize}
%  \item surround the whole section (heading and text) with a \texttt{Sect} structure
%  \item tag the heading with an Hn structure.
%  \end{itemize}
% This is done with tagging sockets which are documented in the code and in \texttt{latex-lab-sec}.
%
% \section{Debugging support}
%
% \begin{function}{\DebugHeadingsOn,\DebugHeadingsOff, \head_debug_on:, \head_debug_off:}
%
% These commands enable/disable debugging messages.
%
% \end{function}
%
%
%
% \end{documentation}
%
% \StopEventually{\setlength\IndexMin{200pt}  \PrintIndex  }
%
%
%
% \begin{implementation}
%
% \section{The Implementation}
%
%
%    \begin{macrocode}
%<*package>
%<@@=head>
%    \end{macrocode}
%
%
%    \begin{macrocode}
\ProvidesExplPackage
 {latex-lab-testphase-sec-template}
 {\ltlabsecIIdate}
 {\ltlabsecIIversion}
 {heading implementation}
%    \end{macrocode}
%
% \changes{v0.9c}{2026-03-12}{Switch from \texttt{x}- to \texttt{e}-type
%   expansion in expl3 code}
%
% \bigskip
%
% \subsection{Debugging}
%
%  \begin{variable}{\g_@@_debug_bool}
%
%    \begin{macrocode}
\bool_new:N \g_@@_debug_bool
%    \end{macrocode}
%  \end{variable}
%
%
%  \begin{macro}{\@@_debug:n,\@@_debug_typeout:n}
%
%    \begin{macrocode}
\cs_new_eq:NN \@@_debug:n \use_none:n
\cs_new_eq:NN \@@_debug_typeout:n \use_none:n
%    \end{macrocode}
%  \end{macro}
%
%  \begin{macro}{\head_debug_on:,\head_debug_off:,
%                \@@_debug_gset:}
%    \begin{macrocode}
\cs_new_protected:Npn \head_debug_on:
  {
    \bool_gset_true:N \g_@@_debug_bool
    \@@_debug_gset:
  }
%    \end{macrocode}
%
%    \begin{macrocode}
\cs_new_protected:Npn \head_debug_off:
  {
    \bool_gset_false:N \g_@@_debug_bool
    \@@_debug_gset:
  }
%    \end{macrocode}
%
%    \begin{macrocode}
\cs_new_protected:Npn \@@_debug_gset:
  {
    \cs_gset_protected:Npe \@@_debug:n ##1
      { \bool_if:NT \g_@@_debug_bool {##1} }
    \cs_gset_protected:Npe \@@_debug_typeout:n ##1
      { \bool_if:NT \g_@@_debug_bool { \typeout{[head]~ ##1} } }
  }
%    \end{macrocode}
%  \end{macro}
%
%
%  \begin{macro}{\DebugHeadingsOn,\DebugHeadingsOff}
%
%    \begin{macrocode}
\cs_new_protected:Npn \DebugHeadingsOn  { \head_debug_on:  }
\cs_new_protected:Npn \DebugHeadingsOff { \head_debug_off: }
%    \end{macrocode}
%
%    \begin{macrocode}
\DebugHeadingsOff
%    \end{macrocode}
%  \end{macro}
%
%  \begin{macro}{\@@_show_arguments:nnnnnn}
%    Some debug data \ldots
%    \begin{macrocode}
\cs_new:Npn \@@_show_arguments:nnnnnn #1#2#3#4#5#6 {
  \@@_debug_typeout:n{---------~ Headformat~ instance~ arguments:}
  \@@_debug_typeout:n{1:~ keys~ =~ \exp_not:n{#1}}
  \@@_debug_typeout:n{2:~ prefix~ =~ \exp_not:n{#2}}
  \@@_debug_typeout:n{3:~ number~ =~ \exp_not:n{#3}}
  \@@_debug_typeout:n{4:~ title~ =~ \exp_not:n{#4}}
  \@@_debug_typeout:n{5:~ subtitle~ =~ \exp_not:n{#5}}
  \@@_debug_typeout:n{6:~ quotation~ =~ \exp_not:n{#6}}
}
%    \end{macrocode}
%  \end{macro}
%  \begin{macro}{\@@_show_arguments:nnnnnnnnn}
%    Some debug data \ldots
%    \begin{macrocode}
\cs_new:Npn \@@_show_arguments:nnnnnnnnn #1#2#3#4#5#6#7#8#9 {
  \@@_debug_typeout:n{---------~ Heading~ instance~ arguments:}
  \@@_debug_typeout:n{1:~ keys~ =~ \exp_not:n{#1}}
  \@@_debug_typeout:n{2:~ unnumbered~ =~ \exp_not:n{#2}}
  \@@_debug_typeout:n{3:~ title~ =~ \exp_not:n{#3}}
  \@@_debug_typeout:n{4:~ toc~ =~ \exp_not:n{#4}}
  \@@_debug_typeout:n{5:~ running~ =~ \exp_not:n{#5}}
  \@@_debug_typeout:n{6:~ bookmark~ =~ \exp_not:n{#6}}
  \@@_debug_typeout:n{7:~ nameref~ =~ \exp_not:n{#7}}
  \@@_debug_typeout:n{8:~ label~ =~ \exp_not:n{#8}}
  \@@_debug_typeout:n{9:~ subtitle | quote ~ =~ \exp_not:n{#9}}
}
%    \end{macrocode}
%  \end{macro}
%
% \subsection{Temp variable(s)}
% \begin{variable}{\l_@@_tmpa_tl}
%    \begin{macrocode}
\tl_new:N\l_@@_tmpa_tl
%    \end{macrocode}
% \end{variable}
%
% \subsection{variable(s)}
%  These token lists are automatically declared by the key machinery.
%    \begin{macrocode}
%\tl_new:N \l_@@_bookmark_tl
%\tl_new:N \l_@@_running_tl
%\tl_new:N \l_@@_toc_tl
%\tl_new:N \l_@@_nameref_tl
%\tl_new:N \l_@@_subtitle_tl
%\tl_new:N \l_@@_quote_tl
%\bool_new:N l_@@_unnumbered_bool
%    \end{macrocode}
%
% \begin{variable}{
%  \l_@@_label_tl,
%  \l_@@_instance_keys_tl,
%  \l_@@_number_tl,
%  \l_@@_saved_secnumdepth_tl,
%  \l_@@_title_tl,
%  \l_@@_placement_tl}
%
% But these token lists needs a declaration:
%
%    \begin{macrocode}
\tl_new:N \l_@@_label_tl
\tl_new:N \l_@@_instance_keys_tl
\tl_new:N \l_@@_number_tl
\tl_new:N \l_@@_saved_secnumdepth_tl
\tl_new:N \l_@@_title_tl
\tl_new:N \l_@@_placement_tl
%    \end{macrocode}
% \end{variable}
%
% \subsection{New user commands}
%
% \begin{macro}{\theheading}
% This command expands to \cs{thechapter}, \cs{thesection} etc
% in every heading command.
%    \begin{macrocode}
\tl_new:N\theheading
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\partmark}
% This replaces the fix \verb+\markboth{}{}+ or similar in the standard \cs{part}
% definition. As the command is already defined in some classes (like \pkg{memoir}),
% we provide it through a hook.
%    \begin{macrocode}
\AddToHook{class/after}{\providecommand*\partmark[1]{\markboth{}{}}}
%    \end{macrocode}
% \end{macro}
%
% \subsection{The \LaTeXe{} parsing interface}
%
%    \LaTeXe{} provides heading commands with a starred form
%    (unnumbered) and one optional argument (to specify an alternative
%    toc/running head). We augment this slightly by supporting a key
%    value interface in the optional argument. This is handled by
%    defining the commands through \cs{ParseLaTeXeHeading}. This
%    should happen in the document class.
%
%
%  \begin{macro}{\ParseLaTeXeHeading}
%^^A
%    \cs{ParseLaTeXeHeading} arguments:
%    \begin{itemize}
%    \item[1:] instance name to use (of type \enquote{heading})
%    \item[2:] numbered? boolean
%    \item[3:] shorttitle or key/val for layout adjustments and individual
%              title settings
%    \item[4:] main title
%    \end{itemize}
%
%    This command handles the document input that may be hidden in the
%    optional argument, i.e., special data for toc, running (header),
%    bookmark, label, and for more specialized headings subtitle and
%    quote. It also handles the legacy case that the optional argument is just
%    an alternate title to be used for toc, running, and bookmark
%    (through the key shorttitle to which it gets converted).
%
%    \begin{macrocode}
\cs_new_protected:Npn \ParseLaTeXeHeading #1 #2 #3 #4 {
%    \end{macrocode}
%
%    \begin{macrocode}
  \@@_debug_typeout:n{==================================}
  \@@_debug_typeout:n{#1:~ \IfBooleanT{#2}{*}
                \IfValueT{#3}{[\exp_not:n{#3}]}
                {\exp_not:n{#4}}}
%    \end{macrocode}
%    We first check if the title argument contains a \cs{label}
%    command. If yes, we remove it and add it to \cs{l_@@_label_tl}
%    (and if more than one all of them) and save the rest of the main title in
%    \cs{l_@@_title_tl} for later use. If there was no \cs{label}
%    command then \cs{l_@@_title_tl} is set to \texttt{\#4}.
%    \begin{macrocode}
  \@@_find_label:w #4 \label\q_no_value \@@_find_label:w
%    \end{macrocode}
%    By default toc, running, and bookmark use the data provided by
%    the main title. However, if the second argument is true (i.e., a
%    star was given) they are all suppressed (because this is the \LaTeXe{} logic).
%    \begin{macrocode}
  \IfBooleanTF{#2}
    { \tl_clear:N \l_@@_toc_tl
      \tl_clear:N \l_@@_running_tl
      \tl_clear:N \l_@@_bookmark_tl
      \bool_set_true:N \l_@@_unnumbered_bool
    }
    { \tl_set_eq:NN \l_@@_toc_tl      \l_@@_title_tl
      \tl_set_eq:NN \l_@@_running_tl  \l_@@_title_tl
      \tl_set_eq:NN \l_@@_bookmark_tl \l_@@_title_tl
      \bool_set_false:N \l_@@_unnumbered_bool
    }
%    \end{macrocode}
%    The nameref always starts out matching the main title.
%    \begin{macrocode}
  \tl_set_eq:NN \l_@@_nameref_tl \l_@@_title_tl
%    \end{macrocode}
%    Normally we don't have a subtitle or quote unless they are
%    explicitly given through keys, so we start with \cs{c_novalue_tl}
%    \begin{macrocode}
  \tl_set_eq:NN \l_@@_subtitle_tl \c_novalue_tl
  \tl_set_eq:NN \l_@@_quote_tl    \c_novalue_tl
%    \end{macrocode}
%    If the optional argument is empty we set the
%    \cs{l_@@_instance_keys_tl} to empty, otherwise process the
%    key/val list setting the keys defined in the module \enquote{head}. This
%    overwrites the defaults specified above if keys like \enquote{toc} are in
%    the list. All the key/vals unknown by that module are put into
%    \cs{l_@@_instance_keys_tl} which may or may not make this token
%    list non-empty.
%
%    If the user has a \key{label} key and also a \cs{label} in the
%    main title argument then the latter is ignored (no error checking
%    for that). We could alternatively set all labels we find,
%    perhaps that is the better approach?
%    \begin{macrocode}
  \IfNoValueTF { #3 }
    { \tl_clear:N \l_@@_instance_keys_tl }
    { \keys_set_known:nnN {heading} { #3 } \l_@@_instance_keys_tl }
%    \end{macrocode}
%
%    Finally we call the heading instance using the collected
%    mandatory arguments. To simplify downstream processing we pass
%    the values not the container tokenlists resulting from the above
%    processing.\footnote {I think this is a common requirement and
%    perhaps \cs{UseInstance} should really o-expand all arguments it
%    receives.}
%    \begin{macrocode}
  \@@_debug_typeout:n{use~ 'heading'~ instance:~ #1 }
  \use:e {
    \exp_not:N \UseInstance{heading}{#1}
              { \exp_not:o \l_@@_instance_keys_tl }
              { \bool_if:NTF \l_@@_unnumbered_bool \BooleanTrue \BooleanFalse }
              { \exp_not:o \l_@@_title_tl}
              { \exp_not:o \l_@@_toc_tl }
              { \exp_not:o \l_@@_running_tl }
              { \exp_not:o \l_@@_bookmark_tl }
              { \exp_not:o \l_@@_nameref_tl }
              { \exp_not:o \l_@@_label_tl }
              { { \exp_not:o \l_@@_subtitle_tl }
                { \exp_not:o \l_@@_quote_tl    } }
  }
}
%    \end{macrocode}
%
%    Syntax keys that can appear in the optional argument of headings
%    parsed by \cs{ParseLaTeXeHeading}. All other keys used there are
%    passed to the heading instance to overwrite instance setting.
%
%    \begin{macrocode}
\keys_define:nn {heading} {
  , shorttitle .meta:n    =
      {toc = {#1} , running = {#1} , bookmark = {#1} , nameref= {#1} }
  , bookmark   .tl_set:N  = \l_@@_bookmark_tl
  , running    .tl_set:N  = \l_@@_running_tl
  , toc        .tl_set:N  = \l_@@_toc_tl
  , nameref    .tl_set:N  = \l_@@_nameref_tl
%
  , numbered   .bool_set_inverse:N = \l_@@_unnumbered_bool
  , numbered   .default:n = true
  , unnumbered .bool_set:N = \l_@@_unnumbered_bool
  , unnumbered .default:n = true
%
  , subtitle   .tl_set:N  = \l_@@_subtitle_tl
  , quote      .tl_set:N  = \l_@@_quote_tl
%    \end{macrocode}
%    We collect labels together with their \cs{label} command in case
%    there is more than one. This way we can later simply execute
%    \cs{l_@@_label_tl} without any status checks.
%    \begin{macrocode}
  , label      .code:n    = \tl_put_right:Nn \l_@@_label_tl { \label{#1} }
}
%    \end{macrocode}
%
%
%  \end{macro}
%
%  \begin{macro}{\@@_find_label:w}
%    A simple-minded check for an existing \cs{label} command in the
%    main title (could be done better I guess). We add
%    \cs{label}\cs{q_no_value} at the end of the argument, so that we
%    can be sure to find something.
%
%    As currently implemented the spaces on both sides of a \cs{label}
%    command survive if it is removed. This may be an issue in which
%    case this may need some adjustments.
%    \begin{macrocode}
\cs_new:Npn \@@_find_label:w #1 \label #2#3 \@@_find_label:w {
%    \end{macrocode}
%    If the token after \cs{label} is \cs{q_no_value} then the title
%    had no label and we set the two variables accordingly.
%    \begin{macrocode}
  \quark_if_no_value:nTF {#2}
     { \@@_debug_typeout:n{---~no~label }
       \tl_clear:N \l_@@_label_tl
       \tl_set:Nn\l_@@_title_tl {#1#3}
     }
%    \end{macrocode}
%    Otherwise, there was a real \cs{label} command and \texttt{\#2}
%    holds the label string.
%    \begin{macrocode}
     { \@@_debug_typeout:n{---~label~found~#2}
       \tl_set:Nn\l_@@_label_tl { \label{#2} }
%    \end{macrocode}
%    To construct the value for \cs{l_@@_title_tl} we have to get rid
%    of the two tokens we added at its end, this is done with
%    \cs{@@_find_label_aux:w}.
%    \begin{macrocode}
       \tl_set:Nn\l_@@_title_tl {#1}
       \@@_find_label_aux:w #3\@@_find_label_aux:w
     }
     \@@_debug_typeout:n{---~return:~ '\exp_not:o \l_@@_title_tl' }
}
%    \end{macrocode}
%    There is at least one more \cs{label} now and the token after it
%    should be our \cs{q_no_value}. If not then the title argument had
%    at least 2 labels and we collect the newly found one and recurse.
%    \begin{macrocode}
\cs_new:Npn \@@_find_label_aux:w #1 \label #2#3 \@@_find_label_aux:w {
%    \end{macrocode}
%    The \texttt{\#1} may not be everything we have to pick up but we
%    know for sure that it belongs to the title.
%    \begin{macrocode}
  \tl_put_right:Nn \l_@@_title_tl { #1 }
%    \end{macrocode}
%    Now let's see if we are at the end of the argument. If not pick
%    up the newly found \cs{label} and recurse on the remaining material.
%    \begin{macrocode}
  \quark_if_no_value:nF {#2}
    { \@@_debug_typeout:n{---~ extra~ label~ '#2'~ found }
      \tl_put_right:Nn \l_@@_label_tl { \label{#2} }
      \@@_find_label_aux:w #3\@@_find_label_aux:w
    }
}
%    \end{macrocode}
%  \end{macro}
%
%
%
% \subsection{General helper commands}
%
%
%
%  \begin{macro}{\WordSpaceAmount}
%    Produce the amount of a (fractional) word space in the current
%    font in a way that it can be used in a skip or dimen register
%    assignment. The argument specifies the fraction, e.g., \texttt{2}
%    gives two word spaces and \texttt{.5} would produce half a word
%    space.
%
%    This general helper doesn't really belong here, so should be
%    eventually moved.
%    \begin{macrocode}
\newcommand\WordSpaceAmount[1]{
  \glueexpr 
        #1\fontdimen2\the\font
  plus  #1\fontdimen3\the\font
  minus #1\fontdimen4\the\font
  \relax
}  
%    \end{macrocode}
%  \end{macro}
%
%
%    Some designs automatically add a punctuation symbol (typically a
%    period) at the end of a title, but that should only happen if the
%    title doesn't already end in a punctuation symbol.
%
%    This is achieved by setting the \cs{spacefactor} for punctuation
%    symbols (slightly) higher than \texttt{1000} and then checking the current
%    \cs{spacefactor} before trying to add the punctuation. If it is
%    \texttt{1000} or less then the title didn't end in a punctuation
%    and we can safely add one, otherwise we don't.
%
%    If \cs{nonfrenchspacing} is in force this is automatically the
%    case, but in \LaTeXe{} \cs{frenchspacing} did set the
%    \cs{spacefactor} of all punctuation symbols to \texttt{1000}
%    making them indistinguishable from other characters.
%
%    Thus, to make this work, we have to change \cs{frenchspacing}
%    which is a breaking change as it can lead to pagination
%    differences given that the word space after a punctuation gets
%    (very minimally) larger this way. However, this approach
%    was successfully used in the AMS classes for ages and it offers
%    nice design possibilities so we enable it in documents using
%    \cs{DocumentMetadata} automatically.
%
%
%  \begin{macro}{\frenchspacing,\nonfrenchspacing}
%    We give all punctuation symbols a unique \cs{sfcode} value so
%    that it is even possible to determine which punctuation was just
%    typeset.
%    \begin{macrocode}
\def\frenchspacing{\sfcode`\.1006\sfcode`\?1005\sfcode`\!1004%
  \sfcode`\:1003\sfcode`\;1002\sfcode`\,1001 }
%    \end{macrocode}
%    The same should be done for \texttt{.?!} if we want to be able to
%    distinguish those when \cs{nonfrenchspacing} is in force.  
%    \begin{macrocode}
\def\nonfrenchspacing{\sfcode`\.3002\sfcode`\?3001\sfcode`\!3000%
  \sfcode`\:2000\sfcode`\;1500\sfcode`\,1250 }
%    \end{macrocode}
%  \end{macro}
%    
%
%  \begin{macro}{\nopunct}
%    The AMS classes also offered \cs{nopunct} that could be added at
%    the end of a title and would prevent the addition of a punctuation
%    symbol.
%
%    It should have a value for \cs{spacefactor} that is not
%    used for \cs{frenchspacing} so that this special case can be
%    detected.
%    \begin{macrocode}
\cs_new_protected:Npn \nopunct {\spacefactor 1007 }
%    \end{macrocode}
%  \end{macro}
%
%
%
%  \begin{macro}{\AddPunct}
%    In the AMS classes this was called \cs{@addpunct}.
%
%    Note: this mechanism will fail if the text ending in a
%    punctuation has an uppercase character just before the
%    punctuation, e.g., if somebody writes \texttt{SOLUTION:}. In that
%    case \texttt{SOLUTION\cs{@}.} would be necessary!
% \changes{0.9j}{2026-057-12}{Support adding punctuation if not
%    already present  (tagging/1477)}
%    \begin{macrocode}
\cs_new_protected:Npn \AddPunct #1 {
  \relax\ifhmode
    \ifnum\spacefactor>\@m
      \@@_debug_typeout:n {--->~ punctuation~ '#1'~ not~ added}
    \else
      \@@_debug_typeout:n {--->~ punctuation~ '#1'~ added}
      #1
    \fi
  \fi
}
%    \end{macrocode}
%  \end{macro}
%
%
%
%
% \subsection{Templates}
%
% \subsubsection{Template types}
%
% \begin{templatetype}{heading}
%    Templates of type \insttype{heading} are used to produce headings. The
%    positional arguments are:
% \begin{verbatim}
%      1: key/val list
%      2: unnumbered?
%      3: title
%      4: toc
%      5: running
%      6: bookmark
%      7: nameref
%      8: label(s)
%      9: { subtitle } { quote }
% \end{verbatim}
%    \begin{macrocode}
\NewTemplateType{heading}{9}
%    \end{macrocode}
% \end{templatetype}
%
% \begin{templatetype}{headformat}
%    Templates of type \insttype{headformat} are used to produce heading
%    layout from the formatted heading number (if any), the heading title,
%    subtitle and quotation. The
%    positional arguments are:
% \begin{verbatim}
%      1: key/val list for document-level customizations
%      2: prefix string
%      3: formatted heading number
%      4: title
%      5: subtitle
%      6: quote
% \end{verbatim}
%    \begin{macrocode}
\NewTemplateType{headformat}{6}
%    \end{macrocode}
% \end{templatetype}
%
%
%
%
%
%
% \subsubsection{heading templates interfaces}
%
% We have two heading templates: display and runin.
%
%  \begin{template}{heading display}
%    The \texttt{display} template produces a display heading, i.e.,
%    one that has vertical space before and after it.
% \changes{0.9h}{2026-06-21}{Support \texttt{column-spanning} key (tagging/1436)}
%    \begin{macrocode}
\DeclareTemplateInterface{heading}{display}{9}
{
  , name            : tokenlist
  , parent-name     : tokenlist
  , reset-counter   : tokenlist
  , level           : integer = 0
%    \end{macrocode}
%    By default headings can be numbered and the numbering is
%    determined for each heading in the document individually.
% \changes{0.9h}{2026-07-04}{Support a \texttt{force-unnumbered} key
%    (tagging/1473)}
%    \begin{macrocode}
  , force-unnumbered : boolean = false
%    \end{macrocode}
%    The \key{placement} key sets default values for the keys
%    \key{start-code} and \key{final-code}.
%    \begin{macrocode}
  , placement       : choice {page , top , normal, ragged } = normal
  , column-spanning : boolean = false
  , mark-cmd        : function(1) =
%    \end{macrocode}
%    
%    \begin{macrocode}
  , para-indent   : choice { true , false } = false
%    \end{macrocode}
%    We use \cs{c_max_int} as a fake penalty to indicate that no
%    penalty was given in a key.
%    \begin{macrocode}
  , before-vspace : skip = 0pt
  , penalty       : integer = \c_max_int
  , after-penalty-vspace : skip = 0pt
  , after-vspace  : skip = 0pt
%    \end{macrocode}
%    The next two keys are only there to overwrite the \key{placement}
%    settings with explicit code. Thus, their default value is set up
%    by the \key{placement} key (which has a default).
%    \begin{macrocode}
  , start-code    : tokenlist =      % no default values!
  , final-code    : tokenlist =      % no default values!
%    \end{macrocode}
%    A prefix string such as \cs{@chappap} could be specified in the
%    next variable. By default it has no value.
%    \begin{macrocode}
  , prefix         : tokenlist = \NoValue
%    \end{macrocode}
%    A postfix string to be added to the heading number (if the
%    heading is numbered). By default empty (not \cs{NoValue})!
%    \begin{macrocode}
  , punct          : tokenlist = 
%    \end{macrocode}
%
%    \begin{macrocode}
  , heading-decls  : tokenlist = \normalfont
  , prefix-decls   : tokenlist =
  , number-decls   : tokenlist =
  , title-decls    : tokenlist =
  , subtitle-decls : tokenlist =
  , quote-decls    : tokenlist =
%    \end{macrocode}
%    
%    \begin{macrocode}
  , heading-format  : function{1} = #1
  , prefix-format   : function{1} = #1
  , number-format   : function{1} = #1
  , punct-format    : function{1} = #1
  , title-format    : function{1} = #1 \par
  , subtitle-format : function{1} = #1
  , quote-format    : function{1} = #1
%    \end{macrocode}
%    Not clear where this key should live and if it really makes sense
%    to offer variations on the individual heading levels as in
%    \verb=\UseStructureName{sec/???/number}=.
%    \begin{macrocode}
  , number-tag      : tokenlist = heading-number  % \UseStructureName{sec/???}
%    \end{macrocode}
%
%    \begin{macrocode}
  , headformat-instance : tokenlist = std
  , contents-extra : tokenlist =
}
%    \end{macrocode}
%  \end{template}
%
%
%  \begin{template}{heading runin}
%    This template is similar to the \texttt{display} template but
%    implements a runin heading, i.e., one where the paragraph text
%    continues on the same line.
%
%    Unfortunately, we can't really use \cs{DeclareTemplateCopy} to
%    set it up because with \cs{EditTemplateDefaults} we are not able
%    to alter the setup for the \key{placement} and \key{para-indent} keys
%    as that involves changing the implementation code. Thus with
%    \cs{DeclareTemplateCopy} we can copy the interface setup but the
%    code setup still needs to be done using \cs{DeclareTemplateCode}.
%
%    \begin{macrocode}
\DeclareTemplateInterface{heading}{runin}{9}
{
  , name             : tokenlist
  , parent-name      : tokenlist
  , reset-counter    : tokenlist
  , level            : integer = 0
  , force-unnumbered : boolean = false
  , placement        : choice {page , top , normal, ragged } = normal
  , column-spanning  : boolean = false
  , mark-cmd         : function(1) =
  , para-indent      : choice { true , false } = false
  , before-vspace    : skip = 0pt
  , penalty          : integer = \c_max_int
  , after-penalty-vspace : skip = 0pt
  , after-hspace     : skip = 0pt
  , start-code       : tokenlist =      % no default values!
  , final-code       : tokenlist =      % no default values!
  , prefix           : tokenlist = \NoValue
  , punct            : tokenlist =
  , heading-decls    : tokenlist = \normalfont
  , prefix-decls     : tokenlist =
  , number-decls     : tokenlist =
  , title-decls      : tokenlist =
  , subtitle-decls   : tokenlist =
  , quote-decls      : tokenlist =
  , heading-format   : function{1} = #1
  , prefix-format    : function{1} = #1
  , number-format    : function{1} = #1
  , punct-format     : function{1} = #1
%    \end{macrocode}
%    We have one difference in the defaults: in runin headings
%    everything has to stay in horizontal mode so we do not append
%    \cs{par} in the default value for \key{title-format}.
%    \begin{macrocode}
  , title-format     : function{1} = #1
  , subtitle-format  : function{1} = #1
  , quote-format     : function{1} = #1
  , number-tag       : tokenlist = heading-number  % \UseStructureName{sec/???}
  , headformat-instance : tokenlist = std
  , contents-extra   : tokenlist =
}
%    \end{macrocode}
%  \end{template}
%
%
%  \subsubsection{headformat templates interfaces}
% We have three template: display, hang and runin.
%
%  \begin{template}{headformat display}
%    The \instname{display} template produces a heading in which the
%    heading elements form a single block, potentially with separators
%    that separates some elements vertically from the other.
%    \begin{macrocode}
\DeclareTemplateInterface{headformat}{display}{6}
{
  , heading-indent    : length = 0pt
%  
  , order             : commalist = {prefix,separator-a,?,number,punct,
                                     separator-b,?,title,
                                     separator-c, subtitle}
  , separator-a       : tokenlist = \nobreakspace
  , separator-b       : tokenlist = \par \nobreak \vspace{20pt}
  , separator-c       : tokenlist = \
  , separator-d       : tokenlist = 
}
%    \end{macrocode}
%  \end{template}
%
%  \begin{template}{headformat hang}
%    The \texttt{hang} template produces a heading where some elements
%    are measured to determine a hanging indentation while the
%    remaining ones are then typeset in that constrained space. This
%    is why we have two order keys.
%    \begin{macrocode}
\DeclareTemplateInterface{headformat}{hang}{6}
{
  , heading-indent    : length = 0pt
  , order-hang        : commalist = {prefix,separator-a,?,number,punct,
                                     separator-b,?}
  , order             : commalist = {title, separator-c, subtitle}
  , separator-a       : tokenlist = \nobreakspace
  , separator-b       : tokenlist = \hspace{1em}
  , separator-c       : tokenlist = \
  , separator-d       : tokenlist =
}
%    \end{macrocode}
%  \end{template}
%
%
%  \begin{template}{headformat runin}
%    The \texttt{runin} template produces a heading which is
%    horizontally oriented and text following the heading will
%    continue on the same line as the heading.
%    \begin{macrocode}
\DeclareTemplateInterface{headformat}{runin}{6}
{
  , heading-indent    : length = 0pt
  , order             : commalist = {prefix,separator-a,?,number,punct,
                                     separator-b,?,title,
                                     separator-c,subtitle}
  , separator-a       : tokenlist = \nobreakspace
  , separator-b       : tokenlist = \hspace{1em}
  , separator-c       : tokenlist = \
  , separator-d       : tokenlist =
}
%    \end{macrocode}
%  \end{template}
%
%
%
%
%
%
%
% \subsubsection{heading templates code}
%
%  \begin{template}{heading display}
%
%    \begin{macrocode}
\DeclareTemplateCode{heading}{display}{9}
{
  , name          = \l_@@_name_tl
  , level         = \l_@@_level_int
% next two not yet used
  , parent-name   = \l_@@_pname_tl
  , reset-counter = \l_@@_reset_cnt_tl
%    \end{macrocode}
%
% \changes{0.9h}{2026-07-04}{Support a \texttt{force-unnumbered} key
%    (tagging/1473)}
%    \begin{macrocode}
  , force-unnumbered = \l_@@_unnumbered_bool
%    \end{macrocode}
%    The \key{placement} key determines whether the heading can appear
%    anywhere (\texttt{normal}), automatically starts a new page or
%    column (\texttt{top}), or is on a page of its own (\texttt{page}.
%
%    It is usually implemented by setting \cs{l_@@_start_code_tl} and
%    \cs{l_@@_final_code_tl} (exceptions are \texttt{normal} and \texttt{ragged}).
%    These settings can be fine-tuned or
%    overwritten with the keys \key{start-code} and
%    \key{final-code}, if necessary.
%    \begin{macrocode}
  , placement     = {
        ,page   = \@@_debug_typeout:n{ A~ page~ heading }
                  \tl_set:Nn \l_@@_placement_tl { page }
        ,top    = \@@_debug_typeout:n{ A~ top~ heading }
                  \tl_set:Nn \l_@@_placement_tl { top }
        ,normal = \@@_debug_typeout:n{ A~ normal~ heading }
                  \tl_set:Nn \l_@@_placement_tl { normal }
        ,ragged = \@@_debug_typeout:n{ A~ normal~ heading~ (ragged~ style) }
                  \tl_set:Nn \l_@@_placement_tl { ragged }
                    }
%    \end{macrocode}
%    
% \changes{0.9h}{2026-06-21}{Support \texttt{column-spanning} key
%    (tagging/1436)}
%    \begin{macrocode}
  , column-spanning = \l_@@_column_spanning_bool
%    \end{macrocode}
%    
%    \begin{macrocode}
  , mark-cmd      = \@@_mark_cmd:n
%    \end{macrocode}
%    For now we make use of the legacy coding for indentation of
%    the following paragraph.
%    \begin{macrocode}
  , para-indent   = {
                      ,true  = \@afterindenttrue
                      ,false = \@afterindentfalse
                    }
  , before-vspace = \l_@@_before_skip
  , penalty       = \l_@@_penalty_int
  , after-penalty-vspace  = \l_@@_after_penalty_skip
  , after-vspace  = \l_@@_after_skip
  , start-code    = \l_@@_start_code_tl
  , final-code    = \l_@@_final_code_tl
%    \end{macrocode}
%
%    \begin{macrocode}
  , prefix        = \l_@@_prefix_tl
  , punct         = \l_@@_punct_tl
%    \end{macrocode}
%
%    \begin{macrocode}
  , headformat-instance = \l_@@_headformat_instance_tl
%    \end{macrocode}
%
%    \begin{macrocode}
  , heading-decls  = \l_@@_heading_decls_tl
  , prefix-decls   = \l_@@_prefix_decls_tl
  , number-decls   = \l_@@_number_decls_tl
  , title-decls    = \l_@@_title_decls_tl
  , subtitle-decls = \l_@@_subtitle_decls_tl
  , quote-decls    = \l_@@_quote_decls_tl
%    \end{macrocode}
%    
%    \begin{macrocode}
  , heading-format  = \@@_heading_format:n
  , prefix-format   = \@@_prefix_format:n
  , number-format   = \@@_number_format:n
  , punct-format    = \@@_punct_format:n
  , title-format    = \@@_title_format:n
  , subtitle-format = \@@_subtitle_format:n
  , quote-format    = \@@_quote_format:n
%
  , number-tag      = \l_@@_number_tag_tl
%    \end{macrocode}
%    
%    \begin{macrocode}
  , contents-extra = \l_@@_contents_extra_tl
}
%    \end{macrocode}
%
%    \begin{macrocode}
{
%    \end{macrocode}
%
%    \begin{macrocode}
  \tl_set_eq:Nc \theheading { the \l_@@_name_tl }
%    \end{macrocode}
% We store the value of \texttt{secnumdepth} so that we can change it locally.
%    \begin{macrocode}
  \tl_set:Ne\l_@@_saved_secnumdepth_tl{\int_use:N\c@secnumdepth}
%    \end{macrocode}
%
%    \begin{macrocode}
  \@@_show_arguments:nnnnnnnnn
       {#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}{#9}
%    \end{macrocode}
%    First evaluate any key setting done by the user in the
%    optional first argument.
%   \fmi{It would be nice if there is a variant of
%   \cs{SetTemplateKey} in which the template type and name are
%   implicit, e.g., \cs{SetCurrentTemplateKeys} because this is
%   usually what I need.}
%    \begin{macrocode}
  \SetKnownTemplateKeys{heading}{display}{#1}
%    \end{macrocode}
%
%    If \key{column-spanning} is requested but we are not typesetting
%    in two columns we turn it off to avoid using \cs{@topnewpage} as
%    this would be wrong. Otherwise we check the placement value and
%    adjust it if necessary.
% \changes{0.9h}{2026-06-21}{Support \texttt{column-spanning} key
%    (tagging/1436)}
%    \begin{macrocode}
  \bool_if:NT \l_@@_column_spanning_bool
       { \if@twocolumn
           \str_if_eq:VnF \l_@@_placement_tl {top}
             {
               \@@_debug_typeout:n {column-spanning~ requires~
                 placement=top.~ Adjusted!}
               \tl_set:Nn \l_@@_placement_tl {top}
             }
         \else
           \bool_set_false:N \l_@@_column_spanning_bool
         \fi
       }
%    \end{macrocode}
%    Based on the \key{placement} key we set up \cs{l_@@_start_code_tl}
%    and \cs{l_@@_final_code_tl}. These two variables can also be set
%    with the keys \key{start-code} and \key{final-code} in which case
%    we don't alter the definition.
%    \begin{macrocode}
  \tl_if_empty:oT \l_@@_start_code_tl
   { \str_case:VnF \l_@@_placement_tl
      {
        { page }
        { \tl_set:Nn \l_@@_start_code_tl
%    \end{macrocode}
%    Straight from the placement definition of \cs{part}.\fmi{Clearly not
%    \cs{@tempswa} and the page styles should be adjustable.}
%    \begin{macrocode}
            { \if@openright
                \cleardoublepage
              \else
                \clearpage
              \fi
              \thispagestyle{plain}%
              \if@twocolumn
                \onecolumn
                \@tempswatrue
              \else
                \@tempswafalse
              \fi
              \null\vfil
            }
        }
        { top }
        { \tl_set:Nn \l_@@_start_code_tl
            { \if@openright\cleardoublepage\else\clearpage\fi
              \thispagestyle{plain}%
              \global\@topnum\z@
            }
        }
%    \end{macrocode}
%    Ragged headings (i.e., those that leave a previous page ragged
%    bottom if they generate a page break) are produced by replacing
%    \cs{addpenalty} with a version that also adds \cs{vfil} and
%    \cs{vfilneg}. This is handled by altering
%    \cs{sec_add_penalty_with_possible_fil:n} which after use resets
%    itself to \cs{addpenalty}.
% \changes{0.9k}{2026-08-04}{Support \texttt{placement=ragged} (github/1844)}
%    \begin{macrocode}
        { ragged }
        { \cs_set_eq:NN \sec_add_penalty_with_possible_fil:n 
                        \sec_add_penalty_with_fil:n
        }
      }
      { \tl_clear:N \l_@@_start_code_tl }
   }
%
  \tl_if_empty:oT \l_@@_final_code_tl
   { \str_case:VnF \l_@@_placement_tl
      {
        { page }
        { \tl_set:Nn \l_@@_final_code_tl
            { \vfil\newpage
              \if@twoside
                \if@openright
                  \null
                  \thispagestyle{empty}%
                \newpage
                \fi
              \fi
              \if@tempswa
                \twocolumn
              \fi
            }
        }
      }
      { \tl_set:Nn  \l_@@_final_code_tl { \@afterheading } }
   }
%    \end{macrocode}
%    Then we set up the penalty to use (might be given as a key value).
%    \begin{macrocode}
  \@@_determine_penalty:
%    \end{macrocode}
%
%    \begin{macrocode}
  \@@_determine_number_typesetting:N #2
%    \end{macrocode}
%    Next comes the vertical spacing and penalty before the heading. This includes
%    running \cs{l_@@_start_code_tl} if it contains any code, e.g., to
%    start a new page.
%    \begin{macrocode}
  \@@_vertical_before_spacing:
%    \end{macrocode}
%    We are in vmode now and here is the point where we (with tagging)
%    can close a previous Sect structure and open the new one.
%    \begin{macrocode}
\UseTaggingSocket{sec/end}{\int_use:N\l_@@_level_int}
\UseTaggingSocket{sec/begin}
                 {{\int_use:N\l_@@_level_int}
                  {tag=\UseStructureName{sec/\int_use:N\l_@@_level_int}}
                 }
%    \end{macrocode}
%    Up to this point everything is identical for both display and
%    runin headings. But from now on they have their own code.
%    We have dealt with argument \#1 and \#2 so now we can unbundle
%    argument \#9 so that it is easier to process downstream
%    \begin{macrocode}
  \@@_debug_typeout:n{use~ 'headformat'~instance:~
                       \l_@@_headformat_instance_tl }
  \UseTaggingSocket{sec/title/begin}{{\int_use:N\l_@@_level_int}{#3}}
%    \end{macrocode}
%    
%    As long as we don't have a decent interface for the OR we have to
%    use \cs{@topnewpage} for getting spanning headings (which means
%    we are really using a top float box. That in turn means we have
%    to get all the vertical spacing and so inside this box so there
%    is a lot of back and forth based on the value of
%    \cs{l_@@_column_spanning_bool} for now.
% \changes{0.9h}{2026-06-21}{Support \texttt{column-spanning} key
%    (tagging/1436)}
%    \begin{macrocode}
  \use:e {
    \bool_if:NT \l_@@_column_spanning_bool
         { \exp_not:n {
             \@topnewpage [
             \dim_compare:nNnF{\l_@@_after_penalty_skip}={0pt}
                 { \vspace*    \l_@@_after_penalty_skip }
           }
         }
    \UseInstance{headformat} { \l_@@_headformat_instance_tl }
                { \exp_not:o \UnusedTemplateKeys }
                { \exp_not:o { \l_@@_prefix_tl } }
                { \exp_not:o { \l_@@_number_tl } }
                { \exp_not:n { #3 } }
                { \exp_not:o { \use_i:nn  #9 } }
                { \exp_not:o { \use_ii:nn  #9 } }
%    \end{macrocode}
%    
% \changes{0.9h}{2026-06-21}{Support \texttt{column-spanning} key
%    (tagging/1436)}
%    \begin{macrocode}
    \bool_if:NT \l_@@_column_spanning_bool
         {
           \skip_vertical:N \l_@@_after_skip
%    \end{macrocode}
%    Add the final vspace after the heading and close the
%    \cs{@topnewpage} which has an optional argument.
%    \begin{macrocode}
           ]
         }
  }
%    \end{macrocode}
%
%    \begin{macrocode}
  \UseTaggingSocket{sec/title/end}
 %
% --- handle marks, toc-entry, bookmark, nameref, and label
%
  \@@_handle_marks_etc:nnnnn {#4}{#5}{#6}{#7}{#8}
%
% --- post-heading handling (vertical)
%    \end{macrocode}
% Restore \texttt{secnumdepth}
%    \begin{macrocode}
  \int_gset:Nn\c@secnumdepth{\l_@@_saved_secnumdepth_tl}
  \par 
%    \end{macrocode}
%    If we have a spanning heading then the vertical skip is handled
%    inside \cs{@topnewpage} and not here.
% \changes{0.9h}{2026-06-21}{Support \texttt{column-spanning} key
%    (tagging/1436)}
%    \begin{macrocode}
  \bool_if:NF \l_@@_column_spanning_bool
       { \nobreak
         \skip_vertical:N \l_@@_after_skip
       }
% --- prepare next paragraph (defaults to \cs{@afterheading}
%
  \l_@@_final_code_tl
%
  \ignorespaces
}
%    \end{macrocode}
%  \end{template}
%
%
%  \begin{macro}{\sec_add_penalty_with_fil:n,
%                \sec_add_penalty_with_possible_fil:n}
%    The command \cs{sec_add_penalty_with_fil:n} adds a penalty
%    surrounded by stretchable glue like the plain \TeX{}
%    \cs{filbreak} command. After use it sets
%    \cs{sec_add_penalty_with_possible_fil:n} back to \cs{addpenalty}.
%
%    They have public names so that they can be used in other heading
%    templates outside of this module.
% \changes{0.9k}{2026-08-04}{Support \texttt{placement=ragged} (github/1844)}
%    \begin{macrocode}
\cs_new_protected:Npn \sec_add_penalty_with_fil:n #1 {
  \@@_debug_typeout:n{apply~ ragged~ bottom~ fil}
%    \end{macrocode}
%    Next code is straight from \cs{addpenalty} except that the
%    generated \cs{penalty} is surrounded by \cs{vfil} and \cs{vfilneg}.
%    \begin{macrocode}
  \addpenaltywithfil { #1 }
%    \end{macrocode}
%    Then reset so that next time \cs{addpenalty} is used again.
%    \begin{macrocode}
  \cs_set_eq:NN
    \sec_add_penalty_with_possible_fil:n
    \addpenalty
}
%    \end{macrocode}
%    By default \cs{sec_add_penalty_with_possible_fil:n} is the same
%    as \cs{addpenalty}. If you set it to
%    \cs{sec_add_penalty_with_fil:n} then it uses the "filbreak"
%    mechanism and afterwards resets itself to its default definition.
%    \begin{macrocode}
\cs_set_eq:NN
  \sec_add_penalty_with_possible_fil:n
  \addpenalty
%    \end{macrocode}
%  \end{macro}
%
%
%
%  \begin{macro}{\__kernel_add_penalty:n,
%                \addpenalty,\addpenaltywithfil}
%    
%    Next code is for inclusion in the kernel.  It is basically the
%    code from \LaTeX{}'s \cs{addpenalty} but with a slightly
%    different argument so that you have to supply
%    \verb=\penalty #1\relax= to mimic \cs{addpenalty} and
%    \verb=\vfil \penalty #1\vfilneg= to produce a penalty generating
%    a filbreak, i.e., a break where the previous page is ragged bottom.
%    \begin{macrocode}
\cs_new_protected:Npn \__kernel_add_penalty:n #1 {
%    \end{macrocode}
%    Don't add anything at the start of a minipage or when
%    \texttt{@nobreak} is set (i.e., directly after a heading).
%    \begin{macrocode}
  \mode_if_horizontal:T
    { \mode_if_inner:TF { \@LRmoderr }{ \par } }  
  \legacy_if:nF { @minipage }
    { \legacy_if:nF { @nobreak }
%    \end{macrocode}
%    Do everything in a group so that the temp variables are restored
%    afterwards in case they are used at the outside.
%    \begin{macrocode}
        { \group_begin:
%    \end{macrocode}
%    The rest is also from \cs{addpenalty} except that we have to give
%    \cs{penalty} explicitly as part of the argument.
%  
%    If there wasn't any previous skip or only a zero-sized one simply
%    set the penalty.
%    \begin{macrocode}
          \skip_set_eq:NN \l_tmpa_skip \tex_lastskip:D
          \dim_compare:nNnTF \l_tmpa_skip = \c_zero_dim
            { #1 }
%    \end{macrocode}
%    Otherwise copy the last skip value also into \cs{l_tmpb_skip}
%    using \TeX's fast direct assignment.
%    \begin{macrocode}
            { \skip_set_eq:NN \l_tmpb_skip \l_tmpa_skip
%    \end{macrocode}
%    Then add to it the current \cs{prevdepth} unless it is
%    \texttt{-1000pt} (which means it should be suppressed) or if it
%    is unusually large, in which case add \cs{maxdepth} instead. We
%    remember that value because it will be reused below.
%    \begin{macrocode}
              \dim_set:Nn \l_tmpa_dim
                 { \dim_compare:nNnTF \prevdepth > \maxdepth
                     \maxdepth
                     { \dim_compare:nNnTF \prevdepth = { -1000pt }
                          \c_zero_dim
                          \prevdepth
                     }
                 }
              \skip_add:Nn \l_tmpb_skip \l_tmpa_dim
%    \end{macrocode}
%    This is the amount we have to back up in order to position us
%    vertically where the bottom of the page would be if a natural
%    break would happen.
%    \begin{macrocode}
              \vskip -\l_tmpb_skip
%    \end{macrocode}
%    That is then the point where we have to add the explicit penalty
%    or the filbreak code.
%    \begin{macrocode}
              #1
%    \end{macrocode}
%    After the penalty (and after a possible \cs{vfilneg}) we have to
%    re-add what we back up but that isn't as trivial as one might
%    think.
%       
%    First we have to move forward by whatever amount we backed up due
%    to \cs{prevdepth} because going forward the \cs{prevdepth} will
%    be zero.   
%    \begin{macrocode}
              \dim_compare:nNnF \l_tmpa_dim = \c_zero_dim
                { \vskip \l_tmpa_dim }
%    \end{macrocode}
%    Finally we have to reinsert what we saved as \cs{lastskip},
%    because that is what any following \cs{addvspace} should see to
%    make its calculations from.
%    \begin{macrocode}
              \vskip \l_tmpa_skip
            }
          \group_end:
        }
    }
}
%    \end{macrocode}
%    Reimplement \cs{addpenalty} using the above macro:
%    \begin{macrocode}
\cs_set_protected:Npn \addpenalty #1 {
  \__kernel_add_penalty:n { \penalty #1 \scan_stop: }
}
%    \end{macrocode}
%    And a new command to add a penalty with some \cs{vfil} around
%    it. They cancel each other if no break is taken.
%    \begin{macrocode}
\cs_new_protected:Npn \addpenaltywithfil #1 {
  \__kernel_add_penalty:n { \vfil \penalty #1 \vfilneg }
}
%    \end{macrocode}
%    
%  \end{macro}
%
%
%
%
%
%  \begin{macro}{\if@openright}
%
%    \begin{macrocode}
\AddToHook{begindocument}{
  \ifcsname if@openright\endcsname
  \else
%    \end{macrocode}
%    Need to hide this a little if it is in fact already defined!
%    \begin{macrocode}
    \expandafter\newif\csname if@openright\endcsname
  \fi
}
%    \end{macrocode}
%  \end{macro}
%
%
%
%
%
%  \begin{template}{heading runin}
%    The \texttt{runin} template is very similar to the
%    \texttt{display} one.
%    \begin{macrocode}
\DeclareTemplateCode{heading}{runin}{9}
 {
  , name           = \l_@@_name_tl
  , level          = \l_@@_level_int
% next two not yet used
  , parent-name    = \l_@@_pname_tl
  , reset-counter  = \l_@@_reset_cnt_tl
%    \end{macrocode}
%
% \changes{0.9h}{2026-07-04}{Support a \texttt{force-unnumbered} key
%    (tagging/1473)}
%    \begin{macrocode}
  , force-unnumbered = \l_@@_unnumbered_bool
%    \end{macrocode}
%
%    It wouldn't make sense to have page placement with a runin heading since
%    there would be nothing to run into.
%    \begin{macrocode}
  , placement      = {
         page   = \typeout{ ^^JA~ runin~ page~ placement~ heading~makes~no~sense
                            (top~used)}
                  \tl_set:Nn \l_@@_placement_tl { top }
        ,top    = \@@_debug_typeout:n{ A~ top~ heading }
                  \tl_set:Nn \l_@@_placement_tl { top }
        ,normal = \@@_debug_typeout:n{ A~ normal~ heading }
                  \tl_set:Nn \l_@@_placement_tl { normal }
        ,ragged = \@@_debug_typeout:n{ A~ normal~ heading~ (ragged~ style) }
                  \tl_set:Nn \l_@@_placement_tl { ragged }
                    }
%    \end{macrocode}
%    
% \changes{0.9h}{2026-06-21}{Support \texttt{column-spanning} key
%    (tagging/1436)}
%    \begin{macrocode}
  , column-spanning = \l_@@_column_spanning_bool
%    \end{macrocode}
%    
%    \begin{macrocode}
  , mark-cmd       = \@@_mark_cmd:n
%    \end{macrocode}
%    In a runin heading you can't set up paragraph indentation of the
%    following paragraph (since that one is \enquote{run in}. But we
%    accept the key and just spit out a warning.
%    \ufi{this types out messages for all run-in headers! Therefore disabled for now}
%    \begin{macrocode}
  , para-indent    =  {
                       ,true  = %\typeout{para-indent~ setting~ ignored}
                       ,false = %\typeout{para-indent~ setting~ ignored}
                      }
  , before-vspace  = \l_@@_before_skip
  , penalty        = \l_@@_penalty_int
  , after-penalty-vspace  = \l_@@_after_penalty_skip
  , after-hspace   = \l_@@_after_skip
  , start-code     = \l_@@_start_code_tl
  , final-code     = \l_@@_final_code_tl
%    \end{macrocode}
%
%    \begin{macrocode}
  , prefix        = \l_@@_prefix_tl
  , punct         = \l_@@_punct_tl
%    \end{macrocode}
%
%    \begin{macrocode}
  , headformat-instance = \l_@@_headformat_instance_tl
%    \end{macrocode}
%
%    \begin{macrocode}
  , heading-decls  = \l_@@_heading_decls_tl
%    \end{macrocode}
%    
%    \begin{macrocode}
  , prefix-decls   = \l_@@_prefix_decls_tl
  , number-decls   = \l_@@_number_decls_tl
  , title-decls    = \l_@@_title_decls_tl
  , subtitle-decls = \l_@@_subtitle_decls_tl
  , quote-decls    = \l_@@_quote_decls_tl
%    \end{macrocode}
%
%    \begin{macrocode}
  , heading-format  = \@@_heading_format:n
  , prefix-format   = \@@_prefix_format:n
  , number-format   = \@@_number_format:n
  , punct-format    = \@@_punct_format:n
  , title-format    = \@@_title_format:n
  , subtitle-format = \@@_subtitle_format:n
  , quote-format    = \@@_quote_format:n
%
  , number-tag      = \l_@@_number_tag_tl
%    \end{macrocode}
%    
%    \begin{macrocode}
  , contents-extra = \l_@@_contents_extra_tl
}
{ \@@_show_arguments:nnnnnnnnn
       {#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}{#9}
%    \end{macrocode}
% store the value of \texttt{secnumdepth} so that we can change it locally.
%    \begin{macrocode}
  \tl_set:Ne\l_@@_saved_secnumdepth_tl{\int_use:N\c@secnumdepth}
%    \end{macrocode}
% define \cs{theheading}
%    \begin{macrocode}
  \tl_set_eq:Nc \theheading { the \l_@@_name_tl }
  \SetKnownTemplateKeys{heading}{runin}{#1}
%    \end{macrocode}
%    For now we don't support column-spanning in this template.
% \changes{0.9h}{2026-06-21}{Support \texttt{column-spanning} key
%    (tagging/1436)}
%    \begin{macrocode}
  \bool_if:NT \l_@@_column_spanning_bool
    { \@@_debug_typeout:n {column-spanning~ is~
        not~ (yet)~ supported~ for~ runin~ headings!}
      \bool_set_false:N \l_@@_column_spanning_bool
    }
%    \end{macrocode}
%
%    \begin{macrocode}
  \tl_if_empty:oT \l_@@_start_code_tl
    { \str_case:Vn \l_@@_placement_tl
      {
        { top }   { \tl_set:Nn \l_@@_start_code_tl {\clearpage } }
%    \end{macrocode}
%    
% \changes{0.9k}{2026-08-04}{Support \texttt{placement=ragged} (github/1844)}
%    \begin{macrocode}
        { ragged }
        { \cs_set_eq:NN \sec_add_penalty_with_possible_fil:n 
                        \sec_add_penalty_with_fil:n
        }   
      }
%    \end{macrocode}
%    All other cases want an empty \cs{l_@@_start_code_tl} so nothing
%    to do.
%    \begin{macrocode}
%      { \tl_clear:N \l_@@_start_code_tl }
    }
%
%    \end{macrocode}
%    Nothing at all to do (for now) for \cs{l_@@_final_code_tl}, it
%    should by default be empty in all heading placement. But maybe
%    we end up supporting further placements, so~\ldots
%    \begin{macrocode}
%  \tl_if_empty:oT \l_@@_final_code_tl
%   { \str_case:VnF \l_@@_placement_tl
%      {
%        { top } { \tl_clear:N \l_@@_final_code_tl }
%      }
%      { \tl_clear:N \l_@@_final_code_tl }
%   }
%    \end{macrocode}
%
%    \begin{macrocode}
  \@@_determine_penalty:
  \@@_determine_number_typesetting:N #2
  \@@_vertical_before_spacing:
%    \end{macrocode}
%    We are in vmode now and here is the point where we (with tagging)
%    can close a previous Sect structure and open the new one. We also
%    have to initialize the change in the para tagging here as run-in
%    titles typeset the heading in \cs{everypar}.
%    \begin{macrocode}
  \UseTaggingSocket{sec/end}{\int_use:N\l_@@_level_int}
  \UseTaggingSocket{sec/begin}
                   {{\int_use:N\l_@@_level_int}
                    {tag=\UseStructureName{sec/\int_use:N\l_@@_level_int}}
                   }
  \UseTaggingSocket{sec/title/init}{\int_use:N\l_@@_level_int}
  \def \@svsechd {
      \@@_debug_typeout:n{use~ 'headformat'~instance:~
                          \l_@@_headformat_instance_tl }
      \use:e {
        \UseInstance{headformat} { \l_@@_headformat_instance_tl }
                 { \exp_not:o \UnusedTemplateKeys }
                 { \exp_not:o { \l_@@_prefix_tl } }
                 { \exp_not:o { \l_@@_number_tl } }
                 { \exp_not:n { #3 } }
                 { \exp_not:o { \use_i:nn  #9 } }
                 { \exp_not:o { \use_ii:nn  #9 } }
      }
      \@@_handle_marks_etc:nnnnn {#4}{#5}{#6}{#7}{#8}
%    \end{macrocode}
% Restore \texttt{secnumdepth}
%    \begin{macrocode}
      \int_gset:Nn\c@secnumdepth{\l_@@_saved_secnumdepth_tl}
  }
  \@nobreakfalse
  \global\@noskipsectrue
  \everypar{%
    \if@noskipsec
       \global\@noskipsecfalse
       {\setbox\z@\lastbox}
       \clubpenalty\@M
       \@svsechd
       \unskip
%    \end{macrocode}
%  This tagging socket starts the \enquote{paragraph} after the run-in heading
%    \begin{macrocode}
       \UseTaggingSocket{sec/title/split}
       \skip_horizontal:N \l_@@_after_skip
    \else
      \clubpenalty \@clubpenalty
      \everypar{}%
    \fi
  }
%    \end{macrocode}
% --- prepare next paragraph (does nothing by default)
%    \begin{macrocode}
  \l_@@_final_code_tl
  \ignorespaces
}
%    \end{macrocode}
%  \end{template}
%
% \subsubsection{headformat templates code}
%
%  \begin{template}{headformat display}
%  This template creates a headformat where the number is on a line on its own.
%    \begin{macrocode}
\DeclareTemplateCode{headformat}{display}{6}
  % args: keys,prefix,number,title,subtitle,quotation
 {
  , heading-indent    = \l_@@_heading_indent_dim
  , order             = \l_@@_order_clist
  , separator-a       = name {l_@@_separator-a_tl}
  , separator-b       = name {l_@@_separator-b_tl}
  , separator-c       = name {l_@@_separator-c_tl}
  , separator-d       = name {l_@@_separator-d_tl}
 }
 {
  \@@_show_arguments:nnnnnn {#1}{#2}{#3}{#4}{#5}{#6}
%    \end{macrocode}
%    First evaluate any key setting done by the user (normally
%    supplied from the main heading instance.
%    \begin{macrocode}
  \SetTemplateKeys{headformat}{display}{#1}
%    \end{macrocode}
%
%    \begin{macrocode}
  \group_begin:
%    \end{macrocode}
%    \cs{parbox}es can be used within the title of a heading (or
%    withing it layout). \env{minipage} environments currently do not
%    work if used directly in the title because purify can't handle
%    that environment. But it can be  used as part of the layout
%    definition which is why we also add a suitable setting for it.
%    \begin{macrocode}
    \AssignTaggingSocketPlug{parbox/before}{heading}
    \AssignTaggingSocketPlug{minipage/before}{heading}
    \AssignTaggingSocketPlug{para/restore}{heading}
    \tagpdfparaOff
%
    \tl_set:Nn \l_@@_prefix_tl {#2}
    \tl_set:Nn \l_@@_number_tl {#3}
    \tl_set:Nn \l_@@_title_tl  {#4}
%
%    \end{macrocode}
% \changes{0.9f}{2026-05-23}{Removed \cs{normalcolor} as it adds a
%    break point and prevents color changes tagging/1215} TODO:
%    revisit if \cs{normalcolor} is needed, if yes, use as
%    \cs{SaveLastSkip} \cs{normalcolor} \cs{RestoreLastSkip}.
%    \begin{macrocode}
    \normalfont 
    \interlinepenalty \@M
    \l_@@_heading_decls_tl
%    \end{macrocode}
%    If there is a number and so a prefix, the link target should be
%    before the number.  We use for now the same place in the
%    unnumbered case.  TODO: If we put the target here we do not know
%    the height of the line and the target is perhaps not high
%    enough. And for unnumbered chapter it is perhaps too high.
%    Check!
%    \begin{macrocode}
    \bool_if:NTF \l_@@_unnumbered_bool
      { \dim_compare:nNnTF  \l_@@_heading_indent_dim < \c_zero_skip
          { \skip_horizontal:N \l_@@_heading_indent_dim
            \MakeLinkTarget[\l_@@_name_tl]{}
          }
          { \MakeLinkTarget[\l_@@_name_tl]{}
            \skip_horizontal:N \l_@@_heading_indent_dim
          }
      }
      { \dim_compare:nNnTF  \l_@@_heading_indent_dim < \c_zero_skip
          { \skip_horizontal:N \l_@@_heading_indent_dim
            \MakeLinkTarget{\l_@@_name_tl}
          }
          { \MakeLinkTarget{\l_@@_name_tl}
            \skip_horizontal:N \l_@@_heading_indent_dim
          }
      }
%
    \@@_heading_format:n {
      \template_process_order_clist:nnn
         { head }{ order }
         { number, prefix, punct, separator-a,
           separator-b, separator-c, separator-d, title, subtitle }
    }
    \par
  \group_end:
 }
%    \end{macrocode}
%  \end{template}
%
%
%
%    The the plugs we assigned to the tagging sockets in the template
%    need to be defined.
%    \begin{macrocode}
\NewTaggingSocketPlug{minipage/before}{heading}
  { \tag_mc_end_push:
    \bool_if:NT \l__tag_para_bool {\tag_struct_end:}
    \tag_struct_begin:n{tag=\UseStructureName{sec/minipage}}
  }
%    \end{macrocode}
%
%    \begin{macrocode}
\NewTaggingSocketPlug{parbox/before}{heading}
  { \tag_mc_end_push:
    \bool_if:NT \l__tag_para_bool {\tag_struct_end:}
    \tag_struct_begin:n{tag=\UseStructureName{sec/parbox}}
  }
%    \end{macrocode}
%    
%    \begin{macrocode}
\NewTaggingSocketPlug{para/restore}{heading}
%    \end{macrocode}
%    We have only structure names on heading levels for this, so for
%    now I use \texttt{heading-fragment} directly. Should probably
%    become \texttt{sec/fragment}.\fmi{resolve}
%    \begin{macrocode}
 { \AssignStructureRole{para/textblock}{heading-fragment}
   \bool_set_true:N\l__tag_para_flattened_bool
   \tagpdfparaOn
 }
%    \end{macrocode}
%    
%
%    
%
%
%
%  \begin{template}{headformat hang}
% This template creates a heading with a hanging number.
%    \begin{macrocode}
\DeclareTemplateCode{headformat}{hang}{6}
  % args: keys,prefix,number,title,subtitle,quotation
 {
  , heading-indent    = \l_@@_heading_indent_dim
  , order-hang        = name {l_@@_order-hang_clist}
  , order             = \l_@@_order_clist
  , separator-a       = name {l_@@_separator-a_tl}
  , separator-b       = name {l_@@_separator-b_tl}
  , separator-c       = name {l_@@_separator-c_tl}
  , separator-d       = name {l_@@_separator-d_tl}
 }
 {
  \@@_show_arguments:nnnnnn {#1}{#2}{#3}{#4}{#5}{#6}
%    \end{macrocode}
%    First evaluate any key setting done by the user (normally
%    supplied from the main heading instance.
%    \begin{macrocode}
  \SetTemplateKeys{headformat}{hang}{#1}
%    \end{macrocode}
%
%    \begin{macrocode}
  \group_begin:
%
    \AssignTaggingSocketPlug{parbox/before}{noop}
    \AssignTaggingSocketPlug{parbox/after}{noop}
    \AssignTaggingSocketPlug{para/restore}{noop}
    \tagpdfparaOff
%
    \tl_set:Nn \l_@@_prefix_tl {#2}
    \tl_set:Nn \l_@@_number_tl {#3}
    \tl_set:Nn \l_@@_title_tl  {#4}
%
%    \end{macrocode}
% \changes{0.9f}{2026-05-23}{Removed \cs{normalcolor} as it adds a break point 
%  and prevents color changes tagging/1215}
%    \begin{macrocode}
    \normalfont 
    \interlinepenalty \@M
    \l_@@_heading_decls_tl
    \noindent      
    \setbox\@tempboxa\hbox{{
%    \end{macrocode}
% The link target should be at the left text margin, or, if the section
% is moved into the margin, at the left of the number.
%    \begin{macrocode}
      \bool_if:NTF \l_@@_unnumbered_bool
        { \dim_compare:nNnTF  \l_@@_heading_indent_dim < \c_zero_skip
              { \skip_horizontal:N \l_@@_heading_indent_dim
                \MakeLinkTarget[\l_@@_name_tl]{}
              }
              { \MakeLinkTarget[\l_@@_name_tl]{}
                \skip_horizontal:N \l_@@_heading_indent_dim
              }
        }
        { \dim_compare:nNnTF  \l_@@_heading_indent_dim < \c_zero_skip
              { \skip_horizontal:N \l_@@_heading_indent_dim
                \MakeLinkTarget{\l_@@_name_tl}
              }
              { \MakeLinkTarget{\l_@@_name_tl}
                \skip_horizontal:N \l_@@_heading_indent_dim
              }
          \template_process_order_clist:nnn
              { head }{ order-hang }
              { number, prefix, punct, separator-a,
                separator-b, separator-c, separator-d, title, subtitle }
        }
    }}
    \hangindent \wd\@tempboxa
    \box\@tempboxa
    \template_process_order_clist:nnn
         { head }{ order }
         { number, prefix, punct, separator-a,
           separator-b, separator-c, separator-d, title, subtitle }
%    \end{macrocode}
%    \begin{macrocode}
    \par
  \group_end:
 }

%    \end{macrocode}
%  \end{template}
%
%
%
%
%
%
%  \begin{template}{headformat runin}
% This template creates a heading with a run-in title.
% Arguments are key-value, number, title, subtitle, quotation.
%    \begin{macrocode}
\DeclareTemplateCode{headformat}{runin}{6}
    % args: keys,prefix,number,title,subtitle,quotation
 {
  , heading-indent    = \l_@@_heading_indent_dim
  , order             = \l_@@_order_clist
  , separator-a       = name {l_@@_separator-a_tl}
  , separator-b       = name {l_@@_separator-b_tl}
  , separator-c       = name {l_@@_separator-c_tl}
  , separator-d       = name {l_@@_separator-d_tl}
}
 {
  \@@_show_arguments:nnnnnn {#1}{#2}{#3}{#4}{#5}{#6}
%    \end{macrocode}
%    First evaluate any key setting done by the user (normally
%    supplied from the main heading instance.
%    \begin{macrocode}
  \SetTemplateKeys{headformat}{hang}{#1}
%    \end{macrocode}
%
%    \begin{macrocode}
  \group_begin:
%
    \AssignTaggingSocketPlug{parbox/before}{noop}
    \AssignTaggingSocketPlug{parbox/after}{noop}
    \AssignTaggingSocketPlug{para/restore}{noop}
    \tagpdfparaOff
%
    \tl_set:Nn \l_@@_prefix_tl {#2}
    \tl_set:Nn \l_@@_number_tl {#3}
    \tl_set:Nn \l_@@_title_tl  {#4}
%    \end{macrocode}
%
% \changes{0.9f}{2026-05-23}{Removed \cs{normalcolor} as it adds a break point 
%  and prevents color changes tagging/1215}
%    \begin{macrocode}
    \normalfont 
%    \end{macrocode}
%    \fmi{Setting \cs{interlinepenalty} makes little sense I think
%    (but that's the way it was in \LaTeXe)}
%    \begin{macrocode}
    \interlinepenalty \@M
    \l_@@_heading_decls_tl
%    \end{macrocode}
% We must avoid that the sep between number and title is used in the unnumbered case.
% So we test with the boolean.
%    \begin{macrocode}
    \bool_if:NTF \l_@@_unnumbered_bool
      { \dim_compare:nNnTF  \l_@@_heading_indent_dim < \c_zero_skip
         { \skip_horizontal:N \l_@@_heading_indent_dim
           \MakeLinkTarget[\l_@@_name_tl]{}
         }
         { \MakeLinkTarget[\l_@@_name_tl]{}
           \skip_horizontal:N \l_@@_heading_indent_dim
         }
      }
      { \dim_compare:nNnTF  \l_@@_heading_indent_dim < \c_zero_skip
         { \skip_horizontal:N \l_@@_heading_indent_dim
           \MakeLinkTarget{\l_@@_name_tl}
         }
         { \MakeLinkTarget{\l_@@_name_tl}
           \skip_horizontal:N \l_@@_heading_indent_dim
         }
      }
    \template_process_order_clist:nnn
         { head }{ order }
         { number, prefix, punct, separator-a,
           separator-b, separator-c, separator-d, title, subtitle }
  \group_end:
}
%    \end{macrocode}
%  \end{template}
%
% \subsubsection{Internal commands used by the template code}
%
%  \begin{macro}{\@@_determine_penalty:}
%
%    \begin{macrocode}
\cs_new:Npn \@@_determine_penalty: {
%    \end{macrocode}
%    If a penalty was specified use it, otherwise use \cs{@secpenalty}.
%    \begin{macrocode}
  \int_compare:nNnT \l_@@_penalty_int = \c_max_int
    { \int_set:Nn \l_@@_penalty_int \@secpenalty }
}
%    \end{macrocode}
%  \end{macro}
%
%
%
%
%  \begin{macro}{\@@_determine_number_typesetting:N}
%
%    \begin{macrocode}
\cs_new:Npn \@@_determine_number_typesetting:N #1 {
%    \end{macrocode}
%    If \key{force-unnumbered} was set to true (i.e.,
%    \cs{l_@@_unnumbered_bool}) we don't do numbering.
%    If that is not the case then  using or suppressing a heading
%    number depends on the heading level
%    compared to the document value of \cs{c@secnumdepth}. If that
%    doesn't suppress the number then an explicit key or a star form
%    might still have suppressed it.
% \changes{0.9h}{2026-07-04}{Support a \texttt{force-unnumbered} key
%    (tagging/1473)}
%    \begin{macrocode}
  \bool_if:NF \l__head_unnumbered_bool
     { \bool_set:Nn \l_@@_unnumbered_bool
        { \bool_lazy_or_p:nn
          { \int_compare_p:nNn \l_@@_level_int > \c@secnumdepth }
          { \bool_if_p:N #1 }
        }
     }
%    \end{macrocode}
%    If we aren't producing a heading with a number we set
%    \cs{c@secnumdepth} to a low number (it is reset at the end of the template
%    code)
%    \begin{macrocode}
  \bool_if:NTF \l_@@_unnumbered_bool
    { \int_gset:Nn\c@secnumdepth{-99}
%    \end{macrocode}
%    and we set \cs{l_@@_number_tl}, \cs{l_@@_prefix_tl}, and
%    \cs{l_@@_punct_tl} to do nothing.
%    \begin{macrocode}
      \tl_set:Nn \l_@@_number_tl { \NoValue }
      \tl_set:Nn \l_@@_prefix_tl { \NoValue }
      \tl_set:Nn \l_@@_punct_tl  { \NoValue }
    }
%    \end{macrocode}
%    Otherwise the heading counter is incremented and a formatted
%    version of the number plus any following (or preceding) space is
%    stored in \cs{l_@@_number_tl}.
%    We use the kernel version of \cs{refstepcounter} as anchors are
%    handled elsewhere. 
%    \begin{macrocode}
    {
      \@kernel@refstepcounter{ \l_@@_name_tl }
      \tl_set:Nn \l_@@_number_tl { \theheading }
    }
}
%    \end{macrocode}
%  \end{macro}



%  \begin{macro}{\@@_vertical_before_spacing:}
%
%    \begin{macrocode}
\cs_new:Npn \@@_vertical_before_spacing: {
  \tl_if_blank:VTF \l_@@_start_code_tl
     { \if@noskipsec \leavevmode \fi
       \par
       \if@nobreak
         \everypar{}
       \else
%    \end{macrocode}
%    Normally the penalty is added with \cs{addpenalty} but in some
%    cases (\texttt{placement=ragged}) we want to use a variant of
%    \cs{filbreak} instead. So we use
%    \cs{sec_add_penalty_with_possible_fil:n} which is either equal to
%    \cs{addpenalty} or  to \cs{sec_add_penalty_with_fil:n} depending
%    on the setup.
% \changes{0.9k}{2026-08-04}{Support \texttt{placement=ragged} (github/1844)}
%    \begin{macrocode}
         \sec_add_penalty_with_possible_fil:n
            \l_@@_penalty_int
         \addvspace  \l_@@_before_skip
%    \end{macrocode}
% The \cs{vspace*} inserts a rule, we insert therefore the
% skip only if it is different to zero.
%    \begin{macrocode}
         \dim_compare:nNnF{\l_@@_after_penalty_skip}={0pt}
          { \vspace*    \l_@@_after_penalty_skip }
       \fi
     }
     {
       \l_@@_start_code_tl
%    \end{macrocode}
%    If \cs{l_@@_start_code_tl} holds code, we assume that it handles
%    pagination, e.g., a \cs{clearpage}, etc. We therefore only add
%    the skip that would follow the penalty.
%
%    And we do nothing at all when we have a spanning heading. Then
%    this vspace is done inside \cs{@topnewpage}.
% \changes{0.9h}{2026-06-21}{Support \texttt{column-spanning} key
%    (tagging/1436)}
%    \begin{macrocode}
       \bool_if:NF \l_@@_column_spanning_bool
            {
              \dim_compare:nNnF{\l_@@_after_penalty_skip}={0pt}
                  { \vspace*    \l_@@_after_penalty_skip }
            }
     }
}
%    \end{macrocode}
%  \end{macro}
%
% \begin{macro}{\addcontentslinebookmark,\addcontentslinebookmarkOff,
% \addcontentslinebookmarkOn}
%    
%    We want to be able to control bookmarks independently from the
%    toc entries, and also want to disable a bookmark by setting it to
%    empty. For this we need some command to handle the bookmark
%    command.
%    \begin{macrocode}
\newcommand\addcontentslinebookmark[3]{}
\newcommand\addcontentslinebookmarkOff{}
\newcommand\addcontentslinebookmarkReset{}
\providecommand\texorpdfstring[2]{#1}
%    \end{macrocode}
% This can go once hyperref is updated (ufi,2026-04-21):
%    \begin{macrocode}
\AddToHook{package/hyperref/after}
 {
   \RenewCommandCopy\addcontentslinebookmark
                    \Hy@addcontentsline@addbookmark
   \renewcommand\addcontentslinebookmarkOff
     { \ifHy@bookmarks
       \let\addcontentslinebookmarkReset
           \Hy@bookmarkstrue
       \else
         \let\addcontentslinebookmarkReset\relax
       \fi 
       \Hy@bookmarksfalse
     }
 }
%    \end{macrocode}
% \end{macro}
%
%  \begin{macro}{\@@_handle_marks_etc:nnnnn}
% Arg 1: toc entry, arg 2: mark, arg 3: bookmark, arg 4: nameref, arg 5: label code
%    \begin{macrocode}
\cs_new:Npn \@@_handle_marks_etc:nnnnn #1#2#3#4#5 {
%
  \tl_set:Nn\@currentlabelname{#4}
  \IfBlankF {#2}
     { \@@_mark_cmd:n { #2 } }
  \IfBlankTF {#1}
%    \end{macrocode}
%    If the toc entry is empty the bookmarks must be set without
%    \cs{addcontentsline}.
%    \begin{macrocode}
    { \IfBlankF{#3}
       {
        \addcontentslinebookmark{toc}{\l__head_name_tl}
          {
            \bool_if:NF \l_@@_unnumbered_bool
              {
                \protect\numberline{ \use:c{ the \l_@@_name_tl } }
              }
            #3
          }
       }
    }
%    \end{macrocode}
% If the bookmark entry is empty we must disable the bookmarks locally
% before the \cs{addcontentsline} and reenable afterwards. We do not
% check if they are already disabled, perhaps later.
%    \begin{macrocode}
    { \IfBlankT{#3}{\addcontentslinebookmarkOff}
      \addcontentsline{toc}{ \l_@@_name_tl }
        {
          \bool_if:NF \l_@@_unnumbered_bool
            {
              \protect\numberline{ \use:c{ the \l_@@_name_tl } }
            }
%    \end{macrocode}
% We use \cs{texorpdfstring} to separate toc and bookmark text.
%    \begin{macrocode}
          \texorpdfstring{#1}{#3}
        }
      \addcontentslinebookmarkReset
    }
%    \end{macrocode}
%    Some headings (like \cs{chapter}) also want to write stuff to
%    other contents files like \texttt{.lot} or
%    \texttt{.lof}.\fmi{perhaps this should have a hook for packages}
%    \begin{macrocode}
    \l_@@_contents_extra_tl
%    \end{macrocode}
%    We can always run the label code (it might be empty)
%    \begin{macrocode}
    \@@_debug_typeout:n{--->~label(s):~ \exp_not:n{#5}}
    #5
}
%    \end{macrocode}
%  \end{macro}
%
%
%
%
% \subsection{Support for legacy classes and packages}
%
%   If we define heading commands in the kernel (or in the tagging
%    code) using
% \begin{verbatim}
%   \DeclareDocumentCommand \section {s ={shorttitle}o m}
%       { \ParseLaTeXeHeading {section} {#1} {#2} {#3} }
% \end{verbatim}
%   then this gets overwritten by every class right now.
%
%    If we redeclare them after the class was loaded then
%    we overwrite the layout of legacy classes (done, for example, with
%    \cs{@startsection}). New classes that use the above interface
%    would be fine though, as long as we have declared the instances
%    before the class is loaded.
%
%    So to make legacy classes work with their existing layout, we
%    should not (ever) overwrite \cs{section} but let the class
%    definition call
%    \cs{@startsection} which would then set up suitable instances and
%    only after that call \cs{ParseLaTeXeHeading}.
%
%    However, that would mean a \enquote{new} class like ltx-article
%    would need to add the above definition and declare or edit the
%    corresponding instances, instead of just declaring or adding the
%    instances.
%
%    A perhaps better alternative could be to delay the definition of
%    \cs{section} and friends until after the class got loaded and
%    then take a peak at \cs{section} as defined by the class and if
%    it contains a \cs{@startsection} call, leave it alone and
%    otherwise overwrite it. And if the class hasn't defined
%    \cs{section} (because it is a new class) declare it. Of course
%    that means \cs{section} would then be available with every class
%    even if it was never meant to contain headings.
%
%    But while writing this up, I start to think it is best if a new
%    class defines both the document interface (i.e., the above
%    command) as well as the layout (declare the instances) and the
%    kernel does neither. It has been this way before and it is
%    consistent, so why change.
%
%    The situation with headings defined via \cs{secdef} is worse: we
%    don't have a nice handle as with \cs{@startsection} so there is
%    no real way other than through static analysis to set up such
%    a heading in the new template style. So all that is possible (I
%    think) is that after the class has been loaded, we look if the
%    usual candidates (\cs{part} and \cs{chapter}) have been defined
%    and overwrite them with a standard layout. That would make the
%    class tagging aware but, of course, would likely change the
%    layout.
%
%    The current implementation
%    \begin{itemize}
%    \item provides instance for the heading commands of the standard classes;
%    \item declares the heading commands for the standard classes with
%    the new interfaces through class hooks;
%    \item other classes call the adapted \cs{@startsection}; other headings
%    command like \cs{part} or \cs{chapter} are not handled and must be setup
%    individually.
%    \end{itemize}
%
% \subsubsection{Instances (sample/default definitions)}
%
%
%  \begin{instance}{heading part}
%  An instance suitable for \cls{book} and \cls{report}. An instance suitable
%  for \cls{article} is above in the hook.
%    \begin{macrocode}
\DeclareInstance{heading}{part}{display}
{
  , name          = part
  , level         = -1
  , placement     = page
  , after-penalty-vspace = 0pt
  , prefix        = \partname
  , number-format = \thepart
  , heading-decls = \centering\bfseries\huge
  , title-decls   = \Huge
  , headformat-instance = part
  , mark-cmd      = \partmark {#1}
}
%    \end{macrocode}
%  \end{instance}
%
%  \begin{instance}{heading chapter}
%
%    \begin{macrocode}
\DeclareInstance{heading}{chapter}{display}
{
  , name           = chapter
  , level          = 0
  , placement      = top
  , column-spanning = true
  , after-penalty-vspace = 50pt
  , after-vspace   = 40pt
  , prefix         = \@chapapp
  , number-format  = \thechapter
  , heading-decls  = \raggedright \parindent0pt \bfseries \huge
  , title-decls    = \Huge
  , headformat-instance = chapter
  , mark-cmd       = \chaptermark {#1}
  , contents-extra = \addtocontents{lof}{\addvspace{10pt}}
                     \addtocontents{lot}{\addvspace{10pt}}
}
%    \end{macrocode}
%  \end{instance}
%
%
%  \begin{macro}{\@chapapp}
%    To improve compatibility with classes that use \cs{secdef} but
%    don't provide a definition for \cs{@chapapp} used in the
%    \key{prefix} key above, we define this command if
%    necessary. Otherwise such a class would error if \cs{chapter} is
%    used.
% \changes{0.9h}{2026-07-08}{Define \cs{@chapapp}, if necessary (tagging/1482)}
%    \begin{macrocode}
\AtBeginDocument{
  \cs_if_exist:NF \@chapapp { \cs_new:Npn \@chapapp {Chapter} } }
%    \end{macrocode}
%  \end{macro}
%  \begin{instance}{heading section}
%
%    \begin{macrocode}
\DeclareInstance{heading}{section}{display}
{
  , name          = section
  , level         = 1
  , mark-cmd      = \sectionmark {#1}
  , before-vspace = 3.5ex plus 1ex minus .2ex
  , after-vspace  = 2.3ex plus .2ex
  , heading-decls = \normalfont\Large\bfseries
  , headformat-instance = section
}
%    \end{macrocode}
%  \end{instance}
%
%
%  \begin{instance}{heading subsection}
%
%    \begin{macrocode}
\DeclareInstance{heading}{subsection}{display}
{
  , name          = subsection
  , parent-name   = section
  , level         = 2
  , mark-cmd      = \subsectionmark {#1}
  , before-vspace = 3.25ex plus 1ex minus .2ex
  , after-vspace  = 1.5ex plus .2ex
  , heading-decls = \normalfont\large\bfseries
  , headformat-instance = subsection
}
%    \end{macrocode}
%  \end{instance}
%
%
%  \begin{instance}{heading subsubsection}
%
%    \begin{macrocode}
\DeclareInstance{heading}{subsubsection}{display}
{
  , name          = subsubsection
  , parent-name   = subsection
  , level         = 3
  , before-vspace = 3.25ex plus 1ex minus .2ex
  , after-vspace  = 1.5ex plus .2ex
  , heading-decls = \normalfont\normalsize\bfseries
  , headformat-instance = subsubsection
}
%    \end{macrocode}
%  \end{instance}
%
%  \begin{instance}{heading paragraph}
%
%    \begin{macrocode}
\DeclareInstance{heading}{paragraph}{runin}
{
  , name          = paragraph
  , parent-name   = subsubsection
  , level         = 4
  , before-vspace = 3.25ex \@plus1ex \@minus.2ex
  , after-hspace  = 1em
  , heading-decls = \normalfont\normalsize\bfseries
  , mark-cmd      =  \paragraphmark {#1}
  , headformat-instance = paragraph

}
%    \end{macrocode}
%  \end{instance}
%
%
%
%  \begin{instance}{heading subparagraph}
%
%    \begin{macrocode}
\DeclareInstance{heading}{subparagraph}{runin}
{
  , name          = subparagraph
  , parent-name   = paragraph
  , level         = 5
  , before-vspace = 3.25ex \@plus1ex \@minus .2ex
  , after-hspace  = 1em
  , heading-decls = \normalfont\normalsize\bfseries
  , mark-cmd      =  \subparagraphmark {#1}
  , headformat-instance = subparagraph

}
%    \end{macrocode}
%  \end{instance}
%
%  \begin{instance}{headformat part}
%  \begin{instance}{headformat chapter}
%    The \insttype{headformat} instances for part and chapter use the
%    \texttt{display} template with identical settings by default,
%    so one is made a copy of the other to speed up loading.
%    \begin{macrocode}
\DeclareInstance{headformat}{part}{display}
{
  , heading-indent    = 0pt
  , separator-a       = \nobreakspace                % between prefix and number
  , separator-b       = \par \nobreak \vspace{20pt}  % between label block and title
}
%    \end{macrocode}
%    
%    \begin{macrocode}
\DeclareInstanceCopy{headformat}{chapter}{part}
%    \end{macrocode}
%  \end{instance}
%  \end{instance}
%
%
%  \begin{instance}{headformat std}
%  \begin{instance}{headformat section}
%  \begin{instance}{headformat subsection}
%  \begin{instance}{headformat subsubsection}
%    Similarly, by default the instances for section, subsection, and
%    subsubsection are all using the \texttt{hang} template and the
%    same key values as the \texttt{std} instance, so they
%    are all made a copy of that one.
%    \begin{macrocode}
\DeclareInstance{headformat}{std}{hang}
{
  , heading-indent = 0pt
}
%    \end{macrocode}
%    
%    \begin{macrocode}
\DeclareInstanceCopy{headformat}{section}{std}
\DeclareInstanceCopy{headformat}{subsection}{std}
\DeclareInstanceCopy{headformat}{subsubsection}{std}
%    \end{macrocode}
%  \end{instance}
%  \end{instance}
%  \end{instance}
%  \end{instance}
%
%
%  \begin{instance}{headformat paragraph}
%  \begin{instance}{headformat subparagraph}
%    In contrast, paragraph and subparagraph differ even though both
%    use the \texttt{runin} template.
%    \begin{macrocode}
\DeclareInstance{headformat}{paragraph}{runin}
{
  , heading-indent = 0pt
}
%    \end{macrocode}
%
%    \begin{macrocode}
\DeclareInstance{headformat}{subparagraph}{runin}
{
  , heading-indent = \parindent
}
%    \end{macrocode}
%  \end{instance}
%  \end{instance}
%
%
%  \begin{instance}{headformat section-special}
%
%    A special headformat instance for testing. It can be used with
%    \verb+\section[headformat-instance=section-special]{bla}+
%    \begin{macrocode}
\DeclareInstance{headformat}{section-special}{hang}
{
  , heading-indent = 4em
%%%%  , title-format   = {#1!}   % no longer
}
%    \end{macrocode}
%  \end{instance}
%

% \subsubsection{New \cs{@startsection}}
%
%  \begin{macro}{\@startsection}
%    To support legacy classes that implement headings through a call
%    to \cs{@startsection} we redefine this command to generate a
%    \text{heading} instance from the arguments of \cs{@startsection} if
%    it doesn't yet exist and then use this instance to typeset the
%    heading.
%
%    NOTE: To handle legacy definition like
%    \verb+{\normalfont\Large\bfseries\MakeUppercase}+ in the last argument
%    it copies this argument both to
%    \key{heading-decls} and to \key{title-format}.
%
%    \begin{macrocode}
\DeclareDocumentCommand \@startsection {mmmmmm s ={shorttitle}o m}{
%    \end{macrocode}
%    If there already exists an instance \texttt{\#1-@startsection} then arguments
%    2--6 are ignored and we simply call that instance. Otherwise we
%    go through the process to set it up. This allows classes, packages
%    and authors to create and overwrite definitions with \cs{@startsection}.
%    But after a call to a command using the \cs{@startsection}
%    the instances are created. It is therefore not possible to redefine the command
%    after a first use or to create two commands using the same level, e.g. \cs{section}
%    and \cs{specialsection}. Such setups should use the new interfaces to declare
%    heading commands.
%    \begin{macrocode}
  \IfInstanceExistsF{heading}{#1-@startsection}{
%    \end{macrocode}
%
%    \begin{macrocode}
    \@@_debug_typeout:n{Info:~ setting~ up~ instances~ for~
                       legacy~ \string\@startsection}
%    \end{macrocode}
%    \cs{@startsection} supported the use of a macro
%    with one argument as the last token in its \meta{style}
%    argument, for example, \cs{MakeUppercase} to make the whole title
%    uppercase. To support that we need to take a look at \texttt{\#6}
%    and if that ends in such a macro split it off, so that we can put
%    the first tokens into \key{heading-decls} and this last token
%    into \key{title-format}. This is what the next call prepares for:
% \changes{0.9m}{2026-08-12}{Split style argument of
%    \cs{@startsection} based off type of last token (tagging/1521)}
%    \begin{macrocode}
    \@@_prep_decls_and_format_from_tl:nNN {#6}
       \l_@@_heading_decls_tl
       \l_@@_title_format_tl
%    \end{macrocode}
%    In the \LaTeXe{} logic a negative \#4 means we do not indent the
%    following paragraph \ldots
%
%    It is okay to change any \texttt{em} or \texttt{ex}
%    specifications to real \texttt{pt} values here, because this code
%    is executed in the same place where \cs{@startsection} is
%    normally executed and inside the original definitions such
%    assignments happen as well, before there is any font change
%    happening for \#4 and \#5.
%    \begin{macrocode}
    \@tempskipa #4\relax
    \@afterindenttrue
    \ifdim \@tempskipa <\z@
      \@tempskipa -\@tempskipa
      \@afterindentfalse
    \fi
%    \end{macrocode}
%    \ldots\ and a negative \#5 means we should produce a runin heading.
%    \begin{macrocode}
    \@tempskipb #5\relax
    \ifdim \@tempskipb>\z@
      \use:e {
        \DeclareInstance{heading}{#1-@startsection}{display}{
         , name          = #1
         , level         = #2
         , mark-cmd      = \exp_not:c {#1mark} {##1}
         , before-vspace = \the\@tempskipa
         , after-vspace  = \the\@tempskipb
         , para-indent   = \if@afterindent true \else false\fi
%    \end{macrocode}
%    Argument \texttt{\#6} contains the declarations for the whole
%    heading but it is allowed that the last token is a macro with one
%    argument that receives the heading text as its argument.
%    This is why we have split off the last token above, in case it
%    contained a macro with one argument. That token is then used as
%    the \key{title-format}.  We end this key value in \cs{par} if we
%    are in a display instance.          
%    \begin{macrocode}
         , heading-decls = \exp_not:o \l_@@_heading_decls_tl
         , title-format  = \exp_not:o \l_@@_title_format_tl {##1}
                           \exp_not:N \par
%    \end{macrocode}
%    \begin{macrocode}
         , headformat-instance = #1-@startsection
      }}
      \DeclareInstance{headformat}{#1-@startsection}{hang}{heading-indent = #3}
%    \end{macrocode}
%    We can expect that the instance \texttt{\#1-@startsection} is not
%    set up by the user if \texttt{\#1-@startsection} isn't, so no check.
%    \begin{macrocode}
    \else
      \@tempskipb=-\@tempskipb
      \use:e {
       \DeclareInstance{heading}{#1-@startsection}{runin}{
         , name          = #1
         , level         = #2
         , mark-cmd      = \exp_not:c {#1mark} {##1}
         , before-vspace = \the\@tempskipa
         , after-hspace  = \the\@tempskipb
         , heading-decls = \exp_not:o \l_@@_heading_decls_tl
%    \end{macrocode}
%    In a runin instance \key{title-format} should not end in \cs{par}!
%    \begin{macrocode}
         , title-format  = \exp_not:o \l_@@_title_format_tl {##1}
         , headformat-instance = #1-@startsection
      }}
    \DeclareInstance{headformat}{#1-@startsection}{runin}{heading-indent = #3}
    \fi
  }
  \ParseLaTeXeHeading {#1-@startsection}{#7}{#8}{#9}
}
%    \end{macrocode}
%  \end{macro}
%
%
%
%  \begin{macro}{\@@_prep_decls_and_format_from_tl:nNN}
%    Examine \texttt{\#1}. If the last token is a macro with one
%    argument put it in \texttt{\#3} and the remainder of \texttt{\#1}
%    into \texttt{\#2}.
%    Otherwise, put \cs{use:n} in \texttt{\#3} and all of \texttt{\#1}
%    in \texttt{\#2}.
% \changes{0.9m}{2026-08-12}{Provide command to split off last token of
%    a token list if it is a macro with one argument (tagging/1521)}
%    \begin{macrocode}
\cs_new:Npn \@@_prep_decls_and_format_from_tl:nNN #1#2#3
  { \tl_set:Nn #3 { \use:n }
    \exp_args:Ne
    \@@_prep_decls_and_auxi:nnNN
        { \tl_reverse:n {#1} } {#1} #2 #3
  }
%    \end{macrocode}
%
%    \begin{macrocode}
\cs_new:Npn \@@_prep_decls_and_auxi:nnNN #1#2#3#4
  { \tl_if_head_is_N_type:nTF {#1}
      { \@@_prep_decls_and_auxii:nNwNN {#2} #1 \q_stop #3 #4 }
      { \tl_set:Nn #3 {#2} }
  }
%    \end{macrocode}
%
%    \begin{macrocode}
\cs_new:Npn \@@_prep_decls_and_auxii:nNwNN #1#2#3 \q_stop #4 #5
  { \token_if_macro:NTF #2
      { \exp_args:Ne
        \@@_prep_decls_and_auxiii:nnNnNN
          { \cmd_arg_spec:N #2 } {#1} #2 {#3} #4 #5
      }
      { \tl_set:Nn #4 {#1} }
  }
%    \end{macrocode}
%
%    \begin{macrocode}
\cs_new:Npn \@@_prep_decls_and_auxiii:nnNnNN #1#2#3#4#5#6 {
  \bool_lazy_any:nTF
    {
%    \end{macrocode}
%    This tests for macros with one argument and defined by \cs{def}
%    or similar.
%    \begin{macrocode}
      { \str_if_eq_p:ee { \cs_parameter_spec:N #3 } { \c_hash_str 1 } }
%    \end{macrocode}
%    For those defined with \cs{NewDocumentCommand} we need to look at
%    the signature instead. We also accept macros with one optional
%    argument first followed by a mandatory one.
%    \begin{macrocode}
      { \str_if_eq_p:nn {#1} { m } }
      { \str_if_eq_p:nn {#1} { +m } }
      { \str_if_eq_p:nn {#1} { O{} m } }
      { \str_if_eq_p:nn {#1} { O{} +m } }
%    \end{macrocode}
%    Another possibility are macros declared with \cs{DeclareRobustCommand}.
%    \begin{macrocode}
      { \bool_lazy_and_p:nn
          { \cs_if_exist_p:c { \cs_to_str:N #3 \c_space_tl } }
          { \str_if_eq_p:ee
              { \cs_parameter_spec:c { \cs_to_str:N #3 \c_space_tl } }
              { \c_hash_str 1 }
          }
      }
      { \bool_lazy_and_p:nn
          { \cs_if_exist_p:c { \token_to_str:N #3 \c_space_tl } }
          { \str_if_eq_p:ee
              { \cs_parameter_spec:c { \token_to_str:N #3 \c_space_tl } }
              { [ \c_hash_str 1 ] \c_hash_str 2 }
          }
      }
    }
    { \tl_set:Ne #5 { \tl_reverse:n {#4} }
      \tl_set:Nn #6 {#3}
    }
    { \tl_set:Nn #5 {#2} }
}
%    \end{macrocode}
%    
%    \begin{macrocode}
\cs_generate_variant:Nn \cs_parameter_spec:N { c }
%    \end{macrocode}
%  \end{macro}
%
%
% Some classes redefine \cs{@startsection} and then our redefinition is lost. So we
% reinstate it
%    \begin{macrocode}
\NewCommandCopy\kernel@startsection\@startsection
\AddToHook{class/after}[head/@startsection]
  {\RenewCommandCopy\@startsection\kernel@startsection}
%    \end{macrocode}
%
%
%  \subsubsection{New \cs{secdef}}
% The command maps standard \cs{secdef} definition of \cs{part} and \cs{chapter} to
% the new interface. Unknown heading commands warn (or error if tagging is active) and
% then call the old commands.
% \begin{macro}{\secdef}
%    \begin{macrocode}
\RenewDocumentCommand\secdef{mmsO{#5}m}
 {
  \str_case:enF {\cs_to_str:N#1}
   {
    {@part}
     { \IfNoValueTF{#4}
        {\ParseLaTeXeHeading{part}{#3} {start-code=\relax} {#5}}
        {
         \@@_process_shorttitle:nN{#4}\l_@@_tmpa_tl
         \ExpandArgs{nne}\ParseLaTeXeHeading{part}{#3}
                    {start-code=\relax,\exp_not:o{\l_@@_tmpa_tl}} {#5}
        }
      \@latex@warning{\noexpand\secdef~ detected~ in~ \noexpand\part
          command.\MessageBreak
         \noexpand\part~will~be~redefined~to~use~templates.\MessageBreak
         This~may~change~the~layout!}
       \DeclareDocumentCommand \part {s ={shorttitle}o m}
         { \ParseLaTeXeHeading {part} {##1} {##2} {##3} }
     }
    {@chapter}
     { \IfNoValueTF{#4}
        { \ParseLaTeXeHeading{chapter}{#3} {#4} {#5} }
        {
          \@@_process_shorttitle:nN{#4}\l_@@_tmpa_tl
          \ExpandArgs{nno}\ParseLaTeXeHeading{chapter}{#3}
                                             {\l_@@_tmpa_tl} {#5}
        }
      \@latex@warning{\noexpand\secdef~ detected~ in~
         \noexpand\chapter command.\MessageBreak
         \noexpand\chapter~ will~ be~ redefined~ to~ use~
         templates.\MessageBreak
         This~may~change~the~layout!}
       \DeclareDocumentCommand \chapter {s ={shorttitle}o m}
        { \ParseLaTeXeHeading {chapter} {##1} {##2} {##3} }
     }
   }
   {
    \tag_if_active:TF\@latex@error\@latex@warning
        {\noexpand\secdef~ with~ unknown~ argument~ \noexpand#1
          found.\MessageBreak
      The~command~can~not~be~adapted~on~the~fly~to~support~tagging.\MessageBreak
      The~heading~command~using~this~\noexpand\secdef~should~be~
                 reimplemented\MessageBreak with~templates}{}
    \IfBooleanTF{#3}{#2{#5}}{#1[#4]{#5}}
   }
 }
%    \end{macrocode}
% A helper command to reprocess the argument as key-val
%    \begin{macrocode}
\NewDocumentCommand\@@_process_shorttitle:nN{={shorttitle}mm}
 { \tl_set:Nn#2{#1} }
%    \end{macrocode}
% \end{macro}
% 
% 
% 
%  \subsubsection{Core \LaTeX{}}
% 
%   We define here as an example the heading commands with the new
%   interfaces for the three standard classes.
%    
%    \begin{macrocode}
\AddToHook{class/article/after}[head/example]
 {
   \DeclareInstance{heading}{part}{display}
     {
      , name          = part
      , level         = -1
      , before-vspace = 4ex
      , after-vspace  = 3ex
      , mark-cmd      = \partmark {#1}
      , prefix        = \partname
      , punct         = 
      , heading-decls = \raggedright\bfseries\Large
      , title-decls   = \huge
      , headformat-instance = part
     }
   \DeclareInstance{headformat}{part}{display}
     {
       , heading-indent    = 0pt
       , separator-a       = \nobreakspace
       , separator-b       = \par \nobreak \vspace{20pt}
     }
   \DeclareDocumentCommand \part {s ={shorttitle}o m}
      { \ParseLaTeXeHeading {part} {#1} {#2} {#3} }
   \@@_setup_default_heading:
 }
%    \end{macrocode}
% \changes{0.9b}{2026-01-26}{Correct chapter definition, tagging/1984}
%    \begin{macrocode}
\AddToHook{class/report/after}[head/example]
 {
    \DeclareDocumentCommand \part {s ={shorttitle}o m}
      { \ParseLaTeXeHeading {part} {#1} {#2} {#3} }
    \DeclareDocumentCommand \chapter {s ={shorttitle}o m}
      {
        \ParseLaTeXeHeading {chapter}{#1} {#2} {#3}
      }
    \@@_setup_default_heading:
 }
\AddToHook{class/book/after}[head/example]
 {
    \DeclareDocumentCommand \part {s ={shorttitle}o m}
      { \ParseLaTeXeHeading {part} {#1} {#2} {#3} }
    \DeclareDocumentCommand \chapter {s ={shorttitle}o m}
      {
        \if@mainmatter
         \ParseLaTeXeHeading {chapter}{#1} {#2} {#3}
        \else
         \IfBooleanTF{#1}
          {% starred:
           \ParseLaTeXeHeading {chapter}{\BooleanTrue} {#2} {#3}
          }
          {\IfNoValueTF{#2}
            {\ParseLaTeXeHeading {chapter}{\BooleanTrue} {shorttitle={#3}} {#3}}
            {\ParseLaTeXeHeading {chapter}{\BooleanTrue} {#2} {#3}}
          }
        \fi
      }
    \@@_setup_default_heading:
 }
%    \end{macrocode}
%
%
%
%    \begin{macrocode}
\cs_new_protected:Npn \@@_setup_default_heading:
 {
%    \end{macrocode}
%  \begin{macro}{\section}
%
%    \begin{macrocode}
   \DeclareDocumentCommand \section {s ={shorttitle}o m}
     { \ParseLaTeXeHeading {section} {##1} {##2} {##3} }
%    \end{macrocode}
%  \end{macro}
%
%  \begin{macro}{\subsection}
%
%    \begin{macrocode}
   \DeclareDocumentCommand \subsection {s ={shorttitle}o m}
     { \ParseLaTeXeHeading {subsection} {##1} {##2} {##3} }
%    \end{macrocode}
%  \end{macro}
%
%  \begin{macro}{\subsubsection}
%
%    \begin{macrocode}
   \DeclareDocumentCommand \subsubsection {s ={shorttitle}o m}
     { \ParseLaTeXeHeading {subsubsection} {##1} {##2} {##3}  }
%    \end{macrocode}
%  \end{macro}
%
%  \begin{macro}{\paragraph}
%
%    \begin{macrocode}
   \DeclareDocumentCommand \paragraph {s ={shorttitle}o m}
     { \ParseLaTeXeHeading {paragraph} {##1} {##2} {##3} }
%    \end{macrocode}
%  \end{macro}
%
%  \begin{macro}{\subparagraph}
%
%    \begin{macrocode}
   \DeclareDocumentCommand \subparagraph {s ={shorttitle}o m}
     { \ParseLaTeXeHeading {subparagraph} {##1} {##2} {##3} }
 } %end of command
%    \end{macrocode}
%  \end{macro}

%    \begin{macrocode}
%</package>
%    \end{macrocode}
%
%
%
%
%
%
% \section{Issues and problems noticed along the way}
%
% \subsection{Local \cs{DeclareInstance}}
%
%    \cs{DeclareInstance} does its declaration locally. That might be the
%    right decision (or not) but we need to make sure that it in that
%    case all of the declaration is local.
%
%    One potential problem with that is that it might allocate \TeX{}
%    registers.
%
%    The problem showed up in the redefinition of \cs{@startsection},
%    because in the current document some headings are local to an
%    environment, so things get redeclared over and over again.
%
% \subsection{\cs{SetCurrentTemplateKeys}}
%
%    Furthermore, I think I would like to have some
%    \cs{SetCurrentTemplateKeys} where one does not have to specify
%    the type nor the template name, because that is how it is always
%    used (by me).
%
% \subsection{O-expansion of \cs{UseInstance} arguments}
%
%    Whenever a template code calls a sub-instance and that
%    sub-instance takes arguments, then the values for these arguments
%    are typically inside tokenlists or registers so that for
%    efficiency (and sometimes as a total must) one has to o-expand
%    all arguments. While that can be coded somehow, e.g.,
% \begin{verbatim}
%   \use:e {
%     \UseInstance{headformat} { \l_@@_headformat_instance_tl }
%                 { \exp_not:o \UnusedTemplateKeys }
%                 { \exp_not:o { \l_@@_number_tl } }
%                 { \exp_not:n { #3 } }
%                 { \exp_not:o { \use_i:nn  #9 } }
%                 { \exp_not:o { \use_ii:nn  #9 } }
%   }
% \end{verbatim}
%
%    it would be better to have a version of \cs{UseInstance} that
%    does this automatically. No suggestion for a name.
%
%
%
% \subsection{Switch \cs{openright} is not defined by core}
%
%   I think this should change and it might be enough to just define
%    it in the kernel (I think \cs{newif} no longer complains if it
%    acts on an existing \cs{if...}
%
% \subsection{Indexheading at least for l3doc is wrong now}
%
%  Needs checking.
%
%
%
%
%
%
%
% \appendix
%
% \section{Templates from the 2026-06-01 release of \LaTeX{}} \label{appendix:a}
% 
%    In this appendix we provide the template implementations that I came
%    up with in my first attempt (only renamed to
%    \meta{name}\texttt{-v1}). Eventually, we want to drop the
%    \texttt{-v1} versions but for the next couple of releases we
%    provide them alongside the new more flexible templates, so that
%    there is no need to transitioning to the new 
%    templates in a rush.
%
% \subsection{Template documentation for \texttt{-v1} templates}
%
%
% \subsubsection{Templates of type \texttt{heading}}
%
%
%    There are a number of keys that are expected to be recognized by
%    all heading templates (though they may choose not to make use of
%    them). These are listed below instead of being repeated on the
%    actual templates.
%
%    All other keys are either attached to the \texttt{heading} or to
%    the \texttt{headformat} templates. Those that typically vary
%    from heading instance to the next (e.g., \key{heading-decls}) are
%    all declared in the
%    \texttt{heading} templates even if they are actually only used
%    within \texttt{headformat} templates. In other words,
%    \texttt{headformat} templates have a number of implicit
%    variables that they expect to be set.\footnote{Maybe questionable}
%
%
% \begin{TemplateDescription}{heading}{\meta{all}}
%
%  \TemplateKey{name}{tokenlist}
%              {Referenceable name of the heading instance. String that
%               is acceptable in csnames for use in building counter
%               names, etc.}{}
%  \TemplateKey{parent-name}{tokenlist}
%              {Name of the next higher heading instance. If not
%               given, then the internal heading level of the heading
%               instance is set to \texttt{0}}{}
%  \TemplateKey{reset-counter}{tokenlist}
%              {Name of the heading instance that should reset the
%               numbering of this heading level (if any)}{}
%  \TemplateKey{level}{integer}
%              {Sets the internal heading-level rather than deducing
%               it from \key{parent-name}. Can be used to specify the
%               top-level heading if not \texttt{0}, or all headings
%               in legacy implementations, e.g., through \cs{@startsection}}{}
%
%  \TemplateKey{placement}{choice}
%              {Set the heading placement, i.e., the behavior of the
%               heading with respect to page breaks. Allowed values
%               are
%               \texttt{page} (heading forms a page if its own),
%               \texttt{top} (heading starts a new page),
%               \texttt{normal} (heading can appear anywhere on the
%               page). Further possibilities might be
%               \texttt{rectopage} and \texttt{rectotop} if we
%               implement that.}{\texttt{normal}}
%
%  \TemplateKey{start-code}{tokenlist}
%              {Default value is set by the \key{placement}
%    key. Executed before the heading starts, so can issue, for
%    example, a \cs{clearpage}}
%              {}
%
%  \TemplateKey{final-code}{tokenlist}
%              {Default value is set by the \key{placement}
%    key. Executed after the heading is typeset. Can set up code for
%    putting the heading on a page by its own, or arrange for
%    paragraph handling of a following paragraph, etc.}
%              {}
%
%  \TemplateKey{prefix}{tokenlist}
%              {A fixed string, such as \enquote{Chapter}, that can be
%               used together with the number (if any) to form a
%               \enquote{heading label}. Usage and placement is up to
%               the template, so it could be placed after the number
%               by the template (in which case it isn't really a
%               prefix).} {\cs{NoValue}}
%
%  \TemplateKey{mark-cmd}{function(1)}
%              {Function that receives the \meta{running} argument and
%               creates a suitable mark insertion}
%              {\texttt\textbackslash\meta{name}\texttt{mark}}
%
%    \TemplateSemantics
%
%    The above keys should be implemented by all heading templates.
%
%    At the moment I have retained the \LaTeXe{} interfaces for marks,
%    e.g., one has to set up \cs{chaptermark}, \cs{sectionmark},
%    etc.\ but I'm not sure this should stay (even though it is
%    certainly simpler from a compatibility perspective).
%
%    All templates should set up \cs{theheading} to correspond to
%    \cs{the\meta{name}}.
% \end{TemplateDescription}
%
%
% \begin{TemplateDescription}{heading}{display-v1}
%
%  \TemplateKey{para-indent}{boolean}
%              {Should the paragraph after the heading be indented?}
%              {false}
%
%  \TemplateKey{before-vspace}{skip}
%              {Vertical space before the heading if there is no page
%               or column break. If there is one it vanishes.
%               In particular this means it will not be used in the
%              heading \texttt{placement}s \texttt{page} or \texttt{top}}
%              {0pt}
%
%  \TemplateKey{penalty}{integer}
%              {Penalty to break before the heading. The default
%    (\TeX's largest integer) indicates that no penalty was set in
%    which case \cs{@secpenalty} is used.}
%              {\number\maxdimen}
%
%  \TemplateKey{after-penalty-vspace}{skip}
%              {Vertical space before the heading but after the
%    penalty for the heading. If the penalty results in a page or
%    column break, this space remains at the top of the page}
%              {0pt}
%
%  \TemplateKey{after-vspace}{skip}
%              {Vertical space after the heading}
%              {0pt}
%
%  \TemplateKey{heading-decls}{tokenlist}
%              {Declarations (such as font or color settings) applied
%               to all heading elements, i.e., number, title,
%               subtitle, and quotation, if present.
%               Note that color commands (unless \pkg{luacolor} is used)
%               introduce a break point before the heading and therefore one should either
%               surround color commands with \cs{SaveLastSkip} and \cs{RestoreLastSkip} or
%               to use the keys \texttt{prefix-decls}, \texttt{number-decls},
%               \texttt{title-decls}, etc.\ instead.}
%              {\cs{normalfont}}
%
%  \TemplateKey{prefix-decls}{tokenlist}
%              {Declarations (such as font or color settings) applied
%               to the heading prefix, overwriting the setting
%               of \key{heading-decls}.}
%              {\meta{empty}}
%
%  \TemplateKey{number-decls}{tokenlist}
%              {Declarations (such as font or color settings) applied
%               to the heading  number, overwriting the setting
%               of \key{heading-decls}.}
%              {\meta{empty}}
%
%  \TemplateKey{title-decls}{tokenlist}
%              {Declarations (such as font or color settings) applied
%               to the heading  title, overwriting the setting
%               of \key{heading-decls}.}
%              {\meta{empty}}
%
%  \TemplateKey{subtitle-decls}{tokenlist}
%              {Declarations (such as font or color settings) applied
%               to the heading  subtitle, overwriting the setting
%               of \key{heading-decls}.}
%              {\meta{empty}}
%
%  \TemplateKey{quote-decls}{tokenlist}
%              {Declarations (such as font or color settings) applied
%               to the heading  quote, overwriting the setting
%               of \key{heading-decls}.}
%              {\meta{empty}}
%
%  \TemplateKey{number-format}{function(1)}
%              {Code that produces a formatted version of the
%               heading number
%               including any ornamentations. Its argument is the
%               counter name for the head. However, instead of using
%               a specific counter representations, e.g.,
%               \cs{thesection}, it
%               can refer to the counter representation for the
%               current heading counter via \cs{theheading} and ignore
%               the argument.}
%              {\cs{theheading}}
%
%  \TemplateKey{contents-extra}{tokenlist}
%              {Code containing \cs{addcontents} calls to write to
%               files like \texttt{.lot} or \texttt{.lot}}
%              {\meta{empty}}
%
%
%  \TemplateKey{headformat-instance}{instance}
%              {Template instances of type \texttt{headformat}}
%              {std}
%
%    \TemplateSemantics
%
%    Several of the key names are simply bad and need revision!
% \end{TemplateDescription}
%
%
%
%
% \begin{TemplateDescription}{heading}{runin-v1}
%
%  \TemplateKey{before-vspace}{skip}
%              {Vertical space before the heading if there is no page
%               or column break. If there is one it vanishes.}
%              {0pt}
%
%  \TemplateKey{penalty}{integer}
%              {Penalty to break before the heading. The default
%    (\TeX's largest integer) indicates that no penalty was set in
%    which case \cs{@secpenalty} is used.}
%              {\number\maxdimen}
%
%  \TemplateKey{after-penalty-vspace}{skip}
%              {Vertical space before the heading but after the
%    penalty for the heading. If the penalty results in a page or
%    column break, this space remains at the top of the page. It is
%    also applied if the heading is a \texttt{page} or \texttt{top} heading.}
%              {0pt}
%
%  \TemplateKey{after-vspace}{skip}
%              {Vertical space after the heading -- ignored in runin
%               headings so should be dropped!}
%              {0pt}
%
%  \TemplateKey{heading-decls}{tokenlist}
%              {Declarations (such as font or color settings) applied
%               to all heading elements, i.e., number, title,
%               subtitle, and quotation, if present.}
%              {\cs{normalfont}}
%
%  \TemplateKey{prefix-decls}{tokenlist}
%              {Declarations (such as font or color settings) applied
%               to the heading prefix, overwriting the setting
%               of \key{heading-decls}.}
%              {\meta{empty}}
%
%  \TemplateKey{number-decls}{tokenlist}
%              {Declarations (such as font or color settings) applied
%               to the heading  number, overwriting the setting
%               of \key{heading-decls}.}
%              {\meta{empty}}
%
%  \TemplateKey{title-decls}{tokenlist}
%              {Declarations (such as font or color settings) applied
%               to the heading  title, overwriting the setting
%               of \key{heading-decls}.}
%              {\meta{empty}}
%
%  \TemplateKey{subtitle-decls}{tokenlist}
%              {Declarations (such as font or color settings) applied
%               to the heading  subtitle, overwriting the setting
%               of \key{heading-decls}.}
%              {\meta{empty}}
%
%  \TemplateKey{quote-decls}{tokenlist}
%              {Declarations (such as font or color settings) applied
%               to the heading  quote, overwriting the setting
%               of \key{heading-decls}.}
%              {\meta{empty}}
%
%  \TemplateKey{number-format}{function(1)}
%              {Code that produces a formatted version of the
%               heading number
%               including any ornamentations. Its argument is the
%               counter name for the head. However, instead of using
%               a specific counter representations, e.g.,
%               \cs{thesection}, it
%               can refer to the counter representation for the
%               current heading counter via \cs{theheading} and ignore
%               the argument.}
%              {\cs{theheading}}
%
%  \TemplateKey{headformat-instance}{instance}
%              {Template instances of type \texttt{headformat}}
%              {std}
%
%    \TemplateSemantics
%
%    Several of the key names are simply bad and need revision!
% \end{TemplateDescription}
%
%
%
%
% \subsubsection{Templates of type \texttt{headformat}}
%
%    At the moment all templates of this type assume that placement of
%    prefix, number, title is done in exactly this order. Anything
%    else would require defining further templates.
%
%    TODO: consider a more versatile mechanism (like in theorem-like
%    templates) to allow for more flexible placements without the need
%    to define additional templates.
%
% \begin{TemplateDescription}{headformat}{hang-v1}
%
%  \TemplateKey{heading-indent}{dimen}
%              {Horizontal space before the heading (shifting it to
%               the right in a LR typesetting context)}
%              {0pt}
%
%  \TemplateKey{title-format}{tokenlist}
%              {Code executed directly before the heading is typeset
%               and after the vertical spacing is done. The code takes an argument,
%               e.g., \cs{MakeUppercase}}
%              {\meta{\#1}}
%
%  \TemplateKey{prefix-number-sep}{tokenlist}
%              {Token list that can be used in the assignment to a
%               \TeX{} dimension (can contain \texttt{em} or
%               \texttt{ex} values) specifying the separation between
%               title prefix (if used) and title number. Evaluated after fonts for
%               title text have been set up, i.e., the \texttt{em} will be based
%               on the then current font.}
%              {.5em}
%
%  \TemplateKey{number-title-sep}{tokenlist}
%              {Token list that can be used in the assignment to a
%               \TeX{} dimension (can contain \texttt{em} or
%               \texttt{ex} values) specifying the separation between
%               title number and title text. Evaluated after fonts for
%               title text have been set up, i.e., the \texttt{em} will be based
%               on the then current font.}
%              {1em}
%
%    \TemplateSemantics
%
%    Implements a heading layout where number and title start on the
%    same line and the title is hanging off from  that if the title
%    has more than one line. It is what \LaTeX{} always used by
%    default for \cs{section}, \cs{subsection}, and
%    \cs{subsubsection}.
%
%    Several of the key names are simply bad and need a revision!
% \end{TemplateDescription}
%
%
% \begin{TemplateDescription}{headformat}{runin-v1}
%
%  \TemplateKey{heading-indent}{dimen}
%              {Horizontal space before the heading (shifting it to
%               the right in a LR typesetting context)}
%              {0pt}
%
%  \TemplateKey{title-format}{tokenlist}
%              {Code executed directly before the heading is typeset
%               and after the vertical spacing is done. The code can take an argument,
%               e.g., \cs{MakeUppercase}}
%              {\meta{empty}}
%
%  \TemplateKey{prefix-number-sep}{tokenlist}
%              {Token list that can be used in the assignment to a
%               \TeX{} dimension (can contain \texttt{em} or
%               \texttt{ex} values) specifying the separation between
%               title prefix (if used) and title number. Evaluated after fonts for
%               title text have been set up, i.e., the \texttt{em} will be based
%               on the then current font.}
%              {.5em}
%
%  \TemplateKey{number-title-sep}{tokenlist}
%              {Token list that can be used in the assignment to a
%               \TeX{} dimension (can contain \texttt{em} or
%               \texttt{ex} values) specifying the separation between
%               title number and title text. Evaluated after fonts for
%               title text have been set up, i.e., the \texttt{em} will be based
%               on the then current font.
%
%               In the hang template it is a horizontal dimension!}
%              {1em}
%
%    \TemplateSemantics
%
%    Implements a heading layout where number and title start on the
%    same line but then continue with the following paragraph on the
%    same line (or the next if the title overflows, i.e., the title is
%    run-in. It is what \LaTeX{} always used by default for
%    \cs{paragraph} and \cs{subparagraph}.
%
%    Several of the key names are simply bad and need a revision!
% \end{TemplateDescription}
%
%
% \begin{TemplateDescription}{headformat}{display-v1}
%
%  \TemplateKey{heading-indent}{dimen}
%              {Horizontal space before the heading (shifting it to
%               the right in a LR typesetting context)}
%              {0pt}
%  \TemplateKey{title-format}{tokenlist}
%              {Code executed directly before the heading is typeset
%               and after the vertical spacing is done. The code can take an argument,
%               e.g., \cs{MakeUppercase}}
%              {\meta{\#1}}
%
%  \TemplateKey{prefix-number-sep}{tokenlist}
%              {Token list that can be used in the assignment to a
%               \TeX{} dimension (can contain \texttt{em} or
%               \texttt{ex} values) specifying the separation between
%               title prefix (if used) and title number. Evaluated after fonts for
%               title text have been set up, i.e., the \texttt{em} will be based
%               on the then current font.}
%              {.5em}
%
%  \TemplateKey{number-title-sep}{tokenlist}
%              {Token list that can be used in the assignment to a
%               \TeX{} dimension (can contain \texttt{em} or
%               \texttt{ex} values) specifying the separation between
%               title number and title text. Evaluated after fonts for
%               title text have been set up, i.e., the \texttt{em} will be based
%               on the then current font.
%         \endgraf
%               In the display template it is a vertical dimension!}
%              {20 pt}
%
%    \TemplateSemantics
%
%    Implements a heading layout where number and title are vertically
%    separated. It is what \LaTeX{} always used by default for
%    \cs{chapter} and \cs{part}.
%
%    Several of the key names are simply bad and need a revision!
% \end{TemplateDescription}
%
%
% \subsection{Implementation of \texttt{-v1} templates}  
%
%  \begin{template}{heading display-v1}
%    \begin{macrocode}
\DeclareTemplateInterface{heading}{display-v1}{9}
{
  , name          : tokenlist
  , parent-name   : tokenlist
  , reset-counter : tokenlist
  , level         : integer = 0
  , placement     : choice {page , top , normal } = normal
  , mark-cmd      : function(1) =
  , para-indent   : choice { true , false } = false
  , before-vspace : skip = 0pt
  , penalty       : integer = \c_max_int
  , after-penalty-vspace : skip = 0pt
  , after-vspace  : skip = 0pt
  , start-code    : tokenlist =      % no default values!
  , final-code    : tokenlist =      % no default values!
  , prefix         : tokenlist = \NoValue
  , heading-decls  : tokenlist = \normalfont
  , prefix-decls   : tokenlist =
  , number-decls   : tokenlist =
  , title-decls    : tokenlist =
  , subtitle-decls : tokenlist =
  , quote-decls    : tokenlist =
  , headformat-instance : tokenlist = std
  , number-format  : function(1) = \theheading
  , contents-extra : tokenlist =
}
\DeclareTemplateCode{heading}{display-v1}{9}
{
  , name          = \l__head_name_tl
  , level         = \l__head_level_int
  , parent-name   = \l__head_pname_tl
  , reset-counter = \l__head_reset_cnt_tl
  , placement     = {
        ,page   = \__head_debug_typeout:n{ A~ page~ heading }
                  \tl_set:Nn \l__head_placement_tl { page }
        ,top    = \__head_debug_typeout:n{ A~ top~ heading }
                  \tl_set:Nn \l__head_placement_tl { top }
        ,normal = \__head_debug_typeout:n{ A~ normal~ heading }
                  \tl_set:Nn \l__head_placement_tl { normal }
                    }
  , mark-cmd      = \__head_mark_cmd:n
  , para-indent   = {
                      ,true  = \@afterindenttrue
                      ,false = \@afterindentfalse
                    }
  , before-vspace = \l__head_before_skip
  , penalty       = \l__head_penalty_int
  , after-penalty-vspace  = \l__head_after_penalty_skip
  , after-vspace  = \l__head_after_skip
  , start-code    = \l__head_start_code_tl
  , final-code    = \l__head_final_code_tl
  , prefix        = \l__head_typeset_prefix_tl
  , headformat-instance = \l__head_headformat_instance_tl
  , heading-decls  = \l__head_heading_decls_tl
  , prefix-decls   = \l__head_prefix_decls_tl
  , number-decls   = \l__head_number_decls_tl
  , title-decls    = \l__head_title_decls_tl
  , subtitle-decls = \l__head_subtitle_decls_tl
  , quote-decls    = \l__head_quote_decls_tl
  , number-format  = \__head_number_format:n
  , contents-extra = \l__head_contents_extra_tl
}
{
  \tl_set_eq:Nc \theheading { the \l__head_name_tl }
  \tl_set:Ne\l__head_saved_secnumdepth_tl{\int_use:N\c@secnumdepth}
  \__head_show_arguments:nnnnnnnnn
       {#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}{#9}
  \tl_if_empty:oF {#1} { \SetTemplateKeys{heading}{display}{#1} }
  \tl_if_empty:oT \l__head_start_code_tl
   { \str_case:VnF \l__head_placement_tl
      {
        { page }
        { \tl_set:Nn \l__head_start_code_tl
            {
             \if@openright
               \cleardoublepage
             \else
               \clearpage
             \fi
             \thispagestyle{plain}
             \if@twocolumn
               \onecolumn
               \@tempswatrue
             \else
               \@tempswafalse
             \fi
             \null\vfil
            }
        }
        { top }
        { \tl_set:Nn \l__head_start_code_tl
            {
              \if@openright\cleardoublepage\else\clearpage\fi
              \thispagestyle{plain}
              \global\@topnum\z@
            }
        }
      }
      { \tl_clear:N \l__head_start_code_tl }
   }
  \tl_if_empty:oT \l__head_final_code_tl
   { \str_case:VnF \l__head_placement_tl
      {
        { page }
        { \tl_set:Nn \l__head_final_code_tl
            {
              \vfil\newpage
              \if@twoside
                \if@openright
                  \null
                  \thispagestyle{empty}
                \newpage
                \fi
              \fi
              \if@tempswa
                \twocolumn
              \fi
            }
        }
      }
      { \tl_set:Nn  \l__head_final_code_tl { \@afterheading } }
   }
  \__head_determine_penalty:
%    \end{macrocode}
%    Next lines are an inline version of
%    \cs{__head_determine_number_typesetting:N}\verb= #2=
%    This macro has changed so here we inline the original code;
%    \begin{macrocode}
  \bool_set:Nn \l__head_unnumbered_bool
     { \bool_lazy_or_p:nn
       { \int_compare_p:nNn \l__head_level_int > \c@secnumdepth }
       { \bool_if_p:N #2 }
     }
  \bool_if:NTF \l__head_unnumbered_bool
    {
      \int_gset:Nn\c@secnumdepth{-99}
      \tl_clear:N \l__head_typeset_number_tl
    }
    {
      \@kernel@refstepcounter{ \l__head_name_tl }
      \protected@edef \l__head_typeset_number_tl
        {
          \__head_number_format:n { \l__head_name_tl }
        }
    }
%    \end{macrocode}
%    End of inlined code.
%    \begin{macrocode}
  \__head_vertical_before_spacing:
  \UseTaggingSocket{sec/end}{\int_use:N\l__head_level_int}
  \UseTaggingSocket{sec/begin}
                   {{\int_use:N\l__head_level_int}
                    {tag=\UseStructureName{sec/\int_use:N\l__head_level_int}}}
  \__head_debug_typeout:n{use~ 'headformat'~instance:~
                       \l__head_headformat_instance_tl }
  \use:e {
    \UseInstance{headformat} { \l__head_headformat_instance_tl }
                { \exp_not:o \UnusedTemplateKeys }
                { \exp_not:o { \l__head_typeset_prefix_tl } }
                { \exp_not:o { \l__head_typeset_number_tl } }
                { \exp_not:n { #3 } }
                { \exp_not:o { \use_i:nn  #9 } }
                { \exp_not:o { \use_ii:nn  #9 } }
  }
  \__head_handle_marks_etc:nnnnn {#4}{#5}{#6}{#7}{#8}
  \int_gset:Nn\c@secnumdepth{\l__head_saved_secnumdepth_tl}
  \par \nobreak
  \skip_vertical:N \l__head_after_skip
  \l__head_final_code_tl
  \ignorespaces
}
%    \end{macrocode}
%  \end{template}
%
%
%
%
%
%  \begin{template}{heading runin-v1}
%    \begin{macrocode}
\DeclareTemplateCopy{heading}{runin-v1}{display-v1}
\DeclareTemplateCode{heading}{runin-v1}{9}
 {
  , name           = \l__head_name_tl
  , level          = \l__head_level_int
  , parent-name    = \l__head_pname_tl
  , reset-counter  = \l__head_reset_cnt_tl
  , placement      = {
         page   = \typeout{ ^^JA~ runin~ page~ placement~ heading~makes~no~sense
                            (top~used)}
                  \tl_set:Nn \l__head_placement_tl { top }
        ,top    = \__head_debug_typeout:n{ A~ top~ heading }
                  \tl_set:Nn \l__head_placement_tl { top }
        ,normal = \__head_debug_typeout:n{ A~ normal~ heading }
                  \tl_set:Nn \l__head_placement_tl { normal }
                    }
  , mark-cmd       = \__head_mark_cmd:n
  , para-indent    =  {
                       ,true  = %\typeout{para-indent~ setting~ ignored}
                       ,false = %\typeout{para-indent~ setting~ ignored}
                      }
  , before-vspace  = \l__head_before_skip
  , penalty        = \l__head_penalty_int
  , after-penalty-vspace  = \l__head_after_penalty_skip
  , after-vspace   = \l__head_after_skip
  , start-code     = \l__head_start_code_tl
  , final-code     = \l__head_final_code_tl
  , prefix        = \l__head_typeset_prefix_tl
  , headformat-instance = \l__head_headformat_instance_tl
  , heading-decls  = \l__head_heading_decls_tl
  , prefix-decls   = \l__head_prefix_decls_tl
  , number-decls   = \l__head_number_decls_tl
  , title-decls    = \l__head_title_decls_tl
  , subtitle-decls = \l__head_subtitle_decls_tl
  , quote-decls    = \l__head_quote_decls_tl
  , number-format  = \__head_number_format:n
  , contents-extra = \l__head_contents_extra_tl
}
{
  \__head_show_arguments:nnnnnnnnn
       {#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}{#9}
  \tl_set:Ne\l__head_saved_secnumdepth_tl{\int_use:N\c@secnumdepth}
  \tl_set_eq:Nc \theheading { the \l__head_name_tl }
  \tl_if_empty:oF {#1} { \SetTemplateKeys{heading}{runin}{#1} }
  \tl_if_empty:oT \l__head_start_code_tl
   {
    \str_case:Vn \l__head_placement_tl
      {
        { top }   { \tl_set:Nn \l__head_start_code_tl {\clearpage } }
      }
   }
  \__head_determine_penalty:
%    \end{macrocode}
%    Next lines are an inline version of
%    \cs{__head_determine_number_typesetting:N}\verb= #2=
%    This macro has changed so here we inline the original code;
%    \begin{macrocode}
  \bool_set:Nn \l__head_unnumbered_bool
     { \bool_lazy_or_p:nn
       { \int_compare_p:nNn \l__head_level_int > \c@secnumdepth }
       { \bool_if_p:N #2 }
     }
  \bool_if:NTF \l__head_unnumbered_bool
    {
      \int_gset:Nn\c@secnumdepth{-99}
      \tl_clear:N \l__head_typeset_number_tl
    }
    {
      \@kernel@refstepcounter{ \l__head_name_tl }
      \protected@edef \l__head_typeset_number_tl
        {
          \__head_number_format:n { \l__head_name_tl }
        }
    }
%    \end{macrocode}
%    End of inlined code.
%    \begin{macrocode}
  \__head_vertical_before_spacing:
  \UseTaggingSocket{sec/end}{\int_use:N\l__head_level_int}
  \UseTaggingSocket{sec/begin}
    {{\int_use:N\l__head_level_int}{tag=\UseStructureName{sec/\int_use:N\l__head_level_int}}}
  \UseTaggingSocket{sec/title/init}{\int_use:N\l__head_level_int}
  \def \@svsechd {
      \__head_debug_typeout:n{use~ 'headformat'~instance:~
                          \l__head_headformat_instance_tl }
      \use:e {
        \UseInstance{headformat} { \l__head_headformat_instance_tl }
                 { \exp_not:o \UnusedTemplateKeys }
                 { \exp_not:o { \l__head_typeset_prefix_tl } }
                 { \exp_not:o { \l__head_typeset_number_tl } }
                 { \exp_not:n { #3 } }
                 { \exp_not:o { \use_i:nn  #9 } }
                 { \exp_not:o { \use_ii:nn  #9 } }
      }
      \__head_handle_marks_etc:nnnnn {#4}{#5}{#6}{#7}{#8}
      \int_gset:Nn\c@secnumdepth{\l__head_saved_secnumdepth_tl}
  }
  \@nobreakfalse
  \global\@noskipsectrue
  \everypar{%
    \if@noskipsec
       \global\@noskipsecfalse
       {\setbox\z@\lastbox}
       \clubpenalty\@M
       \@svsechd
       \unskip
       \UseTaggingSocket{sec/title/split}
       \skip_horizontal:N \l__head_after_skip
    \else
      \clubpenalty \@clubpenalty
      \everypar{}%
    \fi
  }
  \l__head_final_code_tl
  \ignorespaces
}
%    \end{macrocode}
%  \end{template}
%
%
%
%
%
%
%
%  \begin{template}{headformat display-v1}
%    The \texttt{display} template produces
%    \begin{macrocode}
\DeclareTemplateInterface{headformat}{display-v1}{6}
{
  , heading-indent    : length = 0pt
  , title-format      : function(1) = #1
  , prefix-number-sep : tokenlist = \WordSpaceAmount{1}
  , number-title-sep  : tokenlist = 20pt
}
%    \end{macrocode}
%  \end{template}
%
%  \begin{template}{headformat hang-v1}
%    \begin{macrocode}
\DeclareTemplateInterface{headformat}{hang-v1}{6}
{
  , heading-indent    : length = 0pt
  , title-format      : function(1) = #1
  , prefix-number-sep : tokenlist = \WordSpaceAmount{1}
  , number-title-sep  : tokenlist = 1em
}
%    \end{macrocode}
%  \end{template}
%
%
%  \begin{template}{headformat runin-v1}
%    \begin{macrocode}
\DeclareTemplateInterface{headformat}{runin-v1}{6}
{
  , heading-indent    : length = 0pt
  , title-format      : function(1) = #1
  , prefix-number-sep : tokenlist = \WordSpaceAmount{1}
  , number-title-sep  : tokenlist = 1em
}
%    \end{macrocode}
%  \end{template}
% 
% 
%
%  \begin{template}{headformat display-v1}
%    \begin{macrocode}
\DeclareTemplateCode{headformat}{display-v1}{6}
       % args: keys,prefix,number,title,subtitle,quotation
 {
  , heading-indent    = \l_@@_heading_indent_dim
  , title-format      = \@@_title_format:n
  , prefix-number-sep = \l_@@_prefix_number_sep_tl
  , number-title-sep  = \l_@@_number_title_sep_tl
 }
 {
  \@@_show_arguments:nnnnnn {#1}{#2}{#3}{#4}{#5}{#6}
  \tl_if_empty:oF {#1} { \SetTemplateKeys{headformat}{display-v1}{#1} }
  \group_begin:
    \UseTaggingSocket{sec/title/begin}{{\int_use:N\l_@@_level_int}{#4}}
    \normalfont 
    \interlinepenalty \@M
    \l_@@_heading_decls_tl{}
    \bool_if:NTF \l_@@_unnumbered_bool
      {
        \dim_compare:nNnTF  \l_@@_heading_indent_dim < \c_zero_skip
          {
            \skip_horizontal:N \l_@@_heading_indent_dim
            \MakeLinkTarget[\l_@@_name_tl]{}
          }
          {
            \MakeLinkTarget[\l_@@_name_tl]{}
            \skip_horizontal:N \l_@@_heading_indent_dim
          }
      }
      {
        \dim_compare:nNnTF  \l_@@_heading_indent_dim < \c_zero_skip
          {
            \skip_horizontal:N \l_@@_heading_indent_dim
            \MakeLinkTarget{\l_@@_name_tl}
          }
          {
            \MakeLinkTarget{\l_@@_name_tl}
            \skip_horizontal:N \l_@@_heading_indent_dim
          }
        \IfNoValueF{#2}
          {    
            { \l_@@_prefix_decls_tl #2 }
            \nobreak
            \skip_horizontal:n { \l_@@_prefix_number_sep_tl }
          }
        \l_@@_number_decls_tl
        #3
        \par\nobreak
        \skip_vertical:n { \l_@@_number_title_sep_tl }
      }
    \l_@@_title_decls_tl
    \@@_title_format:n {#4}
    \par
    \UseTaggingSocket{sec/title/end}
  \group_end:
}
%    \end{macrocode}
%  \end{template}
%
%
%
%
%
%
%  \begin{template}{headformat hang-v1}
%    \begin{macrocode}
\DeclareTemplateCode{headformat}{hang-v1}{6}
 {
  , heading-indent    = \l_@@_heading_indent_dim
  , title-format      = \@@_title_format:n
  , prefix-number-sep = \l_@@_prefix_number_sep_tl
  , number-title-sep  = \l_@@_number_title_sep_tl
 }
 {
  \@@_show_arguments:nnnnnn {#1}{#2}{#3}{#4}{#5}{#6}
  \tl_if_empty:oF {#1} { \SetTemplateKeys{headformat}{hang-v1}{#1} }
  \group_begin:
    \UseTaggingSocket{sec/title/init}{\int_use:N\l_@@_level_int}
    \normalfont 
    \interlinepenalty \@M
    \l_@@_heading_decls_tl{}
    \bool_if:NTF \l_@@_unnumbered_bool
      {
        \tl_set:Nn\l_@@_tmpa_tl
         {
          \dim_compare:nNnTF  \l_@@_heading_indent_dim < \c_zero_skip
            {
              \skip_horizontal:N \l_@@_heading_indent_dim
              \MakeLinkTarget[\l_@@_name_tl]{}
            }
            {
              \MakeLinkTarget[\l_@@_name_tl]{}
              \skip_horizontal:N \l_@@_heading_indent_dim
            }
         }
      }
      {
       \tl_set:Nn \l_@@_tmpa_tl
        {
          \dim_compare:nNnTF  \l_@@_heading_indent_dim < \c_zero_skip
              {
                \skip_horizontal:N \l_@@_heading_indent_dim
                \MakeLinkTarget{\l_@@_name_tl}
              }
              {
                \MakeLinkTarget{\l_@@_name_tl}
                \skip_horizontal:N \l_@@_heading_indent_dim
              }
          \IfNoValueF{#2}
              {    
                { \l_@@_prefix_decls_tl #2 }
                \nobreak
                \skip_horizontal:n { \l_@@_prefix_number_sep_tl }
              }
          { \l_@@_number_decls_tl #3 }
          \skip_horizontal:n { \l_@@_number_title_sep_tl }
        }
       }
     \UseTaggingSocket{sec/title/hang}
       {{\int_use:N\l_@@_level_int}\l_@@_unnumbered_bool{\l_@@_tmpa_tl}{#4}}
       {
        \@hangfrom
          {
           \l_@@_tmpa_tl
          }
       }
    \l_@@_title_decls_tl
    \@@_title_format:n {#4}
    \par
  \group_end:
}
%    \end{macrocode}
%  \end{template}
%
%
%  \begin{template}{headformat runin-v1}
%    \begin{macrocode}
\DeclareTemplateCode{headformat}{runin-v1}{6}
 {
  , heading-indent    = \l_@@_heading_indent_dim
  , title-format      = \@@_title_format:n
  , prefix-number-sep = \l_@@_prefix_number_sep_tl
  , number-title-sep  = \l_@@_number_title_sep_tl
 }
 {
  \@@_show_arguments:nnnnnn {#1}{#2}{#3}{#4}{#5}{#6}
  \tl_if_empty:oF {#1} { \SetTemplateKeys{headformat}{runin-v1}{#1} }
  \group_begin:
    \normalfont 
    \interlinepenalty \@M
    \l_@@_heading_decls_tl{}
    \bool_if:NTF \l_@@_unnumbered_bool
      {
        \dim_compare:nNnTF  \l_@@_heading_indent_dim < \c_zero_skip
         {
           \skip_horizontal:N \l_@@_heading_indent_dim
           \MakeLinkTarget[\l_@@_name_tl]{}
         }
         {
           \MakeLinkTarget[\l_@@_name_tl]{}
           \skip_horizontal:N \l_@@_heading_indent_dim
         }
      }
      {
         \dim_compare:nNnTF  \l_@@_heading_indent_dim < \c_zero_skip
         {
           \skip_horizontal:N \l_@@_heading_indent_dim
           \MakeLinkTarget{\l_@@_name_tl}
         }
         {
           \MakeLinkTarget{\l_@@_name_tl}
           \skip_horizontal:N \l_@@_heading_indent_dim
         }
         {
           \UseTaggingSocket{sec/title/number}{\int_use:N\l_@@_level_int}
             {
               \IfNoValueF{#2}
                 {    
                   { \l_@@_prefix_decls_tl #2 }
                   \nobreak
                   \skip_horizontal:n { \l_@@_prefix_number_sep_tl }
                 }
                 \l_@@_number_decls_tl
                 #3
             }
         }
         \skip_horizontal:n { \l_@@_number_title_sep_tl }
      }
    \l_@@_title_decls_tl
    \@@_title_format:n {#4}
  \group_end:
}
%    \end{macrocode}
%  \end{template}
%
%
% 
%
%
% 
%
%
% \end{implementation}
%
%
%
% \Finale
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\endinput
