% \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: ltplain.dtx
%
%<*driver>
% \fi
\ProvidesFile{ltplain.dtx}
             [2024/02/08 v2.3j LaTeX Kernel (Plain TeX)]
% \iffalse
\documentclass{ltxdoc}
\GetFileInfo{ltplain.dtx}
\begin{document}
\title{\filename\\(The file plain.tex, modified for \LaTeX)}
\author{Donald~E.~Knuth\\
 Modified by
 Leslie Lamport, Frank Mittelbach,\\
 Rainer Sch\"opf, David Carlisle}
\date{\filedate}
 \MaintainedByLaTeXTeam{latex}
 \maketitle
 \DocInput{\filename}
\end{document}
%</driver>
% \fi
%
%
% \changes{v1.0a}{1994/03/08}
%         {Remove need for a driver file.}
% \changes{v1.0b}{1994/03/12}
%         {Name changed from lplain. The end of an era}
% \changes{v1.0e}{1994/03/12}{Replaced remaining width, height, depth
%       by \LaTeX{} macro names to save tokens.}
% \changes{v1.1a}{1994/10/14}
%         {Moved code to other files.}
% \changes{v1.1b}{1994/11/10}
%         {(CAR) added patch to \cs{loop}.}
% \changes{v1.1f}{1994/11/25}
%         {(DPC) Comment out lots of obsolete code}
% \changes{v1.1g}{1994/12/01}
%         {(DPC) More doc changes}
% \changes{v1.1j}{1995/05/07}{Use \cs{hb@xt@}}
% \changes{v1.1j}{1995/05/21}{Moved some code to other files}
% \changes{v1.1n}{1995/07/02}{Removed surplus `by' and `\quotechar=' in
%                             various places}
% \changes{v1.1o}{1995/09/14}{Moved \cs{multispan} to lttab.dtx}
% \changes{v1.1r}{1995/10/10}{Autoload tracing code}
% \changes{v1.1u}{1996/10/28}{(CAR) More doc changes}
% \changes{v2.0e}{2015/02/21}{Removed autoload code}
% \changes{v2.2d}{2016/10/15}{Require e\TeX{}}
% \changes{v2.3b}{2016/11/06}{Drop \cs{outer} entirely}
%
% \section{Plain \TeX}
%
% \LaTeX\ includes almost all of the functionality of Knuth's original
% `Basic Macros' That is, the plain \TeX\ format described in Appendix~B
% of the \TeX{}Book.  However, some of the user commands are not much
% use so, in order to save memory, we may remove them from the kernel
% into a package.  Here is a list of the commands that may be removed
% (PROBABLY NOT COMPLETE).
% \begin{verbatim}
%    \magstep    \magstephalf
%    \mathhexbox
%    \vglue      \vgl@
%    \hglue      \hgl@
% \end{verbatim}
%
% This file is by now very small as most of it has been moved to more
% appropriate kernel files: it may disappear completely one day.
%
% \LaTeX\ font definitions are done using NFSS2 so none of PLAIN's
% font definitions are in \LaTeX.
%
% \LaTeX\ has its own tabbing environment, so PLAIN's is disabled.
%
% \LaTeX{} uses its own output routine, so most of the plain one was
% removed.
%
% \MaybeStop{}
%
%
%    \begin{macrocode}
%<*2ekernel>
\catcode`\{=1 % left brace is begin-group character
\catcode`\}=2 % right brace is end-group character
\catcode`\$=3 % dollar sign is math shift
\catcode`\&=4 % ampersand is alignment tab
\catcode`\#=6 % hash mark is macro parameter character
\catcode`\^=7 % circumflex and uparrow are for superscripts
\catcode`\_=8 % underline and downarrow are for subscripts
\catcode`\^^I=10 % ascii tab is a blank space
\chardef\active=13 \catcode`\~=\active % tilde is active
\catcode`\^^L=\active \def^^L{\par}% ascii form-feed is \par
%    \end{macrocode}
%
%    \begin{macrocode}
\message{catcodes,}
%    \end{macrocode}
%
% We had to define the |\catcodes| right away, before the message line,
% since |\message| uses the |{| and |}| characters.
% When INITEX (the \TeX\ initializer) starts up,
% it has defined the following |\catcode| values:\\
% |\catcode`\^^@=9 % | ascii null is ignored\\
% |\catcode`\^^M=5 % | ascii return is end-line\\
% |\catcode`\\=0 %   | backslash is TeX escape character\\
% |\catcode`\%=14 %  | percent sign is comment character\\
% |\catcode`\ =10 %  | ascii space is blank space\\
% |\catcode`\^^?=15 %| ascii delete is invalid\\
% |\catcode`\A=11 ... \catcode`\Z=11 %| uppercase letters\\
% |\catcode`\a=11 ... \catcode`\z=11 %| lowercase letters\\
% all others are type 12 (other)
%
% Here is a list of the characters that have been specially catcoded:
%    \begin{macrocode}
\def\dospecials{\do\ \do\\\do\{\do\}\do\$\do\&%
  \do\#\do\^\do\_\do\%\do\~}
%    \end{macrocode}
% (not counting ascii null, tab, linefeed, formfeed, return, delete)
% Each symbol in the list is preceded by \do, which can be defined
% if you want to do something to every item in the list.
%
% We make |@| signs act like letters, temporarily, to avoid conflict
% between user names and internal control sequences of plain format.
%    \begin{macrocode}
\catcode`@=11
%    \end{macrocode}
%
% To make the plain macros more efficient in time and space,
% several constant values are declared here as control sequences.
% If they were changed, anything could happen;
% so they are private symbols.
% \begin{macro}{\@ne}
% \begin{macro}{\tw@}
% \begin{macro}{\thr@@}
% \begin{macro}{\sixt@@n}
% \begin{macro}{\@cclv}
% Small constants are defined using |\chardef|.
%    \begin{macrocode}
\chardef\@ne=1
\chardef\tw@=2
\chardef\thr@@=3
\chardef\sixt@@n=16
\chardef\@cclv=255
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\@cclvi}
% \begin{macro}{\@m}
% \begin{macro}{\@M}
% \begin{macro}{\@MM}
% Constants above 255 defined using |\mathchardef|.
%    \begin{macrocode}
\mathchardef\@cclvi=256
\mathchardef\@m=1000
\mathchardef\@M=10000
\mathchardef\@MM=20000
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% Allocation of registers
%
% Here are macros for the automatic allocation of |\count|, |\box|,
% |\dimen|, |\skip|, |\muskip|, and |\toks| registers, as well as
% |\read| and |\write| stream numbers, |\fam| codes, |\language| codes,
% and |\insert| numbers.
%
%    \begin{macrocode}
\message{registers,}
%    \end{macrocode}
%
% When a register is used only temporarily, it need not be allocated;
% grouping can be used, making the value previously in the register
% return after the close of the group.  The main use of these macros is
% for registers that are defined by one macro and used by others,
% possibly at different nesting levels.  All such registers should be
% defined through these macros; otherwise conflicts may occur,
% especially when two or more macro packages are being used at
% the same time.
%
% \begin{oldcomments}
% The following counters are reserved:
%   0 to 9  page numbering
%       10  count allocation
%       11  dimen allocation
%       12  skip allocation
%       13  muskip allocation
%       14  box allocation
%       15  toks allocation
%       16  read file allocation
%       17  write file allocation
%       18  math family allocation
%       19  language allocation
%       20  insert allocation
%       21  the most recently allocated number
%       22  constant -1
% \end{oldcomments}
%
% New counters are allocated starting with 23, 24, etc.  Other registers
% are allocated starting with 10.  This leaves 0 through 9 for the user
% to play with safely, except that counts 0 to 9 are considered to be
% the page and subpage numbers (since they are displayed during
% output). In this scheme, |\count| 10 always contains the number of the
% highest-numbered counter that has been allocated, |\count| 14 the
% highest-numbered box, etc. Inserts are given numbers 254, 253, etc.,
% since they require a |\count|, |\dimen|, |\skip|, and |\box| all with
% the same number; |\count| 20 contains the lowest-numbered insert that
% has been allocated. Of course, |\box|255 is reserved for |\output|;
% |\count|255, |\dimen|255, and |\skip|255 can be used freely.
%
% It is recommended that macro designers always use
% |\global| assignments with respect to registers numbered\\
% 1, 3, 5, 7, 9,\\
% and always non-|\global| assignments with respect to registers\\
% 0, 2, 4, 6, 8, 255.\\
% This will prevent ``save stack buildup'' that might otherwise occur.
%
%    \begin{macrocode}
\count10=22 % allocates \count registers 23, 24, ...
\count11=9 % allocates \dimen registers 10, 11, ...
\count12=9 % allocates \skip registers 10, 11, ...
\count13=9 % allocates \muskip registers 10, 11, ...
\count14=9 % allocates \box registers 10, 11, ...
\count15=9 % allocates \toks registers 10, 11, ...
\count16=-1 % allocates input streams 0, 1, ...
\count17=-1 % allocates output streams 0, 1, ...
\count18=3 % allocates math families 4, 5, ...
\count19=0 % allocates \language codes 1, 2, ...
\count20=255 % allocates insertions 254, 253, ...
%    \end{macrocode}
%
% \begin{macro}{\insc@unt}
% \begin{macro}{\allocationnumber}
% The insertion counter and most recent allocation.
%    \begin{macrocode}
\countdef\insc@unt=20
\countdef\allocationnumber=21
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\m@ne}
% The constant $-1$.
%    \begin{macrocode}
\countdef\m@ne=22 \m@ne=-1
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\wlog}
% Write on log file (only)
%    \begin{macrocode}
\def\wlog{\immediate\write\m@ne}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\count@}
% \begin{macro}{\dimen@}
% \begin{macro}{\dimen@i}
% \begin{macro}{\dimen@ii}
% \begin{macro}{\skip@}
% \begin{macro}{\toks@}
% Here are abbreviations for the names of scratch registers
% that don't need to be allocated.
%    \begin{macrocode}
\countdef\count@=255
\dimendef\dimen@=0
\dimendef\dimen@i=1 % global only
\dimendef\dimen@ii=2
\skipdef\skip@=0
\toksdef\toks@=0
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\newcount}
% \begin{macro}{\newdimen}
% \begin{macro}{\newskip}
% \begin{macro}{\newmuskip}
% \begin{macro}{\newbox}
% \begin{macro}{\newtoks}
% \begin{macro}{\newread}
% \begin{macro}{\newwrite}
% \begin{macro}{\newfam}
% \begin{macro}{\newlanguage}
% \changes{v1.0c}{1994/03/28}
%         {Remove some \cs{outer} declarations.}
% \changes{v1.1h}{1995/04/24}
%         {Remove remaining \cs{outer} declarations.}
% Now, we define |\newcount|, |\newbox|, etc. so that you can say
% |\newcount\foo| and |\foo| will be defined (with |\countdef|) to
% be the next counter.
%
% To find out which counter |\foo| is, you can look at
% |\allocationnumber|.
%
% Since there's no |\boxdef| command, |\chardef| is used to define a
% |\newbox|, |\newinsert|, |\newfam|, and so on.
%
% \LaTeX\ change: remove |\outer| from |\newcount| and |\newdimen| (FMi)
%            This is necessary to use |\newcount| inside |\if...|
%            later on. Also remove from |\newskip|, |\newbox|
%            |\newwrite| and |\newfam| (DPC) to save later redefinition.
% \changes{v2.0a}{2014/12/30}{New engine-specific allocation scheme (latexrelease)}
% \changes{v2.0f}{2015/03/02}{allow 255 math groups in Unicode engines}
% \changes{v2.0h}{2015/06/19}{Use $-1$ for first range to get contiguous allocation}
%    \begin{macrocode}
%</2ekernel>
%<*2ekernel|latexrelease>
%<latexrelease>\IncludeInRelease{2015/01/01}%
%<latexrelease>                 {\newcount}{Extended Allocation}%
%    \end{macrocode}
%
%    \begin{macrocode}
\def\newcount {\e@alloc\count \countdef {\count10}\insc@unt\float@count}
\def\newdimen {\e@alloc\dimen \dimendef {\count11}\insc@unt\float@count}
\def\newskip  {\e@alloc\skip  \skipdef  {\count12}\insc@unt\float@count}
\def\newmuskip
           {\e@alloc\muskip\muskipdef{\count13}\m@ne\e@alloc@top}
