% \iffalse meta-comment
%
% Copyright (C) 1993-2023
% 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: ltfssini.dtx
%% Copyright (C) 1989-2001 Frank Mittelbach and Rainer Sch\"opf,
%% all rights reserved.
%
%<*driver>
% \fi
%
%
\ProvidesFile{ltfssini.dtx}
             [2021/09/10 v3.2i LaTeX Kernel (NFSS Initialisation)]
% \iffalse
\documentclass{ltxdoc}
\begin{document}
\DocInput{ltfssini.dtx}
\end{document}
%</driver>
% \fi
%
% \iffalse
%<+checkmem>\def\CHECKMEM{\tracingstats=2
%<+checkmem>  \newlinechar=`\^^J
%<+checkmem>  \message{^^JMemory usage: \filename}\shipout\hbox{}}
%<+checkmem>\CHECKMEM
% \fi
%
%
%
% \GetFileInfo{ltfssini.dtx}
% \title{A new font selection scheme for \TeX{} macro packages\\
%        (Initialization)\thanks
%       {This file has version number
%       \fileversion\ dated \filedate}}
%
% \author{Frank Mittelbach \and Rainer Sch\"opf}
%
% \MaintainedByLaTeXTeam{latex}
% \maketitle
%
% This file contains the top level \LaTeX\ interface to the font
% selection scheme commands. See other parts of the \LaTeX\
% distribution, or \emph{The \LaTeX\ Companion} for higher level
% documentation of these commands.
%
% \MaybeStop{}
%
%
% \changes{v3.0i}{1998/08/17}{(RmS) Minor documentation fixes.}
% \changes{v3.0b}{1995/06/28}
%      {(DPC) Fix documentation typos}
% \changes{v3.0a}{1995/05/24}
%      {(DPC) Make file from previous file, lfonts.dtx 1995/05/23 v2.2e}
% \changes{v3.1b}{2016/10/15}
%      {Require e\TeX{}}
% \changes{v3.1d}{2019/08/27}{Make various commands robust}
%
%
% \section{NFSS Initialization}
%
% \iffalse
%<+checkmem>\CHECKMEM
% \fi
%
%
% \changes{v2.2a}{1994/10/14}{New coding for cfg files}
% \changes{v2.1a}{1993/12/03}{update for LaTeX2e}
% \changes{v1.2c}{1992/01/06}{added slitex code}
% \changes{v1.2d}{1992/03/21}{Renamed \cs{text} to \cs{nfss@text}
%                            to make it internal.}
% \changes{v1.2a}{1991/11/27}{All \cs{family}, \cs{shape} etc. renamed
%                        to \cs{fontfamily} etc.}
% \changes{v1.1i}{1990/04/02}{\cs{input} of files now handled
%                          by docstrip.}
% \changes{v1.1g}{1990/02/08}{Protected the commands
%         \cs{family}, \cs{series},
%         \cs{shape}, \cs{size}, \cs{selectfont}, and \cs{mathversion}.}
% \changes{v1.1c}{1989/12/03}{Some internal macros renamed to make them
%           inaccessible.}
% \changes{v1.1b}{1989/12/02}{\cs{rmmath} renamed to \cs{mathrm}}
%
% \changes{v1.0i}{1989/11/07}{All family, series, and shape names
%           abbreviated.}
% \changes{v1.0g}{1989/05/22}{Lines shortened to 72 characters}
% \changes{v1.0f}{1989/04/29}{Corrections to \LaTeX\ tabular env.
%                         added.}
% \changes{v1.0e}{1989/04/27}{Definitions of \LaTeX\ symbols corrected.}
% \changes{v1.0d}{1989/04/26}{\cs{xpt} added.}
% \changes{v1.0c}{1989/04/21}{Changed to conform to fam.tex.}
% \changes{v1.0b}{1989/04/15}{\cs{mathfontset} renamed to
%                                              \cs{mathversion.}}
% \changes{v1.0a}{1989/04/10}{Starting with version numbers!
%           \cs{newif} for \cs{@tempswa} added since this switch is
%           unknown at the time when this file is read in.
%           (latex.tex is loaded later.)
%           \cs{math@famname} changed to \cs{math@version.}}
%
%
% \changes{v2.1j}{1994/05/13}{Removed file identification typeout}
%
% Finally, there are six commands that are to be used in \LaTeX{}
% and that we will therefore protect against expansion at the
% wrong point:
% |\fontfamily|, |\fontseries|, |\fontshape|, |\fontsize|,
% |\selectfont|, and |\mathversion|.
%
% \changes{v2.1i}{1994/05/12}{Moved \cs{fontfamily} to fam.dtx}
% \changes{v2.1i}{1994/05/12}{Moved \cs{fontencoding} to fam.dtx}
% \changes{v2.1i}{1994/05/12}{Moved \cs{fontseries} to fam.dtx}
% \changes{v2.1i}{1994/05/12}{Moved \cs{fontshape} to fam.dtx}
% \changes{v2.1i}{1994/05/12}{Moved \cs{fontsize} to fam.dtx}
% \changes{v2.1i}{1994/05/12}{Moved \cs{mathversion} to fam.dtx}
% \changes{v2.1i}{1994/05/12}{Moved \cs{selectfont} to tracefnt.dtx}
%
%
%    \begin{macrocode}
%<*2ekernel>
%    \end{macrocode}
%
% \subsection{Providing math \emph{versions}}
%
%  \LaTeX{} provides two \emph{versions}. We call them
%  \textsf{normal} and \textsf{bold}, respectively.
%    \begin{macrocode}
\DeclareMathVersion{normal}
\DeclareMathVersion{bold}
%    \end{macrocode}
%
%
%    Now we define the standard font change commands.
%    We don't allow the use of |\rmfamily| etc.\ in math mode.
%
%    (Actually most are now defined further down in the file.)
%
%    First the changes to another \emph{family}:
%    \begin{macrocode}
%\DeclareRobustCommand\rmfamily
%        {\not@math@alphabet\rmfamily\mathrm
%         \fontfamily\rmdefault\selectfont}
%\DeclareRobustCommand\sffamily
%        {\not@math@alphabet\sffamily\mathsf
%         \fontfamily\sfdefault\selectfont}
%\DeclareRobustCommand\ttfamily
%        {\not@math@alphabet\ttfamily\mathtt
%         \fontfamily\ttdefault\selectfont}
%    \end{macrocode}
%    Then the commands changing the \emph{series}:
%    \begin{macrocode}
%\DeclareRobustCommand\bfseries
%        {\not@math@alphabet\bfseries\mathbf
%         \fontseries\bfdefault\selectfont}
%\DeclareRobustCommand\mdseries
%        {\not@math@alphabet\mdseries\relax
%         \fontseries\mddefault\selectfont}
\DeclareRobustCommand\upshape
        {\not@math@alphabet\upshape\relax
         \fontshape\updefault\selectfont}
%    \end{macrocode}
%    Then the commands changing the \emph{shape}:
%    \begin{macrocode}
\DeclareRobustCommand\slshape
        {\not@math@alphabet\slshape\relax
         \fontshape\sldefault\selectfont}
\DeclareRobustCommand\scshape
        {\not@math@alphabet\scshape\relax
         \fontshape\scdefault\selectfont}
\DeclareRobustCommand\itshape
        {\not@math@alphabet\itshape\mathit
         \fontshape\itdefault\selectfont}
%    \end{macrocode}
%
%
%
%
% \section{Custom series settings for main document families}
%
%    This section was introduced 2020/02/02 and for now we support a
%    full rollback (may need splitting later).
% \changes{v3.1e}{2019/12/17}{Provide custom series settings a la mweights}
%    \begin{macrocode}
%</2ekernel>
%<*2ekernel|latexrelease>
%<latexrelease>\IncludeInRelease{2021/11/15}%
%<latexrelease>                 {\DeclareFontSeriesDefault}{Custom series}%
%    \end{macrocode}
%
%    One problem with the NFSS approach of handling the series axis
%    turned out to be that (especially with respect to ``boldness'')
%    different font families implemented different strategies. For
%    example, with Computer Modern fonts you normally only have
%    \texttt{bx} whereas most PostScript fonts offered only \texttt{b}
%    but not \texttt{bx}. As a result \LaTeX's standard setting for
%    \cs{bfdefault} didn't work with such fonts, but if it got changed
%    to produce \texttt{b}, then that didn't work with Computer Modern
%    if the fonts got combined (e.g., using Computer Modern Typewriter
%    with such fonts).
%
%    The solution back then was to provide substitution rules in the
%    font \texttt{.fd} such that if a \texttt{bx} series got requested
%    the \texttt{b} series got used. While this works in that
%    particular case, it isn't a very
%    general solution. For example, if you happen to have a font family that
%    has several weights you may want to typeset  the whole document
%    in a somewhat lighter or darker font but if you then modify
%    \cs{mddefault} to allow for this, then of course your change only
%    works with that particular family but not with the typewriter
%    or sans serif family you also want to use.
%
%    A better solution was provided by the \texttt{mweights} package by
%    Bob Tennent that offers defaults on the level of the three main
%    font families in the document: for ``rm'', ``sf'' and ``tt'' so
%    that font packages could define defaults for the sans serif
%    document font by providing \cs{bfseries@sf} which then was used
%    when \cs{bfseries} got executed and the current family was the
%    \cs{sffamily}.
%
%  \DescribeMacro\DeclareFontSeriesDefault
%    We now support this concept directly from within \LaTeX{} and for
%    use in font packages (or the document preamble) we offer
%    \cs{DeclareFontSeriesDefault}. This declaration takes three
%    arguments:
%   \begin{description}
%   \item[document family interface:] Can either be \texttt{rm},
%    \texttt{sf} or \texttt{tt}. This is optional and if not given the
%    overall default.
%   \item[document series interface:] Can be \texttt{md} or
%    \texttt{bf}.
%   \item[series value:] This is the value that is going to be used
%    with the combination is requested.
%  \end{description}
%
%    For example, \verb=\DeclareFontSeriesDefault[rm]{bf}{sb}= would
%    use \texttt{sb} (semi-bold) when \cs{rmfamily} \cs{bfseries} is
%    asked for.
%
%    If used without the optional argument, e.g.,
%    \verb=\DeclareFontSeriesDefault{bf}{b}=  then this is like
%    redefining \cs{bfdefault} or \cs{mddefault}.
%
%    If some family specify defaults aren't given, e.g. if there are
%    no declarations for, say, \texttt{tt} then the format defaults
%    of \cs{mddefault} and \cs{bfdefault} are assumed. If those are
%    later changed this is \emph{not} reflected!\footnote{I see no
%    easy way to achieve this without compromising compatibility with
%    existing packages that currently use \textsf{mweights} and directly
%    define (some) of the \cs{mdseries@..} commands but not others.}
%
%
%
%  \begin{macro}{\DeclareFontSeriesDefault}
%    The command to declare font series defaults for the ``rm'', ``sf'' or
%    ``tt'' family.
%    \begin{macrocode}
\let\DeclareFontSeriesDefault\@undefined      % for rollback
\newcommand\DeclareFontSeriesDefault[3][]{%
%    \end{macrocode}
%    
% \changes{v3.2i}{2021/09/10}{Do delayed changes to \cs{bfdefault} or
%    \cs{mddefault} first (gh/663)}
%    \begin{macrocode}
  \expand@font@defaults
  \maybe@update@bfseries@defaults
  \maybe@update@mdseries@defaults
%    \end{macrocode}
%    
%    \begin{macrocode}
  \def\reserved@a{#1}%
%    \end{macrocode}
%    No optional argument: set up general default.
% \changes{v3.1g}{2020/02/05}{Corrected misspelled csname (gh/264)}
%    \begin{macrocode}
  \ifx\reserved@a\@empty
    \ifcsname #2series\endcsname           % supported are
                                           % \[md/bf]default
%    \end{macrocode}
%    Adding \cs{@empty} allows us to detect if the default gets
%    redefined with \cs{renewcommand} or \cs{def} by the user.
% \changes{v3.1k}{2020/03/19}{Support legacy use of \cs{bfdefault}
%        and \cs{mddefault} (gh/306)}
%    \begin{macrocode}
      \expandafter\def
        \csname #2default\endcsname{#3\@empty}%
      \expandafter\def
        \csname #2default@previous\endcsname{#3\@empty}%
    \else
%    \end{macrocode}
%
% \changes{v3.1g}{2020/02/05}{Clarified error text}
%    \begin{macrocode}
       \@latex@error{Wrong syntax for \string\DeclareFontSeriesDefault}%
          {Mandatory first argument must be 'md'  or 'bf'.}
    \fi
%    \end{macrocode}
%    Optional argument given, set up specific default.
%    \begin{macrocode}
  \else
    \ifcsname #2series@#1\endcsname          % supported are
                                             % \[md/bf]series@[rm/sf/tt]
      \expandafter\edef
         \csname #2series@#1\endcsname{#3}%
%    \end{macrocode}
%
%    If the interface is used we remove the frozen kernel
%    default. This way, we know that something was explicitly set up
%    (even if the setup has the same value as the default).
%    \begin{macrocode}
      \expandafter\let
         \csname #2series@#1@kernel\endcsname\@undefined
    \else
       \@latex@error{Wrong syntax for \string\DeclareFontSeriesDefault}%
          {Optional argument must be 'rm', 'sf', or 'tt'. \MessageBreak
           Mandatory first argument must be 'md'  or 'bf'.}
    \fi
  \fi
}
%    \end{macrocode}
%  \end{macro}


%    \begin{macrocode}
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{2020/02/02}%
%<latexrelease>                 {\DeclareFontSeriesDefault}{Custom series}%
%<latexrelease>
%<latexrelease>\let\DeclareFontSeriesDefault\@undefined      % for rollback
%<latexrelease>\newcommand\DeclareFontSeriesDefault[3][]{%
%<latexrelease>  \def\reserved@a{#1}%
%<latexrelease>  \ifx\reserved@a\@empty
%<latexrelease>    \ifcsname #2series\endcsname           % supported are
%<latexrelease>                                           % \[md/bf]default
%<latexrelease>      \expandafter\def
%<latexrelease>        \csname #2default\endcsname{#3\@empty}%
%<latexrelease>      \expandafter\def
%<latexrelease>        \csname #2default@previous\endcsname{#3\@empty}%
%<latexrelease>    \else
%<latexrelease>       \@latex@error{Wrong syntax for \string\DeclareFontSeriesDefault}%
%<latexrelease>          {Mandatory first argument must be 'md'  or 'bf'.}
%<latexrelease>    \fi
%<latexrelease>  \else
%<latexrelease>    \ifcsname #2series@#1\endcsname          % supported are
%<latexrelease>                                             % \[md/bf]series@[rm/sf/tt]
%<latexrelease>      \expandafter\edef
%<latexrelease>         \csname #2series@#1\endcsname{#3}%
%<latexrelease>      \expandafter\let
%<latexrelease>         \csname #2series@#1@kernel\endcsname\@undefined
%<latexrelease>    \else
%<latexrelease>       \@latex@error{Wrong syntax for \string\DeclareFontSeriesDefault}%
%<latexrelease>          {Optional argument must be 'rm', 'sf', or 'tt'. \MessageBreak
%<latexrelease>           Mandatory first argument must be 'md'  or 'bf'.}
%<latexrelease>    \fi
%<latexrelease>  \fi
%<latexrelease>}
%<latexrelease>
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{0000/00/00}%
%<latexrelease>                 {\DeclareFontSeriesDefault}{Custom series}%
%<latexrelease>
%<latexrelease>\let\DeclareFontSeriesDefault\@undefined
%<latexrelease>\let\bfseries@rm\@undefined
%<latexrelease>\let\bfseries@sf\@undefined
%<latexrelease>\let\bfseries@tt\@undefined
%<latexrelease>\let\bfseries@rm@kernel\@undefined
%<latexrelease>\let\bfseries@sf@kernel\@undefined
%<latexrelease>\let\bfseries@tt@kernel\@undefined
%<latexrelease>\let\mdseries@rm\@undefined
%<latexrelease>\let\mdseries@sf\@undefined
%<latexrelease>\let\mdseries@tt\@undefined
%<latexrelease>\expandafter\let\csname ver@mweights.sty\endcsname\@undefined
%<latexrelease>
%<latexrelease>\let\@meta@family@list\@undefined
%<latexrelease>\let\prepare@family@series@update\@undefined
%<latexrelease>\let\update@series@target@value\@undefined
%<latexrelease>
%    \end{macrocode}
%    This is always called in \cs{document} so don't make it undefined.
%    \begin{macrocode}
%<latexrelease>\let\init@series@setup\relax
%<latexrelease>
%<latexrelease>\EndIncludeInRelease
%<*2ekernel>
%    \end{macrocode}


%    \begin{macrocode}
%</2ekernel>
%<*2ekernel|latexrelease>
%<latexrelease>\IncludeInRelease{2020/02/02}%
%<latexrelease>                 {\mdseries@rm}{Custom series}%
%    \end{macrocode}

%  \begin{macro}{\mdseries@rm}
%  \begin{macro}{\mdseries@sf}
%  \begin{macro}{\mdseries@tt}
%  \begin{macro}{\bfseries@rm}
%  \begin{macro}{\bfseries@sf}
%  \begin{macro}{\bfseries@tt}
%    We initialize the family specific default at the end of the
%    format generation. Later on they may get overwritten in the
%    preamble or a package via \cs{DeclareFontSeriesDefault} (or
%    possibly directly).
%
%    Conceptual change: The \cs{bfdefault} will be \texttt{b} not
%    \texttt{bx} because that is what it should be really for nearly
%    every font except Computer/Latin Modern.
%
%    To account for the fact that by default we typeset in CM or LM we
%    set up the \cs{bfseries@..} defaults to use \texttt{bx} instead.
%
%    This means that it behaves like before because if the default
%    fonts are used then \cs{bfseries@rm} etc kick in and make
%    \cs{textbf} use \texttt{bx}. However, if the font gets changed
%    then \cs{bfdefault} will get used.
%
%    \begin{macrocode}
\def\bfseries@rm{bx}
\def\bfseries@sf{bx}
\def\bfseries@tt{bx}
%    \end{macrocode}
%
%    Frozen version of the kernel defaults so we can see if they have changed.
%    \begin{macrocode}
\let\bfseries@rm@kernel\bfseries@rm
\let\bfseries@sf@kernel\bfseries@sf
\let\bfseries@tt@kernel\bfseries@tt
%    \end{macrocode}
%
%    The default for the medium series is \texttt{m} and this will be
%    interpreted as resetting both weight and width. To reset only one
%    of them the virtual value \texttt{?m} and \texttt{m?} are available.
%    \begin{macrocode}
\def\mdseries@rm{m}
\def\mdseries@sf{m}
\def\mdseries@tt{m}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}



%
%
%
%  \begin{macro}{\series@change@debug}
%    For debugging, but right now none of this code is extracted. The
%    idea is to have a separate package with debugging code
%    one day.
%    \begin{macrocode}
%<*debug>
\let\series@change@debug\typeout
\let\series@change@debug\@gobble
%</debug>
%    \end{macrocode}
%  \end{macro}
%
%
%
%
%  \begin{macro}{\prepare@family@series@update}
%    This is core command that prepares for the family update. The big
%    difference to the documented code above is that the nested
%    \cs{ifx} statements seem to be missing. Instead we loop through
%    an internal list that holds the names of the three meta
%    families. This approach allows us to extend the mechanism at a
%    later stage to allow for additional named meta families.
%
%  \begin{macro}{\@meta@family@list}
%    Here is the current definition of that list:
%    \begin{macrocode}
\def\@meta@family@list{\@elt{rm}\@elt{sf}\@elt{tt}}
%    \end{macrocode}
%  \end{macro}
%
%    \begin{macrocode}
\def\prepare@family@series@update#1#2{%
%    \end{macrocode}
%    
% \changes{v3.1i}{2020/02/18}{No series auto-update when forced (gh/277)}
%    \begin{macrocode}
 \if@forced@series
%<+debug> \series@change@debug{No series preparation (forced \f@series)\on@line}%
   \fontfamily#2%
 \else
%<+debug> \series@change@debug{Preparing for switching to #1 (#2)\on@line}%
   \expand@font@defaults
%    \end{macrocode}
%    We prepare for changing the current series. We have to find it
%    before changing the family as discussed above.
%    \begin{macrocode}
   \let\target@series@value\@empty
   \def\target@meta@family@value{#1}%
%    \end{macrocode}
%    As the very last item in the meta family list we add
%    \verb=\@elt{??}= and define this pseudo meta family to be the
%    current font family. So if none of the real meta families matched then
%    this will match. This will cover the following case:
%    \begin{itemize}
%    \item \cs{bfseries} is called  for a family using \texttt{bx}
%       (e.g., CMR) 
%    \item Switch to a font family that is none of the meta
%       families, e.g., via \verb=\fontfamily{ptm}\allowbreak\verb=\selectfont=
%    \item Then none of the real meta families, match but the final
%      \verb=\@elt{??}= will.
%    \item Therefore if the current series is \cs{mddefault} or
%    \cs{bfdefault} it will be detected and the corresponding target
%    series selected.
%    \end{itemize}
% \changes{v3.1i}{2020/02/18}{Recognize current family if it is not a
%    ``meta'' family and auto-update series using \cs{bfdefault} (gh/277)}
%    \begin{macrocode}
   \expandafter\edef\csname ??def@ult\endcsname{\f@family}%
%    \end{macrocode}
%    To find it we loop over the meta family list with a suitable
%    definition of \cs{@elt}.
%    \begin{macrocode}
   \let\@elt\update@series@target@value
      \@meta@family@list
%    \end{macrocode}
%    Last resort pseudo meta family. Will only be looked at f none of
%    the real ones have matched.
%    \begin{macrocode}
      \@elt{??}%
   \let\@elt\relax
%    \end{macrocode}
%    That will figure out the correct series value to use without updating
%    it. Now we can change the family.
%    \begin{macrocode}
   \fontfamily#2%
%    \end{macrocode}
%    After that we update the series. That code is again like the one
%    above.
%    \begin{macrocode}
   \ifx\target@series@value\@empty
%<+debug> \series@change@debug{Target series still empty ...}%
   \else
     \ifx \f@series\target@series@value
%<+debug> \series@change@debug{Target series unchanged:
%<+debug>                      \f@series \space = \target@series@value}%
     \else
       \maybe@load@fontshape
%<+debug> \series@change@debug{Target series:
%<+debug>                      \f@series \space -> \target@series@value}%
%    \end{macrocode}
%    The \cs{target@series@value} may contain something like
%    \texttt{cm} (coming from a default) and so we can't directly
%    assign it to \cs{f@series} be have to drop any surplus \texttt{m}
%    first.
% \changes{v3.1j}{2020/02/25}{Drop surplus ``m'' from
%                             \cs{target@series@value} (gh/291)}
%    \begin{macrocode}
%      \let\f@series\target@series@value
       \series@maybe@drop@one@m\target@series@value\f@series
     \fi
   \fi
 \fi
}
%    \end{macrocode}
%  \end{macro}
%
%
%
%  \begin{macro}{\update@series@target@value}
%    In this macro used in the look you basically find the nested
%    \cs{ifx}s from the outline above. The only difference is that is
%    it is parameterized instead of being written out and only for one
%    block of tests because the code is called repeatedly when looping
%    over the meta family list. From the list we get each meta family
%    name in turn.
%    \begin{macrocode}
\def\update@series@target@value#1{%
%    \end{macrocode}
%    There is one additional test at the beginning, because the list
%    contains all meta families and we need to ignore the case where
%    current one from the list and target one are identical.
%    \begin{macrocode}
  \def\reserved@a{#1}%
  \ifx\target@meta@family@value\reserved@a   % rm -> rm do nothing
  \else
%<+debug> \series@change@debug{Trying to match #1: \csname#1def@ult\endcsname
%<+debug>                      \space = \f@family\space ?}%
%    \end{macrocode}
%    We only ``do'' something if the current font family matches the
%    current meta family.
%    \begin{macrocode}
    \expandafter\ifx\csname#1def@ult\endcsname\f@family
%    \end{macrocode}
%    If that's the case we know that this is the block that applies
%    (only one meta family can match). So  to speed things up we
%    change \cs{@elt} so that the rest of the loop gets gobbled.
%    \begin{macrocode}
      \let\@elt\@gobble
%    \end{macrocode}
%    Then we try to find the right new value for the series (as
%    explained above). The two macros defined first are only there
%    because we now need to use \cs{csname} and this way the code will
%    be a little faster.
%    \begin{macrocode}
      \expandafter\let\expandafter\reserved@b
                      \csname mdseries@\target@meta@family@value\endcsname
      \expandafter\let\expandafter\reserved@c
                      \csname bfseries@\target@meta@family@value\endcsname
%<+debug>\series@change@debug{Targets for mdseries and bfseries:
%<+debug>                     \reserved@b\space and \reserved@c}%
%    \end{macrocode}
%    This here is now identical to the nested \cs{ifx} block from the
%    outline, except that it there appeared twice in
%    \cs{rmfamily}. This is now covered by looping and stopping the
%    loop when a match was found.
%    \begin{macrocode}
%    \end{macrocode}
%    We have to sanitize the default value first because it may
%    contain something like \texttt{mc} and that would never match
%    \cs{f@series} because there it would be called \texttt{c} with
%    the \texttt{m} dropped. It would be probably better to do that
%    differently these days, but it is hard to adjust without causing
%    a lot of issues, so we do the dropping in various places instead.
% \changes{v3.1j}{2020/02/25}{Drop surplus ``m'' from \cs{reserved@d}
%                                (gh/291)}
%    \begin{macrocode}
      \expandafter\series@maybe@drop@one@m
          \csname mdseries@#1\endcsname\reserved@d
      \ifx\reserved@d\f@series
%<+debug>   \series@change@debug{mdseries@#1 matched -> \reserved@b}%
                                      \let\target@series@value\reserved@b
      \else
%    \end{macrocode}
%    Again do some sanitizing.
% \changes{v3.1j}{2020/02/25}{Drop surplus ``m'' from \cs{reserved@d}
%                                (gh/291)}
%    \begin{macrocode}
        \expandafter\series@maybe@drop@one@m
           \csname bfseries@#1\endcsname\reserved@d
        \ifx\reserved@d\f@series
%<+debug>  \series@change@debug{bfseries@#1 matched -> \reserved@c}%
                                      \let\target@series@value\reserved@c
      \else\ifx\f@series\mddef@ult    \let\target@series@value\reserved@b
%<+debug>  \series@change@debug{mddef@ult matched -> \reserved@b}%
      \else\ifx\f@series\bfdef@ult    \let\target@series@value\reserved@c
%<+debug>  \series@change@debug{bfdef@ult matched -> \reserved@c}%
      \fi\fi\fi\fi
    \fi
  \fi
}
%    \end{macrocode}
%  \end{macro}
%
%
%
%
%
%  \begin{macro}{\init@series@setup}
%    This is code to be run at begin document \ldots
%    \begin{macrocode}
\def\init@series@setup{%
%    \end{macrocode}
%
%    We only want \texttt{bx} in \cs{bfseries@rm} if the roman font is
%    Computer Modern or Latin Modern, otherwise it should be
%    \texttt{b}. It was set to \texttt{bx} in the kernel so that any
%    font use with the default families in the preamble get this
%    value. Now at the real document start we check if the fonts have
%    been changed. If there was a \cs{DeclareFontSeriesDefault}
%    declaration or \cs{bfseries@rm} was directly altered then it
%    differs from \cs{bfseries@rm@kernel} and we do nothing.
%    Otherwise we check if \cs{rmdefault} is one of the CM/LM font
%    families and if so we keep \texttt{bx} otherwise we change it to
%    \texttt{b}.
%
%    This approach doesn't cover one case: CM/LM got changed to a
%    different family that supports \texttt{bx}, but the support
%    package for that family used \verb=\def\bfseries@rm{bx}= instead
%    of using  \cs{DeclareFontSeriesDefault}. In that case the code
%    here changes it to \texttt{b}. Solution: use the
%    \cs{DeclareFontSeriesDefault} interface.
%    \begin{macrocode}
  \ifx\bfseries@rm@kernel\bfseries@rm
     \expandafter\in@\expandafter{\rmdefault}%
                     {cmr,cmss,cmtt,lcmss,lcmtt,lmr,lmss,lmtt}%
    \ifin@ \else \def\bfseries@rm{b}\fi\fi
%    \end{macrocode}
%    Same approach for \cs{bfseries@sf} and \cs{bfseries@tt}:
%    \begin{macrocode}
  \ifx\bfseries@sf@kernel\bfseries@sf
    \expandafter\in@\expandafter{\sfdefault}%
                    {cmr,cmss,cmtt,lcmss,lcmtt,lmr,lmss,lmtt}%
    \ifin@ \else \def\bfseries@sf{b}\fi\fi
  \ifx\bfseries@tt@kernel\bfseries@tt
    \expandafter\in@\expandafter{\ttdefault}%
                    {cmr,cmss,cmtt,lcmss,lcmtt,lmr,lmss,lmtt}%
    \ifin@ \else \def\bfseries@tt{b}\fi\fi
%    \end{macrocode}
%
%    If the document preamble has changed the \cs{familydefault} or if
%    the if the \cs{rmdefault} contains a new font family, we may have to
%    adjust the series defaults accordingly, before starting
%    typesetting.
%    
%    Similarly, if the user has changed the \cs{mddefault} or the
%    medium series for the family selected as document font we may
%    also have to adjust the \cs{seriesdefault}.    
%
%    On the other hand if the document font is still CM or LM then
%    \cs{bfdefault} is wrong, because it is now saying \texttt{b} and not
%    \texttt{bx} as it should for such fonts.
%
%    To fix all this we first run \cs{reset@font} (the internal kernel
%    name for \cs{normalfont}). This will set up the document encoding,
%    family, series and shape based on the current values of
%    \cs{encodingdefault}, \cs{familydefault}, \cs{seriesdefault} and
%    \cs{shapedefault}.
%    However, if the family (from \cs{familydefault}) has special medium
%    default we should switch to that (and not use what is current
%    value from \cs{seriesdefault}). This can be achieved by afterwards
%    calling \cs{mediumseries} and then changing \cs{seriesdefault} to
%    the now current series value (in \cs{f@series}).
%
%    But what should happen if \cs{seriesdefault} got explicitly
%    changed?  In that case the explicit change should survive and we
%    should not alter \cs{seriesdefault}. This is solved by comparing
%    the current value of \cs{seriesdefault} with a kernel version
%    saved in the format and if they differ we do not call
%    \cs{mdseries} or change \cs{seriesdefault}.
% \changes{v3.1n}{2020/04/13}{Handling \cs{seriesdefault} changes (gh/315)}
%    \begin{macrocode}
  \reset@font
  \ifx\seriesdefault\seriesdefault@kernel
    \mdseries
    \let\seriesdefault\f@series
  \fi
}%
%    \end{macrocode}
%  \end{macro}
%
%
%
%    As the kernel code now implements the same functionality as
%    \textsf{mweights}, albeit internally coded slightly differently,
%    that package shouldn't be loaded any more.  We therefore pretend
%    that it already got loaded. Thus, a font package that tries to
%    load it and then sets \cs{mdseries@..}, etc.\ will continue to
%    work but will now use the kernel code.
%
%    Of course, mid-term such package should probably use
%    \cs{DeclareFontSeriesDefault} instead of making using low-level
%    definitions.
%
%    \begin{macrocode}
\expandafter\let\csname ver@mweights.sty\endcsname\fmtversion
%    \end{macrocode}
%
%
%
%    \begin{macrocode}
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{0000/00/00}%
%<latexrelease>                 {\mdseries@rm}{Custom series}%
%<latexrelease>
%<latexrelease>\let\bfseries@rm\@undefined
%<latexrelease>\let\bfseries@sf\@undefined
%<latexrelease>\let\bfseries@tt\@undefined
%<latexrelease>\let\bfseries@rm@kernel\@undefined
%<latexrelease>\let\bfseries@sf@kernel\@undefined
%<latexrelease>\let\bfseries@tt@kernel\@undefined
%<latexrelease>\let\mdseries@rm\@undefined
%<latexrelease>\let\mdseries@sf\@undefined
%<latexrelease>\let\mdseries@tt\@undefined
%<latexrelease>\expandafter\let\csname ver@mweights.sty\endcsname\@undefined
%<latexrelease>
%<latexrelease>\let\@meta@family@list\@undefined
%<latexrelease>\let\prepare@family@series@update\@undefined
%<latexrelease>\let\update@series@target@value\@undefined
%<latexrelease>
%    \end{macrocode}
%    This is always called in \cs{document} so don't make it undefined.
%    \begin{macrocode}
%<latexrelease>\let\init@series@setup\relax
%<latexrelease>
%<latexrelease>\EndIncludeInRelease
%<*2ekernel>
%    \end{macrocode}
%
%
%    \begin{macrocode}
%</2ekernel>
%<*2ekernel|latexrelease>
%<latexrelease>\IncludeInRelease{2021/11/15}%
%<latexrelease>                 {\bfseries}{Custom series with hooks}%
%    \end{macrocode}


%  \begin{macro}{\bfseries}
%    This document command switches to the bold series.
%    \begin{macrocode}
\DeclareRobustCommand\bfseries{%
  \not@math@alphabet\bfseries\mathbf
%    \end{macrocode}
%    In the original NFSS definition it then called \cs{fontseries}
%    with the value \cs{bfdefault}. In the new scheme we have more
%    alternatives and therefore check if the current family
%    (\cs{f@family}) is the current \cs{rmdef@ult}, \cs{sfdef@ult} or
%    \cs{ttdef@ult}  and the select the correct family default in that case.
% \changes{v3.1i}{2020/02/18}{Make the \cs{ifx} selection outside
%            of \cs{fontseries} argument so that it is not done several times}
% \changes{v3.2i}{2021/09/10}{Do delayed changes to \cs{bfdefault} in
%    a separate macro for better reuse (gh/663)}
%    \begin{macrocode}
  \expand@font@defaults
  \maybe@update@bfseries@defaults
%    \end{macrocode}
%    
%    \begin{macrocode}
  \ifx\f@family\rmdef@ult      \fontseries\bfseries@rm
  \else\ifx\f@family\sfdef@ult \fontseries\bfseries@sf
  \else\ifx\f@family\ttdef@ult \fontseries\bfseries@tt
%    \end{macrocode}
%    If not \cs{bfdefault} is used.
%    \begin{macrocode}
  \else                        \fontseries\bfdefault
  \fi\fi\fi
%    \end{macrocode}
%    This hook in contrast is always executed.
%    \begin{macrocode}
  \UseHook{bfseries}%
  \selectfont
}
%    \end{macrocode}
%  \end{macro}



%  \begin{macro}{\maybe@update@bfseries@defaults}
%    
%    If \cs{bfdefault} and \cs{bfdefault@previous} are different then
%    the default got changed directly through the legacy interface
%    (i.e., via \cs{def} or \cs{renewcommand}. In that case we reset
%    all meta family defaults so that the document behaves like it was
%    the case before the new mechanism was introduced.
% \changes{v3.1k}{2020/03/19}{Support legacy use of \cs{bfdefault}
%        and \cs{mddefault} (gh/306)}
% \changes{v3.2i}{2021/09/10}{Do delayed changes to \cs{bfdefault} in
%    a separate macro for better reuse (gh/663)}
%    \begin{macrocode}
\def\maybe@update@bfseries@defaults{%
  \ifx\bfdefault\bfdefault@previous\else
%    \end{macrocode}
%    We add \cs{@empty} and then let \cs{bfdefault@previous} to
%    \cs{bfdefault} so that we can detect any further change.
% \changes{v3.2d}{2020/09/30}{\cs{bfdefault@previous} not \cs{bfseries@previous}
%        (gh/395)}
%    \begin{macrocode}
    \expandafter\def\expandafter\bfdefault
                    \expandafter{\bfdefault\@empty}%
    \let\bfdefault@previous\bfdefault
%    \end{macrocode}
%    And we reset the meta family defaults (\cs{bfdef@ult} is an
%    expanded version of \cs{bfdefault}.
%    \begin{macrocode}
    \let\bfseries@rm\bfdef@ult
    \let\bfseries@sf\bfdef@ult
    \let\bfseries@tt\bfdef@ult
%    \end{macrocode}
%    
%    Formats that set up parallel fonts, e.g., for Japanese, can use
%    this hook to add resets here. Not that this hook is only run when
%    resets are necessary.
% \changes{v3.1m}{2020/04/06}{Hook added (gh/306)}
% \changes{v3.2b}{2020/08/21}{Integration of new hook management interface}
%    \begin{macrocode}
    \UseHook{bfseries/defaults}%
  \fi
}
%    \end{macrocode}
%  \end{macro}


%  \begin{macro}{\mdseries}
%    This document command switches to the medium series.
% \changes{v3.1i}{2020/02/18}{Make the \cs{ifx} selection outside
%            of \cs{fontseries} argument so that it is not done several times}
% \changes{v3.1k}{2020/03/19}{Support legacy use of \cs{bfdefault}
%        and \cs{mddefault} (gh/306)}
% \changes{v3.2d}{2020/09/30}{\cs{mddefault@previous} not \cs{mdseries@previous}
%        (gh/395)}
% \changes{v3.2i}{2021/09/10}{Do delayed changes to \cs{mddefault} in
%    a separate macro for better reuse (gh/663)}
%    \begin{macrocode}
\DeclareRobustCommand\mdseries{%
  \not@math@alphabet\mdseries\relax
  \expand@font@defaults
  \maybe@update@mdseries@defaults
  \ifx\f@family\rmdef@ult      \fontseries\mdseries@rm
    \else\ifx\f@family\sfdef@ult \fontseries\mdseries@sf
    \else\ifx\f@family\ttdef@ult \fontseries\mdseries@tt
    \else                        \fontseries\mddefault
  \fi\fi\fi
  \UseHook{mdseries}%
  \selectfont
}
%    \end{macrocode}
%  \end{macro}

%  \begin{macro}{\maybe@update@mdseries@defaults}
%    
% \changes{v3.2i}{2021/09/10}{Do delayed changes to \cs{mddefault} in
%    a separate macro for better reuse (gh/663)}
%    \begin{macrocode}
\def\maybe@update@mdseries@defaults{%
  \ifx\mddefault\mddefault@previous\else
    \expandafter\def\expandafter\mddefault\expandafter{\mddefault\@empty}%
    \let\mddefault@previous\mddefault
    \let\mdseries@rm\mddef@ult
    \let\mdseries@sf\mddef@ult
    \let\mdseries@tt\mddef@ult
%    \end{macrocode}
%    
%    Formats that set up parallel fonts, e.g., for Japanese, can use
%    this hook to add resets here.
% \changes{v3.1m}{2020/04/06}{Hook added (gh/306)}
% \changes{v3.2b}{2020/08/21}{Integration of new hook management interface}
%    \begin{macrocode}
    \UseHook{mdseries/defaults}%
  \fi
}
%    \end{macrocode}
%  \end{macro}

%
%    \begin{macrocode}
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{2020/10/01}%
%<latexrelease>                 {\bfseries}{Custom series with hooks}%
%<latexrelease>
%<latexrelease>\let\maybe@update@bfseries@defaults\@undefined
%<latexrelease>\let\maybe@update@mdseries@defaults\@undefined
%<latexrelease>
%<latexrelease>\DeclareRobustCommand\bfseries{%
%<latexrelease>  \not@math@alphabet\bfseries\mathbf
%<latexrelease>  \expand@font@defaults
%<latexrelease>  \ifx\bfdefault\bfdefault@previous\else
%<latexrelease>    \expandafter\def\expandafter\bfdefault
%<latexrelease>                    \expandafter{\bfdefault\@empty}%
%<latexrelease>    \let\bfdefault@previous\bfdefault
%<latexrelease>    \let\bfseries@rm\bfdef@ult
%<latexrelease>    \let\bfseries@sf\bfdef@ult
%<latexrelease>    \let\bfseries@tt\bfdef@ult
%<latexrelease>    \UseHook{bfseries/defaults}%
%<latexrelease>  \fi
%<latexrelease>    \ifx\f@family\rmdef@ult      \fontseries\bfseries@rm
%<latexrelease>    \else\ifx\f@family\sfdef@ult \fontseries\bfseries@sf
%<latexrelease>    \else\ifx\f@family\ttdef@ult \fontseries\bfseries@tt
%<latexrelease>    \else                        \fontseries\bfdefault
%<latexrelease>    \fi\fi\fi
%<latexrelease>  \UseHook{bfseries}%
%<latexrelease>  \selectfont
%<latexrelease>}
%<latexrelease>
%<latexrelease>\DeclareRobustCommand\mdseries{%
%<latexrelease>  \not@math@alphabet\mdseries\relax
%<latexrelease>  \expand@font@defaults
%<latexrelease>  \ifx\mddefault\mddefault@previous\else
%<latexrelease>    \expandafter\def\expandafter\mddefault\expandafter{\mddefault\@empty}%
%<latexrelease>    \let\mddefault@previous\mddefault
%<latexrelease>    \let\mdseries@rm\mddef@ult
%<latexrelease>    \let\mdseries@sf\mddef@ult
%<latexrelease>    \let\mdseries@tt\mddef@ult
%<latexrelease>    \UseHook{mdseries/defaults}%
%<latexrelease>  \fi
%<latexrelease>    \ifx\f@family\rmdef@ult      \fontseries\mdseries@rm
%<latexrelease>    \else\ifx\f@family\sfdef@ult \fontseries\mdseries@sf
%<latexrelease>    \else\ifx\f@family\ttdef@ult \fontseries\mdseries@tt
%<latexrelease>    \else                        \fontseries\mddefault
%<latexrelease>    \fi\fi\fi
%<latexrelease>  \UseHook{mdseries}%
%<latexrelease>  \selectfont
%<latexrelease>}
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{2020/02/02}%
%<latexrelease>                 {\bfseries}{Custom series with hooks}%
%<latexrelease>
%<latexrelease>
%<latexrelease>\DeclareRobustCommand\bfseries{%
%<latexrelease>  \not@math@alphabet\bfseries\mathbf
%<latexrelease>  \expand@font@defaults
%<latexrelease>    \ifx\f@family\rmdef@ult      \fontseries\bfseries@rm
%<latexrelease>    \else\ifx\f@family\sfdef@ult \fontseries\bfseries@sf
%<latexrelease>    \else\ifx\f@family\ttdef@ult \fontseries\bfseries@tt
%<latexrelease>    \else                        \fontseries\bfdefault
%<latexrelease>    \fi\fi\fi
%<latexrelease>  \selectfont
%<latexrelease>}
%<latexrelease>
%<latexrelease>\DeclareRobustCommand\mdseries{%
%<latexrelease>  \not@math@alphabet\mdseries\relax
%<latexrelease>  \expand@font@defaults
%<latexrelease>    \ifx\f@family\rmdef@ult      \fontseries\mdseries@rm
%<latexrelease>    \else\ifx\f@family\sfdef@ult \fontseries\mdseries@sf
%<latexrelease>    \else\ifx\f@family\ttdef@ult \fontseries\mdseries@tt
%<latexrelease>    \else                        \fontseries\mddefault
%<latexrelease>    \fi\fi\fi
%<latexrelease>  \selectfont
%<latexrelease>}
%<latexrelease>
%<latexrelease>
%    \end{macrocode}
%    
%    \begin{macrocode}
%<latexrelease>
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{0000/00/00}%
%<latexrelease>                 {\bfseries}{Custom series with hooks}%
%<latexrelease>
%<latexrelease>\DeclareRobustCommand\bfseries
%<latexrelease>        {\not@math@alphabet\bfseries\mathbf
%<latexrelease>         \fontseries\bfdefault\selectfont}
%<latexrelease>\DeclareRobustCommand\mdseries
%<latexrelease>        {\not@math@alphabet\mdseries\relax
%<latexrelease>         \fontseries\mddefault\selectfont}
%<latexrelease>
%<latexrelease>\EndIncludeInRelease
%<*2ekernel>




%</2ekernel>
%<*2ekernel|latexrelease>
%<latexrelease>\IncludeInRelease{2020/10/01}%
%<latexrelease>                 {\expand@font@defaults}{Custom series with hooks}%
%    \end{macrocode}



%  \begin{macro}{\expand@font@defaults}
%  \begin{macro}{\rm@def@ult}
%  \begin{macro}{\sf@def@ult}
%  \begin{macro}{\tt@def@ult}
%  \begin{macro}{\md@def@ult}
%  \begin{macro}{\bf@def@ult}
%
%    The family specific defaults are fully expanded, i.e., they are
%    defined via \cs{edef} inside \cs{DeclareFontSeriesDefault}.
%    However, the overall defaults, e.g., \cs{bfdefault} may have been
%    redefined by the user and thus may not be fully expanded. So to
%    enable reliable comparison we make expanded versions of
%    them. That we rerun each time. The alternative would be to only
%    allow for changes before begin document.
%    \begin{macrocode}
\def\expand@font@defaults{%
  \edef\rmdef@ult{\rmdefault}%
  \edef\sfdef@ult{\sfdefault}%
  \edef\ttdef@ult{\ttdefault}%
%    \end{macrocode}
%    The series defaults may contain some surplus \texttt{m} that we
%    need to drop here.
% \changes{v3.1j}{2020/02/25}{Drop surplus ``m'' from \cs{bfdef@ult}
%                             and \cs{mddef@ult} (gh/291)}
%    \begin{macrocode}
  \series@maybe@drop@one@m\bfdefault\bfdef@ult
  \series@maybe@drop@one@m\mddefault\mddef@ult
%    \end{macrocode}
%    Formats that set up parallel fonts, e.g., for Japanese, can use
%    this hook to add additional code here.
% \changes{v3.1m}{2020/04/06}{Hook added (gh/306)}
% \changes{v3.2b}{2020/08/21}{Integration of new hook management interface}
%    \begin{macrocode}
  \UseHook{expand@font@defaults}%
}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}



%  \begin{macro}{\rmfamily}
%    Here are the document level commands for changing the main font
%    families, or rather, here is a documented outline of the code,
%    the actual code is then streamlined and somewhat generalized.
%\begin{verbatim}
%\DeclareRobustCommand\rmfamily{%
%  \not@math@alphabet\rmfamily\mathrm
%\end{verbatim}
%    If families are changed then we have to do a bit more work.
%    In the original NFSS implementation
%    a family change kept encoding, series shape and size unchanged
%    but now we can't any
%    longer simply reuse the current series value. Instead we may have
%    to change it from one family default to the next.
%\begin{verbatim}
%  \expand@font@defaults
%\end{verbatim}
%    We have to do the testing while the current family is still
%    unchanged but we have to do the adjustment of the series after it
%    got changed (because the new family might have different sets
%    of shapes available and we certainly don't want to see
%    substitution going on. So we use \cs{target@series@value} to
%    hold the target series (if any).
%\begin{verbatim}
%  \let\target@series@value\@empty
%\end{verbatim}
%    Thus, if the current family is the sans family
%\begin{verbatim}
%  \ifx\f@family\sfdef@ult
%\end{verbatim}
%    and if we using the medium series of the sans family
%\begin{verbatim}
%       \ifx\f@series\mdseries@sf
%\end{verbatim}
%    then lets switch to the medium series for the serif family
%\begin{verbatim}
%                                       \let\target@series@value\mdseries@rm
%\end{verbatim}
%    and if we use the bold series of the sans family switch to the
%    bold default of the serif family:
%\begin{verbatim}
%       \else\ifx\f@series\bfseries@sf  \let\target@series@value\bfseries@rm
%\end{verbatim}
%    However, the sans family may not have any specific defaults set,
%    so we also compare with the overall defaults.
%\begin{verbatim}
%       \else\ifx\f@series\mddef@ult    \let\target@series@value\mdseries@rm
%       \else\ifx\f@series\bfdef@ult    \let\target@series@value\bfseries@rm
%\end{verbatim}
%    If neither test was true we leave the series alone. This way a
%    special manual setting such as \verb=\fontseries{lc}= is not
%    undone if the family changes (of course there may not be any
%    support for it in the new family but then the NFSS
%    substitution kicks in and  sorts it out).
%\begin{verbatim}
%       \fi\fi\fi\fi
%
%\end{verbatim}
%    We need to do the same if the current family is the typewriter family:
%\begin{verbatim}
%  \else\ifx\f@family\ttdef@ult
%       \ifx\f@series\mdseries@tt       \let\target@series@value\mdseries@rm
%       \else\ifx\f@series\bfseries@tt  \let\target@series@value\bfseries@rm
%       \else\ifx\f@series\mddef@ult    \let\target@series@value\mdseries@rm
%       \else\ifx\f@series\bfdef@ult    \let\target@series@value\bfseries@rm
%       \fi\fi\fi\fi
%  \fi\fi
%\end{verbatim}
%    With these preparations for series out of the way we can now
%    change the font family to \cs{rmdefault}.
%\begin{verbatim}
%  \fontfamily\rmdefault
%\end{verbatim}
%
%    If \cs{target@series@value} is still empty there is nothing more
%    to do other than selecting the new family. However, if not then
%    we should update the font series now as well. But there is one
%    further subtle issue. We may not have loaded an \texttt{.fd} file
%    for our target font family yet. In the past that was done in
%    \cs{selectfont} if necessary but since we are now doing all the
%    comparisons in \cs{fontseries} we need to make sure that the font
%    family specifications are already loaded prior to calling
%    \cs{fontseries}.
%\begin{verbatim}
%  \ifx\target@series@value\@empty \else
%    \maybe@load@fontshape
%\end{verbatim}
%    Updating the series in this case means directly changing
%    \cs{f@series} to the target value. We don't want to go through
%    \cs{fontseries} because that would apply the mappings and then
%    \texttt{bx + b} would keep \texttt{bx} instead of changing to
%    \texttt{b} as desired.
%    as
%\begin{verbatim}
%    \let\f@series\target@series@value
%  \fi
%  \selectfont}
%\end{verbatim}
%
%    So now for the real definition: most of the code above gets
%    delegated to a helper command \cs{prepare@family@series@update}
%    so that the definition becomes again fairly short. In addition we
%    add a hook, mainly for our Japanese friends so that the code can
%    be extended prior to the call to \cs{selectfont}.
%
% \changes{v3.1f}{2020/01/11}{Streamlined implementation with hook}
%    \begin{macrocode}
\DeclareRobustCommand\rmfamily{%
   \not@math@alphabet\rmfamily\mathrm
%    \end{macrocode}
%    This holds all the code discussed above, first argument is the
%    meta family, i.e., \texttt{rm} in this case, and second argument
%    is the default family name, e.g., \texttt{cmr} indirectly
%    accessed via \cs{rmdefault}. This is calling \cs{fontfamily} and
%    if necessary \cs{fontseries} as outline above.
%    \begin{macrocode}
   \prepare@family@series@update{rm}\rmdefault
%    \end{macrocode}
%    Then comes the hook code (by default a no-op) and finally the call
%    to \cs{selectfont}.
% \changes{v3.2b}{2020/08/21}{Integration of new hook management interface}
%    \begin{macrocode}
   \UseHook{rmfamily}%
   \selectfont}
%    \end{macrocode}
%
%  \begin{macro}{\sffamily}
%  \begin{macro}{\ttfamily}
%    The definitions for \cs{sffamily} and \cs{ttfamily} are similar,
%    the differences are only in what font families get checked.
% \changes{v3.1f}{2020/01/11}{Streamlined implementation with hook}
% \changes{v3.2b}{2020/08/21}{Integration of new hook management interface}
%    \begin{macrocode}
\DeclareRobustCommand\sffamily{%
   \not@math@alphabet\sffamily\mathsf
   \prepare@family@series@update{sf}\sfdefault
   \UseHook{sffamily}%
   \selectfont}
%    \end{macrocode}
%
% \changes{v3.1f}{2020/01/11}{Streamlined implementation with hook}
% \changes{v3.2b}{2020/08/21}{Integration of new hook management interface}
%    \begin{macrocode}
\DeclareRobustCommand\ttfamily{%
   \not@math@alphabet\ttfamily\mathtt
   \prepare@family@series@update{tt}\ttdefault
   \UseHook{ttfamily}%
   \selectfont}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%
%
%  \begin{macro}{rmfamily,sffamily,ttfamily,normalfont,expand@font@defaults,
%                bfseries,bfseries/defaults,mdseries,mdseries/defaults}
%    Declare the hooks used above.
% \changes{v3.2b}{2020/08/21}{Integration of new hook management interface}
%    \begin{macrocode}
\NewHook{rmfamily}
\NewHook{sffamily}
\NewHook{ttfamily}
\NewHook{normalfont}
\NewHook{expand@font@defaults}
\NewHook{bfseries}
\NewHook{bfseries/defaults}
\NewHook{mdseries}
\NewHook{mdseries/defaults}
%    \end{macrocode}
%  \end{macro}
%
%  \begin{macro}{\@rmfamilyhook}
%  \begin{macro}{\@sffamilyhook}
%  \begin{macro}{\@ttfamilyhook}
%  \begin{macro}{\@defaultfamilyhook}
% \changes{v3.1h}{2020/02/10}{Add \cs{@defaultfamilyhook} to \cs{normalfont} (gh/269)}
%     These four hooks have legacy versions used in 2020/02/02 so we
%    should support them until they aren't any longer used.
%
%    By default the hooks do nothing.
%    \begin{macrocode}
\let\@rmfamilyhook\@empty
\let\@sffamilyhook\@empty
\let\@ttfamilyhook\@empty
\let\@defaultfamilyhook\@empty   %FMi sort out
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%
%
% \changes{v3.2g}{2021/03/18}
%         {Add legacy hook definitions for rollback.}
%    \begin{macrocode}
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{2020/02/02}%
%<latexrelease>                 {\expand@font@defaults}{Custom series with hooks}%
%<latexrelease>
%<latexrelease>\def\expand@font@defaults{%
%<latexrelease>  \edef\rmdef@ult{\rmdefault}%
%<latexrelease>  \edef\sfdef@ult{\sfdefault}%
%<latexrelease>  \edef\ttdef@ult{\ttdefault}%
%<latexrelease>  \edef\bfdef@ult{\bfdefault}%
%<latexrelease>  \edef\mddef@ult{\mddefault}%
%<latexrelease>  \edef\famdef@ult{\familydefault}%
%<latexrelease>}
%<latexrelease>
%<latexrelease>
%<latexrelease>\DeclareRobustCommand\rmfamily{%
%<latexrelease>   \not@math@alphabet\rmfamily\mathrm
%<latexrelease>   \prepare@family@series@update{rm}\rmdefault
%<latexrelease>   \@rmfamilyhook
%<latexrelease>   \selectfont}
%<latexrelease>\DeclareRobustCommand\sffamily{%
%<latexrelease>   \not@math@alphabet\sffamily\mathsf
%<latexrelease>   \prepare@family@series@update{sf}\sfdefault
%<latexrelease>   \@sffamilyhook
%<latexrelease>   \selectfont}
%<latexrelease>\DeclareRobustCommand\ttfamily{%
%<latexrelease>   \not@math@alphabet\ttfamily\mathtt
%<latexrelease>   \prepare@family@series@update{tt}\ttdefault
%<latexrelease>   \@ttfamilyhook
%<latexrelease>   \selectfont}
%<latexrelease>\let\@rmfamilyhook\@empty
%<latexrelease>\let\@sffamilyhook\@empty
%<latexrelease>\let\@ttfamilyhook\@empty
%<latexrelease>
%    \end{macrocode}
%    
%    \begin{macrocode}
%<latexrelease>
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{0000/00/00}%
%<latexrelease>                 {\expand@font@defaults}{Custom series with hooks}%
%<latexrelease>
%<latexrelease>\let\expand@font@defaults\@undefined
%<latexrelease>
%<latexrelease>\DeclareRobustCommand\bfseries
%<latexrelease>        {\not@math@alphabet\bfseries\mathbf
%<latexrelease>         \fontseries\bfdefault\selectfont}
%<latexrelease>\DeclareRobustCommand\mdseries
%<latexrelease>        {\not@math@alphabet\mdseries\relax
%<latexrelease>         \fontseries\mddefault\selectfont}
%<latexrelease>\DeclareRobustCommand\rmfamily
%<latexrelease>        {\not@math@alphabet\rmfamily\mathrm
%<latexrelease>         \fontfamily\rmdefault\selectfont}
%<latexrelease>\DeclareRobustCommand\sffamily
%<latexrelease>        {\not@math@alphabet\sffamily\mathsf
%<latexrelease>         \fontfamily\sfdefault\selectfont}
%<latexrelease>\DeclareRobustCommand\ttfamily
%<latexrelease>        {\not@math@alphabet\ttfamily\mathtt
%<latexrelease>         \fontfamily\ttdefault\selectfont}
%<latexrelease>
%<latexrelease>\let\@rmfamilyhook\@undefined
%<latexrelease>\let\@sffamilyhook\@undefined
%<latexrelease>\let\@ttfamilyhook\@undefined
%<latexrelease>
%<latexrelease>\EndIncludeInRelease
%<*2ekernel>
%    \end{macrocode}
%
%
%
%  \begin{macro}{\IfFontSeriesContextTF}
%
%    With the ability for \cs{bfseries} or \cs{mdseries} to be mapped
%    to different NFSS axis values it becomes important to have the
%    ability to determine the current context as we can no longer look
%    at \cs{f@series} to answer a question such as ``am I currently
%    typesetting in a bold typeface?''
%
%    This is provided by the test \cs{IfFontSeriesContextTF}. It takes
%    three arguments:
%    \begin{itemize}
%    \item
%      The context we try to check (either \texttt{bf} for bold or
%      \texttt{md} for medium, i.e., the same that can go into the
%      first mandatory argument of \cs{DeclareFontSeriesDefault}),
%
%    \item
%      what to do if we are in this context (true case) and
%
%    \item
%      what to do if we are not (false case).
%    \end{itemize}
%    This allows you to define commands like \cs{IfBold}, e.g.,
%\begin{verbatim}
%    \newcommand\IfBold[2]{\IfSeriesContextTF{bf}{#1}{#2}}
%\end{verbatim}
%    and then do
%\begin{verbatim}
%    This is \IfBold{bold}{non-bold} text.
%\end{verbatim}
%    and get the appropriate result.
%    
% \changes{v3.2a}{2020/05/19}{Macros added (gh/335)}
%    \begin{macrocode}
%</2ekernel>
%<*2ekernel|latexrelease>
%<latexrelease>\IncludeInRelease{2020/10/01}%
%<latexrelease>                 {\IfFontSeriesContextTF}{Font series context}%
%    \end{macrocode}
%
%    \begin{macrocode}
\DeclareRobustCommand\IfFontSeriesContextTF[1]{%
  \expand@font@defaults
%    \end{macrocode}
%    In the beginning we haven't found the context we are looking for.
%    \begin{macrocode}
  \@font@series@contextfalse
%    \end{macrocode}
%    We store the requested context away for use in the tests.
%    \begin{macrocode}
  \def\requested@test@context{#1}%
%    \end{macrocode}
%    The next definition is there to ensure that get a final match
%    during testing
%    even if the current family is non of the meta families
%    (\texttt{rm}, \texttt{sf} or \texttt{tt}). This will then
%    basically tests if the current font family matches the overall default.
%    \begin{macrocode}
  \expandafter\edef\csname ??def@ult\endcsname{\f@family}%
%    \end{macrocode}
%    Then we run through the meta family list (currently containing
%    just the three values) followed by the artificial meta family
%    \texttt{??} and test each of them in turn using
%    \cs{test@font@series@context} as the testing command.
%    \begin{macrocode}
  \let\@elt\test@font@series@context
      \@meta@family@list
      \@elt{??}%
  \let\@elt\relax
%    \end{macrocode}
%    Following that we evaluate the status of
%    \cs{if@font@series@context} to determine which of the remaining
%    arguments (true/false case) we have to execute.
%    \begin{macrocode}
  \if@font@series@context
  \expandafter\@firstoftwo
  \else
  \expandafter\@secondoftwo
  \fi
}
%    \end{macrocode}
%  \end{macro}



%  \begin{macro}{\test@font@series@context}
%    This tests the context (stored in \cs{requested@test@context})
%    and updates the boolean if the right context is found.
%    \begin{macrocode}
\def\test@font@series@context#1{%
%    \end{macrocode}
%    First task is to figure out whether the current family matches
%    \cs{rmfamily}, \cs{sffamily}, etc.\ so in \cs{reserved@a} we
%    store the value of \cs{rmdef@ult} (or whatever the given meta
%    family is) and compare that to \cs{f@family}.
%    \begin{macrocode}
  \edef\reserved@a{\csname #1def@ult\endcsname}%
  \ifx\f@family\reserved@a
%    \end{macrocode}
%    If they match we have found the right meta family so we don't
%    need to test any of the remaining  meta family and therefore
%    change \cs{@elt} to \cs{@gobble}.
%    \begin{macrocode}
    \let\@elt\@gobble
%    \end{macrocode}
%    Now we have to test if \cs{f@series} matches the requested
%    context (e.g., whether \cs{bfseries@rm} has that value if the
%    current meta family is \texttt{rm} and we are looking for the
%    \texttt{bf} context).
%    \begin{macrocode}
    \expandafter\ifx
                \csname\requested@test@context series@#1\endcsname\f@series
%    \end{macrocode}
%    If yes we change the boolean and are done.
%    \begin{macrocode}
      \@font@series@contexttrue
%    \end{macrocode}
%    If not then maybe the reason is that nothing special was set up
%    for that meta family so we also check now check if \cs{f@series}
%    matches the overall default (e.g., \cs{bfdef@ult} if we are
%    looking for the bold context). If that matches we change the boolean.
%    \begin{macrocode}
    \else
      \expandafter\ifx
                  \csname\requested@test@context def@ult\endcsname\f@series
        \@font@series@contexttrue
  \fi\fi\fi
}
%    \end{macrocode}
%  \end{macro}
%
%
%
%  \begin{macro}{\if@font@series@context}
%    The boolean to signal if we found the requested font series context.
%    \begin{macrocode}
\newif\if@font@series@context
%    \end{macrocode}
%  \end{macro}
%
%
%    \begin{macrocode}
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%    \end{macrocode}
%    
%    \begin{macrocode}
%<latexrelease>\IncludeInRelease{0000/00/00}%
%<latexrelease>                 {\IfFontSeriesContextTF}{Font series context}%
%<latexrelease>
%<latexrelease>\let\IfFontSeriesContextTF\@undefined
%<latexrelease>\let\test@font@series@context\@undefined
%<latexrelease>\let\if@font@series@context\@undefined
%<latexrelease>\let\@font@series@contexttrue\@undefined
%<latexrelease>\let\@font@series@contextfalse\@undefined
%<latexrelease>\EndIncludeInRelease
%<*2ekernel>
%    \end{macrocode}
%
%
%
%
%
%
% \section{Supporting nested emphasis}
%
%    By default \LaTeXe{} supports two levels of nested emphasis: if
%    the current font has an upright shape then it switches to
%    \cs{itshape} otherwise to \cs{eminnershape} (which defaults to
%    \cs{upshape}). This means nested emphasis will oscillate between
%    italic and upright shapes.
%
%    Sometimes it would be nice to allow for a more lengthy sequence,
%    but instead of providing a fixed one \LaTeX{} now offers a
%    general mechanism that allows to define arbitrary sequences.
%
%    \DescribeMacro\DeclareEmphSequence
%    \DescribeMacro\emforce
%
%    This declaration expects a comma separated list of (font) change
%    declarations corresponding to increasing levels of emphasis.
%    The mechanism tries to be ``smart'' and verifies that the
%    declarations actually alter the font. If not it will ignore this
%    level and tries the next one---the assumption being that
%    there was a manual font change in the document to the font that
%    is now supposed to be used for emphasis. Of course, this only
%    works if the declarations in the list actually change the font
%    and not, say, just the color.
%    In such a case one has to use \cs{emforce} to which directs the
%    mechanism to use the level even if the font attributes haven't changed.
%
%  \DescribeMacro\emreset
%    If the nesting is so deep, that the specified  levels are
%    exhausted then \cs{emreset} is used as a final set of
%    declarations (which by default returns
%    back to the upright shape). Any additional nesting levels will
%    then reuse the list from its beginning.
%
%
%
%  \begin{macro}{\DeclareEmphSequence}
%
%    \cs{DeclareEmphSequence} expects a clist of declaration. Spaces in the
%    argument are dropped to avoid spurious spaces in the output. The
%    declarations are additive. At the very end the shape is reset
%    using |\emreset| and |\emforce| so that this case is never
%    skipped.\footnote{Maybe we should not add \cs{emforce} but allow
%    that case to be  skipped as well. Of course, that might result in
%    an endless loop if somebody defines a sequence without any font
%    change and without \cs{emforce} but \ldots}
%    Further nested calls restart at the beginning.
% \changes{v3.1e}{2019/12/17}{Provide \cs{emph} sequences}
%    \begin{macrocode}
%</2ekernel>
%<*2ekernel|latexrelease>
%<latexrelease>\IncludeInRelease{2020/02/02}%
%<latexrelease>                 {\DeclareEmphSequence}{Nested emph}%
\def\DeclareEmphSequence#1{%
  \protected@edef\emfontdeclare@clist{\zap@space#1, \@empty\emforce\emreset}%
}
%    \end{macrocode}
%    By default the it is empty, in which case \cs{eminnershape} is
%    used by \LaTeX.
%    \begin{macrocode}
\let\emfontdeclare@clist\@empty
%    \end{macrocode}
%  \end{macro}
%
%
%
%  \begin{macro}{\emrest}
%    Reset the font to upright and upper/lower case. With the default rules
%    using \cs{shapedefault} does that for us but to be on the safe side we
%    do it like this:
%    \begin{macrocode}
\DeclareRobustCommand\emreset{\upshape\ulcshape}
%    \end{macrocode}
%  \end{macro}
%
%
%
%  \begin{macro}{\em}
%
%    The new definition for \cs{em} (and implicitly \cs{emph}) is the
%    same as before as long as \cs{emfontdeclare@clist} is empty.
%    \begin{macrocode}
\DeclareRobustCommand\em{%
  \@nomath\em
  \ifx\emfontdeclare@clist\@empty
    \ifdim \fontdimen\@ne\font >\z@
      \eminnershape \else \itshape \fi
  \else
%    \end{macrocode}
%    But if not we use the list to decide how to do emphasis.
%
%    We use the current font to check if the declarations have any
%    effect, so even a size change is allowed and identified as a
%    modification (but a color change, for example, isn't).  So first
%    we save the current status.
%    \begin{macrocode}
  \edef\em@currfont{\csname\curr@fontshape/\f@size\endcsname}%
%    \end{macrocode}
%    Then we grab the next element from the list and check if it can
%    be used.
%    \begin{macrocode}
    \expandafter\do@emfont@update\emfontdeclare@clist\do@emfont@update
  \fi
}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\eminnershape{\upshape}
%    \end{macrocode}
%  \end{macro}
%
%
%
%  \begin{macro}{\do@emfont@update}
%    We know that the list (if not empty) has at least 2 elements
%    separated by a comma, so we pick up the first in \texttt{\#1} and
%    the rest in \texttt{\#2}.
%    \begin{macrocode}
\def\do@emfont@update#1,#2\do@emfont@update{%
%    \end{macrocode}
%    First action is to alter the list and move the first entry to the end
%    \begin{macrocode}
  \def\emfontdeclare@clist{#2,#1}%
%    \end{macrocode}
%    Then we execute current declaration. Appending |\selectfont| means one
%    can write just |\fontshape{it}}| and that works then too.
%    \begin{macrocode}
%  \typeout{Use: \detokenize{#1}}%
  #1\selectfont
%    \end{macrocode}
%    We then compare the current font with our saved version, but with
%    a slight twist: we add \cs{em@force} at the end of the
%    name. Normally this is empty so has no effect but if there was an
%    \cs{emforce} as part of \texttt{\#1} it will append a |/| to the
%    font name (making it invalid) thus this will then always fail the
%    test.
%
%    If the test fails we are done and the declarations will be used.
%    Otherwise we will try the next declaration in the sequence.
%    \begin{macrocode}
  \expandafter\ifx\csname \curr@fontshape/\f@size\em@force
%    \end{macrocode}
%    For the comparison with \cs{ifx} we have to expand
%    \cs{em@currfont} once as the relevant info is inside.
%    \begin{macrocode}
                          \expandafter\endcsname
                  \em@currfont
  \expandafter\do@emfont@update\emfontdeclare@clist\do@emfont@update
%    \end{macrocode}
%    If \cs{emforce} was used, we have to undo its effect:
%    \begin{macrocode}
  \else
    \let\em@force\@empty
  \fi
}
%    \end{macrocode}
%  \end{macro}



%  \begin{macro}{\emforce}
%  \begin{macro}{\em@force}
%    The definition of \cs{emforce} is simple: change \cs{em@force} to
%    make the above test always invalid.
%    \begin{macrocode}
\protected\def\emforce{\def\em@force{/}}
\let\em@force\@empty
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%    \end{macrocode}
%  \end{macro}
%  \end{macro}



%
% \begin{macro}{\em}
% \changes{v1.2b}{1990/01/28}{Call to \cs{@nomath} added.}
% \changes{v3.1a}{2015/01/09}{Allow \cs{emph} to produce small caps (latexrelease)}
% \begin{macro}{\eminnershape}
% \changes{v3.1a}{2015/01/09}{macro added (latexrelease)}
%
%  These are the older definitions for \cs{em}, prior to 2020.
%
% We also have to define the {\em emphasize\/} font change command
% (i.e.\ |\em|). This command will look is the current font is
% sloped (i.e.\ has a positive |\fontdimen1|) and will then
% select either |\upshape| or |\itshape|.
%    \begin{macrocode}
%<latexrelease>\IncludeInRelease{2015/01/01}{\DeclareEmphSequence}{Nested emph}%
%<latexrelease>\let\DeclareEmphSequence\@undefined
%<latexrelease>\let\emfontdeclare@clist\@undefined
%<latexrelease>\let\emreset\@undefined
%<latexrelease>\let\do@emfont@update\@undefined
%<latexrelease>\let\emforce\@undefined
%<latexrelease>\let\em@force\@undefined
%<latexrelease>
%<latexrelease>\DeclareRobustCommand\em
%<latexrelease>        {\@nomath\em \ifdim \fontdimen\@ne\font >\z@
%<latexrelease>                       \eminnershape \else \itshape \fi}%
%<latexrelease>\EndIncludeInRelease
%<latexrelease>
%<latexrelease>\IncludeInRelease{0000/00/00}{\DeclareEmphSequence}{Nested emph}%
%<latexrelease>\DeclareRobustCommand\em
%<latexrelease>        {\@nomath\em \ifdim \fontdimen\@ne\font >\z@
%<latexrelease>                       \upshape \else \itshape \fi}%
%<latexrelease>\let\eminnershape\@undefined
%<latexrelease>\EndIncludeInRelease
%<*2ekernel>
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%
%  \begin{macro}{\not@math@alphabet}
%    This function generates an error message when it is called in
%    math mode. The same function should be defined in
%    \texttt{newlfont.sty}.
% \changes{v1.4d}{1992/09/21}{Macro defined.}
% \changes{v2.1e}{1994/01/17}{Message changed}
% \changes{v2.1f}{1994/01/18}{Message corrected}
% \changes{v2.1g}{1994/04/22}{Message changed again}
% \changes{v2.2d}{1995/04/02}{add \cs{noexpand} to second part of message}
%    \begin{macrocode}
\def\not@math@alphabet#1#2{%
   \relax
   \ifmmode
     \@latex@error{Command \noexpand#1invalid in math mode}%
        {%
         Please
         \ifx#2\relax
            define a new math alphabet^^J%
            if you want to use a special font in math mode%
          \else
%    \end{macrocode}
%    We have to a |\noexpand| below to prevent expansion of |#2|. In
%    case of |#1| we can omit this (due to the current definition of
%    robust commands since they do come out right there :-).
%    \begin{macrocode}
            use the math alphabet \noexpand#2instead of
            the #1command%
         \fi
         .
        }%
   \fi}
%    \end{macrocode}
%  \end{macro}
%
%
%
% Finally we provide two abbreviations to switch to the \LaTeX{}
% \emph{versions}.
%    \begin{macrocode}
\DeclareRobustCommand\boldmath{\@nomath\boldmath
              \mathversion{bold}}
\DeclareRobustCommand\unboldmath{\@nomath\unboldmath
              \mathversion{normal}}
%    \end{macrocode}
% Here we switch to the default math version by defining the internal
% macro |\math@version|. We dare not to call |\mathversion|
% at this place because this would call |\glb@settings|.
%    \begin{macrocode}
\def\math@version{normal}
%    \end{macrocode}
%
% \subsection{Legacy}
%
%    We start by defining a few macros that are part of
%    standard \LaTeX's user interface. The use of these functions is
%    not encouraged, but they will allow to process older documents
%    without changes to the source.
%
% \begin{macro}{\newfont}
% \changes{v1.2g}{1991/03/30}{Definition added.}
% \changes{v2.2e}{1995/05/23}{Font assignment made local again.}
%    \begin{macrocode}
\def\newfont#1#2{\@ifdefinable#1{\font#1=#2\relax}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\symbol}
% \changes{v1.2g}{1991/03/30}{Definition added.}
% \changes{v3.1h}{2020/02/07}{XeTeX-specific version to avoid bug in maths mode.}
%    \begin{macrocode}
%</2ekernel>
%<*2ekernel|latexrelease>
%<latexrelease>\IncludeInRelease{2020/10/01}%
%<latexrelease>                 {\symbol}{XeTeX change for math}%
\ifdefined\XeTeXversion
  \DeclareRobustCommand\symbol[1]{\Ucharcat#1 12\relax}
\else
  \DeclareRobustCommand\symbol[1]{\char#1\relax}
\fi
%</2ekernel|latexrelease>
%    \end{macrocode}
%    
%    \begin{macrocode}
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{0000/00/00}%
%<latexrelease>                 {\symbol}{XeTeX change for math}%
%<latexrelease>
%<latexrelease>\DeclareRobustCommand\symbol[1]{\char#1\relax}
%<latexrelease>
%<latexrelease>\EndIncludeInRelease
%<*2ekernel>
%    \end{macrocode}
% \end{macro}
%
% \subsection{Miscellaneous}
%
% \begin{macro}{\@setfontsize}
% \begin{macro}{\@setsize}
%    This abbreviation is used by \LaTeX's user level size changing
%    commands, such as |\large|.
%    \begin{macrocode}
\def\@setfontsize#1#2#3{\@nomath#1%
%    \end{macrocode}
%    For the benefit of people relying on keeping the name of the
%    current font command saved in |\@currsize| we define it. To ensure
%    that |\@setfontsize| keeps being robust we omit this assignment
%    during times where |\protect| differs from |\@typeset@protect|.
% \changes{v1.4b}{1992/08/20}{Added \cs{@currsize}.}
% \changes{v2.2b}{1994/11/06}{Use \cs{@typeset@protect}}
%    \begin{macrocode}
    \ifx\protect\@typeset@protect
      \let\@currsize#1%
    \fi
    \fontsize{#2}{#3}\selectfont}
%    \end{macrocode}
%    For compatibility  we also define |\@setsize| the 209 command
%    \begin{macrocode}
%<*compat>
\def\@setsize#1#2#3#4{\@setfontsize#1{#4}{#2}}
%</compat>
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%
% \begin{macro}{\hexnumber@}
%    To set up \LaTeX's special math character
%    definitions we first provide a macro to generate hexadecimal
%    numbers.  It is a rather simple |\ifcase|.
% \changes{v?}{1992/11/13}{Made expandable.}
% \changes{v?}{1992/12/03}{Make it accept counters.}
%    \begin{macrocode}
\def\hexnumber@#1{\ifcase\number#1
 0\or 1\or 2\or 3\or 4\or 5\or 6\or 7\or 8\or
 9\or A\or B\or C\or D\or E\or F\fi}
%    \end{macrocode}
%  \end{macro}
%
%
%
% \begin{macro}{\nfss@text}
% \changes{v1.1e}{1990/01/25}{Macro added.}
%    In it simplest form |\nfss@text| is an |\mbox|.  This will
%    produce unbreakable text outside math and inside math you will
%    get text with the same fonts as outside. The only drawback is
%    that such item won't change sizes in subscripts. But this
%    behavior can be easily changed. With the \texttt{amstex} style
%    option one will get a sub style called \texttt{amstext} which will
%    redefine the |\nfss@text| macro to produce correct text in all
%    sizes.
%
%    We have to use |\def| instead of the shorter |\let| since
%    |\mbox| is undefined when we reach this point.
% \changes{v1.1k}{1990/06/23}{Changed to \cs{mbox}.}
% \changes{v2.1n}{1994/05/17}{Added braces to allow use in subscripts}
%    \begin{macrocode}
\def\nfss@text#1{{\mbox{#1}}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\copyright}
%    The definition of |\copyright| was changed so
%    that it works in other type styles,
%    and to make it robust. We leave the family untouched so that
%    the copyright notice will come out differently if a different
%    font family is in use.
%    This command is commented out, since it is now defined in
%    ltoutenc.dtx.
% \changes{v1.1m}{1991/03/28}{Extra braces added.}
% \changes{v2.1n}{1994/05/17}{Really add extra braces}
% \changes{v2.2c}{1994/12/02}{\cs{copyright} is now in ltoutenc.
%    ASAJ}
%    \begin{macrocode}
%\DeclareRobustCommand\copyright
%    {{\ooalign{\hfil
%     \raise.07ex\hbox{\mdseries\upshape c}\hfil\crcr
%     \mathhexbox20D}}}
%    \end{macrocode}
% \end{macro}
%
% \changes{v2.1a}{1993/11/24}{Removed \cs{xpt} stuff}
%
%
% \begin{macro}{\normalfont}
% \changes{v2.1a}{1993/11/11}{Macro added}
% \begin{macro}{\reset@font}
% \changes{v1.1n}{1991/08/26}{Macro introduced}
%    The macro |\reset@font| is used in \LaTeX{} to switch to a standard
%    font, in order to initialize the current font in situations where
%    typesetting is done in a new visual context (e.g.\ in a
%    footnote). We define it here to allow the test for the new
%    \LaTeX{} version above but nevertheless are able to run all kind
%    of mixtures.
% \changes{v1.1o}{1991/11/21}{Changed to protected version of macro.}
% \changes{v1.1o}{1991/11/21}{Added extra braces for robustness.}
%
%    The user interface name for |\reset@font| is |\normalfont|:
% \changes{v2.1k}{1994/05/14}{Remove surplus braces}
% \changes{v3.0f}{1995/10/16}{Added \cs{relax} after \cs{usefont},
%              as the latter eats up spaces.}
% \changes{v3.1h}{2020/02/10}{Add \cs{@defaultfamilyhook} to \cs{normalfont} (gh/269)}
%    \begin{macrocode}
%</2ekernel>
%<*2ekernel|latexrelease>
%<latexrelease>\IncludeInRelease{2021/06/01}%
%<latexrelease>                 {\normalfont}{Add hook to \normalfont}%
\DeclareRobustCommand\normalfont{%
%    \end{macrocode}
%    Instead of calling \cs{usefont}, as it was done in the past, we
%    inline the code from \cs{usefont} as we want to add the hook
%    before \cs{selectfont}, but after all the font attributes are set.
%    \begin{macrocode}
   \fontencoding\encodingdefault
   \edef\f@family{\familydefault}%
   \edef\f@series{\seriesdefault}%
   \edef\f@shape{\shapedefault}%
%    \end{macrocode}
%    Any earlier \cs{fontseries}, etc.\ should be canceled and we
%    should switch unconditionally to the requested font face so we
%    drop any  code that may have been stored in
%    \cs{delayed@f@adjustment}.
% \changes{v3.2h}{2021/04/26}{Unconditionally switch to the requested
%    font face (gh/444)}
%    \begin{macrocode}
   \let\delayed@f@adjustment\@empty
%    \end{macrocode}
%    
% \changes{v3.2b}{2020/08/21}{Integration of new hook management interface}
%    \begin{macrocode}
   \UseHook{normalfont}%
%    \end{macrocode}
%    This is the old name for the hook introduced in 2020/02/02.
%    It will be removed in one of the future releases!
%    \begin{macrocode}
   \@defaultfamilyhook        % hookname from 2020/02 will vanish
   \selectfont}
%    \end{macrocode}
%
%    \begin{macrocode}
\let\reset@font\normalfont
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%
%
%    \begin{macrocode}
% \changes{v3.2g}{2021/03/18}
%         {Add missing 2020/02/02 latexrelease entry.}
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%<latexrelease>
%<latexrelease>\IncludeInRelease{2020/10/01}%
%<latexrelease>                 {\normalfont}{Add hook to \normalfont}%
%<latexrelease>
%<latexrelease>\DeclareRobustCommand\normalfont{%
%<latexrelease>   \fontencoding\encodingdefault
%<latexrelease>   \edef\f@family{\familydefault}%
%<latexrelease>   \edef\f@series{\seriesdefault}%
%<latexrelease>   \edef\f@shape{\shapedefault}%
%<latexrelease>   \UseHook{normalfont}%
%<latexrelease>   \@defaultfamilyhook        % hookname from 2020/02 will vanish
%<latexrelease>   \selectfont}
%<latexrelease>
%<latexrelease>\let\reset@font\normalfont
%<latexrelease>
%<latexrelease>\EndIncludeInRelease
%<latexrelease>
%<latexrelease>\IncludeInRelease{2020/02/02}%
%<latexrelease>                 {\normalfont}{Add hook to \normalfont}%
%<latexrelease>
%<latexrelease>\DeclareRobustCommand\normalfont{%
%<latexrelease>   \fontencoding\encodingdefault
%<latexrelease>   \edef\f@family{\familydefault}%
%<latexrelease>   \edef\f@series{\seriesdefault}%
%<latexrelease>   \edef\f@shape{\shapedefault}%
%<latexrelease>   \@defaultfamilyhook
%<latexrelease>   \selectfont}
%<latexrelease>
%<latexrelease>\let\reset@font\normalfont
%<latexrelease>
%<latexrelease>\let\@defaultfamilyhook\@empty
%<latexrelease>
%<latexrelease>\EndIncludeInRelease
%<latexrelease>
%<latexrelease>\IncludeInRelease{0000/00/00}%
%<latexrelease>                 {\normalfont}{Add hook to \normalfont}%
%<latexrelease>
%<latexrelease>\DeclareRobustCommand\normalfont
%<latexrelease>         {\usefont\encodingdefault
%<latexrelease>                  \familydefault
%<latexrelease>                  \seriesdefault
%<latexrelease>                  \shapedefault
%<latexrelease>                  \relax}
%<latexrelease>\let\reset@font\normalfont
%<latexrelease>
%<latexrelease>\let\@defaultfamilyhook\@undefined
%<latexrelease>
%<latexrelease>\EndIncludeInRelease
%<*2ekernel>
%    \end{macrocode}
%
%
%
% We left out the special \LaTeX{} fonts which are not automatically
% included in the base version of the font selection since these fonts
% contain only a few characters which are also included in the AMS
% fonts so anybody who is using these fonts doesn't need them.
% But for compatibility reasons we will define these symbols.
%
% \changes{v2.1g}{1994/02/22}{Correct error message}
%    \begin{macrocode}
\def\not@base#1{\@latex@error
  {Command \noexpand#1not provided in base LaTeX2e}%
  {Load the latexsym or the amsfonts package to
   define this symbol}}
\def\mho{\not@base\mho}
\def\Join{\not@base\Join}
\def\Box{\not@base\Box}
\def\Diamond{\not@base\Diamond}
\def\leadsto{\not@base\leadsto}
\def\sqsubset{\not@base\sqsubset}
\def\sqsupset{\not@base\sqsupset}
\def\lhd{\not@base\lhd}
\def\unlhd{\not@base\unlhd}
\def\rhd{\not@base\rhd}
\def\unrhd{\not@base\unrhd}
%    \end{macrocode}
%
%
%
%    We now initialize all variables set by |\DeclareErrorFont|. These
%    values are not really important since they will be overwritten
%    later on by the definition in |fontdef.ltx|.
%
%    However, if \texttt{fontdef.cfg} is corrupted then at least a
%    hopefully suitable error font is present.
%
% \changes{v2.1k}{1994/05/14}{Init error font just before checking for
%                             fontdef.cfg}
%    \begin{macrocode}
\DeclareErrorFont{OT1}{cmr}{m}{n}{10}  %% don't modify this setting
                                       %% overwrite it in fontdef.cfg
                                       %% if necessary
%    \end{macrocode}
%    We also set some default values for |\f@family| etc. Note that we
%    don't yet have any encodings that comes later. In the past this
%    was implicitly done by |\DeclareErrorFont|.
% \changes{v3.1c}{2019/07/09}{Explicitly set some defaults}
%    \begin{macrocode}
\fontfamily{cmr}
%    \end{macrocode}
%    
% \changes{v3.2f}{2020/12/04}{Adjust start values for series and shape (gh/444)}
%    Previously the default values for series and shape were set by
%    calling \cs{fontseries} and \cs{fontshape}, but their action is
%    now delayed until \cs{selectfont} which isn't called inside the
%    format (to avoid unnecessarily loading a font that may never get used).
%    We therefore have to set \cs{f@series} and \cs{f@shape} directly instead.
%    \begin{macrocode}
\def\f@series{m}           % \fontseries{m}
\def\f@shape{n}            % \fontshape{n}
%    \end{macrocode}
%
%    \begin{macrocode}
\fontsize{10}{10}
%    \end{macrocode}
%
%
%    The initial \texttt{fontenc} package load list. This will get
%    overwritten in \texttt{fonttext} and is only provided in case an
%    old \texttt{fonttext.cfg} does not define the command:
% \changes{v3.1h}{2020/02/11}{Provide default value for
%                 \cs{@fontenc@load@list} (gh/273)}
%    \begin{macrocode}
\def\@fontenc@load@list{\@elt{T1,OT1}}
%    \end{macrocode}
%
%
% We now load the customizable parts of NFSS.
% \changes{v3.0d}{1995/07/19}
%      {(DPC) TeX2 support}
% \changes{v3.0e}{1995/09/15}
%      {(DPC) Modify TeX2 message}
% \changes{v3.0g}{1995/11/01}
%      {(DPC) Switch meaning of \cs{@addtofilelist} for cfg files}
% \changes{v3.0h}{1996/12/06}
%      {(DPC) Remove *** from messages internal/2338}
%    \begin{macrocode}
\InputIfFileExists{fonttext.cfg}
           {\typeout{====================================^^J%
                     ^^J%
                      Local config file fonttext.cfg used^^J%
                     ^^J%
                     ====================================}%
             \def\@addtofilelist##1{\xdef\@filelist{\@filelist,##1}}%
            }
           {\input{fonttext.ltx}}
\let\@addtofilelist\@gobble
%    \end{macrocode}
%
%
% Ditto for math although I don't think that we will get a lot of
% customisation :-)
%    \begin{macrocode}
\InputIfFileExists{fontmath.cfg}
           {\typeout{====================================^^J%
                     ^^J%
                      Local config file fontmath.cfg used^^J%
                     ^^J%
                     ====================================}%
             \def\@addtofilelist##1{\xdef\@filelist{\@filelist,##1}}%
            }
           {\input{fontmath.ltx}}
\let\@addtofilelist\@gobble
%    \end{macrocode}
%
% Then we preload several fonts. This file might be customized
% \emph{without} changing the behavior of the format (i.e.\ necessary
% font definitions will be loaded at runtime if they are not
% preloaded).  This is done in the file \texttt{preload.ltx}.
%    \begin{macrocode}
\InputIfFileExists{preload.cfg}
           {\typeout{====================================^^J%
                     ^^J%
                      Local config file preload.cfg used^^J%
                     ^^J%
                     =====================================}%
             \def\@addtofilelist##1{\xdef\@filelist{\@filelist,##1}}%
            }
           {\input{preload.ltx}}
\let\@addtofilelist\@gobble
%    \end{macrocode}
%
%
%
%  \begin{macro}{\seriesdefault}
%  \begin{macro}{\seriesdefault@kernel}
%    After \cs{seriesdefault} got defined inside \texttt{fonttext.ltx}
%    or a \texttt{.cfg} file overwriting it, we alter its value by
%    appending \cs{@empty} to it. This will vanish if expanded but
%    allows us to check if the default gets altered (even to the same
%    value) in the document preamble. All we have to do is to save the
%    current value somewhere and later compare the two. For this we
%    use \cs{seriesdefault@kernel}.
% \changes{v3.1n}{2020/04/13}{Handling \cs{seriesdefault} changes (gh/315)}
%    \begin{macrocode}
\expandafter\def\expandafter\seriesdefault\expandafter{\seriesdefault\@empty}
\let\seriesdefault@kernel\seriesdefault
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%
%
%
% \begin{macro}{\@acci}
% \begin{macro}{\@accii}
% \begin{macro}{\@acciii}
% \changes{v2.1m}{1994/05/16}{Define saved versions of accents}
%    We also save the values of some accents in |\@acci|, |\@accii|
%    and |\@acciii| so they can be restored by a |minipage| inside a
%    |tabbing| environment.
%    \begin{macrocode}
\let\@acci\' \let\@accii\` \let\@acciii\=
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
% \begin{macro}{\cal}
% \changes{v3.0a}{1995/05/24}
%      {(DPC) Remove definition}
% \begin{macro}{\mit}
% \changes{v3.0a}{1995/05/24}
%      {(DPC) Remove definition}
%    Here were the two old \meta{alphabet identifiers}.
% \end{macro}
% \end{macro}
%
%
% \iffalse
%<+checkmem>\CHECKMEM
% \fi
%
%    \begin{macrocode}
%</2ekernel>
%    \end{macrocode}
%
% \Finale
%
