core-mat.tex / last modification: 2008-09-18 14:58
%D \module
%D   [       file=core-mat,
%D        version=2006.03.27, % 1998.12.07
%D          title=\CONTEXT\ Core Macros,
%D       subtitle=Math Fundamentals,
%D         author={Hans Hagen, Taco Hoekwater \& Aditya Mahajan},
%D           date=\currentdate,
%D      copyright=PRAGMA]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.

% engels maken

\writestatus{loading}{Context Core Macros / Math Fundamentals}

\unprotect

% \startlines
% $\mathopnolimits{\rm d}x$
% $\mathopnolimits{\kern\zeropoint \rm d}x$
% $\puremathcomm{nolop}{\rm d}x$
% $\puremathcomm{nolop}{\kern\zeropoint\rm d}x$
% \blank
% $\puremathcomm{nolop}{\mr d}x$
% $\puremathcomm{nolop}{\kern\zeropoint\mr d}x$
% $\mathop{\kern\zeropoint\mr d}x$
% $\mathopnolimits{\kern\zeropoint d}x$
% \stoplines

% \definemessageconstant{math}

% \startmessages  all  library: math
%   title: math
%       1: don't use -- here (line \the\inputlineno)
% \stopmessages

% \def\invalidmathcommand#1{\showmessage\m!math1{#1}}

% \let\normaleqno \eqno
% \let\normalleqno\leqno

% \appendtoks
%     \def\eqno {\invalidmathcommand{\string\eqno }}%
%     \def\leqno{\invalidmathcommand{\string\leqno}}%
% \to \everydisplay

% \appendtoks
%     \let\eqno\normaleqno
%     \let\leqno\normaleqno
% \to \everymath

% \placeformula\startformula
% 	H(K|M,C) = H(K|C) - H(M|C)\eqno{\hbox{(\in{}[eq:keyapp])}}
% \stopformula

\def\mathortext
  {\ifmmode
     \expandafter\firstoftwoarguments
   \else
     \expandafter\secondoftwoarguments
   \fi}

% \defineactivecharacter _ {\mathortext{_}{\_}} text_text  $a^2$

% force text mode, will be overloaded later

\ifx\text\undefined \let\text\hbox \fi

\newdimen\lastlinewidth

% does not work at all
%
% \def\setlastlinewidth
%   {\resetlastlinewidth
%    \ifmmode\else\ifhmode\else\ifoptimizedisplayspacing
%      \bgroup
%      \forgetdisplayskips
%      $$\global\lastlinewidth\predisplaysize$$
%      \vskip-\baselineskip
%      \egroup
%    \fi\fi\fi}

% test \par \dorecurse{10}{test } \moveformula \startformula test \stopformula test \endgraf
% test \par \dorecurse{10}{test } \startformula test \stopformula test \endgraf
% \dorecurse{30}{\bpar \dorecurse\recurselevel{test } \epar \startformula formula \stopformula}

\def\setlastlinewidth
  {\resetlastlinewidth
   \ifoptimizedisplayspacing\ifmmode\else\ifhmode
     \bgroup
     \forgetdisplayskips
     \displaywidowpenalty\widowpenalty % brrr, else widowpenalty does not work
     \everymath   \emptytoks
     \everydisplay\emptytoks
     $$\strut\global\lastlinewidth\predisplaysize$$
     \vskip-\lineheight
     \vskip\zeropoint
     \egroup
   \fi\fi\fi}

\def\resetlastlinewidth
  {\global\lastlinewidth\zeropoint\relax}

% not here: \appendtoks \setlastlinewidth \to \everyendofpar

%D moved from main-001

%\def\EveryMathPar{\EveryPar}
%
%\newevery \everymath \EveryMath

\abovedisplayskip      = \zeropoint
\abovedisplayshortskip = \zeropoint % evt. 0pt minus 3pt
\belowdisplayskip      = \zeropoint
\belowdisplayshortskip = \zeropoint % evt. 0pt minus 3pt

\predisplaypenalty     = \zerocount
\postdisplaypenalty    = \zerocount % -5000 gaat mis, zie penalty bij \paragraaf