%    \end{macrocode}
% For compatibility use |\chardef| in the classical range.
%    \begin{macrocode}
\def\newbox   {\e@alloc\box
                  {\ifnum\allocationnumber<\@cclvi
                     \expandafter\chardef
                   \else
                     \expandafter\e@alloc@chardef
                   \fi}
                                        {\count14}\insc@unt\float@count}
\def\newtoks  {\e@alloc\toks \toksdef{\count15}\m@ne\e@alloc@top}
\def\newread  {\e@alloc\read \chardef{\count16}\m@ne\sixt@@n}
%    \end{macrocode}
%
% \changes{v2.2a}{2015/11/18}
%         {Extended stream allocation in luatex (0.85)}
% \changes{v2.2b}{2015/11/19}
%         {Only extend allocation of write streams (see luatex list)}
% \changes{v2.3c}{2017/04/10}
%         {Correction to code to skip write18 in luatex}
% Skip |\write18| due to its traditional use as a shell-escape.
%    \begin{macrocode}
\ifx\directlua\@undefined
  \def\newwrite   {\e@alloc\write \chardef{\count17}\m@ne\sixt@@n}
\else
  \def\newwrite   {\e@alloc\write
                   {\ifnum\allocationnumber=18
                     \advance\count17\@ne
                     \allocationnumber\count17 %
                    \fi
                    \global\chardef}%
                   {\count17}%
                   \m@ne
                   {128}}
\fi
%    \end{macrocode}
%
%    \begin{macrocode}
\def\new@mathgroup
  {\e@alloc\mathgroup\chardef{\count18}\m@ne\e@mathgroup@top}
\let\newfam\new@mathgroup
%    \end{macrocode}
%
% \changes{v2.3a}{2016/10/16}{Allow languages up to 16383 in luatex}
%    \begin{macrocode}
\ifx\directlua\@undefined
  \def\newlanguage  {\e@alloc\language \chardef{\count19}\m@ne\@cclvi}
\else
  \def\newlanguage  {\e@alloc\language \chardef{\count19}\m@ne{16384}}
\fi
%</2ekernel|latexrelease>
%    \end{macrocode}
%
%    \begin{macrocode}
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{0000/00/00}%
%<latexrelease>                 {\newcount}{Extended Allocation}%
%<latexrelease>\def\newcount{\alloc@0\count\countdef\insc@unt}
%<latexrelease>\def\newdimen{\alloc@1\dimen\dimendef\insc@unt}
%<latexrelease>\def\newskip{\alloc@2\skip\skipdef\insc@unt}
%<latexrelease>\def\newmuskip{\alloc@3\muskip\muskipdef\@cclvi}
%<latexrelease>\def\newbox{\alloc@4\box\chardef\insc@unt}
%<latexrelease>\def\newtoks{\alloc@5\toks\toksdef\@cclvi}
%<latexrelease>\def\newread{\alloc@6\read\chardef\sixt@@n}
%<latexrelease>\def\newwrite{\alloc@7\write\chardef\sixt@@n}
%<latexrelease>\def\new@mathgroup{\alloc@8\fam\chardef\sixt@@n}
%<latexrelease>\def\newlanguage{\alloc@9\language\chardef\@cclvi}
%<latexrelease>\let\newfam\new@mathgroup
%<latexrelease>\EndIncludeInRelease
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
%\begin{macro}{\e@alloc@chardef}
% \changes{v2.0a}{2014/12/30}{macro added}
%\begin{macro}{\e@alloc@top}
% \changes{v2.0a}{2014/12/30}{macro added}
% The upper limit of  extended registers, which leaves
% this number (eg |\dimen32767|) always unallocated
% by these macros.
% cf traditional |\dimen255|.
%    \begin{macrocode}
%<*2ekernel|latexrelease>
%<latexrelease>\IncludeInRelease{2015/01/01}%
%<latexrelease>                 {\e@alloc@chardef}{Extended Allocation}%
%    \end{macrocode}
%
%    \begin{macrocode}
\ifx\directlua\@undefined
  \ifx\widowpenalties\@undefined
%    \end{macrocode}
% classic tex has $2^8$ registers.
%    \begin{macrocode}
    \mathchardef\e@alloc@top=255
    \let\e@alloc@chardef\chardef
  \else
%    \end{macrocode}
% etex and xetex have $2^{15}$ registers.
%    \begin{macrocode}
    \mathchardef\e@alloc@top=32767
    \let\e@alloc@chardef\mathchardef
  \fi
\else
%    \end{macrocode}
% luatex has $2^{16}$ registers.
%    \begin{macrocode}
  \chardef\e@alloc@top=65535
  \let\e@alloc@chardef\chardef
