%% mathformule.sty %% A small display-math environment with no explicit auxiliary-package load. %% %% Copyright (C) 2026 Quan Sun %% Released under the LaTeX Project Public License, version 1.3c or later. %% This work has LPPL maintenance status `maintained'. %% The Current Maintainer is Quan Sun. \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{mathformule}[2026/07/22 v0.6 Lightweight multiline formulas] \makeatletter % The amount by which the normal baseline separation is opened up between % formula rows. Three points follows TeX's traditional multiline-math % default. It is a dimension (not glue), so row baselines stay predictable. \newdimen\mathformulelineskip \mathformulelineskip=3pt % Global correction to the normal row separation. A lineskip key on an % individual formule replaces this value, so local settings take precedence. % The assignment is global by design: the public command is a document-wide % setup interface, normally used in the preamble. \newdimen\mathformule@globallineskipadjust \mathformule@globallineskipadjust=0pt \newcommand*\formuleskip[1]{% \global\mathformule@globallineskipadjust=#1\relax } % Package options only select a numbering parent. With no option, the % existing definition of the equation counter is left completely untouched. \let\mathformule@numberwithin\@empty \DeclareOption{section}{\def\mathformule@numberwithin{section}} \DeclareOption{chapter}{\def\mathformule@numberwithin{chapter}} \DeclareOption*{% \PackageWarning{mathformule}{Unknown option `\CurrentOption' ignored}% } \ProcessOptions\relax % Bind the shared equation counter to any existing LaTeX counter. Since the % standard equation counter is changed, native equation environments and % formule continue to share both their sequence and printed representation. \newcommand*\mathformulenumberwithin[1]{% \@ifundefined{c@#1}{% \PackageError{mathformule}{Counter `#1' is not defined}{% Use the name of an existing LaTeX counter, for example `section'.}% }{% \ifx\mathformule@numberwithin\@empty \else \@removefromreset{equation}{\mathformule@numberwithin}% \fi \@addtoreset{equation}{#1}% \expandafter\gdef\expandafter\theequation\expandafter{% \csname the#1\endcsname.\arabic{equation}}% \def\mathformule@numberwithin{#1}% }% } \ifx\mathformule@numberwithin\@empty \else \expandafter\mathformulenumberwithin\expandafter {\mathformule@numberwithin}% \fi \newdimen\mathformule@lineskip \newdimen\mathformule@lineskipadjust \newdimen\mathformule@lbraceadjust \newdimen\mathformule@rbraceadjust \newcount\mathformule@braceside \newcount\mathformule@rowcount \newcount\mathformule@rowindex \newcount\mathformule@typesetrow \newcount\mathformule@cellcount \newcount\mathformule@scancells \newif\ifmathformule@multnum \newif\ifmathformule@rowtag \newif\ifmathformule@fleqn \newif\ifmathformule@toomanycols \newif\ifmathformule@trailingbreak \newif\ifmathformule@hasalignment % A monotonically increasing counter gives every multnum row its own reference % target. Its printed representation is set locally to the visible subnumber; % the underlying value is never reset, so hyperref destinations stay unique % even when equation numbering restarts in a new section. \newcounter{mathformulerow} \providecommand*\mathformulerowautorefname{\equationautorefname} \AtBeginDocument{% \@ifpackageloaded{cleveref}{% \crefalias{mathformulerow}{equation}% }{}% } \def\mathformule@key@lineskip{lineskip} \def\mathformule@key@lbrace{lbrace} \def\mathformule@key@rbrace{rbrace} \def\mathformule@key@lbraceskip{lbraceskip} \def\mathformule@key@rbraceskip{rbraceskip} \def\mathformule@key@multnum{multnum} \def\mathformule@style@aa@dot{arabic.arabic} \def\mathformule@style@aa@dash{arabic-arabic} \def\mathformule@style@ar@dot{arabic.roman} \def\mathformule@style@ar@dash{arabic-roman} \def\mathformule@style@arabic{arabic} \def\mathformule@style@roman{roman} % A deliberately small key--value reader for the environment option. Commas % inside a value are protected by braces in the usual TeX way. Appending two % equals signs lets the same splitter accept both a bare key and key={value}. % A bare unrecognised item retains the prototype shorthand [] % and has the same signed-correction semantics as lineskip=. \def\mathformule@parseoptions#1{% \@for\mathformule@item:=#1\do{% \expandafter\mathformule@splititem\mathformule@item==\@nil }% } \def\mathformule@splititem#1=#2=#3\@nil{% \edef\mathformule@key{\zap@space#1 \@empty}% \def\mathformule@value{#2}% \ifx\mathformule@key\mathformule@key@lbrace \mathformule@setbrace{1}{#2}% \else\ifx\mathformule@key\mathformule@key@rbrace \mathformule@setbrace{2}{#2}% \else\ifx\mathformule@key\mathformule@key@multnum \mathformule@setmultnum{#2}% \else\ifx\mathformule@key\mathformule@key@lineskip \ifx\mathformule@value\@empty \PackageError{mathformule}{The lineskip key needs a value}{% For example, use lineskip=2pt or lineskip=-1ex.}% \else \mathformule@lineskipadjust=#2\relax \fi \else\ifx\mathformule@key\mathformule@key@lbraceskip \ifx\mathformule@value\@empty \PackageError{mathformule}{The lbraceskip key needs a value}{% For example, use lbraceskip=2pt or lbraceskip=-1pt.}% \else \mathformule@lbraceadjust=#2\relax \fi \else\ifx\mathformule@key\mathformule@key@rbraceskip \ifx\mathformule@value\@empty \PackageError{mathformule}{The rbraceskip key needs a value}{% For example, use rbraceskip=2pt or rbraceskip=-1pt.}% \else \mathformule@rbraceadjust=#2\relax \fi \else \ifx\mathformule@value\@empty \mathformule@lineskipadjust=\mathformule@key\relax \else \PackageError{mathformule}{Unknown formule key `\mathformule@key'}{% The supported keys are lineskip, lbrace, rbrace, lbraceskip, rbraceskip, and multnum.}% \fi \fi\fi\fi\fi\fi\fi } \def\mathformule@subarabic{\number\mathformule@rowindex} \def\mathformule@subroman{\romannumeral\mathformule@rowindex} \def\mathformule@setmultnum#1{% \mathformule@multnumtrue \def\mathformule@multseparator{.}% \let\mathformule@subnumber\mathformule@subarabic \def\mathformule@value{#1}% \ifx\mathformule@value\@empty \else \def\mathformule@multstyle{#1}% \ifx\mathformule@multstyle\mathformule@style@aa@dot \else\ifx\mathformule@multstyle\mathformule@style@aa@dash \def\mathformule@multseparator{-}% \else\ifx\mathformule@multstyle\mathformule@style@ar@dot \let\mathformule@subnumber\mathformule@subroman \else\ifx\mathformule@multstyle\mathformule@style@ar@dash \def\mathformule@multseparator{-}% \let\mathformule@subnumber\mathformule@subroman \else\ifx\mathformule@multstyle\mathformule@style@arabic \else\ifx\mathformule@multstyle\mathformule@style@roman \let\mathformule@subnumber\mathformule@subroman \else \PackageError{mathformule}{Unknown multnum style `\mathformule@multstyle'}{% Use arabic.arabic, arabic-arabic, arabic.roman, or arabic-roman.}% \fi\fi\fi\fi\fi\fi \fi } \def\mathformule@setbrace#1#2{% \ifnum\mathformule@braceside=\z@ \mathformule@braceside=#1\relax \def\mathformule@braceformula{#2}% \else \ifnum\mathformule@braceside=#1\relax \def\mathformule@braceformula{#2}% \else \PackageError{mathformule}{lbrace and rbrace cannot be combined}{% Select only one side for the brace.}% \fi \fi } % multnum uses a full-width alignment whose equation-number cell has zero % width. The formula columns therefore remain centred and the tags do not % become part of the material measured by a surrounding brace. \newskip\mathformule@leftskip \newskip\mathformule@rightskip \newbox\mathformule@multbox \newbox\mathformule@sidebox \newdimen\mathformule@formulawidth \newdimen\mathformule@colwdA \newdimen\mathformule@colwdB \newdimen\mathformule@colwdC \newdimen\mathformule@colwdD \newdimen\mathformule@colwdE \newdimen\mathformule@colwdF \newdimen\mathformule@colwdG \newdimen\mathformule@colwdH % Follow the document-wide fleqn convention when \mathindent exists. In the % ordinary case equal infinite glues centre the formula independently of its % zero-width equation tag. \def\mathformule@preparelayout{% \@ifundefined{mathindent}{% \mathformule@fleqnfalse \mathformule@leftskip=0pt plus 1000pt \mathformule@rightskip=0pt plus 1000pt }{% \mathformule@fleqntrue \mathformule@leftskip=\mathindent \mathformule@rightskip=0pt plus 1fil }% } \def\mathformule@resetcolwidths{% \global\mathformule@colwdA=\z@ \global\mathformule@colwdB=\z@ \global\mathformule@colwdC=\z@ \global\mathformule@colwdD=\z@ \global\mathformule@colwdE=\z@ \global\mathformule@colwdF=\z@ \global\mathformule@colwdG=\z@ \global\mathformule@colwdH=\z@ } \def\mathformule@updatecolwidth#1{% \ifcase#1\relax \or \ifdim\wd\z@>\mathformule@colwdA \global\mathformule@colwdA=\wd\z@ \fi \or \ifdim\wd\z@>\mathformule@colwdB \global\mathformule@colwdB=\wd\z@ \fi \or \ifdim\wd\z@>\mathformule@colwdC \global\mathformule@colwdC=\wd\z@ \fi \or \ifdim\wd\z@>\mathformule@colwdD \global\mathformule@colwdD=\wd\z@ \fi \or \ifdim\wd\z@>\mathformule@colwdE \global\mathformule@colwdE=\wd\z@ \fi \or \ifdim\wd\z@>\mathformule@colwdF \global\mathformule@colwdF=\wd\z@ \fi \or \ifdim\wd\z@>\mathformule@colwdG \global\mathformule@colwdG=\wd\z@ \fi \or \ifdim\wd\z@>\mathformule@colwdH \global\mathformule@colwdH=\wd\z@ \fi \fi } % Save and restore reference state that would otherwise be local to the first % alignment cell. Labels in every formula column then agree, and optional % reference packages see a real row counter rather than only the parent. \def\mathformule@newrowreference{% \refstepcounter{mathformulerow}% \global\let\mathformule@savedlabel\@currentlabel \@ifundefined{@currentHref}{% \global\let\mathformule@savedhref\@undefined }{% \global\let\mathformule@savedhref\@currentHref }% \@ifundefined{cref@currentlabel}{% \global\let\mathformule@savedcreflabel\@undefined }{% \global\let\mathformule@savedcreflabel\cref@currentlabel }% } \def\mathformule@restorerowreference{% \let\@currentlabel\mathformule@savedlabel \def\@currentcounter{mathformulerow}% \@ifundefined{mathformule@savedhref}{}{% \let\@currentHref\mathformule@savedhref }% \@ifundefined{mathformule@savedcreflabel}{}{% \let\cref@currentlabel\mathformule@savedcreflabel }% } \def\mathformule@preparemultcell#1{% \global\mathformule@cellcount=#1\relax \ifnum#1=\@ne \global\advance\mathformule@typesetrow\@ne \global\advance\mathformule@rowindex\@ne \global\mathformule@rowtagtrue \mathformule@newrowreference \fi \mathformule@restorerowreference } \def\mathformule@addpairgap{% \@tempdima=\wd\z@ \advance\@tempdima by \ht\z@ \advance\@tempdima by \dp\z@ \ifdim\@tempdima=\z@ \else \setbox\tw@=\box\z@ \setbox\z@\hbox{\qquad\box\tw@}% \fi } \def\mathformule@rownumber{% \mathformule@basenumber \mathformule@multseparator \mathformule@subnumber } \def\mathformule@multtagcell#1{% \def\mathformule@tagcontent{#1}% \ifx\mathformule@tagcontent\@empty \else \PackageError{mathformule}{Too many alignment columns with multnum}{% multnum supports at most four ampersand-aligned pairs per row.}% \fi \strut \ifmathformule@rowtag \hbox to\z@{% \hss \hbox{% \begingroup \edef\theequation{\mathformule@rownumber}% \@eqnnum \endgroup}}% \else \global\advance\mathformule@rowindex\m@ne \fi } \protected\def\mathformule@notag{% \global\mathformule@rowtagfalse } % Complete the fixed eight formula columns. The conditional must finish % before the selected macro emits alignment tabs: TeX conditionals may not % remain open across cells of an alignment. \def\mathformule@pad@eight{& & & & & & & &} \def\mathformule@pad@seven{& & & & & & &} \def\mathformule@pad@six{& & & & & &} \def\mathformule@pad@five{& & & & &} \def\mathformule@pad@four{& & & &} \def\mathformule@pad@three{& & &} \def\mathformule@pad@two{& &} \def\mathformule@pad@one{&} \let\mathformule@pad@none\@empty \def\mathformule@pad@error{% \PackageError{mathformule}{Too many alignment columns with multnum}{% multnum supports at most four ampersand-aligned pairs per row.}% } \def\mathformule@padmultrow{% \ifcase\mathformule@cellcount \let\mathformule@next\mathformule@pad@eight \or \let\mathformule@next\mathformule@pad@seven \or \let\mathformule@next\mathformule@pad@six \or \let\mathformule@next\mathformule@pad@five \or \let\mathformule@next\mathformule@pad@four \or \let\mathformule@next\mathformule@pad@three \or \let\mathformule@next\mathformule@pad@two \or \let\mathformule@next\mathformule@pad@one \or \let\mathformule@next\mathformule@pad@none \else \let\mathformule@next\mathformule@pad@error \fi \mathformule@next } % Temporarily balance the current alignment template while the LaTeX kernel % tests for an optional row adjustment. This prevents a following alignment % tab---including one at the start of the next row---from ending the template % during lookahead. \protected\def\mathformule@multcr{% \relax\iffalse{\fi\ifnum0=`}\fi \@ifnextchar[{\mathformule@multcr@i}{\mathformule@multcr@i[0pt]}% } \def\mathformule@multcr@i[#1]{% \ifnum0=`{\fi\iffalse}\fi \let\mathformule@next\mathformule@multcr@normal \ifmathformule@trailingbreak \ifnum\mathformule@typesetrow=\mathformule@rowcount \let\mathformule@next\mathformule@multcr@last \fi \fi \mathformule@next{#1}% } \def\mathformule@multcr@normal#1{% \mathformule@padmultrow&\cr \noalign{% \global\mathformule@cellcount=\z@ \vskip #1\relax}% } % A final \\ already closes the last physical row. Consume the synthetic % end marker instead of starting an empty, numbered row. Any adjustment on a % trailing break has no following row to separate and is therefore ignored. \def\mathformule@multcr@last#1\mathformule@endmultrow{% \mathformule@padmultrow&\crcr } \def\mathformule@endmultrow{% \mathformule@padmultrow&\crcr } \def\mathformule@initoptions{% \mathformule@lineskip=\mathformulelineskip \mathformule@lineskipadjust=\mathformule@globallineskipadjust \mathformule@lbraceadjust=\z@ \mathformule@rbraceadjust=\z@ \mathformule@braceside=\z@ \mathformule@multnumfalse \def\mathformule@multseparator{.}% \let\mathformule@subnumber\mathformule@subarabic \let\mathformule@braceformula\@empty } % Count top-level row breaks without expanding the body. Braced arguments are % consumed as single items, and an explicit environment depth keeps \\ inside % array/matrix-like nested environments from activating multnum by accident. \newcount\mathformule@envdepth \def\mathformule@scansentinel{\mathformule@scansentinel} \def\mathformule@sentineltoken{\mathformule@scansentinel} \def\mathformule@begintoken{\begin} \def\mathformule@endtoken{\end} \def\mathformule@breaktoken{\\} \def\mathformule@ampersandtoken{&} \long\def\mathformule@countrows#1{% \mathformule@rowcount=\@ne \mathformule@scancells=\@ne \mathformule@envdepth=\z@ \mathformule@toomanycolsfalse \mathformule@trailingbreakfalse \mathformule@hasalignmentfalse \mathformule@scanrows#1\mathformule@scansentinel } \long\def\mathformule@scanrows#1{% \def\mathformule@scanitem{#1}% \ifx\mathformule@scanitem\mathformule@sentineltoken \ifmathformule@trailingbreak \advance\mathformule@rowcount\m@ne \fi \let\mathformule@next\relax \else\ifx\mathformule@scanitem\mathformule@begintoken \mathformule@trailingbreakfalse \let\mathformule@next\mathformule@scanbegin \else\ifx\mathformule@scanitem\mathformule@endtoken \mathformule@trailingbreakfalse \let\mathformule@next\mathformule@scanend \else \let\mathformule@next\mathformule@scanrows \ifnum\mathformule@envdepth=\z@ \ifx\mathformule@scanitem\mathformule@breaktoken \advance\mathformule@rowcount\@ne \mathformule@scancells=\@ne \mathformule@trailingbreaktrue \let\mathformule@next\mathformule@scanbreaktail \else\ifx\mathformule@scanitem\mathformule@ampersandtoken \mathformule@trailingbreakfalse \mathformule@hasalignmenttrue \advance\mathformule@scancells\@ne \ifnum\mathformule@scancells>8 \mathformule@toomanycolstrue \fi \else \mathformule@trailingbreakfalse \fi\fi \fi \fi\fi\fi \mathformule@next } % A row break's optional local spacing belongs to that break, not to the next % row. Consume it here so a final \\[] is still recognised as a % trailing break rather than as mathematical content. \def\mathformule@scanbreaktail{% \@ifnextchar[{\mathformule@scanbreakadjust}{\mathformule@scanrows}% } \def\mathformule@scanbreakadjust[#1]{\mathformule@scanrows} \long\def\mathformule@scanbegin#1{% \advance\mathformule@envdepth\@ne \mathformule@scanrows } \long\def\mathformule@scanend#1{% \ifnum\mathformule@envdepth>\z@ \advance\mathformule@envdepth\m@ne \fi \mathformule@scanrows } % A row break accepts an optional *additional* vertical adjustment. The % environment-wide separation has already been installed by \openup. % Use the same alignment-safe optional-argument lookahead in shared-tag mode. \protected\def\mathformule@cr{% \relax\iffalse{\fi\ifnum0=`}\fi \@ifnextchar[{\mathformule@cr@i}{\mathformule@cr@i[0pt]}% } \def\mathformule@cr@i[#1]{% \ifnum0=`{\fi\iffalse}\fi \let\mathformule@next\mathformule@cr@normal \ifmathformule@trailingbreak \ifnum\mathformule@typesetrow=\mathformule@rowcount \let\mathformule@next\mathformule@cr@last \fi \fi \mathformule@next{#1}% } \def\mathformule@cr@normal#1{% \cr \noalign{\vskip #1\relax}% } \def\mathformule@cr@last#1\mathformule@endsinglerow{\crcr} \def\mathformule@endsinglerow{\crcr} % With no top-level ampersand, the sole formula column is left aligned. Once % an alignment point is present, retain the conventional right-before/left- % after column pattern. The selected fill macros contain no open conditionals % when TeX crosses an alignment cell boundary. \let\mathformule@firstbefore\hfil \let\mathformule@firstafter\@empty \def\mathformule@preparefirstcolumn{% \ifmathformule@hasalignment \let\mathformule@firstbefore\hfil \let\mathformule@firstafter\@empty \else \let\mathformule@firstbefore\@empty \let\mathformule@firstafter\hfil \fi } \def\mathformule@beginsharedrow{% \global\advance\mathformule@typesetrow\@ne } % The full-width outer hbox keeps the tag at the document margin while the % formula obeys either centred display layout or the class's fleqn indent. \def\mathformule@tagbox{% \hbox to\z@{\hss\hbox{\@eqnnum}}% } \long\def\mathformule@singletagtypeset#1{% \let\\\mathformule@cr % Primitive display math supplies TeX's contextual, rubber vertical % spaces: \abovedisplayskip/\abovedisplayshortskip and their below forms. \m@th \dollardollar@begin \hbox to\displaywidth{% \hskip\mathformule@leftskip $\m@th\displaystyle \ifcase\mathformule@braceside \or \mathformule@braceformula\left\{\kern\mathformule@lbraceadjust \or \left. \fi \vcenter{% \openup\mathformule@lineskip \m@th \everycr{}% \tabskip\z@skip \ialign{% \mathformule@beginsharedrow \strut\mathformule@firstbefore$\displaystyle{##}$% \mathformule@firstafter &$\displaystyle{{}##}$\hfil% &&\qquad\hfil$\displaystyle{##}$% &$\displaystyle{{}##}$\hfil\crcr #1\mathformule@endsinglerow }% }% \ifcase\mathformule@braceside \or \right. \or \kern\mathformule@rbraceadjust\right\}\mathformule@braceformula \fi $% \hskip\mathformule@rightskip \mathformule@tagbox }% \dollardollar@end } \long\def\mathformule@multtypeset#1{% \protected@edef\mathformule@basenumber{\theequation}% \def\themathformulerow{% \mathformule@basenumber \mathformule@multseparator \mathformule@subnumber}% \let\\\mathformule@multcr \let\notag\mathformule@notag \let\nonumber\mathformule@notag \global\mathformule@rowindex=\z@ \global\mathformule@typesetrow=\z@ \global\mathformule@cellcount=\z@ \mathformule@resetcolwidths \m@th \dollardollar@begin \setbox\mathformule@multbox=\vbox{% \openup\mathformule@lineskip \m@th \everycr{}% \tabskip\mathformule@leftskip \halign to\displaywidth\bgroup \mathformule@preparemultcell{1}% \setbox\z@\hbox{$\displaystyle{##}$}% \mathformule@updatecolwidth{1}% \mathformule@firstbefore\box\z@\mathformule@firstafter \tabskip\z@skip &\mathformule@preparemultcell{2}% \setbox\z@\hbox{$\displaystyle{{}##}$}% \mathformule@updatecolwidth{2}\box\z@\hfil \tabskip\z@skip &\mathformule@preparemultcell{3}% \setbox\z@\hbox{$\displaystyle{##}$}% \mathformule@addpairgap \mathformule@updatecolwidth{3}\hfil\box\z@ \tabskip\z@skip &\mathformule@preparemultcell{4}% \setbox\z@\hbox{$\displaystyle{{}##}$}% \mathformule@updatecolwidth{4}\box\z@\hfil \tabskip\z@skip &\mathformule@preparemultcell{5}% \setbox\z@\hbox{$\displaystyle{##}$}% \mathformule@addpairgap \mathformule@updatecolwidth{5}\hfil\box\z@ \tabskip\z@skip &\mathformule@preparemultcell{6}% \setbox\z@\hbox{$\displaystyle{{}##}$}% \mathformule@updatecolwidth{6}\box\z@\hfil \tabskip\z@skip &\mathformule@preparemultcell{7}% \setbox\z@\hbox{$\displaystyle{##}$}% \mathformule@addpairgap \mathformule@updatecolwidth{7}\hfil\box\z@ \tabskip\z@skip &\mathformule@preparemultcell{8}% \setbox\z@\hbox{$\displaystyle{{}##}$}% \mathformule@updatecolwidth{8}\box\z@\hfil \tabskip\mathformule@rightskip &\mathformule@multtagcell{##}% \tabskip\z@skip\crcr #1\mathformule@endmultrow \egroup }% \mathformule@formulawidth=\mathformule@colwdA \advance\mathformule@formulawidth by \mathformule@colwdB \advance\mathformule@formulawidth by \mathformule@colwdC \advance\mathformule@formulawidth by \mathformule@colwdD \advance\mathformule@formulawidth by \mathformule@colwdE \advance\mathformule@formulawidth by \mathformule@colwdF \advance\mathformule@formulawidth by \mathformule@colwdG \advance\mathformule@formulawidth by \mathformule@colwdH \ifmathformule@fleqn \@tempdima=\mathformule@leftskip \else \@tempdima=\displaywidth \advance\@tempdima by -\mathformule@formulawidth \divide\@tempdima\tw@ \fi \ifcase\mathformule@braceside \or \setbox\mathformule@sidebox=\hbox{$\displaystyle \mathformule@braceformula \left\{\vphantom{\vcenter{\copy\mathformule@multbox}}\right.$}% \hbox to\z@{% \kern\@tempdima \kern-\mathformule@lbraceadjust \kern-\wd\mathformule@sidebox \box\mathformule@sidebox\hss}% \or \setbox\mathformule@sidebox=\hbox{$\displaystyle \left.\vphantom{\vcenter{\copy\mathformule@multbox}}\right\}% \mathformule@braceformula$}% \hbox to\z@{% \kern\@tempdima \kern\mathformule@formulawidth \kern\mathformule@rbraceadjust \box\mathformule@sidebox\hss}% \fi \vcenter{\box\mathformule@multbox}% \dollardollar@end } \long\def\mathformule@dispatch#1#2{% \ifmmode \PackageError{mathformule}{formule cannot be nested in math mode}{% End the surrounding math mode before starting formule.}% \else \begingroup \mathformule@initoptions \mathformule@parseoptions{#1}% \advance\mathformule@lineskip by \mathformule@lineskipadjust \mathformule@preparelayout \mathformule@countrows{#2}% \mathformule@preparefirstcolumn \global\mathformule@typesetrow=\z@ \refstepcounter{equation}% \ifmathformule@multnum \ifnum\mathformule@rowcount>\@ne \ifmathformule@toomanycols \PackageError{mathformule}{Too many alignment columns with multnum}{% multnum supports at most four ampersand-aligned pairs per row.}% \mathformule@singletagtypeset{#2}% \else \mathformule@multtypeset{#2}% \fi \else \mathformule@singletagtypeset{#2}% \fi \else \mathformule@singletagtypeset{#2}% \fi \endgroup \@ignoretrue \fi } \def\mathformule@targetenv{formule} \protected\long\def\mathformule@collect#1{% \mathformule@collect@i{#1}{}% } \long\def\mathformule@collect@i#1#2#3\end#4{% \def\mathformule@foundenv{#4}% \ifx\mathformule@foundenv\mathformule@targetenv \let\mathformule@next\mathformule@collect@finish \else \let\mathformule@next\mathformule@collect@continue \fi \mathformule@next{#1}{#2#3}{#4}% } \long\def\mathformule@collect@finish#1#2#3{% \mathformule@dispatch{#1}{#2}% \end{#3}% } \long\def\mathformule@collect@continue#1#2#3{% \mathformule@collect@i{#1}{#2\end{#3}}% } % The optional argument accepts keys and retains the old [] form. % Capturing the body lets multnum distinguish a genuine multiline display % without executing or typesetting the formula twice. Refuse to replace an % environment (or either of its defining commands) supplied by another file. \def\mathformule@nameclash{% \PackageError{mathformule}{Environment `formule' is already defined}{% Rename or remove the conflicting definition before loading mathformule.}% } \newif\ifmathformule@environmentdefined \@ifundefined{formule}{% \@ifundefined{endformule}{% \newenvironment{formule}[1][] {\mathformule@collect{#1}} {}% \mathformule@environmentdefinedtrue }{\mathformule@nameclash}% }{\mathformule@nameclash} % The experimental tagged-math layer in current LaTeX grabs complete % environments before they start. Our ordinary definition already performs % that job itself, so in this one configuration use the kernel's built-in body % argument and notify its math processor explicitly. The branch is dormant % on conventional LaTeX runs and does not load an auxiliary package. \def\mathformule@enabletaggedmath{% \RenewDocumentEnvironment{formule}{O{} +b}{% \csname __math_process:nn\endcsname{formule}{##2}% \@kernel@math@registered@begin \mathformule@dispatch{##1}{##2}% }{}% } \AtBeginDocument{% \ifmathformule@environmentdefined \@ifundefined{@kernel@math@registered@begin}{}{% \mathformule@enabletaggedmath }% \fi } \makeatother \endinput