% \iffalse meta-comment
%
% Copyright (C) 1997-2003 by Michael J. Downes
% Copyright (C) 2007-2008 by Morten Hoegholm
% Copyright (C) 2007-2014 by Lars Madsen
% Copyright (C) 2010-2017 by Joseph Wright
% Copyright (C) 2007-2019 by Will Robertson
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either
% version 1.3 of this license or (at your option) any later
% version. The latest version of this license is in
%    http://www.latex-project.org/lppl.txt
% and version 1.3 or later is part of all distributions of
% LaTeX version 2005/12/01 or later.
%
% This work has the LPPL maintenance status "maintained".
%
% The Current Maintainer of this work is Will Robertson.
%
% This work consists of the main source file mathstyle.dtx
% and the derived files
%    mathstyle.sty, mathstyle.pdf, mathstyle.ins, mathstyle.drv.
%
% Distribution:
%    CTAN:macros/latex/contrib/mh/mathstyle.dtx
%    CTAN:macros/latex/contrib/mh/mathstyle.pdf
%
% Unpacking:
%           tex breqnbundle.ins
%
% Documentation:
%    The class ltxdoc loads the configuration file ltxdoc.cfg
%    if available. Here you can specify further options, e.g.
%    use A4 as paper format:
%       \PassOptionsToClass{a4paper}{article}
%
%    Programm calls to get the documentation (example):
%       pdflatex mathstyle.dtx
%       makeindex -s gind.ist mathstyle.idx
%       pdflatex mathstyle.dtx
%       makeindex -s gind.ist mathstyle.idx
%       pdflatex mathstyle.dtx
%
% Installation:
%    TDS:tex/latex/breqn/mathstyle.sty
%    TDS:doc/latex/breqn/mathstyle.pdf
%    TDS:source/latex/breqn/mathstyle.dtx
%
%<*driver>
\documentclass{ltxdoc}
\providecommand*\pkg[1]{\textsf{#1}}
\begin{document}
  \DocInput{mathstyle.dtx}
\end{document}
%</driver>
% \fi
%
% \title{The \textsf{mathstyle} package}
% \def\fileversion{0.98j}
% \def\filedate{2020/04/19}
% \date{\filedate\quad\fileversion}
% \author{Authors: Michael J. Downes, Morten H\o gholm\\ Maintained by Morten H\o gholm, Will Robertson\\ Feedback: \texttt{https://github.com/wspr/breqn/issues}}
%
%
% \maketitle
%
% \part*{User's guide}
%
% This package exists for two reasons:
% \begin{itemize}
% \item The primitive operations for creating a super- or subscript in
%   \TeX\ work almost as if \verb|^| and \verb|_| are macros taking an
%   argument. However, that is not quite the case, and
%   some things that you'd expect to work don't (e.g., \verb|^\cong|)
%   whereas others which you'd think shouldn't work actually
%   do (such as |^\mathsf{s}|). We do everyone a favor if it behaves
%   consistently, i.e., if the superscript and subscript operations
%   act as if they are macros taking exactly one argument.
%
% \item Because the \TeX\ math typesetting engine uses infix notation
%   for fractions, one has to use \cs{mathchoice} or \cs{mathpalette}
%   whenever trying to do anything requiring boxing or measuring
%   math. This creates problems for loading fonts on demand as the
%   font loading mechanism has to load fonts for all styles without
%   even knowing if the font is going to be used. Getting the timing
%   of \cs{mathchoice} right can be tricky as well. Since \LaTeX\ does
%   not promote the primitive infix notation, this package keeps track
%   of a current mathstyle parameter.
% \end{itemize}
%
%
% \section{Some usage tips}
%
% If you want to use this package with \pkg{amsmath}, it is important
% \pkg{mathstyle} is loaded \emph{after} \pkg{amsmath}.
%
% The current mathstyle is stored in the variable \cs{mathstyle}. The
% command \cs{currentmathstyle} can be used to switch to the mode
% currently active. Below is shown how the macro \cs{mathrlap} from
% \pkg{mathtools} is implemented without knowing about the current
% mathstyle using \cs{mathpalette}.
% \begin{verbatim}
% \providecommand*\mathrlap[1][]{%
%   \ifx\@empty#1\@empty
%     \expandafter \mathpalette \expandafter \@mathrlap
%   \else
%     \expandafter \@mathrlap \expandafter #1%
%   \fi}
% \providecommand*\@mathrlap #1#2{{}\rlap{$\m@th#1{#2}$}}
% \end{verbatim}
% The same definition using \cs{currentmathstyle} from this package.
% \begin{verbatim}
% \providecommand*\mathrlap[2][]{%
%   #1 {}\rlap{$\m@th \currentmathstyle {#2}$}}
% \end{verbatim}
%
% \subsection{Package options}
%
% This package has one set of options affecting the \verb|_| and \verb|^| characters:
%
% \begin{itemize}
% \item\verb|\usepackage[mathactivechars]{mathstyle}|
%
% This is the default behaviour. Here, \verb|_| and \verb|^| are made into harmless
% characters in text mode and behave as expected (for entering sub/superscript) when
% inside math mode.
% Certain code that assumes the catcodes of these characters may get confused about
% this; see below for a possible fix.
%
% \item\verb|\usepackage[activechars]{mathstyle}|
%
% With this option, \verb|_| and \verb|^| are made into active characters for
% entering sub/superscript mode in all cases---therefore, in text mode they will
% produce a regular error (`Missing \$ inserted') indicating they are being used
% out of place.
%
% \item\verb|\usepackage[noactivechars]{mathstyle}|
%
% This is the option most like to solve any compatibility problems. Here,
% \verb|_| and \verb|^| retain their regular catcodes at all times and behave
% in their default fashion. \textbf{However}, certain other features of this
% package (such as \cs{currentmathstyle} inside a subscript) will then fail
% to work, so only use this option as a last resort.
% \end{itemize}
%
% \StopEventually{}
% \part*{Implementation}
%
%    \begin{macrocode}
%<*package>
\NeedsTeXFormat{LaTeX2e}
\RequirePackage{expl3}
\ProvidesExplPackage{mathstyle}{2020/04/19}{0.98j}{Tracking mathstyle implicitly}
\ExplSyntaxOff
%    \end{macrocode}
%
% \begin{macro}{\@saveprimitive}
%   A straight copy from \pkg{breqn}, see implementation details
%   there.  Of course, with a recent pdf\TeX\ (v1.40+), one can just
%   use \cs{primitive} to get the original. We will implement that
%   some day.
%    \begin{macrocode}
\providecommand\@saveprimitive[2]{%
  \begingroup
  \edef\@tempa{\string#1}\edef\@tempb{\meaning#1}%
  \ifx\@tempa\@tempb \global\let#2#1%
  \else
    \edef\@tempb{\meaning#2}%
    \ifx\@tempa\@tempb
    \else \@saveprimitive@a#1#2%
    \fi
  \fi
  \endgroup
}
\providecommand\@saveprimitive@a[2]{%
  \begingroup
  \def\@tempb##1#1##2{\edef\@tempb{##2}\@car{}}%
  \@tempb\nullfont{select font nullfont}%
    \topmark{\string\topmark:}%
    \firstmark{\string\firstmark:}%
    \botmark{\string\botmark:}%
    \splitfirstmark{\string\splitfirstmark:}%
    \splitbotmark{\string\splitbotmark:}%
    #1{\string#1}%
    \@nil % for the \@car
  \edef\@tempa{\expandafter\strip@prefix\meaning\@tempb}%
  \edef\@tempb{\meaning#1}%
  \ifx\@tempa\@tempb \global\let#2#1%
  \else
    \PackageError{mathstyle}%
      {Unable to properly define \string#2; primitive
      \noexpand#1no longer primitive}\@eha
    \fi
  \fi
  \endgroup
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\everydisplay}
% We need to keep track of whether we're in inline or display maths, and the only
% way to do that is to add a switch inside \verb|\everydisplay|.
% We act sensibly and preserve any of the previous contents of that token register
% before adding our own code here. As we'll see in a second, Lua\TeX{}
% provides a native mechanism for this so we don't need any action in that
% case. (Various other parts of the code also need to have different paths
% for Lua\TeX{} use.)
%    \begin{macrocode}
\begingroup\expandafter\expandafter\expandafter\endgroup
\expandafter\ifx\csname directlua\endcsname\relax
  \everydisplay=\expandafter{\the\everydisplay\chardef\mathstyle\z@}
\fi
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\mathstyle}
% \begin{macro}{\mathstyledenom}
% A counter for the math style: 0--display, 2--text, 4--script, 6--scriptscript.
% The logic is that display maths will explicitly
% set \verb|\mathstyle| to zero (see above), so by default it is set to the
% `text' maths style.  With Lua\TeX{} there is a primitive to do the same
% so it just has to be enabled. Note that in all cases we use Lua\TeX{}-like
% numbering for the states.
%    \begin{macrocode}
\begingroup\expandafter\expandafter\expandafter\endgroup
\expandafter\ifx\csname directlua\endcsname\relax
  \chardef\mathstyle=2\relax
  \chardef\mathstyledenom=0\relax
\else
  \directlua{tex.enableprimitives("", {"mathstyle"})}
\fi
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% Save the four style changing primitives, \cs{mathchoice} and the
% fraction commands.
%    \begin{macrocode}
\@saveprimitive\displaystyle\@@displaystyle
\@saveprimitive\textstyle\@@textstyle
\@saveprimitive\scriptstyle\@@scriptstyle
\@saveprimitive\scriptscriptstyle\@@scriptscriptstyle
\@saveprimitive\mathchoice\@@mathchoice
\@saveprimitive\over\@@over
\@saveprimitive\atop\@@atop
\@saveprimitive\above\@@above
\@saveprimitive\overwithdelims\@@overwithdelims
\@saveprimitive\atopwithdelims\@@atopwithdelims
\@saveprimitive\abovewithdelims\@@abovewithdelims
%    \end{macrocode}
% Then we redeclare the four style changing primitives: set the value of
% \cs{mathstyle} if Lua\TeX{} is not in use.
%    \begin{macrocode}
\begingroup\expandafter\expandafter\expandafter\endgroup
\expandafter\ifx\csname directlua\endcsname\relax
  \DeclareRobustCommand{\displaystyle}{%
    \@@displaystyle \chardef\mathstyle0\relax}
  \DeclareRobustCommand{\textstyle}{%
    \@@textstyle \chardef\mathstyle2\relax}
  \DeclareRobustCommand{\scriptstyle}{%
    \@@scriptstyle \chardef\mathstyle4\relax}
  \DeclareRobustCommand{\scriptscriptstyle}{%
    \@@scriptscriptstyle \chardef\mathstyle6\relax}
\fi
%    \end{macrocode}
% First we get the primitive operations. These should have been
% control sequences in \TeX\ just like operations for begin math, end
% math, begin display, end display.
%    \begin{macrocode}
\begingroup \catcode`\^=7\relax \catcode`\_=8\relax % just in case
\lowercase{\endgroup
\let\@@superscript=^ \let\@@subscript=_
}%
\begingroup \catcode`\^=12\relax \catcode`\_=12\relax % just in case
\lowercase{\endgroup
\let\@@superscript@other=^ \let\@@subscript@other=_
}%
%    \end{macrocode}
% If we enter a sub- or superscript the \cs{mathstyle} must be
% adjusted. Since all is happening in a group, we do not have to worry
% about resetting. We can't tell the difference between cramped and
% non-cramped styles unless Lua\TeX{} is in use, in which case this command
% is a no-op.
%    \begin{macrocode}
\begingroup\expandafter\expandafter\expandafter\endgroup
\expandafter\ifx\csname directlua\endcsname\relax
  \def\subsupstyle{%
    \ifnum\mathstyle<4\relax
      \chardef\mathstyle\numexpr4+\mathstyledenom\relax
    \else
      \chardef\mathstyle\numexpr6+\mathstyledenom\relax
    \fi
  }
\else
  \def\subsupstyle{}
\fi
%    \end{macrocode}
% Provide commands with meaningful names for the two primitives, cf.\
% \cs{mathrel}.
%    \begin{macrocode}
\let\mathsup=\@@superscript
\let\mathsub=\@@subscript
%    \end{macrocode}
% \cs{sb} and \cs{sp} are then defined as macros.
%    \begin{macrocode}
\def\sb#1{\mathsub{\protect\subsupstyle#1}}%
\def\sp#1{\mathsup{\protect\subsupstyle#1}}%
%    \end{macrocode}
%
% \begin{macro}{\mathchoice}
% \changes{v0.98e}{2016/04/09}{Lua\TeX{} primitive \cs{mathstyle} needs
%   termination}
% \cs{mathchoice} is now just a switch. Note that this redefinition
% does not allow the arbitrary \meta{filler} of the \TeX\
% primitive. Very rarely used anyway.
%    \begin{macrocode}
\def\mathchoice{%
  \relax\ifcase\numexpr\mathstyle\relax
    \expandafter\@firstoffour % Display
  \or
    \expandafter\@firstoffour % Cramped display
  \or
    \expandafter\@secondoffour % Text
  \or
    \expandafter\@secondoffour % Cramped text
  \or
    \expandafter\@thirdoffour % Script
  \or
    \expandafter\@thirdoffour % Cramped script
  \else
    \expandafter\@fourthoffour % (Cramped) Scriptscript
  \fi
}
%    \end{macrocode}
% Helper macros.
%    \begin{macrocode}
\providecommand\@firstoffour[4]{#1}
\providecommand\@secondoffour[4]{#2}
\providecommand\@thirdoffour[4]{#3}
\providecommand\@fourthoffour[4]{#4}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\genfrac}
% The amsmath definition:
% \begin{verbatim}
%    \DeclareRobustCommand{\genfrac}[4]{%
%      \def\@tempa{#1#2}%
%      \edef\@tempb{\@nx\@genfrac\@mathstyle{#4}%
%        \csname @@\ifx @#3@over\else above\fi
%        \ifx\@tempa\@empty \else withdelims\fi\endcsname}
%      \@tempb{#1#2#3}}
% \end{verbatim}
% with arguments:
% \begin{itemize}
% \item left-delim
% \item right-delim
% \item line thickness (default if empty)
% \item mathstyle override
% \item numerator
% \item denominator
% \end{itemize}
% The fractions. Note that this uses the same names as in
% \pkg{amsmath}. Much the same except here they call \cs{fracstyle}.
%    \begin{macrocode}
\DeclareRobustCommand\genfrac[6]{%
  {%
    % emulate old amsmath syntax:
    \if 0#4\relax\displaystyle\else
    \if 1#4\relax\textstyle\else
    \if 2#4\relax\scriptstyle\else
    \if 3#4\relax\scriptscriptstyle\else
      #4%
    \fi\fi\fi\fi
    \fracstyle
    {\begingroup #5\endgroup
      \csname @@\ifx\maxdimen#3\maxdimen over\else above\fi
        \if @#1@\else withdelims\fi\endcsname #1 #2 #3\relax
      \ifnum\mathstyledenom=0\relax
        \chardef\mathstyledenom=1\relax
        \edef\mathstyle@tempa{\number\mathstyle}%
        \chardef\mathstyle=\numexpr\mathstyle@tempa+1\relax
      \fi
      #6%
      \chardef\mathstyledenom=0\relax}%
  }%
}
\begingroup\expandafter\expandafter\expandafter\endgroup
\expandafter\ifx\csname directlua\endcsname\relax\else
\DeclareRobustCommand\genfrac[6]{%
  {%
    % emulate old amsmath syntax:
    \if 0#4\relax\displaystyle\else
    \if 1#4\relax\textstyle\else
    \if 2#4\relax\scriptstyle\else
    \if 3#4\relax\scriptscriptstyle\else
      #4%
    \fi\fi\fi\fi
    \fracstyle
    {\begingroup #5\endgroup
      \csname @@\ifx\maxdimen#3\maxdimen over\else above\fi
        \if @#1@\else withdelims\fi\endcsname #1 #2 #3\relax
      #6%
    }%
  }%
}
\fi
%    \end{macrocode}
% \changes{v0.90}{2011/08/03}{\cs{fracstyle} must be called \emph{after}
%   changing to the required style}
% \changes{v0.98e}{2016/04/09}{Lua\TeX{} primitive \cs{mathstyle} needs
%   termination}
% \end{macro}
%
%    \begin{macrocode}
\renewcommand{\frac}{\genfrac{}{}{}{}}
\providecommand{\dfrac}{}
\providecommand{\tfrac}{}
\renewcommand{\dfrac}{\genfrac{}{}{}\displaystyle}
\renewcommand{\tfrac}{\genfrac{}{}{}\displaystyle}
\providecommand{\binom}{}
\providecommand{\tbinom}{}
\providecommand{\dbinom}{}
\renewcommand{\binom}{\genfrac(){0pt}{}}
\renewcommand{\dbinom}{\genfrac(){0pt}\displaystyle}
\renewcommand{\tbinom}{\genfrac(){0pt}\textstyle}
%    \end{macrocode}

% The \cs{fracstyle} command is a switch to go one level down but no
% further than three.
%    \begin{macrocode}
\begingroup\expandafter\expandafter\expandafter\endgroup
\expandafter\ifx\csname directlua\endcsname\relax
  \def\fracstyle{%
    \ifcase\numexpr\mathstyle\relax
          \chardef\mathstyle=0\relax % 0
    \or   \chardef\mathstyle=1\relax % 1
    \or   \chardef\mathstyle=2\relax % 2
    \or   \chardef\mathstyle=3\relax % 3
    \else \chardef\mathstyle=3\relax % 4 or more
    \fi
  }
\else
  \def\fracstyle{}
\fi
%    \end{macrocode}
% \changes{v0.98e}{2016/04/09}{Lua\TeX{} primitive \cs{mathstyle} needs
%   termination}
% The \cs{currentmathstyle} checks the value of \cs{mathstyle} and
% switches to it so it is in essence the opposite of \cs{displaystyle}
% and friends.
%    \begin{macrocode}
\def\currentmathstyle{%
  \ifcase\numexpr\mathstyle\relax
    \@@displaystyle
  \or
    \@@displaystyle
  \or
    \@@textstyle
  \or
    \@@textstyle
  \or
    \@@scriptstyle
  \or
    \@@scriptstyle
  \else
    \@@scriptscriptstyle
  \fi}
%    \end{macrocode}
% Finally, we declare the package options.
% \changes{v0.89}{2010/11/17}{Options should only change catcodes at
% begin document, not straight away}
%    \begin{macrocode}
\DeclareOption{mathactivechars}{%
 %  \catcode`\^=12\relax
 %  \catcode`\_=12\relax
\AtBeginDocument{\catcode`\^=12\relax \catcode`\_=12\relax}%
}
\DeclareOption{activechars}{%
 %  \catcode`\^=13\relax
 %  \catcode`\_=13\relax
\AtBeginDocument{\catcode`\^=13\relax \catcode`\_=13\relax}%
}
\DeclareOption{noactivechars}{%
 %  \catcode`\^=7\relax
 %  \catcode`\_=8\relax
\AtBeginDocument{\catcode`\^=7\relax \catcode`\_=8\relax}%
}
\ExecuteOptions{mathactivechars}
\ProcessOptions\relax
%    \end{macrocode}
% WSPR: Set up the active behaviours: (this is set even in the
% |noactivechars| case but they are never activated. no worries?)
%    \begin{macrocode}
\ifnum\catcode`\^=13\relax
  \let^=\sp \let_=\sb
\else
  \mathcode`\^="8000\relax
  \mathcode`\_="8000\relax
  \begingroup
    \catcode`\^=\active
    \catcode`\_=\active
    \global\let^=\sp
    \global\let_=\sb
  \endgroup
\fi
%</package>
%    \end{macrocode}
%
% \PrintIndex
%
% \Finale