\fi
%    \end{macrocode}
%
%    \begin{macrocode}
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{0000/00/00}%
%<latexrelease>                 {\e@alloc@chardef}{Extended Allocation}%
%<latexrelease>\let\e@alloc@top\@undefined
%<latexrelease>\let\e@alloc@chardef\@undefined
%<latexrelease>\EndIncludeInRelease
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%\begin{macro}{\e@mathgroup@top}
% \changes{v2.0f}{2015/03/02}{macro added}
% The upper limit of extended math groups (|\fam|)
% 16 in classic \TeX\ and e-\TeX, but 256 in Unicode TeX variants.
%    \begin{macrocode}
%<*2ekernel|latexrelease>
%<latexrelease>\IncludeInRelease{2015/01/01}%
%<latexrelease>                 {\e@mathgroup@top}{Extended Allocation}%
%    \end{macrocode}
%
%    \begin{macrocode}
\ifx\Umathcode\@undefined
%    \end{macrocode}
% classic and e tex have 16 fam (0--15).
%    \begin{macrocode}
  \chardef\e@mathgroup@top=16
\else
%    \end{macrocode}
% xetex and luatex have 256 fam (0--255).
%    \begin{macrocode}
  \chardef\e@mathgroup@top=256
\fi
%    \end{macrocode}
%
%    \begin{macrocode}
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{0000/00/00}%
%<latexrelease>                 {\e@mathgroup@top}{Extended Allocation}%
%<latexrelease>\let\e@mathgroup@top\@undefined
%<latexrelease>\EndIncludeInRelease
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\e@alloc}
% \changes{v2.0a}{2014/12/30}{macro added}
% A modified version of |\alloc@| that
% takes the count register rather than just the final digit of its number
% (assuming |\count|$1x$).
% It also has an extra argument to give the top of the extended range.
%
% |           #1  #2      #3     #4    #5         #6    |
%
% | \e@alloc type defcmd current top extended-top newname|
%
% Note that if just a single allocation range is required
% (not omitting a range up to 255 for inserts) then $-1$
% should be used for the first upper bound argument, |#4|.
%
%    \begin{macrocode}
%<*2ekernel|latexrelease>
%<latexrelease>\IncludeInRelease{2015/01/01}{\e@alloc}{Extended Allocation}%
%    \end{macrocode}
%
% \changes{v2.0h}{2015/06/19}{extra braces in case arguments not single token}
%    \begin{macrocode}
\def\e@alloc#1#2#3#4#5#6{%
  \global\advance#3\@ne
  \e@ch@ck{#3}{#4}{#5}#1%
  \allocationnumber#3\relax
  \global#2#6\allocationnumber
  \wlog{\string#6=\string#1\the\allocationnumber}}%
%    \end{macrocode}
%
%    \begin{macrocode}
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{0000/00/00}{\e@alloc}{Extended Allocation}%
%<latexrelease>\let\e@alloc\@undefined
%<latexrelease>\EndIncludeInRelease
%<*2ekernel>
%    \end{macrocode}
% \end{macro}
%
%\begin{macro}{\e@ch@ck}
% \changes{v2.0a}{2014/12/30}{macro added}
% Extended check command.
% If the first range is exceeded, bump to 256 (or 266 for counts)
% and try again, testing the extended range.
%\begin{macro}{\extrafloats}
% \changes{v2.0a}{2014/12/30}{macro added}
% \changes{v2.0c}{2015/01/23}{reserve counts 256--265}
% Allocate matching registers from the top of the extended range
% and add to |\@freelist|.
%    \begin{macrocode}
%</2ekernel>
%<*2ekernel|latexrelease>
%<latexrelease>\IncludeInRelease{2015/10/01}
%<latexrelease>                 {\e@ch@ck}{Extended Allocation (checking)}%
%    \end{macrocode}
%
%    \begin{macrocode}
\gdef\e@ch@ck#1#2#3#4{%
  \ifnum#1<#2\else
%    \end{macrocode}
%
% If we've reached the classical top limit, bump to 256
% or 266 for counts (count 256--265 are reserved by the allocation
% system).
% \changes{v2.1b}{2015/10/27}
%         {Use global assignment when switching to extended range}
%    \begin{macrocode}
    \ifnum#1=#2\relax
      \global#1\@cclvi
      \ifx\count#4\global\advance#1 10 \fi
    \fi
%    \end{macrocode}
% Check we are below the extended limit.
% \changes{v2.0i}{2015/08/06}
%         {Add \cs{string} in case argument is not an unexpandable primitive}
%    \begin{macrocode}
    \ifnum#1<#3\relax
    \else
      \errmessage{No room for a new \string#4}%
    \fi
  \fi}%
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{2015/01/01}%
%<latexrelease>                 {\e@ch@ck}{Extended Allocation (checking)}%
%<latexrelease>\gdef\e@ch@ck#1#2#3#4{%
%<latexrelease>  \ifnum#1<#2\else
%<latexrelease>    \ifnum#1=#2\relax
%<latexrelease>      #1\@cclvi
%<latexrelease>      \ifx\count#4\advance#1 10 \fi
%<latexrelease>    \fi
%<latexrelease>    \ifnum#1<#3\relax
%<latexrelease>    \else
%<latexrelease>      \errmessage{No room for a new #4}%
%<latexrelease>    \fi
%<latexrelease>  \fi}%
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{0000/00/00}%
%<latexrelease>                 {\e@ch@ck}{Extended Allocation (checking)}%
%<latexrelease>\let\e@ch@ck\@undefined
%<latexrelease>\EndIncludeInRelease
%    \end{macrocode}
%
%    \begin{macrocode}
%<latexrelease>\IncludeInRelease{2015/01/01}%
%<latexrelease>                 {\extrafloats}{Extra floats}%
%    \end{macrocode}
% \end{macro}
%
%    \begin{macrocode}
\let\float@count\e@alloc@top
%    \end{macrocode}
%
% \begin{macro}{\extrafloats}
% \changes{v2.2c}{2016/07/29}{use \cs{global} \cs{chardef}}
%    \begin{macrocode}
\ifx\numexpr\@undefined
%    \end{macrocode}
% In classic TeX use |\newinsert| to allocate float boxes.
%    \begin{macrocode}
\def\extrafloats#1{%
\count@#1\relax
\ifnum\count@>\z@
\newinsert\reserved@a
\global\expandafter\chardef
            \csname bx@\the\allocationnumber\endcsname\allocationnumber
\@cons\@freelist{\csname bx@\the\allocationnumber\endcsname}%
\advance\count@\m@ne
\expandafter\extrafloats
\expandafter\count@
\fi
}%
%    \end{macrocode}
%
%    \begin{macrocode}
\else
%    \end{macrocode}
% In e-tex take float boxes from the top of the extended range.
%    \begin{macrocode}
\def\extrafloats#1{%
\ifnum#1>\z@
\count@\numexpr\float@count-1\relax
%    \end{macrocode}
% \changes{v2.3i}{2023/04/15}{Protect box 255 in lualatex gh/1041}
%    \begin{macrocode}
  \ifnum\count@<266 \ch@ck0\m@ne\insert\fi
  \ch@ck0\count@\count
  \ch@ck1\count@\dimen
  \ch@ck2\count@\skip
  \ch@ck4\count@\box
\global\e@alloc@chardef\float@count\count@
\global\expandafter\e@alloc@chardef
            \csname bx@\the\float@count\endcsname\float@count
\@cons\@freelist{\csname bx@\the\float@count\endcsname}%
%    \end{macrocode}
% \changes{v2.3i}{2023/04/15}{unwind numexpr and ifnum nesting}
%    \begin{macrocode}
\expandafter\extrafloats\expandafter{\the\numexpr#1-1\expandafter}%
%    \end{macrocode}
%    \begin{macrocode}
\fi}%
%    \end{macrocode}
%
%    \begin{macrocode}
\fi
%    \end{macrocode}
%
%    \begin{macrocode}
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{0000/00/00}%
%<latexrelease>                 {\extrafloats}{Extra floats}%
%<latexrelease>\let\float@count\@undefined
%<latexrelease>\let\extrafloats\@undefined
%<latexrelease>\EndIncludeInRelease
%<*2ekernel>
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\alloc@}
% \changes{v2.3d}{2020/08/20}
%         {Define \cs{alloc@} in terms of \cs{e@alloc}}
% Since |\e@alloc| was added in 2015, |\@alloc| has not been used,
% but was left as some legacy code calls it. However the original
% definition gives spurious errors once the ``classic'' registers
% run out, so it is now defined to call |\e@alloc| internally.
%    \begin{macrocode}
%</2ekernel>
%<*2ekernel|latexrelease>
%<latexrelease>\IncludeInRelease{2020/10/01}
%<latexrelease>                 {\alloc@}{emulate alloc@}%
\def\alloc@#1#2#3#4{\e@alloc#2#3{\count1#1}#4\float@count}
%</2ekernel|latexrelease>
%    \end{macrocode}
%
%    \begin{macrocode}
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{0000/00/00}%
%<latexrelease>                 {\alloc@}{emulate alloc@}%
%<latexrelease>\def\alloc@#1#2#3#4#5{\global\advance\count1#1\@ne
%<latexrelease>  \ch@ck#1#4#2%
%<latexrelease>  \allocationnumber\count1#1%
%<latexrelease>  \global#3#5\allocationnumber
%<latexrelease>  \wlog{\string#5=\string#2\the\allocationnumber}}
%<latexrelease>\EndIncludeInRelease
%<*2ekernel>
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\newinsert}
% \changes{v2.1a}{2015/08/30}{new \cs{newinsert} implementation}
%    \begin{macrocode}
%</2ekernel>
%<*2ekernel|latexrelease>
%<latexrelease>\IncludeInRelease{2015/10/01}
%<latexrelease>                 {\newinsert}{Extended \newinsert}%
%    \end{macrocode}
%    \begin{macrocode}
\ifx\numexpr\@undefined
%    \end{macrocode}
% If e-\TeX\ is not available use the original plain \TeX\
% definition of |\newinsert|.
%    \begin{macrocode}
\def\newinsert#1{\global\advance\insc@unt \m@ne
  \ch@ck0\insc@unt\count
  \ch@ck1\insc@unt\dimen
  \ch@ck2\insc@unt\skip
  \ch@ck4\insc@unt\box
  \allocationnumber\insc@unt
  \global\chardef#1\allocationnumber
  \wlog{\string#1=\string\insert\the\allocationnumber}}
%    \end{macrocode}
%    \begin{macrocode}
\else
%    \end{macrocode}
% The highest register allowed with |\insert|.
%    \begin{macrocode}
\ifx\directlua\@undefined
  \chardef\e@insert@top255
\else
  \chardef\e@insert@top\e@alloc@top
\fi
%    \end{macrocode}
% If the classic registers are exhausted, take an insert from the free
% float list and use |\extrafloats| to add a new float to that list.
% \changes{v2.2c}{2016/07/29}{fix for tlb-newinsert-001}
%    \begin{macrocode}
\def\newinsert#1{%
\@tempswafalse
\global\advance\insc@unt\m@ne
\ifnum\count10<\insc@unt
\ifnum\count11<\insc@unt
\ifnum\count12<\insc@unt
\ifnum\count14<\insc@unt
  \@tempswatrue
\fi\fi\fi\fi
\if@tempswa
\allocationnumber\insc@unt
\else
\global\advance\insc@unt\@ne
  \extrafloats\@ne
  \@next\@currbox\@freelist
    {\ifnum\@currbox<\e@insert@top
      \allocationnumber\@currbox
     \else
     \ch@ck0\m@ne\insert
     \fi}%
     {\ch@ck0\m@ne\insert}%
\fi
\global\chardef#1\allocationnumber
\wlog{\string#1=\string\insert\the\allocationnumber}%
}
%    \end{macrocode}
%    \begin{macrocode}
\fi
%</2ekernel|latexrelease>
%    \end{macrocode}
%
%    \begin{macrocode}
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{0000/00/00}%
%<latexrelease>                 {\newinsert}{Extended \newinsert}%
%<latexrelease>\let\e@insert@top\@undefined
%<latexrelease>\def\newinsert#1{\global\advance\insc@unt \m@ne
%<latexrelease>  \ch@ck0\insc@unt\count
%<latexrelease>  \ch@ck1\insc@unt\dimen
%<latexrelease>  \ch@ck2\insc@unt\skip
%<latexrelease>  \ch@ck4\insc@unt\box
%<latexrelease>  \allocationnumber\insc@unt
%<latexrelease>  \global\chardef#1\allocationnumber
%<latexrelease>  \wlog{\string#1=\string\insert\the\allocationnumber}}
%<latexrelease>\EndIncludeInRelease
%<*2ekernel>
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\ch@ck}
%    \begin{macrocode}
\gdef\ch@ck#1#2#3{%
  \ifnum\count1#1<#2\else
    \errmessage{No room for a new #3}%
  \fi}
%    \end{macrocode}
% \end{macro}
%
% \changes{v2.0h}{2015/06/19}{delete spurious old definition of \cs{newtoks}}
% \begin{macro}{\newhelp}
%    \begin{macrocode}
\def\newhelp#1#2{\newtoks#1#1\expandafter{\csname#2\endcsname}}
%    \end{macrocode}
% \end{macro}
%
%
%
%  \begin{macro}{\@inputcheck}
%  \begin{macro}{\@unused}
%    Allocate read stream for testing and output stream that is never open an
%    thus writes to the terminal.
% \changes{v1.0l}{1994/11/07}
%      {move here from ltdefns, remove duplicate \cs{@mainaux}}
% \changes{v2.3e}{2021/03/26}{Allocate \cs{@inputcheck} and
%    \cs{@unused} early so that they are before expl3 allocates
%    more streams (gh/538)}
%    \begin{macrocode}
\newread\@inputcheck
\newwrite\@unused
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%
%
%
%
%
% \begin{macro}{\maxdimen}
% \begin{macro}{\hideskip}
% Here are some examples of allocation.
%    \begin{macrocode}
\newdimen\maxdimen \maxdimen=16383.99999pt % the largest legal <dimen>
\newskip\hideskip \hideskip=-1000pt plus 1fill % negative but can grow
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\p@}
% \begin{macro}{\z@}
% \begin{macro}{\z@skip}
% \begin{macro}{\voidb@x}
%    \begin{macrocode}
\newdimen\p@ \p@=1pt % this saves macro space and time
\newdimen\z@ \z@=0pt % can be used both for 0pt and 0
\newskip\z@skip \z@skip=0pt plus0pt minus0pt
\newbox\voidb@x % permanently void box register
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% Assign initial values to \TeX's parameters
%
%    \begin{macrocode}
\message{parameters,}
%    \end{macrocode}
%
% All of \TeX's numeric parameters are listed here,
% but the code is commented out if no special value needs to be set.
% INITEX makes all parameters zero except where noted.
%
%    \begin{macrocode}
\pretolerance=100
\tolerance=200 % INITEX sets this to 10000
\hbadness=1000
\vbadness=1000
\linepenalty=10
\hyphenpenalty=50
\exhyphenpenalty=50
\binoppenalty=700
\relpenalty=500
\clubpenalty=150
\widowpenalty=150
\displaywidowpenalty=50
\brokenpenalty=100
\predisplaypenalty=10000
%    \end{macrocode}
%
%    \begin{macrocode}
% \postdisplaypenalty=0
% \interlinepenalty=0
% \floatingpenalty=0, set during \insert
% \outputpenalty=0, set before TeX enters \output
%    \end{macrocode}
%
%    \begin{macrocode}
\doublehyphendemerits=10000
\finalhyphendemerits=5000
\adjdemerits=10000
%    \end{macrocode}
%    \begin{macrocode}
% \looseness=0, cleared by TeX after each paragraph
% \pausing=0
% \holdinginserts=0
% \tracingonline=0
% \tracingmacros=0
% \tracingstats=0
% \tracingparagraphs=0
% \tracingpages=0
% \tracingoutput=0
%    \end{macrocode}
%    In the past \LaTeX{} used the default value of \texttt{1} for
%    \cs{tracinglostchars} because this was the best it could do.  This
%    way one would at least get a warning in the \texttt{.log}
%    file. e-\TeX{} improved on that and supported a value of \texttt{2}
%    to show the warning on the terminal, so we could have changed the
%    default when we made the e-\TeX{} extensions required---however,
%    we overlooked that oportunity.
%    In 2021 this parameter was improved on again and now also accepts
%    the value \texttt{3}
%    (error on the terminal). This made us realize that we should
%    change the default. Using \texttt{3} would really be the
%    best, but for compatibility reasons we only use \texttt{2}.
% \changes{v2.3g}{2021/07/16}{Use 2 as default value for \cs{tracinglostchars}}
%    \begin{macrocode}
\tracinglostchars=2
%    \end{macrocode}
%    \begin{macrocode}
% \tracingcommands=0
% \tracingrestores=0
%    \end{macrocode}
%
% \begin{macro}{\tracingstacklevels}
%   For Lua\TeX, the \cs{tracingstacklevels} functionality was
%   implemented as a callback, so here we just define the count register
%   to hold the value of the parameter.
%    \begin{macrocode}
%</2ekernel>
%<*2ekernel|latexrelease>
%<latexrelease>\IncludeInRelease{2021/06/01}{\tracingstacklevels}%
%<latexrelease>                 {tracingstacklevels}%
\ifx\directlua\@undefined
  % \tracingstacklevels=0 % added in 2021
