% \iffalse meta-comment
%
% Copyright (C) 2019-2024
% The LaTeX Project and any individual authors listed elsewhere
% in this file.
%
% This file is part of the LaTeX base system.
% -------------------------------------------
%
% It may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3c
% of this license or (at your option) any later version.
% The latest version of this license is in
%    https://www.latex-project.org/lppl.txt
% and version 1.3c or later is part of all distributions of LaTeX
% version 2008 or later.
%
% This file has the LPPL maintenance status "maintained".
%
% The list of all files belonging to the LaTeX base distribution is
% given in the file `manifest.txt'. See also `legal.txt' for additional
% information.
%
% The list of derived (unpacked) files belonging to the distribution
% and covered by LPPL is defined by the unpacking scripts (with
% extension .ins) which are part of the distribution.
%
% \fi
%
% \iffalse
%%% From File: ltexpl.dtx
%
%<*driver>
% \fi
\ProvidesFile{ltexpl.dtx}
             [2024/04/17 v1.3h LaTeX Kernel (expl3-dependent code)]
% \iffalse
\documentclass{ltxdoc}
\GetFileInfo{ltexpl.dtx}
\title{\filename}
\date{\filedate}
\author{%
  Joseph Wright}

\providecommand\pkg[1]{\texttt{#1}}

\begin{document}
 \MaintainedByLaTeXTeam{latex}
 \maketitle
 \DocInput{ltexpl.dtx}
\end{document}
%</driver>
% \fi
%
%
% \changes{v1.2d}{2020/08/21}{Dropped unused command}
%
% \section{\pkg{expl3}-dependent code}
%
% \MaybeStop{}
%
% \changes{v0.0}{2019-10-02}{Initial version}
%
% \subsection{Loader}
%
% \changes{v1.0a}{2020/03/02}
%         {Don't load expl3 if already in the format (gh/295)}
% \changes{v1.1}{2020/03/05}
%         {Load xparse.ltx if \cs{NewDocumentCommand} is not defined
%         by expl3.ltx}
% \changes{v1.2c}{2020/06/04}
%         {Define a local version of some \LaTeXe{} basic macros to support
%          package loading}
%
% \begin{macro}{\@kernel@after@enddocument,
%                \@kernel@after@enddocument@afterlastpage}
%   These two kernel hooks are used by the shipout code.  They are
%   defined earlier here because the \pkg{lthooks} code adds material
%   to them.
% \changes{v1.2h}{2020/12/18}
%         {Define kernel \cs{enddocument} hooks early}
%    \begin{macrocode}
%<*2ekernel|latexrelease>
%<latexrelease>\IncludeInRelease{2020/10/01}%
%<latexrelease>  {kernel@enddocument hooks}{Define several kernel hooks}
%    \end{macrocode}
%    We only initialize these kernel hooks if they are not already
%    existing. Otherwise they would be set to \cs{@empty} on rollback
%    which would be wrong because code that has been added to them
%    may still have to be executed in the rollback situation . Instead
%    code that writes to them needs to handle the rollback as needed.
%    It is likely that we have to change that approach in the future,
%    but for now it should do.
%    (It is enough to test only for the existence of one hook, as all
%    got added at the same time.)
% \changes{v1.3c}{2021/04/20}{Don't empty kernel hooks on rollback}
%    \begin{macrocode}
\ifx\@kernel@after@enddocument\@undefined
  \let \@kernel@after@enddocument               \@empty
  \let \@kernel@after@enddocument@afterlastpage \@empty
%    \end{macrocode}
%
%  \begin{macro}{\@kernel@before@begindocument,\@kernel@after@begindocument}
%    For the similar reasons we also define those that are used in
%    \cs{document} because they too get material added to in early modules.
%    \begin{macrocode}
  \let \@kernel@before@begindocument \@empty
  \let \@kernel@after@begindocument  \@empty
\fi
%<latexrelease>\EndIncludeInRelease
%    \end{macrocode}
%
%    \begin{macrocode}
%<latexrelease>\IncludeInRelease{0000/00/00}%
%<latexrelease>  {kernel@enddocument hooks}{Define several kernel hooks}
%<latexrelease>\let\@kernel@after@enddocument\@undefined
%<latexrelease>\let\@kernel@after@enddocument@afterlastpage\@undefined
%<latexrelease>\let\@kernel@before@begindocument\@undefined
%<latexrelease>\let\@kernel@after@begindocument\@undefined
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% First define some blank commands, so that in case something goes wrong while
% loading \textsf{expl3}, we won't get strange \texttt{Undefined control
% sequence} errors.
% \changes{v1.3a}{2021/01/24}{Define \pkg{expl3} hooks conditionally}
%    \begin{macrocode}
%<*2ekernel|latexrelease>
%<latexrelease>\IncludeInRelease{2020/10/01}%
%<latexrelease>            {\@expl@sys@load@backend@@}{Roll forward support}%
\def\reserved@a#1{\ifdefined#1\else\def#1{}\fi}
\reserved@a\@expl@sys@load@backend@@
\reserved@a\@expl@push@filename@@
\reserved@a\@expl@push@filename@aux@@
\reserved@a\@expl@pop@filename@@
%<latexrelease>\EndIncludeInRelease
%</2ekernel|latexrelease>
%    \end{macrocode}
%
% \changes{v1.2d}{2020/07/08}
%         {Add a last-minute hook for \textsf{expl3}}
% Create a hook for last-minute \pkg{expl3} material.
%    \begin{macrocode}
%<*2ekernel>
\def\@expl@finalise@setup@@{}
%</2ekernel>
%    \end{macrocode}
%
% Now define some basics to support loading \textsf{expl3}.  These macros can
% be defined here safely, because they are redefined later on by the kernel,
% so we define simpler versions just to suit our needs.
%    \begin{macrocode}
%<*2ekernel>
\long\def\@gobble#1{}
\long\def\@firstofone#1{#1}
\long\def\@firstoftwo#1#2{#1}
\long\def\@secondoftwo#1#2{#2}
\long\def\IfFileExists#1{%
  \openin\@inputcheck"#1" %
  \ifeof\@inputcheck
    \expandafter\@secondoftwo
  \else
    \closein\@inputcheck
    \expandafter\@firstoftwo
  \fi}
\long\def\@ifnextchar#1#2#3{%
  \let\reserved@d=#1%
  \def\reserved@a{#2}%
  \def\reserved@b{#3}%
  \futurelet\@let@token\@ifnch}
\def\@ifnch{%
  \ifx\@let@token\reserved@d
    \expandafter\reserved@a
  \else
    \expandafter\reserved@b
  \fi}
%</2ekernel>
%    \end{macrocode}
%
%    If we are doing a rollback with a format containing expl3 we
%    aren't reloading it as that creates havoc. This may need a
%    refined version!
%    \begin{macrocode}
%<*2ekernel|latexrelease>
%<latexrelease>\IncludeInRelease{2020/10/01}%
%<latexrelease>                 {expl3}{Pre-load expl3}%
\expandafter\ifx\csname tex\string _let:D\endcsname\relax
  \expandafter\@firstofone
\else
  \GenericInfo{}{Skipping: expl3 code already part of the format}%
%<2ekernel>  \expandafter\endinput
%<latexrelease>  \expandafter\@gobble
\fi
%    \end{macrocode}
%
%  Check for the required primitive/engine support and the existence of
%  a loader.
%    \begin{macrocode}
  {%
    \IfFileExists{expl3.ltx}
      {%
        \ifnum0%
          \ifdefined\pdffilesize 1\fi
          \ifdefined\filesize 1\fi
          \ifdefined\luatexversion\ifnum\luatexversion>94 1\fi\fi
          \ifdefined\kanjiskip 1\fi
            >0 %
          \expandafter\@firstofone
        \else
%    \end{macrocode}
%
% In \texttt{2ekernel} mode, an error is fatal and building the format
% is aborted. Use \verb=\batchmode \read -1 to \tokenlist=, which errors
% with
%\begin{verbatim}
%   ! Emergency stop. (cannot \read from terminal in nonstop modes)
%\end{verbatim}
% and aborts the \TeX{} run.  In \texttt{latexrelease} mode, raise an
% error and do nothing.  Both ways, the error message shows the minimum
% \textsf{expl3} engine requirements.
%    \begin{macrocode}
%<2ekernel>          \def~{ }\def\MessageBreak{^^J~~~~~~~~~~~~~~~}%
%<2ekernel>          \errmessage{LaTeX Error:
%<latexrelease>          \@latex@error{%
            LaTeX requires the e-TeX primitives and additional\MessageBreak
            functionality available in the engines:\MessageBreak
              - pdfTeX v1.40\MessageBreak
              - XeTeX v0.99992\MessageBreak
              - LuaTeX v0.95\MessageBreak
              - e-(u)pTeX mid-2012\MessageBreak
            or later%
%<latexrelease>          }\@ehd \expandafter\@gobble
%<2ekernel>          }\batchmode \read -1 to \reserved@a
        \fi
      }
      {%
%<*2ekernel>
        \errmessage{LaTeX requires expl3}%
        \batchmode \read -1 to \reserved@a
%</2ekernel>
%    \end{macrocode}
%    We do not support a roll forward across 2019. You need to start
%    with 2019 if you want to get to 2020 or beyond.
% \changes{v1.2g}{2020/11/24}{Support for roll forward (gh/434)}
%    \begin{macrocode}
%<*latexrelease>
        \@latex@warning@no@line
          {You need a format that already contains a recent\MessageBreak
           expl3 as part of the kernel, e.g. at least a kernel\MessageBreak
           from 2019 to roll forward to that date!\MessageBreak
           --- I'm giving up!\MessageBreak\MessageBreak
           Note that manually loading the expl3 package\MessageBreak
           from your distribution is not enough}%
        \batchmode \read -1 to \reserved@a
%</latexrelease>
      }%
      {\input expl3.ltx }%
  }
%<latexrelease>\EndIncludeInRelease
%<latexrelease>
%    \end{macrocode}
% To support roll-forward for the case where \textsf{xparse} is fully
% integrated into the kernel, we do not need to repeat the complex test
% above as we can simply look for the marker command.
%    \begin{macrocode}
%<latexrelease>\IncludeInRelease{2020/02/02}%
%<latexrelease>                 {expl3}{Pre-load expl3}%
%<latexrelease>\IfFileExists{expl3.ltx}
%<latexrelease>  {%
%<latexrelease>    \ifnum0%
%<latexrelease>      \ifdefined\pdffilesize 1\fi
%<latexrelease>      \ifdefined\filesize 1\fi
%<latexrelease>      \ifdefined\luatexversion\ifnum\luatexversion>94 1\fi\fi
%<latexrelease>      >0 %
%<latexrelease>    \else
%<latexrelease>      \message{Skipping expl3-dependent extensions}
%<latexrelease>      \expandafter\@gobbletwo
%<latexrelease>    \fi
%<latexrelease>  }
%<latexrelease>  {%
%<latexrelease>    \message{Skipping expl3-dependent extensions}%
%<latexrelease>    \@gobbletwo
%<latexrelease>  }%
%<latexrelease>\input{expl3.ltx}
%<latexrelease>\EndIncludeInRelease
%    \end{macrocode}
%
% Now in |latexrelease| mode, redefine a few commands to avoid ``already
% defined'' errors.
% \changes{v1.3f}{2022/02/28}
%                {Move latexrelease redefinitions from ltcmd.dtx}
%    \begin{macrocode}
%<latexrelease>\@ifundefined{ExplSyntaxOff}{}{\latexrelease@postltexpl}
%    \end{macrocode}
%
% \changes{v1.3a}{2021/01/21}
%                {Move \pkg{xparse} rollback code to \texttt{ltcmd.dtx}}
%
%    \subsection{Using expl3 code}
%
%    In order to ease the implementation of some new features in
%    \LaTeXe\ we may (temporarily) use some coding based on the
%    \pkg{expl3}-code.
%    Such macros will eventually vanish and may be changed
%    unannounced. They are there for internal use in the \LaTeXe\
%    kernel and are not meant to be used in third-party
%    packages. These macros will always have the \verb|@expl@|
%    prefix in their name.
%
%    The rest of the name matches the \pkg{expl3} name but with all
%    underscores replaced by \texttt{@}s and the \texttt{:} replaced
%    by \texttt{@@}, e.g.,
%\begin{verbatim}
%  \cs_new_eq:NN \@expl@tl@trim@spaces@apply@@nN \tl_trim_spaces_apply:nN
%\end{verbatim}
%    if that \pkg{expl3} command is needed in places that are others
%    coded in \LaTeXe{} conventions.
%
%
%    In this file, each release of LaTeX adds an \cs{IncludeInRelease}
%    block, in which the macros copied for that release were defined.
%    In case a rollback is requested, the entire block is changed.
%
%    Each macro copied has a \cs{changes} entry to explain when and why
%    it was copied, so that further to that may spot it easily.
%
%    Here \cs{cs\string_gset\string_eq:NN} is used, instead of the |new|
%    variant because if different releases use that same name for
%    different purposes, each can copy the macro without worrying about
%    redefinitions.
%
%    \begin{macrocode}
%<latexrelease>\IncludeInRelease{2020/10/01}{\@expl@cs@to@str@@N}%
%<latexrelease>        {expl3 macros added for the 2020-10-01 release}%
%    \end{macrocode}
%
%    The expl3 activation needs to be inside the release guards as
%    otherwise rolling forward is broken in old kernels that do not
%    have expl3 loaded.
% \changes{v1.2g}{2020/11/24}{Support for roll forward (gh/434)}
%    \begin{macrocode}
\ExplSyntaxOn
%    \end{macrocode}
%
% \changes{v1.2e}{2020/08/19}
%         {Add \cs{@expl@cs@to@str@@N} and \cs{@expl@str@if@eq@@nnTF}
%          for \cs{NewCommandCopy} (gh/239)}
%    \begin{macrocode}
\cs_gset_eq:NN \@expl@cs@to@str@@N \cs_to_str:N
\cs_gset_eq:NN \@expl@str@if@eq@@nnTF \str_if_eq:nnTF
%    \end{macrocode}
%
% \changes{v1.2e}{2020/08/19}
%         {Add \cs{@expl@cs@\meta{thing}@spec@@N}
%          for \cs{ShowCommand} (gh/373)}
% \changes{v1.3h}{2024/04/17}
%         {Rename \cs{@expl@cs@argument@spec@@N} to
%          \cs{@expl@cs@parameter@spec@@N} (gh/1014)}
% \changes{v1.3h}{2024/04/17}
%         {Update name of \pkg{expl3} function}
% \changes{v1.3h}{2024/04/17}
%         {Add a kernel-level copy of \cs{cs_parameter_spec:N}}
%    \begin{macrocode}
\cs_gset_eq:NN \@expl@cs@prefix@spec@@N \cs_prefix_spec:N
\cs_if_exist:NTF \cs_parameter_spec:N
  { \cs_gset_eq:NN \@expl@cs@parameter@spec@@N \cs_parameter_spec:N }
  { \cs_gset_eq:NN \@expl@cs@parameter@spec@@N \cs_argument_spec:N }
\cs_gset_eq:NN \__kernel_cs_parameter_spec:N \@expl@cs@parameter@spec@@N
\cs_gset_eq:NN \@expl@cs@replacement@spec@@N \cs_replacement_spec:N
%    \end{macrocode}
%
% \changes{v1.2f}{2020/09/06}
%         {Add \cs{@expl@str@map@function@@NN
%          and \cs{@expl@char@generate@@nn}}
%          for \cs{string@makeletter} (gh/386)}
%    \begin{macrocode}
\cs_gset_eq:NN \@expl@str@map@function@@NN \str_map_function:NN
\cs_gset_eq:NN \@expl@char@generate@@nn \char_generate:nn
%    \end{macrocode}
%
%    \begin{macrocode}
\ExplSyntaxOff
%    \end{macrocode}
%
%
%    Here we can't assume that expl3 is available. It will be if we
%    roll back but if this code is executed rolling forward it needs
%    to be pure 2e.
% \changes{v1.2g}{2020/11/24}{Support for roll forward (gh/434)}
%    \begin{macrocode}
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{0000/00/00}{\@expl@cs@to@str@@N}%
%<latexrelease>        {expl3 macros added for the 2020-10-01 release}%
%<latexrelease>\let \@expl@cs@to@str@@N \@undefined
%<latexrelease>\let \@expl@str@if@eq@@nnTF \@undefined
%<latexrelease>\let \@expl@cs@prefix@spec@@N \@undefined
%<latexrelease>\let \@expl@cs@parameter@spec@@N \@undefined
%<latexrelease>\let \@expl@cs@replacement@spec@@N \@undefined
%<latexrelease>\let \@expl@str@map@function@@NN \@undefined
%<latexrelease>\EndIncludeInRelease
%</2ekernel|latexrelease>
%    \end{macrocode}
%
%
%
%
%
%
% \section{Document-level command names for \pkg{expl3} functions}
%
%    Current home for L3 programing layer functions that we make
%    directly available at the document level. This section may need
%    to be moved later (after \cs{NewDocumentCommand} is defined in
%    case we want to use that in the setup).
%
%
% \DescribeMacro\fpeval
%    The expandable command \cs{fpeval} takes as its argument a
%    floating point expression and produces a result using the normal
%    rules of mathematics. As this command is expandable it can be
%    used where \TeX{} requires a number and for example within a
%    low-level \cs{edef} operation to give a purely numerical
%    result. See \texttt{usrguide3} for further explanation.
%
% \DescribeMacro\inteval
% \DescribeMacro\dimeval
% \DescribeMacro\skipeval
%    The expandable command \cs{inteval} takes as its argument an
%    integer expression and produces a result using the normal rules
%    of mathematics. The operations recognised are |+|, |-|, |*| and
%    |/| plus parentheses. Division occurs with \emph{rounding}, and
%    ties are rounded away from zero. As this command is expandable it
%    can be used where \TeX{} requires a number and for example within
%    a low-level \cs{edef} operation to give a purely numerical
%    result. See \texttt{usrguide3} for further explanation.
%    \cs{dimeval} and \cs{skipeval} are similar, but generate fixed and
%    rubber length values, respectively.
%
%
%
% \begin{macro}{\fpeval,\inteval,\dimeval,\skipeval}
%    A document level wrapper around the code level function for
%    floating point calculations.
% \changes{v1.3d}{2021/11/30}{Moved over from \texttt{xfp} package (gh/711)}
%    \begin{macrocode}
%<*2ekernel|latexrelease>
%<latexrelease>\IncludeInRelease{2022/06/01}%
%<latexrelease>                 {\fpeval}{fp and int calculations}%
\ExplSyntaxOn
\cs_new_eq:NN \fpeval \fp_eval:n
%    \end{macrocode}
%     And a few more, this time wrappers around the e\TeX{} primitives.
%    \begin{macrocode}
\cs_new_eq:NN \inteval \int_eval:n
%    \end{macrocode}
%    
% \changes{v1.3d}{2021/12/07}{Added \cs{dimeval} and \cs{skipeval} (gh/711)}
%    \begin{macrocode}
\cs_new_eq:NN \dimeval  \dim_eval:n
\cs_new_eq:NN \skipeval \skip_eval:n
\ExplSyntaxOff
%    \end{macrocode}
% \end{macro}
%
%    \begin{macrocode}
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{0000/00/00}%
%<latexrelease>                 {\fpeval}{fp and int calculations}%
%<latexrelease>
%<latexrelease>\let\fpeval\@undefined
%<latexrelease>\let\inteval\@undefined
%<latexrelease>\let\dimeval\@undefined
%<latexrelease>\let\skipeval\@undefined
%<latexrelease>\EndIncludeInRelease
%    \end{macrocode}
%
%
% \DescribeMacro\UseName
% \DescribeMacro\ExpandArgs
%    When declaring new commands with \cs{NewDocumentCommand} or
%    \cs{NewCommandCopy} or similar, it is sometimes necessary to
%    ``construct'' the csname. As a general mechanism the L3
%    programming layer has \cs{exp\_args:N...} for this, but there is
%    no mechanism for it  if \cs{ExplSyntaxOn} is not active. We
%    therefore offer a few of these commands also with CamelCase names.
%
%
% \begin{macro}{\UseName,\ExpandArgs}
%    A document wrapper for changing arguments to cs names for use
%    with \cs{NewDocumentCommand} and similar functions.
%
% \changes{v1.3d}{2021/12/28}{Added document level names for \cs{exp\_args:Nc} and the like (gh/735)}
% \changes{v1.3e}{2022/01/06}{Adjust document level names for \cs{exp\_args:Nc} and the like (gh/735)}
%    \begin{macrocode}
%<*2ekernel|latexrelease>
%<latexrelease>\IncludeInRelease{2022/06/01}%
%<latexrelease>                 {\ExpandArgs}{Some pre-expansion commands}%
\ExplSyntaxOn
\cs_new_eq:NN \UseName \use:c
%    \end{macrocode}
%
%    \begin{macrocode}
\cs_new:Npn \ExpandArgs #1
  {
    \cs_if_exist_use:cF { exp_args:N #1 }
      { \msg_expandable_error:nnn { kernel } { unknown-arg-expansion } {#1} }
  }
\msg_new:nnn { kernel } { unknown-arg-expansion }
  { Unknown~arg~expansion~"#1" }
\ExplSyntaxOff
%    \end{macrocode}
% \end{macro}
%
%    \begin{macrocode}
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{0000/00/00}%
%<latexrelease>                 {\ExpandArgs}{Some pre-expansion commands}%
%<latexrelease>
%<latexrelease>\let\UseName\@undefined
%<latexrelease>\let\ExpandArgs\@undefined
%<latexrelease>\EndIncludeInRelease
%    \end{macrocode}
%
% \DescribeMacro\IfExplAtLeastTF
%   A pretty simple wrapper.
%
% \begin{macro}{\IfExplAtLeastTF}
% \changes{v1.3g}{2023/10/13}{Provide a test for \pkg{expl3} date (gh/1004)}
%    \begin{macrocode}
%<*2ekernel|latexrelease>
%<latexrelease>\IncludeInRelease{2023/11/01}%
%<latexrelease>                 {\IfExplAtLeastTF}{Test for expl3 date}%
\def\IfExplAtLeastTF{\@ifl@t@r\ExplLoaderFileDate}
%    \end{macrocode}
% \end{macro}
% We make sure the command is always available.
%    \begin{macrocode}
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{0000/00/00}%
%<latexrelease>                 {\IfExplAtLeastTF}{Test for expl3 date}%
%<latexrelease>
%<latexrelease>\def\IfExplAtLeastTF{\@ifl@t@r\ExplLoaderFileDate}
%<latexrelease>\EndIncludeInRelease
%    \end{macrocode}
%
% \Finale
