strc-mat.mkii / last modification: 2020-01-30 14:15
%D \module
%D   [       file=strc-mat,
%D        version=2006.03.27, % 1998.12.07
%D          title=\CONTEXT\ Structure Macros,
%D       subtitle=Math Fundamentals,
%D         author={Hans Hagen, Taco Hoekwater \& Aditya Mahajan},
%D           date=\currentdate,
%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
%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

\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}

% % messages moved

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

% \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

\unexpanded\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\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 ?
\@@fmnumbercommand
{\dostartattributes\??fm\c!numberstyle\c!numbercolor
\strut
\@@fmleft
\preparefullnumber\??fm\composedsectionnumber\preparednumber
\labeltexts\v!formula
{\ignorespaces\preparednumber\ignorespaces\hetsubnummer\unskip}%
\@@fmright
\dostopattributes}%
\fi
\egroup}

\def\dodoformulanumber[#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
\fi
\advance\predisplaysize \displayindent % needed ?
\ifdim\predisplaysize>\hsize
\predisplaysize\hsize
\fi
\else
\predisplaysize\zeropoint
\fi}

\def\setdisplaydimensions
{\displayindent\leftdisplayskip
\displaywidth\hsize
% \setlocalhsize
% \displaywidth\localhsize
\ifdim\hangindent>\zeropoint
\else
\fi
\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
\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
\ifindentfirstparagraph % tricky, probably needs more testing
\prevdepth-\maxdimen % texbook pagina 79-80
% otherwise problems at the top of a page, don't remove:
\verticalstrut
\vskip-\struttotal
\vskip-\baselineskip
\fi
\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]