\else
  \newcount\tracingstacklevels
  % Code for \tracingstacklevels defined in ltfinal.dtx
\fi
%<latexrelease>\EndIncludeInRelease
%<latexrelease>
%<latexrelease>\IncludeInRelease{0000/00/00}{\tracingstacklevels}%
%<latexrelease>                 {tracingstacklevels}%
%<latexrelease>\ifx\directlua\@undefined
%<latexrelease>\else
%<latexrelease>  \let\tracingstacklevels\@undefined
%<latexrelease>\fi
%<latexrelease>\EndIncludeInRelease
%</2ekernel|latexrelease>
%<*2ekernel>
%    \end{macrocode}
% \end{macro}
%
% \language=0
%    \begin{macrocode}
\uchyph=1
%    \end{macrocode}
%
%    \begin{macrocode}
% \lefthyphenmin=2 \righthyphenmin=3 set below
% \globaldefs=0
% \maxdeadcycles=25 % INITEX does this
% \hangafter=1 % INITEX does this, also TeX after each paragraph
% \fam=0
% \mag=1000 % INITEX does this
% \escapechar=`\\ % INITEX does this
%    \end{macrocode}
%
%    \begin{macrocode}
\defaulthyphenchar=`\-
\defaultskewchar=-1
%    \end{macrocode}
%
%    \begin{macrocode}
% \endlinechar=`\^^M % INITEX does this
% \newlinechar=-1     \LaTeX\ sets this in ltdefns.dtx.
%    \end{macrocode}
%
%    \begin{macrocode}
\delimiterfactor=901
%    \end{macrocode}
%
%    \begin{macrocode}
% \time=now % TeX does this at beginning of job
% \day=now % TeX does this at beginning of job
% \month=now % TeX does this at beginning of job
% \year=now % TeX does this at beginning of job
%    \end{macrocode}
%
%    In \LaTeX{} we don't want box information in the transcript
%    unless we do a full tracing.
%  \changes{v1.0g}{1994/04/28}{Turn off overfull box tracing in log}
%
%    \begin{macrocode}
\showboxbreadth=-1
\showboxdepth=-1
\errorcontextlines=-1
%    \end{macrocode}
%
%    \begin{macrocode}
\hfuzz=0.1pt
\vfuzz=0.1pt
\overfullrule=5pt
\maxdepth=4pt
\splitmaxdepth=\maxdimen
\boxmaxdepth=\maxdimen
%    \end{macrocode}
%
%    \begin{macrocode}
% \lineskiplimit=0pt, changed by \normalbaselines
%    \end{macrocode}
%
%    \begin{macrocode}
\delimitershortfall=5pt
\nulldelimiterspace=1.2pt
\scriptspace=0.5pt
%    \end{macrocode}
%
%    \begin{macrocode}
% \mathsurround=0pt
% \predisplaysize=0pt, set before TeX enters $$
% \displaywidth=0pt, set before TeX enters $$
% \displayindent=0pt, set before TeX enters $$
%    \end{macrocode}
%
%    \begin{macrocode}
\parindent=20pt
%    \end{macrocode}
%
%    \begin{macrocode}
% \hangindent=0pt, zeroed by TeX after each paragraph
% \hoffset=0pt
% \voffset=0pt
%
% \baselineskip=0pt, changed by \normalbaselines
% \lineskip=0pt, changed by \normalbaselines
%    \end{macrocode}
%
%    \begin{macrocode}
\parskip=0pt plus 1pt
\abovedisplayskip=12pt plus 3pt minus 9pt
\abovedisplayshortskip=0pt plus 3pt
\belowdisplayskip=12pt plus 3pt minus 9pt
\belowdisplayshortskip=7pt plus 3pt minus 4pt
%    \end{macrocode}
%
%    \begin{macrocode}
% \leftskip=0pt
% \rightskip=0pt
%    \end{macrocode}
%
%    \begin{macrocode}
\topskip=10pt
\splittopskip=10pt
%    \end{macrocode}
%
%    \begin{macrocode}
% \tabskip=0pt
% \spaceskip=0pt
% \xspaceskip=0pt
%    \end{macrocode}
%
%    \begin{macrocode}
\parfillskip=0pt plus 1fil
%    \end{macrocode}
%
%
% \begin{macro}{\normalbaselineskip}
% \begin{macro}{\normallineskip}
% \begin{macro}{\normallineskiplimit}
% We also define special registers that function like parameters:
%    \begin{macrocode}
\newskip\normalbaselineskip \normalbaselineskip=12pt
\newskip\normallineskip \normallineskip=1pt
\newdimen\normallineskiplimit \normallineskiplimit=0pt
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\interfootlinepenalty}
%    \begin{macrocode}
\newcount\interfootnotelinepenalty \interfootnotelinepenalty=100
%    \end{macrocode}
% \end{macro}
%
% Definitions for preloaded fonts
%
% \begin{macro}{\magstephalf}
% \begin{macro}{\magstep}
%    \begin{macrocode}
\def\magstephalf{1095 }
\def\magstep#1{\ifcase#1 \@m\or 1200\or 1440\or 1728\or
               2074\or 2488\fi\relax}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%
% Macros for setting ordinary text
%
% \begin{macro}{\frenchspacing}
% \begin{macro}{\nonfrenchspacing}
%    \begin{macrocode}
\def\frenchspacing{\sfcode`\.\@m \sfcode`\?\@m \sfcode`\!\@m
  \sfcode`\:\@m \sfcode`\;\@m \sfcode`\,\@m}
\def\nonfrenchspacing{\sfcode`\.3000\sfcode`\?3000\sfcode`\!3000%
  \sfcode`\:2000\sfcode`\;1500\sfcode`\,1250 }
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\normalbaselines}
%    \begin{macrocode}
\def\normalbaselines{\lineskip\normallineskip
  \baselineskip\normalbaselineskip \lineskiplimit\normallineskiplimit}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\M}
% \begin{macro}{\I}
% \changes{v1.1m}{1995/09/01}{Use \cs{let} to save space}
% Save a bit of space by using |\let| here.
%    \begin{macrocode}
\def\^^M{\ } % control <return> = control <space>
\let\^^I\^^M % same for <tab>
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\lq}
% \begin{macro}{\rq}
%    \begin{macrocode}
\def\lq{`}
\def\rq{'}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\lbrack}
% \begin{macro}{\rbrack}
%    \begin{macrocode}
\def\lbrack{[}
\def\rbrack{]}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\aa}
% \begin{macro}{\AA}
% These are not from plain.tex but they are similar to other commands
% found here and nowhere else, being alternate input forms for
% characters.
%    \begin{macrocode}
\def \aa {\r a}
\def \AA {\r A}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\endgraf}
% \begin{macro}{\endline}
%    \begin{macrocode}
\let\endgraf=\par
\let\endline=\cr
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\space}
%    \begin{macrocode}
\def\space{ }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\empty}
% \changes{v1.1m}{1995/09/01}{Use \cs{let} to save space}
% This probably ought to go altogether, but let it to the \LaTeX\
% version to save space.
%    \begin{macrocode}
\let\empty\@empty
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\null}
%    \begin{macrocode}
\def\null{\hbox{}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\bgroup}
% \begin{macro}{\egroup}
%    \begin{macrocode}
\let\bgroup={
\let\egroup=}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\obeylines,\obeyspaces}
%    In |\obeylines|, we say |\let^^M=\obeyedline| instead of |\def^^M{\obeyedline}|
%    since this allows, for example,
% |\let\obeyedline=\cr \obeylines \halign{...|.
%
%    This is essentially a plain \TeX{} trick and in its original
%    version where you had to use to use |\let\par=\cr| not really a
%    safe idea in \LaTeX. If anybody used this trick
%    this now breaks (and one needs to use \cs{obeyedline} instead).
% \changes{v2.3h}{2022/01/25}{Provide redirection to support special
%    use cases (gh/367)}
%    \begin{macrocode}
%</2ekernel>
%<*2ekernel|latexrelease>
%<latexrelease>\IncludeInRelease{2022/06/01}{\obeylines}%
%<latexrelease>    {Add a redirection to obeylines and obeyspaces}%
%    \end{macrocode}
%    If the active |^^M| escapes, e.g., into a \cs{write} (which is
%    effectively in a different context) then we don't want the definition
%    from \cs{obeylines} but rather a simple \cs{par} (in fact even
%    the primitive one, not the \LaTeX{} version \cs{para\_end:} which
%    is only defined later).
%
%    \begin{macrocode}
\begingroup
\catcode`\^^M=\active % these lines must end with %
  \gdef\obeylines{\catcode`\^^M\active%
    \let^^M\obeyedline%
%    \end{macrocode}
%
%    The next line ending the definition is rather curious and it took
%    me awhile to understand why rollback fails. The problem is the
%    following: if \texttt{latexrelease} is used, then blocks of
%    \cs{IncludeInRelease} \dots\ \cs{EndIncludeInRelease} are
%    bypassed at high speed by grabbing each as a delimited
%    argument. However, in that case |^^M| is seen not as code but as
%    line ending characters and in that mode \TeX{} discards
%    everything from that point onwards to the real end of the line so
%    it works like a comment --- pretty strange really (and I think
%    due to the fact that the original pascal compiler could have some
%    garbage showing up after the normal line ending character. Thus
%    we really have to make sure that any closing braces is not one
%    the same line as an |^^M|, because otherwise it would get dropped
%    and we end with unbalanced braces and never see the
%    \cs{EndIncludeInRelease} --- weird. In other places it doesn't
%    matter because we aren't using the incomplete result.
%    \begin{macrocode}
  }%
  \global\let^^M\par % this is in case ^^M appears in a \write
\endgroup
%    \end{macrocode}
%
% \begin{macro}{\obeyedline}
%    The \cs{obeyedline} expands by default to
%    \cs{par} with whatever definition \cs{par} has when it is
%    executed. It can, however, be
%    redefined (before calling \cs{obeylines}!) to achieve some
%    special effects. If you want to alter this definition when already
%    in the scope of \cs{obeylines}, it has no effect (because
%    \cs{let} is used above).
%    In that case simply make another call to \cs{obeylines}
%    immediately. As you are in a restricted scope all that happens is
%    that your redefinition is applied.
%
%    For the default definition we have to use \cs{def} not \cs{let}
%    because the meaning of \cs{par} can change and we want to use the
%    one that is current when \cs{obeylines} act.
%
%    There is a small subtlety here: in an \cs{edef} the active |^^M| stayed
%    put (because it was equal to the primitive \cs{par}), now
%    \cs{obeyedline} expands and you get what it  contains, i.e., in that
%    case \cs{par}, into the \cs{edef} or \cs{mark} unless we use
%    \cs{protected} on it.
%    \begin{macrocode}
\protected\gdef\obeyedline{\par}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\obeyedspace}
%    The definition of \cs{obeyspaces} is changed in the same way and
%    now executes \cs{obeyedspace} for each active space.
%    \begin{macrocode}
\global\let\obeyedspace\space
%    \end{macrocode}
% \end{macro}
%
%    \begin{macrocode}
\begingroup
\catcode`\ =\active%
\gdef\obeyspaces{\catcode`\ \active\let =\obeyedspace}%
%    \end{macrocode}
%    An active space elsewhere generates \cs{space} by default
%    (for example in a \cs{write}).  
%    \begin{macrocode}
\global\let =\space%
\endgroup
%    \end{macrocode}
%
%    \begin{macrocode}
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{0000/00/00}{\obeylines}%
%<latexrelease>    {Add a redirection to obeylines and obeyspaces}%
%<latexrelease>
%    \end{macrocode}
%    From 2019 onwards the commands are made robust (somewhat later in
%    the kernel sources). So if we roll back they are robust, so when
%    redefining them we have get rid of the robust payload
%    first. Otherwise that is seen by the later rollback below, which
%    then installs a fragile version of the new definition on top of
%    the one we roll back to here, sigh. \cs{kernel@make@fragile} also
%    changes its definition (later own) so this is done directly.
%    \begin{macrocode}
%<latexrelease>\expandafter\let\csname obeylines \endcsname\@undefined
%<latexrelease>\expandafter\let\csname obeyspace \endcsname\@undefined
%<latexrelease>
%<latexrelease>\begingroup
%<latexrelease>\catcode`\^^M=\active % these lines must end with %
%<latexrelease>  \gdef\obeylines{\catcode`\^^M\active \let^^M\par %
%    \end{macrocode}
%    Closing brace on a separate line (see comment above).
%    \begin{macrocode}
%<latexrelease>                 }%
%    \end{macrocode}
%    Another pitfall: if we do a rollback \cs{par} is no longer the
%    primitive, so the roll back definition needs \cs{let} to what is
%    new the primitive.
%    \begin{macrocode}
%<latexrelease>  \global\let^^M\RawParEnd % this is in case ^^M appears in a \write
%<latexrelease>\endgroup
%<latexrelease>\def\obeyspaces{\catcode`\ \active}
%<latexrelease>
%<latexrelease>\let\obeyedline\@undefined
%<latexrelease>\let\obeyedspace\@undefined
%<latexrelease>\EndIncludeInRelease
%<*2ekernel>
%    \end{macrocode}
% \end{macro}
%
%  \begin{macro}{\loop}
% \changes{v1.0h}{1994/05/16}{Use Kabelschacht method}
%  \begin{macro}{\iterate}
% \changes{v1.1b}{1994/11/10}
%         {(CAR) added extra \cs{relax}}
% \changes{v1.1m}{1994/05/26}
%         {(CAR) added \cs{long}}
%  \begin{macro}{\repeat}
%    We use Kabelschacht's method of doing loops, see TUB 8\#2 (1987).
%    (unless that breaks something :-).  It turned out to need an
%    extra |\relax|: see pr/642 (|\loop| could do one iteration too much
%    in certain cases).
%    \begin{macrocode}
\long\def \loop #1\repeat{%
  \def\iterate{#1\relax  % Extra \relax
               \expandafter\iterate\fi
               }%
  \iterate
  \let\iterate\relax
}
%    \end{macrocode}
%    This setting of |\repeat| is needed to make |\loop...\if...\repeat|
%    skippable within another |\if...|.
%    \begin{macrocode}
\let\repeat=\fi
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%
% \LaTeX\ defines |\smallskip|, etc.\ in |ltspace.dtx|.
%
% \begin{macro}{\nointerlineskip}
% \begin{macro}{\offinterlineskip}
% \changes{v1.1n}{1995/07/02}{Replaced 1000 by \cs{@m}}
%    \begin{macrocode}
\def\nointerlineskip{\prevdepth-\@m\p@}
\def\offinterlineskip{\baselineskip-\@m\p@
  \lineskip\z@ \lineskiplimit\maxdimen}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%
% \begin{macro}{\vglue}
% \begin{macro}{\hglue}
%    \begin{macrocode}
\def\vglue{\afterassignment\vgl@\skip@=}
\def\vgl@{\par \dimen@\prevdepth \hrule \@height\z@
  \nobreak\vskip\skip@ \prevdepth\dimen@}
\def\hglue{\afterassignment\hgl@\skip@=}
\def\hgl@{\leavevmode \count@\spacefactor \vrule \@width\z@
  \nobreak\hskip\skip@ \spacefactor\count@}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%
% \LaTeX\ defines |~| in |ltdefns.dtx|.
%
% \begin{macro}{\slash}
%    This generates a |/| acting a bit like |-| but still allows hyphenation
%    in the word part preceding it (but not after).
%    \begin{macrocode}
\def\slash{/\penalty\exhyphenpenalty}
%    \end{macrocode}
%  \end{macro}
%
% \begin{macro}{\break}
% \begin{macro}{\nobreak}
% \begin{macro}{\allowbreak}
%    \begin{macrocode}
\def\break{\penalty-\@M}
\def\nobreak{\penalty \@M}
\def\allowbreak{\penalty \z@}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%
% \begin{macro}{\filbreak}
% \begin{macro}{\goodbreak}
%    \begin{macrocode}
\def\filbreak{\par\vfil\penalty-200\vfilneg}
\def\goodbreak{\par\penalty-500 }
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%
% \begin{macro}{\eject}
% \changes{v1.1s}{1995/10/17}{Move \cs{supereject} to compat file}
% Define |\eject| as in plain \TeX\ but define |\supereject| only in
% the compatibility file.
%    \begin{macrocode}
\def\eject{\par\break}
%    \end{macrocode}
%  \end{macro}
%
% \begin{macro}{\removelastskip}
%    \begin{macrocode}
\def\removelastskip{\ifdim\lastskip=\z@\else\vskip-\lastskip\fi}
%    \end{macrocode}
%  \end{macro}
%
% \begin{macro}{\smallbreak}
% \begin{macro}{\medbreak}
% \begin{macro}{\bigbreak}
%    \begin{macrocode}
\def\smallbreak{\par\ifdim\lastskip<\smallskipamount
  \removelastskip\penalty-50\smallskip\fi}
\def\medbreak{\par\ifdim\lastskip<\medskipamount
  \removelastskip\penalty-100\medskip\fi}
\def\bigbreak{\par\ifdim\lastskip<\bigskipamount
  \removelastskip\penalty-200\bigskip\fi}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%
% \begin{macro}{\m@th}
% \changes{v1.0h}{1994/05/16}{Remove unnecessary space}
%    \begin{macrocode}
\def\m@th{\mathsurround\z@}
%    \end{macrocode}
%  \end{macro}
%
% \begin{macro}{\underbar}
%    Due to \LaTeX's redefinition of |\underline| plain \TeX's
%    |\underbar| can be done in a simpler fashion (but do we
%    need it at all?).
% \changes{v1.1m}{1994/05/26}
%         {(CAR/FMi) changed to use box \cs{tw@}}
% \changes{v1.1p}{1994/05/26}
%         {(DPC) changed to use \cs{sbox}}
%    \begin{macrocode}
\def\underbar#1{\underline{\sbox\tw@{#1}\dp\tw@\z@\box\tw@}}
%    \end{macrocode}
%  \end{macro}
%
% \begin{macro}{\strutbox}
% \begin{macro}{\strut}
% \LaTeX\ sets |\strutbox| in |\set@fontsize|.
%    \begin{macrocode}
\newbox\strutbox
\def\strut{\relax\ifmmode\copy\strutbox\else\unhcopy\strutbox\fi}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%
% \begin{macro}{\hidewidth}
% For alignment entries that can stick out.
%    \begin{macrocode}
\def\hidewidth{\hskip\hideskip}
%    \end{macrocode}
%  \end{macro}
%
% \changes{v1.0h}{1994/05/16}{Remove unnecessary def for \cs{item}}
% \changes{v1.1i}{1995/04/27}
%   {Move \cs{hang} and \cs{textindent} to latex209.def}
% \changes{RmS}{1991/11/04}{Removed \cs{itemitem} since never
%    needed/useful with \LaTeX.}
%
% \begin{macro}{\narrower}
%    \begin{macrocode}
\def\narrower{%
  \advance\leftskip\parindent
  \advance\rightskip\parindent}
%    \end{macrocode}
%  \end{macro}
%
% \changes{v1.1c}{1994/11/12}{Comment out more encoding specific
%                             commands}
% \LaTeX\ defines |\ae| and similar commands elsewhere.
%
%    \begin{macrocode}
\chardef\%=`\%
\chardef\&=`\&
\chardef\#=`\#
%    \end{macrocode}
%
% Most text commands are actually encoding specific and therefore
% defined later, so commented out or removed from this file.
% \changes{v1.0h}{1994/05/16}{Comment out encoding specific commands}
%
% \begin{macro}{\leavevmode}
% begins a paragraph, if necessary
%    \begin{macrocode}
\def\leavevmode{\unhbox\voidb@x}
%    \end{macrocode}
%  \end{macro}
%
% \begin{macro}{\mathhexbox}
%    \begin{macrocode}
\def\mathhexbox#1#2#3{\mbox{$\m@th \mathchar"#1#2#3$}}
%    \end{macrocode}
%  \end{macro}
%
%
% \begin{macro}{\ialign}
%    \begin{macrocode}
\def\ialign{\everycr{}\tabskip\z@skip\halign} % initialized \halign
%    \end{macrocode}
%  \end{macro}
%
% \begin{macro}{\oalign}
% \begin{macro}{\o@lign}
% \begin{macro}{\ooalign}
%    \begin{macrocode}
\def\oalign#1{\leavevmode\vtop{\baselineskip\z@skip \lineskip.25ex%
  \ialign{##\crcr#1\crcr}}}
\def\o@lign{\lineskiplimit\z@ \oalign}
\def\ooalign{\lineskiplimit-\maxdimen \oalign}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%
% \begin{macro}{\sh@ft}
% \changes{v1.1t}{1996/07/26}{replace \cs{dimen}\cs{z@} by
%          \cs{dimen@}}
% \changes{v1.1y}{2005/09/27}{Macro no longer used but
%   left for compatibility}
% The definition of this macro in plain.tex was improved in
% about 1997; but as a result its usage was changed and its new
% definition is not appropriate for \LaTeX{}.
%
% Since the version given here has been in use by
% \LaTeX{} for many years it does not seem prudent to remove it now.
% As far as we can tell it has only been used to define~|\b| and~|\d|
% but this cannot be certain.
%    \begin{macrocode}
\def\sh@ft#1{\dimen@.00#1ex\multiply\dimen@\fontdimen1\font
  \kern-.0156\dimen@} % compensate for slant in lowered accents
%    \end{macrocode}
%  \end{macro}
%
% \begin{macro}{\ltx@sh@ft}
% \changes{v1.1y}{2005/09/27}{New macro}
% This is the \LaTeX{} version of the second incarnation of the plain
% macro |\sh@ft|, which takes a dimension as its argument.  It shifts
% a pseudo-accent horizontally by an amount proportional to the product
% of its argument and the slant-per-point (fontdimen 1).
%
%    \begin{macrocode}
\def\ltx@sh@ft #1{%
  \dimen@ #1%
  \kern \strip@pt
    \fontdimen1\font \dimen@
  } % kern by #1 times the current slant
