% \iffalse meta-comment
%
% Copyright (C) 2019-2024
% The LaTeX Project and any individual authors listed elsewhere
% in this file.
%
% This file is part of the LaTeX base system.
% -------------------------------------------
%
% It may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3c
% of this license or (at your option) any later version.
% The latest version of this license is in
%    https://www.latex-project.org/lppl.txt
% and version 1.3c or later is part of all distributions of LaTeX
% version 2008 or later.
%
% This file has the LPPL maintenance status "maintained".
%
% The list of all files belonging to the LaTeX base distribution is
% given in the file `manifest.txt'. See also `legal.txt' for additional
% information.
%
% The list of derived (unpacked) files belonging to the distribution
% and covered by LPPL is defined by the unpacking scripts (with
% extension .ins) which are part of the distribution.
%
% \fi
% \iffalse
%%% From File: ltfssaxes.dtx
%% Copyright (C) 2019-2020 Frank Mittelbach
%
%<*driver>
% \fi
%
%
\ProvidesFile{ltfssaxes.dtx}
             [2024/11/19 v1.0j LaTeX Kernel (NFSS Axes handing)]
% \iffalse
\documentclass{ltxdoc}
\begin{document}
\DocInput{ltfssaxes.dtx}
\end{document}
%</driver>
% \fi
%
%
%
%
% \GetFileInfo{ltfssaxes.dtx}
% \title{A new font selection scheme for \TeX{} macro packages\\
%        (Axes Handling)\thanks
%       {This file has version number
%       \fileversion\ dated \filedate}}
%
% \author{Frank Mittelbach}
%
% \MaintainedByLaTeXTeam{latex}
% \maketitle
%
% This file contains the implementation for handling extra axes
% splitting the series and the values into sub-categories.  selection
% commands. See other parts of the \LaTeX\ distribution, or \emph{The
% \LaTeX\ Companion} for higher level documentation of the
% \LaTeX\ Font Selection Scheme.
%
%
%
% \MaybeStop{}
%
% \changes{v1.0h}{2020/12/04}{Reorganized the rollback data}
%
%    \begin{macrocode}
%<2ekernel>\message{NFSS axes,}
%    \end{macrocode}
%    
% Everything in the this file got introduced 2020/02/02, so we use large rollback
% chunks, only interrupted if necessary.
%    \begin{macrocode}
%<*2ekernel|latexrelease>
%    \end{macrocode}
%
%    \begin{macrocode}
%<latexrelease>\IncludeInRelease{2020/02/02}%
%<latexrelease>   {\DeclareFontSeriesChangeRule}{Series change rules}%
%    \end{macrocode}
%
%
%
% \section{Changing the font series}
%
% In the original NFSS implementation the series was a single
% attribute stored in \cs{f@series} and so one always had to specify
% both weight and width together. This means it was impossible to
% typeset, a paragraph in a condensed font and inside have a few words
% in bold weight (but still condensed) without doing this manually by
% requesting \verb=\fontseries{bc}\selectfont=.
%
% The new implementation now works differently by looking both at the
% current value of \cs{f@series} and the requested new series and out
% of that combination selects a resulting series value. Thus, if the
% current series is \texttt{c} and we ask for \texttt{b} we  now get
% \texttt{bc}.
%
% This is done by consulting a simple lookup table. This table is
% configurable (though most likely that flexibility will seldom of
% ever be needed) Adding or changing entries in this table are done
% with \cs{DeclareFontSeriesChangeRule}.
%
% \subsection{The series lookup table}
%
%
%  \begin{macro}{\DeclareFontSeriesChangeRule}
%    The \cs{DeclareFontSeriesChangeRule} defines entries in a simple
%    database (implemented as a set of commands) that define mappings
%    between from an existing series and requested new series and maps
%    that to  a result series (and additionally offers an alternative
%    if the desired one is not existing):
%    \begin{itemize}
%    \item[\texttt{\#1}] current \cs{f@series}
%    \item[\texttt{\#2}] requested new series
%    \item[\texttt{\#3}] result (if that exist for the given font family
%    \item[\texttt{\#4}] alternative result (if \texttt{\#3} does not exist)
%    \end{itemize}
%    If an \texttt{.fd} file has its own substitution rules then
%    \texttt{\#3} exist and thus \texttt{\#4} is not applied.
%
%    If there is no matching database entry or if neither the result
%    nor the alternate result exist in the font family the requested
%    new series is used (which then may trigger substitutions later on.
%    \begin{macrocode}
\def\DeclareFontSeriesChangeRule#1#2#3#4{%
  \@namedef{series@#1@#2}{{#3}{#4}}}
%    \end{macrocode}
%  \end{macro}
%
% \subsection{Mapping rules for series changes}
%
% The rules set up use explicit series values not \cs{..default}
% indirections; my current feeling is that this is in fact better.
%
% With 9 weights and 9 width classes this table is getting a bit large
% in the end (324 entries) but on the other hand it doesn't change and
% accessing speed and it is fast this way.
%
% We could alternatively split the axis and maintain weight and width
% separately, but that would take more processing time and would not
% allow for setting up explicit exceptions nicely (not sure that this
% would ever get used though).
%
% Design considerations for mapping entries:
% \begin{itemize}
% \item
%
%    We make \texttt{m} to reset both weight and width (as this is
%    how it always worked). To reset just the width \texttt{?m} is
%    provided and to reset just the weight \texttt{m?}.
%
% \item
%
%   We do support ``\texttt{m}\textit{width}'' and
%    ``\textit{weight}\texttt{m}'', e.g., \texttt{mec} to mean ``go to
%    medium weight and extra-condensed width''. At the end of the
%    process we automatically drop any leftover \texttt{m} in the
%    series name (unless it is just a single \texttt{m}).
%
%
% \item
%
%    If there is no table entry then the target series is used
%    unconditionally. This means that any request to set both weight
%    and width (e.g. \texttt{bx} or \texttt{ulc}) needs no table
%    entries.
%    For that reason there are no entries which have a weight+width as
%    request (i.e., second argument).
%
%    In particular this is also true for cases involving \texttt{m},
%    e.g., \texttt{bm} (bold medium width) which automatically gets
%    reduced result in \texttt{b} or \texttt{mc} (medium weight
%    condensed) which becomes \texttt{c} as a result.
%
% \item
%
%    Only a few entries have ``alternative'' values and perhaps most of
%    them should get dropped. Or maybe not \ldots{} needs some thought
%    perhaps.
%
%    The idea is that you don't want the normal substitution to kick
%    in because that would reset the shape first and it may be better
%    to stay with \texttt{b} when a change to \texttt{c} is requested
%    and \texttt{bc} doesn't exist, than to go to first change the
%    shape to \texttt{n} and then find that \texttt{bc/n} doesn't
%    exist either and thus ending up with \texttt{m/n}.
%
% \item
%
%    Also: while I did set up all nine standard weight values from
%    \texttt{ul} to \texttt{ub} I only bothered to provide entries for
%    \texttt{ec},  \texttt{sc}, \texttt{c} and \texttt{x}, because other levels of
%    compression/expansion are not in any real fonts that I know.
%
%    Could and perhaps should be eventually extended to cover the
%    whole set.
%
% \end{itemize}
%
%    \begin{macrocode}
\DeclareFontSeriesChangeRule {bc}{b}{bc}{}
\DeclareFontSeriesChangeRule {bc}{c}{bc}{}
\DeclareFontSeriesChangeRule {bc}{eb}{ebc}{}
\DeclareFontSeriesChangeRule {bc}{ec}{bec} {bc}
\DeclareFontSeriesChangeRule {bc}{el}{elc}{}
\DeclareFontSeriesChangeRule {bc}{l}{lc}{}
\DeclareFontSeriesChangeRule {bc}{sb}{sbc}{}
\DeclareFontSeriesChangeRule {bc}{sc}{bsc} {bc}
\DeclareFontSeriesChangeRule {bc}{sl}{slc}{}
\DeclareFontSeriesChangeRule {bc}{ub}{ubc}{}
\DeclareFontSeriesChangeRule {bc}{ul}{ulc}{}
\DeclareFontSeriesChangeRule {bc}{x}{bx}{}
%    \end{macrocode}
%
%    \begin{macrocode}
\DeclareFontSeriesChangeRule {bx}{b}{bx}{}
\DeclareFontSeriesChangeRule {bx}{c}  {bc}  {bx}	%<-----
\DeclareFontSeriesChangeRule {bx}{eb}{ebx}{}
\DeclareFontSeriesChangeRule {bx}{ec}  {bec}  {bx}	%<-----
\DeclareFontSeriesChangeRule {bx}{el}{elx}{}
\DeclareFontSeriesChangeRule {bx}{l}{lx}{}
\DeclareFontSeriesChangeRule {bx}{sb} {sbx} {}
\DeclareFontSeriesChangeRule {bx}{sc}  {bsc}  {bx}	%<-----
\DeclareFontSeriesChangeRule {bx}{sl}{slx}  {}
\DeclareFontSeriesChangeRule {bx}{ub}{ubx}{}
\DeclareFontSeriesChangeRule {bx}{ul}{ulx}{}
\DeclareFontSeriesChangeRule {bx}{x}{bx}{}
%    \end{macrocode}
%
%    \begin{macrocode}
\DeclareFontSeriesChangeRule {b}{bx} {bx}  {b}		%<-----
\DeclareFontSeriesChangeRule {b}{c}  {bc}  {b}		%<-----
\DeclareFontSeriesChangeRule {b}{ec}  {bec}  {b}	%<-----
\DeclareFontSeriesChangeRule {b}{sb} {sb}  {b}		%<-----
\DeclareFontSeriesChangeRule {b}{sc}  {bsc}  {b}	%<-----
\DeclareFontSeriesChangeRule {b}{x}  {bx}  {b}		%<-----
%    \end{macrocode}
%
%    \begin{macrocode}
\DeclareFontSeriesChangeRule {c}{bx} {bx}  {b} 		%<-----
\DeclareFontSeriesChangeRule {c}{b}{bc}{}
\DeclareFontSeriesChangeRule {c}{eb}{ebc}{}
\DeclareFontSeriesChangeRule {c}{el}{elc}{}
\DeclareFontSeriesChangeRule {c}{l}{lc}{}
\DeclareFontSeriesChangeRule {c}{sb}{sbc}{}
\DeclareFontSeriesChangeRule {c}{sl}{slc}{}
\DeclareFontSeriesChangeRule {c}{ub}{ubc}{}
\DeclareFontSeriesChangeRule {c}{ul}{ulc}{}
\DeclareFontSeriesChangeRule {c}{x}{x}{m}               %<-----
%    \end{macrocode}
%
%    \begin{macrocode}
\DeclareFontSeriesChangeRule {ebc}{b}{bc}{}
\DeclareFontSeriesChangeRule {ebc}{c}{ebc}{}
\DeclareFontSeriesChangeRule {ebc}{eb}{ebc}{}
\DeclareFontSeriesChangeRule {ebc}{ec}{ebec}{ebc}
\DeclareFontSeriesChangeRule {ebc}{el}{elc}{}
\DeclareFontSeriesChangeRule {ebc}{l}{lc}{}
\DeclareFontSeriesChangeRule {ebc}{sb}{sbc}{}
\DeclareFontSeriesChangeRule {ebc}{sc}{ebsc}{ebc}
\DeclareFontSeriesChangeRule {ebc}{sl}{slc}{}
\DeclareFontSeriesChangeRule {ebc}{ub}{ubc}{}
\DeclareFontSeriesChangeRule {ebc}{ul}{ulc}{}
\DeclareFontSeriesChangeRule {ebc}{x}{ebx}{}
%    \end{macrocode}
%
%
%    \begin{macrocode}
\DeclareFontSeriesChangeRule {ec}{bx} {bx}  {b} 	%<-----
\DeclareFontSeriesChangeRule {ec}{b}{bec}{}
\DeclareFontSeriesChangeRule {ec}{eb}{ebec}{}
\DeclareFontSeriesChangeRule {ec}{el}{elec}{}
\DeclareFontSeriesChangeRule {ec}{l}{lec}{}
\DeclareFontSeriesChangeRule {ec}{sb}{sbec}{}
\DeclareFontSeriesChangeRule {ec}{sl}{slec}{}
\DeclareFontSeriesChangeRule {ec}{ub}{ubec}{}
\DeclareFontSeriesChangeRule {ec}{ul}{ulec}{}
\DeclareFontSeriesChangeRule {ec}{x}{x}{m}              %<-----
%    \end{macrocode}
%
%    \begin{macrocode}
\DeclareFontSeriesChangeRule {sc}{bx} {bx}  {b} 	%<-----
\DeclareFontSeriesChangeRule {sc}{b}{bsc}{}
\DeclareFontSeriesChangeRule {sc}{eb}{ebsc}{}
\DeclareFontSeriesChangeRule {sc}{el}{elsc}{}
\DeclareFontSeriesChangeRule {sc}{l}{lsc}{}
\DeclareFontSeriesChangeRule {sc}{sb}{sbsc}{}
\DeclareFontSeriesChangeRule {sc}{sl}{slsc}{}
\DeclareFontSeriesChangeRule {sc}{ub}{ubsc}{}
\DeclareFontSeriesChangeRule {sc}{ul}{ulsc}{}
\DeclareFontSeriesChangeRule {sc}{x}{x}{m}              %<-----
%    \end{macrocode}
%
%    \begin{macrocode}
\DeclareFontSeriesChangeRule {ebx}{b}{bx}{}
\DeclareFontSeriesChangeRule {ebx}{c}{ebc}{}
\DeclareFontSeriesChangeRule {ebx}{eb}{ebx}{}
\DeclareFontSeriesChangeRule {ebx}{ec}{ebec}{}
\DeclareFontSeriesChangeRule {ebx}{el}{elx}{}
\DeclareFontSeriesChangeRule {ebx}{l}{lx}{}
\DeclareFontSeriesChangeRule {ebx}{sb}{sbx}{}
\DeclareFontSeriesChangeRule {ebx}{sc}{ebsc}{}
\DeclareFontSeriesChangeRule {ebx}{sl}{slx}{}
\DeclareFontSeriesChangeRule {ebx}{ub}{ubx}{}
\DeclareFontSeriesChangeRule {ebx}{ul}{ulx}{}
\DeclareFontSeriesChangeRule {ebx}{x}{ebx}{}
%    \end{macrocode}
%
%    \begin{macrocode}
\DeclareFontSeriesChangeRule {eb}{c}{ebc}{}
\DeclareFontSeriesChangeRule {eb}{ec}{ebec}{}
\DeclareFontSeriesChangeRule {eb}{sc}{ebsc}{}
\DeclareFontSeriesChangeRule {eb}{x}{ebx}{}
%    \end{macrocode}
%
%    \begin{macrocode}
\DeclareFontSeriesChangeRule {elc}{b}{bc}{}
\DeclareFontSeriesChangeRule {elc}{c}{elc}{}
\DeclareFontSeriesChangeRule {elc}{eb}{ebc}{}
\DeclareFontSeriesChangeRule {elc}{ec}{elec}{}
\DeclareFontSeriesChangeRule {elc}{el}{elc}{}
\DeclareFontSeriesChangeRule {elc}{l}{lc}{}
\DeclareFontSeriesChangeRule {elc}{sb}{sbc}{}
\DeclareFontSeriesChangeRule {elc}{sc}{elsc}{}
\DeclareFontSeriesChangeRule {elc}{sl}{slc}{}
\DeclareFontSeriesChangeRule {elc}{ub}{ubc}{}
\DeclareFontSeriesChangeRule {elc}{ul}{ulc}{}
\DeclareFontSeriesChangeRule {elc}{x}{elx}{}
%    \end{macrocode}
%
%    \begin{macrocode}
\DeclareFontSeriesChangeRule {elx}{b}{bx}{}
\DeclareFontSeriesChangeRule {elx}{c}{elc}{}
\DeclareFontSeriesChangeRule {elx}{eb}{ebx}{}
\DeclareFontSeriesChangeRule {elx}{ec}{elec}{}
\DeclareFontSeriesChangeRule {elx}{el}{elx}{}
\DeclareFontSeriesChangeRule {elx}{l}{lx}{}
\DeclareFontSeriesChangeRule {elx}{sb}{sbx}{}
\DeclareFontSeriesChangeRule {elx}{sc}{elsc}{}
\DeclareFontSeriesChangeRule {elx}{sl}{slx}{}
\DeclareFontSeriesChangeRule {elx}{ub}{ubx}{}
\DeclareFontSeriesChangeRule {elx}{ul}{ulx}{}
\DeclareFontSeriesChangeRule {elx}{x}{elx}{}
%    \end{macrocode}
%
%    \begin{macrocode}
\DeclareFontSeriesChangeRule {el}{c}{elc}{}
\DeclareFontSeriesChangeRule {el}{ec}{elec}{}
\DeclareFontSeriesChangeRule {el}{sc}{elsc}{}
\DeclareFontSeriesChangeRule {el}{x}{elx}{}
%    \end{macrocode}
%
%    \begin{macrocode}
\DeclareFontSeriesChangeRule {lc}{b}{bc}{}
\DeclareFontSeriesChangeRule {lc}{c}{lc}{}
\DeclareFontSeriesChangeRule {lc}{eb}{ebc}{}
\DeclareFontSeriesChangeRule {lc}{ec}{lec}{}
\DeclareFontSeriesChangeRule {lc}{el}{elc}{}
\DeclareFontSeriesChangeRule {lc}{l}{lc}{}
\DeclareFontSeriesChangeRule {lc}{sb}{sbc}{}
\DeclareFontSeriesChangeRule {lc}{sc}{lsc}{}
\DeclareFontSeriesChangeRule {lc}{sl}{slc}{}
\DeclareFontSeriesChangeRule {lc}{ub}{ubc}{}
\DeclareFontSeriesChangeRule {lc}{ul}{ulc}{}
\DeclareFontSeriesChangeRule {lc}{x}{lx}{}
%    \end{macrocode}
%
%    \begin{macrocode}
\DeclareFontSeriesChangeRule {lx}{b}{bx}{}
\DeclareFontSeriesChangeRule {lx}{c}{lc}{}
\DeclareFontSeriesChangeRule {lx}{eb}{ebx}{}
\DeclareFontSeriesChangeRule {lx}{ec}{lec}{}
\DeclareFontSeriesChangeRule {lx}{el}{elx}{}
\DeclareFontSeriesChangeRule {lx}{l}{lx}{}
\DeclareFontSeriesChangeRule {lx}{sb}{sbx}{}
\DeclareFontSeriesChangeRule {lx}{sc}{lsc}{}
\DeclareFontSeriesChangeRule {lx}{sl}{slx}{}
\DeclareFontSeriesChangeRule {lx}{ub}{ubx}{}
\DeclareFontSeriesChangeRule {lx}{ul}{ulx}{}
\DeclareFontSeriesChangeRule {lx}{x}{lx}{}
%    \end{macrocode}
%
%    \begin{macrocode}
\DeclareFontSeriesChangeRule {l}{bx} {bx}  {b}		%<-----
\DeclareFontSeriesChangeRule {l}{b}  {b}   {bx}		%<-----
\DeclareFontSeriesChangeRule {l}{c}  {lc}  {l}  % ?	%<-----
\DeclareFontSeriesChangeRule {l}{ec}  {lec}  {l}  % ?	%<-----
\DeclareFontSeriesChangeRule {l}{sb} {sb}  {b}  % ?	%<-----
\DeclareFontSeriesChangeRule {l}{sc}  {lsc}  {l}  % ?	%<-----
\DeclareFontSeriesChangeRule {l}{x}  {lx}  {l}  % ?	%<-----
%    \end{macrocode}
%
%    \begin{macrocode}
\DeclareFontSeriesChangeRule {m}{bx} {bx} {b}	  	%<-----
\DeclareFontSeriesChangeRule {m}{b}  {b}  {bx}		%<-----
\DeclareFontSeriesChangeRule {m}{c}  {c}  {m}		%<-----
\DeclareFontSeriesChangeRule {m}{ec}  {ec}  {m}		%<-----
\DeclareFontSeriesChangeRule {m}{l}  {l}  {m}		%<-----
\DeclareFontSeriesChangeRule {m}{sb} {sb} {b}		%<-----
\DeclareFontSeriesChangeRule {m}{sc}  {sc}  {m}		%<-----
\DeclareFontSeriesChangeRule {m}{x}  {x}  {m}		%<-----
%    \end{macrocode}
%
%    \begin{macrocode}
\DeclareFontSeriesChangeRule {sbc}{b}{bc}{}
\DeclareFontSeriesChangeRule {sbc}{c}{sbc}{}
\DeclareFontSeriesChangeRule {sbc}{eb}{ebc}{}
\DeclareFontSeriesChangeRule {sbc}{ec}{sbec}{sbc}
\DeclareFontSeriesChangeRule {sbc}{el}{elc}{}
\DeclareFontSeriesChangeRule {sbc}{l}{lc}{}
\DeclareFontSeriesChangeRule {sbc}{sb}{sbc}{}
\DeclareFontSeriesChangeRule {sbc}{sc}{sbsc}{sbc}
\DeclareFontSeriesChangeRule {sbc}{sl}{slc}{}
\DeclareFontSeriesChangeRule {sbc}{ub}{ubc}{}
\DeclareFontSeriesChangeRule {sbc}{ul}{ulc}{}
\DeclareFontSeriesChangeRule {sbc}{x}{sbx}{}
%    \end{macrocode}
%
%    \begin{macrocode}
\DeclareFontSeriesChangeRule {sbx}{b}{bx}{}
\DeclareFontSeriesChangeRule {sbx}{c}{sbc}{}
\DeclareFontSeriesChangeRule {sbx}{eb}{ebx}{}
\DeclareFontSeriesChangeRule {sbx}{ec}{sbec}{}
\DeclareFontSeriesChangeRule {sbx}{el}{elx}{}
\DeclareFontSeriesChangeRule {sbx}{l}{lx}{}
\DeclareFontSeriesChangeRule {sbx}{sb}{sbx}{}
\DeclareFontSeriesChangeRule {sbx}{sc}{sbsc}{}
\DeclareFontSeriesChangeRule {sbx}{sl}{slx}{}
\DeclareFontSeriesChangeRule {sbx}{ub}{ubx}{}
\DeclareFontSeriesChangeRule {sbx}{ul}{ulx}{}
\DeclareFontSeriesChangeRule {sbx}{x}{sbx}{}
%    \end{macrocode}
%
%    \begin{macrocode}
\DeclareFontSeriesChangeRule {sb}{c}  {sbc} {bc} %?	%<-----
\DeclareFontSeriesChangeRule {sb}{ec}  {sbec} {sbc} %?	%<-----
\DeclareFontSeriesChangeRule {sb}{sc}  {sbsc} {sbc} %?	%<-----
\DeclareFontSeriesChangeRule {sb}{x}  {sbx} {bx} %?	%<-----
%    \end{macrocode}
%
%    \begin{macrocode}
\DeclareFontSeriesChangeRule {slc}{b}{bc}{}
\DeclareFontSeriesChangeRule {slc}{c}{slc}{}
\DeclareFontSeriesChangeRule {slc}{eb}{ebc}{}
\DeclareFontSeriesChangeRule {slc}{ec}{slec}{}
\DeclareFontSeriesChangeRule {slc}{el}{elc}{}
\DeclareFontSeriesChangeRule {slc}{l}{lc}{}
\DeclareFontSeriesChangeRule {slc}{sb}{sbc}{}
\DeclareFontSeriesChangeRule {slc}{sc}{slsc}{}
\DeclareFontSeriesChangeRule {slc}{sl}{slc}{}
\DeclareFontSeriesChangeRule {slc}{ub}{ubc}{}
\DeclareFontSeriesChangeRule {slc}{ul}{ulc}{}
\DeclareFontSeriesChangeRule {slc}{x}{slx}{}
%    \end{macrocode}
%
%    \begin{macrocode}
\DeclareFontSeriesChangeRule {slx}{b}{bx}{}
\DeclareFontSeriesChangeRule {slx}{c}{slc}{}
\DeclareFontSeriesChangeRule {slx}{eb}{ebx}{}
\DeclareFontSeriesChangeRule {slx}{ec}{slec}{}
\DeclareFontSeriesChangeRule {slx}{el}{elx}{}
\DeclareFontSeriesChangeRule {slx}{l}{lx}{}
\DeclareFontSeriesChangeRule {slx}{sb}{sbx}{}
\DeclareFontSeriesChangeRule {slx}{sc}{slsc}{}
\DeclareFontSeriesChangeRule {slx}{sl}{slx}{}
\DeclareFontSeriesChangeRule {slx}{ub}{ubx}{}
\DeclareFontSeriesChangeRule {slx}{ul}{ulx}{}
\DeclareFontSeriesChangeRule {slx}{x}{slx}{}
%    \end{macrocode}
%
%    \begin{macrocode}
\DeclareFontSeriesChangeRule {sl}{c}{slc}{}
\DeclareFontSeriesChangeRule {sl}{ec}{slec}{}
\DeclareFontSeriesChangeRule {sl}{sc}{slsc}{}
\DeclareFontSeriesChangeRule {sl}{x}{slx}{}
%    \end{macrocode}
%
%    \begin{macrocode}
\DeclareFontSeriesChangeRule {ubc}{b}{bc}{}
\DeclareFontSeriesChangeRule {ubc}{c}{ubc}{}
\DeclareFontSeriesChangeRule {ubc}{eb}{ebc}{}
\DeclareFontSeriesChangeRule {ubc}{ec}{ubec}{}
\DeclareFontSeriesChangeRule {ubc}{el}{elc}{}
\DeclareFontSeriesChangeRule {ubc}{l}{lc}{}
\DeclareFontSeriesChangeRule {ubc}{sb}{sbc}{}
\DeclareFontSeriesChangeRule {ubc}{sc}{ubsc}{}
\DeclareFontSeriesChangeRule {ubc}{sl}{slc}{}
\DeclareFontSeriesChangeRule {ubc}{ub}{ubc}{}
\DeclareFontSeriesChangeRule {ubc}{ul}{ulc}{}
\DeclareFontSeriesChangeRule {ubc}{x}{ubx}{}
%    \end{macrocode}
%
%    \begin{macrocode}
\DeclareFontSeriesChangeRule {ubx}{b}{bx}{}
\DeclareFontSeriesChangeRule {ubx}{c}{ubc}{}
\DeclareFontSeriesChangeRule {ubx}{eb}{ebx}{}
\DeclareFontSeriesChangeRule {ubx}{ec}{ubec}{}
\DeclareFontSeriesChangeRule {ubx}{el}{elx}{}
\DeclareFontSeriesChangeRule {ubx}{l}{lx}{}
\DeclareFontSeriesChangeRule {ubx}{sb}{sbx}{}
\DeclareFontSeriesChangeRule {ubx}{sc}{ubsc}{}
\DeclareFontSeriesChangeRule {ubx}{sl}{slx}{}
\DeclareFontSeriesChangeRule {ubx}{ub}{ubx}{}
\DeclareFontSeriesChangeRule {ubx}{ul}{ulx}{}
\DeclareFontSeriesChangeRule {ubx}{x}{ubx}{}
%    \end{macrocode}
%
%    \begin{macrocode}
\DeclareFontSeriesChangeRule {ub}{c}{ubc}{}
\DeclareFontSeriesChangeRule {ub}{ec}{ubec}{}
\DeclareFontSeriesChangeRule {ub}{sc}{ubsc}{}
\DeclareFontSeriesChangeRule {ub}{x}{ubx}{}
%    \end{macrocode}
%
%    \begin{macrocode}
\DeclareFontSeriesChangeRule {ulc}{b}{bc}{}
\DeclareFontSeriesChangeRule {ulc}{c}{ulc}{}
\DeclareFontSeriesChangeRule {ulc}{eb}{ebc}{}
\DeclareFontSeriesChangeRule {ulc}{ec}{ulec}{ulc}
\DeclareFontSeriesChangeRule {ulc}{el}{elc}{}
\DeclareFontSeriesChangeRule {ulc}{l}{lc}{}
\DeclareFontSeriesChangeRule {ulc}{sb}{sbc}{}
\DeclareFontSeriesChangeRule {ulc}{sc}{ulsc}{ulc}
\DeclareFontSeriesChangeRule {ulc}{sl}{slc}{}
\DeclareFontSeriesChangeRule {ulc}{ub}{ubc}{}
\DeclareFontSeriesChangeRule {ulc}{ul}{ulc}{}
\DeclareFontSeriesChangeRule {ulc}{x}{ulx}{}
%    \end{macrocode}
%
%    \begin{macrocode}
\DeclareFontSeriesChangeRule {ulx}{b}{bx}{}
\DeclareFontSeriesChangeRule {ulx}{c}{ulc}{}
\DeclareFontSeriesChangeRule {ulx}{eb}{ebx}{}
\DeclareFontSeriesChangeRule {ulx}{ec}{ulec}{}
\DeclareFontSeriesChangeRule {ulx}{el}{elx}{}
\DeclareFontSeriesChangeRule {ulx}{l}{lx}{}
\DeclareFontSeriesChangeRule {ulx}{sb}{sbx}{}
\DeclareFontSeriesChangeRule {ulx}{sc}{ulsc}{}
\DeclareFontSeriesChangeRule {ulx}{sl}{slx}{}
\DeclareFontSeriesChangeRule {ulx}{ub}{ubx}{}
\DeclareFontSeriesChangeRule {ulx}{ul}{ulx}{}
\DeclareFontSeriesChangeRule {ulx}{x}{ulx}{}
%    \end{macrocode}
%
%    \begin{macrocode}
\DeclareFontSeriesChangeRule {ul}{c}{ulc}{}
\DeclareFontSeriesChangeRule {ul}{ec}{ulec}{}
\DeclareFontSeriesChangeRule {ul}{sc}{ulsc}{}
\DeclareFontSeriesChangeRule {ul}{x}{ulx}{}
%    \end{macrocode}
%
%    \begin{macrocode}
\DeclareFontSeriesChangeRule {x}{b}{bx}{}
\DeclareFontSeriesChangeRule {x}{c}{c}{}
\DeclareFontSeriesChangeRule {x}{eb}{ebx}{}
\DeclareFontSeriesChangeRule {x}{ec}{ec}{}
\DeclareFontSeriesChangeRule {x}{el}{elx}{}
\DeclareFontSeriesChangeRule {x}{l}{lx}{}
\DeclareFontSeriesChangeRule {x}{sb}{sbx}{}
\DeclareFontSeriesChangeRule {x}{sc}{sc}{}
\DeclareFontSeriesChangeRule {x}{sl}{slx}{}
\DeclareFontSeriesChangeRule {x}{ub}{ubx}{}
\DeclareFontSeriesChangeRule {x}{ul}{ulx}{}
%    \end{macrocode}
%
%
%    Special rules for \texttt{lm} etc.\ aren't needed because if the
%    target \texttt{lm} is request it will used if there is no rule
%    and that id then reduced to \texttt{l}
%    automatically. Same for \texttt{mc} and friends. Only \texttt{?m}
%    and \texttt{m?} need rules.
%
%    So here are the special rules for \texttt{m?}:
%    \begin{macrocode}
\DeclareFontSeriesChangeRule {bc}{m?}{c}{}
\DeclareFontSeriesChangeRule {bec}{m?}{ec}{}
\DeclareFontSeriesChangeRule {bsc}{m?}{sc}{}
\DeclareFontSeriesChangeRule {bx}{m?}{x}{}
\DeclareFontSeriesChangeRule {b}{m?}{m}{}
\DeclareFontSeriesChangeRule {c}{m?}{c}{}
\DeclareFontSeriesChangeRule {ebc}{m?}{c}{}
\DeclareFontSeriesChangeRule {ebec}{m?}{ec}{}
\DeclareFontSeriesChangeRule {ebsc}{m?}{sc}{}
\DeclareFontSeriesChangeRule {ebx}{m?}{x}{}
\DeclareFontSeriesChangeRule {eb}{m?}{m}{}
\DeclareFontSeriesChangeRule {ec}{m?}{ec}{}
\DeclareFontSeriesChangeRule {elc}{m?}{c}{}
\DeclareFontSeriesChangeRule {elec}{m?}{ec}{}
\DeclareFontSeriesChangeRule {elsc}{m?}{sc}{}
\DeclareFontSeriesChangeRule {elx}{m?}{x}{}
\DeclareFontSeriesChangeRule {el}{m?}{m}{}
\DeclareFontSeriesChangeRule {lc}{m?}{c}{}
\DeclareFontSeriesChangeRule {lec}{m?}{ec}{}
\DeclareFontSeriesChangeRule {lsc}{m?}{sc}{}
\DeclareFontSeriesChangeRule {lx}{m?}{x}{}
\DeclareFontSeriesChangeRule {l}{m?}{m}{}
\DeclareFontSeriesChangeRule {m}{m?}{m}{}
\DeclareFontSeriesChangeRule {sbc}{m?}{c}{}
\DeclareFontSeriesChangeRule {sbec}{m?}{ec}{}
\DeclareFontSeriesChangeRule {sbsc}{m?}{sc}{}
\DeclareFontSeriesChangeRule {sbx}{m?}{x}{}
\DeclareFontSeriesChangeRule {sb}{m?}{m}{}
\DeclareFontSeriesChangeRule {sc}{m?}{sc}{}
\DeclareFontSeriesChangeRule {slc}{m?}{c}{}
\DeclareFontSeriesChangeRule {slec}{m?}{ec}{}
\DeclareFontSeriesChangeRule {slsc}{m?}{sc}{}
\DeclareFontSeriesChangeRule {slx}{m?}{x}{}
\DeclareFontSeriesChangeRule {sl}{m?}{m}{}
\DeclareFontSeriesChangeRule {ubc}{m?}{c}{}
\DeclareFontSeriesChangeRule {ubec}{m?}{ec}{}
\DeclareFontSeriesChangeRule {ubsc}{m?}{sc}{}
\DeclareFontSeriesChangeRule {ubx}{m?}{x}{}
\DeclareFontSeriesChangeRule {ub}{m?}{ub}{}
\DeclareFontSeriesChangeRule {ulc}{m?}{c}{}
\DeclareFontSeriesChangeRule {ulec}{m?}{ec}{}
\DeclareFontSeriesChangeRule {ulsc}{m?}{sc}{}
\DeclareFontSeriesChangeRule {ulx}{m?}{x}{}
\DeclareFontSeriesChangeRule {ul}{m?}{m}{}
\DeclareFontSeriesChangeRule {x}{m?}{x}{}
%    \end{macrocode}
%
%    And there the special rules for \texttt{?m}:
%    \begin{macrocode}
\DeclareFontSeriesChangeRule {bc}{?m}{b}{}
\DeclareFontSeriesChangeRule {bec}{?m}{b}{}
\DeclareFontSeriesChangeRule {bsc}{?m}{b}{}
\DeclareFontSeriesChangeRule {bsc}{?m}{b}{}
\DeclareFontSeriesChangeRule {bx}{?m}{b}{}
\DeclareFontSeriesChangeRule {b}{?m}{b}{}
\DeclareFontSeriesChangeRule {c}{?m}{m}{}
\DeclareFontSeriesChangeRule {ebc}{?m}{eb}{}
\DeclareFontSeriesChangeRule {ebec}{?m}{eb}{}
\DeclareFontSeriesChangeRule {ebsc}{?m}{eb}{}
\DeclareFontSeriesChangeRule {ebsc}{?m}{eb}{}
\DeclareFontSeriesChangeRule {ebx}{?m}{eb}{}
\DeclareFontSeriesChangeRule {eb}{?m}{eb}{}
\DeclareFontSeriesChangeRule {ec}{?m}{m}{}
\DeclareFontSeriesChangeRule {elc}{?m}{el}{}
\DeclareFontSeriesChangeRule {elec}{?m}{el}{}
\DeclareFontSeriesChangeRule {elsc}{?m}{el}{}
\DeclareFontSeriesChangeRule {elsc}{?m}{el}{}
\DeclareFontSeriesChangeRule {elx}{?m}{el}{}
\DeclareFontSeriesChangeRule {el}{?m}{el}{}
\DeclareFontSeriesChangeRule {lc}{?m}{l}{}
\DeclareFontSeriesChangeRule {lec}{?m}{l}{}
\DeclareFontSeriesChangeRule {lsc}{?m}{l}{}
\DeclareFontSeriesChangeRule {lsc}{?m}{l}{}
\DeclareFontSeriesChangeRule {lx}{?m}{l}{}
\DeclareFontSeriesChangeRule {l}{?m}{l}{}
\DeclareFontSeriesChangeRule {m}{?m}{m}{}
\DeclareFontSeriesChangeRule {sbc}{?m}{sb}{}
\DeclareFontSeriesChangeRule {sbec}{?m}{sb}{}
\DeclareFontSeriesChangeRule {sbsc}{?m}{sb}{}
\DeclareFontSeriesChangeRule {sbsc}{?m}{sb}{}
\DeclareFontSeriesChangeRule {sbx}{?m}{sb}{}
\DeclareFontSeriesChangeRule {sb}{?m}{sb}{}
\DeclareFontSeriesChangeRule {sc}{?m}{m}{}
\DeclareFontSeriesChangeRule {sc}{?m}{m}{}
\DeclareFontSeriesChangeRule {slc}{?m}{sl}{}
\DeclareFontSeriesChangeRule {slec}{?m}{sl}{}
\DeclareFontSeriesChangeRule {slsc}{?m}{sl}{}
\DeclareFontSeriesChangeRule {slsc}{?m}{sl}{}
\DeclareFontSeriesChangeRule {slx}{?m}{sl}{}
\DeclareFontSeriesChangeRule {sl}{?m}{sl}{}
\DeclareFontSeriesChangeRule {ubc}{?m}{ub}{}
\DeclareFontSeriesChangeRule {ubec}{?m}{ub}{}
\DeclareFontSeriesChangeRule {ubsc}{?m}{ub}{}
\DeclareFontSeriesChangeRule {ubsc}{?m}{ub}{}
\DeclareFontSeriesChangeRule {ubx}{?m}{ub}{}
\DeclareFontSeriesChangeRule {ub}{?m}{m}{}
\DeclareFontSeriesChangeRule {ulc}{?m}{ul}{}
\DeclareFontSeriesChangeRule {ulec}{?m}{ul}{}
\DeclareFontSeriesChangeRule {ulsc}{?m}{ul}{}
\DeclareFontSeriesChangeRule {ulsc}{?m}{ul}{}
\DeclareFontSeriesChangeRule {ulx}{?m}{ul}{}
\DeclareFontSeriesChangeRule {ul}{?m}{ul}{}
\DeclareFontSeriesChangeRule {x}{?m}{m}{}
%    \end{macrocode}
%
%
% Supporting rollback \ldots
%    \begin{macrocode}
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{0000/00/00}%
%<latexrelease>   {\DeclareFontSeriesChangeRule}{Series change rules}%
%<latexrelease>
%<latexrelease>\let\DeclareFontSeriesChangeRule\@undefined
%<latexrelease>
%<latexrelease>\EndIncludeInRelease
%    \end{macrocode}
%
%
%
%
%
% \subsection{Changing to a new series}
%
%
%    \begin{macrocode}
%<*2ekernel|latexrelease>
%<latexrelease>\IncludeInRelease{2021/06/01}%
%<latexrelease>                 {\fontseries}{delay fontseries update}%
%    \end{macrocode}
%
%
%  \begin{macro}{\fontseries}
%    The \cs{fontseries} command takes one argument which is the requested new
%    font series. In the original implementation  it simply saved the
%    expanded value in \cs{f@series}. Now we do a bit more processing
%    and look up the final value in the font series data base. This is
%    done by \cs{merge@font@series}. But the lookup should be done
%    within the target family and call to \cs{fontseries} might be
%    followed by a \cs{fontfamily} call. So we delay the processing to
%    \cs{selectfont} and only record the necessary action in
%    \cs{delayed@f@adjustment}.
% \changes{v1.0c}{2020/02/10}{Switch \cs{if@forced@series} added}
% \changes{v1.0h}{2020/12/04}{Distangle series and shape update (gh/444)}
%    \begin{macrocode}
\DeclareRobustCommand\fontseries[1]{\@forced@seriesfalse
    \expandafter\def\expandafter\delayed@f@adjustment\expandafter
        {\delayed@f@adjustment\delayed@merge@font@series{#1}}}
%    \end{macrocode}
%  \end{macro}
%
%
%  \begin{macro}{\delayed@f@adjustment}
%    The macro holding the delayed action(s) for use in \cs{selectfont}.
%    \begin{macrocode}
\let\delayed@f@adjustment\@empty
%    \end{macrocode}
%  \end{macro}
%
%  \begin{macro}{\fontseriesforce}
%    To change unconditionally to a new series you can use
%    \cs{fontseriesforce}. Of course, if the series doesn't exist for
%    the current family substitution still happens, but there is not
%    dependency on the current series.
% \changes{v1.0c}{2020/02/10}{Switch \cs{if@forced@series} added}
%    \begin{macrocode}
\DeclareRobustCommand\fontseriesforce[1]{\@forced@seriestrue
    \expandafter\def\expandafter\delayed@f@adjustment\expandafter
      {\delayed@f@adjustment\edef\f@series{#1}}}
%    \end{macrocode}
%  \end{macro}
%
%
%
%  \begin{macro}{\if@forced@series}
%    If the series gets forced we need to know that fact later on.
% \changes{v1.0c}{2020/02/10}{Switch \cs{if@forced@series} added}
%    \begin{macrocode}
\newif\if@forced@series
%    \end{macrocode}
%  \end{macro}
%
%
%    \begin{macrocode}
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%    \end{macrocode}
%
%    \begin{macrocode}
%<latexrelease>\IncludeInRelease{2020/02/02}%
%<latexrelease>                 {\fontseries}{delay fontseries update}%
%<latexrelease>
%<latexrelease>\DeclareRobustCommand\fontseries[1]{\@forced@seriesfalse
%<latexrelease>                                    \merge@font@series{#1}}
%<latexrelease>\DeclareRobustCommand\fontseriesforce[1]{\@forced@seriestrue
%<latexrelease>                                         \edef\f@series{#1}}
%<latexrelease>\let\delayed@f@adjustment\@undefined
%<latexrelease>
%    \end{macrocode}
%    For a roll forward we may have to define \cs{if@forced@series}
%    but this needs doing in a way that \TeX{} doesn't see it when
%    skipping over conditionals.
% \changes{v1.0i}{2021/03/18}
%         {Fix rollforward definition.}
%    \begin{macrocode}
%<latexrelease>\expandafter\newif\csname if@forced@series\endcsname
%<latexrelease>
%<latexrelease>\EndIncludeInRelease
%    \end{macrocode}
%
%    \begin{macrocode}
%<latexrelease>\IncludeInRelease{0000/00/00}%
%<latexrelease>                 {\fontseries}{delay fontseries update}%
%<latexrelease>
%<latexrelease>\DeclareRobustCommand\fontseries[1]{\edef\f@series{#1}}
%<latexrelease>\let\fontseriesforce\@undefined
%<latexrelease>
%<latexrelease>\EndIncludeInRelease
%    \end{macrocode}
%
%
%
%    \begin{macrocode}
%<*2ekernel|latexrelease>
%<latexrelease>\IncludeInRelease{2020/02/02}%
%<latexrelease>   {\merge@font@series}{Merge series values}%
%    \end{macrocode}
%
%
%  \begin{macro}{\merge@font@series}
%    We look up the data base value by expanding the right command
%    twice. If no such value exist then the result will be \cs{relax}
%    otherwise it will be the two brace groups: the desired result and
%    the alternate result. The first case means that the third
%    argument to \cs{merge@font@series} will be empty.
%    \begin{macrocode}
\def\merge@font@series#1{%
  \expandafter\expandafter\expandafter
  \merge@font@series@
    \csname series@\f@series @#1\endcsname
    {#1}%
    \@nil
}
%    \end{macrocode}
%  \end{macro}
%
%
%
%  \begin{macro}{\merge@font@series@}
%    This now defines the new \cs{f@series}:
%    \begin{macrocode}
\def\merge@font@series@#1#2#3\@nil{%
%    \end{macrocode}
%    If the third argument is empty there is no database entry for the
%    combination and the second argument holds the new series so we
%    return that.
%
%    Originally the test was simply \verb=\ifx!#3!= but that actually
%    dies if \texttt{\#3} starts with a conditional and in the
%    definition of \cs{AmSfont} that is actually the case.
%    \begin{macrocode}
%\ifcat\expandafter X\detokenize{#1}X%
  \def\reserved@a{#3}%
  \ifx\reserved@a\@empty
    \set@target@series{#2}%
  \else
%    \end{macrocode}
%    Otherwise we check if the desired result for the series
%    (\texttt{\#1}) exists for the font family and the current shape.
%    All this happens inside \cs{selectfont} which has already taken care to load
%    the \texttt{.fd}, file if necessary.
%    \begin{macrocode}
    \edef\reserved@a{\f@encoding /\f@family /#1/\f@shape}%
     \ifcsname \reserved@a \endcsname
%    \end{macrocode}
%     If the desired result is available then we use that. However, we
%    do need some post-processing because we need to drop surplus
%    \texttt{m}s due to the way naming convention was designed in the
%    '90s (sigh).
%    \begin{macrocode}
       \set@target@series{#1}%
%    \end{macrocode}
%    If not, then we try the alternate result (\texttt{\#2}).
%    \begin{macrocode}
    \else
       \ifcsname \f@encoding /\f@family /#2/\f@shape \endcsname
%    \end{macrocode}
%    If the alternate result exist we use that and also issue a
%    warning (or rather a log entry) that we didn't managed to change
%    to the desired font.
%    \begin{macrocode}
         \set@target@series{#2}%
         \@font@shape@subst@warning
%    \end{macrocode}
%    If that doesn't exist either, then we use the requested series unmodified
%    (again with a warning).
%    \begin{macrocode}
       \else
         \set@target@series{#3}%
         \@font@shape@subst@warning
       \fi
    \fi
  \fi
}
%    \end{macrocode}
%    It is possible that the previous font and the new one are
%    actually identical (and the font was not found because it still
%    needs loading) in which case a warning would look rather odd. So
%    we make a quick check for that (which is the reason why we
%    defined \cs{@reserveda} above instead of doing inline testing
%    inside \cs{ifcsname}).
%    \begin{macrocode}
\def\@font@shape@subst@warning{%
   \edef\reserved@b{\curr@fontshape}%
   \ifx\reserved@a\reserved@b \else
     \@font@warning{Font shape `\reserved@a' undefined\MessageBreak
                    using `\reserved@b' instead}%
   \fi
}
%    \end{macrocode}
%  \end{macro}
%
%
%
%  \begin{macro}{\merge@font@series@without@substitution,
%                \merge@font@series@without@substitution@,
%                \delayed@merge@font@series}
%
% \changes{v1.0h}{2020/12/22}{Distangle series and shape update (gh/444)}
%
%    \cs{merge@font@series@without@substitution} works like
%    \cs{merge@font@series}, i.e., it looks up the combination in the
%    rule base and if there exists an entry it uses it and if not it
%    uses the new series value. However, it doesn't check if there is
%    actually a font face with the new series value as
%    \cs{merge@font@series} does. This simplified command is used in
%    \cs{selectfont} at a point where other font attributes are not
%    yet updated so that checking the font face might result incorrect
%    in substitutions.
%
%    \begin{macrocode}
\def\merge@font@series@without@substitution#1{%
  \expandafter\expandafter\expandafter
  \merge@font@series@without@substitution@
    \csname series@\f@series @#1\endcsname
    {#1}%
    \@nil
}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\merge@font@series@without@substitution@#1#2#3\@nil{%
  \def\reserved@a{#3}%
  \ifx\reserved@a\@empty
    \set@target@series{#2}%
  \else
    \set@target@series{#1}%
  \fi
}
%    \end{macrocode}
%  \end{macro}
%
%
%
%  \begin{macro}{\delayed@merge@font@series}
%
%    When we delay the merge action in \cs{fontseries} we first
%    attempt to use merging without substitution. If that results in a
%    non-existing font face the merge is redone in \cs{selectfont}
%    using a version with substitution. See \cs{selectfont} for details.
%
% \changes{v1.0h}{2020/12/22}{Distangle series and shape update
%    (gh/444)}
%    \begin{macrocode}
\let\delayed@merge@font@series\merge@font@series@without@substitution
%    \end{macrocode}
%  \end{macro}
%
%  \begin{macro}{\maybe@load@fontshape}
%    A small helper that we use a couple of times: try loading a
%    fontshape (in a group because \cs{try@load@fontshape} normalizes
%    catcodes and we also want to change \cs{typeout} so that it
%    doesn't report missing \texttt{.fd} files on the terminal).
%    \begin{macrocode}
\def\maybe@load@fontshape{%
  \begingroup
    \let \typeout \@font@info
    \try@load@fontshape
  \endgroup}
%    \end{macrocode}
%  \end{macro}
%
%
%
%  \begin{macro}{\set@target@series}
%
%    Finally the code for normalizing the \cs{f@series} value.
%
%    The combined series value determined by the mapping may still
%    contain an \texttt{m} that we have to remove (as the \texttt{.fd}
%    files use \texttt{c} not \texttt{mc} to denote a medium weight
%    condensed series, etc.). We do this in all branches above because a user
%    might have written
%\begin{verbatim}
%    \DeclareFontSeriesChangeRule {m}{sc}{msc}{mc}
%\end{verbatim}
%    instead of using \texttt{sc} and \texttt{c} as needed in the
%    \texttt{.fd} file.
%    \begin{macrocode}
\def\set@target@series#1{%
%    \end{macrocode}
%    We need to \cs{edef} the argument first in case it starts with a
%    conditional. Then we check (and perhaps drop) an ``m'' from the
%    value and assign the result to \cs{f@series}.
% \changes{v1.0d}{2020/02/27}{Drop ``m'' only in a specific set of values (gh/293)}
%    \begin{macrocode}
    \edef\f@series{#1}%
    \series@maybe@drop@one@m\f@series\f@series
}
%    \end{macrocode}
%  \end{macro}
%    
%  \begin{macro}{\series@maybe@drop@one@m}
%    If the series value is in NFSS notation then it should not
%    contain any ``m'' unless it is just an ``m'' by it own. So we
%    need to drop surplus ``m''s. But we better don't do this for full
%    names, such as ``\texttt{semibold}'' as used by
%    \texttt{autoinst}, for example. So we test against the possible
%    explicit values that should drop an ``m''.
%    After that we assign the result to \verb=#2= for further use.
% \changes{v1.0d}{2020/02/27}{Drop ``m'' in certain values from a
%    fixed list (gh/293)}
%    \begin{macrocode}
\def\series@maybe@drop@one@m#1{%
  \expandafter\series@maybe@drop@one@m@x\expandafter{#1}}
%    \end{macrocode}
%    
%    \begin{macrocode}

\def\series@maybe@drop@one@m@x#1#2{%
%    \end{macrocode}
%    The code below is an inline version of the \cs{in@} macro without
%    the group, so that it works in \cs{accent}.
%    \begin{macrocode}
  \def\in@@##1,#1,{}%
  \series@check@toks\expandafter{\in@@
    ,ulm,elm,lm,slm,mm,sbm,bm,ebm,ubm,muc,mec,mc,msc,msx,mx,mex,mux,{}{},#1,}%
  \edef\in@@{\the\series@check@toks}%
  \ifx\in@@\@empty
%    \end{macrocode}
%    The default definition for \cs{bfdefault} etc is actually
%    \texttt{b\cs{@empty}} so that we can detect if the user has
%    changed the default. However that means a) the above test will
%    definitely fail (maybe something to change) and b) we better use
%    \cs{edef} on the next line to get rid of it as otherwise the test
%    against \verb=#2= (e.g. \cs{bfdef@ult}) will fail in other places.
% \changes{v1.0e}{2020/05/19}{Need to use \cs{edef} (gh/336)}
%    \begin{macrocode}
    \edef#2{#1}%
  \else
    \edef#2{\expandafter\series@drop@one@m #1m\series@drop@one@m}%
  \fi
}
%    \end{macrocode}
%    As a precaution we use a private toks register not \cs{toks@} as
%    that is no longer hidden inside the group.
%    \begin{macrocode}
\newtoks\series@check@toks
%    \end{macrocode}
%  \end{macro}
%
%  \begin{macro}{\series@drop@one@m}
%    Drop up to two \texttt{m}s but keep one if that makes the series
%    value empty. Actually, with the current implementation we know
%    that there is at least one in the series value itself and we
%    added one after it, so all we have to do is now returning
%    \verb=#1#2= and dropping the rest.
%    \begin{macrocode}
\def\series@drop@one@m#1m#2m#3\series@drop@one@m{%
%  \ifx\relax#1#2\relax m\else#1#2\fi
   #1#2%
}
%    \end{macrocode}
%  \end{macro}
%
%
%
% Supporting rollback \ldots
%    \begin{macrocode}
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{0000/00/00}%
%<latexrelease>   {\merge@font@series}{Merge series values}%
%<latexrelease>
%<latexrelease>\let\merge@font@series\@undefined
%<latexrelease>\let\merge@font@series@\@undefined
%<latexrelease>\let\@font@shape@subst@warning\@undefined
%<latexrelease>\let\merge@font@series@without@substitution\@undefined
%<latexrelease>\let\merge@font@series@without@substitution@\@undefined
%<latexrelease>\let\delayed@merge@font@series\@undefined
%<latexrelease>\let\maybe@load@fontshape\@undefined
%<latexrelease>\let\set@target@series\@undefined
%<latexrelease>\let\series@maybe@drop@one@m\@undefined
%<latexrelease>\let\series@drop@one@m\@undefined
%<latexrelease>
%<latexrelease>\EndIncludeInRelease
%    \end{macrocode}




% \section{Changing the shape}
%
%    Shapes are also split in two axes (though it could be more if
%    that is desirable), essentially building in an ``sc''
%    axis.
%
%    \begin{macrocode}
%<*2ekernel|latexrelease>
%<latexrelease>\IncludeInRelease{2020/02/02}%
%<latexrelease>   {\DeclareFontShapeChangeRule}{Font shape change rules}%
%    \end{macrocode}
%
%
%
%  \begin{macro}{\DeclareFontShapeChangeRule}
%    The database for shapes is done in exactly the same way, only
%    that it is much smaller and we usually have no alternative shape
%    (or rather it is empty thus not used).
%    \begin{macrocode}
\def\DeclareFontShapeChangeRule #1#2#3#4{%
  \@namedef{shape@#1@#2}{{#3}{#4}}}
%    \end{macrocode}
%  \end{macro}
%
%
%    There is kind of the same problem with returning back from
%    \texttt{sc} to normal. It sort of needs its own letter.  In
%    \texttt{fontspec} this was solved by the first time \cs{upshape} changes
%    \texttt{it} or \texttt{sl} back (so only \texttt{sc} remains) and
%    second time it changes then \texttt{sc} back to normal.  Maybe
%    that's not a bad way to handle it, but decided for a slightly
%    different approach: \texttt{n} always returns to ``normal'', ie
%    resets everything and \texttt{up} changes italic or slanted to
%    upright and \texttt{ulc} undoes small caps.
%
%    So we now offer \cs{normalshape} (using \cs{shapedefault}) which
%    is normally the same as calling both \cs{ulcshape} and
%    \cs{upshape}, only more efficient.
%
%
%  \begin{macro}{\ulcshape}
%  \begin{macro}{\textulc}
%  \begin{macro}{\ulcdefault}
%    To request going back to upper/lowercase we need a new
%    command. It uses \texttt{ulc} as shape name but this shape is
%    virtual, i.e., it doesn't exist as a real shape, it is only used
%    as part of the database table entries and thus only appears in
%    the second argument there (but not in the first).
%    \begin{macrocode}
\DeclareRobustCommand\ulcshape
        {\not@math@alphabet\ulcshape\relax
         \fontshape\ulcdefault\selectfont}
\let\ulcdefault\@undefined      % for rollback
\newcommand\ulcdefault{ulc}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%
%  \begin{macro}{\swshape}
%  \begin{macro}{\textsw}
%  \begin{macro}{\swdefault}
%    New command to select a swash shape.  The standard rules put this
%    in the same category as italics or slanted, i.e., if you ask for
%    it then italics are undone. One could provide more complicated
%    rules so that \texttt{it} + \texttt{sw} becomes \texttt{swit} but
%    given that there are only very few fonts that have swash letters
%    that level of flexibility (these days) would be just resulting in
%    a lot of combinations that do not exist.
%    \begin{macrocode}
\DeclareRobustCommand\swshape
        {\not@math@alphabet\swshape\relax
         \fontshape\swdefault\selectfont}
\let\swdefault\@undefined      % for rollback
\newcommand\swdefault{sw}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%
%
%
%  \begin{macro}{\sscshape}
%  \begin{macro}{\textssc}
%  \begin{macro}{\sscdefault}
%    New command to select spaced small capitals. This is only here
%    because \texttt{fontaxes} offered it. There isn't a single free
%    font that supports it. However, some commercial ones do, so we
%    offer it so that at some point \texttt{fontaxes} could be
%    retired.
%
%    So far there aren't any rules for it---probably there should be
%    some putting it in the same category as \texttt{sc}.
%    \begin{macrocode}
\DeclareRobustCommand\sscshape
        {\not@math@alphabet\sscshape\relax
         \fontshape\sscdefault\selectfont}
\let\sscdefault\@undefined      % for rollback
\newcommand\sscdefault{ssc}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%
%
%
% \subsection{Mapping rules for shape combinations}
%
%    Many of the entries are commented out as we will get that result
%    without any entry.
%    \begin{macrocode}
%\DeclareFontShapeChangeRule {n}{n}   {n}   {}
\DeclareFontShapeChangeRule {n}{it}  {it}  {sl}
\DeclareFontShapeChangeRule {n}{sl}  {sl}  {it}
%\DeclareFontShapeChangeRule {n}{sw}  {sw}  {}
%\DeclareFontShapeChangeRule {n}{sc}  {sc}  {}
\DeclareFontShapeChangeRule {n}{ulc} {n}   {}
\DeclareFontShapeChangeRule {n}{up} {n}    {}
%    \end{macrocode}
%
%    \begin{macrocode}
%\DeclareFontShapeChangeRule {it}{n}   {n}     {}
%\DeclareFontShapeChangeRule {it}{it}  {it}    {}
\DeclareFontShapeChangeRule {it}{sl}  {sl}    {it}
%\DeclareFontShapeChangeRule {it}{sw}  {sw}    {}
%    \end{macrocode}
%    If neither \texttt{scit} nor \texttt{scsl} exist then \texttt{sc}
%    will be used as a fallback albeit with a log entry, so except for
%    the latter there will be no change for CM or Latin Modern fonts.
%    \begin{macrocode}
\DeclareFontShapeChangeRule {it}{sc}  {scit}  {scsl}
\DeclareFontShapeChangeRule {it}{ulc} {it}    {}
\DeclareFontShapeChangeRule {it}{up} {n}      {}
%    \end{macrocode}
%
%    \begin{macrocode}
%\DeclareFontShapeChangeRule {sl}{n}   {n}     {}
\DeclareFontShapeChangeRule {sl}{it}  {it}    {sl}
%\DeclareFontShapeChangeRule {sl}{sl}  {sl}    {}
%\DeclareFontShapeChangeRule {sl}{sw}  {sw}    {}
\DeclareFontShapeChangeRule {sl}{sc}  {scsl}  {scit}
\DeclareFontShapeChangeRule {sl}{ulc} {sl}    {}
\DeclareFontShapeChangeRule {sl}{up} {n}      {}
%    \end{macrocode}
%
%    \begin{macrocode}
%\DeclareFontShapeChangeRule {sc}{n}   {n}     {}
\DeclareFontShapeChangeRule {sc}{it}  {scit}  {scsl}
\DeclareFontShapeChangeRule {sc}{sl}  {scsl}  {scit}
\DeclareFontShapeChangeRule {sc}{sw}  {scsw}  {sw}
%\DeclareFontShapeChangeRule {sc}{sc}  {sc}    {}
\DeclareFontShapeChangeRule {sc}{ulc} {n}     {}
%    \end{macrocode}
%
%    The next rule might be a bit surprising and rightly so. Correct
%    would be that \texttt{sc} is not affected by \texttt{up}, i.e.,
%    remains \texttt{sc} as showed in the commented out rule. However,
%    for nearly three decades commands such as \cs{sc} or
%    \cs{textup} changed small caps back to the ``normal'' shape. So
%    for backward compatibility we keep that behavior.
%
%    As a result you are currently typesetting in \texttt{scit} or
%    \texttt{scsl} using \cs{upshape} twice will return you to the
%    normal shape too, the first will change to \texttt{sc} and the
%    second (because of the rule below) change that to
%    \texttt{n}. This is the way \texttt{fontspec} implemented its
%    version on this interface, so this rule means we are also
%    compatible with the way \texttt{fontspec} behaved. Still it
%    remains an oddity which I would rather liked to have avoided.
%    \begin{macrocode}
%\DeclareFontShapeChangeRule {sc}{up} {sc}     {}
\DeclareFontShapeChangeRule {sc}{up} {n}     {}
%    \end{macrocode}
%
%    \begin{macrocode}
%\DeclareFontShapeChangeRule {scit}{n}   {n}    {}
\DeclareFontShapeChangeRule {scit}{it}  {scit}  {}
\DeclareFontShapeChangeRule {scit}{sl}  {scsl}  {scit}
\DeclareFontShapeChangeRule {scit}{sw}  {scsw}  {sc}    % or scit?
\DeclareFontShapeChangeRule {scit}{sc}  {scit}  {}
\DeclareFontShapeChangeRule {scit}{ulc} {it}    {}
\DeclareFontShapeChangeRule {scit}{up} {sc}     {}
%    \end{macrocode}
%    The previous rule assumes that if \texttt{scit} exists then
%    \texttt{it} exists as well. If not, the mechanism will save
%    \texttt{ulc} in \cs{f@series} which most certainly doesn't
%    exist. So when a font is later selected that would result in a
%    substitution (so no harm done really). Alternatively, we could in
%    this case use \texttt{n} as alternative, which may be a bit
%    faster, but such a  setup would be so weird in the first place
%    that this isn't worth the effort.
%
%    \begin{macrocode}
%\DeclareFontShapeChangeRule {scsl}{n}   {n}     {}
\DeclareFontShapeChangeRule {scsl}{it}  {scit}  {scsl}
\DeclareFontShapeChangeRule {scsl}{sl}  {scsl}  {}
\DeclareFontShapeChangeRule {scsl}{sw}  {scsw}  {sc}    % or scsl?
\DeclareFontShapeChangeRule {scsl}{sc}  {scsl}  {}
\DeclareFontShapeChangeRule {scsl}{ulc} {sl}    {}
\DeclareFontShapeChangeRule {scsl}{up}   {sc}   {}
%    \end{macrocode}
%
%    \begin{macrocode}
%\DeclareFontShapeChangeRule {scsw}{n}   {n}     {}
\DeclareFontShapeChangeRule {scsw}{it}  {scit}  {scsw}
\DeclareFontShapeChangeRule {scsw}{sl}  {scsl}  {}
\DeclareFontShapeChangeRule {scsw}{sw}  {scsw}  {}
\DeclareFontShapeChangeRule {scsw}{sc}  {scsw}  {}
\DeclareFontShapeChangeRule {scsw}{ulc} {sw}    {}
\DeclareFontShapeChangeRule {scsw}{up} {sc}     {}
%    \end{macrocode}
%
%    \begin{macrocode}
%\DeclareFontShapeChangeRule {sw}{n}   {n}     {}
%\DeclareFontShapeChangeRule {sw}{it}  {it}    {}
%\DeclareFontShapeChangeRule {sw}{sl}  {sl}    {}
%\DeclareFontShapeChangeRule {sw}{sw}  {sw}    {}
\DeclareFontShapeChangeRule {sw}{sc}  {scsw}  {}
\DeclareFontShapeChangeRule {sw}{ulc} {sw}    {}
\DeclareFontShapeChangeRule {sw}{up} {n}      {}
%    \end{macrocode}
%
% Supporting rollback \ldots
%    \begin{macrocode}
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{0000/00/00}%
%<latexrelease>   {\DeclareFontShapeChangeRule}{Font shape change rules}%
%<latexrelease>
%<latexrelease>\let\DeclareFontShapeChangeRule\@undefined
%<latexrelease>\let\ulcshape\@undefined
%<latexrelease>\let\ulcdefault\@undefined
%<latexrelease>\let\swshape\@undefined
%<latexrelease>\let\swdefault\@undefined
%<latexrelease>\let\sscshape\@undefined
%<latexrelease>\let\sscdefault\@undefined
%<latexrelease>
%<latexrelease>\EndIncludeInRelease
%    \end{macrocode}
%
%
% \subsection{Changing to a new shape}
%
%
%    \begin{macrocode}
%<*2ekernel|latexrelease>
%<latexrelease>\IncludeInRelease{2021/06/01}%
%<latexrelease>   {\fontshape}{Font shape change}%
%    \end{macrocode}
%
%
%
%  \begin{macro}{\fontshape}
%    Again the \cs{fontshape} now has to do a lookup to get to its new
%    value in \cs{f@shape}. The method is exactly the same as in
%    \cs{fontseries}.
% \changes{v1.0h}{2020/12/04}{Distangle series and shape update (gh/444)}
%    \begin{macrocode}
\DeclareRobustCommand\fontshape[1]
   {\expandafter\def\expandafter\delayed@f@adjustment\expandafter
        {\delayed@f@adjustment\delayed@merge@font@shape{#1}}}
%    \end{macrocode}
%  \end{macro}
%
%
%  \begin{macro}{\fontshapeforce}
%    The unconditional version:
%
% \changes{v1.0h}{2020/12/04}{Distangle series and shape update (gh/444)}
%    \begin{macrocode}
\DeclareRobustCommand\fontshapeforce[1]
   {\expandafter\def\expandafter\delayed@f@adjustment\expandafter
        {\delayed@f@adjustment\edef\f@shape{#1}}}
%    \end{macrocode}
%  \end{macro}
%
%
% Supporting rollback \ldots
%    \begin{macrocode}
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{2020/02/02}%
%<latexrelease>   {\fontshape}{Font shape change}%
%<latexrelease>
%<latexrelease>\DeclareRobustCommand\fontshape[1]{\merge@font@shape{#1}}
%<latexrelease>\DeclareRobustCommand\fontshapeforce[1]{\edef\f@shape{#1}}
%<latexrelease>
%<latexrelease>\EndIncludeInRelease
%    \end{macrocode}
%
%    \begin{macrocode}
%<latexrelease>\IncludeInRelease{0000/00/00}%
%<latexrelease>   {\fontshape}{Font shape change}%
%<latexrelease>
%<latexrelease>\DeclareRobustCommand\fontshape [1]{\edef\f@shape{#1}}
%<latexrelease>\let\fontshapeforce\@undefined
%<latexrelease>
%<latexrelease>\EndIncludeInRelease
%    \end{macrocode}
%





%    \begin{macrocode}
%<*2ekernel|latexrelease>
%<latexrelease>\IncludeInRelease{2020/02/02}%
%<latexrelease>   {\merge@font@shape}{Font shape change rules}%
%    \end{macrocode}
%
%
%
%  \begin{macro}{\merge@font@shape}
%    Look up the database entry (if existing) and act accordingly.
%    \begin{macrocode}
\def\merge@font@shape#1{%
  \expandafter\expandafter\expandafter
  \merge@font@shape@
    \csname shape@\f@shape @#1\endcsname
    {#1}%
    \@nil
}
%    \end{macrocode}
%  \end{macro}
%

%  \begin{macro}{\merge@font@shape@}
%    Same game now, except that we look at shapes not series values
%    and we can set the shape without the complication of dropping
%    ``m''s from the name as we had to for the series.
%    \begin{macrocode}
\def\merge@font@shape@#1#2#3\@nil{%
  \def\reserved@a{#3}%
  \ifx\reserved@a\@empty
    \edef\f@shape{#2}%
  \else
%    \end{macrocode}
%    \cs{reserved@a} is used in \cs{@font@shape@subst@warning} so we
%    have to define it in addition to do the \cs{ifcsname} test
%    \begin{macrocode}
    \edef\reserved@a{\f@encoding /\f@family /\f@series/#1}%
    \ifcsname \reserved@a\endcsname
       \edef\f@shape{#1}%
    \else
       \ifcsname \f@encoding /\f@family /\f@series/#2\endcsname
         \edef\f@shape{#2}%
         \@font@shape@subst@warning
       \else
         \edef\f@shape{#3}%
         \@font@shape@subst@warning
       \fi
    \fi
  \fi
}
%    \end{macrocode}
%  \end{macro}
%
%
%  \begin{macro}{\merge@font@shape@without@substitution,
%                \merge@font@shape@without@substitution@,
%                \delayed@merge@font@shape}
%    See definition of \cs{selectfont} for how these macros are used.
% \changes{v1.0h}{2020/12/22}{Distangle series and shape update (gh/444)}
%    \begin{macrocode}
\def\merge@font@shape@without@substitution#1{%
  \expandafter\expandafter\expandafter
  \merge@font@shape@without@substitution@
    \csname shape@\f@shape @#1\endcsname
    {#1}%
    \@nil
}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\merge@font@shape@without@substitution@#1#2#3\@nil{%
  \def\reserved@a{#3}%
  \ifx\reserved@a\@empty
    \edef\f@shape{#2}%
  \else
    \edef\f@shape{#1}%
  \fi
}
%    \end{macrocode}
%    
%    \begin{macrocode}
\let\delayed@merge@font@shape\merge@font@shape@without@substitution
%    \end{macrocode}
%  \end{macro}
%
%
%
%  \begin{macro}{\normalshape}
%
%    \cs{normalshape} resets both sub-axes if the default rules are used.
%    \begin{macrocode}
\protected\def\normalshape
    {\not@math@alphabet\normalshape\relax
      \fontshape\shapedefault\selectfont}%
%    \end{macrocode}
%  \end{macro}
%
%
%
%
% \section{Make sure we win \ldots}
%
%    This code implements one aspect of what the package \textsf{fontaxes}
%    provide. So its redefinitions for the various shape commands,
%    such as \cs{itshape} should no longer happen. We therefore force
%    the standard definitions at \cs{AtBeginDocument} (later when this
%    is defined). Once
%    \texttt{fontaxes} is no longer doing such redefinitions that could
%    be taken out again.
%
%    We use a separate macro so that we can easily disable this (in
%    case of rollback).
%
%  \begin{macro}{\reinstall@nfss@defs}
%
%    I use \cs{protected} here not \cs{DeclareRobustCommand} to avoid
%    extra status lines.
%    \begin{macrocode}
\def\reinstall@nfss@defs{%
  \protected\def\upshape
          {\not@math@alphabet\upshape\relax
           \fontshape\updefault\selectfont}%
  \protected\def\slshape
          {\not@math@alphabet\slshape\relax
           \fontshape\sldefault\selectfont}%
  \protected\def\scshape
          {\not@math@alphabet\scshape\relax
           \fontshape\scdefault\selectfont}%
  \protected\def\itshape
          {\not@math@alphabet\itshape\mathit
           \fontshape\itdefault\selectfont}%
  \protected\def\ulcshape
          {\not@math@alphabet\ulcshape\relax
           \fontshape{ulc}\selectfont}%
  \protected\def\swshape
          {\not@math@alphabet\swshape\relax
           \fontshape\swdefault\selectfont}%
  \protected\def\sscshape
          {\not@math@alphabet\sscshape\relax
           \fontshape\sscdefault\selectfont}%
}
%    \end{macrocode}
%  \end{macro}
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Supporting rollback \ldots
%    \begin{macrocode}
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{0000/00/00}%
%<latexrelease>   {\merge@font@shape}{Font shape change rules}%
%<latexrelease>
%<latexrelease>\DeclareRobustCommand\fontshape [1]{\edef\f@shape{#1}}
%<latexrelease>\let\fontshapeforce\@undefined
%<latexrelease>
%<latexrelease>\let\merge@font@shape\@undefined
%<latexrelease>\let\merge@font@shape@\@undefined
%<latexrelease>
%<latexrelease>\let\merge@font@shape@without@substitution\@undefined
%<latexrelease>\let\merge@font@shape@without@substitution@\@undefined
%<latexrelease>\let\delayed@merge@font@shape\@undefined
%<latexrelease>
%<latexrelease>\let\normalshape\@undefined
%<latexrelease>
%    \end{macrocode}
%    This is always called in \cs{document} so don't make it undefined.
%    \begin{macrocode}
%<latexrelease>
%<latexrelease>\let\reinstall@nfss@defs\relax
%<latexrelease>\EndIncludeInRelease
%    \end{macrocode}
%
%
%
%    This initializes the 2020/02/02 extensions to NFSS after any changes
%    in the preamble. 
% \changes{v1.0g}{2020/08/21}{Integration of new hook management interface}
%    \begin{macrocode}
%<*2ekernel|latexrelease>
%<latexrelease>\IncludeInRelease{2020/10/01}%
%<latexrelease>                 {\reinstall@nfss@defs}{NFSS series init}%
\g@addto@macro\@kernel@after@begindocument@before
              {\reinstall@nfss@defs\init@series@setup}
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%    \end{macrocode}
%
%    The initialization was introduced in 2020/02/02 but 
%    \begin{macrocode}
%<latexrelease>\IncludeInRelease{2020/02/02}%
%<latexrelease>                 {\reinstall@nfss@defs}{NFSS series init}%
%<latexrelease>\AtBeginDocument{\reinstall@nfss@defs\init@series@setup}
%<latexrelease>\EndIncludeInRelease
%    \end{macrocode}
%
%    \begin{macrocode}
%<latexrelease>\IncludeInRelease{0000/00/00}%
%<latexrelease>                 {\reinstall@nfss@defs}{NFSS series init}%
%<latexrelease>\EndIncludeInRelease
%<*2ekernel>
%</2ekernel>
%    \end{macrocode}
%
% \Finale
%
