From b3225c4301e7724de481f410444fef5463799b9d Mon Sep 17 00:00:00 2001
From: Norbert Preining <norbert@preining.info>
Date: Tue, 14 Jan 2020 03:00:43 +0000
Subject: CTAN sync 202001140300

---
 macros/latex-dev/base/ltfssini.dtx | 940 ++++++++++++++++++++++++++++++++++---
 1 file changed, 882 insertions(+), 58 deletions(-)

(limited to 'macros/latex-dev/base/ltfssini.dtx')

diff --git a/macros/latex-dev/base/ltfssini.dtx b/macros/latex-dev/base/ltfssini.dtx
index b073a5cc37..e948aa4809 100644
--- a/macros/latex-dev/base/ltfssini.dtx
+++ b/macros/latex-dev/base/ltfssini.dtx
@@ -1,6 +1,6 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2019
+% Copyright (C) 1993-2020
 % The LaTeX3 Project and any individual authors listed elsewhere
 % in this file.
 %
@@ -36,7 +36,7 @@
 %
 %
 \ProvidesFile{ltfssini.dtx}
-             [2019/08/27 v3.1d LaTeX Kernel (NFSS Initialisation)]
+             [2020/01/11 v3.1f LaTeX Kernel (NFSS Initialisation)]
 % \iffalse
 \documentclass{ltxdoc}
 \begin{document}
@@ -157,26 +157,28 @@
 %    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}
+%\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\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}
@@ -195,30 +197,874 @@
 %    \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{2020/02/02}%
+%<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{DeclareSeriesDefault}. 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}
+\newcommand\DeclareFontSeriesDefault[3][]{%
+  \def\@reserveda{#1}%
+%    \end{macrocode}
+%    No optional argument: set up general default.
+%    \begin{macrocode}
+  \ifx\@resereda\@empty
+    \ifcsname #2series\endcsname           % supported are
+                                           % \[md/bf]default
+      \expandafter\def
+         \csname #2default\endcsname{#3}%                     
+    \else
+       \@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 first argument must be 'rm', 'sf', or 'tt'. \MessageBreak
+           Second argument must be 'md'  or 'bf'.}
+    \fi
+  \fi
+}
+%    \end{macrocode}
+%  \end{macro}
+
+
+
+
+%  \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}{\expand@font@defaults}
+%
+%    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}%
+  \edef\bfdef@ult{\bfdefault}%
+  \edef\mddef@ult{\mddefault}%
+  \edef\famdef@ult{\familydefault}%
+}
+%    \end{macrocode}
+%
+%  \end{macro}
+
+
+
+%  \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.
+%    \begin{macrocode}
+  \expand@font@defaults
+  \fontseries{%
+    \ifx\f@family\rmdef@ult      \bfseries@rm
+    \else\ifx\f@family\sfdef@ult \bfseries@sf
+    \else\ifx\f@family\ttdef@ult \bfseries@tt
+%    \end{macrocode}
+%    If not \cs{bfdefault} is used.
+%    \begin{macrocode}
+    \else                        \bfdefault
+    \fi\fi\fi
+  }%
+  \selectfont
+}
+%    \end{macrocode}
+%  \end{macro}
+
+
+
+%  \begin{macro}{\mdseries}
+%    This document command switches to the medium series.
+%    \begin{macrocode}
+\DeclareRobustCommand\mdseries{%
+  \not@math@alphabet\mdseries\relax
+  \expand@font@defaults
+  \fontseries{%
+    \ifx\f@family\rmdef@ult      \mdseries@rm
+    \else\ifx\f@family\sfdef@ult \mdseries@sf
+    \else\ifx\f@family\ttdef@ult \mdseries@tt
+    \else                        \mddefault
+    \fi\fi\fi
+  }%
+  \selectfont
+}
+%    \end{macrocode}
+%  \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 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 has different sets
+%    ofshapes available and we certainly don't want to see
+%    substituation 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}
+%    The comes the hook code (by default a no-op) and finally the call
+%    to \cs{selectfont}.
+%    \begin{macrocode}
+   \@rmfamilyhook
+   \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}
+%    \begin{macrocode}
+\DeclareRobustCommand\sffamily{%
+   \not@math@alphabet\sffamily\mathsf
+   \prepare@family@series@update{sf}\sfdefault
+   \@sffamilyhook
+   \selectfont}
+%    \end{macrocode}
+%
+% \changes{v3.1f}{2020/01/11}{Streamlined implementation with hook}
+%    \begin{macrocode}
+\DeclareRobustCommand\ttfamily{%
+   \not@math@alphabet\ttfamily\mathtt
+   \prepare@family@series@update{tt}\ttdefault
+   \@ttfamilyhook
+   \selectfont}
+%    \end{macrocode}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%
+%    
+%  \begin{macro}{\@rmfamilyhook}
+%  \begin{macro}{\@sffamilyhook}
+%  \begin{macro}{\@ttfamilyhook}
+%    By default the hooks do nothing.   
+%    \begin{macrocode}
+\let\@rmfamilyhook\@empty
+\let\@sffamilyhook\@empty
+\let\@ttfamilyhook\@empty
+%    \end{macrocode}
+%  \end{macro}
+%  \end{macro}
+%  \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{%
+   \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}
+%    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
+   \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
+   \else
+     \maybe@load@fontshape
+     \let\f@series\target@series@value
+   \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 reatedly 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\@reserveda{#1}%
+  \ifx\target@meta@family@value\@reserveda   % rm -> rm do nothing
+  \else
+%    \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\@reservedb
+                      \csname mdseries@\target@meta@family@value\endcsname
+      \expandafter\let\expandafter\@reservedc
+                      \csname bfseries@\target@meta@family@value\endcsname
+%    \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}
+      \expandafter\ifx\csname mdseries@#1\endcsname\f@series
+                                      \let\target@series@value\@reservedb
+      \else\expandafter\ifx\csname bfseries@#1\endcsname\f@series
+                                      \let\target@series@value\@reservedc
+      \else\ifx\f@series\mddef@ult    \let\target@series@value\@reservedb
+      \else\ifx\f@series\bfdef@ult    \let\target@series@value\@reservedc
+      \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 have to
+%    adjust the series defaults accordingly, before starting
+%    typesetting.
+%
+%    On the other hand if we still typeset in CM or LM then
+%    \cs{bfdefault} is wrong since it is now saying \texttt{b} and not
+%    \texttt{bx}.
+    
+%    To fix this we run \cs{rmfamily}, \cs{sffamily} or
+%    \cs{ttfamily} depending on the situation and this will correct
+%    the setup for us.
+%    \begin{macrocode}
+  \expand@font@defaults
+  \ifx\famdef@ult\rmdef@ult      \rmfamily
+  \else\ifx\famdef@ult\sfdef@ult \sffamily
+  \else\ifx\famdef@ult\ttdef@ult \ttfamily
+  \fi\fi\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>                 {\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>\let\expand@font@defaults\@undefined
+%<latexrelease>\expandafter\let\csname ver@mweights.sty\endcsname\@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>\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}
+       
+%
+%
+%
+% \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 ocssilate between
+%    italic and upright shapes.
+%
+%    Sometimes it would be nice to allow for a more lengthly 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 surious 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 like
+%    it was before if \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 exand
+%    \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}
-%</2ekernel>
-%<latexrelease>\IncludeInRelease{2015/01/01}{\eminnershape}{\eminnershape}%
-%<*2ekernel|latexrelease>
-\DeclareRobustCommand\em
-        {\@nomath\em \ifdim \fontdimen\@ne\font >\z@
-                       \eminnershape \else \itshape \fi}%
-%    \end{macrocode}
-%
-%    \begin{macrocode}
-\def\eminnershape{\upshape}%
-%</2ekernel|latexrelease>
+%<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>\IncludeInRelease{0000/00/00}{\eminnershape}{\eminnershape}%
+%<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}%
@@ -230,6 +1076,12 @@
 % \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