%    \end{macrocode}
%  \end{macro}
%
%
%
% \LaTeX{} change: the text commands such as
% |\d|, |\b|, |\c|, |\copyright|,~|\TeX|
% are now defined elsewhere.
%
% \changes{LaTeX2e}
%     {1993/11/29}{All accents in decimals; suggested by Paul Taylor}
% \changes{v1.0d}{1994/04/12}
%         {Define \cs{@acci}}
% \changes{v1.0h}{1994/05/16}{Remove \cs{@acci} and friends again}
%
% \LaTeX{} change: Make |\t| work in a moving argument.
% Now defined elsewhere.
%
% \begin{macro}{\hrulefill}
% \begin{macro}{\dotfill}
% \LaTeX\ change: |\kern\z@| added to end of
% |\hrulefill| and |\dotfill|
% to make them work in `tabular' and `array' environments.
% (Change made 24 July 1987).
% \LaTeX\ change: |\leavevmode| added at beginning of
% |\dotfill| and |\hrulefill|
% so that they work as expected in vertical mode.
%    \begin{macrocode}
\def\hrulefill{\leavevmode\leaders\hrule\hfill\kern\z@}
%    \end{macrocode}
% The box in |\dotfill| originally contained (in plain.tex):\\
% |\mkern 1.5mu .\mkern 1.5mu|;\\
% the width of .44em differs from this
% by .04pt which is probably an acceptable difference within leaders.
% \changes{v1.1u}{1996/10/28}{Removed math mode}
% \changes{v1.1v}{1996/10/29}{Got arithmetic correct (CAR)}
% \changes{v1.1w}{1996/11/03}{Saved tokens by using \cs{hb@xt@}}
%    \begin{macrocode}
\def\dotfill{%
  \leavevmode
  \cleaders \hb@xt@ .44em{\hss.\hss}\hfill
  \kern\z@}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%