% \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\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. \newcount\interdisplaylinepenalty \interdisplaylinepenalty=100 \newif\ifdt@p \def\displ@y {\global\dt@ptrue \openup\displayopenupvalue % was \openup\jot \everycr {\noalign {\ifdt@p \global\dt@pfalse \ifdim\prevdepth>-\thousandpoint \vskip-\lineskiplimit \vskip\normallineskiplimit \fi \else \penalty\interdisplaylinepenalty \fi}}} \let\normaldispl@y\displ@y \def\displ@y{\resetdisplaymatheq\normaldispl@y} \def\m@th{\mathsurround\zeropoint} % obsolete %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 specialized %D modules. \def\startinnermath {\getvalue{\e!start\??fm\formulaparameter\c!align}} \def\stopinnermath {\getvalue{\e!stop \??fm\formulaparameter\c!align}} \def\mathinnerstrut {\doif{\formulaparameter\c!strut}\v!yes\strut} \long\def\defineinnermathhandler#1#2#3% {\setvalue{\e!start\??fm#1}{#2}% \setvalue{\e!stop \??fm#1}{#3}} \newif\iftracemath \def\mathhbox {\iftracemath\ruledhbox\else\hbox\fi} \chardef\mathraggedstatus=0 % normal left center right \chardef\mathnumberstatus=0 % nothing normal shift_right \let\mathnumbercorrection\!!zeropoint \def\startmathbox#1% {\hsize\displaywidth \global\chardef\mathnumberstatus\plusone \chardef\mathraggedstatus#1\relax \let\mathnumbercorrection\!!zeropoint \global\let\@eqno \empty \def\eqno {\gdef\@eqno }% \global\let\@leqno\empty \def\leqno{\gdef\@leqno}% % added \let\normalreqno\eqno \let\normalleqno\leqno % added \doplaceformulanumber \setbox\scratchbox\mathhbox to \displaywidth\bgroup \mathinnerstrut % \displaystyle \ifcase\mathraggedstatus\or\hfill\or\hfill\fi} \def\llappedmathno {\ifcase\mathraggedstatus\or \@eqno \or \llap{\@eqno}% \or \llap{\@eqno}% \fi} \def\rlappedmathno {\ifcase\mathraggedstatus\or \rlap{\@leqno}% \or \rlap{\@leqno}% \or \@leqno \fi} \def\stopmathbox {% \ifcase\mathraggedstatus\or\or\hfill\or\hfill\fi \egroup \setbox0\hbox{\unhcopy\scratchbox}% \scratchdimen\wd0 \ifdim\scratchdimen>\displaywidth \donetrue \else \donefalse \fi \hbox to \displaywidth\bgroup \ifcase\mathnumberstatus \box\scratchbox \or \ifx\@leqno\empty \ifx\@eqno\empty \box\scratchbox \else \ifdone \vbox{\box\scratchbox\hbox to \displaywidth{\hss\llappedmathno}}% \else \hss\box\scratchbox\llappedmathno % hss makes room for number \fi \fi \else \ifdone \vbox{\hbox to \displaywidth{\rlappedmathno\hss}\box\scratchbox}% \else \rlappedmathno\box\scratchbox\hss % hss makes room for number \fi \fi \or \hskip\mathnumbercorrection \box\scratchbox \hss \else \box\scratchbox \fi \egroup} \defineinnermathhandler\v!left {\startmathbox\plusone }{\stopmathbox} \defineinnermathhandler\v!middle {\startmathbox\plustwo }{\stopmathbox} \defineinnermathhandler\v!right {\startmathbox\plusthree}{\stopmathbox} \defineinnermathhandler\v!flushleft {\startmathbox\plusthree}{\stopmathbox} \defineinnermathhandler\v!center {\startmathbox\plustwo }{\stopmathbox} \defineinnermathhandler\v!flushright{\startmathbox\plusone }{\stopmathbox} %D [The examples below are in english and don't process in the %D documentation style, which will be english some day.] %D %D Normally a formula is centered, but in case you want to %D align it left or right, you can set up formulas to behave %D that way. Normally a formula will adapt is left indentation %D to the environment: %D %D \startbuffer %D \fakewords{20}{40}\epar %D \startitemize %D \item \fakewords{20}{40}\epar %D \placeformula \startformula \fakeformula \stopformula %D \item \fakewords{20}{40}\epar %D \stopitemize %D \fakewords{20}{40}\epar %D \stopbuffer %D %D % \getbuffer %D %D In the next examples we explicitly align formulas to the %D left (\type {\raggedleft}), center and right (\type %D {\raggedright}): %D %D \startbuffer %D \setupformulas[align=left] %D \startformula\fakeformula\stopformula %D \setupformulas[align=middle] %D \startformula\fakeformula\stopformula %D \setupformulas[align=right] %D \startformula\fakeformula\stopformula %D \stopbuffer %D %D \typebuffer %D %D Or in print: %D %D % {\getbuffer} %D %D With formula numbers these formulas look as follows: %D %D \startbuffer %D \setupformulas[align=left] %D \placeformula \startformula\fakeformula\stopformula %D \setupformulas[align=middle] %D \placeformula \startformula\fakeformula\stopformula %D \setupformulas[align=right] %D \placeformula \startformula\fakeformula\stopformula %D \stopbuffer %D %D % {\getbuffer} %D %D This was keyed in as: %D %D \typebuffer %D %D When tracing is turned on (\type {\tracemathtrue}) you can %D visualize the bounding box of the formula, %D %D % {\tracemathtrue\getbuffer} %D %D As you can see, the dimensions are the natural ones, but if %D needed you can force a normalized line: %D %D \startbuffer %D \setupformulas[strut=yes] %D \placeformula \startformula \fakeformula \stopformula %D \stopbuffer %D %D \typebuffer %D %D This time we get a more spacy result. %D %D % {\tracemathtrue\getbuffer} %D %D We will now show a couple of more settings and combinations %D of settings. In centered formulas, the number takes no space %D %D \startbuffer %D \setupformulas[align=middle] %D \startformula \fakeformula \stopformula %D \placeformula \startformula \fakeformula \stopformula %D \stopbuffer %D %D \typebuffer % {\tracemathtrue\getbuffer} %D %D You can influence the placement of the whole box with the %D parameters \type {leftmargin} and \type {rightmargin}. %D %D \startbuffer %D \setupformulas[align=right,leftmargin=3em] %D \startformula \fakeformula \stopformula %D \placeformula \startformula \fakeformula \stopformula %D %D \setupformulas[align=left,rightmargin=1em] %D \startformula \fakeformula \stopformula %D \placeformula \startformula \fakeformula \stopformula %D \stopbuffer %D %D \typebuffer % {\tracemathtrue\getbuffer} %D %D You can also inherit the margin from the environment. %D %D \startbuffer %D \setupformulas[align=right,margin=standard] %D \startformula \fakeformula \stopformula %D \placeformula \startformula \fakeformula \stopformula %D \stopbuffer %D %D \typebuffer % {\tracemathtrue\getbuffer} %D %D The distance between the formula and the number is only %D applied when the formula is left or right aligned. %D %D \startbuffer %D \setupformulas[align=left,distance=2em] %D \startformula \fakeformula \stopformula %D \placeformula \startformula \fakeformula \stopformula %D \stopbuffer %D %D \typebuffer % {\tracemathtrue\getbuffer} %D \macros %D {big..} %D %D Because they are related to the bodyfontsize, we redefine %D some \PLAIN\ macros. \def\@@dobig#1#2% {{\hbox{\left#2\vbox\!!to#1\bodyfontsize{}\right.\nulldelimiterspace\zeropoint\relax\mathsurround\zeropoint}}} \def\big {\@@dobig{0.85}} \def\Big {\@@dobig{1.15}} \def\bigg{\@@dobig{1.45}} \def\Bigg{\@@dobig{1.75}} %D \macros %D {bordermatrix} %D %D We already redefined \type {\bordermatrix} in \type %D {font-ini}. %D \macros %D {setuptextformulas} %D %D This command sets up in||line math. Most features deals %D with grid snapping and are experimental. \newevery \everysetuptextformulas \relax \def\setuptextformulas {\dosingleempty\dosetuptextformulas} \def\dosetuptextformulas[#1]% {\getparameters[\??mt][#1]% \the\everysetuptextformulas} %D \macros %D {super, sub} %D %D \TEX\ uses \type{^} and \type{_} for entering super- and %D subscript mode. We want however a bit more control than %D normally provided, and therefore provide \type {\super} %D and \type{sub}. \global\let\normalsuper=^ \global\let\normalsuber=_ \newcount\supersubmode \newevery\everysupersub \EverySuperSub \appendtoks \advance\supersubmode \plusone \to \everysupersub \appendtoks \gridsupsubstyle \to \everysupersub \appendtoks \doifelse\@@mtsize\v!small {\let\gridsupsubstyle \scriptscriptstyle \let\gridsupsubbodyfont \setsmallbodyfont}% {\let\gridsupsubstyle \scriptstyle \let\gridsupsubbodyfont \relax}% \to \everysetuptextformulas \setuptextformulas [\c!size=\v!normal] \def\dogridsupsub#1#2% {\begingroup \setbox\nextbox\iftracegridsnapping\ruledhbox\else\hbox\fi {\gridsupsubbodyfont \strut^{\the\everysupersub#1}_{\the\everysupersub#2}}% \nextboxht\strutheight \nextboxdp\strutdepth \flushnextbox \endgroup} \def\gridsupsub {\ifconditional\crazymathsnapping \ifgridsnapping \@EAEAEA\dogridsupsub \else \@EAEAEA\normalsupsub \fi \else \@EA\normalsupsub \fi} \def\normalsupsub#1#2% {^{\the\everysupersub#1}_{\the\everysupersub#2}} \appendtoks \let\gridsupsubstyle \relax \let\gridsupsubbodyfont\relax \let\gridsupsub \normalsupsub \to \everydisplay \def\super#1{^{\the\everysupersub#1}} \def\suber#1{_{\the\everysupersub#1}} \def\supsub#1#2{\super{#1}\suber{#2}} \def\subsup#1#2{\suber{#1}\super{#2}} %\def\super#1{\gridsupsub{#1}{}} % %\def\suber#1{\gridsupsub{}{#1}} % % %\def\supsub#1#2{\gridsupsub{#1}{#2}} %\def\subsup#1#2{\gridsupsub{#2}{#1}} \def\gridsuper#1{\gridsupsub{#1}{}} \def\gridsuber#1{\gridsupsub{}{#1}} % \let\sup\super % math char % \let\sub\suber % test set: % % \startbuffer % \sform{x\frac{1}{2}} % \sform{x\sup{\frac{1}{2}} + x\sup{2} + 2} % \sform{x\supsub{\frac{1}{2}}{\frac{1}{2}} + x\sup{2} + 2} % \stopbuffer % % \typebuffer % % \startlines % \getbuffer % \stoplines % % \startbuffer % x\frac{1}{2} % x\sup{\frac{1}{2}} + x^2 + 2 % x\supsub{\frac{1}{2}}{\frac{1}{2}} + x^2 + 2 % \stopbuffer % % \typebuffer % % \start % \enablesupersub % \enableautomath % \startlines % \getbuffer % \stoplines % \stop %D \macros %D {enablesupersub,enablesimplesupersub} %D %D We can let \type {^} and \type {_} act like \type {\super} %D and \type {\sub} by saying \type {\enablesupersub}. \bgroup \catcode\^=\@@active \catcode\_=\@@active \gdef\enablesupersub {\catcode\^=\@@active \def^{\ifmmode\expandafter\super\else\expandafter\normalsuper\fi}% \catcode\_=\@@active \def_{\ifmmode\expandafter\suber\else\expandafter\normalsuber\fi}} \egroup %D \macros %D {enableautomath} %D %D The next one can be dangerous, but handy in controlled %D situations. \bgroup \catcode\=\active \gdef\enableautomath {\catcode\=\active \def##1{\snappedinlineformula{##1}}} % \gdef\enableautomath % {\catcode\=\active % \def{\doifnextcharelse\doautodmath\doautoimath}% % \def\doautoimath##1{\snappedinlineformula{##1}}% % \def\doautodmath##1{\startformula##1\stopformula}} \egroup %D \macros %D {...} %D %D New and experimental: snapping big inline math! \newconditional\halfcrazymathlines % \settrue\halfcrazymathlines \newconditional\crazymathsnapping % \settrue\crazymathsnapping \appendtoks \doifelse\@@mtgrid\v!yes \settrue\setfalse\crazymathsnapping \doifelse\@@mtstep\v!halfline\settrue\setfalse\halfcrazymathlines \to \everysetuptextformulas \setuptextformulas [\c!grid=\v!yes, \c!step=\v!line] \newcount\crazymathhack \let\lastcrazymathline \!!zeropoint \let\lastcrazymathpage \!!zerocount \let\lastcrazymathprelines \!!zerocount \let\lastcrazymathpostlines\!!zerocount \def\crazymathtag{amh:\the\crazymathhack} \def\crazytexttag{\v!text:\lastcrazymathpage} \def\crazymathindent{\hskip\MPx\crazymathtag\hskip-\MPx\crazytexttag} \def\flushcrazymathbox {\nextboxht\strutheight \nextboxdp\strutdepth \hbox{\iftracegridsnapping\ruledhbox\fi{\flushnextbox}}} % possible pdftex bug: % % \dorecurse{100}{gest \vadjust {\strut} \par} \page % \dorecurse{100}{gest \vadjust pre {\strut} \par} \page % % duplicate depth compensation with pre \def\snappedinlineformula {\dosingleempty\dosnappedinlineformula} %D \starttabulate[|Tl|l|] %D \NC - \NC half lines \NC \NR %D \NC + \NC full lines \NC \NR %D \NC = \NC force \NC \NR %D \NC < \NC force, minus pre \NC \NR %D \NC > \NC force, minus post \NC \NR %D \stoptabulate \newif\if!!donee \newif\if!!donef \def\inlinemathmargin{1pt} \settrue\autocrazymathsnapping % FROM NOW ON, CHANGES AS OPTIONS % TODO: SKYLINE (PREV LINE POS SCAN) \def\dosnappedinlineformula[#1]#2% {\ifvmode\dontleavehmode\fi % tricky \strut % prevents funny space at line break \begingroup % interesting: \bgroup can make \vadjust disappear \ifconditional\crazymathsnapping \ifgridsnapping \ifx\pdftexversion\undefined \donefalse \else \checktextbackgrounds % we need pos tracking, to be made less redundant \donetrue \fi \else \donefalse \fi \else \donefalse \fi \!!doneafalse % forced or not auto \!!donebfalse % too heigh \!!donecfalse % too low \!!donedfalse % less before \!!doneefalse % less after \ifdone \setbox\nextbox\hbox{#2}% \iftracegridsnapping \setbox\nextbox\ruledhbox {\incolortrue\localcolortrue \backgroundline[gray]{\showstruts\strut\flushnextbox}}% \fi \def\docommand##1% {\doif{##1}-{\settrue \halfcrazymathlines}% \doif{##1}+{\setfalse\halfcrazymathlines}% \doif{##1}={\!!doneatrue}% \doif{##1}<{\!!donedtrue}% \doif{##1}>{\!!doneetrue}}% \processcommalist[#1]\docommand \if!!doneb \if!!donec \else \setfalse\halfcrazymathlines \fi \else \if!!donec \setfalse\halfcrazymathlines \fi \fi \donefalse \if!!donea \donetrue \scratchdimen \nextboxht \advance\scratchdimen .5\lineheight \nextboxht\scratchdimen \scratchdimen \nextboxdp \advance\scratchdimen .5\lineheight \nextboxdp\scratchdimen \else\ifdim\nextboxht>\strutht \donetrue \else\ifdim\nextboxdp>\strutdp \donetrue \fi\fi\fi \ifconditional\autocrazymathsnapping \else \if!!donea \else % don't compensate, just snap to strut \donefalse % signal for next else, snap line to strut \!!doneatrue \fi \fi \fi \ifdone % analyze height \scratchdimen\inlinemathmargin \advance\scratchdimen \strutht \ifdim\nextboxht<\scratchdimen \else \!!donebtrue \fi % analyze depth \scratchdimen\inlinemathmargin \advance\scratchdimen \strutdp \ifdim\nextboxdp<\scratchdimen \else \!!donectrue \fi % analyzed or forced \ifdone \global\advance\crazymathhack\plusone \donefalse \ifnum\MPp\crazymathtag=\lastcrazymathpage\relax \ifdim\MPy\crazymathtag=\lastcrazymathline\relax \donetrue \fi \fi \ifnum\MPp\crazymathtag=\zerocount \donefalse \fi \ifdim\MPy\crazymathtag=\zeropoint \donefalse \fi \ifdone % same page and same line \else \global\let\lastcrazymathprelines \!!zerocount \global\let\lastcrazymathpostlines\!!zerocount \xdef\lastcrazymathpage{\MPp\crazymathtag}% \xdef\lastcrazymathline{\MPy\crazymathtag}% \fi \if!!doneb % \getrawnoflines\nextboxht \scratchdimen\nextboxht \advance\scratchdimen-\strutht \getnoflines\scratchdimen \if!!doned \advance\noflines\minusone \fi \scratchcounter\noflines \advance\noflines-\lastcrazymathprelines\relax \ifnum\noflines>\zerocount \xdef\lastcrazymathprelines{\the\scratchcounter}% \scratchdimen\noflines\lineheight \ifconditional\halfcrazymathlines \advance\scratchdimen-.5\lineheight \fi \advance\scratchdimen-\strutdepth \setbox\scratchbox\null \wd\scratchbox2\bodyfontsize \ht\scratchbox\scratchdimen \dp\scratchbox\strutdepth %%% top correction code (see below) \normalvadjust pre {%\allowbreak % sometimes breaks spacing \forgetall \crazymathindent \iftracegridsnapping \setbox\scratchbox\hbox {\incolortrue\localcolortrue\green \ruledhbox{\box\scratchbox}}% \fi \box\scratchbox \endgraf \nobreak}% \else\ifnum\scratchcounter>\zerocount \normalvadjust pre {\nobreak}% \fi\fi \fi \if!!donec % \getrawnoflines\nextboxdp \scratchdimen\nextboxdp \advance\scratchdimen-\strutdp \getnoflines\scratchdimen \if!!donee \advance\noflines\minusone \fi \scratchcounter\noflines \advance\noflines-\lastcrazymathpostlines\relax \ifnum\noflines>\zerocount \donetrue \else\ifnum\lastcrazymathpostlines=\zerocount \donetrue \else \donefalse \fi\fi \else \donefalse \fi \ifdone \xdef\lastcrazymathpostlines{\the\scratchcounter}% \ifnum\lastcrazymathpostlines=\zerocount \global\let\lastcrazymathpostlines\!!plusone \fi \hbox{\setposition\crazymathtag\flushcrazymathbox}% \scratchdimen\noflines\lineheight \advance\scratchdimen-\lineheight \advance\scratchdimen+\strutheight \ifdim\scratchdimen>\zeropoint \else \scratchdimen=\strutheight % todo : test for half lines \fi \ifconditional\halfcrazymathlines \advance\scratchdimen-.5\lineheight \fi \setbox\scratchbox\null \wd\scratchbox2\bodyfontsize \ht\scratchbox\scratchdimen \dp\scratchbox\strutdepth \normalvadjust {\forgetall \crazymathindent \iftracegridsnapping \setbox\scratchbox\hbox {\incolortrue\localcolortrue\color[blue]{\ruledhbox{\box\scratchbox}}}% \fi \box\scratchbox \endgraf % precaution: else we stick below the text bottom \ifconditional\halfcrazymathlines \allowbreak \else \vskip-\lineheight \vskip \lineheight \fi}% \else \hbox{\setposition\crazymathtag\flushcrazymathbox}% \fi \else \flushcrazymathbox \fi \else\if!!donea \flushcrazymathbox \else \mathematics{#2}% \fi\fi \endgroup} %%% top correction code %%% %%% correct for fuzzy top of page situations % % \scratchdimen\lastcrazymathprelines\lineheight % \advance\scratchdimen\MPy\crazymathtag % \advance\scratchdimen\lineheight % \advance\scratchdimen\topskip % \advance\scratchdimen-\strutheight % \dimen0=\MPy\crazytexttag % \advance\dimen0 \MPh\crazytexttag % \advance\scratchdimen-\dimen0\relax % % do we need correction at all % \ifdim\scratchdimen>\strutdepth\relax % \donefalse % \else\ifdim\scratchdimen<\zeropoint % \donefalse % \else % \donetrue % \fi\fi % % analysis done % \donefalse % \ifdone % \edef\crazymathcorrection{\the\scratchdimen}% % \advance\scratchdimen-\dp\scratchbox % \dp\scratchbox-\scratchdimen % \else % \let\crazymathcorrection\zeropoint % \fi % %%% %%% keep the previous code %%% \let\tform\mathematics \let\gform\snappedinlineformula % test set: % % \startbuffer % Crazy math \gform {1+x} or \gform {\dorecurse {100} {1+} 1 = % 101} and even gore crazy \gform {2^{2^2}_{1_1}} % again\dorecurse {20} { and again} \gform {\sqrt {\frac % {x^{5^5}} {\frac {1} {2}}}} even gore\dorecurse {50} { and % gore} \tform {\dorecurse {12} {\gform {\sqrt {\frac % {x^{5^5}} {3}}}+\gform {\sqrt {\frac {x^{5^5}} {\frac {1} % {2}}}}+}x=10}\dorecurse{20} { super crazy math}: \tform % {\dorecurse {30} {\gform {\sqrt {\frac {x^{5^5}} {3}}}+ % \gform {\sqrt {\frac {x^{5^5}} {\frac {1} {2}}}}+ }x = 10}, % and we're\dorecurse {20} { done}! % \stopbuffer % % \setupcolors[state=start] \setuppapersize[S6][S6] % % \showgrid \tracegridsnappingtrue \showstruts % % \starttext % \setuplayout[grid=yes,lines=15]\getbuffer \page % \setuplayout[grid=yes,lines=16]\getbuffer \page % \setuplayout[grid=yes,lines=17]\getbuffer \page % \setuplayout[grid=yes,lines=18]\getbuffer \page % \setuplayout[grid=yes,lines=19]\getbuffer \page % \stoptext % % test % % \startregels % \gform[<]{35 \cdot p^{\frac{3}{4}} = 70} % \gform{12{,}4 \cdot d^3 = 200} % \gform{a \cdot x^b}. % \gform{12x^6 \cdot \negative 3x^4} % \gform{\frac{12x^6}{\negative 3x^4}} % \gform{(4x^2)^3} % \gform{4x \sqrt{x} \cdot 3x^2} % \gform{\frac{2x^4}{4x \sqrt{x}}} % \gform{y = a \cdot x^b}. % \gform{y_1 = \frac{15x^2}{x}} % \gform{y_2 = x \cdot \sqrt{x}} % \gform{y_3 = \frac{6x^3}{x^2}} % \gform[<]{y_4 = \left(2x^2\right)^{\frac{1}{2}}} % \gform{y_1 = \frac{4x^5}{x^2}} % \gform{y_2 = 4 \cdot \sqrt{x}} % \gform{y_3 = 4x^3} % \gform{y_4 = \frac{100x}{\sqrt{x}}} % \gform[<]{y_5 = 4 \cdot x^{\frac{1}{2}}} % \gform{y_6 = \frac{1}{2} x \cdot 4x^2} % \gform{y_7 = 2 \cdot x^3} % \gform{y_8 = 100 \cdot x^{\frac{1}{2}}} % \gform{4x^8 \cdot 8x^3} % \gform{\frac{4x^8}{8x^3}} % \gform{\left(\negative3x^4\right)^3} % \gform{x^3 \sqrt{x} \cdot 3x^2} % \gform{\frac{6x^3}{x^2 \sqrt{x}}} % \gform{\frac{6}{2x^4}} % \gform{\frac{1}{3x^6}} % \gform{\frac{12x^8}{4x^{10}}} % \gform{\frac{4}{\sqrt{x}}} % \gform{\frac{1}{2x \sqrt{x}}} % \gform{\frac{2{,}25}{p} = 0{,}35} % \gform{4{,}50 + \frac{300}{k} = 4{,}70} % \gform{\frac{1200}{k+12} - 42 = 6} % \stopregels %D \macros %D {restoremathstyle} %D %D We can pick up the current math style by calling \type %D {\restoremathstyle}. \def\restoremathstyle {\ifmmode \ifcase\supersubmode \textstyle \or \scriptstyle \else \scriptscriptstyle \fi \fi} %D \macros %D {mathstyle} %D %D If one want to be sure that something is typeset in the %D appropriate style, \type {\mathstyle} can be used: %D %D \starttyping %D \mathstyle{something} %D \stoptyping \def\mathstyle#1% {\mathchoice {\displaystyle #1}% {\textstyle #1}% {\scriptstyle #1}% {\scriptscriptstyle#1}} %D Something similar can be used in the (re|)|definition %D of \type {\text}. This version is a variation on the one %D in the math module (see \type{m-math} and|/|or \type %D {m-newmat}). \unexpanded\def\mathtext {\mathortext\domathtext\hbox} \def\domathtext#1% {\mathchoice {\dodomathtext\displaystyle \textface {#1}}% {\dodomathtext\textstyle \textface {#1}}% {\dodomathtext\scriptstyle \scriptface {#1}}% {\dodomathtext\scriptscriptstyle\scriptscriptface{#1}}} \def\dodomathtext#1#2#3% no \everymath ! %{\hbox{\everymath{#1}\switchtobodyfont [#2]#3}} % 15 sec {\hbox{\everymath{#1}\setcurrentfontbody{#2}#3}} % 3 sec (no math) %D Because we may overload \type {\text} in other (structuring) %D macros, we say: \appendtoks \let\text\mathtext \to \everymathematics %D \macros %D {\definemathalignment, setupmathalignment, startmathalignment} %D %D Modules may provide additional alignment features. The following %D mechanisms are provided by the core. % n>1 #### needed, strange # interaction in recurse \def\presetdisplaymath{\displ@y} % some day i will relocate the plain stuff \def\buildeqalign {\scratchtoks\emptytoks \dorecurse{\mathalignmentparameter\c!m} {\ifnum\recurselevel>\plusone \appendtoks \tabskip\mathalignmentparameter\c!distance&\tabskip\zeropoint \to\scratchtoks \fi \expanded{\scratchtoks{\the\scratchtoks\the\!!toksa}}% \dorecurse{\numexpr\mathalignmentparameter\c!n-\plusone\relax} {\expanded{\scratchtoks{\the\scratchtoks\the\!!toksb}}}}% \expanded{\scratchtoks{\the\scratchtoks\the\!!toksc}}} \def\forgetalign {\tabskip\zeropoint\everycr\emptytoks} \let\firstineqalign\empty \let\nextineqalign \empty \let\leftofeqalign \empty \let\rightofeqalign\empty \def\mathineqalign#1{\forgetalign\displaystyle{{}#1{}}} \def\textineqalign#1{\forgetalign#1} \def\eqalign#1% why no halign here, probably because of displaywidth {\null\,\vcenter {\openup.25\bodyfontsize% was: \openup\jot \mathsurround\zeropoint \ialign{\strut\hfil\displaystyle{##}$&$\displaystyle{{}##{}}\hfil\crcr#1\crcr}% }\,} % preamble is scanned for tabskips so we need the span to prevent an error message \chardef\eqalignmode\plusone \def\preparereqalignno {\!!toksa{\strut\firstineqalign\hfil\leftofeqalign\span\mathineqalign{##}\rightofeqalign\tabskip\zeropoint}% \!!toksb{&\nextineqalign\leftofeqalign\span\mathineqalign{##}\rightofeqalign\tabskip\zeropoint}% \ifnum\mathraggedstatus=\plusone \!!toksc{\hfil&\span\textineqalign{##}\tabskip\zeropoint}% \else\ifnum\mathraggedstatus=\plusthree \!!toksc{\hfil\tabskip\zeropoint\!!plus 1\!!fill&\span\textineqalign{##}\tabskip\zeropoint}% \else \!!toksc{\hfil\tabskip\centering&\llap{\span\textineqalign{##}}\tabskip\zeropoint}% \fi\fi \global\chardef\mathnumberstatus\zerocount \buildeqalign \presetdisplaymath \tabskip\centering} \def\prepareleqalignno {\!!toksa{\strut\firstineqalign\hfil\leftofeqalign\span\mathineqalign{##}\rightofeqalign\tabskip\zeropoint}% \!!toksb{&\nextineqalign\leftofeqalign\span\mathineqalign{##}\rightofeqalign\tabskip\zeropoint}% % problem: number is handled after rest and so ends up in the margin \ifnum\mathraggedstatus=\plusone \!!toksc{\hfil&\kern-\displaywidth\rlap{\span\textineqalign{##}}\tabskip\displaywidth}% \else\ifnum\mathraggedstatus=\plusthree \!!toksc{\hfil\tabskip\zeropoint\!!plus 1\!!fill&\kern-\displaywidth\span\mrlap{\span\textineqalign{##}}\tabskip\displaywidth}% \else \!!toksc{\hfil\tabskip\centering&\kern-\displaywidth\rlap{\span\textineqalign{##}}\tabskip\displaywidth}% \fi\fi \global\chardef\mathnumberstatus\zerocount \buildeqalign \presetdisplaymath \tabskip\centering} \def\dobotheqalignno#1#2% {\ifmmode \displ@y % \let\doplaceformulanumber\relax % strange hack \vcenter\bgroup \let\finishalignno\egroup \else \let\finishalignno\relax \fi #1% \halign \ifcase\eqalignmode \or to \displaywidth \fi \@EA {\the\scratchtoks\crcr#2\crcr}% \finishalignno} \def\dobothaligneqalignno#1% {\ifmmode \displ@y \global\chardef\mathnumberstatus\plusone \ifcase\mathraggedstatus \def\finishalignno{\crcr\egroup}% \else % we're in a mathbox \vcenter\bgroup \def\finishalignno{\crcr\egroup\egroup}% \fi \fi #1% \halign \ifcase\eqalignmode \or to \displaywidth \fi \@EA \bgroup\the\scratchtoks\crcr} \def\mrlap#1% {\setbox\scratchbox\hbox{#1}% \ifdim\wd\scratchbox>\mathnumbercorrection \xdef\mathnumbercorrection{\the\wd\scratchbox}% \fi \box\scratchbox \global\chardef\mathnumberstatus\plustwo} % \def\dobothaligneqalignno#1% % {\ifmmode % \displ@y % \global\chardef\mathnumberstatus\plusone % we're in a mathbox % \vcenter\bgroup % \def\finishalignno{\crcr\egroup\egroup}% % \else % \def\finishalignno{\crcr\egroup}% % \fi % #1% % \halign \ifcase\eqalignmode \or to \displaywidth \fi \@EA \bgroup\the\scratchtoks\crcr} \def\reqalignno {\dobotheqalignno \preparereqalignno} \def\leqalignno {\dobotheqalignno \prepareleqalignno} \def\alignreqalignno{\dobothaligneqalignno\preparereqalignno} \def\alignleqalignno{\dobothaligneqalignno\prepareleqalignno} \def\finishalignno {\crcr\egroup} \let \equalignno \reqalignno \let\aligneqalignno\alignreqalignno %D Here we implement the user interface part. \def\setupmathalignment {\dodoubleempty\dosetupmathalignment} \def\dosetupmathalignment[#1][#2]% {\ifsecondargument \getparameters[\??eq#1][#2]% \else \getparameters[\??eq][#1]% \fi} \let\currentmathalignment\empty \def\mathalignmentparameter#1% {\executeifdefined{\??eq\currentmathalignment#1}{\executeifdefined{\??eq#1}\empty}} \setupmathalignment [\c!n=2, \c!m=1, \c!distance=1em] \def\numberedeqalign {\doifelse\@@fmlocation\v!left\alignleqalignno\alignreqalignno} \def\doxxdoubleempty#1#2% {\ifx#2[\expandafter\dodoxxdoubleempty\else\expandafter\noxxdoubleempty\fi#1#2} \def\dodoxxdoubleempty#1[#2]#3% {\ifx#3[\else\expandafter\nonoxxdoubleempty\fi#1[#2]#3} \def\noxxdoubleempty #1{#1[][]} \def\nonoxxdoubleempty#1[#2]{#1[#2][]} \newcount\eqaligncolumn \def\firstineqalign{\global\eqaligncolumn\plusone} \def\nextineqalign {\global\advance\eqaligncolumn\plusone} \def\leftofeqalign {\getvalue{\??eq:\v!left :\number\eqaligncolumn}} \def\rightofeqalign{\getvalue{\??eq:\v!right:\number\eqaligncolumn}} \def\doseteqaligncolumn#1% {\letvalue{\??eq:\v!left :\number\eqaligncolumn}\empty \letvalue{\??eq:\v!right:\number\eqaligncolumn}\empty \doif{#1}\v!left {\letvalue{\??eq:\v!right:\number\eqaligncolumn}\hfill}% \doif{#1}\v!right {\letvalue{\??eq:\v!left :\number\eqaligncolumn}\hfill}% \doif{#1}\v!middle{\letvalue{\??eq:\v!right:\number\eqaligncolumn}\hfill \letvalue{\??eq:\v!left :\number\eqaligncolumn}\hfill}} \def\dodoalignNC {\gdef\doalignNC##1{&##1}} \def\doalignNR[#1][#2]% {\donestedformulanumber{#1}{#2}\crcr} %D \starttyping %D \placeformula[eqn0]\startformula \startalign[n=1] a\NR \stopalign \stopformula See \in[eqn0] %D \placeformula[eqn1]\startformula \startalign[n=1] a\NR \stopalign \stopformula See \in[eqn1] %D \placeformula \startformula \startalign[n=1] a\NR[eqn2] \stopalign \stopformula See \in[eqn2] %D \placeformula[eqn3]\startformula \startalign[n=1] a\NR[+] \stopalign \stopformula See \in[eqn3] %D \stoptyping % todo: pop in cell \def\dostartmathalignment[#1][#2]% {% \begingroup not permitted (...assignments...\halign... ) \pushmacro\doalignNC \edef\currentmathalignment{#1}% \doifassignmentelse{#2}{\setupmathalignment[#1][#2]}\donothing \def\NC{\doalignNC}% \global\let\doalignNC\dodoalignNC \def\EQ{&=}% \def\NR{&\global\let\doalignNC\dodoalignNC\doxxdoubleempty\doalignNR}% % amstex compatibility mode: (ugly, will disappear) \def\notag{\def\\{&\crcr}}% \doifelse{#2}{*}{\def\\{&\crcr}}{\def\\{&\doalignNR[+][]\crcr}}% % end of compatibility mode \eqaligncolumn\zerocount \processcommacommand [\mathalignmentparameter\c!align] {\advance\eqaligncolumn\plusone\doseteqaligncolumn}% takes argument % the real action \global\eqaligncolumn\plusone \numberedeqalign} \def\dostopmathalignment {\finishalignno \popmacro\doalignNC} \def\definemathalignment {\dodoubleempty\dodefinemathalignment} \def\dodefinemathalignment[#1]% [#2]% {\setvalue{\e!start#1}{\dodoubleempty\dostartmathalignment[#1]}% \setvalue{\e!stop #1}{\dostopmathalignment}% \setupmathalignment[#1]}% [#2] %D For the moment we only provide english commands. \definemathalignment[align] % default case (this is what amstex users expect) \definemathalignment[\v!mathalignment] % prefered case (this is cleaner, less clashing) %D \startbuffer %D \placeformula \startformula \eqalignno { %D a &= b & \formulanumber \cr %D c &= d \cr %D &= e \cr %D &= f & \formulanumber %D } \stopformula %D \stopbuffer %D %D \typebuffer \getbuffer %D %D \startbuffer %D \placeformula \startformula \startalign %D \NC a \EQ b \NR[+] %D \NC c \EQ d \NR %D \NC \EQ f \NR[for:demo-a-1] %D \NC \EQ g \NR[for:demo-a-2][a] %D \NC \EQ h \NR[for:demo-a-3][b] %D \NC \EQ i \NR %D \stopalign \stopformula %D \stopbuffer %D %D \typebuffer \getbuffer %D %D \startbuffer %D \placeformula \startformula \startalign %D \NC a \EQ b \NR[+] %D \NC c \EQ d \NR %D \NC \EQ f \NR %D \NC \EQ g \NR %D \NC \EQ h \NR %D \NC \EQ i \NR[+] %D \stopalign \stopformula %D \stopbuffer %D %D \typebuffer \getbuffer %D %D \startbuffer %D \placeformula \startformula \startalign %D a &= b \\ %D c &= d \notag \\ %D &= e \notag \\ %D &= f \\ %D \stopalign \stopformula %D \stopbuffer %D %D \typebuffer \getbuffer %D %D \startbuffer %D \placeformula \startformula \startalign %D \NC a \NC \eq b \NR[+] %D \NC c \NC \neq d \NR %D \NC \NC \neq f \NR[for:demo-b-1] %D \NC \NC \geq g \NR[for:demo-b-2][a] %D \NC \NC \leq h \NR[for:demo-b-3][b] %D \NC \NC \neq i \NR %D \stopalign \stopformula %D \stopbuffer %D %D \typebuffer \getbuffer %D %D \startbuffer %D \placeformula \startformula \startalign[*] %D a &= b \\ %D c &= d \\ %D &= e \\ %D &= f \\ %D \stopalign \stopformula %D \stopbuffer %D %D \typebuffer \getbuffer %D %D \startbuffer %D \placeformula \startformula \startalign %D x &= y \\ %D a &= b \\ %D \stopalign \stopformula %D \stopbuffer %D %D \typebuffer \getbuffer %D %D \startbuffer %D \placeformula \startformula \startalign[m=3] %D x &= y & x &= y & z &= t \\ %D a &= b & p &= q & w &= s \\ %D \stopalign \stopformula %D \stopbuffer %D %D \typebuffer \getbuffer %D %D \startbuffer %D \placeformula \startformula \startalign[m=3,distance=0pt] %D x &= y &= x &= y &= z &= t \\ %D a &= b &= p &= q &= w &= s \\ %D \stopalign \stopformula %D \stopbuffer %D %D \typebuffer \getbuffer %D %D \startbuffer %D \placeformula \startformula \startalign[n=5,distance=0pt] %D x &= yy &= xx &= yy &= zz \\ %D a &= b &= p &= q &= w \\ %D \stopalign \stopformula %D \stopbuffer %D %D \typebuffer \getbuffer %D %D \startbuffer %D \placeformula \startformula \startalign[n=3,align={left,middle,right}] %D \NC l \NC = \NC r \NR %D \NC left \NC = \NC right \NR %D \stopalign \stopformula %D \stopbuffer %D %D \typebuffer \getbuffer %D %D \startbuffer %D \placeformula \startformula \startalign[n=3,align={right,middle,left}] %D \NC l \NC = \NC r \NR %D \NC left \NC = \NC right \NR %D \stopalign \stopformula %D \stopbuffer %D %D \typebuffer \getbuffer %D %D \startbuffer %D \placeformula \startformula \startalign[n=3,align={middle,middle,middle}] %D \NC l \NC = \NC r \NR %D \NC left \NC = \NC right \NR %D \stopalign \stopformula %D \stopbuffer %D %D \typebuffer \getbuffer %D %D \startbuffer %D \placeformula %D \startformula %D \startalign[n=3,align={middle,middle,middle}] %D \NC a \NC = \NC b \NR[+] %D \NC 2a \NC = \NC 2b \NR %D \stopalign %D \stopformula %D \stopbuffer %D %D \typebuffer \getbuffer %D %D \startbuffer %D \placeformula %D \startformulas %D \setupmathalignment[n=3,align={middle,middle,middle}]% %D \startformula %D \startalign %D \NC a \NC = \NC b \NR[+] %D \NC 2a \NC = \NC 2b \NR %D \stopalign %D \stopformula %D \startformula %D \startalign %D \NC a \NC = \NC b \NR[+] %D \NC 2a \NC = \NC 2b \NR %D \stopalign %D \stopformula %D \stopformulas %D \stopbuffer %D %D \typebuffer \getbuffer %D %D \startbuffer %D \placeformula %D \startformulas %D \dorecurse{5}{\startformula %D \startalign[n=3,align={middle,middle,middle}] %D \NC a \NC = \NC b \NR[+] %D \NC 2a \NC = \NC 2b \NR %D \stopalign %D \stopformula} %D \stopformulas %D \stopbuffer %D %D \typebuffer \getbuffer %D \macros %D {definemathcases, setupmathcases, startmathcases} %D %D Another wish \unknown \def\setupmathcases {\dodoubleempty\dosetupmathcases} \def\dosetupmathcases[#1][#2]% {\ifsecondargument \getparameters[\??ce#1][#2]% \else \getparameters[\??ce][#1]% \fi} \let\currentmathcases\empty \def\mathcasesparameter#1% {\executeifdefined{\??ce\currentmathcases#1}{\executeifdefined{\??ce#1}\empty}} \setupmathcases [\c!distance=1em, \c!numberdistance=2.5em, \c!left={\left\{\,}, \c!right={\right.}] \def\dodocasesNC {\gdef\docasesNC{\endmath&}} \let\docasesNR\doalignNR \def\dostartmathcases[#1][#2]% {\begingroup \edef\currentmathcases{#1}% \doifassignmentelse{#2}{\setupmathcases[#1][#2]}\donothing \mathcasesparameter\c!left \vcenter\bgroup \pushmacro\docasesNC \let\endmath\relax \def\NC{\docasesNC}% \def\MC{\docasesNC\ifmmode\else\def\endmath{}\fi}% \global\let\docasesNC\dodocasesNC \def\NR{\unskip\endmath&\global\let\docasesNC\dodocasesNC\doxxdoubleempty\docasesNR}% \normalbaselines \mathsurround\zeropoint \everycr\emptytoks \tabskip\zeropoint \global\eqaligncolumn\plusone \halign\bgroup \mathcasesparameter\c!style##\hfil &\hskip\mathcasesparameter\c!distance\relax \popmacro\docasesNC##\hfil &\hskip\mathcasesparameter\c!numberdistance\relax \let\formuladistance\!!zeropoint \span\textineqalign{##}% \crcr} % todo: number \def\dostopmathcases {\crcr \egroup \popmacro\docasesNC \egroup \mathcasesparameter\c!right \endgroup} \def\definemathcases {\dodoubleempty\dodefinemathcases} \def\dodefinemathcases[#1]% [#2]% {\setvalue{\e!start#1}{\dodoubleempty\dostartmathcases[#1]}% \setvalue{\e!stop #1}{\dostopmathcases}% \setupmathcases[#1]}% [#2] \definemathcases[cases] \definemathcases[\v!mathcases] %D \startbuffer %D \placeformula \startformula \startcases %D \NC 2 \NC y > 0 \NR %D \NC 7 \NC x = 7 \NR[+] %D \NC 4 \NC otherwise \NR %D \stopcases \stopformula %D \stopbuffer %D %D \typebuffer \getbuffer %D %D \startbuffer %D \placeformula \startformula x \startcases %D \NC 2 \NC y > 0 \NR[+] %D \NC 7 \NC x = 7 \NR %D \NC 4 \NC otherwise \NR %D \stopcases \stopformula %D \stopbuffer %D %D \typebuffer \getbuffer %D %D \startbuffer %D \placeformula \startformula \startcases %D \NC 2 \NC y > 0 \NR %D \NC 7 \NC x = 7 \NR %D \NC 4 \NC otherwise \NR %D \stopcases \stopformula %D \stopbuffer %D %D \typebuffer \getbuffer %D %D \startbuffer %D \placeformula \startformula x \startcases %D \NC 2 \NC y > 0 \NR %D \NC 7 \NC x = 7 \NR %D \NC 4 \NC otherwise \NR %D \stopcases \stopformula %D \stopbuffer %D %D \typebuffer \getbuffer %D \macros %D {definemathmatrix, setupmathmatrix, startmathmatrix} %D %D Yet another one \unknown \def\setupmathmatrix {\dodoubleempty\dosetupmathmatrix} \def\dosetupmathmatrix[#1][#2]% {\ifsecondargument \getparameters[\??mx#1][#2]% \else \getparameters[\??mx][#1]% \fi} \let\currentmathmatrix\empty \def\mathmatrixparameter#1% {\executeifdefined{\??mx\currentmathmatrix#1}{\executeifdefined{\??mx#1}\empty}} \setupmathmatrix [\c!distance=1em, \c!left=, \c!right=, \c!align=\v!middle] \def\dosetmatrixcolumn#1% hh: todo: \definematrixalign {\letvalue{\??eq:\v!left :\number\eqaligncolumn}\hfil \letvalue{\??eq:\v!right:\number\eqaligncolumn}\hfil \doif{#1}\v!left {\letvalue{\??eq:\v!left :\number\eqaligncolumn}\relax \letvalue{\??eq:\v!right:\number\eqaligncolumn}\hfil}% \doif{#1}\v!right {\letvalue{\??eq:\v!left :\number\eqaligncolumn}\hfil \letvalue{\??eq:\v!right:\number\eqaligncolumn}\relax }% \doif{#1}\v!middle{\letvalue{\??eq:\v!left :\number\eqaligncolumn}\hfil \letvalue{\??eq:\v!right:\number\eqaligncolumn}\hfil}} \def\buildmathmatrix % beware: etex only {\scratchtoks\emptytoks \expanded{\scratchtoks{\the\scratchtoks\the\!!toksa}}% \dorecurse{\numexpr\scratchcounter-\plusone\relax} {\expanded{\scratchtoks{\the\scratchtoks\the\!!toksb}}}% \expanded{\scratchtoks{\the\scratchtoks\the\!!toksc }}} \def\preparemathmatrix {\!!toksa{\strut \firstineqalign\leftofeqalign \span \textineqalign{\mathmatrixparameter\c!style ##}\rightofeqalign}% \!!toksb{&\hskip\mathmatrixparameter\c!distance \nextineqalign\leftofeqalign \span \textineqalign{\mathmatrixparameter\c!style ##}\rightofeqalign}% \!!toksc{&&\hskip\mathmatrixparameter\c!distance \leftofeqalign \span \textineqalign{\mathmatrixparameter\c!style ##}\rightofeqalign}% \buildmathmatrix \halign \@EA \bgroup\the\scratchtoks \crcr} \def\definemathmatrix {\dodoubleempty\dodefinemathmatrix} \def\dodefinemathmatrix[#1]% [#2]% {\setvalue{\e!start#1}{\dodoubleempty\dostartmathmatrix[#1]}% \setvalue{\e!stop #1}{\dostopmathmatrix}% \setupmathmatrix[#1]}% [#2] \definemathmatrix[matrix] \definemathmatrix[\v!mathmatrix] \def\dodomatrixNC {\gdef\domatrixNC{\endmath&}} \def\installmathmatrixhandler#1#2% {\setvalue{\??mx:#1}{#2}} % First alternative: % % \def\processlowhighmathmatrix#1% % {\def\mathmatrixleft % {\setbox\nextbox} % \def\mathmatrixright % {#1.5\dimexpr\nextboxdp-\nextboxht\relax % \hbox{\mathmatrixparameter\c!left % \vcenter{\unvbox\nextbox}% % \mathmatrixparameter\c!right}}% % \let\mathmatrixbox\vbox} % % \installmathmatrixhandler\v!high {\processlowhighmathmatrix\raise} % \installmathmatrixhandler\v!low {\processlowhighmathmatrix\lower} % % \installmathmatrixhandler\v!top {\processlowhighmathmatrix\raise} % \installmathmatrixhandler\v!bottom{\processlowhighmathmatrix\lower} % % \installmathmatrixhandler\v!lohi % {\def\mathmatrixleft {\mathmatrixparameter\c!left}% % \def\mathmatrixright{\mathmatrixparameter\c!right}% % \let\mathmatrixbox\vcenter} % % An alternative % % \let\mathmatrixleft \empty % \let\mathmatrixright\empty % % \def\processlowhighmathmatrix#1% % {\dowithnextbox % {#1.5\dimexpr\nextboxdp-\nextboxht\relax % \hbox{\mathmatrixparameter\c!left % \vcenter{\unvbox\nextbox}% % \mathmatrixparameter\c!right}}% % \vbox} % % \def\processlohimathmatrix % {\dowithnextbox % {\mathmatrixparameter\c!left % \vcenter{\unvbox\nextbox}% % \mathmatrixparameter\c!right}% % \vbox} % % \installmathmatrixhandler\v!high {\def\mathmatrixbox{\processlowhighmathmatrix\raise}} % \installmathmatrixhandler\v!low {\def\mathmatrixbox{\processlowhighmathmatrix\lower}} % \installmathmatrixhandler\v!top {\def\mathmatrixbox{\processlowhighmathmatrix\raise}} % \installmathmatrixhandler\v!bottom{\def\mathmatrixbox{\processlowhighmathmatrix\lower}} % \installmathmatrixhandler\v!lohi {\let\mathmatrixbox \processlohimathmatrix} % % Final version \let\mathmatrixleft \empty % experimental hook \let\mathmatrixright\empty % experimental hook \def\processlowhighmathmatrix#1#2% {\dowithnextbox {\scratchdimen\dimexpr(\nextboxdp-\nextboxht)/2 \ifcase#2\or+\mathaxisheight\textfont2\fi\relax \ifcase#1\relax\or\lower\scratchdimen\or\or\raise\scratchdimen\fi \hbox{\mathmatrixparameter\c!left \vcenter{\unvbox\nextbox}% \mathmatrixparameter\c!right}}% \vbox} \installmathmatrixhandler\v!top {\def\mathmatrixbox{\processlowhighmathmatrix\plusthree\plusone }} \installmathmatrixhandler\v!high {\def\mathmatrixbox{\processlowhighmathmatrix\plusthree\zerocount}} \installmathmatrixhandler\v!lohi {\def\mathmatrixbox{\processlowhighmathmatrix\plustwo \zerocount}} \installmathmatrixhandler\v!low {\def\mathmatrixbox{\processlowhighmathmatrix\plusone \zerocount}} \installmathmatrixhandler\v!bottom{\def\mathmatrixbox{\processlowhighmathmatrix\plusone \plusone }} \def\dostartmathmatrix[#1][#2]% {\begingroup \edef\currentmathmatrix{#1}% \doifassignmentelse{#2}{\setupmathmatrix[#1][#2]}\donothing \null \executeifdefined{\??mx:\mathmatrixparameter\c!location}{\getvalue{\??mx:\v!lohi}}% \mathmatrixleft \mathmatrixbox\bgroup \pushmacro\domatrixNC \let\endmath\relax \def\NC{\domatrixNC}% \def\MC{\domatrixNC\ifmmode\else\def\endmath{}\fi}% \global\let\domatrixNC\dodomatrixNC \def\NR{\endmath\global\let\domatrixNC\dodomatrixNC\crcr}% \normalbaselines \mathsurround\zeropoint \everycr\emptytoks \tabskip\zeropoint \eqaligncolumn\zerocount % could be \scratchcounter \processcommacommand[\mathmatrixparameter\c!align]{\advance\eqaligncolumn\plusone\dosetmatrixcolumn}% \scratchcounter=\ifnum\eqaligncolumn>\zerocount \eqaligncolumn \else \plusone \fi \global\eqaligncolumn\plusone \preparemathmatrix } % uses scratchcounter \def\dostopmathmatrix {\crcr \mathstrut\crcr \noalign{\kern-\baselineskip}% \egroup \popmacro\domatrixNC \egroup \mathmatrixright \endgroup} %D \startbuffer %D \placeformula \startformula[-] \startmatrix %D \NC 1 \NC x \NC a \NR %D \NC 2 \NC y \NC b \NR %D \NC 3 \NC z \NC c \NR %D \stopmatrix \stopformula %D \stopbuffer %D %D \typebuffer \getbuffer %D %D \definemathmatrix[bmatrix][left={\left[\,},right={\,\right]}] %D %D \startbuffer %D \placeformula \startformula[-] \startbmatrix %D \NC 1 \NC x \NC a \NR %D \NC 2 \NC y \NC b \NR %D \NC 3 \NC z \NC c \NR %D \stopbmatrix \stopformula %D \stopbuffer %D %D \typebuffer \getbuffer %D %D Taco added some code (dedicated to Aditya Mahajan) that gives more %D control over aligments: %D \startbuffer %D \startformula %D \startmatrix %D \NC a + x \NC = \NC a + d \NR %D \NC y \NC = \NC d \NR %D \stopmatrix %D \stopformula %D \stopbuffer %D %D \typebuffer \getbuffer %D \startbuffer %D \startformula %D \startmatrix [distance=3pt,align={right,left}] %D \NC a + x \NC = a + d \NR %D \NC y \NC = d \NR %D \stopmatrix %D \stopformula %D \stopbuffer %D %D \typebuffer \getbuffer %D \startbuffer %D \startformula %D \startmatrix [left=\left(,right=\right)] %D \NC a + x \NR %D \NC y \NR %D \stopmatrix %D \stopformula %D \stopbuffer %D %D \typebuffer \getbuffer %D %D A bit more complex code: %D %D \startbuffer %D \startformula %D \text{Let }{\cal R} = \bigcup_{P_{X_1},P_{X_2}} %D \left\{ (R_1, R_2) : %D \startmatrix[distance=1em,align={left,left,right}] %D \NC R_1 \NC < I(X_1 ; Y \mid X_2) \NC R_1 \NR %D \NC \hfill Q_2 \NC < I(X_2 ; Y \mid X_1) \NC R_2 \NR %D \NC R_1 + R_2 \NC < I(X_1 ; Y) \NC R_1 + R_2 \NR %D \stopmatrix %D \right\} %D \stopformula %D \stopbuffer %D %D \typebuffer \getbuffer %D \macros %D {startmatrices} %D %D Just a handy keystroke safer: \def\startmatrices {\begingroup \setupmathmatrix} \def\stopmatrices {\endgroup} %D \startbuffer %D \startformula %D \startmatrix[left={\left(},right={\right)}] %D \NC A \NC B \NR \NC C \NC D \NR %D \stopmatrix %D = %D \startmatrix[left={\left(},right={\right)},location=low] %D \NC A \NC B \NR \NC C \NC D \NR %D \stopmatrix %D = %D \startmatrix[left={\left(},right={\right)},location=high] %D \NC A \NC B \NR \NC C \NC D \NR %D \stopmatrix %D \stopformula %D \stopbuffer %D %D \typebuffer \getbuffer %D %D \startbuffer %D \startformula %D \startmatrices[left={\left(},right={\right)}] %D \startmatrix %D \NC A \NC B \NR \NC C \NC D \NR %D \stopmatrix %D = %D \startmatrix[location=bottom] %D \NC A \NC B \NR \NC C \NC D \NR %D \stopmatrix %D = %D \startmatrix[location=top] %D \NC A \NC B \NR \NC C \NC D \NR %D \stopmatrix %D \stopmatrices %D \stopformula %D \stopbuffer %D %D \typebuffer \getbuffer %D \macros %D {startintertext} %D %D Preliminary feature: %D %D {\em example code} \def\startintertext#1\stopintertext {\noalign{\dointertext{#1}}} \def\intertext#1% {\noalign{\dointertext{#1}}} \unexpanded\def\dointertext#1% {\penalty\postdisplaypenalty \afterdisplayspace \vbox{\forgetall\noindent#1\par}% \penalty\predisplaypenalty \beforedisplayspace} % %D \macros % %D {substack} % %D % %D Preliminary code: % %D % %D \starttyping % %D \startformula % %D \sum_{% % %D \startsubstack % %D i = 1 \NR % %D i \neq n \NR % %D i \neq m % %D \stopsubstack % %D }a_i % %D \stopformula % %D \stoptyping % \def\startsubstack % {\begingroup % \null % \vcenter\bgroup % \pushmacro\domatrixNC % \let\stopmathmode\relax % \def\NC{\domatrixNC}% % \def\MC{\domatrixNC\startmathmode}% % \global\let\domatrixNC\dodomatrixNC % \def\NR % {\stopmathmode % \global\let\domatrixNC\dodomatrixNC % \crcr\noalign{\nointerlineskip}}% % \mathsurround\zeropoint % \everycr\emptytoks % \halign\bgroup\hfil\scriptstyle\mathstrut##\hfil\crcr} % \def\stopsubstack % {\crcr % \egroup % \popmacro\domatrixNC % \egroup % \endgroup} %D \macros %D {substack} %D %D Preliminary code: %D %D \startbuffer %D \startformula %D \sum_{% %D \startsubstack %D i = 1 \NR %D i \neq n \NR %D i \neq m %D \stopsubstack %D }a_i %D \stopformula %D \stopbuffer %D %D \getbuffer which was typed as \typebuffer %D %D Notice that these macros give the correct spacing for %D subscripts. Compare for example %D %D \startbuffer %D \startformula %D \sum_{\startsubstack a \NR b \NR \stopsubstack} %D \text{ and } %D \sum_{\scriptstyle a \atop \scriptstyle} %D \stopformula %D \typebuffer which gives \getbuffer \def\startsubstack {\begingroup \vcenter\bgroup \baselineskip\mathstacktotal \lineskip\mathstackvgap \lineskiplimit\lineskip \let\stopmathmode\relax \def\NC{\domatrixNC}% \def\MC{\domatrixNC\startmathmode}% \global\let\domatrixNC\dodomatrixNC \def\NR {\stopmathmode \global\let\domatrixNC\dodomatrixNC \crcr}% \mathsurround\zeropoint \everycr\emptytoks \halign\bgroup\hfil\scriptstyle##\hfil\crcr} \def\stopsubstack {\crcr \egroup \egroup \endgroup} %D \macros %D {frac, xfrac, xxfrac} %D %D This is another one Tobias asked for. It replaces the %D primitive \type {\over}. We also take the opportunity to %D handle math style restoring, which makes sure units and %D chemicals come out ok. %D %D \starttyping %D \def\frac#1#2% %D {\relax %D \ifmmode %D {{\mathstyle{#1}}\over{\mathstyle{#2}}}% %D \else %D \frac{#1}{#2}% %D \fi} %D \stoptyping %D %D Better is: %D %D \starttyping %D \def\frac#1#2% %D {\relax\mathematics{{{\mathstyle{#1}}\over{\mathstyle{#2}}}}} %D \stoptyping %D %D The \type {\frac} macro kind of replaces the awkward \type %D {\over} primitive. Say that we have the following formulas: %D %D \startbuffer[sample] %D test \frac {1}{2} test1 + \frac {1}{2} = 1.5$$%D test \xfrac {1}{2} test$$1 + \xfrac {1}{2} = 1.5$$%D test \xxfrac{1}{2} test$$1 + \xxfrac{1}{2} = 1.5$%D \stopbuffer %D %D \typebuffer[sample] %D %D With the most straightforward definitions, we get: %D %D \startbuffer[code] %D \def\dofrac#1#2#3{\relax\mathematics{{{#1{#2}}\over{#1{#3}}}}} %D %D \def\frac {\dofrac\mathstyle} %D \def\xfrac {\dofrac\scriptstyle} %D \def\xxfrac{\dofrac\scriptscriptstyle} %D \stopbuffer %D %D \typebuffer[code] \getbuffer[code,sample] %D %D Since this does not work well, we can try: %D %D \startbuffer[code] %D \def\xfrac #1#2{\hbox{$\dofrac\scriptstyle      {#1}{#2}$}} %D \def\xxfrac#1#2{\hbox{$\dofrac\scriptscriptstyle{#1}{#2}$}} %D \stopbuffer %D %D \typebuffer[code] \getbuffer[code,sample] %D %D This for sure looks better than: %D %D \startbuffer[code] %D \def\xfrac #1#2{{\scriptstyle \dofrac\relax{#1}{#2}}} %D \def\xxfrac#1#2{{\scriptscriptstyle\dofrac\relax{#1}{#2}}} %D \stopbuffer %D %D \typebuffer[code] \getbuffer[code,sample] %D %D So we stick to the next definitions (watch the local %D overloading of \type {\xfrac}). \def\dofrac#1#2#3{\relax\mathematics{{{#1{#2}}\over{#1{#3}}}}} % \unexpanded\def\frac % {\dofrac\mathstyle} % % \chardef\mathfracmode=0$\frac{1}{2}$% \chardef\mathfracmode=1$\frac{1}{2}$% \chardef\mathfracmode=2$\frac{1}{2}$% \chardef\mathfracmode=3$\frac{1}{2}$% \chardef\mathfracmode=4$\frac{1}{2}$% \chardef\mathfracmode=5$\frac{1}{2}$\chardef\mathfracmode=0 % 0=mathstyle, 1=displaystyle, 2=textstyle, 3=scriptstyle, 4=scriptscriptstyle \unexpanded\def\frac {\ifcase\mathfracmode \expandafter\dofrac\expandafter\mathstyle \or \expandafter\dofrac\expandafter\displaystyle \or \expandafter\dofrac\expandafter\textstyle \or \expandafter\dofrac\expandafter\scriptstyle \or \expandafter\dofrac\expandafter\scriptscriptstyle \else \expandafter\dofrac\expandafter\mathstyle \fi} \unexpanded\def\xfrac#1#2% {\begingroup \let\xfrac\xxfrac \dofrac\scriptstyle{#1}{#2}% \endgroup} \unexpanded\def\xxfrac#1#2% {\begingroup \dofrac\scriptscriptstyle{#1}{#2}% \endgroup} %D The \type {xx} variant looks still ugly, so maybe it's %D best to say: \unexpanded\def\xxfrac#1#2% {\begingroup \dofrac\scriptscriptstyle{#1}{\raise.25ex\hbox{$\scriptscriptstyle#2$}}% \endgroup} %D Something low level for scientific calculator notation: \unexpanded\def\scinot#1#2% {#1\times10^{#2}} %D The next macro, \type {\ch}, is \PPCHTEX\ aware. In %D formulas one can therefore best use \type {\ch} instead of %D \type {\chemical}, especially in fractions. \ifx\mathstyle\undefined \let\mathstyle\relax \fi \unexpanded\def\ch#1% {\ifx\@@chemicalletter\undefined \mathstyle{\rm#1}% \else \dosetsubscripts \mathstyle{\@@chemicalletter{#1}}% \doresetsubscripts \fi} %D \macros %D {/} %D %D Just to be sure, we restore the behavior of some typical %D math characters. \bgroup \catcode\/=\@@other \global \let\normalforwardslash/ \catcode\/=\@@active \doglobal\appendtoks\let/\normalforwardslash\to\everymathematics \egroup %D These macros were first needed by Frits Spijker (also %D known as Gajes) for typesetting the minus sign that is %D keyed into scientific calculators. % This is the first alternative, which works okay for the % minus, but less for the plus. % % \def\dodoraisedmathord#1#2#3% % {\mathord{{#2\raise.#1ex\hbox{#2#3}}}} % % \def\doraisedmathord#1% % {\mathchoice % {\dodoraisedmathord5\tf #1}% % {\dodoraisedmathord5\tf #1}% % {\dodoraisedmathord4\tfx #1}% % {\dodoraisedmathord3\tfxx#1}} % % \def\negative{\doraisedmathord-} % \def\positive{\doraisedmathord+} % % So, now we use the monospaced signs, that we also % define as symbol, so that they can be overloaded. \def\dodoraisedmathord#1#2#3% {\mathord{{#2\raise.#1ex\hbox{#2\symbol[#3]}}}} \def\doraisedmathord#1% {\mathchoice {\dodoraisedmathord5\tf {#1}}% {\dodoraisedmathord5\tf {#1}}% {\dodoraisedmathord4\tx {#1}}% {\dodoraisedmathord3\txx{#1}}} \def\dodonumbermathord#1#2% {\setbox\scratchbox\hbox{0}% \mathord{\hbox to \wd\scratchbox{\hss#1\symbol[#2]\hss}}} \def\donumbermathord#1% {\mathchoice {\dodonumbermathord\tf {#1}}% {\dodonumbermathord\tf {#1}}% {\dodonumbermathord\tx {#1}}% {\dodonumbermathord\txx{#1}}} \definesymbol[positive] [\getglyph{Mono}{+}] \definesymbol[negative] [\getglyph{Mono}{-}] \definesymbol[zeroamount][\getglyph{Mono}{-}] \def\negative {\doraisedmathord{negative}} \def\positive {\doraisedmathord{positive}} \def\zeroamount{\donumbermathord{zeroamount}} %D The following macros are used in the MathML interpreter, so %D there is a good change of them never being documented for %D other usage. \let\normalordelimiter\secondoftwoarguments \let\normalorfiller \firstoftwoarguments \def\enabledelimiter {\let\normalordelimiter\secondoftwoarguments} \def\disabledelimiter{\let\normalordelimiter\firstoftwoarguments} \def\enablefiller {\let\normalorfiller\secondoftwoarguments} \def\disablefiller {\let\normalorfiller\firstoftwoarguments} \def\mathopnolimits#1{\mathop{\mr#1}\nolimits} % was \rm, which follows text fonts (used in mml parser) \def\mathopdolimits#1{\mathop{\mr#1}} % was \rm, which follows text fonts (used in mml parser) %D \macros{overset, underset} %D %D The macros \type{\overset} and \type{\underset} are provided by %D \AMS\ packages in \LATEX. These macro allows you to place a symbol %D above or below another symbol, irrespective of whether the other %D symbol is a relation or something else, and without influencing the %D spacing. For most cases there is a better way to do such things %D (declaring a math command with limop option, or using accents), but %D occasionally these macros can be useful, for example: %D %D \startbuffer %D \startformula %D \overset{*}{X} \underset{*}{X} %D \stopformula %D \stopbuffer %D \typebuffer \getbuffer %D %D Use these macros sparingly. Remember, \TEX\ was designed for %D mathematics, so there is usually a proper method for typesetting %D common math notation. %D These macros are a clearer version of \type{\binrel@} and %D \type{\binrel@@} macros in \AMSTEX\ packages. \def\preparebinrel#1% {\begingroup \setbox\scratchbox\hbox {\thinmuskip 0mu \medmuskip -1mu \thickmuskip -1mu \setbox\scratchbox\hbox{$#1\mathsurround\zeropoint$}% \kern-\wd\scratchbox${}#1{}\mathsurround\zeropoint$}% \expanded {\endgroup \let\noexpand\currentbinrel \ifdim\wd\scratchbox<\zeropoint \mathbin \else\ifdim\wd\scratchbox>\zeropoint \mathrel \else \relax \fi\fi}} \unexpanded\def\overset#1#2% {\preparebinrel{#2}% \currentbinrel{\mathop{\kern\zeropoint#2}\limits^{#1}}} \unexpanded\def\underset#1#2% {\preparebinrel{#2}% \currentbinrel{\mathop{\kern\zeropoint#2}\limits_{#1}}} %D \macros %D {boldsymbol} %D %D The math definition is inspired by amsmath. %D %D \startbuffer %D \definetypeface [boldmath] [mm] [boldmath] [latin-modern] [modern] [encoding=texnansi] %D %D$a \times ba \boldsymbol{\times} b$%D \stopbuffer %D %D \typebuffer \start \getbuffer \stop \def\mathboldsymbol#1% {\preparebinrel{#1}% \currentbinrel{\mathchoice {\hbox{\switchtoformulabodyfont [boldmath]$\mathsurround\zeropoint#1$}} {\hbox{\switchtoformulabodyfont [boldmath]$\mathsurround\zeropoint#1$}} {\hbox{\switchtoformulabodyfont [boldmath,script]$\mathsurround\zeropoint#1$}} {\hbox{\switchtoformulabodyfont[boldmath,scriptscript]$\mathsurround\zeropoint#1$}}}} \def\boldsymbol {\mathortext\mathboldsymbol\bold} %D Some encoding hackery (for Mojca. who else): %D %D \starttyping %D \startmathcollection[eul:texnansi] %D \definemathsymbol [breve] [accent] [tf] ["15] %D \stopmathcollection %D \startmathcollection[eul:ec] %D \definemathsymbol [breve] [accent] [tf] ["08] %D \stopmathcollection %D %D$\breve e$%D \stoptyping \let\outerencoding\empty \def\checkoutermathencoding {\ifx\outerencoding\empty \ifx\outerencoding\s!default\else \edef\outerencoding{\currentencoding}% \fi \fi} \prependtoks \checkoutermathencoding \to \everymathematics %D More. (A temp hack, else no proper default fall back (like \type %D {\textmultiply}); todo: sync encoding. \def\dealwithmathtextencoding {\expanded{\everyhbox{\the\everyhbox\noexpand\fastenableencoding{\currentencoding}}}% \expanded{\everyvbox{\the\everyvbox\noexpand\fastenableencoding{\currentencoding}}}% \def\dealwithmathtextencoding{\let\characterencoding\nocharacterencoding}% \dealwithmathtextencoding} \appendtoks \dealwithmathtextencoding \to \everymathematics %D How negative such a symbol looks is demonstrated in: %D$\negative 10^{\negative 10^{\negative 10}}\$.

\setupformulas
[\c!way=\@@nrway,
\c!blockway=,
\c!sectionnumber=\@@nrsectionnumber,
\c!location=\v!right,
\c!left=(,
\c!right=),
\c!numberstyle=,
\c!numbercolor=,
\c!numbercommand=,
\c!spacebefore=\v!big,
\c!spaceafter=\@@fmspacebefore,
\c!grid=]

\protect \endinput
`