@@ -331,35 +1183,6 @@
 % \end{macro}
 %
 %
-%  \begin{macro}{\oldstylenums}
-%    This macro implements old style numerals but only works if we
-%    assume that the standard math fonts are used. Thus it needs
-%    changing in case other math encodings are used.
-%    \begin{macrocode}
-\DeclareRobustCommand\oldstylenums[1]{%
-   \begingroup
-%    \end{macrocode}
-%    Provide spacing using the interword space of the current font.
-%    \begin{macrocode}
-    \spaceskip\fontdimen\tw@\font
-%    \end{macrocode}
-%    Then switch to the math italic font. We don't change the current
-%    value of |\f@series| which means that you can use bold numerals
-%    if |\bfseries| is in force. As family we use |\rmdefault| which
-%    means that this only works if there exist an |OML| encoded
-%    version of that font or rather a corresponding |.fd| file (which
-%    is the case for standard \LaTeX{} fonts even though they only
-%    contain substitutions).
-% \changes{v3.0j}{1999/02/12}{Use \cs{rmdefault} instead of \texttt{cmm}
-%                 (pr/2954)}
-%    \begin{macrocode}
-    \usefont{OML}{\rmdefault}{\f@series}{it}%
-    \mathgroup\symletters #1%
-   \endgroup
-}
-%    \end{macrocode}
-%  \end{macro}
-%
 % \begin{macro}{\hexnumber@}
 %    To set up \LaTeX's special math character
 %    definitions we first provide a macro to generate hexadecimal
@@ -528,6 +1351,7 @@
 \let\@addtofilelist\@gobble
 %    \end{macrocode}
 %
+%
 % Ditto for math although I don't think that we will get a lot of
 % customisation :-)
 %    \begin{macrocode}
-- 
cgit v1.2.3