% INITEX sets |\sfcode x=1000| for all x, except that |\sfcode`X=999|
% for uppercase letters. The following changes are needed:
%    \begin{macrocode}
\sfcode`\)=0 \sfcode`\'=0 \sfcode`\]=0
%    \end{macrocode}
% The |\nonfrenchspacing| macro will make further changes to
% |\sfcode| values.
%
%
% Definitions related to output
%
%
% \changes{v1.1k}{1995/05/22}{Definitions of \cs{footins} and
%                 \cs{footnoterule} moved to ltfloat.}
%
%
% |\magnification| doesn't work in \LaTeX.
%\begin{verbatim}
%\def\magnification{\afterassignment\m@g\count@}
%\def\m@g{\mag\count@
%  \hsize6.5truein\vsize8.9truein\dimen\footins8truein}
%\end{verbatim}
%
% \begin{macro}{\showoverfull}
% \changes{v0.1k ltfinal}{1994/05/19}{used \cs{@ne} not 1}
% The following commands are used in debugging:
%    \begin{macrocode}
\def\showoverfull{\tracingonline\@ne}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\showoutput}
% \changes{v0.1k ltfinal}{1994/05/19}
%         {used \cs{maxdimen} not 99999}
% \changes{v1.1n}{1995/07/02}{Use \cs{showoverfull} to save space}
% \changes{v1.1x}{2002/02/24}{Use newly added \cs{loggingoutput}}
% \begin{macro}{\loggingoutput}
% \changes{v1.1x}{2002/02/24}{Macro added}
%    \begin{macrocode}
\gdef\loggingoutput{\tracingoutput\@ne
    \showboxbreadth\maxdimen\showboxdepth\maxdimen\errorstopmode}