% we don't use the skip's

\def\displayskipsize#1#2% obsolete
  {\ifdim\ctxparskip>\zeropoint
     #1\ctxparskip\!!plus#2\ctxparskip\!!minus#2\ctxparskip\relax
   \else
     #1\lineheight\!!plus#2\lineheight\!!minus#2\lineheight\relax
   \fi}

\def\displayskipfactor          {1.0} % obsolete
\def\displayshortskipfactor     {0.8} % obsolete
\def\displayskipgluefactor      {0.3} % obsolete
\def\displayshortskipgluefactor {0.2} % obsolete

\def\abovedisplayskipsize% obsolete
  {\displayskipsize\displayskipfactor\displayskipgluefactor}

\def\belowdisplayskipsize% obsolete
  {\displayskipsize\displayskipfactor\displayskipgluefactor}

\def\abovedisplayshortskipsize% obsolete
  {\displayskipsize\displayshortskipfactor\displayshortskipgluefactor}

\def\belowdisplayshortskipsize% obsolete
  {\displayskipsize\displayshortskipfactor\displayshortskipgluefactor}

\def\forgetdisplayskips % to do
  {\abovedisplayskip     \zeropoint
   \belowdisplayskip     \zeropoint
   \abovedisplayshortskip\zeropoint
   \belowdisplayshortskip\zeropoint}

\definenumber % \definelabel
  [\v!formula]
  [\c!text=\v!formula,
   \c!way=\@@fmway,
   \c!blockway=\@@fmblockway,
   \c!location=\v!intext,
   \c!conversion=\@@fmconversion]

\def\setupformulas
  {\dodoubleargument\getparameters[\??fm]}

\newconditional\handleformulanumber
\newconditional\incrementformulanumber

\def\formuladistance{\formulaparameter\c!distance}

