% \iffalse meta-comment
%
% Copyright (C) 1993-2025
% 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: ltdefns.dtx
%<*driver>
% \fi
\ProvidesFile{ltdefns.dtx}
             [2025/06/26 v1.5v LaTeX Kernel (definition commands)]
% \iffalse
\documentclass{ltxdoc}
\GetFileInfo{ltdefns.dtx}
\title{\filename}
\date{\filedate}
 \author{%
  Johannes Braams\and
  David Carlisle\and
  Alan Jeffrey\and
  Leslie Lamport\and
  Frank Mittelbach\and
  Chris Rowley\and
  Rainer Sch\"opf}
\begin{document}
 \MaintainedByLaTeXTeam{latex}
 \maketitle
 \DocInput{\filename}
\end{document}
%</driver>
% \fi
%
%
% \changes{v1.0n}{1994/05/10}{(ASAJ) Added
%    \cs{DeclareProtectedCommand}.}
% \changes{v1.0p}{1994/05/12}{(ASAJ) Fixed a bug with \cs{relax}
%    which was
%    using \cs{@gobble} before defining it.}
% \changes{v1.0q}{1994/05/13}{(ASAJ) Renamed
%    \cs{DeclareProtectedCommand} to
%    \cs{DeclareRobustCommand}.  Removed \cs{@if@short@command}.}
% \changes{v1.0q}{1994/05/13}{(ASAJ) Replaces \cs{space} by `~' in
%    \cs{csname}.}
% \changes{v1.0r}{1994/05/13}{(ASAJ) Added logging message to
%    \cs{DeclareProtectedCommand}.}
% \changes{v1.0s}{1994/05/13}{(ASAJ) Added \cs{@backslashchar}.}
% \changes{v1.0s}{1994/05/13}{(ASAJ) Coded \cs{@ifdefinable} more
%    efficiently.}
% \changes{v1.1a}{1994/05/16}{(ASAJ) Split from ltinit.dtx.}
% \changes{v1.1b}{1994/05/17}{(ASAJ) Removed warnings and logging to
%    lterror.dtx.}
% \changes{v1.1b}{1994/05/17}{(ASAJ) Added definitions for protect.}
% \changes{v1.1c}{1994/05/17}{(ASAJ) Redid definitions for protect.}
% \changes{v1.1d}{1994/05/19}{(RmS) Added definitions for
%           \cs{@namedef} and \cs{@nameuse} again.}
% \changes{v1.1e}{1994/05/20}{Changed command name from
%    \cs{@checkcommand} to \cs{CheckCommand}.}
% \changes{v1.1f}{1994/05/22}{Use new warning and error cmds}
% \changes{v1.2a}{1994/10/18}{Add star-forms for all commands}
% \changes{v1.2a}{1994/10/18}{Add extra test for \cs{endgraf}}
% \changes{v1.2b}{1994/10/25}{Documentation improvements}
% \changes{v1.2c}{1994/10/30}{(CAR)\cs{@onelevel@sanitize} added}
% \changes{v1.2f}{1994/10/30}{(DPC)\cs{newwrite}'s moved to ltfiles}
% \changes{v1.0g}{1994/11/17}
%         {\cs{@tempa} to \cs{reserved@a}}
% \changes{v1.0p}{1995/07/13}{Updates to documentation}
% \changes{v1.4b}{2015/02/21}
%         {Removed autoload support}
% \changes{v1.5l}{2020/08/21}{Integration of new hook management interface}
% \changes{v1.5t}{2024/04/17}
%         {Rename \cs{@expl@cs@argument@spec@@N} to
%          \cs{@expl@cs@parameter@spec@@N} (gh/1014)}
%
% \section{Definitions}
%
% This section contains commands used in defining other macros.
%
% \MaybeStop{}
%
%    \begin{macrocode}
%<*2ekernel>
%    \end{macrocode}
%
%
% \subsection{Initex initializations}
%
% \task{???}{This section needs extension}
%
% \begin{macro}{\two@digits}
% \changes{LaTeX2e}{1993/11/23}{Macro added}
%    Prefix a number less than 10 with `0'.
%    \begin{macrocode}
\def\two@digits#1{\ifnum#1<10 0\fi\number#1}
%    \end{macrocode}
% \end{macro}
%
% \changes{v1.2e}{1994/11/04}{Added \cs{set@display@protect} to
%    \cs{typeout}.  ASAJ.}
%
%  \begin{macro}{\typeout}
%    Display something on the terminal.
% \changes{v1.5g}{2020/05/15}{Allow \cs{par} in the argument (gh/335)}
%    \begin{macrocode}
%</2ekernel>
%<*2ekernel|latexrelease>
%<latexrelease>\IncludeInRelease{2020/10/01}%
%<latexrelease>                 {\typeout}{Allow "par" in \typeout}%
\protected\long\def\typeout#1{\begingroup
  \set@display@protect
  \def\par{^^J^^J}%
  \immediate\write\@unused{#1}\endgroup}
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{0000/00/00}%
%<latexrelease>                 {\typeout}{Allow "par" in \typeout}%
%<latexrelease>
%<latexrelease>\def\typeout#1{\begingroup\set@display@protect
%<latexrelease>    \immediate\write\@unused{#1}\endgroup}
%<latexrelease>\EndIncludeInRelease
%<*2ekernel>
%    \end{macrocode}
%  \end{macro}
%
%  \begin{macro}{\newlinechar}
%    A char to be used as new-line in output to files.
%    \begin{macrocode}
\newlinechar`\^^J
%    \end{macrocode}
%  \end{macro}
%
% \subsection{Saved versions of \TeX{} primitives}
%
%  The TeX primitive |\foo| is saved as |\@@foo|.
%  The following primitives are handled in this way:
% \begin{macro}{\@@par}
%    \begin{macrocode}
\let\@@par=\par
%\let\@@input=\input    %%% moved earlier
%\let\@@end=\end        %%%
%    \end{macrocode}
%  \end{macro}
%
% \begin{macro}{\@@hyph}
% Save original primitive definition.
%    \begin{macrocode}
\let\@@hyph=\-
%    \end{macrocode}
% \end{macro}
%
%
%  \begin{macro}{\@@italiccorr}
% Save the original italic correction.
% \changes{v1.0a}{1994/03/07}{Macro added}
%    \begin{macrocode}
\let\@@italiccorr=\/
%    \end{macrocode}
%  \end{macro}
%
%  \begin{macro}{\@height}
%  \begin{macro}{\@depth}
%  \begin{macro}{\@width}
%  \begin{macro}{\@minus}
% \changes{LaTeX2e}{1993/11/22}{Macro added}
%  \begin{macro}{\@plus}
% \changes{LaTeX2e}{1993/11/22}{Macro added}
%
%    The following definitions save token space.  E.g., using
%    |\@height| instead of height saves 5 tokens at the cost in time
%    of one macro expansion.
%    \begin{macrocode}
\def\@height{height} \def\@depth{depth} \def\@width{width}
\def\@minus{minus}
\def\@plus{plus}
%    \end{macrocode}
%  \begin{macro}{\hb@xt@}
% \changes{v1.2k}{1995/05/07}{Macro added}
%    The next one is another 100 tokens worth.
%    \begin{macrocode}
\def\hb@xt@{\hbox to}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%
%    \begin{macrocode}
\message{hacks,}
%    \end{macrocode}
%
% \subsection{Command definitions}
%
% This section defines the following commands:
%
% \DescribeMacro
%  {\@namedef}\marg{NAME}\\ Expands to |\def\|\meta{NAME},
%   except name can contain any characters.
%
% \DescribeMacro
%  {\@nameuse}\marg{NAME}\\
%   Expands to |\|\meta{NAME}.
%
% \DescribeMacro
%  {\@ifnextchar} X\marg{YES}\marg{NO}\\
%    Expands to \meta{YES} if next character is an `X',
%          and to \meta{NO} otherwise.
%          (Uses |\reserved@a|--|\reserved@c|.)
%          NOTE: GOBBLES ANY SPACE FOLLOWING IT.
%
% \DescribeMacro
%  {\@ifstar}\marg{YES}\marg{NO}\\
%          Gobbles following spaces and then tests if next the
%          character is a '*'.  If it is, then it gobbles the
%   `*' and expands to \meta{YES}, otherwise it expands to \meta{NO}.
%
% \DescribeMacro
%  {\@dblarg}\marg{CMD}\marg{ARG}\\
%     Expands to |\|\marg{CMD}\oarg{ARG}\marg{ARG}.  Use
%          |\@dblarg\CS| when |\CS| takes arguments |[ARG1]{ARG2}|,
%          where default is| ARG1| = |ARG2|.
%
% \DescribeMacro
%  {\@ifundefined}\marg{NAME}\marg{YES}\marg{NO}\\
%          : If \cs{NAME} is undefined then it executes \meta{YES},
%            otherwise it executes \meta{NO}.  More precisely,
%            true if \cs{NAME} either undefined or = |\relax|.
%
% \DescribeMacro
%  {\@ifdefinable}|\NAME|\marg{YES}
%       Executes \meta{YES} if the user is allowed to define |\NAME|,
%            otherwise it gives an error.  The user can define |\NAME|
%            if |\@ifundefined{NAME}| is true, '|NAME|' $\neq$ '|relax|'
%            and the first three letters of '|NAME|' are not
%           '|end|', and if |\endNAME| is not defined.
%
% \DescribeMacro
%  \newcommand|*|\marg{\cs{FOO}}\oarg{i}\marg{TEXT}\\
%         User command to define |\FOO| to be a macro with
%            i arguments (i = 0 if missing) having the definition
%            \meta{TEXT}.  Produces an error if |\FOO| already
%            defined.
%
%            Normally the command is defined to be |\long| (ie it may
%            take multiple paragraphs in its argument). In the
%            star-form, the command is not defined as |\long| and a
%            blank line in any argument to the command would generate
%            an error.
%
% \DescribeMacro
%  \renewcommand|*|\marg{\cs{FOO}}\oarg{i}\marg{TEXT}\\
%  Same as |\newcommand|, except it checks if |\FOO| already defined.
%
% \DescribeMacro
%  \newenvironment|*|\marg{FOO}\oarg{i}\marg{DEF1}\marg{DEF2}\\
%         equivalent to:\\
%         |\newcommand{\FOO}[i]{DEF1}| |\def{\endFOO}{DEF2}|\\
% (or the appropriate star forms).
%
% \DescribeMacro
%  \renewenvironment\\ Obvious companion to |\newenvironment|.
%
% \DescribeMacro
%  \@cons : See description of |\output| routine.
%
% \DescribeMacro{\@car}
%  |\@car T1 T2 ... Tn\@nil| == |T1|  (unexpanded)
%
% \DescribeMacro{\@cdr}
%  |\@cdr T1 T2 ... Tn\@ni|l == |T2 ... Tn|     (unexpanded)
%
% \DescribeMacro
%  \typeout\marg{message}\\ Produces a warning message on the terminal.
%
% \DescribeMacro
%  \typein\marg{message}\\
%        Types message, asks the user to type in a command, then
%            executes it
%
% \DescribeMacro
%  \typein\oarg{\cs{CS}}\marg{MSG}\\
%  Same as above, except defines |\CS| to be the input
%                      instead of executing it.
%
% \changes{LaTeX209}{1992/03/18}
%  {(RMS) changed input channel from 0 to \cs{@inputcheck} to avoid
%     conflicts with other channels allocated by \cs{newread}}
%
%  \begin{macro}{\typein}
%
% \changes{v1.2k}{1995/05/08}{Use \cs{@firstofone}}
% \changes{v1.2l}{1995/05/08}{Remove unnecessary braces}
% \changes{v1.2l}{1995/05/08}{Replace \cs{def} by \cs{let}}
% \changes{v1.2m}{1995/05/24}{(DPC) New implementation}
% \changes{v1.2u}{1995/10/16}{(DPC) Use \cs{@testopt} /1911}
%    \begin{macrocode}
\def\typein{%
  \let\@typein\relax
  \@testopt\@xtypein\@typein}
%    \end{macrocode}
%
% \changes{v1.2r}{1995/10/03}
%     {Add missing \cs{@typein} for /1710 (from patch file)}
% \changes{v1.4a}{2015/01/03}{use modified definition in luatex}
%    \begin{macrocode}
\ifx\directlua\@undefined
%    \end{macrocode}
%
%    \begin{macrocode}
\def\@xtypein[#1]#2{%
 \typeout{#2}%
 \advance\endlinechar\@M
 \read\@inputcheck to#1%
 \advance\endlinechar-\@M
 \@typein}%
%    \end{macrocode}
%
%    \begin{macrocode}
\else
%    \end{macrocode}
%
%    \begin{macrocode}
\def\@xtypein[#1]#2{%
  \typeout{#2}%
  \begingroup \endlinechar\m@ne
  \read\@inputcheck to#1%
  \expandafter\endgroup
  \expandafter\def\expandafter#1\expandafter{#1}%
  \@typein}%
%    \end{macrocode}
%
%    \begin{macrocode}
\fi
%    \end{macrocode}
%  \end{macro}
%
%  \begin{macro}{\@namedef}
%    \begin{macrocode}
\def\@namedef#1{\expandafter\def\csname #1\endcsname}
%    \end{macrocode}
%  \end{macro}
%
%  \begin{macro}{\@nameuse}
%    \begin{macrocode}
\def\@nameuse#1{\csname #1\endcsname}
%    \end{macrocode}
%  \end{macro}
%
%  \begin{macro}{\@cons}
%    \begin{macrocode}
\def\@cons#1#2{\begingroup\let\@elt\relax\xdef#1{#1\@elt #2}\endgroup}
%    \end{macrocode}
%  \end{macro}
%
%  \begin{macro}{\@car}
%  \begin{macro}{\@cdr}
%    \begin{macrocode}
\def\@car#1#2\@nil{#1}
\def\@cdr#1#2\@nil{#2}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%
%  \begin{macro}{\@carcube}
% |\@carcube T1 ... Tn\@nil| = |T1| |T2| |T3| , $n > 3$
% \changes{v1.5k}{2020/08/19}{Made \cs{long} for \cs{NewCommandCopy}}
% \changes{v1.5o}{2020/11/25}{Added missing latexrelease entry}
%    \begin{macrocode}
%</2ekernel>
%<latexrelease>\IncludeInRelease{2020/10/01}{\@carcube}{Make \@carcube long}%
%<*2ekernel|latexrelease>
\long\def\@carcube#1#2#3#4\@nil{#1#2#3}
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%
%<latexrelease>\IncludeInRelease{0000/00/00}{\@carcube}{Undo: Make \@carcube long}%
%<latexrelease>\def\@carcube#1#2#3#4\@nil{#1#2#3}
%<latexrelease>\EndIncludeInRelease
%<*2ekernel>
%    \end{macrocode}
%  \end{macro}
%
%
%
%  \begin{macro}{\@onlypreamble}
%  \begin{macro}{\@preamblecmds}
%    This macro adds its argument to the list of commands stored in
%    |\@preamblecmds| to be
%    disabled after |\begin{document}|. These commands are redefined
%    to generate |\@notprerr| at this point.
%    \begin{macrocode}
\def\@preamblecmds{}
\def\@onlypreamble#1{%
  \expandafter\gdef\expandafter\@preamblecmds\expandafter{%
       \@preamblecmds\do#1}}
\@onlypreamble\@onlypreamble
\@onlypreamble\@preamblecmds
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%
%
% \begin{macro}{\@star@or@long}
% \changes{v1.2a}{1994/10/18}{macro added}
% Look ahead for a |*|. If present reset |\l@ngrel@x| so that
% the next definition, |#1|,  will be non-long.
%    \begin{macrocode}
\def\@star@or@long#1{%
  \@ifstar
   {\let\l@ngrel@x\relax#1}%
   {\let\l@ngrel@x\long#1}}
%    \end{macrocode}
% \end{macro}
%

%  \begin{macro}{\l@ngrel@x}
% This is either |\relax| or |\long| depending on whether the |*|-form
% of a definition command is being executed.
%    \begin{macrocode}
\let\l@ngrel@x\relax
%    \end{macrocode}
%  \end{macro}
%
% \begin{macro}{\newcommand}
% \changes{LaTeX2e}{1993/11/23}{Macro reimplemented and extended}
%    User level |\newcommand|.%
%    \begin{macrocode}
\def\newcommand{\@star@or@long\new@command}
%    \end{macrocode}
%
% \begin{macro}{\new@command}
% \changes{v1.2u}{1995/10/16}{(DPC) Use \cs{@testopt} /1911}
%    \begin{macrocode}
\def\new@command#1{%
  \@testopt{\@newcommand#1}0}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%
%  \begin{macro}{\@newcommand}
% \changes{LaTeX2e}{1993/11/23}{Macro added}
%  \begin{macro}{\@argdef}
% \changes{LaTeX2e}{1993/11/23}{Macro added}
%  \begin{macro}{\@xargdef}
% \changes{LaTeX2e}{1993/11/23}{Macro interface changed}
% \changes{v1.1g}{2004/01/23}{Use kernel version of
%                             \cs{@ifnextchar} (pr/3501)}
%    Handling arguments for |\newcommand|.
%    \begin{macrocode}
\def\@newcommand#1[#2]{%
  \kernel@ifnextchar [{\@xargdef#1[#2]}%
                {\@argdef#1[#2]}}
%    \end{macrocode}
%    Define |#1| if it is definable.
%
%    Both here and in |\@xargdef| the replacement text is absorbed as
%    an argument because if we are not allowed to make the definition
%    we have to get rid of it completely.
%    \begin{macrocode}
\long\def\@argdef#1[#2]#3{%
   \@ifdefinable #1{\@yargdef#1\@ne{#2}{#3}}}
%    \end{macrocode}
%
% \changes{v1.2q}{1995/10/02}
%     {New implementation, using \cs{@test@opt}}
%    Handle the second optional argument.
%    \begin{macrocode}
\long\def\@xargdef#1[#2][#3]#4{%
  \@ifdefinable#1{%
%    \end{macrocode}
%    Define the actual command to be:\\
%    |\def\foo{\@protected@testopt\foo\\foo{default}}|\\
%    where |\\foo| is a csname generated from applying |\csname| and
%    |\string| to |\foo|, ie the actual name contains a backslash and
%    therefore can't clash easily with existing command names.
%    ``Default'' is the contents of the second optional argument of
%    |(re)newcommand|.
%
% \changes{v1.2z2}{1998/03/04}
%     {Unnecessary \cs{expandafter} removed: pr/2758}
%    \begin{macrocode}
     \expandafter\def\expandafter#1\expandafter{%
          \expandafter
          \@protected@testopt
          \expandafter
          #1%
          \csname\string#1\endcsname
          {#3}}%
%    \end{macrocode}
%    Now we define the internal macro ie |\\foo| which is supposed to
%    pick up all arguments (optional and mandatory).
%    \begin{macrocode}
       \expandafter\@yargdef
          \csname\string#1\endcsname
           \tw@
           {#2}%
           {#4}}}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%
% \begin{macro}{\@testopt}
% \changes{v1.2q}{1995/10/02}
%     {Macro added}
% \changes{v1.3a}{1999/01/07}
%     {made long and brace optional arg. latex/2896}
% This macro encapsulates the most common call to |\@ifnextchar|, saving
% several tokens each time it is used in the definition of a command
% with an optional argument.
% |#1| The code to execute in the case that there is a |[| \iffalse]\fi
% need not be
% a single token but can be any sequence of commands that `expects' to
% be followed by |[|. \iffalse]\fi
% If this command were only used in |\newcommand|
% definitions then |#1| would be a single token and the braces could
% be omitted from |{#1}| in the definition below, saving a bit of
% memory.
% \changes{v1.1g}{2004/01/23}{Use kernel version of
%                             \cs{@ifnextchar} (pr/3501)}
%    \begin{macrocode}
\long\def\@testopt#1#2{%
  \kernel@ifnextchar[{#1}{#1[{#2}]}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@protected@testopt}
% \changes{v1.2q}{1995/10/02}
%     {Macro added}
% Robust version of |\@testopt|. The extra argument (|#1|) must be a
% single token. If protection is needed the call expands to |\protect|
% applied to this token, and the 2nd and 3rd arguments are
% discarded (by |\@x@protect|). Otherwise |\@testopt| is called on
% the 2nd and 3rd arguments.
%
% This method of making commands robust avoids the need for using up
% two csnames per command, the price is the extra expansion time
% for the |\ifx| test.
%    \begin{macrocode}
\def\@protected@testopt#1{%
  \ifx\protect\@typeset@protect
    \expandafter\@testopt
  \else
    \@x@protect#1%
  \fi}
%    \end{macrocode}
% \end{macro}
%
%  \begin{macro}{\@yargdef}
%  \begin{macro}{\@yargd@f}
% \changes{v1.3f}{1999/04/29}{New macro added}
%
% \changes{LaTeX2e}{1993/11/23}{Macro interface changed}
% \changes{LaTeX2e}{1993/11/23}{Avoid \cs{@?@?} token}
% \changes{v1.0b}{1994/03/12}{Name changed from \cs{XXX@argdef}}
% \changes{v1.3c}{1999/01/18}{New implementation DPC /2942}
% \changes{v1.3d}{1999/02/09}{catch bad argument forms by re-inserting \#3}
% \changes{v1.3f}{1999/04/29}{Full expansion and conversion needed
%    for digit in new version, see pr/3013}
%
%    These generate a primitive argument specification, from a
%    \LaTeX\ |[|\meta{digit}|]| form; in fact \meta{digit} can be
%    anything such that |\number|~\meta{digit} is single digit.
%
%    Reorganised slightly so that |\renewcommand{\reserved@a}[1]{foo}|
%    works.  I am not sure this is worth it, as a following
%    |\newcommand| would over-write the definition of |\reserved@a|.
%
%    Recall that \LaTeX2.09 goes into an infinite loop with\\
%    |\renewcommand[1]{\@tempa}{foo}|\\
%    (DPC 6 October 93).
%
%    Reorganised again (DPC 1999). Rather than make a loop to
%    construct the argument spec by counting, just extract the
%    required argument spec by using a delimited argument (delimited
%    by the digit).  This is faster and uses less tokens. The coding
%    is slightly odd to preserve the old interface (using |#2| =
%    |\tw@| as the flag to surround the first argument with |[]|).  But
%    the new method did not allow for the number of arguments |#3| not
%    being given as an explicit digit; hence (further expansion of
%    this argument and use of) |\number| was added later in 1999.
%
%    It is not clear why these are still |\long|.
%
%    \begin{macrocode}
\long \def \@yargdef #1#2#3{%
  \ifx#2\tw@
    \def\reserved@b##11{[####1]}%
  \else
    \let\reserved@b\@gobble
  \fi
  \expandafter
    \@yargd@f \expandafter{\number #3}#1%
}
%    \end{macrocode}
%
%    \begin{macrocode}
\long \def \@yargd@f#1#2{%
  \def \reserved@a ##1#1##2##{%
    \expandafter\def\expandafter#2\reserved@b ##1#1%
    }%
  \l@ngrel@x \reserved@a 0##1##2##3##4##5##6##7##8##9###1%
}
%    \end{macrocode}
%
%  \end{macro}
%  \end{macro}
%
% \begin{macro}{\@reargdef}
%  \changes{LaTeX2e}{1993/12/20}
%                {Kept old version of \cs{@reargdef}, for array.sty}
% \changes{v1.0b}{1994/03/12}{New defn, in terms of \cs{@yargdef}}
%  \changes{v1.2y}{1996/07/26}{third arg picked up by \cs{@yargdef}}
%    \begin{macrocode}
\long\def\@reargdef#1[#2]{%
  \@yargdef#1\@ne{#2}}
%    \end{macrocode}
% \end{macro}
%
%  \begin{macro}{\renewcommand}
%    Check the command name is already used.  If not give an error
%    message. Then temporarily
%    disable |\@ifdefinable| then call |\newcommand|. (Previous
%    version |\let#1=\relax| but this does not work too well if |#1|
%    is |\@temp|\emph{a--e}.)
% \changes{LaTeX2e}{1993/11/23}{Macro reimplemented and extended}
% \changes{v1.1f}{1994/05/02}{Removed surplus \cs{space} in error}
%    \begin{macrocode}
\def\renewcommand{\@star@or@long\renew@command}
%    \end{macrocode}
%
%  \begin{macro}{\renew@command}
%  \changes{v1.2y}{1996/07/26}{use \cs{relax} in place of empty arg}
%  \changes{v1.2y}{1996/07/26}{use \cs{noexpand} instead of \cs{string}}
% \changes{v1.2z1}{1997/10/21}{Use \cs{begingroup}/\cs{endgroup} rather
%    than braces for grouping, to avoid generating empty math atom.}
% \changes{v1.5e}{2018/09/26}{Always explicitly generate a space after the csname and
%    not rely on \cs{noexpand} to save tokens (gh/41)}
%  \changes{v1.5u}{2025/06/03}{Strip trailing spaces from arg (gh/1708)}
%    \begin{macrocode}
\def\renew@command#1{%
  \begingroup
    \escapechar\m@ne\xdef\@gtempa{{\expandafter\string\@car#1?\@nil}}%
  \endgroup
  \expandafter\@ifundefined\@gtempa
     {\@latex@error{Command \string#1 undefined}\@ehc}%
     \relax
  \let\@ifdefinable\@rc@ifdefinable
  \new@command#1}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%
% \changes{v1.0n}{1994/05/10}{Removed braces around \cs{@ifundefined}
%    argument.  ASAJ.}
% \changes{v1.0s}{1994/05/13}{Coded more efficiently, thanks to FMi.}
%
%  \begin{macro}{\@ifdefinable}
%  \begin{macro}{\@@ifdefinable}
%  \begin{macro}{\@rc@ifdefinable}
%    Test if user is allowed to define a command.
%    \begin{macrocode}
\long\def\@ifdefinable #1#2{%
      \edef\reserved@a{\expandafter\@gobble\string #1}%
     \@ifundefined\reserved@a
         {\edef\reserved@b{\expandafter\@carcube \reserved@a xxx\@nil}%
          \ifx \reserved@b\@qend \@notdefinable\else
            \ifx \reserved@a\@qrelax \@notdefinable\else
              #2%
            \fi
          \fi}%
         \@notdefinable}
%    \end{macrocode}
%    Saved definition of |\@ifdefinable|.
%    \begin{macrocode}
\let\@@ifdefinable\@ifdefinable
%    \end{macrocode}
%    Version of |\@ifdefinable| for use with |\renewcommand|.  Does
%    not do the check this time, but restores the normal definition.
%    \begin{macrocode}
\long\def\@rc@ifdefinable#1#2{%
  \let\@ifdefinable\@@ifdefinable
  #2}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%
% \begin{macro}{\newenvironment}
%    Define a new user environment.
%    |#1| is the environment name. |#2#| Grabs all the tokens up to
%    the first |{|. \iffalse}\fi
%    These will be any optional arguments. They are not
%    parsed at this point, but are just passed to |\@newenv| which
%    will eventually call |\newcommand|. Any optional arguments will
%    then be parsed by |\newcommand| as it defines the command that
%    executes the `begin code' of the environment.
%
% This |#2#| trick removed with version 1.2i as it fails if a |{| \iffalse}\fi
% occurs in the optional argument. Now use |\@ifnextchar| directly.
%    \begin{macrocode}
\def\newenvironment{\@star@or@long\new@environment}
%    \end{macrocode}
%
% \begin{macro}{\new@environment}
% \changes{v1.2i}{1995/04/25}{Parse arguments slowly but safely /1507}
% \changes{v1.2u}{1995/10/16}{(DPC) Use \cs{@testopt} /1911}
%    \begin{macrocode}
\def\new@environment#1{%
  \@testopt{\@newenva#1}0}
%    \end{macrocode}
%
% \begin{macro}{\@newenva}
% \changes{v1.1g}{2004/01/23}{Use kernel version of
%                             \cs{@ifnextchar} (pr/3501)}
%    \begin{macrocode}
\def\@newenva#1[#2]{%
   \kernel@ifnextchar [{\@newenvb#1[#2]}{\@newenv{#1}{[#2]}}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@newenvb}
% \changes{v1.3a}{1999/01/07}
%     {made long and brace optional arg. latex/2896}
%    \begin{macrocode}
\def\@newenvb#1[#2][#3]{\@newenv{#1}{[#2][{#3}]}}
%    \end{macrocode}
% \end{macro}
%
% \end{macro}
% \end{macro}
%
%
%  \begin{macro}{\renewenvironment}
%    Redefine an environment.
%    For |\renewenvironment| disable |\@ifdefinable| and then call
%    |\newenvironment|.  It is OK to |\let| the argument to |\relax|
%    here as there should not be a |@temp|\ldots\ environment.
% \changes{LaTeX2e}{1993/11/23}{Macro reimplemented and extended}
% \changes{v1.1f}{1994/05/02}{Removed surplus \cs{space} in error}
%    \begin{macrocode}
\def\renewenvironment{\@star@or@long\renew@environment}
%    \end{macrocode}
%
%  \begin{macro}{\renew@environment}
% \changes{v1.2a}{1994/10/18}{reset end command}
% \changes{v1.2y}{1996/07/26}{use \cs{relax} in place of empty arg}
%    \begin{macrocode}
\def\renew@environment#1{%
  \@ifundefined{#1}%
     {\@latex@error{Environment #1 undefined}\@ehc
     }\relax
  \expandafter\let\csname#1\endcsname\relax
  \expandafter\let\csname end#1\endcsname\relax
  \new@environment{#1}}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%
%
% \begin{macro}{\@newenv}
% \changes{LaTeX2e}{1993/11/23}{Macro interface changed}
% \changes{v1.2h}{1994/11/24}{Added test for \cs{endgraf}}
%    The internal version of |\newenvironment|.
%
%    Call |\newcommand| to define the \meta{begin-code} for the
%    environment.  |\def| is used for the \meta{end-code} as it does
%    not take arguments. (but may contain |\par|s)
%
% Make sure that an attempt to define a `graf' or `group' environment
% fails by temporarily letting the undefined \verb=\...= (begin code) to
% the definition of \verb=\end...= and as a result we get an error if that
% has a definition.
%    \begin{macrocode}
\long\def\@newenv#1#2#3#4{%
  \@ifundefined{#1}%
    {\expandafter\let\csname#1\expandafter\endcsname
                         \csname end#1\endcsname}%
    \relax
  \expandafter\new@command
     \csname #1\endcsname#2{#3}%
     \l@ngrel@x\expandafter\def\csname end#1\endcsname{#4}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\newif}
% \changes{v1.1l}{1995/05/24}{(DPC) New implementation}
% And here's a different sort of allocation:
% For example,
% |\newif\iffoo| creates |\footrue|, |\foofalse| to go with |\iffoo|.
%    \begin{macrocode}
\def\newif#1{%
  \count@\escapechar \escapechar\m@ne
    \let#1\iffalse
    \@if#1\iftrue
    \@if#1\iffalse
  \escapechar\count@}
%    \end{macrocode}
%
% \begin{macro}{\@if}
%    \begin{macrocode}
\def\@if#1#2{%
  \expandafter\def\csname\expandafter\@gobbletwo\string#1%
                    \expandafter\@gobbletwo\string#2\endcsname
                       {\let#1#2}}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%
% \begin{macro}{\providecommand}
% |\providecommand| takes the same arguments as |\newcommand|, but
% discards them if |#1| is already defined, Otherwise it just acts like
% |\newcommand|. This implementation currently leaves any discarded
% definition in |\reserved@a| (and possibly |\\reserved@a|) this
% wastes a bit of space, but it will be reclaimed as soon as these
% scratch macros are redefined.
%
% \changes{LaTeX2e}{1993/11/22}{Macro added}
%    \begin{macrocode}
\def\providecommand{\@star@or@long\provide@command}
%    \end{macrocode}
%
% \begin{macro}{\provide@command}
% \changes{v1.2z}{1997/09/09}{Use \cs{begingroup} to avoid generating
%    math ords if used in math mode. pr/2573}
%  \changes{v1.5u}{2025/06/03}{Strip trailing spaces from arg (gh/1708)}
%    \begin{macrocode}
\def\provide@command#1{%
  \begingroup
    \escapechar\m@ne\xdef\@gtempa{{\expandafter\string\@car#1?\@nil}}%
  \endgroup
  \expandafter\@ifundefined\@gtempa
    {\def\reserved@a{\new@command#1}}%
    {\def\reserved@a{\renew@command\reserved@a}}%
   \reserved@a}%
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\CheckCommand}
% \changes{LaTeX2e}{1993/11/22}{Macro added}
% \changes{v1.1e}{1994/05/20}{Changed name from \cs{@checkcommand} to
%    \cs{CheckCommand}.}
%    |\CheckCommand| takes the same arguments as |\newcommand|. If
%    the command already exists, with the same definition, then
%    nothing happens, otherwise a warning is issued. Useful for
%    checking the current state before a macro package starts
%    redefining things.  Currently two macros are considered to have
%    the same definition if they are the same except for different
%    default arguments.  That is, if the old definition was:
%    |\newcommand\xxx[2][a]{(#1)(#2)}| then
%    |\CheckCommand\xxx[2][b]{(#1)(#2)}| would \emph{not} generate a
%    warning, but, for instance |\CheckCommand\xxx[2]{(#1)(#2)}|
%    would.
%    \begin{macrocode}
\def\CheckCommand{\@star@or@long\check@command}
%    \end{macrocode}
%    |\CheckCommand| is only available in the preamble part of the
%    document.
%    \begin{macrocode}
\@onlypreamble\CheckCommand
%    \end{macrocode}
%
% \begin{macro}{\check@command}
%    \begin{macrocode}
\def\check@command#1#2#{\@check@c#1{#2}}
\@onlypreamble\check@command
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\@check@c}
% \changes{v1.2i}{1995/04/25}{Make \cs{long} for latex/1346}
%    |\CheckCommand| itself just grabs all the arguments we need,
%    without actually looking for |[| \iffalse]\fi
%    optional argument forms.  Now
%    define |\reserved@a|. If |\\reserved@a| is then defined, compare it
%    with the ``|\#1|' otherwise compare |\reserved@a| with |#1|.
%    \begin{macrocode}
\long\def\@check@c#1#2#3{%
  \expandafter\let\csname\string\reserved@a\endcsname\relax
  \renew@command\reserved@a#2{#3}%
  \@ifundefined{\string\reserved@a}%
   {\@check@eq#1\reserved@a}%
   {\expandafter\@check@eq
           \csname\string#1\expandafter\endcsname
           \csname\string\reserved@a\endcsname}}
\@onlypreamble\@check@c
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@check@eq}
%     Complain if |#1| and |#2| are not |\ifx| equal.
%    \begin{macrocode}
\def\@check@eq#1#2{%
  \ifx#1#2\else
     \@latex@warning@no@line
               {Command \noexpand#1 has
                changed.\MessageBreak
                Check if current package is valid}%
  \fi}
\@onlypreamble\@check@eq
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@gobble}
% \begin{macro}{\@gobbletwo}
% \begin{macro}{\@gobblethree}
% \changes{v1.5g}{2020/02/27}{Macro added}
% \begin{macro}{\@gobblefour}
% \changes{v1.2n}{1995/05/26}{(CAR) Added \cs{long}s}
%    The |\@gobble| macro is used to get rid of its argument.
%    \begin{macrocode}
\long\def \@gobble #1{}
\long\def \@gobbletwo #1#2{}
\long\def \@gobblethree #1#2#3{}
\long\def \@gobblefour #1#2#3#4{}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% There are also \cs{@gobble@om}, \cs{@gobble@som},
% \cs{@gobble@with@sphack@om}, and \cs{@gobble@with@sphack@som}. They
% accept an optional and a mandatory argument, possibly preceeded by a
% star. In all cases the expansion is empty or just manipulates the
% spaces around the command.  Used to disable commands such as
% \cs{index} or \cs{label} in certain situations.  Since they are
% defined with \cs{DeclareDocumentCommand}, which is not yet available
% at this point, the actual definition happens in \texttt{ltsect.dtx}.
%
% \begin{macro}{\@firstofone}
% \begin{macro}{\@firstoftwo}
% \begin{macro}{\@secondoftwo}
%    Some argument-grabbers.
%    \begin{macrocode}
\long\def\@firstofone#1{#1}
\long\def\@firstoftwo#1#2{#1}
\long\def\@secondoftwo#1#2{#2}
%    \end{macrocode}
% \begin{macro}{\@iden}
%    |\@iden| is another name for |\@firstofone| for
%    compatibility reasons.
%    \begin{macrocode}
\let\@iden\@firstofone
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\@thirdofthree}
%    Another grabber now used in the encoding specific
%    section.
% \changes{v1.2z3}{1998/03/20}{Macro added}
%    \begin{macrocode}
\long\def\@thirdofthree#1#2#3{#3}
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\@expandtwoargs}
%    A macro to totally expand two arguments to another macro
% \changes{v1.5r}{2022/10/22}{Use \cs{protected@edef}.}
%    \begin{macrocode}
%</2ekernel>
%<latexrelease>\IncludeInRelease{2022/11/01}%
%<latexrelease>        {\@expandtwoargs}{protected edef}%
%<*2ekernel|latexrelease>
\def\@expandtwoargs#1#2#3{%
\protected@edef\reserved@a{\noexpand#1{#2}{#3}}\reserved@a}
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{00/00/00}%
%<latexrelease>        {\@expandtwoargs}{protected edef}%
%<latexrelease>\def\@expandtwoargs#1#2#3{%
%<latexrelease>\edef\reserved@a{\noexpand#1{#2}{#3}}\reserved@a}
%<latexrelease>\EndIncludeInRelease
%<*2ekernel>
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@backslashchar}
%    A category code 12 backslash.
%    \begin{macrocode}
\edef\@backslashchar{\expandafter\@gobble\string\\}
%    \end{macrocode}
% \end{macro}
%
% \changes{v1.0n}{1994/05/10}{Added \cs{DeclareProtectedCommand}}
% \changes{v1.0p}{1994/05/12}{Fixed a bug with \cs{relax } which was
%    using \cs{@gobble} before defining it.}
% \changes{v1.0q}{1994/05/13}{Renamed \cs{DeclareProtectedCommand} to
%    \cs{DeclareRobustCommand}.  Removed \cs{@if@short@command}.
%    Moved to after the definition of \cs{@gobble}.}
% \changes{v1.0r}{1994/05/13}{Added logging message to
%    \cs{DeclareProtectedCommand}.}
%
% \subsection{Robust commands and protect}
%
% \changes{v1.1b}{1994/05/17}{Added the discussion of protected
%    commands, defined the values that \cs{protect} should have.}
% \changes{v1.1c}{1994/05/18}{Redid the discussion and definitions, in
%    line with the proposed new setting of \cs{protect} in the output
%    routine.}
%
% Fragile and robust commands are one of the thornier issues in
% \LaTeX's commands.  Whilst typesetting documents, \LaTeX{} makes use
% of many of \TeX's features, such as arithmetic, defining macros, and
% setting variables.  However, there are (at least) three different
% occasions when these commands are not safe.  These are called
% `moving arguments' by \LaTeX, and consist of:
% \begin{itemize}
% \item writing information to a file, such as indexes or tables of
%    contents.
% \item writing information to the screen.
% \item inside an |\edef|, |\message|, |\mark|, or other command which
%    evaluates its argument fully.
% \end{itemize}
% The method \LaTeX{} uses for making fragile commands robust is to
% precede them with |\protect|.  This can have one of four possible
% values:
% \begin{itemize}
% \item |\relax|, for normal typesetting.  So |\protect\foo| will
%    execute |\foo|.
% \item |\string|, for writing to the screen.  So |\protect\foo| will
%    write |\foo|.
% \item |\noexpand|, for writing to a file.  So |\protect\foo| will
%    write |\foo| followed by a space.
% \item |\@unexpandable@protect|, for writing a moving argument to a
%    file.  So |\protect\foo| will write |\protect\foo| followed by a
%    space.  This value is also used inside |\edef|s, |\mark|s and
%    other commands which evaluate their arguments fully.
%    More precisely, whenever the content of an |\edef| or |\xdef| etc.\
%    can contain arbitrary user input not under the direct control of the
%    programmer, one should use |\proetected@edef| instead of |\edef|, etc.,
%    so that |\protect| has a suitable definition and the user input will
%    not break if it contains fragile commands.
% \end{itemize}
%
% \changes{1.1b}{1994/05/17}
%     {(ASAJ) Added the \cs{@protect@...} commands.}
% \changes{1.1c}{1994/05/18}
%     {(ASAJ) Renamed the commands, and removed
%       one which is no longer needed.}
%
% \begin{macro}{\@unexpandable@protect}
% \changes{1.2w}{1995/12/05}{Removed \cs{unexpandable@noexpand} as never used. internal/1733}
%    \begin{macrocode}
\def\@unexpandable@protect{\noexpand\protect\noexpand}
%    \end{macrocode}
% \end{macro}
%
% \changes{v1.2e}{1994/11/04}{Rewrote protected short commands
%    using \cs{x@protect}. ASAJ.}
%
% \begin{macro}{\DeclareRobustCommand}
% \begin{macro}{\declare@robustcommand}
% \changes{v1.5v}{2025-06-26}{Allow for active chars}
% \begin{macro}{\declare@robustcommand@auxi}
% \changes{v1.5v}{2025-06-26}{New macro}
% \begin{macro}{\declare@robustcommand@auxii}
% \changes{v1.5v}{2025-06-26}{New macro}
% \begin{macro}{\declare@robustcommand@auxiii}
% \changes{v1.5v}{2025-06-26}{New macro}
%    This is a package-writers command, which has the same syntax as
%    |\newcommand|, but which declares a protected command.  It does
%    this by having\\
%    |\DeclareRobustCommand\foo|\\
%    define |\foo| to be
%    |\protect\foo<space>|,\\
%    and then use |\newcommand\foo<space>|.\\
%    Since the internal command is |\foo<space>|, when it is written
%    to an auxiliary file, it will appear as |\foo|.
%
%    We have to be a
%    bit cleverer if we're defining a short command, such as |\_|, in
%    order to make sure that the auxiliary file does not include a
%    space after the command, since |\_ a| and |\_a| aren't the same.
%    In this case we define |\_| to be:
%\begin{verbatim}
%    \x@protect\_\protect\_<space>
%\end{verbatim}
%    which expands to:
%\begin{verbatim}
%    \ifx\protect\@typeset@protect\else
%       \@x@protect@\_
%    \fi
%    \protect\_<space>
%\end{verbatim}
%    Then if |\protect| is |\@typeset@protect| (normally |\relax|)
%    then we just perform |\_<space>|, and otherwise
%    |\@x@protect@| gobbles everything up and expands to
%    |\protect\_|. None of that works with an active char (as we have only one
%    character token to play with), so we resort to using the engine mechanism
%    there. (The braces in passing |#1| there are defensive in case someone has
%    passed more than one token!)
%
%    \emph{Note}: setting |\protect| to any value other than |\relax|
%    whilst in `typesetting' mode will cause commands to go into an
%    infinite loop!  In particular, setting |\protect| to |\@empty| will
%    cause |\_| to loop forever.  It will also break lots of other
%    things, such as protected |\ifmmode|s inside |\halign|s.  If you
%    really have to do such a thing, then please set
%    |\@typeset@protect| to be |\@empty| as well.  (This is what the
%    code for |\patterns| does, for example.)
%
%    More fun with |\expandafter| and |\csname|.
%    \begin{macrocode}
\def\DeclareRobustCommand{\@star@or@long\declare@robustcommand}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\declare@robustcommand#1{%
   \ifx\@undefined#1\else\ifx\relax#1\else
      \@latex@info{Redefining \string#1}%
   \fi\fi
  \ifcat\noexpand~\noexpand#1%
    \expandafter\declare@robustcommand@auxi
  \else
    \expandafter\declare@robustcommand@auxiii
  \fi
    {#1}%
}
%    \end{macrocode}
%   For active chars, we cannot use an auxiliary so have to `pack' everything we need
%   in one definition. To allow for use in file names, etc., we need \cs{ifincsname}]
%   in the definition, so we use two steps to grab that. We also take advantage
%   of the need for an extra auxiliary to do some expansion to give us the string
%   we will want.
%    \begin{macrocode}
\protected\long\def\declare@robustcommand@auxi#1#2#{%
  \expandafter\declare@robustcommand@auxii\expandafter{\string#1}#1{#2}%
}
\protected\long\def\declare@robustcommand@auxii#1#2#3#4{%
  \ifx\l@ngrel@x\relax
    \let\l@ngrel@x\protected
  \else
    \def\l@ngrel@x{\protected\long}%
  \fi
   \let\@ifdefinable\@rc@ifdefinable
   \new@command#2#3{%
       \ifincsname
         \expandafter\@firstoftwo
       \else
         \expandafter\@secondoftwo
      \fi
      {#1}{#4}%
    }%
  }
\protected\def\declare@robustcommand@auxiii#1{%
   \edef\reserved@a{\string#1}%
   \def\reserved@b{#1}%
   \edef\reserved@b{\expandafter\strip@prefix\meaning\reserved@b}%
   \edef#1{%
      \ifx\reserved@a\reserved@b
         \noexpand\x@protect
         \noexpand#1%
      \fi
      \noexpand\protect
      \expandafter\noexpand\csname
         \expandafter\@gobble\string#1 \endcsname
   }%
   \let\@ifdefinable\@rc@ifdefinable
   \expandafter\new@command\csname
      \expandafter\@gobble\string#1 \endcsname
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
% \begin{macro}{\@x@protect}
% \begin{macro}{\x@protect}
%
%    \begin{macrocode}
\def\x@protect#1{%
   \ifx\protect\@typeset@protect\else
      \@x@protect#1%
   \fi
}
\def\@x@protect#1\fi#2#3{%
   \fi\protect#1%
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\@typeset@protect}
%     We set \cs{@typeset@protect} to \cs{relax} rather than \cs{@empty}
%     to make sure that the protection mechanism stops the look-ahead
%     and expansion performed at the start of \cs{halign} cells.
%    \begin{macrocode}
\let\@typeset@protect\relax
%    \end{macrocode}
% \end{macro}
%
% \changes{v1.2e}{1994/11/04}{Added commands for setting and restoring
%    \cs{protect}.  ASAJ.}
%
% \begin{macro}{\set@display@protect}
% \begin{macro}{\set@typeset@protect}
%    These macros set |\protect| appropriately for typesetting or
%    displaying.
% \changes{v1.2o}{1995/07/03}{Use \cs{@typeset@protect} for init}
%    \begin{macrocode}
\def\set@display@protect{\let\protect\string}
\def\set@typeset@protect{\let\protect\@typeset@protect}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\protected@edef}
% \begin{macro}{\protected@xdef}
% \begin{macro}{\unrestored@protected@xdef}
% \begin{macro}{\restore@protect}
%    The commands |\protected@edef| and |\protected@xdef| perform
%    `safe' |\edef|s and |\xdef|s, saving and restoring |\protect|
%    appropriately.  For cases where restoring |\protect| doesn't
%    matter, there's an `unsafe' |\unrestored@protected@xdef|, useful
%    if you know what you're doing!
%    \begin{macrocode}
\def\protected@edef{%
   \let\@@protect\protect
   \let\protect\@unexpandable@protect
   \afterassignment\restore@protect
   \edef
}
\def\protected@xdef{%
   \let\@@protect\protect
   \let\protect\@unexpandable@protect
   \afterassignment\restore@protect
   \xdef
}
\def\unrestored@protected@xdef{%
   \let\protect\@unexpandable@protect
   \xdef
}
\def\restore@protect{\let\protect\@@protect}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
%  \begin{macro}{\protect}
%    The normal meaning of |\protect|
% \changes{v1.2j}{1995/04/29}{Init \cs{protect} here}
%    \begin{macrocode}
\set@typeset@protect
%    \end{macrocode}
%  \end{macro}
%
% \begin{macro}{\MakeRobust}
% \changes{v1.4a}{2015/01/08}{Added macro}
% \changes{v1.5f}{2019/08/27}{Make the assignments global as we may
%   need to apply them inside a group}
% \changes{v1.5m}{2020/08/21}{Make \cs{MakeRobust} produce the same
%   command structure as \cs{DeclareRobustCommand}}
%
%    This macro makes an existing fragile macro robust, but only if it
%    hasn't been robust in the past, i.e., it checks for the existence
%    of the macro
%    \verb*=\<name> = and if that exists it assumes that
%    \verb=\<name>= is already robust. In that case either undefine
%    the inner macro first or use \cs{DeclareRobustCommand} to
%    define it in a robust way directly.  We could probably test the
%    top-level definition to have the right kind of structure, but
%    this is somewhat problematical as we then have to distinguish
%    between \cs{long} macros and others and also take into account
%    that sometimes the top-level is deliberately done manually (like
%    with \cs{begin}).
%
%    The macro firstly checks if the control sequence in question exists
%    at all.
% \changes{v1.5p}{2021/05/26}{Normalize error message in \cs{MakeRobust}}
%    \begin{macrocode}
%</2ekernel>
%<latexrelease>\IncludeInRelease{2020/10/01}{\MakeRobust}{\MakeRobust}%
%<*2ekernel|latexrelease>
\def\MakeRobust#1{%
  \count@=\escapechar
  \escapechar=`\\
  \@ifundefined{\expandafter\@gobble\string#1}{%
    \@latex@error{Command `\string#1' undefined.%
      \MessageBreak There is nothing here to make robust}%
    \@eha
  }%
%    \end{macrocode}
% Then we check if the macro is already robust. We do this by testing
% if the internal name for a robust macro is defined, namely
% \verb*=\foo =. If it is already defined do nothing, otherwise set
% \verb*=\foo = equal to \verb*=\foo= and redefine \verb*=\foo= so
% that it acts like a macro defined with \verb=\DeclareRobustCommand=.
% We use \cs{@kernel@rename@newcommand} to copy \verb*=\foo= over to
% \verb*=\foo =, including a possible default optional argument.
%    \begin{macrocode}
  {%
    \@ifundefined{\expandafter\@gobble\string#1\space}%
    {%
      \expandafter\@kernel@rename@newcommand
        \csname\expandafter\@gobble\string#1\space\endcsname
        #1%
      \edef\reserved@a{\string#1}%
      \def\reserved@b{#1}%
      \edef\reserved@b{\expandafter\strip@prefix\meaning\reserved@b}%
      \xdef#1{%
        \ifx\reserved@a\reserved@b
          \noexpand\x@protect\noexpand#1%
        \fi
        \noexpand\protect\expandafter\noexpand
        \csname\expandafter\@gobble\string#1\space\endcsname}%
    }%
    {\@latex@info{Command `\string#1' is already robust}}%
  }%
  \escapechar=\count@
}%
%    \end{macrocode}
%
%  \begin{macro}{\@kernel@rename@newcommand}
%    This macro renames a command, possibly with an optional argument (defined
%    with \cs{newcommand}) from |#2| to |#1|, by renaming the internal macro
%    \verb=\\#2= to \verb=\\#1= and defining \verb=\#1= appropriately, then
%    undefining \verb=\#2= and \verb=\\#2=.  The \cs{afterassignment} trick is
%    to make both definitions in \cs{@copy@newcommand} global (which are local
%    by default).
%
%    In case the macro was defined with \cs{newcommand} and an optional
%    argument, to replicate exactly the behaviour of \cs{DeclareRobustCommand}
%    we have to move also the internal \verb*=\\foo= to \verb*=\\foo =.  In that
%    case, \verb=#1= will be a parameterless macro (\cs{robust@command@chk@safe}
%    checks that), and \cs{@if@newcommand} will return true (both defined below
%    in this file).  If so, we can use \cs{@copy@newcommand} rather than plain
%    \cs{let} to copy the command over.  \cs{@kernel@rename@newcommand} does
%    this test and carries out the renaming.
%    \begin{macrocode}
\def\@kernel@rename@newcommand#1#2{%
  \robust@command@chk@safe#2%
    {\@if@newcommand#2%
      {\afterassignment\global
       \global\@copy@newcommand#1#2%
       \global\let#2\@undefined
       \global\expandafter\let\csname\string#2\endcsname\@undefined}%
      {\global\let#1=#2}}%
    {\global\let#1=#2}}
%    \end{macrocode}
%  \end{macro}
%
%    \begin{macrocode}
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%
%<latexrelease>\IncludeInRelease{2019/10/01}{\MakeRobust}{\MakeRobust}%
%<latexrelease>\def\MakeRobust#1{%
%<latexrelease>  \@ifundefined{\expandafter\@gobble\string#1}{%
%<latexrelease>    \@latex@error{The control sequence `\string#1' is undefined!%
%<latexrelease>      \MessageBreak There is nothing here to make robust}%
%<latexrelease>    \@eha
%<latexrelease>  }%
%<latexrelease>  {%
%<latexrelease>    \@ifundefined{\expandafter\@gobble\string#1\space}%
%<latexrelease>    {%
%<latexrelease>      \global\expandafter\let\csname
%<latexrelease>      \expandafter\@gobble\string#1\space\endcsname=#1%
%<latexrelease>      \edef\reserved@a{\string#1}%
%<latexrelease>      \def\reserved@b{#1}%
%<latexrelease>      \edef\reserved@b{\expandafter\strip@prefix\meaning\reserved@b}%
%<latexrelease>      \xdef#1{%
%<latexrelease>        \ifx\reserved@a\reserved@b
%<latexrelease>          \noexpand\x@protect\noexpand#1%
%<latexrelease>        \fi
%<latexrelease>        \noexpand\protect\expandafter\noexpand
%<latexrelease>        \csname\expandafter\@gobble\string#1\space\endcsname}%
%<latexrelease>    }%
%<latexrelease>    {\@latex@info{The control sequence `\string#1' is already robust}}%
%<latexrelease>   }%
%<latexrelease>}%
%<latexrelease>\let\@kernel@rename@newcommand\@undefined
%<latexrelease>\EndIncludeInRelease
%
%<latexrelease>\IncludeInRelease{2015/01/01}{\MakeRobust}{\MakeRobust}%
%<latexrelease>\def\MakeRobust#1{%
%<latexrelease>  \@ifundefined{\expandafter\@gobble\string#1}{%
%<latexrelease>    \@latex@error{The control sequence `\string#1' is undefined!%
%<latexrelease>      \MessageBreak There is nothing here to make robust}%
%<latexrelease>    \@eha
%<latexrelease>  }%
%<latexrelease>  {%
%<latexrelease>    \@ifundefined{\expandafter\@gobble\string#1\space}%
%<latexrelease>    {%
%<latexrelease>      \expandafter\let\csname
%<latexrelease>      \expandafter\@gobble\string#1\space\endcsname=#1%
%<latexrelease>      \edef\reserved@a{\string#1}%
%<latexrelease>      \def\reserved@b{#1}%
%<latexrelease>      \edef\reserved@b{\expandafter\strip@prefix\meaning\reserved@b}%
%<latexrelease>      \edef#1{%
%<latexrelease>        \ifx\reserved@a\reserved@b
%<latexrelease>          \noexpand\x@protect\noexpand#1%
%<latexrelease>        \fi
%<latexrelease>        \noexpand\protect\expandafter\noexpand
%<latexrelease>        \csname\expandafter\@gobble\string#1\space\endcsname}%
%<latexrelease>    }%
%<latexrelease>    {\@latex@info{The control sequence `\string#1' is already robust}}%
%<latexrelease>   }%
%<latexrelease>}%
%<latexrelease>\let\@kernel@rename@newcommand\@undefined
%<latexrelease>\EndIncludeInRelease
%
%<latexrelease>\IncludeInRelease{0000/00/00}{\MakeRobust}{\MakeRobust}%
%<latexrelease>\let\MakeRobust\@undefined
%<latexrelease>\let\@kernel@rename@newcommand\@undefined
%<latexrelease>\EndIncludeInRelease
%<*2ekernel>
%    \end{macrocode}
% \end{macro}
%
%  \begin{macro}{\kernel@make@fragile}
%    The opposite of |\MakeRobust| except that it doesn't do many
%    checks as it is internal to the kernel. Why does one want such a
%    thing?
%    Only for compatibility reasons if \texttt{latexrelease} requests
%    a rollback of the kernel. For this reason we pretend that this
%    command existed in all earlier versions of \LaTeX{} i.e., we are
%    not rolling it back since we need it precisely then. But we have
%    to get it into the \texttt{latexrelease} file so that a roll
%    forward is possible too.
%    \begin{macrocode}
%</2ekernel>
%<*2ekernel|latexrelease>
%<latexrelease>\IncludeInRelease{2020/10/01}%
%<latexrelease>                 {\kernel@make@fragile}{Undo robustness}%
\def\kernel@make@fragile#1{%
  \@ifundefined{\expandafter\@gobble\string#1\space}%
%    \end{macrocode}
%    If not robust do nothing.
%    \begin{macrocode}
     {}%
%    \end{macrocode}
%    Otherwise copy \verb*=\foo = back to \verb=\foo=.
%    Then use \cs{@kernel@rename@newcommand} to check and copy
%    \verb*=\\foo = back to \verb*=\\foo= in case the command has an optional
%    argument.  If so, also undefine \verb*=\\foo =, and at the end undefine
%    \verb*=\foo =.
%    \begin{macrocode}
     {%
      \global\expandafter\let\expandafter #1\csname
        \expandafter\@gobble\string#1\space\endcsname
      \expandafter\@kernel@rename@newcommand
        \csname\expandafter\@gobble\string#1\expandafter\endcsname
        \csname\expandafter\@gobble\string#1\space\endcsname
      \global\expandafter\let\csname
        \expandafter\@gobble\string#1\space\endcsname\@undefined
     }%
}
%    \end{macrocode}
%
%    \begin{macrocode}
%<latexrelease>\EndIncludeInRelease
%
%<latexrelease>\IncludeInRelease{0000/00/00}%
%<latexrelease>                 {\kernel@make@fragile}{Undo robustness}%
%<latexrelease>\def\kernel@make@fragile#1{%
%<latexrelease>  \@ifundefined{\expandafter\@gobble\string#1\space}%
%<latexrelease>     {}%
%<latexrelease>     {%
%<latexrelease>      \global\expandafter\let\expandafter #1\csname
%<latexrelease>      \expandafter\@gobble\string#1\space\endcsname
%<latexrelease>      \global\expandafter\let\csname
%<latexrelease>      \expandafter\@gobble\string#1\space\endcsname\@undefined
%<latexrelease>     }%
%<latexrelease>}
%<latexrelease>\EndIncludeInRelease
%</2ekernel|latexrelease>
%<*2ekernel>
%    \end{macrocode}
%  \end{macro}
%
%
% \subsection{Acting on robust commands}
%
%    \begin{macrocode}
%</2ekernel>
%<latexrelease>\IncludeInRelease{2020-10-01}{\robust@command@act}
%<latexrelease>  {Add \robust@command@act}%
%<*2ekernel|latexrelease>
%    \end{macrocode}
%
%   With most document level commands being robust now there is more of a
%   requirement to have a standard way of aliasing (or copying) a command to a
%   new name, for example to save an original definition before changing a
%   command.  \cs{DeclareCommandCopy} is analogous to \TeX's \cs{let}, except
%   that it copes with the different types of robust commands defined by
%   \LaTeX's mechanisms.
%
%   A couple of ``types of robustness'' are defined by the \LaTeXe{} kernel,
%   namely robust commands defined with \cs{DeclareRobustCommand} and commands
%   with optional arguments defined with \cs{newcommand}.  However there are
%   other types of robust commands that are frequently used, which are not
%   defined in the \LaTeXe{} kernel, like commands defined with
%   \textsf{xparse}'s \cs{NewDocumentCommand} and \textsf{etoolbox}'s
%   \cs{newrobustcmd}.
%
%   In this section we will define a generic extensible machinery to act on
%   robust commands.  This code will then be used to test if a command is
%   robust, considered the different types of robustness, and then either copy
%   that definition, if \cs{DeclareCommandCopy} (or similar) is used, or show
%   the definition of the command, if \cs{ShowCommand} is used.
%
% \begin{macro}{\robust@command@act}
% \changes{v1.5k}{2020/08/19}{Made \cs{robust@command@act}
%     (was \cs{declare@command@copy}) more generic}
%
%   The looping machinery is generic and knows nothing about what is to be done
%   for each case.  The syntax of the main macro \cs{robust@command@act} is:
%   \begin{quote}
%     |\robust@command@act|\meta{action-list}\meta{robust-cmd}\\
%       \meta{fallback-action}\meta{act-arg}
%   \end{quote}
%   \meta{action-list} is a token list of the form:
%   \begin{quote}
%     |{|\meta{if-type-1} \meta{act-type-1}|}|\\
%     |{|\meta{if-type-2} \meta{act-type-2}|}|\\
%     \ldots
%   \end{quote}
%   \cs{robust@command@act} will iterate over the \meta{action-list}, evaluating
%   each \meta{if-type-$n$} \meta{robust-cmd} |{|\meta{true}|}{|\meta{false}|}|.
%   If the \meta{if-type-$n$} conditional returns \meta{true}, then
%   \meta{act-type-$n$}\meta{act-arg} is executed, and the loop ends.  If the
%   conditional returns \meta{false}, then \meta{if-type-$n+1$} is executed in
%   the same way, until either one of the conditionals return \meta{true}, or
%   the end of the \meta{action-list} is reached.  If the end is reached, then
%   \meta{fallback-action}\meta{act-arg} is executed before
%   \cs{robust@command@act} exits.
%
%   \cs{robust@command@act} will start by using \cs{robust@command@act@chk@args}
%   to check if the \meta{robust-cmd} (|#2|) is a parameterless (possibly
%   \cs{protected}) macro.  If it is not, the command is not a robust command:
%   these always start with a parameterless user-level macro;  in that case,
%   \cs{robust@command@act@end} is used to short-circuit the process and do the
%   \meta{fallback-action} (|#3|).  This first test is necessary because later
%   on we need to be able to expand the \meta{robust-cmd} without the risk of it
%   Breaking Badly, and as a bonus, this speeds up the process in case we used
%   \cs{NewCommandCopy} in a ``normal'' macro.
%    \begin{macrocode}
\long\def\robust@command@act#1#2#3#4{%
  \robust@command@chk@safe#2%
    {\expandafter\robust@command@act@loop
       \expandafter#2%
         #1{\@nnil\@nnil}%
     \robust@command@act@end}%
    {\robust@command@act@end}%
      {#3}{#4}}%
%    \end{macrocode}
%
% \begin{macro}{\robust@command@act@loop}
% \begin{macro}{\robust@command@act@loop@aux}
% \begin{macro}{\robust@command@act@do}
%   If \cs{robust@command@act@chk@args} branched to false, then
%   \cs{robust@command@act@loop} will loop over the list of items in the
%   \meta{action-list} (|#1|), and process each item as described earlier.
%   If the \meta{if-type-$n$} command expands to \meta{true} then
%   \cs{robust@command@act@do} is used to execute \meta{act-type-$n$} on the
%   \meta{act-arg}, otherwise the loop resumes with the next item.
%    \begin{macrocode}
\long\def\robust@command@act@loop#1#2{\robust@command@act@loop@aux#1#2}
\long\def\robust@command@act@loop@aux#1#2#3{%
  \ifx\@nnil#2%
  \else
    #2{#1}%
      {\robust@command@act@do{#3}}%
      {\expandafter\robust@command@act@loop\expandafter#1}%
  \fi}
\long\def\robust@command@act@do#1%
  \fi#2%
  \robust@command@act@end#3#4{%
  \fi
  #1#4}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\robust@command@act@end}
%   If the end is reached and no action was taken, then do
%   \meta{fallback-action}\meta{act-arg}.
%    \begin{macrocode}
\long\def\robust@command@act@end#1#2{#1#2}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\robust@command@chk@safe}
% \begin{macro}{\robust@command@act@chk@args}
%    \begin{macrocode}
\long\def\robust@command@chk@safe#1{%
  \begingroup
    \escapechar=`\\
  \expandafter\endgroup\expandafter
  \robust@command@act@chk@args\meaning#1:->\@nil}
\def\robust@command@act@chk@args#1:->#2\@nil{%
  \@expl@str@if@eq@@nnTF{#1}{macro}%
    {\@firstoftwo}%
    {\@expl@str@if@eq@@nnTF{#1}{\protected macro}%
      {\@firstoftwo}%
      {\@secondoftwo}}}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%    \begin{macrocode}
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{0000-00-00}{\robust@command@act}
%<latexrelease>  {Add \robust@command@act}%
%<latexrelease>\let\robust@command@act\@undefined
%<latexrelease>\let\robust@command@act@loop\@undefined
%<latexrelease>\let\robust@command@act@loop@aux\@undefined
%<latexrelease>\let\robust@command@act@do\@undefined
%<latexrelease>\let\robust@command@act@end\@undefined
%<latexrelease>\let\robust@command@chk@safe\@undefined
%<latexrelease>\let\robust@command@act@chk@args\@undefined
%<latexrelease>\EndIncludeInRelease
%<*2ekernel>
%    \end{macrocode}
%
% \end{macro}
%
%
% \subsubsection{Copying robust commands}
%
%    \begin{macrocode}
%</2ekernel>
%<latexrelease>\IncludeInRelease{2020-10-01}{\DeclareCommandCopy}
%<latexrelease>  {Add \NewCommandCopy, \RenewCommandCopy, and \DeclareCommandCopy}%
%<*2ekernel|latexrelease>
%    \end{macrocode}
%
% \begin{macro}{\NewCommandCopy}
% \begin{macro}{\RenewCommandCopy}
% \begin{macro}{\DeclareCommandCopy}
% \changes{v1.5j}{2020/05/09}{Added \cs{DeclareCommandCopy} (gh/239)}
%
%   \cs{NewCommandCopy} starts by checking if \verb=#1= is already defined, and
%   raises an error if so, otherwise the definition is carried out.
%   \cs{RenewCommandCopy} does (almost) the opposite.  If the command is
%   \emph{not} defined, then an error is raised.  But the definition is carried
%   out anyhow, so the behaviour is consistent with \cs{renewcommand}.
%
%   A \cs{ProvideCommandCopy} isn't defined because it's not reasonably useful.
%   \verb=\provide...= commands mean ``define this if there's no other
%   definition'', but copying a command (usually) implies that the command being
%   copied is defined, so \cs{ProvideCommandCopy} doesn't make a lot of sense.
%   But more importantly, the most common use case of copying a command is to
%   redefine it later, while preserving the old definition, as in:
% \begin{verbatim}
%   \ProvideCommandCopy \A \B
%   \renewcommand \B { ... \A ... }
% \end{verbatim}
%   then, if \verb=\A= is already defined the first line is skipped, an in this
%   case \verb=\B= won't work as expected.
%
%   The three versions call the internal \cs{declare@commandcopy} with the
%   proper action.  \cs{@firstofone} will carry out the copy.  The only case
%   when the copy is not made is the \meta{false} case for \cs{NewCommandCopy},
%   in which the command already exists and the definition is aborted.
%    \begin{macrocode}
\def\NewCommandCopy{%
  \declare@commandcopy
    {\@firstofone}%
    {\@firstoftwo\@notdefinable}}
\def\RenewCommandCopy{%
  \declare@commandcopy
    {\@latex@error{Command \@backslashchar\reserved@a\space undefined}\@ehc
     \@firstofone}%
    {\@firstofone}}
\def\DeclareCommandCopy{%
  \declare@commandcopy
    {\@firstofone}%
    {\@firstofone}}
%    \end{macrocode}
%
% \begin{macro}{\declare@commandcopy}
% \begin{macro}{\declare@commandcopy@do}
%   Start by checking if the command is already defined.  The proper action is
%   taken by each specific command above.  If all's good, then
%   \cs{robust@command@act} is called with the proper arguments as described
%   earlier, with \cs{@declarecommandcopylisthook} as the \meta{action-list} and
%   \cs{declare@commandcopy@let} as the \meta{fallback-action}.
%    \begin{macrocode}
\long\def\declare@commandcopy#1#2#3#4{%
  \edef\reserved@a{\@expl@cs@to@str@@N#3}%
  \@ifundefined\reserved@a{#1}{#2}%
    {\declare@commandcopy@do{#3}{#4}}}
\long\def\declare@commandcopy@do#1#2{%
  \robust@command@act
    \@declarecommandcopylisthook#2%
    \declare@commandcopy@let{#1#2}}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\@declarecommandcopylisthook}
%   The initial definition of \cs{@declarecommandcopylisthook} contains the
%   tests for the two types of robust command in the kernel.
%    \begin{macrocode}
\def\@declarecommandcopylisthook{%
  {\@if@DeclareRobustCommand \@copy@DeclareRobustCommand}%
  {\@if@newcommand \@copy@newcommand}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\declare@commandcopy@let}
%   The initial definition of \cs{@declarecommandcopylisthook} contains the
%   tests for the two types of robust command in the kernel.
%    \begin{macrocode}
\long\def\declare@commandcopy@let#1#2{\let#1=#2\relax}
%    \end{macrocode}
% \end{macro}
%
%   Now the rollback code.
%    \begin{macrocode}
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{0000-00-00}{\DeclareCommandCopy}
%<latexrelease>  {Undefine \NewCommandCopy, \RenewCommandCopy, and \DeclareCommandCopy}%
%<latexrelease>\let\NewCommandCopy\@undefined
%<latexrelease>\let\RenewCommandCopy\@undefined
%<latexrelease>\let\DeclareCommandCopy\@undefined
%<latexrelease>\let\declare@commandcopy\@undefined
%<latexrelease>\let\@declarecommandcopylisthook\@undefined
%<latexrelease>\let\declare@commandcopy@let\@undefined
%<latexrelease>\EndIncludeInRelease
%<*2ekernel>
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
%    \begin{macrocode}
%</2ekernel>
%<latexrelease>\IncludeInRelease{2023-06-01}{\DeclareEnvironmentCopy}
%<latexrelease>  {Add \NewEnvironmentCopy, \RenewEnvironmentCopy, and \DeclareEnvironmentCopy}%
%<*2ekernel|latexrelease>
%    \end{macrocode}
%
% \begin{macro}{\NewEnvironmentCopy}
% \begin{macro}{\RenewEnvironmentCopy}
% \begin{macro}{\DeclareEnvironmentCopy}
%    If \verb=\#1= or \verb=\end#1= already exist one gets an error
%    message talking about the problematical command (not the
%    environment).
%    The remainder of the \LaTeX{} run is probably badly
%    broken and it is unlikely that continuing it gives
%    reasonable results.
% \changes{v1.5s}{2022/11/24}{Add \cs{NewEnvironmentCopy},
%            \cs{RenewEnvironmentCopy}, and \cs{DeclareEnvironmentCopy} (gh/963)}
%    \begin{macrocode}
\def\NewEnvironmentCopy{%
  \declare@environmentcopy
    {\@firstofone}%
    {\@firstoftwo\@notdefinable}}
\def\RenewEnvironmentCopy{%
  \declare@environmentcopy
    {\@latex@error{Environment \reserved@a\space undefined}\@ehc
     \@firstofone}%
    {\@firstofone}}
\def\DeclareEnvironmentCopy{%
  \declare@environmentcopy
    {\@firstofone}%
    {\@firstofone}}
\long\def\declare@environmentcopy#1#2#3#4{%
  \edef\reserved@a{\@ifundefined{#3}{end#3}{#3}}%
  \@ifundefined\reserved@a
      {\def\reserved@a{#3}#1}%
      {\def\reserved@a{#3}#2}%
    {\ExpandArgs{cc}\declare@commandcopy@do{#3}{#4}%
     \ExpandArgs{cc}\declare@commandcopy@do{end#3}{end#4}}}
%    \end{macrocode}
%
%   Now the rollback code.
%    \begin{macrocode}
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{0000-00-00}{\DeclareEnvironmentCopy}
%<latexrelease>  {Undefine \NewEnvironmentCopy, \RenewEnvironmentCopy, and \DeclareEnvironmentCopy}%
%<latexrelease>\let\NewEnvironmentCopy\@undefined
%<latexrelease>\let\RenewEnvironmentCopy\@undefined
%<latexrelease>\let\DeclareEnvironmentCopy\@undefined
%<latexrelease>\EndIncludeInRelease
%<*2ekernel>
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
% \subsubsection{Showing robust commands}
%
% \begin{macro}{\ShowCommand}
% \changes{v1.5k}{2020/08/19}{Added \cs{ShowCommand} (gh/373)}
%
%   Most of the machinery defined for \cs{NewCommandCopy} can be used to show
%   the definition of a robust command, in a similar fashion to \texttt{texdef}.
%   The difference is that after the command is detected to have a given type
%   of robustness, rather than making a copy, we use a separate routine to show
%   its definition.
%
%   With all the machinery in place, \cs{ShowCommand} itself is quite simple: we
%   use \cs{robust@command@act} to iterate through the \cs{@showcommandlisthook}
%   list, and if nothing is found, fallback to \cs{show}.
%    \begin{macrocode}
%</2ekernel>
%<latexrelease>\IncludeInRelease{2020-10-01}{\ShowCommand}%
%<latexrelease>  {Add \ShowCommand}%
%<*2ekernel|latexrelease>
%    \end{macrocode}
%
%    \begin{macrocode}
\long\def\ShowCommand#1{%
  \robust@command@act
    \@showcommandlisthook#1%
    \show#1}
%    \end{macrocode}
%
% \begin{macro}{\@showcommandlisthook}
%   The initial definition of \cs{@showcommandlisthook} contains the same tests
%   as used for copying, but \cs{@show@...} commands instead of \cs{@copy@...}.
%   Same as before, it is initialized to cope with \cs{DeclareRobustCommand} and
%   \cs{newcommand} with optional arguments.
%    \begin{macrocode}
\def\@showcommandlisthook{%
  {\@if@DeclareRobustCommand \@show@DeclareRobustCommand}%
  {\@if@newcommand \@show@newcommand}}
%    \end{macrocode}
% \end{macro}
%
%   Now the rollback code.
%    \begin{macrocode}
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{0000-00-00}{\ShowCommand}
%<latexrelease>  {Undefine \ShowCommand}%
%<latexrelease>\let\ShowCommand\@undefined
%<latexrelease>\let\@showcommandlisthook\@undefined
%<latexrelease>\EndIncludeInRelease
%<*2ekernel>
%    \end{macrocode}
% \end{macro}
%
%    \begin{macrocode}
%</2ekernel>
%<latexrelease>\IncludeInRelease{2020-10-01}{\@if@DeclareRobustCommand}
%<latexrelease>  {Add \@if@DeclareRobustCommand, \@if@newcommand,
%<latexrelease>       \@copy@DeclareRobustCommand, \@copy@newcommand,
%<latexrelease>       \@show@DeclareRobustCommand, \@show@newcommand}%
%<*2ekernel|latexrelease>
%    \end{macrocode}
%
% \subsubsection{Commands defined with \cs{DeclareRobustCommand}}
%
% \begin{macro}{\@if@DeclareRobustCommand}
% \changes{v1.5j}{2020/05/09}{Added \cs{DeclareCommandCopy} (gh/239)}
%
%   Now that we provided a generic way to copy one macro to another, we need to
%   define a way to check if a command is one of \LaTeXe's robust types.  These
%   tests are heavily based on Heiko's \cs{LetLtxMacro}, but chopped into
%   separate macros.
%
%   The command \cs{@if@DeclareRobustCommand} checks if a command
%   \verb=\cmd= was defined by 
%   \cs{DeclareRobustCommand}.  The test returns true if the expansion of
%   \verb=\cmd= is exactly \verb*=\protect\cmd =.
%
%    \begin{macrocode}
\long\def\@if@DeclareRobustCommand#1{%
  \begingroup
    \escapechar=`\\
    \edef\reserved@a{\string#1}%
    \edef\reserved@b{\detokenize{#1}}%
    \xdef\@gtempa{%
      \ifx\reserved@a\reserved@b
         \noexpand\x@protect
         \noexpand#1%
      \fi
      \noexpand\protect
      \expandafter\noexpand\csname\@expl@cs@to@str@@N#1 \endcsname}%
  \endgroup
  \ifx\@gtempa#1\relax
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi}
%    \end{macrocode}
%
% \begin{macro}{\@copy@DeclareRobustCommand}
% \begin{macro}{\copy@kernel@robust@command}
%   If a command was defined by \cs{DeclareRobustCommand} (that is,
%   \cs{@if@DeclareRobustCommand} returns true), then to make a copy of \verb=\cmd=
%   into \verb=\foo= we define the latter such that it expands to
%   \verb*=\protect\foo =, then make \verb*=\foo = equal to \verb*=\cmd =.
%
%   There is one detail we need to take care of:  if a command was defined with
%   \cs{DeclareRobustCommand} it may still have an optional argument, in which
%   case there is one more macro layer before the actual definition of the
%   command.  We use \cs{@if@newcommand} to check that and
%   \cs{@copy@newcommand} to do the copying.
%    \begin{macrocode}
\long\def\@copy@DeclareRobustCommand#1#2{%
  \begingroup
    \escapechar=`\\
    \edef\reserved@a{\string#1}%
    \edef\reserved@b{\detokenize{#1}}%
    \edef\reserved@a{%
  \endgroup
  \def\noexpand#1{%
    \ifx\reserved@a\reserved@b
       \noexpand\x@protect
       \noexpand#1%
    \fi
    \noexpand\protect
    \expandafter\noexpand\csname\@expl@cs@to@str@@N#1 \endcsname}%
  \noexpand\copy@kernel@robust@command
    \expandafter\noexpand\csname\@expl@cs@to@str@@N#1 \endcsname
    \expandafter\noexpand\csname\@expl@cs@to@str@@N#2 \endcsname}%
  \reserved@a}
\long\def\copy@kernel@robust@command#1#2{%
  \robust@command@chk@safe#2%
    {\@if@newcommand#2%
       {\@copy@newcommand}%
       {\declare@commandcopy@let}}
    {\declare@commandcopy@let}%
  #1#2}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\@show@DeclareRobustCommand}
% \begin{macro}{\show@kernel@robust@command}
% \begin{macro}{\@show@macro}
%   Showing the command is pretty simple.  This command prints the top-level
%   expansion as \TeX's \cs{show} would, but with |robust macro:| rather than
%   just |macro:|, then a blank line and then \cs{show} the inner command.
%   For a macro defined with, say, |\DeclareRobustCommand\foo[1]{bar}|, it will
%   print:
% \begin{verbatim}
%   > \foo=robust macro:
%   ->\protect \foo  .
%   
%   > \foo =\long macro:
%   #1->bar.
% \end{verbatim}
%   If the inner command is defined with an optional argument, then
%   \cs{@show@newcommand} is also used.
%
%   The value of \cs{escapechar} is deliberately not enforced, so
%   \cs{ShowCommand} behaves more like \cs{show}.
%    \begin{macrocode}
\long\def\@show@DeclareRobustCommand#1{%
  \typeout{> \string#1=robust macro:}%
  \typeout{->\@expl@cs@replacement@spec@@N#1.^^J}%
  \expandafter\show@kernel@robust@command
    \csname\@expl@cs@to@str@@N#1 \endcsname}
\long\def\show@kernel@robust@command#1{%
  \robust@command@chk@safe#1%
    {\@if@newcommand#1%
       {\@show@newcommand}%
       {\@show@macro}}%
    {\@show@macro}%
  #1}
\let\@show@macro\show
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \end{macro}
%
% \subsubsection{Commands defined with \cs{newcommand} (with optional argument)}
%
% \begin{macro}{\@if@newcommand}
%   A command \verb=\cmd= (or \verb*=\cmd =, if it was defined with
%   \cs{DeclareRobustCommand}) with an optional argument will expand to
%   \verb*=\@protected@testopt\cmd\\cmd{<opt>}=.  To check that we look at the
%   first three tokens in the expansion of \verb=\cmd=, and return true or false
%   accordingly.
%
%   This test \emph{requires} that the command be a parameterless macro,
%   otherwise it will not work (and probably break).  This is ensured with
%   \cs{robust@command@chk@safe} before calling \cs{@if@newcommand}.
%    \begin{macrocode}
\long\def\@if@newcommand#1{%
  \edef\reserved@a{%
    \noexpand\@protected@testopt
    \noexpand#1%
    \expandafter\noexpand\csname\@backslashchar\@expl@cs@to@str@@N#1\endcsname}%
  \edef\reserved@b{%
    \unexpanded\expandafter\expandafter\expandafter
      {\expandafter\@carcube#1{}{}{}\@nil}}%
  \ifx\reserved@a\reserved@b
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi}
%    \end{macrocode}
%
% \begin{macro}{\@copy@newcommand}
%   Then, if a command \verb=\cmd= takes an optional argument, we copy it to
%   \verb=\foo= by defining the latter to expand to
%   \verb=\@protected@testopt\foo\\foo{<opt>}=.
%    \begin{macrocode}
\long\def\@copy@newcommand#1#2{%
  \edef#1{\noexpand\@protected@testopt
    \noexpand#1%
    \expandafter\noexpand\csname\@backslashchar\@expl@cs@to@str@@N#1\endcsname
    \unexpanded\expandafter\expandafter\expandafter
      {\expandafter\@gobblethree#2}}%
  \expandafter
  \let\csname\@backslashchar\@expl@cs@to@str@@N#1\expandafter\endcsname
      \csname\@backslashchar\@expl@cs@to@str@@N#2\endcsname}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@show@newcommand}
% \begin{macro}{\@show@newcommand@aux}
%   A command being \cs{show}n here is guaranteed to have an optional argument.
%   Start by showing the top-level expansion of the command (using \cs{typeout}
%   to avoid TeX asking for interaction and extra context lines), then call
%   \cs{@show@newcommand@aux} with the internal command, which contains the
%   actual definition, and with the expansion of the command to extract the
%   default value of the optional argument.
%    \begin{macrocode}
\long\def\@show@newcommand#1{%
  \typeout{> \string#1=robust macro:}%
  \typeout{->\@expl@cs@replacement@spec@@N#1.^^J}%
  \expandafter\@show@newcommand@aux
    \csname\@backslashchar\@expl@cs@to@str@@N#1\expandafter\endcsname
    \expandafter{#1}\@show@tokens}
%    \end{macrocode}
%
%   For a macro defined with, say, |\newcommand\foo[1][opt]{bar}|, it will
%   print:
% \begin{verbatim}
%   > \foo=robust macro:
%   ->\@protected@testopt \foo \\foo {opt}.
%   
%   > \\foo=\long macro:
%   > default #1=opt.
%   [#1]->bar.
% \end{verbatim}
%   If the command was defined with \cs{DeclareRobustCommand}, then another pair
%   of lines show the top-level expansion \verb*|\protect \foo  |.
%    \begin{macrocode}
\long\def\@show@newcommand@aux#1#2#3{%
  \typeout{> \string#1=\@expl@cs@prefix@spec@@N#1macro:}%
  #3{default \string##1=\expandafter\detokenize\@gobblethree#2.^^J%
    \@expl@cs@parameter@spec@@N#1->\@expl@cs@replacement@spec@@N#1}}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\@show@tokens}
%   This macro prints the contents of the token list (macro) |#1| using
%   \cs{showtokens}.  The \cs{expandafter} gymnastics ensures that
%   \cs{showtokens} itself, and the internals of this macro aren't
%   showed in the context lines.
%    \begin{macrocode}
\long\def\@show@tokens#1{%
  \edef\reserved@a{#1}%
  \showtokens\expandafter
    \expandafter\expandafter{\expandafter\reserved@a}}
%    \end{macrocode}
% \end{macro}
%
%   Now the rollback code.
%    \begin{macrocode}
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{0000-00-00}{\@if@DeclareRobustCommand}
%<latexrelease>  {Undefine \@if@DeclareRobustCommand, \@if@newcommand,
%<latexrelease>            \@copy@DeclareRobustCommand, \@copy@newcommand,
%<latexrelease>            \@show@DeclareRobustCommand, \@show@newcommand}%
%<latexrelease>\let\@if@DeclareRobustCommand\@undefined
%<latexrelease>\let\@copy@DeclareRobustCommand\@undefined
%<latexrelease>\let\@show@DeclareRobustCommand\@undefined
%<latexrelease>\let\@if@newcommand\@undefined
%<latexrelease>\let\@copy@newcommand\@undefined
%<latexrelease>\let\@show@newcommand\@undefined
%
%<latexrelease>\let\copy@kernel@robust@command\@undefined
%<latexrelease>\let\show@kernel@robust@command\@undefined
%<latexrelease>\let\@show@newcommand@aux\@undefined
%<latexrelease>\EndIncludeInRelease
%<*2ekernel>
%    \end{macrocode}
%
% \end{macro}
%
%
% \subsubsection{Showing environments}
%
% \begin{macro}{\ShowEnvironment}
% \changes{v1.5s}{2022/11/24}{Added \cs{ShowEnvironment}}
%
%    \begin{macrocode}
%</2ekernel>
%<latexrelease>\IncludeInRelease{2023-06-01}{\ShowEnvironment}
%<latexrelease>  {Add \ShowEnvironment}%
%<*2ekernel|latexrelease>
%    \end{macrocode}
%
%   \cs{ShowEnvironment} is quite similar to \cs{ShowCommand}.  We will
%   pass the environment \meta{env} around as the macro
%   \cs[no-index]{env}, because \cs{robust@command@act} expects a single
%   token.
%    \begin{macrocode}
\def\ShowEnvironment#1{%
  \expandafter\@show@environment\csname #1\endcsname}
\long\def\@show@environment#1{%
  \robust@command@act
    \@showenvironmentlisthook#1%
    \@show@normalenv#1}
%    \end{macrocode}
%
% \begin{macro}{\@showenvironmentlisthook}
%   This is similar to \cs{@showcommandlisthook}, but uses the dedicated
%   versions for environments.
%    \begin{macrocode}
\def\@showenvironmentlisthook{%
  {\@if@DeclareRobustCommand \@show@DeclareRobustCommand@env}%
  {\@if@newcommand \@show@newcommand@env}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@show@newcommand@env}
% \begin{macro}{\@show@DeclareRobustCommand@env}
%   These are similar to the command versions below, except they say
%   \enquote{environment} and call \cs{@show@environment@end} to print
%   the \cs{end} part.
%    \begin{macrocode}
\long\def\@show@newcommand@env#1{%
  \@show@environment@begin#1%
  \expandafter\@show@newcommand@aux
    \csname\@backslashchar\@expl@cs@to@str@@N#1\expandafter\endcsname
    \expandafter{#1}\@show@typeout
  \@show@environment@end#1}
\long\def\@show@DeclareRobustCommand@env#1{%
  \@show@environment@begin#1%
  \begingroup
    \let\@show@tokens\@show@typeout
    \let\@show@macro\@show@nonstop
    \expandafter\show@kernel@robust@command
      \csname\@expl@cs@to@str@@N#1 \endcsname
  \endgroup
  \@show@environment@end#1}
\long\def\@show@environment@begin#1{%
  \typeout{> \string\begin{\@expl@cs@to@str@@N#1}=environment:}%
  \typeout{\@expl@cs@parameter@spec@@N#1->%
           \@expl@cs@replacement@spec@@N#1.^^J}}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\@show@normalenv}
% \begin{macro}{\@show@environment@end}
%   A \enquote{normal} environment is straightforward.
%   \cs{@show@environment@end} needs to check if the \cs{end} part is
%   defined and show it accordingly, otherwise the output would show
%   gibberish.
%    \begin{macrocode}
\long\def\@show@normalenv#1{%
  \@show@environment@begin#1%
  \@show@environment@end#1}
\long\def\@show@environment@end#1{%
  \expandafter\@show@environment@end@aux
    \csname end\@expl@cs@to@str@@N#1\endcsname#1}
\long\def\@show@environment@end@aux#1#2{%
  \@show@tokens{\string\end{\@expl@cs@to@str@@N#2}%
    \ifx\relax#1=undefined%
    \else:^^J\@expl@cs@parameter@spec@@N#1->%
             \@expl@cs@replacement@spec@@N#1%
    \fi}}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\@show@nonstop}
% \begin{macro}{\@show@typeout}
%   And here some auxiliaries:
%   \begin{description}
%     \item[\cs{@show@nonstop}] same output as \cs{show}, but doesn't
%       stop for interaction;
%     \item[\cs{@show@typeout}] same output as \cs{showtokens}, but
%       doesn't stop for interaction.
%   \end{description}
%    \begin{macrocode}
\def\@show@nonstop#1{%
  \typeout{> \string#1=\@expl@cs@prefix@spec@@N#1macro:^^J%
   \@expl@cs@parameter@spec@@N#1->\@expl@cs@replacement@spec@@N#1.}}
\def\@show@typeout#1{\typeout{> #1.^^J}}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%   Now the rollback code.
%    \begin{macrocode}
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{0000-00-00}{\ShowEnvironment}
%<latexrelease>  {Undefine \ShowEnvironment}%
%<latexrelease>\let\ShowEnvironment\@undefined
%<latexrelease>\EndIncludeInRelease
%<*2ekernel>
%    \end{macrocode}
% \end{macro}
%
%
% \subsection{Internal defining commands}
%
% These commands are used internally to define other \LaTeX{}
% commands.
% \begin{macro}{\@ifundefined}
% \changes{LaTeX2e}{1993/11/23}{Redefined to remove a trailing \cs{fi}}
%    Check if first arg is undefined or \cs{relax} and execute second or
%    third arg depending,
% \changes{1.5c}{2018/01/06}{Avoid defining undefined commands to \cs{relax}}
%    \begin{macrocode}
%</2ekernel>
%<latexrelease>\IncludeInRelease{2018-04-01}{\@ifundefined}
%<latexrelease>{Leave commands undefined in \@ifundefined}%
%<*2ekernel|latexrelease>
%    \end{macrocode}
% Version using |\ifcsname| to avoid defining undefined tokens to |\relax|.
% Defined here to simplify using unmatched |\fi|.
%    \begin{macrocode}
\def\@ifundefined#1{%
  \ifcsname#1\endcsname\@ifundefin@d@i\else\@ifundefin@d@ii\fi{#1}}
%    \end{macrocode}
%    \begin{macrocode}
\long\def\@ifundefin@d@i#1\fi#2{\fi
  \expandafter\ifx\csname #2\endcsname\relax
    \@ifundefin@d@ii
  \fi
  \@secondoftwo}
%    \end{macrocode}
%    \begin{macrocode}
\long\def\@ifundefin@d@ii\fi#1#2#3{\fi #2}
%    \end{macrocode}
% Now test of engine.
%    \begin{macrocode}
\ifx\numexpr\@undefined
%    \end{macrocode}
% Classic version (should not be needed as etex is assumed).
%    \begin{macrocode}
\def\@ifundefined#1{%
  \expandafter\ifx\csname#1\endcsname\relax
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi}
\else\ifx\directlua\@undefined
%    \end{macrocode}
% Use the |\ifcsname| defined above.
%    \begin{macrocode}
\else
%    \end{macrocode}
% Optimised version for Lua\TeX, using |\lastnamedcs|
%    \begin{macrocode}
\def\@ifundefined#1{%
  \ifcsname#1\endcsname
    \expandafter\ifx\lastnamedcs\relax\else\@ifundefin@d@i\fi
  \fi
  \@firstoftwo}
%    \end{macrocode}
%    \begin{macrocode}
\long\def\@ifundefin@d@i#1#2#3#4#5{#1#2#5}
%    \end{macrocode}
%    \begin{macrocode}
\fi
\fi
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{0000-00-00}{\@ifundefined}
%<latexrelease>{Leave commands undefined in \@ifundefined}%
%<latexrelease>\def\@ifundefined#1{%
%<latexrelease>  \expandafter\ifx\csname#1\endcsname\relax
%<latexrelease>    \expandafter\@firstoftwo
%<latexrelease>  \else
%<latexrelease>    \expandafter\@secondoftwo
%<latexrelease>  \fi}
%<latexrelease>\EndIncludeInRelease
%<*2ekernel>
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\@qend}
% \begin{macro}{\@qrelax}
% The following define |\@qend| and |\@qrelax| to be the strings
% `|end|' and `|relax|' with the characters |\catcode|d 12.
%    \begin{macrocode}
\edef\@qend{\expandafter\@cdr\string\end\@nil}
\edef\@qrelax{\expandafter\@cdr\string\relax\@nil}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%
%
% \begin{macro}{\@ifnextchar}
% \changes{LaTeX209}{1992/08/24}
%     {(Rms) \cs{@ifnextchar} didn't work if its
%         first argument was an equal sign.}
% \changes{v1.2q}{1995/10/02}
%     {Use \cs{@let@token} }
% \changes{v1.3a}{1999/01/07}
%     {made long}
% \changes{v1.3b}{1999/01/07}
%     {extra \cs{long}. latex/2902}
% \changes{v1.3e}{1999/03/01}
%     {remove extra \cs{long}. internal/2967}
%  |\@ifnextchar| peeks at the following character and compares it
%  with its first argument. If both are the same it executes its
%  second argument, otherwise its third.
%    \begin{macrocode}
\long\def\@ifnextchar#1#2#3{%
  \let\reserved@d=#1%
  \def\reserved@a{#2}%
  \def\reserved@b{#3}%
  \futurelet\@let@token\@ifnch}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\kernel@ifnextchar}
% \changes{v1.3g}{2004/01/23}{Added macro (pr/3501)}
%    This macro is the kernel version of |\@ifnextchar| which is used
%    in a couple of places to prevent the AMS variant from being used
%    since in some places this produced chaos. For example,
%    if an \texttt{fd} file
%    is loaded in a random place then the optional argument to
%    |\ProvidesFile| could get printed there instead of being written
%    only in the log file.  This happened
%    when there was a space or a newline between the mandatory and
%    optional arguments! It should really be fixed in the
%    \texttt{amsmath} package one day, but\ldots
%
%    Note that there may be other places in the kernel where this version
%    should be used rather than the original, but variable, version.
%
%    \begin{macrocode}
\let\kernel@ifnextchar\@ifnextchar
%    \end{macrocode}
% \end{macro}
%
%
%  \begin{macro}{\@ifnch}
%    |\@ifnch| is a tricky macro to skip any space tokens that may
%    appear before the character in question. If it encounters a space
%    token, it calls \@xifnch.
% \changes{v1.2q}{1995/10/02}
%     {Use \cs{@let@token} for internal/924, save \cs{reserved@e}}
%    \begin{macrocode}
\def\@ifnch{%
  \ifx\@let@token\@sptoken
    \let\reserved@c\@xifnch
  \else
    \ifx\@let@token\reserved@d
      \let\reserved@c\reserved@a
    \else
      \let\reserved@c\reserved@b
    \fi
  \fi
  \reserved@c}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@sptoken}
%    The following code makes |\@sptoken| a space token. It is
%    important here that the control sequence |\:| consists of
%    a non-letter only, so that the following whitespace is
%    significant. Together with the fact that the equal sign
%    in a |\let| may be followed by only one optional space
%    the desired effect is achieved.
%    NOTE: the following hacking must precede the definition of |\:|
%    as math medium space.
%    \begin{macrocode}
\def\:{\let\@sptoken= } \:  % this makes \@sptoken a space token
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@xifnch}
%    In the following definition of |\@xifnch|, |\:| is again used
%    to get a space token as delimiter into the definition.
%    \begin{macrocode}
\def\:{\@xifnch} \expandafter\def\: {\futurelet\@let@token\@ifnch}
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\@ifstar}
% \changes{v1.2u}{1995/10/16}{(DPC) New implementation, for /1910}
% The new implementation below avoids passing the \meta{true code}
% Through one more |\def| than the \meta{false code}, which previously
% meant that |#| had to be written as |####| in one argument, but |##|
% in the other. The |*| is gobbled by |\@firstoftwo|.
%    \begin{macrocode}
\def\@ifstar#1{\@ifnextchar *{\@firstoftwo{#1}}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@dblarg}
% \begin{macro}{\@xdblarg}
% \changes{v1.1g}{2004/01/23}{Use kernel version of
%                             \cs{@ifnextchar} (pr/3501)}
%    \begin{macrocode}
\long\def\@dblarg#1{\kernel@ifnextchar[{#1}{\@xdblarg{#1}}}
\long\def\@xdblarg#1#2{#1[{#2}]{#2}}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\@sanitize}
% The command |\@sanitize| changes the catcode of all special characters
% except for braces to `other'.  It can be used for commands like
% |\index| that want to write their arguments verbatim.  Needless to
% say, this command should only be executed within a group, or chaos
% will ensue.
%
%    \begin{macrocode}
\def\@sanitize{\@makeother\ \@makeother\\\@makeother\$\@makeother\&%
\@makeother\#\@makeother\^\@makeother\_\@makeother\%\@makeother\~}
%    \end{macrocode}
% \end{macro}
%
%  \begin{macro}{\@onelevel@sanitize}
% \changes{v1.2c}{1994/10/30}{Macro added}
%
%    This makes the whole ``meaning'' of |#1| (its one-level
%    expansion) into catcode 12 tokens: it could be used in
%    |\DeclareRobustCommand|.
%
%    If it is to be used on default float specifiers, this should be
%    done when they are defined.
%    \begin{macrocode}
\def \@onelevel@sanitize #1{%
  \edef #1{\expandafter\strip@prefix
           \meaning #1}%
}
%    \end{macrocode}
%  \end{macro}
%
%
% \begin{macro}{\string@makeletter}
% \begin{macro}{\@string@makeletter}
% \begin{macro}{\char@if@alph}
%   Iterates through a string, turning each alphabetic character into
%   a catcode-11 token (partly undoes a \cs{detokenize}).  Useful for
%   \cs{ifx}-based string comparisons where \cs{detokenize}-ing the
%   other string would break too much code.
%
%   \changes{v1.5n}{2020/09/06}
%         {Macro added}
%
%   The macro uses \textsf{expl3}'s \cs{@expl@str@map@function@@NN} to
%   iterate on the string (without losing spaces) and applies
%   \cs{@string@makeletter} on each character.  The latter checks if
%   character is between a--z or A--Z, and uses \cs{@alph} or \cs{@Alph}
%   to get the corresponding catcode-11 token.  Other tokens are passed
%   through unchanged.
%    \begin{macrocode}
%</2ekernel>
%<latexrelease>\IncludeInRelease{2020/10/01}{\string@makeletter}
%<latexrelease>  {Add \string@makeletter}%
%<*2ekernel|latexrelease>
\def\string@makeletter#1{%
  \@expl@str@map@function@@NN#1\@string@makeletter}
\def\@string@makeletter#1{%
  \char@if@alph{#1}%
    {\@expl@char@generate@@nn{`#1}{11}}%
    {#1}}
\def\char@if@alph#1{%
  \ifnum0\ifnum`#1<`A 1\fi\ifnum`#1>`z 1\fi
      \if\ifnum`#1>`Z @\fi\ifnum`#1<`a @\fi01\fi>0
    \expandafter\@secondoftwo
  \else
    \expandafter\@firstoftwo
  \fi}
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%
%<latexrelease>\IncludeInRelease{0000/00/00}{\string@makeletter}
%<latexrelease>  {Undefine \string@makeletter}%
%<latexrelease>\let\string@makeletter\@undefined
%<latexrelease>\let\@string@makeletter\@undefined
%<latexrelease>\let\char@if@alph\@undefined
%<latexrelease>\EndIncludeInRelease
%<*2ekernel>
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
% \begin{macro}{\makeatletter}
% \begin{macro}{\makeatother}
% \changes{v1.0n}{1994/05/10}{Added \cs{makeatletter} and
%           \cs{makeatother} ASAJ.}
%    Make internal control sequences accessible or inaccessible.
%    \begin{macrocode}
\DeclareRobustCommand\makeatletter{\catcode`\@11\relax}
\DeclareRobustCommand\makeatother{\catcode`\@12\relax}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%
% \section{Discretionary Hyphenation}
% \begin{macro}{\-}
% \changes{1.2x}{1995/12/13}{Documentation changed.}
% \changes{v1.5a}{2017/03/13}{Define \cs{-} in terms of \cs{hyphenchar}}
% \begin{macro}{\@dischyph}
% \changes{v1.0g}{1994/04/12}
%         {Define \cs{@dischyph}, was previously in ltboxes.dtx}
% \changes{v1.5b}{2017/03/27}{Define \cs{@dischyph} after \cs{-}}
% \changes{v1.5j}{2020/05/11}{Do not overwrite \cs{-} under Lua\TeX}
% \end{macro}
% Moved here to be after the definition of |\DeclareRobustCommand|.
%
% The primitive |\-| command adds a discretionary hyphen using the
% current font's |\hyphenchar|. Monospace fonts are usually declared
% with |\hyphenchar| set to $-1$ to suppress hyphenation.
%
% \LaTeX, from \LaTeX2.09 in 1986 defined |\-| by
% \begin{verbatim}
% \def\-{\discretionary{-}{}{}}
% \end{verbatim}
%  The following comment was added when these commands were first set
%  up, 19 April 1986:
% \begin{quote}
%  the |\-| command is redefined to allow it to work in the |\ttfamily|
%  type style, where automatic hyphenation is suppressed by setting
%  |\hyphenchar| to~$-1$. The original primitive \TeX{} definition is
%  saved as |\@@hyph| just in case anyone needs it.
% \end{quote}
%
% \LaTeXe, between 1993 and 2017, had a comment at this point
% saying that the definition ``would probably change'' because
% the definition always uses |-|. The definition used below
% was given in comments at this point during time.
%
% In 2017 we finally enabled this definition by default, with the
% older \LaTeX\ definition accessible via \textsf{latexrelease}
% as usual.
%
% In Lua\LaTeX\ the primitive definition of \cs{-} is used directly
% because it's use of extended hyphenation parameters means that \cs{-}
% works correctly even with \cs{hyphenchar} set to $-1$. This change
% makes \cs{-} under Lua\LaTeX\ compatible with language specific
% hyphenation characters.
%
% Temporary definition of |\@latex@info|, final definition is later.
%    \begin{macrocode}
\def\@latex@info#1{}
%    \end{macrocode}
%
%    \begin{macrocode}
%</2ekernel>
%<latexrelease>\IncludeInRelease{2020/10/01}{\-}{Use primitive \- in Lua\LaTeX}%
%<*2ekernel|latexrelease>
\ifx\directlua\@undefined
  \DeclareRobustCommand{\-}{%
    \discretionary{%
      \char \ifnum\hyphenchar\font<\z@
              \defaulthyphenchar
            \else
              \hyphenchar\font
            \fi
                 }{}{}%
  }
\else
  \let\-\@@hyph
\fi
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{2017/04/15}{\-}{Use \hyphenchar in \-}%
%<latexrelease>\DeclareRobustCommand{\-}{%
%<latexrelease>  \discretionary{%
%<latexrelease>    \char \ifnum\hyphenchar\font<\z@
%<latexrelease>            \defaulthyphenchar
%<latexrelease>          \else
%<latexrelease>            \hyphenchar\font
%<latexrelease>          \fi
%<latexrelease>               }{}{}%
%<latexrelease>}
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{0000/00/00}{\-}{Use \hyphenchar in \-}%
%<latexrelease>\def\-{\discretionary{-}{}{}}
%<latexrelease>\EndIncludeInRelease
%    \end{macrocode}
%    
%    \begin{macrocode}
%<*2ekernel|latexrelease>
\let\@dischyph=\-
%</2ekernel|latexrelease>
%<*2ekernel>
%    \end{macrocode}
% \end{macro}
%
% Delayed from |ltvers.dtx|
%    \begin{macrocode}
\newif\if@includeinrelease
\@includeinreleasefalse
%    \end{macrocode}
%
% \changes{v1.5f}{2019/08/27}{Make various commands robust}
%
% Delayed from |ltplain.dtx|
%    \begin{macrocode}
%</2ekernel>
%<*2ekernel|latexrelease>
%<latexrelease>\IncludeInRelease{2019/10/01}%
%<latexrelease>                 {\allowbreak}{Make various commands robust}%
\MakeRobust\allowbreak
\MakeRobust\bigbreak
\MakeRobust\break
\MakeRobust\dotfill
\MakeRobust\frenchspacing
\MakeRobust\goodbreak
\MakeRobust\hrulefill
\MakeRobust\medbreak
\MakeRobust\nobreak
\MakeRobust\nonfrenchspacing
\MakeRobust\obeylines
\MakeRobust\obeyspaces
\MakeRobust\slash
\MakeRobust\smallbreak
\MakeRobust\strut
\MakeRobust\underbar
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{0000/00/00}%
%<latexrelease>                 {\allowbreak}{Make various commands robust}%
%<latexrelease>
%<latexrelease>\kernel@make@fragile\allowbreak
%<latexrelease>\kernel@make@fragile\bigbreak
%<latexrelease>\kernel@make@fragile\break
%<latexrelease>\kernel@make@fragile\dotfill
%<latexrelease>\kernel@make@fragile\frenchspacing
%<latexrelease>\kernel@make@fragile\goodbreak
%<latexrelease>\kernel@make@fragile\hrulefill
%<latexrelease>\kernel@make@fragile\medbreak
%<latexrelease>\kernel@make@fragile\nobreak
%<latexrelease>\kernel@make@fragile\nonfrenchspacing
%<latexrelease>\kernel@make@fragile\obeylines
%<latexrelease>\kernel@make@fragile\obeyspaces
%<latexrelease>\kernel@make@fragile\slash
%<latexrelease>\kernel@make@fragile\smallbreak
%<latexrelease>\kernel@make@fragile\strut
%<latexrelease>\kernel@make@fragile\underbar
%<latexrelease>
%<latexrelease>\EndIncludeInRelease
%<*2ekernel>
%    \end{macrocode}
%
%
% \begin{macro}{\g@addto@macro}
%    Globally add to the end of a macro.
%    This macro is used by the kernel to add to its internal hooks.
% \changes{v0.2a}{1993/11/14}{Made global}
% \changes{v0.2w}{1994/01/31}
%     {Use toks register to avoid `hash' problems}
% \changes{v1.0o}{1995/05/17}
%     {Make long for latex/1522}
% \changes{v1.0w}{1996/12/17}
%     {Use \cs{begingroup} to save making a mathord}
% \changes{v1.0x}{1997/02/05}
%     {missing percent /2402}
%    \begin{macrocode}
\long\def\g@addto@macro#1#2{%
  \begingroup
    \toks@\expandafter{#1#2}%
    \xdef#1{\the\toks@}%
  \endgroup}
%    \end{macrocode}
% \end{macro}
%
%
%    \begin{macrocode}
%</2ekernel>
%    \end{macrocode}
%
%
% \Finale
%