\gdef\showoutput{\loggingoutput\showoverfull}
%</2ekernel>
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%
% \begin{macro}{\tracingall}
% \changes{LaTeX209}{1991/08/26}{Added
%    \cs{errorcontextlines}!=\cs{maxdimen}, suggested by J. Schrod}
% \changes{v1.1n}{1995/07/02}{Use \cs{showoutput} to save space}
% \changes{v1.1x}{2002/02/24}{Use newly added \cs{loggingoutput}}
% \begin{macro}{\loggingall}
% \changes{v1.1x}{2002/02/24}{Macro added}
% \changes{v2.0b}{2012/01/20}{etex tracing if available}
% \changes{v2.0d}{2015/02/20}{Spell commands correctly :-)}
% \changes{v2.0g}{2015/03/10}{Reorganize to be less noisy}
% \changes{v2.3f}{2021/04/18}{Drop pre-$\varepsilon$-\TeX{} support}
% \changes{v2.3f}{2021/04/18}
%                {Add \cs{tracingstacklevels} and \cs{tracinglostchars}=3}
%    \begin{macrocode}
%<latexrelease>\IncludeInRelease{2021/06/01}{\loggingall}
%<latexrelease>                 {\tracingstacklevels and \tracinglostchars=3}%
%<*2ekernel|latexrelease>
\edef\loggingall{%
  \tracingstats\tw@
  \tracingpages\@ne
  \tracinglostchars\thr@@
  \tracingparagraphs\@ne
  \tracinggroups\@ne
  \tracingifs\@ne
  \tracingscantokens\@ne
  \tracingnesting\@ne
  \errorcontextlines\maxdimen
  \ifdefined\tracingstacklevels \tracingstacklevels\maxdimen \fi
  \noexpand \loggingoutput
  \tracingmacros\tw@
  \tracingcommands\thr@@
  \tracingrestores\@ne
  \tracingassigns\@ne
}%
\def\tracingall{\showoverfull\loggingall}
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%<latexrelease>
%<latexrelease>\IncludeInRelease{2015/01/01}{\loggingall}{etex tracing}%
%<latexrelease>\ifx\tracingscantokens\@undefined
%<latexrelease>\gdef\loggingall{%
%<latexrelease>  \tracingstats\tw@
%<latexrelease>  \tracingpages\@ne
%<latexrelease>  \tracinglostchars\@ne
%<latexrelease>  \tracingparagraphs\@ne
%<latexrelease>  \errorcontextlines\maxdimen
%<latexrelease>  \loggingoutput
%<latexrelease>  \tracingmacros\tw@
%<latexrelease>  \tracingcommands\tw@
%<latexrelease>  \tracingrestores\@ne
%<latexrelease>  }%
%<latexrelease>\else
%<latexrelease>\gdef\loggingall{%
%<latexrelease>  \tracingstats\tw@
%<latexrelease>  \tracingpages\@ne
%<latexrelease>  \tracinglostchars\tw@
%<latexrelease>  \tracingparagraphs\@ne
%<latexrelease>  \tracinggroups\@ne
%<latexrelease>  \tracingifs\@ne
%<latexrelease>  \tracingscantokens\@ne
%<latexrelease>  \tracingnesting\@ne
%<latexrelease>  \errorcontextlines\maxdimen
%<latexrelease>  \loggingoutput
%<latexrelease>  \tracingmacros\tw@
%<latexrelease>  \tracingcommands\thr@@
%<latexrelease>  \tracingrestores\@ne
%<latexrelease>  \tracingassigns\@ne
%<latexrelease>}%
%<latexrelease>\fi
%<latexrelease>\gdef\tracingall{\showoverfull\loggingall}
%<latexrelease>\EndIncludeInRelease
%<latexrelease>
%<latexrelease>\IncludeInRelease{0000/00/00}{\loggingall}{etex tracing}%
%<latexrelease>\gdef\loggingall{\tracingcommands\tw@\tracingstats\tw@
%<latexrelease>  \tracingpages\@ne\tracinglostchars\@ne
%<latexrelease>  \tracingmacros\tw@\tracingparagraphs\@ne\tracingrestores\@ne
%<latexrelease>  \errorcontextlines\maxdimen\loggingoutput}
%<latexrelease>  \gdef\tracingall{\loggingall\showoverfull}
%<latexrelease>\EndIncludeInRelease
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%
% \begin{macro}{\tracingnone}
% \changes{v2.0g}{2015/03/10}{macro added}
% \changes{v2.3f}{2021/04/18}{Drop pre-$\varepsilon$-\TeX{} support}
% \changes{v2.3f}{2021/04/18}
%                {Add \cs{tracingstacklevels} and \cs{tracinglostchars}=3}
%    \begin{macrocode}
%<latexrelease>\IncludeInRelease{2015/01/01}{\tracingnone}%
%<latexrelease>                             {turn off etex tracing}%
%<*2ekernel|latexrelease>
\edef\tracingnone{%
  \tracingassigns\z@
  \tracingrestores\z@
  \tracingonline\z@
  \tracingcommands\z@
  \showboxdepth\m@ne
  \showboxbreadth\m@ne
  \tracingoutput\z@
  \errorcontextlines\m@ne
  \ifdefined\tracingstacklevels \tracingstacklevels\z@ \fi
  \tracingnesting\z@
  \tracingscantokens\z@
  \tracingifs\z@
  \tracinggroups\z@
  \tracingparagraphs\z@
  \tracingmacros\z@
%    \end{macrocode}
%    None really means go back to the \LaTeX{} ``default'' and for
%    \cs{tracinglostchars} this should therefore be 2 these days.
% \changes{v2.3j}{2023/11/07}{Set \cs{tracinglostchars} to 2 in
%    \cs{tracingnone} (gh/549)}
%    \begin{macrocode}
  \tracinglostchars\tw@
  \tracingpages\z@
  \tracingstats\z@
}%
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%<latexrelease>
%<latexrelease>\IncludeInRelease{2015/01/01}{\tracingnone}%
%<latexrelease>                             {turn off etex tracing}%
%<latexrelease>\ifx\tracingscantokens\@undefined
%<latexrelease>\def\tracingnone{%
%<latexrelease>  \tracingonline\z@
%<latexrelease>  \tracingcommands\z@
%<latexrelease>  \showboxdepth\m@ne
%<latexrelease>  \showboxbreadth\m@ne
%<latexrelease>  \tracingoutput\z@
%<latexrelease>  \errorcontextlines\m@ne
%<latexrelease>  \tracingrestores\z@
%<latexrelease>  \tracingparagraphs\z@
%<latexrelease>  \tracingmacros\z@
%<latexrelease>  \tracinglostchars\@ne
%<latexrelease>  \tracingpages\z@
%<latexrelease>  \tracingstats\z@
%<latexrelease>}%
%<latexrelease>\else
%<latexrelease>\def\tracingnone{%
%<latexrelease>  \tracingassigns\z@
%<latexrelease>  \tracingrestores\z@
%<latexrelease>  \tracingonline\z@
%<latexrelease>  \tracingcommands\z@
%<latexrelease>  \showboxdepth\m@ne
%<latexrelease>  \showboxbreadth\m@ne
%<latexrelease>  \tracingoutput\z@
%<latexrelease>  \errorcontextlines\m@ne
%<latexrelease>  \tracingnesting\z@
%<latexrelease>  \tracingscantokens\z@
%<latexrelease>  \tracingifs\z@
%<latexrelease>  \tracinggroups\z@
%<latexrelease>  \tracingparagraphs\z@
%<latexrelease>  \tracingmacros\z@
%<latexrelease>  \tracinglostchars\@ne
%<latexrelease>  \tracingpages\z@
%<latexrelease>  \tracingstats\z@
%<latexrelease>}%
%<latexrelease>\fi
%<latexrelease>\EndIncludeInRelease
%<latexrelease>
%<latexrelease>\IncludeInRelease{0000/00/00}{\tracingnone}%
%<latexrelease>                             {turn off etex tracing}%
%<latexrelease>\let\tracingnone\@undefined
%<latexrelease>\EndIncludeInRelease
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\hideoutput}
% \changes{v2.0g}{2015/03/10}{macro added}
%    \begin{macrocode}
%<*2ekernel|latexrelease>
%<latexrelease>\IncludeInRelease{2015/01/01}{\hideoutput}%
%<latexrelease>                             {hide output from tracing}%
\def\hideoutput{%
  \tracingoutput\z@
  \showboxbreadth\m@ne
  \showboxdepth\m@ne
  \tracingonline\m@ne
}%
%<latexrelease>\EndIncludeInRelease
%<latexrelease>
%<latexrelease>\IncludeInRelease{0000/00/00}{\hideoutput}%
%<latexrelease>                             {hide output from tracing}%
%<latexrelease>\let\hideoutput\@undefined
%<latexrelease>\EndIncludeInRelease
%</2ekernel|latexrelease>
%    \end{macrocode}
% \end{macro}
%
% \LaTeX\ change: |\showhyphens| Defined later.
%
% Punctuation affects the spacing.
%    \begin{macrocode}
%<*2ekernel>
\nonfrenchspacing
%</2ekernel>
%    \end{macrocode}
%
%
% \Finale
%
