%D \module %D [ file=x-newmml, %D version=2005.06.10, % 1999.12.20, %D title=\CONTEXT\ XML Macros, %D subtitle=MathML, %D author=Hans Hagen, %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. %D Remark: from now on this is a module and no longer an xtag %D filter. In due time it will replace the older renderer (which %D we will keep around for sentimental reasons). This variant has %D no namespace support yet, but eventually we will use a \MKIV\ %D version. \useXMLfilter[stk] \ifx\inlinemathematics\undefined \def\inlinemathematics {\dontleavehmode\mathematics} % already in kernel \long\def\inlinemath #1{\dontleavehmode\relax\ifmmode#1\else $#1$\fi} \fi % \defineXMLentity[x000AF]{\normalorfiller{x}\hrulefill} % CHECK FOR: \xmlrent % \enablemathpunctuation %D Then we start defining the rendering macros: \writestatus{loading}{ConTeXt XML Macros / MathML} \startmodule [mathml] %D First we load the entities: \usemodule[newmme] % \setupmodule[a=c] % \setupmodule[a=c] \unprotect \def\MMLrm{\mr} \def\MMLseparator#1{{#1}} % nils space after separator %D First we define some general formula elements. \defineXMLenvironment [formula] [label=,sublabel=] {\dostartXMLformula\placeformula} {\dostopXMLformula} \defineXMLenvironment [subformula] [label=,sublabel=] {\dostartXMLformula\placesubformula} {\dostopXMLformula} \def\dostartXMLformula#1% {\doifelsenothingXMLop{label} {\startformula} {\expanded{#1[\XMLop{label}]{\XMLop{sublabel}}}\startformula}} \def\dostopXMLformula {\stopformula} %D Since I only had the draft of MathML 2 as example of %D rendering, there are probably a lot of omissions and %D misinterpretations. At least I learned some bits and %D pieces of math rendering. %D %D The main complications were not so much the math, but to %D find the most efficient way to handle elements without %D spacing beging messed up. The first implementation was %D aimed at getting reasonable output, this second %D implementation is already better in terms of handling %D nesting, and I will definitely need a third one that has %D more efficient and less ugly code. %D %D The \TEX\ part is not that complicated and once the %D preprocessor was okay, the rest way just a lot of keying %D and testing. It all comes down to gobbling, redefining, %D and not so much to parsing. %D %D The second implementation expanded the whole math sequence %D into an internal \TEX\ representation. This is a rather clean %D and fast process. Filtering and testing takes place by %D redefining the internal representation macros. %D %D The third implementation may look a bit more messy in some %D respects. This is because in \TEX\ it's not that trivial to %D implement a tree handler. We use a stack for the \type {apply} %D element and other sequential content. Occasionally we need to %D peek into child elements which involves messy code. This %D implementation is closer to the normal \XML\ handling in %D \CONTEXT. %D We start with the parent elements and the option handler. \defineXMLdirective [mathml] \setupMMLappearance \defineXMLargument [math] \automathematics \defineXMLargument [imath] \inlinemathematics \defineXMLargument [dmath] \displaymathematics \defineXMLargument [m] \inlinemathematics %D In the styles, options can be set with: \def\setupMMLappearance[#1]{\dodoubleargument\getparameters[@@MML#1]} \def\startusingMMLarguments % optional maken {\begingroup %\expandXMLta % expand entities first \getXMLta} \def\stopusingMMLarguments % optional maken {\endgroup} \def\MMLargumentprefix{@@MML\currentXMLelement} %D We will apply inner math to all bits and pieces made up by an %D \type {apply}. \def\MMLmathinner {\ifinner \expandafter \firstofoneargument \else \expandafter \mathinner \fi} %D A few math related macros: \let\MMLctempresetlist\empty \def\setMMLcreset{\edef\MMLctempresetlist} \newcount\MMLapplydepth \def\MMLcreset{\MMLapplydepth\zerocount} % Stack handler \startXMLmapping[xmlstack:test] \defineXMLnested [apply] {\startsavingXMLelements} {\stopsavingXMLelements} \stopXMLmapping %D Auxiliary MathML macros: (to be generalized) \def\doifelseMMCfunction {\begingroup \XMLdoifonstackelse{fn} {\donetrue} {\XMLdoifonstackelse{apply} {\defXMLfirstnamedtext\ascii{apply}% \startsavingXMLelements % best use a substack so that we do not need to \edef \ascii \stopsavingXMLelements} {}% \XMLdoifonstackelse{fn} {\donetrue} {\defineXMLsave[ci][type=]% \XMLfirstnamed{ci}% \doifelse{\XMLpar{ci}{type}{}}{fn} {\donetrue} {\donefalse}}}% \ifdone \endgroup\expandafter\firstoftwoarguments \else \endgroup\expandafter\secondoftwoarguments \fi} \def\doifelseMMCfunctioninapply#1#2% grouped {\begingroup \startXMLmapping[xmlstack:test]% take fast alternative \getXMLstackdata{#1}% \expanded{\doifinsetelse{\getXMLstackname\plusone}{#2}} {\stopXMLmapping \endgroup\firstoftwoarguments } {\stopXMLmapping \endgroup\secondoftwoarguments}} \def\dodoifelseMMCfunctioninapply#1#2% {\startXMLmapping[xmlstack:test]% take fast alternative \getXMLstackdata{#1}% \expanded{\doifinsetelse{\getXMLstackname\plusone}{#2}} {\stopXMLmapping \firstoftwoarguments } {\stopXMLmapping \secondoftwoarguments}} %D Special features: \newtoks \@@postponedMMLactions \setfalse \somepostponedMMLactions \def\postponeMMLactions#1% {\global\settrue\somepostponedMMLactions \global\@@postponedMMLactions\expandafter{\the\@@postponedMMLactions#1}} \def\postponedMMLactions {\global\setfalse\somepostponedMMLactions \@EA\global\@EA\@@postponedMMLactions\@EA\emptytoks \the\@@postponedMMLactions} %D A couple of lists: \def\MMLcmainresetlist {times,divide,power,% lt,gt,eq,leq,geq,% in,inverse,% fn,% floor,ceiling,% mean,% selector,% abs,int,limit,sum,product,% outerproduct,innerproduct,scalarproduct} \def\MMLcfunctionlist {sin,arcsin,sinh,arcsinh,% cos,arccos,cosh,arccosh,% tan,arctan,tanh,arctanh,% cot,arccot,coth,arccoth,% csc,arccsc,csch,arccsch,% sec,arcsec,sech,arcsech,% ln,exp,log,% abs,int,limit,sum,product,% fn} % ? \def\MMLcconstructlist {diff,partialdiff,root} % apply goes wrong on 1/2 * (a_2 + b_3) % apply % %D We use inner and grouping (begin/end and no b/e) else we %D get problems with 1/2(1+2) and alike (todo: ask taco). %D %D The problem with apply is that we need to take care of %D several situations, like: %D %D \starttyping %D <.../> ... %D ... %D ... %D ... %D \stoptyping %D %D Because we translated version 2 of this renderer into %D version 3 the following definitions may be sub optimal or %D more complex than actually needed. \defineXMLnested % why nested? could be just an environment [apply] [open=,close=] {\setups{mmc:apply:start}} {\setups{mmc:apply:stop}} \startsetups mmc:apply:start \begingroup \startsavingXMLelements \stopsetups \startsetups mmc:apply:stop \stopsavingXMLelements \MMLmathinner { \expanded{\doifinsetelse{\getXMLstackname\plusone}{\MMLcmainresetlist,\MMLctempresetlist}} \MMLcreset \donothing \ifcase\MMLapplydepth \else \doifXMLparelse{apply}{open} \donothing{\getXMLarguments{apply}{open="("}}% slow \doifXMLparelse{apply}{close}\donothing{\getXMLarguments{apply}{close=")"}}% slow \fi \doifXMLparelse{apply}{open}{\left\XMLpar{apply}{open}{}}\donothing \advance\MMLapplydepth\plusone \begingroup \let\MMLctempresetlist\empty \doifelse {\getXMLstackname\plusone} {apply} { % ... .. \doifelseMMCfunctioninapply \plusone {plus,minus} { % yet incomplete and rather untested % x } { \MMLcreset } \getXMLstackdata\plusone \ifconditional\somepostponedMMLactions \postponedMMLactions \else \left(\MMLcreset\getXMLstackdata\plustwo\right) \fi } { \doifelse {\getXMLstackname\plusone} {fn} { % also postpone \directsetup{mmc:fn:apply} } { \doifelse {\getXMLstackname\plusone} {csymbol} { % also postpone \directsetup{mmc:csymbol:apply} } { \doifelse {\getXMLstackname\plusone} {ci} { \getXMLstackdata\plusone \ifnum\XMLstacklevel>\plusone \left(\MMLcreset\flushXMLstackwith\plustwo{\MMLseparator,}\right) \fi } { \getXMLstackdata\plusone } } } } \endgroup \advance\MMLapplydepth\minusone \directsetup{apply:flush} \doifXMLparelse{apply}{close}{\right\XMLpar{apply}{close}{}}\donothing } \endgroup \stopsetups \startsetups apply:flush \relax \ifcase\MMLapplydepth \ifconditional\somepostponedMMLactions \postponedMMLactions \ifx\MMLpowerelement\empty\else ^{\MMLcreset\MMLpowerelement\empty} \global\let\MMLpowerelement\empty \fi \fi \fi \stopsetups % reln \defineXMLnestedenvironmentsave [reln] {\writestatus{XML}{MathML element "reln" is obsolete}} {} % fn \startsetups mmc:fn:plusminus \ifnum\XMLstacklevel>\plustwo \MMLcreset \left(\expandafter\flushXMLstackwith\expandafter\plustwo\expandafter{\XMLfnoperator}\right) \else \getXMLstackdata\plustwo \fi \stopsetups \startsetups mmc:fn:minusplus \directsetup{mmc:fn:plusminus} \stopsetups \defineXMLnested [fn] {\directsetup{mmc:fn:start}} {\directsetup{mmc:fn:stop}} \startsetups mmc:fn:apply \begingroup \startsavingXMLelements \rawXMLstacktext\plusone % still on stack, no check, just fn content \stopsavingXMLelements \doifelse {\getXMLstackname\plusone} {ci} { \flattenXMLcontent{\getXMLstackdata\plusone} \doifsetupselse{mmc:fn:\flattenedXMLcontent} { \global\defXMLstackdata\XMLfnoperator\plusone \expanded{\endgroup\noexpand\directsetup{mmc:fn:\flattenedXMLcontent}} } { \endgroup \MMLcreset \getXMLstackdata\plusone \ifnum\XMLstacklevel>\plusone \getXMLentity{NegThinSpace} \left(\MMLcreset\flushXMLstackwith\plustwo{\MMLseparator,}\right) \fi } } { \endgroup \MMLcreset \getXMLstackdata\plusone } \stopsetups \startsetups mmc:fn:start \ifnum\XMLstacklevel>\plustwo \def\MMCfnleft {\left(} \def\MMCfnright{\right)} \else \let\MMCfnleft \relax \let\MMCfnright\relax \fi \begingroup \startsavingXMLelements \stopsetups \startsetups mmc:fn:stop \stopsavingXMLelements \doifelse {\getXMLstackname\plusone} {ci} { \flattenXMLcontent{\getXMLstackdata\plusone} \doifsetupselse{mmc:fn:\flattenedXMLcontent} { \global\defXMLstackdata\XMLfnoperator\plusone \directsetup{mmc:fn:\flattenedXMLcontent} } { \MMLcreset \getXMLstackdata\plusone } \endgroup } { \doifelse {\getXMLstackname\plusone} {apply} { \doifelseMMCfunctioninapply \plusone {plus,minus} { \left( \getXMLstackdata\plusone \right) } { \getXMLstackdata\plusone } \endgroup \ifnum\XMLstacklevel>\plusone \left( \getXMLstackdata\plustwo \right) \fi } { \MMLcreset \getXMLentity{NegThinSpace} \MMCfnleft \ifnum\XMLstacklevel=\plustwo\MMLccomma\fi \flushXMLstackwith\plustwo\MMLccomma \MMCfnright \endgroup } } \stopsetups % c* \defineXMLargument [ci] [type=] {\XMLval{mmc:ci}{\XMLop{type}} {\firstofoneargument}} \defineXMLargument [cn] [type=,base=] {\XMLval{mmc:cn}{\XMLop{type}} {\firstofoneargument}} \defineXMLargument [csymbol] [encoding=text] {\XMLval{mmc:cs}{\XMLop{encoding}}{\firstofoneargument}} %D The next definition provide a kind of plug-in mechanism (see %D the open math extension module). \defineXMLsingular [csymbol] [encoding=text, definitionURL=] {\doifsomething{\XMLop{definitionURL}}{\directsetup{mmc:csymbol:apply}}} \startsetups mmc:csymbol:apply \begingroup \startsavingXMLelements \rawXMLstacktext\plusone % still on stack, no check, just attr test \stopsavingXMLelements % http://www.publishers.com/SomeName \lowercasestring\XMLpar{csymbol}{definitionURL}{}\to\mmcSymbolURL \doifsetupselse{mmc:csymbol:} {\mmcSymbolURL} { \expanded{\endgroup\noexpand\directsetup{mmc:csymbol:\mmcSymbolURL}} } { % SomeName (fallback) \splitfilename{\XMLpar{csymbol}{definitionURL}{}} \doifsetupselse{mmc:csymbol:\splitoffbase} { \expanded{\endgroup\noexpand\directsetup{mmc:csymbol:\splitoffbase}} } { \endgroup \XMLval{mmc:cs}{\XMLop{encoding}}{\firstofoneargument} } } \stopsetups %D Alternative b will convert periods into comma's: %D %D \startbuffer %D \startXMLdata %D 1.23 %D 1.23 %D \stopXMLdata %D %D \type{\setupMMLappearance[cn] [alternative=b]} %D %D \startXMLdata %D 1.23 %D 1.23 %D \stopXMLdata %D \stopbuffer %D %D \start \typebuffer \getbuffer \stop \setupMMLappearance[cn] [\c!alternative=\v!a] \defineXMLargument[cn][type=,base=]{\MMLdocn} \def\MMLdocn#1% {\begingroup \doif\@@MMLcnalternative\v!b{\redefinemathcharacter [.][ord][mi]["3B]\relax}% \XMLval{mmc:cn}{\XMLop{type}}{\firstofoneargument}{#1}% \endgroup} \defineXMLsingular [sep] {\MMLcsep} \def\MMLcsep{\,} \setupMMLappearance[polar] [\c!alternative=\v!a] % a|b|c \setupMMLappearance[float] [\c!symbol=\v!no] % \v!yes|dot \setupMMLappearance[enotation][\c!symbol=\v!no] % \v!yes|dot \setupMMLappearance[base] [\c!symbol=\v!numbers] % digits|characters|text|no \mapXMLvalue {mmc:ci} {set} {\MMLcCIset} \mapXMLvalue {mmc:ci} {vector} {\MMLcCIvector} \mapXMLvalue {mmc:ci} {matrix} {\MMLcCImatrix} \mapXMLvalue {mmc:ci} {function} {\MMLcCIfunction} \mapXMLvalue {mmc:ci} {complex-cartesian} {\MMLccartesian} \mapXMLvalue {mmc:ci} {complex} {\MMLccartesian} \mapXMLvalue {mmc:ci} {complex-polar} {\MMLcpolar} \mapXMLvalue {mmc:ci} {polar} {\MMLcpolar} \mapXMLvalue {mmc:ci} {fn} {\MMLcCIfunction} \mapXMLvalue {mmc:cn} {integer} {\MMLcCNinteger} \mapXMLvalue {mmc:cn} {logical} {\MMLcCNlogical} \mapXMLvalue {mmc:cn} {rational} {\MMLcCNrational} \mapXMLvalue {mmc:cn} {complex-cartesian} {\MMLccartesian} \mapXMLvalue {mmc:cn} {complex} {\MMLccartesian} \mapXMLvalue {mmc:cn} {complex-polar} {\MMLcpolar} \mapXMLvalue {mmc:cn} {polar} {\MMLcpolar} \mapXMLvalue {mmc:cn} {e-notation} {\MMLcenotation} % new \mapXMLvalue {mmc:cn} {float} {\MMLcfloat} % obsolete \mapXMLvalue {mmc:cn} {real} {\MMLcfloat} \mapXMLvalue {mmc:cs} {text} {\MMLcCStext} \def\MMLcpolar#1% {\doifdefinedelse{MMLcdopolar\@@MMLpolaralternative} {\getvalue{MMLcdopolar\@@MMLpolaralternative}{#1}} {#1}} \def\MMLcdopolara#1% {\def\MMLcsep{\MMLseparator,}\getXMLentity{polar}\left(#1\right)} \def\MMLcdopolarb#1% {\def\MMLcsep##1\empty {\getXMLentity{exponentiale}^{##1\mskip2mu\getXMLentity{imaginaryi}}} #1\empty} \def\MMLcdopolarc#1% {\def\MMLcsep##1\empty {\getXMLentity{exp}\left(##1\mskip2mu\getXMLentity{imaginaryi}\right)}% #1\empty} \def\MMLccartesian#1% {\def\MMLcsep{+}#1\getXMLentity{imaginaryi}} % float will be obsolete, and is replace by e-notation \def\MMLcfloat#1% {\doifelse\@@MMLfloatsymbol\v!no % {{\MMLrm#1}}% make sure that e shows up ok {\mfunction{#1}}% make sure that e shows up ok {% we should ignore \entities ! \beforesplitstring#1\at e\to\first \aftersplitstring #1\at e\to\last \ifx\first\empty #1\else \ifx\last \empty #1\else \first \doifelse\@@MMLfloatsymbol{dot}\cdot\times 10^{\last}% \fi\fi}} % we now have: \def\MMLcenotation#1% {\doifelse\@@MMLenotationsymbol\v!no % {\def\MMLcsep {\unskip{\MMLrm e}\ignorespaces}} {\def\MMLcsep {\unskip\mfunction{e}\ignorespaces}} {\def\MMLcsep##1\empty{\doifelse\@@MMLenotationsymbol{dot}\cdot\times10^{##1}}}% #1\empty} \def\MMLcCIset#1% {{\bbd#1}} \def\widevec#1% {\vbox{\mathsurround\zeropoint\ialign{##\crcr \rightarrowfill\crcr\noalign{\nointerlineskip}% $\hfil\displaystyle{#1}\hfil$\crcr}}} \def\MMLcCIvector#1% {\widevec{#1}} \def\MMLcCImatrix#1% {{\bi#1}} \def\MMLcCIfunction#1% {#1\getXMLentity{NegThinSpace}} \def\MMLcCNinteger#1% {\doifXMLparelse{cn}{base} {\def\MMLcCNbase{\XMLpar{cn}{base}{}}% \doifelse\@@MMLbasesymbol\v!no {\MMLcCNbasedata{#1}} % {\MMLcCNbasedata{#1}_{\hbox{$\MMLrm\scriptscriptstyle {\MMLcCNbasedata{#1}_{\mfunction{% \processaction [\@@MMLbasesymbol] [\v!characters=>\MMLcCNbasestring BODH, \v!text=>\MMLcCNbasestring{BIN}{OCT}{DEC}{HEX}, % \s!unknown=>\MMLcCNbase]$}}}} \s!unknown=>\MMLcCNbase]}}}} {#1}} \def\MMLcCNbasedata#1% % {\ifnum\MMLcCNbase>10{\MMLrm#1}\else#1\fi} {\ifnum\MMLcCNbase>10\mfunction{#1}\else#1\fi} \def\MMLcCNbasestring#1#2#3#4% {\ifnum\MMLcCNbase= 2 #1\else \ifnum\MMLcCNbase= 8 #2\else \ifnum\MMLcCNbase=10 #3\else \ifnum\MMLcCNbase=16 #4\else \MMLcCNbase \fi\fi\fi\fi} \def\MMLcCNlogical#1% % {{\MMLrm#1}} {\mfunction{#1}} \bgroup \catcode`\<=\active % quick and dirty, best track the stack (todo) \gdef\MMLcCNrational#1% {\ConvertConstantAfter\doifinstringelse{sep}{#1} {\doMMLcCNrational#1\empty} {#1}} \gdef\doMMLcCNrational#1#3\empty {\hbox{$\frac{#1}{#3}$}} \egroup \def\MMLcCStext#1% % {{\MMLrm#1}} {\mfunction{#1}} % interval \defineXMLnested [interval] [closure=closed] {\directsetup{mmc:interval:start}} {\directsetup{mmc:interval:stop}} \startsetups mmc:interval:start \begingroup \startsavingXMLelements \stopsetups \startsetups mmc:interval:stop \stopsavingXMLelements \XMLval{mmc:int}{\XMLpar{interval}{closure}{closed}}{error} \endgroup \stopsetups \startsetups mmc:interval:fetch \defineXMLnested [interval] [closure=closed] {\directsetup{mmc:interval:fetch:start}} {\directsetup{mmc:interval:fetch:stop}} \stopsetups \startsetups mmc:interval:fetch:start \begingroup \startsavingXMLelements \stopsetups \startsetups mmc:interval:fetch:stop \stopsavingXMLelements \globallet\MMCintervalfrom\empty \globallet\MMCintervalto \empty \ifcase\XMLstacklevel \or \xdef\MMCintervalfrom{\getXMLstackdata\plusone} \or \xdef\MMCintervalfrom{\getXMLstackdata\plusone} \xdef\MMCintervalto {\getXMLstackdata\plustwo} \fi \endgroup \stopsetups \setupMMLappearance[interval][\c!alternative=\v!a,\c!separator={,}] \mapXMLvalue {mmc:int} {closed} {\left[\getXMLstackdata\plusone\MMLseparator\@@MMLintervalseparator\getXMLstackdata\plustwo\right]} \mapXMLvalue {mmc:int} {open-closed} {\doifelse\@@MMLintervalalternative\v!b {\left<\getXMLstackdata\plusone\MMLseparator\@@MMLintervalseparator\getXMLstackdata\plustwo\right]} {\left(\getXMLstackdata\plusone\MMLseparator\@@MMLintervalseparator\getXMLstackdata\plustwo\right]}} \mapXMLvalue {mmc:int} {closed-open} {\doifelse\@@MMLintervalalternative\v!b {\left[\getXMLstackdata\plusone\MMLseparator\@@MMLintervalseparator\getXMLstackdata\plustwo\right>} {\left[\getXMLstackdata\plusone\MMLseparator\@@MMLintervalseparator\getXMLstackdata\plustwo\right)}} \mapXMLvalue {mmc:int} {open} {\doifelse\@@MMLintervalalternative\v!b {\left<\getXMLstackdata\plusone\MMLseparator\@@MMLintervalseparator\getXMLstackdata\plustwo\right>} {\left(\getXMLstackdata\plusone\MMLseparator\@@MMLintervalseparator\getXMLstackdata\plustwo\right)}} % inverse \defineXMLcommand [inverse] {\directsetup{mmc:inverse}} \startsetups mmc:inverse \ifnum\XMLstacklevel>\plustwo \getXMLentity{\getXMLstackname\plustwo}^{-1} \left[\getXMLstackdata\plusthree\right] \else \xdef\MMLpowerelement{-1} \expanded{\postponeMMLactions{\rawXMLstackdata\plustwo}} \eraseXMLdataonstack\plustwo \fi \stopsetups % condition \defineXMLnested [condition] {\directsetup{mmc:condition:start}} {\directsetup{mmc:condition:stop}} \startsetups mmc:condition:start % \XMLdoifonstackelse{bvar} { % \XMLfirstnamed{bvar}\mid % } { } \begingroup \startsavingXMLelements \stopsetups \startsetups mmc:condition:stop \stopsavingXMLelements \flushXMLstackfrom\plusone \endgroup \stopsetups % declare \setupMMLappearance[declare][\c!state=\v!start] \defineXMLnested [declare] {\directsetup{mmc:declare:start}} {\directsetup{mmc:declare:stop}} \startsetups mmc:declare:start \begingroup \startsavingXMLelements \stopsetups \startsetups mmc:declare:stop \stopsavingXMLelements \doif\@@MMLdeclarestate\v!start { \getXMLentity{declare}\getXMLstackdata\plusone \ifnum\XMLstacklevel>\plusone \getXMLentity{ThickSpace} \getXMLentity{as} \getXMLentity{ThickSpace} \fi \getXMLstackdata\plustwo } \endgroup \stopsetups % lambda \setupMMLappearance[lambda][\c!alternative=b] \defineXMLnested [lambda] {\directsetup{mmc:lambda:start}} {\directsetup{mmc:lambda:stop}} \startsetups mmc:lambda:start \begingroup \startsavingXMLelements \stopsetups \startsetups mmc:lambda:stop \stopsavingXMLelements \doifelse\@@MMLlambdaalternative\v!a { \getXMLentity{lambda}(\flushXMLstackwith\plusone{\MMLseparator,}) } { \countXMLnamedstack{bvar} \ifnum\scratchcounter>\plusone \left(\flushXMLnamedstackwith\plusone{bvar}{\MMLseparator,}\right) \else \XMLfirstnamed{bvar} \fi \getXMLentity{mapsto} \MMLcreset \XMLfirstnamed{apply,reln,ci,cn} } \endgroup \stopsetups \startsetups mmc:lambda:simple \defineXMLnested [lambda] {\directsetup{mmc:lambda:simple:start}} {\directsetup{mmc:lambda:simple:stop}} \stopsetups \startsetups mmc:lambda:simple:start \begingroup \startsavingXMLelements \stopsetups \startsetups mmc:lambda:simple:stop \stopsavingXMLelements \MMLcreset % new \XMLfirstnamed{apply} \endgroup \stopsetups % compose \defineXMLcommand [compose] {\directsetup{mmc:compose}} \startsetups mmc:compose \begingroup \MMLcreset \let\MMLcCIfunction\firstofoneargument % brrr \doifelseMMCfunction { \left(\flushXMLstackwith\plustwo\circ\right) } { \flushXMLstackwith\plustwo\circ } \endgroup \stopsetups \defineXMLcommand [image] {\directsetup{mmc:image}} \startsetups mmc:image \getXMLentity{image} \left( \begingroup \startlocalsetups [mmc:function] \getXMLentity\currentXMLelement \stoplocalsetups \getXMLstackdata\plustwo \endgroup \right) \stopsetups \setupMMLappearance[piece][\c!separator=] \def\setMMLcPIECEseparator {\processaction [\@@MMLpieceseparator] [ \v!yes=>\def\theMMLpieceseparator{,\@col@amp@}, \v!no=>\let\theMMLpieceseparator\@col@amp@, \s!default=>\let\theMMLpieceseparator\@col@amp@, \s!unknown=>\def\theMMLpieceseparator{\,\,\hbox{\@@MMLpieceseparator}\,\,}]} \defineXMLargument[piecewise] {\cases} \defineXMLnested [piece] {\directsetup{mmc:piece:start}} {\directsetup{mmc:piece:stop}} \defineXMLenvironmentsave [otherwise] {} {\directsetup{mmc:otherwise}} \startsetups mmc:piece:start \startsavingXMLelements \setMMLcPIECEseparator \stopsetups \startsetups mmc:piece:stop \stopsavingXMLelements \edef\ascii{\getXMLstackdata\plusone} \@EA\XMLRtoks\@EA{\ascii\theMMLpieceseparator} \edef\ascii{\getXMLstackdata\plustwo} \@EA\appendtoks\@EA\mathematics\@EA{\ascii}\to\XMLRtoks \the\XMLRtoks\crcr \stopsetups \startsetups mmc:otherwise \XMLflush{otherwise}\MMLcPIECEseparator\@col@amp@\mathematics{\getXMLentity{otherwise}}\crcr \stopsetups \defineXMLcommand [quotient] {\directsetup{mmc:quotient}} \startsetups mmc:quotient \lfloor\getXMLstackdata\plustwo/\getXMLstackdata\plusthree\rfloor \stopsetups \defineXMLcommand [factorial] {\getXMLstackdata\plustwo !} \defineXMLcommand [divide] [\MMLargumentprefix] [] {\directsetup{mmc:divide}} % brr not nested \setupMMLappearance [divide] [\c!level=\!!maxcard,\c!alternative=\v!a] \startsetups mmc:divide \startusingMMLarguments \increment\MMLcDIVIDElevel \doifelse \@@MMLdividealternative\v!b { \getXMLstackdata\plustwo/\getXMLstackdata\plusthree } { \ifnum\MMLcDIVIDElevel>\@@MMLdividelevel\space \getXMLstackdata\plustwo/\getXMLstackdata\plusthree \else \MMLcreset \frac{\MMLcreset\getXMLstackdata\plustwo}{\MMLcreset\getXMLstackdata\plusthree}% \fi } \decrement\MMLcDIVIDElevel \stopusingMMLarguments \stopsetups % min max \defineXMLcommand [min] {\min\directsetup{mmc:minmax}} \defineXMLcommand [max] {\max\directsetup{mmc:minmax}} \startsetups mmc:minmax \doifelse{\getXMLstackdata\plustwo}{bvar} { {}_{\getXMLstackdata\plustwo} \left\{\flushXMLstackwith\plusthree{\MMLseparator,}\right\} } { \left\{\flushXMLstackwith\plustwo {\MMLseparator,}\right\} } \stopsetups % minus plus \defineXMLcommand [minus] {\directsetup{mmc:minus}} \defineXMLcommand [plus] [\MMLargumentprefix] [] {\directsetup{mmc:plus}} \setupMMLappearance [plus] [\c!alternative=\v!a] % b = no sign -> 3 1/4 \setupMMLappearance [sign] [\c!reduction=\v!yes] \startsetups mmc:minus \doif \@@MMLsignreduction \v!yes { \setMMLcreset{fn,\MMLcfunctionlist} } \ifcase\XMLstacklevel \or % self \or -\getXMLstackdata\plustwo \else \flushXMLstackwith\plustwo- \fi \stopsetups \startsetups mmc:plus \startusingMMLarguments \doifelse \@@MMLsignreduction \v!yes { \setMMLcreset{fn,plus,minus,\MMLcfunctionlist,\MMLcconstructlist}% was plus/, minus/ \doifelse{\getXMLstackname\plustwo} {apply} { % branch needed, else (a-b) + (c-d) goes wrong % reset check in case of (-x) + 37 \begingroup \dodoifelseMMCfunctioninapply \plustwo {minus} { \ifnum\XMLstacklevel>\plustwo \endgroup \else \endgroup \MMLcreset \fi } { \endgroup } \doifelse \@@MMLplusalternative \v!b { \getXMLstackdata\plustwo \, } { \flushXMLstackwith\plustwo + } } { \flushXMLstackwith\plustwo { \doifelse {\getXMLstackname\recurselevel} {apply} { \begingroup \dodoifelseMMCfunctioninapply \recurselevel {minus} { \ifnum\XMLstacklevel>\plustwo +\fi } { \doifelse \@@MMLplusalternative \v!b { \, % maybe 2 1/3 } { + } } \endgroup \MMLcreset } { + } } } } { \ifcase\XMLstacklevel \or % self \or +\getXMLstackdata\plustwo \else \flushXMLstackwith\plustwo+ \fi } \stopusingMMLarguments \stopsetups % power \defineXMLcommand [power] {\directsetup{mmc:power}} \setupMMLappearance[power][\c!reduction=\v!yes] \let\MMLpowerelement\empty \startsetups mmc:power \doifelse {\getXMLstackname\plustwo} {apply} { \doifelse\@@MMLpowerreduction\v!yes { \doifelseMMCfunctioninapply \plustwo \MMLcfunctionlist { \xdef\MMLpowerelement{\getXMLstackdata\plusthree}% postpone \MMLcreset\getXMLstackdata\plustwo } { \left(\MMLcreset\getXMLstackdata\plustwo\right)^{\MMLcreset\getXMLstackdata\plusthree} } } { \left(\MMLcreset\getXMLstackdata\plustwo\right)^{\MMLcreset\getXMLstackdata\plusthree} } } { \getXMLstackdata\plustwo^{\MMLcreset\getXMLstackdata\plusthree} } \stopsetups % rem \defineXMLcommand [rem] {\flushXMLstackwith\plustwo{\getXMLentity{mod}}} \setupMMLappearance [times] [\c!symbol=\v!no,\c!auto=\v!yes] % new, auto catches cn cn cn \defineXMLcommand [times] [\MMLargumentprefix] [] {\directsetup{mmc:times}} \startsetups mmc:times \startusingMMLarguments \setMMLcreset{\MMLcfunctionlist,\MMLcconstructlist}% \doifelse\@@MMLtimesauto\v!no { \let\@@MMLtimes@@symbol\@@MMLtimessymbol } { \countXMLnamedstack {cn} \ifnum\scratchcounter>\plusone \doifinsetelse\@@MMLtimessymbol{\v!yes,\v!no} { \let\@@MMLtimes@@symbol\v!yes } { \let\@@MMLtimes@@symbol\@@MMLtimessymbol } \else \let\@@MMLtimes@@symbol\@@MMLtimessymbol \fi } \doifelse\@@MMLtimes@@symbol\v!yes { \flushXMLstackwith\plustwo\times } { \doifelse\@@MMLtimes@@symbol{dot} { \flushXMLstackwith\plustwo\cdot } { \doifelse\@@MMLtimes@@symbol{times} { \flushXMLstackwith\plustwo\times } { \flushXMLstackwith\plustwo\empty } } } \stopusingMMLarguments \stopsetups \defineXMLcommand [root] {\directsetup{mmc:root}} \setupMMLappearance[root][\c!symbol=\v!yes] \startsetups mmc:root \XMLdoifonstackelse {degree} { \root \doifnot\@@MMLrootsymbol\v!no{\MMLcreset\XMLfirstnamed{degree}} \of } { \sqrt } {\MMLcreset\XMLfirstnamed{apply,reln,ci,cn}} \stopsetups % gcd \defineXMLcommand [gcd] {\gcd\left(\MMLcreset\flushXMLstackwith\plustwo{\MMLseparator,}\right)} % and or xor implies \defineXMLcommand [and] {\flushXMLstackwith\plustwo{\getXMLentity{and}}} \defineXMLcommand [or] {\flushXMLstackwith\plustwo{\getXMLentity{or}}} \defineXMLcommand [xor] {\flushXMLstackwith\plustwo{\getXMLentity{xor}}} \defineXMLcommand [implies] {\flushXMLstackwith\plustwo{\getXMLentity{implies}}} % not \defineXMLcommand [not] {\getXMLentity{not}\getXMLstackdata\plustwo} % forall exists \defineXMLcommand [forall] {\directsetup{mmc:forall}} \defineXMLcommand [exists] {\directsetup{mmc:exists}} %D We need to shift left below rotated A. \startsetups mmc:forall \getXMLentity{forall} \getXMLentity{NegThinSpace} \directsetup{mmc:forall-exists} \stopsetups \startsetups mmc:exists \getXMLentity{exists} \directsetup{mmc:forall-exists} \stopsetups \startsetups mmc:forall-exists _{\flushXMLnamedstackwith\plustwo{bvar}{\MMLseparator,}} \XMLdoifonstackelse {condition} { \getXMLentity{ThickSpace} \begingroup \XMLfirstnamed{condition} \endgroup \countXMLnamedstack {apply,reln,ci,cn} \ifcase\scratchcounter \or % == snelle volgende \left\vert \MMLcreset \getXMLentity{MediumSpace} \flushXMLnamedstackwith\plustwo{apply,reln,ci,cn}\empty \right. \else % special case % \defineXMLignore[condition] \collectXMLnamedstack{apply,reln,ci,cn}{\hfill\crcr} \left\vert \matrix{\the\XMLRtoks} \right. \fi } { :\XMLfirstnamed{apply,reln,ci,cn} } \stopsetups \defineXMLcommand [abs] {\left\vert \MMLcreset \flushXMLstackfrom\plustwo \right\vert} \defineXMLcommand [conjugate] {{\overline{\MMLcreset \flushXMLstackfrom\plustwo}}} % watch extra {} \defineXMLcommand [arg] {\getXMLentity{arg} \left(\MMLcreset\flushXMLstackfrom\plustwo\right)} \defineXMLcommand [real] {\getXMLentity{real} \left(\MMLcreset\flushXMLstackfrom\plustwo\right)} \defineXMLcommand [imaginary] {\getXMLentity{imaginary}\left(\MMLcreset\flushXMLstackfrom\plustwo\right)} \defineXMLcommand [lcm] {\getXMLentity{lcm} \left(\flushXMLstackwith\plustwo{\MMLseparator,}\right)} \defineXMLcommand [floor] {\getXMLentity{lfloor} \flushXMLstackfrom\plustwo \getXMLentity{rfloor}} \defineXMLcommand [ceiling] {\getXMLentity{lceiling} \flushXMLstackfrom\plustwo \getXMLentity{rceiling}} % relations \defineXMLcommand [eq] [\MMLargumentprefix] [\c!align=] {\MMLcrelation=} \defineXMLcommand [neq] [\MMLargumentprefix] [\c!align=] {\MMLcrelation\neq} \defineXMLcommand [gt] [\MMLargumentprefix] [\c!align=] {\MMLcrelation>} \defineXMLcommand [lt] [\MMLargumentprefix] [\c!align=] {\MMLcrelation<} \defineXMLcommand [geq] [\MMLargumentprefix] [\c!align=] {\MMLcrelation\geq} \defineXMLcommand [leq] [\MMLargumentprefix] [\c!align=] {\MMLcrelation\leq} \defineXMLcommand [equivalent] [\MMLargumentprefix] [\c!align=] {\MMLcrelation\equiv} \defineXMLcommand [approx] [\MMLargumentprefix] [\c!align=] {\MMLcrelation\approx} \defineXMLcommand [factorof] [\MMLargumentprefix] [\c!align=] {\MMLcrelation\mid} \setupMMLappearance[relation][\c!align=\v!no] \def\MMLcrelation {\startusingMMLarguments \MMLcreset \edef\@@MMLrelationalign{\executeifdefined{\MMLargumentprefix\c!align}\@@MMLrelationalign}% \processaction [\@@MMLrelationalign] [\v!last=>\let\next\lastMMLcrelation , \v!first=>\let\next\firstMMLcrelation, \v!yes=>\let\next\leftMMLcrelation , \v!left=>\let\next\leftMMLcrelation , \v!right=>\let\next\rightMMLcrelation, \s!default=>\let\next\noMMLcrelation , \s!unknown=>\let\next\noMMLcrelation ] \next} \def\noMMLcrelation#1% {\flushXMLstackwith\plustwo{#1} \stopusingMMLarguments} \def\lastMMLcrelation#1% weird, probably bugged {\XMLRtoks\emptytoks \dostepwiserecurse\plustwo\XMLstacklevel\plusone {\appendetoks\noexpand\getXMLstackdata{\recurselevel}\to\XMLRtoks \ifnum\recurselevel<\numexpr\XMLstacklevel-1\relax \appendtoks\@col@amp@#1\crcr\to\XMLRtoks \else\ifnum\recurselevel=\numexpr\XMLstacklevel-1\relax \appendtoks\@col@amp@#1\to\XMLRtoks \fi\fi}% \eqalign{\the\XMLRtoks\crcr}% \stopusingMMLarguments} \def\firstMMLcrelation#1% {\collectXMLstackrows\plusthree{\crcr\@col@amp@#1}% \eqalign{\getXMLstackdata\plustwo\@col@amp@#1\the\XMLRtoks}% \stopusingMMLarguments} \def\leftMMLcrelation#1% {\collectXMLstackrows\plustwo{\@col@amp@#1\crcr}% \eqalign{\the\XMLRtoks}% \stopusingMMLarguments} \def\rightMMLcrelation#1% {\collectXMLstackrows\plustwo{\crcr#1{}\@col@amp@}% \eqalign{\@col@amp@\the\XMLRtoks\crcr}% \stopusingMMLarguments} \defineXMLcommand [becomes] {\MMLcrelation{:=}} \addtocommalist{becomes/}\MMLcmainresetlist % calculus and vector calculus \setupMMLappearance[int][\c!location=\v!top] \def\doMMLlimits#1% {\doifelsevalue{@@MML#1\c!location}\v!top\limits\nolimits} \defineXMLnested [domainofapplication] {\directsetup{mmc:domainofapplication:start}} {\directsetup{mmc:domainofapplication:stop}} \startsetups mmc:domainofapplication:start \begingroup \startsavingXMLelements \stopsetups \startsetups mmc:domainofapplication:stop \stopsavingXMLelements % \MMLcreset \flushXMLstackfrom\plusone \endgroup \stopsetups \defineXMLcommand [int] {\directsetup{mmc:int}} \startsetups mmc:int \MMLcreset \XMLdoifonstackelse{domainofapplication} { \int\doMMLlimits{int}_{\XMLfirstnamed{domainofapplication}}\relax } { \XMLdoifonstackelse{condition} { \int\doMMLlimits{int}_{\XMLfirstnamed{condition}}\relax } { \XMLdoifonstackelse{lowlimit} { \int\doMMLlimits{int} _{\XMLfirstnamed{lowlimit}} ^{\XMLfirstnamed{uplimit}} } { % funny, why do we have lowlimit/uplimit then \XMLdoifonstackelse{interval} { \begingroup \startlocalsetups mmc:interval:start % \begingroup \startsavingXMLelements \stoplocalsetups \startlocalsetups mmc:interval:stop % \stopsavingXMLelements \xdef\MMLfirstelement {\getXMLstackdata\plusone} \xdef\MMLsecondelement{\getXMLstackdata\plustwo} \endgroup \stoplocalsetups \globallet\MMLfirstelement \empty \globallet\MMLsecondelement\empty \XMLfirstnamed{interval} \endgroup \int\doMMLlimits{int} _{\MMLfirstelement} ^{\MMLsecondelement} } { \int } } } } \MMLcreset \XMLdoifonstackelse{apply} { \doifelseMMCfunction { \XMLfirstnamed{apply} } { % if there are too many () now, we need to be more clever \left(\XMLfirstnamed{apply}\right) } } { \XMLfirstnamed{ci} } \XMLdoifonstackelse{bvar} { \,% \getXMLentity{ThinSpace}% % {\MMLrm\getXMLentity{mathematicald}} \mfunction{\getXMLentity{mathematicald}} \XMLfirstnamed{bvar} } { % nothing } \stopsetups \setupMMLappearance[diff][\c!location=\v!top,\c!alternative=\v!a] \defineXMLcommand [diff] {\directsetup{mmc:diff}} \defineXMLcommand [partialdiff] {\directsetup{mmc:partialdiff}} % \setupMMLappearance[diff][alternative=b] % % \startXMLdata % xfa % x2fa % \stopXMLdata % d^y/dx^2 % % \startXMLdata % % x2 % xy % % \stopXMLdata \startsetups mmc:diff \MMLcreset \doifelse\@@MMLdiffalternative\v!a { \XMLdoifonstackelse{lambda} { % a special case (mathadore/openmath) \begingroup \defineXMLsave[ci] \defineXMLsave[cn] \defineXMLprocess[lambda] \defineXMLprocess[bvar] \frac { d^{\XMLfirstnamed{bvar}\XMLflush{cn}}{\XMLfirstnamed{lambda}\XMLflush{ci}} } { d{\XMLfirstnamed{bvar}\XMLflush{ci}}^{\XMLfirstnamed{bvar}\XMLflush{cn}} } \endgroup } { \XMLdoifonstackelse{bvar} { \frac { \XMLdoifonstackelse{degree} { \collectXMLnamedstack{degree}\empty } { \collectXMLnamedstacknamed{bvar}{degree}+ } \mfunction{\getXMLentity{mathematicald}} ^{\the\XMLRtoks} \doif\@@MMLdifflocation\v!top { \XMLdoifonstackelse{ci} { \XMLfirstnamed{ci} } { \MMLcreset\XMLfirstnamed{apply} } } } { \mfunction{\getXMLentity{mathematicald}} \begingroup \defineXMLsave[degree] \XMLfirstnamed{bvar} \doifXMLdata{degree} { ^{\XMLflush{degree}} } \endgroup } \doifnot\@@MMLdifflocation\v!top { \left(\MMLcreset\XMLfirstnamed{apply,ci}\right) } } { \flushXMLstackfrom\plustwo^\prime } } } { \MMLcreset \XMLfirstnamed{apply,ci} % there can be problems with nested diff's: ^^{} error % so we add an empty group here {}^ { \XMLdoifonstackelse{degree} { \defXMLfirstnamedtext\ascii{degree} \dorecurse\ascii\prime } { \prime } } } \stopsetups \startsetups mmc:partialdiff \XMLdoifonstackelse{list} { \getXMLentity{capitaldifferentiald}_{ \begingroup \setfalse\MMLlistdelimiters \XMLallnamed{list} \endgroup } \XMLfirstnamed{apply,reln,ci,cn} } { \XMLdoifonstackelse{bvar} { \frac { \XMLdoifonstackelse{degree} { \collectXMLnamedstack{degree}\empty } { \collectXMLnamedstacknamed{bvar}{degree}+ } \getXMLentity{differentiald}^{\the\XMLRtoks} % \let\MMLcDEGREE\gobbletwoarguments % \doifelseMMCfunction\MMLcreset\donothing \MMLcreset \XMLfirstnamed{apply,reln,ci,cn} } { \defineXMLnested[bvar] {\directsetup{mmc:bvar:diff:start}} {\directsetup{mmc:bvar:diff:stop}} \XMLfirstnamed{bvar} } } { \XMLfirstnamed{apply,reln,ci,cn} } } \stopsetups \startsetups mmc:bvar:diff:start \begingroup \startsavingXMLelements \stopsetups \startsetups mmc:bvar:diff:stop \stopsavingXMLelements \getXMLentity{differentiald}\XMLfirstnamed{apply,reln,ci,cn} \XMLdoifonstackelse{degree} { ^{\XMLfirstnamed{degree}} } { % nothing } \endgroup \stopsetups \def\subMMLcelement #1#2{_{#2}} \def\superMMLcelement#1#2{^{#2}} \defineXMLprocess [lowlimit] \defineXMLprocess [uplimit] \defineXMLprocess [bvar] \defineXMLprocess [degree] % option: % % \defineXMLentity [div] {\mathematics{\triangledown\times}} % \defineXMLentity [curl] {\mathematics{\triangledown .}} % \defineXMLentity [grad] {\mathematics{\triangledown }} \defineXMLcommand [divergence] {\getXMLentity{divergence}\directsetup{mmc:donamedfunction}} \defineXMLcommand [grad] {\getXMLentity {grad}\directsetup{mmc:donamedfunction}} \defineXMLcommand [curl] {\getXMLentity {curl}\directsetup{mmc:donamedfunction}} \defineXMLcommand [laplacian] {\getXMLentity {laplacian}\directsetup{mmc:donamedfunction}} \defineXMLcommand [ident] {\getXMLentity {identity}\directsetup{mmc:donamedfunction}} % \defineXMLcommand [domain] {\getXMLentity {domain}\directsetup{mmc:donamedfunction}} % \defineXMLcommand [codomain] {\getXMLentity {codomain}\directsetup{mmc:donamedfunction}} \defineXMLcommand[domain] {\directsetup{mmc:domain:action}} \defineXMLcommand[codomain]{\directsetup{mmc:codomain:action}} \setupMMLappearance[domain] [symbol=] \setupMMLappearance[codomain][symbol=] \startsetups mmc:domain:action \doifelsenothing\@@MMLdomainsymbol { \getXMLentity{domain}\directsetup{mmc:donamedfunction} } { \@@MMLdomainsymbol_{\flushXMLstackfrom\plustwo} } \stopsetups \startsetups mmc:codomain:action \doifelsenothing\@@MMLcodomainsymbol { \getXMLentity{codomain}\directsetup{mmc:donamedfunction} } { \@@MMLcodomainsymbol_{\flushXMLstackfrom\plustwo} } \stopsetups \startsetups mmc:donamedfunction % \left( % \begingroup \MMLcreset\flushXMLstackfrom\plustwo % \endgroup % \right) \stopsetups % theory of sets \defineXMLnested [set] {\setups{mmc:set:start}} {\setups{mmc:set:stop}} \startsetups mmc:set:start \begingroup \startsavingXMLelements \stopsetups \startsetups mmc:set:stop \stopsavingXMLelements \XMLdoifonstackelse{condition} { \left\{\XMLfirstnamed{bvar}\,\middle\vert\,\XMLfirstnamed{condition}\right\} } { \left\{\flushXMLstackwith\plusone{\MMLseparator,}\right\} } \endgroup \stopsetups \defineXMLnested [list] {\setups{mmc:list:start}} {\setups{mmc:list:stop}} \settrue\MMLlistdelimiters \startsetups mmc:list:start \begingroup \startsavingXMLelements \stopsetups \startsetups mmc:list:stop \stopsavingXMLelements \ifconditional\MMLlistdelimiters\left [\fi \begingroup \settrue\MMLlistdelimiters \flushXMLstackwith\plusone{\MMLseparator,} \endgroup \ifconditional\MMLlistdelimiters\right]\fi \endgroup \stopsetups \defineXMLcommand [union] {\MMLcset\cup} \defineXMLcommand [intersect] {\MMLcset\cap} \defineXMLcommand [in] {\MMLcset\in} \defineXMLcommand [notin] {\MMLcset{\not\in}} \defineXMLcommand [subset] {\MMLcset\subset} \defineXMLcommand [prsubset] {\MMLcset\subseteq} \defineXMLcommand [notsubset] {\MMLcset{\not\subset}} \defineXMLcommand [notprsubset] {\MMLcset{\not\subseteq}} \defineXMLcommand [setdiff] {\MMLcset\setminus} \def\MMLcset#1{\getXMLstackdata\plustwo#1\getXMLstackdata\plusthree} \defineXMLcommand [card] {\left\vert\flushXMLstackfrom\plustwo\right\vert} \defineXMLcommand [cartesianproduct] {\flushXMLstackwith\plustwo\times} % sequences and series \defineXMLcommand [sum] {\MMLcSUMandPRODUCT{sum}\sum} \defineXMLcommand [product]{\MMLcSUMandPRODUCT{product}\prod} \setupMMLappearance[sum] [\c!location=\v!top] \setupMMLappearance[product][\c!location=\v!top] \def\stackMMLsubscripts#1% {\vbox {\baselineskip\zeropoint % hack, taco vragen \halign{$\scriptstyle\hss##\hss$\cr#1\crcr}}} \def\MMLcSUMandPRODUCT#1#2% {\begingroup \XMLdoifonstackelse{condition,bvar,lowlimit} {\def\MMLcSUMlow {_{\XMLdoifonstackelse{condition} {\collectXMLnamedstack{condition}{\crcr}% \stackMMLsubscripts{\the\XMLRtoks}} {\XMLdoifonstackelse{bvar} {\XMLfirstnamed{bvar}% \XMLdoifonstackelse{lowlimit}{=}{}}% {}% \XMLfirstnamed{lowlimit}}}}} {\let\MMLcSUMlow\empty}% \XMLdoifonstackelse{uplimit} {\def\MMLcSUMup{^{\XMLfirstnamed{uplimit}}}} {\let\MMLcSUMup\empty}% \XMLdoifonstackelse{interval} % open math converter gives this {\begingroup \directsetup{mmc:interval:fetch}% \XMLfirstnamed{interval}% \endgroup \ifx\MMCintervalfrom\empty\else \def\MMLcSUMlow{_{\XMLdoifonstackelse{bvar}{\XMLfirstnamed{bvar}{=}}{}\MMCintervalfrom}}% \fi \ifx\MMCintervalto\empty \else \def\MMLcSUMup{^{\MMCintervalto}}% \fi} {}% \MMLcreset#2\doMMLlimits{#1}\MMLcSUMup\MMLcSUMlow \directsetup{mmc:lambda:simple}% a bit of open math conversion mess \MMLcreset\XMLfirstnamed{apply,lambda,ci}% \endgroup} \defineXMLcommand [limit] {\directsetup{mmc:limit}} \setupMMLappearance[limit][\c!location=\v!top] \startsetups mmc:limit \MMLcreset \lim \doMMLlimits{limit}_{ \MMLcreset \XMLdoifonstackelse {condition} { \XMLfirstnamed{condition} } { \XMLdoifonstackelse {bvar} { \XMLfirstnamed{bvar}\rightarrow } { } \XMLfirstnamed{lowlimit} } } \begingroup \MMLcreset \directsetup{mmc:lambda:simple}% a bit of open math conversion mess \XMLfirstnamed{apply,lambda}% lambda needed for openmath \endgroup \stopsetups \defineXMLcommand [tendsto] [type=default] {\directsetup{mmc:tendsto}} \startsetups mmc:tendsto \MMLcreset \getXMLstackdata\plustwo \processaction [\XMLpar{tendsto}{type}{default}] [ above=>\downarrow, below=>\uparrow, unknown=>\rightarrow] \MMLcreset \getXMLstackdata\plusthree \stopsetups % elementary classical functions \defineXMLcommand [exp] {\directsetup{mmc:exp}} \defineXMLcommand [ln] {\directsetup{mmc:function}} \defineXMLcommand [log] {\directsetup{mmc:log}} \defineXMLignore [logbase] \setupMMLappearance[log][\c!location=\v!right] \startsetups mmc:exp \getXMLentity{exponentiale}^{\XMLfirstnamed{apply,reln,ci,cn}} \stopsetups \startsetups mmc:log \XMLdoifonstackelse {logbase} { \doifelse\@@MMLloglocation\v!left { \mathop{{}^{{\defineXMLprocess[logbase]\XMLfirstnamed{logbase}}} \getXMLentity{NegThinSpace} \getXMLentity{log}} } { \getXMLentity{log}_{{\defineXMLprocess[logbase]\XMLfirstnamed{logbase}}} } } { \getXMLentity{log} } \MMLcreset % mmc:function:argument assumes that the apply is second in the row (*1*) % \removeXMLdatafromstack{logbase} \directsetup{mmc:function:argument} \stopsetups % statistics \defineXMLcommand [mean] {\overline{\getXMLstackdata\plustwo}} \defineXMLcommand [sdev] {\sigma(\MMLcreset\getXMLstackdata\plustwo)} \defineXMLcommand [variance] {\sigma(\MMLcreset\getXMLstackdata\plustwo)^2} \defineXMLcommand [median] {\getXMLentity{median}(\MMLcreset\getXMLstackdata\plustwo)} \defineXMLcommand [mode] {\getXMLentity{mode}(\MMLcreset\getXMLstackdata\plustwo)} % moments \defineXMLcommand [moment] {\directsetup{mmc:moment}} \defineXMLprocess [momentabout] \startsetups mmc:moment \left\langle\XMLfirstnamed{apply,reln,ci,cn}^{\XMLfirstnamed{degree}}\right\rangle \XMLdoifonstackelse{momentabout} { _{\XMLfirstnamed{momentabout}} } { } \stopsetups % linear algebra \defineXMLcommand [vector] {\directsetup{mmc:vector}} % sequence \setupMMLappearance [vector] [\c!direction=\v!horizontal,\c!separator={,}] \defineXMLnested [vector] {\directsetup{mmc:vector:start}} {\directsetup{mmc:vector:stop}} \startsetups mmc:vector:start \begingroup \startsavingXMLelements \stopsetups \startsetups mmc:vector:stop \stopsavingXMLelements \ifnum\XMLstacklevel>\plusone \doifelse\@@MMLvectordirection\v!horizontal { \left(\flushXMLstackwith\plusone{\MMLseparator\@@MMLvectorseparator}\right) } { \collectXMLstack\crcr \MMLcreset\left(\matrix{\the\XMLRtoks}\right) } \else \overrightarrow{\charhtstrut\getXMLstackdata\plusone} \fi \endgroup \stopsetups \defineXMLnestedenvironmentsave [matrix] {} {\directsetup{mmc:matrix}} \defineXMLnestedenvironmentsave [matrixrow] {} {\directsetup{mmc:matrixrow}} \unexpanded\def\@col@amp@{&} \settrue\MMCdelmatrix %( ) when true \startsetups mmc:matrix \begingroup \MMLcreset \defineXMLnestedenvironmentsave [matrixrow] {} {\directsetup{mmc:matrixrow:do}} \ifconditional\MMCdelmatrix \left(\matrix{\XMLflush{matrix}}\right) \else \settrue\MMCdelmatrix \matrix{\XMLflush{matrix}} \fi \endgroup \stopsetups \startsetups mmc:matrixrow \begingroup \MMLcreset \left(\matrix{\directsetup{mmc:matrixrow:do}}\right) \endgroup \stopsetups \startsetups mmc:matrixrow:do \begingroup \startsavingXMLelements \XMLflush{matrixrow} \stopsavingXMLelements \collectXMLstackrows\plusone\@col@amp@ \edef\ascii{\the\XMLRtoks} \edef\ascii{\ascii} \expandafter\endgroup\ascii\crcr \stopsetups \defineXMLcommand [determinant] {\directsetup{mmc:determinant}} \defineXMLcommand [transpose] {\directsetup{mmc:transpose}} \defineXMLcommand [selector] {\directsetup{mmc:selector}} \startsetups mmc:determinant \begingroup \left| \setfalse\MMCdelmatrix \getXMLstackdata\plustwo \right| \endgroup \stopsetups \startsetups mmc:transpose % \getXMLstackdata\plustwo^{\MMLrm T} \getXMLstackdata\plustwo^{\mfunction{T}} \stopsetups \startsetups mmc:selector \MMLmathinner{\getXMLstackdata\plustwo}_{\MMLcreset\flushXMLstackwith\plusthree{\MMLseparator,}} \stopsetups \defineXMLcommand [vectorproduct] {\getXMLstackdata\plustwo\getXMLentity{vectorproduct}\getXMLstackdata\plusthree} \defineXMLcommand [scalarproduct] {\getXMLstackdata\plustwo\getXMLentity{scalarproduct}\getXMLstackdata\plusthree} \defineXMLcommand [outerproduct] {\getXMLstackdata\plustwo\getXMLentity {outerproduct}\getXMLstackdata\plusthree} % semantic mapping elements \defineXMLnested [semantics] {\directsetup{mmc:semantics:start}} {\directsetup{mmc:semantics:stop}} \startsetups mmc:semantics:start \begingroup \startsavingXMLelements \stopsetups \startsetups mmc:semantics:stop \stopsavingXMLelements \XMLdoifonstackelse {annotation} { \flushXMLnamedstackwith\plusone{annotation}\empty } { \flushXMLnamedstackwith\plusone{apply}\empty } \endgroup \stopsetups \defineXMLenvironmentsave [annotation] [encoding=] {} {\directsetup{mmc:annotation}} \startsetups mmc:annotation \expanded{\doifinset{\XMLpar{annotation}{encoding}{}}{TeX,tex,TEX,ConTeXt,context,CONTEXT}} { \XMLtexdata{annotation} } \stopsetups \defineXMLignore [annotation-xml] % misc \defineXMLcommand [integers] {\getXMLentity{integers}} \defineXMLcommand [reals] {\getXMLentity{reals}} \defineXMLcommand [rationals] {\getXMLentity{rationals}} \defineXMLcommand [naturalnumbers] {\getXMLentity{naturalnumbers}} \defineXMLcommand [complexes] {\getXMLentity{complexes}} \defineXMLcommand [primes] {\getXMLentity{primes}} \defineXMLcommand [exponentiale] {\getXMLentity{ExponentialE}} \defineXMLcommand [imaginaryi] {\getXMLentity{ImaginaryI}} \defineXMLcommand [notanumber] {\mathop{\mfunction{NaN}}} \defineXMLcommand [true] {\mathop{\mfunction{true}}} \defineXMLcommand [false] {\mathop{\mfunction{false}}} \defineXMLcommand [emptyset] {\mathop{\O}} \defineXMLcommand [pi] {\pi} \defineXMLcommand [eulergamma] {\gamma} \defineXMLcommand [infinity] {\infty} % gonio functions \defineXMLcommand[sin] {\directsetup{mmc:function}} \defineXMLcommand[arcsin] {\directsetup{mmc:function}} \defineXMLcommand[sinh]{\directsetup{mmc:function}} \defineXMLcommand[arcsinh]{\directsetup{mmc:function}} \defineXMLcommand[cos] {\directsetup{mmc:function}} \defineXMLcommand[arccos] {\directsetup{mmc:function}} \defineXMLcommand[cosh]{\directsetup{mmc:function}} \defineXMLcommand[arccosh]{\directsetup{mmc:function}} \defineXMLcommand[tan] {\directsetup{mmc:function}} \defineXMLcommand[arctan] {\directsetup{mmc:function}} \defineXMLcommand[tanh]{\directsetup{mmc:function}} \defineXMLcommand[arctanh]{\directsetup{mmc:function}} \defineXMLcommand[cot] {\directsetup{mmc:function}} \defineXMLcommand[arccot] {\directsetup{mmc:function}} \defineXMLcommand[coth]{\directsetup{mmc:function}} \defineXMLcommand[arccoth]{\directsetup{mmc:function}} \defineXMLcommand[csc] {\directsetup{mmc:function}} \defineXMLcommand[arccsc] {\directsetup{mmc:function}} \defineXMLcommand[csch]{\directsetup{mmc:function}} \defineXMLcommand[arccsch]{\directsetup{mmc:function}} \defineXMLcommand[sec] {\directsetup{mmc:function}} \defineXMLcommand[arcsec] {\directsetup{mmc:function}} \defineXMLcommand[sech]{\directsetup{mmc:function}} \defineXMLcommand[arcsech]{\directsetup{mmc:function}} \setupMMLappearance[function][\c!reduction=\v!yes] \startsetups mmc:function \getXMLentity\currentXMLelement \ifx\MMLpowerelement\empty\else ^{\MMLcreset\MMLpowerelement\empty} \getXMLentity{NegThinSpace} \global\let\MMLpowerelement\empty \fi \doif {\getXMLstackname\plusone} {\currentXMLelement} { % rather fuzzy test; looks like an apply case \directsetup{mmc:function:argument} } \stopsetups \startsetups mmc:function:argument \doifelse\@@MMLfunctionreduction\v!yes { % \doifelse {\getXMLstackname\plustwo} {apply} { % \doifelseMMCfunctioninapply \plustwo \MMLcfunctionlist \donefalse \donetrue % % best is to grab the apply (independent of order), (*1*), so: % \XMLdoifonstackelse {apply} { \doifelseMMCfunctioninapply \XMLstackposition {\MMLcfunctionlist,divide} \donefalse \donetrue } { \donefalse } } { \donetrue } % beware, we still flush from 2 up \ifdone \left(\MMLcreset\flushXMLstackfrom\plustwo\right) \else \MMLcreset\flushXMLstackfrom\plustwo \fi \stopsetups % presentation mml \def\resetMMLseparator {\newcounter\MMLxxcounter \let\lastMMLseparator\empty} \def\grabMMLseparator#1% {\increment\MMLxxcounter \newcounter\MMLyycounter \expanded{\dograbMMLseparator#1\noexpand\relax}} \def\dograbMMLseparator {\increment\MMLyycounter \doifnextcharelse\relax {\lastMMLseparator\gobbleoneargument} {\doifnextcharelse\xmlrent\grabMMLseparatora\grabMMLseparatorb}} \def\grabMMLseparatora#1\xmlrent#2% {\ifnum\MMLxxcounter=\MMLyycounter\space \def\lastMMLseparator{\xmlrent{#2}}% \fi \dograbMMLseparator} \def\grabMMLseparatorb#1% {\ifnum\MMLxxcounter=\MMLyycounter\space \doifXMLentityelse{#1} {\def\lastMMLseparator{\xmlrent{#1}}} {\def\lastMMLseparator{#1}}% \fi \dograbMMLseparator} % \defineXMLargument [mi] \MMLpMI \defineXMLargument [mn] \MMLpMN \defineXMLargument [mo] \MMLpMO \def\MMLpMI#1% {\begingroup \setMMLpmathstyle{mstyle}% #1% \endgroup} % \def\MMLpMN#1% % {\begingroup % \MMLrm % \setMMLpmathstyle{mstyle}% % #1% % \endgroup} \def\MMLpMN#1% {\mfunction{\setMMLpmathstyle{mstyle}#1}} \def\MMLpMO#1% yes or no {\flattenXMLcontent{#1}% \doifXMLentityelse\flattenedXMLcontent {\getXMLentity\flattenedXMLcontent} {\ConvertConstantAfter\doifinstringelse{\xmlrent}{#1} % TODO ! ! ! ! ! ! ! ! {#1} {\hbox {\setMMLpmathstyle{mstyle}% \ignorespaces#1\unskip}}}} % we need to get rid of spaces: \def\MMLpMO#1% yes or no {\flattenXMLcontent{#1}% \doifXMLentityelse\flattenedXMLcontent {\getXMLentity\flattenedXMLcontent} {\ignorespaces#1\removeunwantedspaces}} \def\doMMLleft #1{\pushmacro\left \let\left \empty\normalleft #1\popmacro\left} \def\doMMLright#1{\pushmacro\right\let\right\empty\normalright#1\popmacro\right} \let\MMLpopen \empty \let\MMLpclose\empty \defineXMLnested [mfenced] [open=(,close=),separators=] {\directsetup{mmp:mfenced:start}} {\directsetup{mmp:mfenced:stop}} \startsetups mmp:mfenced:start \begingroup \startsavingXMLelements \stopsetups \startsetups mmp:mfenced:stop \stopsavingXMLelements \edef\MMLpopen {\XMLpar{mfenced}{open} {}} \edef\MMLpclose{\XMLpar{mfenced}{close}{}} \ifx\MMLpopen \space\let\MMLpopen \empty\fi \ifx\MMLpclose\space\let\MMLpclose\empty\fi \ifx\MMLpopen\empty \ifx\MMLpclose\empty \else \doMMLleft. \fi \else \doMMLleft\MMLpopen \fi \pushmacro\MMLpopen \pushmacro\MMLpclose \doifelsenothing{\XMLpar{mfenced}{separators}{}} { \flushXMLstackfrom\plusone } { \resetMMLseparator \flushXMLstackwith\plusone { \begingroup \let\myspecialnormalvert\myspecialstretchvert \grabMMLseparator{\XMLpar{mfenced}{separators}{}} \endgroup } } \popmacro\MMLpclose \popmacro\MMLpopen \ifx\MMLpclose\empty \ifx\MMLpopen\empty \else \doMMLright. \fi \else \doMMLright\MMLpclose \fi \endgroup \stopsetups % \startbuffer % x % x % x % x % x % \stopbuffer % % \processXMLbuffer \defineXMLnestedenvironmentsave [menclose] [notation=] {\directsetup{mmp:menclose:start}} {\directsetup{mmp:menclose:stop}} \startsetups mmp:menclose:start \begingroup \stopsetups \startsetups mmp:menclose:stop \doifelse{\XMLpar{menclose}{notation}{}}{longdiv} { \overline{)\XMLflush{menclose}} } { \XMLflush{menclose} } \endgroup \stopsetups \defineXMLnested [mfrac] [linethickness=] {\directsetup{mmp:mfrac:start}} {\directsetup{mmp:mfrac:stop}} \startsetups mmp:mfrac:start \begingroup \startsavingXMLelements \stopsetups \startsetups mmp:mfrac:stop \stopsavingXMLelements \doifXMLparelse{mfrac}{linethickness} { \edef\theXMLpar{\XMLpar{mfrac}{linethickness}{1}} \processaction [\theXMLpar] [ thin=>\scratchdimen=.2pt, medium=>\scratchdimen=.4pt, thick=>\scratchdimen=.8pt, unknown=>\setdimensionwithunit\scratchdimen{\theXMLpar}{}] {{\getXMLstackdata\plusone}\above\scratchdimen{\getXMLstackdata\plustwo}} } { \frac{\getXMLstackdata\plusone}{\getXMLstackdata\plustwo} } \endgroup \stopsetups \defineXMLargument [ms] [lquote=\xmlrent{quot}, rquote=\xmlrent{quot}, fontweight=, fontstyle=, mathstyle=, mathvariant=, background=, color=] {\MMLpSTRING} \def\MMLpSTRING#1% {\hbox {\tf % else encoding problems \MMLpTEXT{\XMLpar{ms}{lquote}{}% \doMMPpbackground{ms}{\doMMPpcolor{ms}{\setMMLptextstyle{ms}\ignorespaces#1\removeunwantedspaces}}% \XMLpar{ms}{rquote}{}}}} \defineXMLenvironment [mstyle] [fontweight=, fontstyle=, mathstyle=, mathvariant=, background=, color=] {\begingroup} {\endgroup} \defineXMLargument [mtext] [CPA] \MMLpTEXT \defineXMLargument [merror] [CPA] \MMLpERROR \defineXMLargument [mphantom] [CPA] \MMLpPHANTOM \defineXMLargument [mpadded] [CPA] \MMLpPADDED \mapXMLvalue{mmp}{normal} {\tf} \mapXMLvalue{mmp}{double-stuck} {\bf} \mapXMLvalue{mmp}{bolditalic} {\bi} \mapXMLvalue{mmp}{bold-italic} {\bi} \mapXMLvalue{mmp}{boldslanted}{\bs} \mapXMLvalue{mmp}{bold-slanted} {\bs} \mapXMLvalue{mmp}{boldnormal} {\bf} \mapXMLvalue{mmp}{bold} {\bf} \mapXMLvalue{mmp}{slanted} {\sl} \mapXMLvalue{mmp}{normalslanted}{\sl} \mapXMLvalue{mmp}{italic} {\it} \mapXMLvalue{mmp}{normalitalic} {\it} \mapXMLvalue{mmp}{fraktur} {\bf} \mapXMLvalue{mmp}{bold-fraktur} {\bf} \mapXMLvalue{mmp}{script} {\tf} \mapXMLvalue{mmp}{bold-script} {\bf} % and all kind of other crappy names \def\setMMLptextstyle#1% {\XMLval{mmp}{\XMLpar{#1}{fontweight}{}\XMLpar{#1}{fontstyle}{}}{}} \def\setMMLpmathstyle#1% {\XMLval{mmp}{\XMLpar{#1}{mathvariant}{}}{}} \def\doMMPpcolor#1#2% {\doifXMLparelse{#1}{color}{\color[\XMLpar{#1}{color}{}]{#2}}{#2}} \def\doMMPpbackground#1#2% {\doifXMLparelse{#1}{background} {\inframed [\c!frame=\v!off, \c!background=\v!color, \c!backgroundcolor=\XMLpar{#1}{background}{}] {#2}} {#2}} \def\MMLpTEXT#1% {\hbox {\tf % else encoding problems \doMMPpbackground{ms}{\doMMPpcolor{ms}{\setMMLptextstyle{ms}\ignorespaces#1\removeunwantedspaces}}}} \def\MMLpERROR#1% {\hbox{$\displaystyle#1$}} \def\MMLpPHANTOM#1% {\phantom{\ignorespaces{}#1\unskip}} % watch spacing {} hack \def\MMLpPADDED#1% {#1} % mrow \defineXMLenvironment [mrow] {\resetMMLbounds} {\finishMMLbounds} % \def\MMLleft #1{\increment\MMLboundslevel\left #1} % \def\MMLright#1{\right#1\decrement\MMLboundslevel} % \def\resetMMLbounds % {\let\MMLboundslevel\!!plusone\left.} % \def\finishMMLbounds % {\dorecurse\MMLboundslevel{\right.}} \def\resetMMLbounds {\pushmacro\MMLboundslevel \newcounter\MMLboundslevel} \def\MMLleft #1% {\increment\MMLboundslevel \normalleft#1} \def\MMLright#1% {\ifnum\MMLboundslevel=0 \normalleft.\!\fi \normalright#1% \decrement\MMLboundslevel} \def\finishMMLbounds {\ifnum\MMLboundslevel>0 \normalright.\!% \decrement\MMLboundslevel \expandafter\finishMMLbounds \else \popmacro\MMLboundslevel \fi} \defineXMLnested [msqrt] {\directsetup{mmp:msqrt:start}} {\directsetup{mmp:msqrt:stop}} \defineXMLnested [mroot] {\directsetup{mmp:mroot:start}} {\directsetup{mmp:mroot:stop}} \startsetups mmp:msqrt:start \begingroup \startsavingXMLelements \stopsetups \startsetups mmp:msqrt:stop \stopsavingXMLelements \sqrt{\flushXMLstackfrom\plusone} \endgroup \stopsetups \startsetups mmp:mroot:start \begingroup \startsavingXMLelements \stopsetups \startsetups mmp:mroot:stop \stopsavingXMLelements \root{\getXMLstackdata\plustwo}\of{\getXMLstackdata\plusone} \endgroup \stopsetups \setupMMLappearance[scripts][\c!alternative=\v!a] \defineXMLnested [msub] {\directsetup{mmp:msub:start}} {\directsetup{mmp:msub:stop}} \defineXMLnested [msup] {\directsetup{mmp:msup:start}} {\directsetup{mmp:msup:stop}} \defineXMLnested [msubsup] {\directsetup{mmp:msbp:start}} {\directsetup{mmp:msbp:stop}} \startsetups mmp:msub:start \begingroup \startsavingXMLelements \stopsetups \startsetups mmp:msub:stop \stopsavingXMLelements \doifelse\@@MMLscriptsalternative\v!a { {\getXMLstackdata\plusone}_{\getXMLstackdata\plustwo} } { \getXMLstackdata\plusone_{\getXMLstackdata\plustwo} } \endgroup \stopsetups \startsetups mmp:msup:start \begingroup \startsavingXMLelements \stopsetups \startsetups mmp:msup:stop \stopsavingXMLelements \doifelse\@@MMLscriptsalternative\v!a { {\getXMLstackdata\plusone}^{\getXMLstackdata\plustwo} } { \getXMLstackdata\plusone^{\getXMLstackdata\plustwo} } \endgroup \stopsetups \startsetups mmp:msbp:start \begingroup \startsavingXMLelements \stopsetups \startsetups mmp:msbp:stop \stopsavingXMLelements \getXMLstackdata\plusone_{\getXMLstackdata\plustwo}^{\getXMLstackdata\plusthree} \endgroup \stopsetups \defineXMLnested [mover] {\directsetup{mmp:mover:start}} {\directsetup{mmp:mover:stop}} \defineXMLnested [munder] {\directsetup{mmp:munder:start}} {\directsetup{mmp:munder:stop}} \defineXMLnested [munderover] {\directsetup{mmp:munderover:start}} {\directsetup{mmp:munderover:stop}} \startsetups mmp:mover:start \begingroup \startsavingXMLelements \stopsetups \startsetups mmp:mover:stop \stopsavingXMLelements \mathop{\vbox{\mathsurround\zeropoint\ialign{\hss##\hss\crcr\noalign{\kern3\points}% \disabledelimiter\doMMLfiller{\getXMLstackdata\plustwo} \crcr\noalign{\kern3\points\nointerlineskip}% \disabledelimiter\doMMLfiller{\getXMLstackdata\plusone} \crcr}}} \limits \endgroup \stopsetups \startsetups mmp:munder:start \begingroup \startsavingXMLelements \stopsetups \startsetups mmp:munder:stop \stopsavingXMLelements \mathop{\vtop{\mathsurround\zeropoint\ialign{\hss##\hss\crcr \disabledelimiter\doMMLfiller{\getXMLstackdata\plusone} \crcr\noalign{\kern3\points\nointerlineskip}% \disabledelimiter\doMMLfiller{\getXMLstackdata\plustwo} \crcr\noalign{\kern3\points}}}} \limits \endgroup \stopsetups \startsetups mmp:munderover:start \begingroup \startsavingXMLelements \stopsetups \startsetups mmp:munderover:stop \stopsavingXMLelements \getXMLstackdata\plusone _{\disablefiller\disabledelimiter\getXMLstackdata\plustwo} ^{\disablefiller\disabledelimiter\getXMLstackdata\plusthree} \endgroup \stopsetups \def\doMMLfiller#1% bugged {\pushmacro\doMMLfiller \let\doMMLfiller\gobbleoneargument \gdef\dodoMMLfiller{\disablefiller\mathematics{#1}}% \hbox {\def\normalorfiller##1##2% {\gdef\dodoMMLfiller{\enablefiller#1}% \let\normalorfiller\gobbletwoarguments}% $#1$}% \popmacro\doMMLfiller \dodoMMLfiller} % tables % obsolete: \setupMMLappearance[mtable][\c!alternative=\v!a] \mapXMLvalue {mmp:mtable} {align:left} {right} \mapXMLvalue {mmp:mtable} {align:right} {left} \mapXMLvalue {mmp:mtable} {align:center} {middle} \mapXMLvalue {mmp:mtable} {frame:none} {off} \mapXMLvalue {mmp:mtable} {frame:solid} {on} \mapXMLvalue {mmp:mtable} {frame:on} {on} \defineXMLnested [mtable] [columnalign=, columnspacing=.25ex, rowspacing=.25ex, frame=, color=, background=] {\directsetup{mmp:mtable:start}} {\directsetup{mmp:mtable:stop}} \defineXMLnestedargument [mtr] {\MMPmtableHANDLEtr} \defineXMLnestedargument [mlabeledtr] {\MMPmtableHANDLEtr} \defineXMLnestedargument [mtd] [columnalign=, columnspacing=.25ex, rowspacing=.25ex, frame=, color=, background=] {\MMPmtableHANDLEtd} \startsetups mmp:mtable:start \vcenter \bgroup \MMLpTABLEsplitter{background} \c!backgroundcolor \MMLpTABLEsplitter{color} \c!color \MMLpTABLEmapper {frame} \c!frame \MMLpTABLEmapper {columnalign}\c!align \setMMLpunit{\XMLpar{mtable}{rowspacing}\empty}{.25ex} \let\MMLpTABLEoffset\MMLpunit \bTABLE[\c!frame=\v!off,\c!background=\v!color,\c!offset=\MMLpTABLEoffset] \stopsetups \startsetups mmp:mtable:stop \eTABLE \egroup \stopsetups \long\def\MMPmtableHANDLEtr#1{% \bTR\ignorespaces#1\removeunwantedspaces\eTR } \long\def\MMPmtableHANDLEtd#1{% \let\theMMLpTABLEmap\empty \MMLpTABLEmap{background} \c!backgroundcolor \MMLpTABLEmap{color} \c!color \MMLpTABLEmap{frame} \c!frame \MMLpTABLEmap{columnalign}\c!align \expanded{\bTD[\theMMLpTABLEmap]}% $\ignorespaces#1\removeunwantedspaces$\eTD } \def\MMLpTABLEmapper#1#2% {\doifXMLparelse{mtable}{#1} {\newcounter\MMLcounter \def\docommand##1% {\increment\MMLcounter \expanded{\setupTABLE[column][\MMLcounter][#2=\XMLval{mmp:mtable}{#2:##1}\empty]}}% \expanded{\processseparatedlist[\XMLpar{mtable}{#1}\empty]}[ ]\docommand} {}} \def\MMLpTABLEsplitter#1#2% {\doifXMLparelse{mtable}{#1} {\newcounter\MMLcounter \def\docommand##1% {\increment\MMLcounter \expanded{\setupTABLE[column][\MMLcounter][#2=##1]}}% \expanded{\processseparatedlist[\XMLpar{mtable}{#1}\empty]}[ ]\docommand} {}} \def\MMLpTABLEmap#1#2% {\doifXMLparelse{mtd}{#1} {\edef\theMMLpTABLEmap{#2=\XMLval{mmp:mtable}{#2:\XMLpar{mtd}{#1}\empty}\empty,\theMMLpTABLEmap}} {}} \defineXMLsingular [mspace] [width=.5em] {\directsetup{mmp:mspace}} \startsetups mmp:mspace \setMMLpunit{\XMLpar{mspace}{width}{}}{.5em} \hskip\MMLpunit\relax \stopsetups \def\setMMLpunit#1#2% i've forgotten what this means {\setbox\scratchbox=\hbox {\edef\ascii{#1}% \@EA\aftersplitstring\ascii\at.\to\ascii \scratchcounter=\ifx\ascii\empty#1\else\ascii\fi \unskip\unskip}% \ifdim\wd\scratchbox=\zeropoint \edef\MMLpunit{#1em}% \else \edefconvertedargument\ascii{#1}% \convertasciiafter\doifinstringelse{em}{\ascii}{\edef\MMLpunit{#1}}{% \convertasciiafter\doifinstringelse{ex}{\ascii}{\edef\MMLpunit{#1}}{% \convertasciiafter\doifinstringelse{pt}{\ascii}{\edef\MMLpunit{#1}}{% \edef\MMLpunit{#2}}}}% \fi} % end of tables \def\setMMLpunit#1#2% {\setbox\scratchbox=\hbox {\edef\ascii{#1}% \@EA\aftersplitstring\ascii\at.\to\ascii \scratchcounter=\ifx\ascii\empty#1\else\ascii\fi \unskip\unskip}% \ifdim\wd\scratchbox=\zeropoint \edef\MMLpunit{#1em}% \else \edefconvertedargument\ascii{#1}% \convertasciiafter\doifinstringelse{em}{\ascii}{\edef\MMLpunit{#1}}{% \convertasciiafter\doifinstringelse{ex}{\ascii}{\edef\MMLpunit{#1}}{% \convertasciiafter\doifinstringelse{pt}{\ascii}{\edef\MMLpunit{#1}}{% \edef\MMLpunit{#2}}}}% \fi} \defineXMLsingular [mspace] [width=.5em] {\directsetup{mmp:mspace}} \startsetups mmp:mspace \setMMLpunit{\XMLpar{mspace}{width}{}}{.5em} \hskip\MMLpunit \stopsetups \defineXMLsingular [mglyph] [fontfamily=,index=1,alt=] {\directsetup{mmp:mglyph}} \startsetups mmp:mglyph \def\MMLpglyph{\XMLpar{mglyph}{fontfamily}{}}% \doifelsenothing{\MMLpglyph} { \hbox{\tttf[fontfamily unspecified]} } { \doifdefinedelse{\MMLpglyph} { \hbox{\getvalue{\MMLpglyph}\char0\XMLpar{mglyph}{index}{1}} } { \doifelsenothing{\XMLpar{mglyph}{alt}{}} { \hbox{\tttf[unknown fontfamily \XMLpar{mglyph}{fontfamily}{}]} } { \hbox{\tttf\XMLpar{mglyph}{alt}{}} } } } \stopsetups \defineXMLsingular [malignmark] {} \defineXMLsingular [none] {} \defineXMLsingular [mprescripts] {} \defineXMLnested [mmultiscripts] {\setups{mmp:mmultiscripts:start}} {\setups{mmp:mmultiscripts:stop}} \startsetups mmp:mmultiscripts:start \begingroup \startsavingXMLelements \stopsetups \startsetups mmp:mmultiscripts:stop \stopsavingXMLelements \donefalse \scratchcounter\zerocount \dorecurse\XMLstacklevel { % watch the extra {}'s \ifdone \ifodd\scratchcounter _{\getXMLstackdata\recurselevel} \else ^{\getXMLstackdata\recurselevel}{} \fi \else \doif{\getXMLstackname\recurselevel}{mprescripts}{\donetrue{}} \fi \ifdone \advance\scratchcounter\plusone \fi } \donetrue \scratchcounter\zerocount \dorecurse\XMLstacklevel { \ifdone % watch the extra {}'s \ifcase\scratchcounter \getXMLstackdata\recurselevel \else\ifodd\scratchcounter _{\getXMLstackdata\recurselevel} \else ^{\getXMLstackdata\recurselevel}{} \fi\fi \fi \doif{\getXMLstackname\recurselevel}{mprescripts}{\donefalse} \ifdone \advance\scratchcounter\plusone \fi } \endgroup \stopsetups % experimental patches \startmoduletestsection \let\MMLdoL\donothing \let\MMLdoR\donothing \startsetups mmc:apply:start \begingroup \startsavingXMLelements \stopsetups \startsetups mmc:apply:stop \stopsavingXMLelements \MMLmathinner { \expanded{\doifinsetelse{\getXMLstackname\plusone}{\MMLcmainresetlist,\MMLctempresetlist}} \MMLcreset \donothing \ifcase\MMLapplydepth \else \doifXMLparelse{apply}{open} \donothing{\getXMLarguments{apply}{open="("}}% slow \doifXMLparelse{apply}{close}\donothing{\getXMLarguments{apply}{close=")"}}% slow \fi \advance\MMLapplydepth\plusone \begingroup \doifXMLparelse{apply}{open} % now inside the group {\edef\MMLdoL{\noexpand\left \XMLpar{apply}{open} {(}} \edef\MMLdoR{\noexpand\right\XMLpar{apply}{close}{)}}} {\let\MMLdoL\donothing \let\MMLdoR\donothing} \let\MMLctempresetlist\empty \doifelse {\getXMLstackname\plusone} {apply} { % ... .. \doifelseMMCfunctioninapply \plusone {plus,minus} { % [a] % yet incomplete and rather untested % x } { % [b] \MMLcreset } \MMLdoL \getXMLstackdata\plusone \ifconditional\somepostponedMMLactions \postponedMMLactions \else \left(\MMLcreset\getXMLstackdata\plustwo\right) \fi \MMLdoR } { \doifelse {\getXMLstackname\plusone} {fn} { % [c] % \MMLdoL/R are to be taken care of in the next setup \directsetup{mmc:fn:apply} } { \doifelse {\getXMLstackname\plusone} {csymbol} { % \MMLdoL/R are to be taken care of in the next setup % [d] \directsetup{mmc:csymbol:apply} } { \doifelse {\getXMLstackname\plusone} {ci} { % [e] % \MMLdoL/R are to be taken care of in the next setup \directsetup{mmc:ci:apply} } { % [f] \MMLdoL \getXMLstackdata\plusone \MMLdoR } } } } \endgroup \advance\MMLapplydepth\minusone \directsetup{apply:flush} } \endgroup \stopsetups \startsetups mmc:fn:apply \begingroup \startsavingXMLelements \rawXMLstacktext\plusone % still on stack, no check, just fn content \stopsavingXMLelements \doifelse {\getXMLstackname\plusone} {ci} { \flattenXMLcontent{\getXMLstackdata\plusone} \doifsetupselse{mmc:fn:\flattenedXMLcontent} { % \MMLdoL/MMLdoR to be handled in plugin \global\defXMLstackdata\XMLfnoperator\plusone \expanded{\endgroup\noexpand\directsetup{mmc:fn:\flattenedXMLcontent}} } { \endgroup \MMLcreset \MMLdoL \getXMLstackdata\plusone \ifnum\XMLstacklevel>\plusone \getXMLentity{NegThinSpace} \left(\MMLcreset\flushXMLstackwith\plustwo{\MMLseparator,}\right) \fi \MMLdoR } } { \endgroup \MMLcreset \MMLdoL \getXMLstackdata\plusone \MMLdoR } \stopsetups \startsetups mmc:csymbol:apply \begingroup \defineXMLsave[csymbol][definitionURL=,encoding=] \rawXMLstackdata\plusone % was text % still on stack, no check, just attr test % \MMLdoL/MMLdoR to be handled in plugin \lowercasestring\XMLpar{csymbol}{definitionURL}{}\to\mmcSymbolURL \doifsetupselse{mmc:csymbol:\mmcSymbolURL} { \expanded{\endgroup\noexpand\directsetup{mmc:csymbol:\mmcSymbolURL}} } { \endgroup %\XMLval{mmc:cs}{\XMLop{encoding}}{\firstofoneargument}% fails when no content \XMLval{mmc:cs}{\XMLop{encoding}}{} } \stopsetups \defineXMLsingular [csymbol] [encoding=text, definitionURL=] {\directsetup{mmc:csymbol:apply:singular}} \startsetups mmc:csymbol:apply:singular \lowercasestring\XMLpar{csymbol}{definitionURL}{}\to\mmcSymbolURL \directsetup{mmc:csymbol:\mmcSymbolURL} \stopsetups \startsetups mmc:ci:apply \getXMLstackdata\plusone \ifnum\XMLstacklevel>\plusone \left(\MMLcreset\flushXMLstackwith\plustwo{\MMLseparator,}\right) \fi \stopsetups \def\xflushXMLstackwith#1#2#3#4% num bgroup egroup whatever {\dostepwiserecurse{#1}\XMLstacklevel\plusone {#2\relax \ifnum\recurselevel>#1\relax#4\fi \getXMLstackdata\recurselevel #3}} \def\xflushXMLstackfrom#1#2#3% {\dostepwiserecurse{#1}\XMLstacklevel\plusone {#2\getXMLstackdata\recurselevel#3}} % % % b % b % a % % % bb % b % a % % \startsetups mmc:minus \doif \@@MMLsignreduction \v!yes { \setMMLcreset{fn,\MMLcfunctionlist} } \ifcase\XMLstacklevel \or % self \or -\getXMLstackdata\plustwo \else \dostepwiserecurse\plustwo\XMLstacklevel\plusone { \begingroup \doifelse {\getXMLstackname\recurselevel} {apply} { \ifnum\recurselevel=\plustwo \begingroup \dodoifelseMMCfunctioninapply \recurselevel {minus} { \ifnum\XMLstacklevel>\plustwo \endgroup \else \endgroup \MMLcreset \fi } { \endgroup } \else \doifelseMMCfunctioninapply \recurselevel {\MMLcfunctionlist,\MMLcconstructlist} { \MMLcreset } { } \fi } { } \getXMLstackdata\recurselevel \ifnum\recurselevel<\XMLstacklevel\relax - \fi \endgroup } \fi \stopsetups \stopmoduletestsection \stopmodule \protect \endinput