% \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) 2007-2020 by Will Robertson % Copyright (C) 2010-2017 by Joseph Wright % Copyright (C) 2020-2020 by Ulrike Fischer % % 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} % % \fi % % \title{The \textsf{mathstyle} package} % \def\fileversion{0.98l} % \def\filedate{2021/10/28} % \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}{2021/10/28}{0.98l}{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 % % \end{macrocode} % % \PrintIndex % % \Finale