\def\doformulareference#1#2%
  {\doifsomething{#1}{\doifnotinset{#1}{+,-}{\rawreference\s!for{#1}{#2}}}}

\def\dododoformulanumber#1#2#3#4% (#1,#2)=outer(ref,sub) (#3,#4)=inner(ref,sub)
  {\hbox\bgroup
   \ifconditional\handleformulanumber
     \ifconditional\incrementformulanumber
       \incrementnumber[\v!formula]%
     \fi
     \makesectionnumber[\v!formula]%
     \setbox0\hbox{\ignorespaces#2\unskip}%
     \ifdim\wd0>\zeropoint
       \edef\hetsubnummer{\@@fnseparator#2}%AM: was \edef\hetsubnummer{#2}%
     \else
       \let\hetsubnummer\empty
     \fi
     \doformulareference{#1}{\composedsectionnumber\hetsubnummer}%
     \setbox0\hbox{\ignorespaces#4\unskip}%
     \ifdim\wd0>\zeropoint
       \edef\hetsubnummer{\@@fnseparator#4}%AM: was \edef\hetsubnummer{#4}%
     \fi
     \doformulareference{#3}{\composedsectionnumber\hetsubnummer}%
     \doflushformulalistentry{\composedsectionnumber\hetsubnummer}%
     \rm % nodig ?
     \doif{\formulaparameter\c!location}\v!right{\hskip\formuladistance}%
     \@@fmnumbercommand
       {\dostartattributes\??fm\c!numberstyle\c!numbercolor
        \strut
        \@@fmleft
        \preparefullnumber\??fm\composedsectionnumber\preparednumber
        \labeltexts\v!formula
          {\ignorespaces\preparednumber\ignorespaces\hetsubnummer\unskip}%
        \@@fmright
        \dostopattributes}%
      \doif{\formulaparameter\c!location}\v!left{\hskip\formuladistance}%
   \fi
   \egroup}

\def\dodoformulanumber[#1][#2][#3]%
  {\doquadruplegroupempty\dododoformulanumber{#1}{#2}{#3}}

\def\doformulanumber
  {\dotripleempty\dodoformulanumber}

\setvalue{\e!start\v!formula}{\dostartformula{}}
\setvalue{\e!stop \v!formula}{\dostopformula}

\def\definieerformule
  {\dodoubleempty\dodefinieerformule}

\def\dodefinieerformule[#1][#2]%
  {\doifsomething{#1}
     {\copyparameters
        [\??fm#1][\??fm]
        [\c!spacebefore,\c!spaceafter,\c!grid,
         \c!leftmargin,\c!rightmargin,\c!margin,
         \c!indentnext,\c!alternative,
         \c!strut,\c!align,\c!distance]%
      \setupformulas[#1][#2]%
      \setvalue{\e!start#1\v!formula}{\dostartformula{#1}}%
      \setvalue{\e!stop #1\v!formula}{\dostopformula}}}

\newtoks \everysetupformulas \relax % we need a hook for extensions in modules

\def\setupformulas
  {\dodoubleempty\dosetupformulas}

\def\dosetupformulas[#1][#2]%
  {\ifsecondargument
     \getparameters[\??fm#1][#2]%
   \else
     \getparameters[\??fm][#1]%
   \fi
   \the\everysetupformulas}

\def\formulaparameter#1%
  {\csname\??fm\currentformula#1\endcsname}

\setupformulas
  [\c!way=\@@nrway,
   \c!blockway=,
   \c!sectionnumber=\@@nrsectionnumber,
   \c!conversion=\v!numbers,
   \c!location=\v!right,
   \c!left=(,
   \c!right=),
   \c!spacebefore=,
   \c!spaceafter=\@@fmspacebefore,
   \c!leftmargin=\!!zeropoint,
   \c!rightmargin=\!!zeropoint,
   \c!margin=,
   \c!indentnext=\v!no,
   \c!alternative=\s!default,
   \c!align=,
   \c!strut=\v!no,
   \c!separator=\@@koseparator,
   \c!distance=1em]

\def\currentformula          {}
\def\predisplaysizethreshhold{2em} % was 3em

\def\leftdisplayskip    {\leftskip}
\def\rightdisplayskip   {\rightskip}
\def\leftdisplaymargin  {\formulaparameter\c!leftmargin}
\def\rightdisplaymargin {\formulaparameter\c!rightmargin}
\def\displaygridsnapping{\formulaparameter\c!grid}

\def\beforedisplayspace
  {\doifnot{\formulaparameter\c!spacebefore}\v!none{\blank[\formulaparameter\c!spacebefore]}}

\def\afterdisplayspace
  {\doifnot{\formulaparameter\c!spaceafter }\v!none{\blank[\formulaparameter\c!spaceafter ]}}

\def\setpredisplaysize#1%
  {\predisplaysize#1\relax
   \ifdim\predisplaysize<\maxdimen
     \ifdim\predisplaysize>\zeropoint
       \advance\predisplaysize \predisplaysizethreshhold
     \fi
     \advance\predisplaysize \displayindent % needed ?
     \ifdim\predisplaysize>\hsize
       \predisplaysize\hsize
     \fi
   \else
     \predisplaysize\zeropoint
   \fi}

\def\setdisplaydimensions
  {\displayindent\leftdisplayskip
   \advance\displayindent\leftdisplaymargin
   \displaywidth\hsize
% \setlocalhsize
% \displaywidth\localhsize
   \ifdim\hangindent>\zeropoint
     \advance\displayindent\hangindent
   \else
     \advance\displaywidth\hangindent
   \fi
   \advance\displaywidth-\displayindent
   \advance\displaywidth-\rightdisplayskip
   \advance\displaywidth-\rightdisplaymargin
   \hsize\displaywidth} % new, else overfull in itemize

\newif\ifoptimizedisplayspacing

\def\dostartformula#1%
  {\dodoubleempty\dodostartformula[#1]}

\newskip\formulaparskip
\newskip\formulastrutht
\newskip\formulastrutdp

% hm, invoke otr in hmode in order to move skips to mvl, could be an option

%D \startbuffer
%D \startformula[9pt] x = 1 \stopformula
%D \startformula[7pt] x = 1 \stopformula
%D \stopbuffer
%D
%D \typebuffer \getbuffer

\def\dodostartformula[#1][#2]% setting leftskip adaption is slow !
  {% todo: test first
   %
   % \ifdim\lastskip>\zeropoint
   %   \resetlastlinewidth % else problems with in between stuff without \epar
   % \fi
   \bgroup % HERE
   \the\everybeforedisplayformula
   \formulaparskip\parskip
   \formulastrutdp\strutdepth
   \formulastrutht\strutheight
   \switchtoformulabodyfont[#2]%
   \parskip\formulaparskip
   \def\currentformula{#1}%
% may look better in itemizations
\doif{\formulaparameter\c!option}\v!middle
  {\def\leftdisplayskip{\zeropoint}%
   \def\rightdisplayskip{\zeropoint}}%
% this was an experiment
   \doifsomething{\formulaparameter\c!margin}% so we test first
     {\dosetleftskipadaption{\formulaparameter\c!margin}%
      \edef\leftdisplaymargin{\the\leftskipadaption}}% overloaded
   \long\def\dostartformula##1{\bgroup\let\dostopformula\egroup}%
   \freezedimenmacro\leftdisplayskip
   \freezedimenmacro\rightdisplayskip
   \freezedimenmacro\leftdisplaymargin
   \freezedimenmacro\rightdisplaymargin
   \freezedimenmacro\predisplaysizethreshhold
   \forgetdisplayskips
   \ifoptimizedisplayspacing
     \ifdim\lastlinewidth>\zeropoint
       \abovedisplayshortskip-\strutht\relax
     \fi
   \else
     \resetlastlinewidth
   \fi
   \getvalue{\e!start\formulaparameter\c!alternative\v!formula}}

\def\switchtoformulabodyfont{\switchtobodyfont}

\setvalue{\v!formula}{\dosingleempty\doformula}

\def\doformula[#1]#2%
  {\begingroup
   \switchtoformulabodyfont[#1]%
   % not : \def\doformula[##1]##2{\mathematics{##2}}%
   \mathematics{#2}%
   \endgroup}

\let\doplaceformulanumber\empty

\def\dostopformula
  {\doplaceformulanumber
   \getvalue{\e!stop\formulaparameter\c!alternative\v!formula}%
   \resetlastlinewidth
   \nonoindentation
   \dochecknextindentation{\??fm\currentformula}%
   \egroup
   \hangafter\minusone   % added for side floats
   \hangindent\zeropoint % added for side floats
   \setfalse\handleformulanumber
   \dorechecknextindentation} % here ?

\newif\ifinformula

\def\startdisplaymath
  {\ifgridsnapping
     \beforedisplayspace
     \snapmathtogrid\vbox
     \bgroup
     \informulatrue
    %\forgetall % breaks side floats
   \else
     \bgroup
     \parskip\formulaparskip % ! !
     \informulatrue
    %\forgetall % otherwise backgrounds fail
     \ifdim\lastskip<\zeropoint\else
       \par
       \ifvmode \ifdim\parskip>\zeropoint\relax
         \whitespace \vskip-\parskip % kind of forces and cancels again
       \fi \fi
     \fi
     \doif\displaygridcorrection{-\v!top}{\kern-\strutht}% new, currently only option/default
     \beforedisplayspace
     \par
     \ifvmode
       \verticalstrut
       \vskip-\struttotal
       \vskip-\baselineskip
     \fi
   \fi
   $$\setdisplaydimensions
   \setpredisplaysize\lastlinewidth
   \startinnermath}

\def\stopdisplaymath
  {\stopinnermath
   $$%
   \ifgridsnapping
     \egroup
     \afterdisplayspace
   \else
     \par\ifvmode\ifdim\parskip>\zeropoint\whitespace\vskip-\parskip\fi\fi
     \afterdisplayspace
     \egroup
   \fi
   \globallet\displaylinecorrection\empty
   \gdef\displaygridcorrection{\displaygridsnapping}}

\newif\ifclipdisplaymath \clipdisplaymathtrue
\def\displaymathclipfactor{1.1}

\def\snapmathtogrid % to do \dp
  {\dowithnextbox
     {\bgroup
      \donefalse
      \ifclipdisplaymath
        \ifdim\nextboxht<\displaymathclipfactor\lineheight
          \donetrue
        \fi
      \fi
      \ifdone
        \nextboxht\lineheight
      \else
        \getnoflines\nextboxht
        \setbox\nextbox\vbox to \noflines\lineheight
          {\vfill\flushnextbox\vfill}%
        \setbox\nextbox\hbox{\lower\strutdepth\flushnextbox}%
      \fi
      \snaptogrid[\displaygridcorrection]\hbox{\flushnextbox}%
      \egroup}}

\def\displaygridcorrection{\displaygridsnapping}
\let\displaygridcorrection\empty

\def\moveformula
  {\dosingleempty\domoveformula}

\def\domoveformula[#1]% brr gaat mogelijk fout
  {\iffirstargument
     \xdef\displaygridcorrection{#1}%
   \else
     \gdef\displaygridcorrection{-\v!top}% handy with short preline
   \fi
   \globallet\displaylinecorrection\displaygridcorrection}

\let\startinnermath\empty
\let\stopinnermath \empty

\def\defineformulaalternative
  {\dotripleargument\dodefineformulaalternative}

\def\dodefineformulaalternative[#1][#2][#3]%
  {\setvalue{\e!start#1\v!formula}{#2}%
   \setvalue{\e!stop #1\v!formula}{#3}}

\defineformulaalternative[\s!default][\startdisplaymath][\stopdisplaymath]

% sp = single line paragraph  sd = single line display
% mp = multi  line paragraph  md = multy  line display

\defineformulaalternative[single][\startdisplaymath][\stopdisplaymath]
\defineformulaalternative[multi] [\startdisplaymath][\stopdisplaymath]

\definieerformule
  [sp]
  [\c!spacebefore=\v!none,\c!spaceafter=\v!none,
   \c!indentnext=\v!no,
   \c!alternative=single]

\definieerformule
  [sd]
  [\c!spacebefore=\v!none,\c!spaceafter=\v!none,
   \c!indentnext=\v!yes,
   \c!alternative=single]

\definieerformule
  [mp]
  [\c!indentnext=\v!no,
   \c!alternative=multi]

\definieerformule
  [md]
  [\c!indentnext=\v!yes,
   \c!alternative=multi]

% in m-math
%
% \defineformulaalternative[multi][\begindmath][\enddmath]
%
% \fakewords{20}{40}\epar
% \placeformula {a} $$              \fakespacingformula $$
% \fakewords{20}{40}\epar
% \placeformula {b} \startformule   \fakespacingformula \stopformule
% \placeformula {b} \startformule   \fakespacingformula \stopformule
% \fakewords{20}{40}\epar
% \placeformula {c} \startmdformule \fakespacingformula \stopmdformule
% \placeformula {c} \startmdformule \fakespacingformula \stopmdformule
% \fakewords{20}{40}\epar
% \placeformula {d} \startmpformule \fakespacingformula \stopmpformule
% \placeformula {d} \startmpformule \fakespacingformula \stopmpformule
% \fakewords{20}{40}\epar
% \placeformula {e} \startsdformule \fakespacingformula \stopsdformule
% \placeformula {e} \startsdformule \fakespacingformula \stopsdformule
% \fakewords{20}{40}\epar
% \placeformula {f} \startspformule \fakespacingformula \stopspformule
% \placeformula {f} \startspformule \fakespacingformula \stopspformule
% \fakewords{20}{40}

\def\placeformula
  {\settrue\incrementformulanumber
   \dodoubleempty\doplaceformula}

\def\placesubformula
  {\setfalse\incrementformulanumber
   \dodoubleempty\doplaceformula}

%D \macros
%D   {setupsubformulas, startsubformulas}
%D
%D New code (by Aditya Mahajan / cleaned up by HH, please check):

% \setupsubformulas[conversion=romannumerals]
%
% \placeformula
% \startsubformulas[Maxwell]
%     \startformulas
%      \startformula \startalign
%        \NC \nabla\cdot\bf E  \NC = \frac{\rho}{\varepsilon_0} \NR[Maxwell 1]
%        \NC \nabla\times\bf E \NC = - \frac{\partial\bf B}{\partial t} \NR[Maxwell II]
%        \stopalign \stopformula
%        \startformula \startalign
%          \NC \nabla\cdot \bf B \NC = 0 \NR[Maxwell III]
%          \NC \nabla\times\bf B \NC = \mu_0{\bf j}+\varepsilon_0\mu_0\frac{\partial\bf E}{\partial t} \NR[Maxwell IV]
%        \stopalign \stopformula
%    \stopformulas
% \stopsubformulas
%
% Maxwell : \in [Maxwell] and II : \in [Maxwell II]

\def\setupsubformulas
  {\dodoubleargument\getparameters[\??fn]}

\definenumber[\v!formula*]

\def\subformulaconversion % #1
  {\getnumber[\v!formula*]\@@fnseparator\convertnumber\@@fnconversion} % #1

\defineconversion[\v!subformula][\subformulaconversion]

\def\startsubformulas
  {\dosingleempty\dostartsubformulas}

\def\dostartsubformulas[#1]%
  {\incrementnumber[\v!formula]%
   \makesectionnumber[\v!formula]%
   \doflushformulalistentry{\composedsectionnumber}%
   \doformulareference{#1}\composedsectionnumber
   \expanded{\setupnumber
     [\v!formula*]
     [\c!start={\rawnumber[\v!formula]},
      \c!way=\@@fmway,
      \c!conversion=\@@fmconversion]}%
   \bgroup
   \savenumber[\v!formula]%
   \setupformulas
     [\c!conversion=\v!subformula,
      \c!way=\v!by\v!text]%
   \resetnumber
     [\v!formula]}

\def\stopsubformulas
  {\restorenumber[\v!formula]%
   \egroup
   \resetlastlinewidth
   \nonoindentation
   \dochecknextindentation\??fn
   \dorechecknextindentation} % here ?

%D Named subformulas

\def\startnamedsubformulas
  {\dosingleempty\dostartnamedsubformulas}

\def\dostartnamedsubformulas[#1]#2%
  {\setformulalistentry{#2}%
   \startsubformulas[#1]}

\def\stopnamedsubformulas
  {\stopsubformulas}

\setupsubformulas
  [\c!conversion=\v!character,
%  \c!separator=\@@fmseparator,
   \c!separator=,%AM: for compatibility with \placesubformula
   \c!indentnext=\@@fmindentnext]

%D Experimental goodie:
%D
%D \startbuffer
%D \placelist[formula][criterium=text] \blank[2*big]
%D \placenamedformula[one]{first}  \startformula a = 1 \stopformula \endgraf
%D \placeformula                   \startformula a = 2 \stopformula \endgraf
%D \placenamedformula     {second} \startformula a = 3 \stopformula \endgraf
%D \stopbuffer
%D
%D \typebuffer \getbuffer

\definelist[\v!formula]

\global\let\doflushformulalistentry\gobbleoneargument

\def\setformulalistentry#1%
  {\gdef\doflushformulalistentry##1%
     {\expanded{\writetolist[\v!formula]{##1}}{#1}%
      \global\let\doflushformulalistentry\gobbleoneargument}}

\def\placenamedformula
  {\dosingleempty\doplacenamedformula}

\def\doplacenamedformula[#1]#2%
  {\iffirstargument
     \def\next{\placeformula[#1]}%
   \else
     \let\next\placeformula
   \fi
   \setformulalistentry{#2}%
   \next}

%D The implementation of placement is a bit ugly:

\def\doplaceformula[#1][#2]% #2 = dummy, gobbles spaces
  {\def\redoplaceformula
     {\bgroup
      \ifx\next\bgroup
        \egroup \@EA\moreplaceformula % [ref]{}
      \else
        \let\nextnext$% no def
        \ifx\next\nextnext
          \egroup \@EAEAEA\dispplaceformula % [ref]$$
        \else
          \egroup \@EAEAEA\dodoplaceformula % [ref]\start
        \fi
      \fi[#1]{}}%
   \futurelet\next\redoplaceformula}

\long\def\moreplaceformula[#1]#2#3#4% #2 dummy #4 gobbles spaces
  {\def\redoplaceformula
     {\bgroup
      \let\nextnext$% no def
      \ifx\next\nextnext
        \egroup \@EA\dispplaceformula % [ref]$$
      \else
        \egroup \@EA\dodoplaceformula % [ref]\start
      \fi
      [#1]{#3}}%
   \futurelet\next\redoplaceformula#4}

\let\startplaceformula\placeformula
\let\stopplaceformula \relax

\def\startformulas#1\stopformulas % new / to be internationalized
  {\bgroup
   \forgetdisplayskips
   \startdisplaymath
   \setlocalhsize
   \long\def\startformula##1\stopformula
     {\advance\scratchcounter\plusone}%
   \scratchcounter\zerocount
   #1% preroll
   \ifcase\scratchcounter\else
     \divide \hsize \scratchcounter
   \fi
   \hbox to \localhsize \bgroup
     \hss
     \def\normalstartformula{\vskip-\strutdepth$$}% i hate this
     \def\normalstopformula {$$}%
     \def\startformula      {$\vcenter\bgroup\normalstartformula}%
     \def\stopformula       {\normalstopformula\egroup$\hss}%
     #1%
     \egroup
   \stopdisplaymath
   \egroup
   \hangafter\minusone    % added for side floats
   \hangindent\zeropoint} % added for side floats

\def\dispplaceformula[#1]#2$$#3$$%
  {\dodoplaceformula[#1]{#2}\dostartformula{}#3\dostopformula}

\let\normalreqno\eqno
\let\normalleqno\leqno

\let\donestedformulanumber\gobbletwoarguments

\def\dodoplaceformula[#1]#2% messy, needs a clean up
  {\doifelse{#1}{-}
     {\setfalse\handleformulanumber}
     {\doifelse{#2}{-}
        {\setfalse\handleformulanumber}
        {\settrue\handleformulanumber}}%
   \ifconditional\handleformulanumber
     \def\formulanumber
       {%\global\let\subformulanumber\doformulanumber % no, bug
        \doformulanumber[#1][#2]}%
     \def\donestedformulanumber##1##2%
       {\doifsomething{##1}
          {\doifelse{##1}{+}{\doformulanumber[#1]}{\doformulanumber[##1]}[##2][]{}}}%
     \def\subformulanumber
       {\setfalse\incrementformulanumber
        \formulanumber}%
     \gdef\doplaceformulanumber
       {\global\let\doplaceformulanumber\empty
        \doifelse\@@fmlocation\v!left
          {\normalleqno{\doformulanumber[#1][#2][]{}}}
          {\normalreqno{\doformulanumber[#1][#2][]{}}}}%
   \else
     \def\formulanumber{\doformulanumber[#1][#2]}%
     \let\donestedformulanumber\gobbletwoarguments
     \let\subformulanumber\doformulanumber % was \global
     \global\let\doplaceformulanumber\empty
   \fi}

%D We need a hook into the plain math alignment macros
%D
%D \starttyping
%D \displaylines
%D \eqalignno
%D \eqalignno
%D \stoptyping
%D
%D Otherwise we get a missing \type {$$} error reported.

\def\resetdisplaymatheq
  {\let\normalleqno\relax \let\leqno\relax
   \let\normalreqno\relax \let\eqno \relax
   \let\doplaceformulanumber\empty}

%D The next code is derived from plain \TEX.

\newif\ifdt@p

\def\displ@y
  {\global\dt@ptrue
   \openup\displayopenupvalue % was \openup\jot
   \everycr
     {\noalign
        {\ifdt@p
           \global\dt@pfalse
           \ifdim\prevdepth>-1000\p@
             \vskip-\lineskiplimit
             \vskip\normallineskiplimit
           \fi
         \else
           \penalty\interdisplaylinepenalty
         \fi}}}

\let\normaldispl@y\displ@y

\def\displ@y{\resetdisplaymatheq\normaldispl@y}

\def\m@th{\mathsurround\z@}

%D Here we implement a basic math alignment mechanism. Numbers
%D are also handled. The macros \type {\startinnermath} and
%D \type {\stopinnermath} can be overloaded in speciali