summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/x-mmc.mkiv
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/context/base/x-mmc.mkiv')
-rw-r--r--Master/texmf-dist/tex/context/base/x-mmc.mkiv2201
1 files changed, 2201 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/context/base/x-mmc.mkiv b/Master/texmf-dist/tex/context/base/x-mmc.mkiv
new file mode 100644
index 00000000000..042ef340652
--- /dev/null
+++ b/Master/texmf-dist/tex/context/base/x-mmc.mkiv
@@ -0,0 +1,2201 @@
+%D \module
+%D [ file=x-newmml,
+%D version=2005.06.10, % 1999.12.20,
+%D title=\CONTEXT\ XML Modules,
+%D subtitle=MathML Renderer,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% todo: more consistent both pi's and attributes to apply
+
+\doifnotmode {atpragma} {\endinput}
+
+% \xmlfilter{#1}{/*/name()} -> \xmltag
+
+\xmlresolveentities
+
+\startluacode
+ function math.register_xml_entities()
+ local entities, char = xml.entities, utf.char
+ for name, unicode in pairs(math.entities) do
+ if not entities[name] then
+ entities[name] = char(unicode)
+ end
+ end
+ end
+ math.register_xml_entities()
+
+ -- not yet needed, we have class info in char-def already
+ --
+ -- characters.data[0x2190].activemath = "mathleftarrow"
+ -- characters.data[0x2190].activemath = "mathuparrow"
+ -- characters.data[0x2192].activemath = "mathrightarrow"
+ -- characters.data[0x2193].activemath = "mathdownarrow"
+ --
+ -- function characters.activate(catcodes)
+ -- local char, sprint, format = utf.char, tex.sprint, string.format
+ -- for k,v in pairs(characters.data) do
+ -- local a = v.activemath
+ -- if a then -- how fast is this?
+ -- sprint(format("\\letcatcodecommand %s %s \\%s",catcodes,k,a))
+ -- end
+ -- end
+ -- end
+ --
+ -- better do this the official way, i.e. defineactivecharacter since it
+ -- permits different meanings for different catcode tables (todo)
+ --
+ -- characters.activate(tex.ctxcatcodes)
+ -- characters.activate(tex.notcatcodes)
+\stopluacode
+
+% \def\mathrightarrow{\normalorfiller\rightarrow\rightarrowfill}
+% \def\mathleftarrow {\normalorfiller\leftarrow \leftarrowfill}
+% \def\mathdownarrow {\mathortext \downarrow \empty}
+% \def\mathuparrow {\mathortext \uparrow \empty}
+
+% \def\mathunderbrace{\normalorfiller\empty\upbracefill}
+% \def\mathoverbrace {\normalorfiller\empty\downbracefill}
+% \def\mathunderbar {\normalorfiller\hrule\hrulefill}
+% \def\mathoverbar {\normalorfiller\hrule\hrulefill}
+% \def\mathhat {\normalorfiller\empty\empty} % todo
+
+%D Remark: from now on this is a module and no longer an xtag
+%D filter. There is an intermediate cleaner module but it has
+%D some namespace limitations. Here we do it the \MKV\ way.
+
+\unprotect
+
+\def\widevec#1%
+ {\vbox{\m@th\ialign{##\crcr
+ \rightarrowfill\crcr\noalign{\nointerlineskip}%
+ $\hfil\displaystyle{#1}\hfil$\crcr}}}
+
+\protect
+
+\ifx\inlinemathematics\undefined
+ \def\inlinemathematics {\dontleavehmode\mathematics} % already in kernel
+ \long\def\inlinemath #1{\dontleavehmode\relax\ifmmode#1\else $#1$\fi}
+\fi
+
+%D Then we start defining the rendering macros:
+
+\writestatus{loading}{Context XML Macros (MathML Renderer)}
+
+\startmodule [mathml]
+
+\ctxlua{environment.loadlucfile("x-mathml")}
+
+\unprotect
+
+\def\MMLrm{\mr}
+
+\def\MMLseparator#1{\removeunwantedspaces{#1}\ignorespaces} % 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 teh 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 % todo
+
+\def\xmlmathmldirective#1{\dosetvalue{MML#1}}
+
+%D In the styles, options can be set with:
+
+\def\setupMMLappearance[#1]{\dodoubleargument\getparameters[MML#1]} % no @@ because passed to lua
+
+%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 Auxiliary MathML macros: (to be generalized)
+
+\def\mmlfirst #1{\xmlindex{#1}{/*}{1}} % \xmlsnippet{1}
+\def\mmlsecond #1{\xmlindex{#1}{/*}{2}} % \xmlsnippet{2}
+\def\mmlthird #1{\xmlindex{#1}{/*}{3}} % \xmlsnippet{3}
+\def\mmlprelast#1{\xmlindex{#1}{/*}{-2}} %
+\def\mmllast #1{\xmlin{#1}{/*}{-1}} %
+
+\starttexdefinition doifelsemmlfunction #1
+ \xmldoifelse {#1} {/mml:fn} {
+ \firstoftwoarguments
+ } {
+ \xmldoifelse {#1} {/mml:apply/mml:fn} {
+ \firstoftwoarguments
+ } {
+ \xmldoifelse {#1} {/mml:ci[@type=='fn']} {
+ \firstoftwoarguments
+ } {
+ \secondoftwoarguments
+ }
+ }
+ }
+\stoptexdefinition
+
+%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:
+
+\convertargument
+ mml:times|mml:divide|mml:power|%
+ mml:lt|mml:gt|mml:eq|mml:leq|mml:geq|%
+ mml:in|mml:inverse|%
+ mml:fn|%
+ mml:floor|mml:ceiling|%
+ mml:mean|%
+ mml:selector|%
+ mml:abs|mml:int|mml:limit|mml:sum|mml:product|%
+ mml:outerproduct|mml:innerproduct|mml:scalarproduct%
+\to \MMLcmainresetlist
+
+\convertargument
+ mml:sin|mml:arcsin|mml:sinh|mml:arcsinh|%
+ mml:cos|mml:arccos|mml:cosh|mml:arccosh|%
+ mml:tan|mml:arctan|mml:tanh|mml:arctanh|%
+ mml:cot|mml:arccot|mml:coth|mml:arccoth|%
+ mml:csc|mml:arccsc|mml:csch|mml:arccsch|%
+ mml:sec|mml:arcsec|mml:sech|mml:arcsech|%
+ mml:ln|mml:exp|mml:log|%
+ mml:abs|mml:int|mml:limit|mml:sum|mml:product|%
+ mml:fn%
+\to \MMLcfunctionlist
+
+\convertargument
+ mml:sin|mml:arcsin|mml:sinh|mml:arcsinh|%
+ mml:cos|mml:arccos|mml:cosh|mml:arccosh|%
+ mml:tan|mml:arctan|mml:tanh|mml:arctanh|%
+ mml:cot|mml:arccot|mml:coth|mml:arccoth|%
+ mml:csc|mml:arccsc|mml:csch|mml:arccsch|%
+ mml:sec|mml:arcsec|mml:sech|mml:arcsech|%
+ mml:ln|mml:exp|mml:log|%
+ mml:abs%
+\to \MMLcpurefunctionlist
+
+\convertargument
+ mml:diff|mml:partialdiff|mml:root%
+\to \MMLcconstructlist
+
+%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 <apply> <.../> ...
+%D <apply> <fn> ...
+%D <apply> <apply> <ci> ...
+%D <apply> <apply> <fn> <ci> ...
+%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.
+
+% simple version
+
+\newcount\@MMLlevel \def\MMLcreset{\@MMLlevel\zerocount}
+
+\let\MMLctempresetlist\empty \def\setMMLcreset{\edef\MMLctempresetlist}
+
+\let\MMLdoL\donothing
+\let\MMLdoR\donothing
+
+\newcount\mmlapplydepth \def\MMLcreset{\mmlapplydepth\zerocount}
+
+\startxmlsetups mml:apply
+ \MMLmathinner {
+ \xmldoif {#1} {/(\MMLcmainresetlist\string|\MMLctempresetlist)} {
+ % \MMLcreset
+ }
+ \edef\mmlapplyopentoken {\xmlatt{#1}{open}}
+ \edef\mmlapplyclosetoken{\xmlatt{#1}{close}}
+ \ifcase\mmlapplydepth \else
+ \ifx\mmlapplyopentoken\empty
+ \def\mmlapplyopentoken {(}
+ \def\mmlapplyclosetoken{)}
+ \fi
+ \fi
+ \advance\mmlapplydepth\plusone
+ \begingroup
+ \ifx\mmlapplyopentoken\empty
+ \let\MMLdoL\donothing
+ \let\MMLdoR\donothing
+ \else
+ \edef\MMLdoL{\noexpand\left \mmlapplyopentoken }
+ \edef\MMLdoR{\noexpand\right\mmlapplyclosetoken}
+ \fi
+ \let\MMLctempresetlist\empty
+ \xmldoifelse {#1} {/mml:apply} {
+% % <apply> <apply> ... </apply> <ci> .. </ci> </apply>
+% \xmldoifelse {#1} {/mml:apply(mml:plus|mml:minus)} {% [a]
+% % yet incomplete and rather untested
+% % <apply> <apply> <minus/> <tan/> <cos/> </apply> <ci>x</ci> </apply>
+ } {% [b]
+% \MMLcreset
+ }
+% \MMLdoL
+% \xmlfirst{#1}{/*}
+% \ifconditional\somepostponedMMLactions
+% \postponedMMLactions
+% \else
+% \left(\MMLcreset\mmlsecond{#1}\right)
+% \fi
+% \MMLdoR
+% } {
+ \edef\mmlapplyaction{\xmlfilter{#1}{/*/name()}}
+ \doifsetupselse {mml:apply:\mmlapplyaction} {
+ \xmlsetup{#1}{mml:apply:\mmlapplyaction}
+ } {
+% \MMLdoL
+ \xmlsetup{#1}{\xmlfilter{#1}{/*/name()}}
+% \MMLdoR
+ }
+% }
+ \endgroup
+ \advance\mmlapplydepth\minusone
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:apply:mml:apply
+ \xmlflush{#1}
+ \xmlall{#1}{../[position()>1]}
+\stopxmlsetups
+\startxmlsetups mml:apply:mml:fn
+ \hbox{todo}% obsolete
+\stopxmlsetups
+\startxmlsetups mml:apply:mml:csymbol
+ \hbox{todo}
+\stopxmlsetups
+
+ % \startsetups mmc:fn:apply
+ % \begingroup
+ % \rawXMLstacktext\plusone % still on stack, no check, just fn content
+ % \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
+
+
+\startxmlsetups mml:apply:mml:ci
+ \xmlfirst{#1}{/mml:ci}
+ \ifnum\xmlcount{#1}{/*}>\plusone
+ \left(\MMLcreset\xmlconcatrange{#1}{/*}{2}{}{\MMLseparator,}\right)
+ \fi
+\stopxmlsetups
+
+% reln
+
+\startxmlsetups mml:reln
+ \writestatus{XML}{MathML element "reln" is obsolete}
+\stopxmlsetups
+
+% 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
+ \rawXMLstacktext\plusone % still on stack, no check, just fn content
+ \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
+ \stopsetups
+
+ \startsetups mmc:fn:stop
+ \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} {
+ \xmldoifelse {#1} {/(mml:plus\string|mml:minus)} {
+ \left(
+ \getXMLstackdata\plusone
+ \right)
+ } {
+ \getXMLstackdata\plusone
+ }
+ \endgroup
+ \ifnum\XMLstacklevel>\plusone
+ \left(
+ \getXMLstackdata\plustwo
+ \right)
+ \fi
+ } {
+ \MMLcreset
+ \getXMLentity{NegThinSpace}
+ \MMCfnleft
+ \ifnum\XMLstacklevel=\plustwo,\fi
+ \flushXMLstackwith\plustwo,
+ \MMCfnright
+ \endgroup
+ }
+ }
+ \stopsetups
+
+%D The next definition provide a kind of plug-in mechanism (see
+%D the open math extension module).
+
+% http://www.publishers.com/somename
+
+\starttexdefinition mmlapplycsymbol #1#2#3#4
+ % #1=full url, #2=name, #3=encoding, #4=text
+ \doifelse {#3} {text} {
+ {\mr #4}
+ } {
+ \doifsetupselse {mml:csymbol:#1} {
+ % full url
+ \directsetup{mml:csymbol:#1}
+ } {
+ % somename (fallback)
+ \doifsetupselse {mmc:csymbol:#2} {
+ \directsetup{mml:csymbol:#2}
+ } {
+ \XMLval{mmc:cs}{#3}{}% todo
+ }
+ }
+ }
+\stoptexdefinition
+
+\startxmlsetups mml:csymbol
+ \ctxlua{lxml.mml.csymbol("#1")}
+\stopxmlsetups
+
+% \startxmlsetups mml:csymbol:<url> \stopxmlsetups
+
+%D Alternative b will convert periods into comma's:
+%D
+%D \startbuffer
+%D \startXMLdata
+%D <imath><apply><cn>1.23</cn></apply></imath>
+%D <dmath><apply><cn>1.23</cn></apply></dmath>
+%D \stopXMLdata
+%D
+%D \type{\setupMMLappearance[cn] [alternative=b]}
+%D
+%D \startXMLdata
+%D <imath><apply><cn>1.23</cn></apply></imath>
+%D <dmath><apply><cn>1.23</cn></apply></dmath>
+%D \stopXMLdata
+%D \stopbuffer
+%D
+%D \start \typebuffer \getbuffer \stop
+
+\setupMMLappearance[cn] [\c!alternative=\v!a]
+\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
+
+\startxmlsetups mml:cs \xmlcommand{#1}{/}{mml:cs:\xmlattdef{#1}{type}{default}} \stopxmlsetups
+\startxmlsetups mml:ci \xmlcommand{#1}{/}{mml:ci:\xmlattdef{#1}{type}{default}} \stopxmlsetups
+\startxmlsetups mml:cn \xmlcommand{#1}{/}{mml:cn:\xmlattdef{#1}{type}{default}} \stopxmlsetups
+
+% helpers cn
+
+\startxmlsetups mml:cn:default
+ \mathopnolimits{\xmlflush{#1}}
+\stopxmlsetups
+
+% helpers ci
+
+\startxmlsetups mml:ci:default
+ \xmlflush{#1}
+\stopxmlsetups
+
+\startxmlsetups mml:ci:set
+ {\bbd\xmlflush{#1}}
+\stopxmlsetups
+
+\startxmlsetups mml:ci:vector
+ \widevec{\xmlflush{#1}}
+\stopxmlsetups
+
+\startxmlsetups mml:ci:matrix
+ {\bi\xmlflush{#1}}
+\stopxmlsetups
+
+\startxmlsetups mml:ci:function
+ \xmlflush{#1}\negthinspace
+\stopxmlsetups
+
+\startxmlsetups mml:ci:fn
+ \xmlsetup{#1}{mml:ci:function}
+\stopxmlsetups
+
+\startxmlsetups mml:ci:complex-cartesian
+ \xmlsetup{#1}{mml:cn:complex}
+\stopxmlsetups
+
+\startxmlsetups mml:ci:complex
+ \xmlsetup{#1}{mml:cn:complex}
+\stopxmlsetups
+
+\startxmlsetups mml:ci:complex-polar
+ \xmlsetup{#1}{mml:cn:polar}
+\stopxmlsetups
+
+\startxmlsetups mml:ci:polar
+ \xmlsetup{#1}{mml:cn:polar}
+\stopxmlsetups
+
+% \doif\MMLcnalternative\v!b{\redefinemathcharacter [.][ord][mi]["3B]\relax}%
+%
+% todo: number function from mmp
+
+% helpers ci
+
+\startxmlsetups mml:cn:default
+ \xmlflush{#1}
+\stopxmlsetups
+
+\startxmlsetups mml:cn:integer
+ \edef\mmlintegerbase{\xmlattdef{#1}{base}{}}
+ \ifx\mmlintegerbase\empty
+ \xmlflush{#1}
+ \else
+ \doifelse \MMLbasesymbol \v!no {
+ \MMLcCNbasedata{\xmlflush{#1}}
+ } {
+ \MMLcCNbasedata{\xmlflush{#1}}_{
+ \hbox {$
+ \mr
+ \scriptscriptstyle
+ \processaction
+ [\MMLbasesymbol]
+ [\v!characters=>\MMLcCNbasestring BODH,
+ \v!text=>\MMLcCNbasestring{BIN}{OCT}{DEC}{HEX},
+ \s!unknown=>\mmlintegerbase]
+ $}
+ }
+ }
+ \fi
+\stopxmlsetups
+
+\def\MMLcCNbasedata#1%
+ {\ifnum\mmlintegerbase>10 \relax{\mr#1}\else#1\fi}
+
+\def\MMLcCNbasestring#1#2#3#4%
+ {\ifnum\mmlintegerbase= 2 #1\else
+ \ifnum\mmlintegerbase= 8 #2\else
+ \ifnum\mmlintegerbase=10 #3\else
+ \ifnum\mmlintegerbase=16 #4\else
+ \mmlintegerbase \fi\fi\fi\fi}
+
+\startxmlsetups mml:cn:polar
+ \xmlsetup{#1}{mml:cn:polar:\MMLpolaralternative}
+\stopxmlsetups
+
+\startxmlsetups mml:cn:polar:a
+ \mathopnolimits{Polar}% ? ? ?
+ \left(\xmlsnippet{#1}{1},\xmlsnippet{#1}{1}\right)
+\stopxmlsetups
+
+\startxmlsetups mml:cn:polar:b
+% {\mr e}^{\xmlsnippet{#1}{1}\mskip2mu\getXMLentity{imaginaryi}}
+ {\mr e}^{\xmlsnippet{#1}{1}+\xmlsnippet{#1}{3}{\mr i}}
+\stopxmlsetups
+
+\startxmlsetups mml:cn:polar:c
+% \exp\left(\xmlsnippet{#1}{1}\mskip2mu\getXMLentity{imaginaryi}\right)}
+ \exp\left(\xmlsnippet{#1}{1}+\xmlsnippet{#1}{3}\mskip2mu\getXMLentity{imaginaryi}\right)
+\stopxmlsetups
+
+\startxmlsetups mml:cn:complex-polar
+ \xmlsetup{#1}{mml:cn:polar}
+\stopxmlsetups
+
+\startxmlsetups mml:cn:complex
+ \xmlsnippet{#1}{1} + \xmlsnippet{#1}{3}{\mr i}
+\stopxmlsetups
+
+\startxmlsetups mml:cn:complex-cartesian
+ \xmlsetup{#1}{mml:cn:complex}
+\stopxmlsetups
+
+\startxmlsetups mml:cn:float
+ \doifelse \MMLfloatsymbol \v!no {
+ % make sure that e shows up ok
+ \mathopnolimits{\xmlflush{#1}}
+ } {
+ % we should ignore \entities !
+ \edef\mmlfloatstring{\xmlflush{#1}}
+ \splitstring\mmlfloatstring\at e\to\first\and\last
+ \ifx\first\empty
+ \mmlfloatstring
+ \else\ifx\last\empty
+ \mmlfloatstring
+ \else
+ \first
+ \doifelse \MMLfloatsymbol {dot} \cdot \times
+ 10^{\last}
+ \fi \fi
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:cn:real
+ \xmlsetup{#1}{mml:cn:float}
+\stopxmlsetups
+
+\startxmlsetups mml:cn:e-notation
+ \doifelse \MMLenotationsymbol \v!no {
+ \xmlsnippet{#1}{1}
+ \unskip\mathopnolimits{e}\ignorespaces
+ \xmlsnippet{#1}{3}
+ } {
+ \xmlsnippet{#1}{1}
+ \doifelse \MMLenotationsymbol {dot} \cdot
+ \times10^{\xmlsnippet{#1}{3}}
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:cn:logical
+ \mathopnolimits{\xmlflush{#1}}
+\stopxmlsetups
+
+\startxmlsetups mml:cn:rational
+ \xmldoifelse {#1} {/mml:sep} {
+ \frac
+ {\xmlsnippet{#1}{1}}
+ {\xmlsnippet{#1}{3}}
+ } {
+ \xmlflush{#1}
+ }
+\stopxmlsetups
+
+% interval
+
+\setupMMLappearance[interval][\c!alternative=\v!a,\c!separator={,}]
+
+\startxmlsetups mml:interval
+ \xmlsetup{#1}{mml:interval:\xmlattdef{#1}{closure}{closed}}
+\stopxmlsetups
+
+\startxmlsetups mml:interval:closed
+ \left[\mmlfirst{#1}\MMLseparator\MMLintervalseparator\mmlsecond{#1}\right]
+\stopxmlsetups
+
+\startxmlsetups mml:interval:open-closed
+ \doifelse \MMLintervalalternative \v!b {
+ \left<\mmlfirst{#1}\MMLseparator\MMLintervalseparator\mmlsecond{#1}\right]
+ } {
+ \left(\mmlfirst{#1}\MMLseparator\MMLintervalseparator\mmlsecond{#1}\right]
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:interval:closed-open
+ \doifelse \MMLintervalalternative \v!b {
+ \left[\mmlfirst{#1}\MMLseparator\MMLintervalseparator\mmlsecond{#1}\right>
+ } {
+ \left[\mmlfirst{#1}\MMLseparator\MMLintervalseparator\mmlsecond{#1}\right)
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:interval:open
+ \doifelse \MMLintervalalternative \v!b {
+ \left<\mmlfirst{#1}\MMLseparator\MMLintervalseparator\mmlsecond{#1}\right>
+ } {
+ \left(\mmlfirst{#1}\MMLseparator\MMLintervalseparator\mmlsecond{#1}\right)
+ }
+\stopxmlsetups
+
+% inverse
+
+% \startxmlsetups mml:inverse
+% \xmldoifelse {#1} {/(\MMLcpurefunctionlist)} {
+% \mmlsecond{#1}^{-1}
+% \xmlall{#1}{/[position()>2]}
+% } {
+% {\left[\mmlthird{#1}\right]}^{-1}
+% }
+% \stopxmlsetups
+
+\setfalse\xmlinversefunction
+
+\startxmlsetups mml:apply:inverse
+ \settrue\xmlinversefunction
+% \ctxlua{print(table.serialize(lxml.id("#1")))}
+ \xmlsetup{#1}{\xmlfilter{#1}{/mml:apply/*/name(1)}}
+\stopxmlsetups
+
+\startxmlsetups xml:mml:inverse
+ \xmlsetsetup{\xmldocument}{mml:apply/mml:apply/mml:inverse/../../..}{mml:apply:inverse}
+\stopxmlsetups
+
+\xmlregistersetup{xml:mml:inverse}
+
+% condition
+
+% maybe a fast \xmlnonfirst
+
+\startxmlsetups mml:bvar \xmlflush{#1} \stopxmlsetups
+\startxmlsetups mml:lowlimit \xmlflush{#1} \stopxmlsetups
+\startxmlsetups mml:uplimit \xmlflush{#1} \stopxmlsetups
+\startxmlsetups mml:degree \xmlflush{#1} \stopxmlsetups
+
+\startxmlsetups mml:condition
+% \xmldoif {#1} {/mml:bvar} {
+% \xmlfirst{#1}{/mml:bvar}\mid
+% }
+ \xmlall{#1}{/!(mml:condition\string|mml:bvar)}
+\stopxmlsetups
+
+% declare
+
+\setupMMLappearance[declare][\c!state=\v!start]
+
+\startxmlsetups mml:declare
+ \doif \MMLdeclarestate \v!start {
+ \mathopnolimits{declare}
+ \xmlindex{#1}{/*}{1}
+ \ifnum \xmlcount{#1}{/} > \plusone
+ \thickspace
+ \mathopnolimits{as}
+ \thickspace
+ \fi
+ \mmlsecond{#1}
+ }
+\stopxmlsetups
+
+% lambda
+
+\setupMMLappearance[lambda][\c!alternative=b]
+
+\startxmlsetups mml:lambda
+ \begingroup
+ \doifelse \MMLlambdaalternative \v!a {
+ \lambda\left(\xmlconcat{#1}{/!mml:lambda}{\MMLseparator,}\left)
+ } {
+ \ifnum \xmlcount {#1} {/mml:bvar} > \plusone
+ \left(\xmlconcat{#1}{/mml:bvar}{\MMLseparator,}\right)
+ \else
+ \xmlfirst{#1}{/mml:bvar}
+ \fi
+ \mapsto
+ \MMLcreset
+ \xmlall{#1}{/!(mml:bvar|mml:lambda)}
+ }
+ \endgroup
+\stopxmlsetups
+
+% compose
+
+\startxmlsetups mml:compose
+ \begingroup
+ \MMLcreset
+% \let\MMLcCIfunction\firstofoneargument % brrr ? ? ?
+ \doifelsemmlfunction {
+ \left(\xmlconcatrange{#1}{/*}{2}{}{\circ}\right)
+ } {
+ \xmlconcatrange{#1}{/*}{2}{}{\circ}
+ }
+ \endgroup
+\stopxmlsetups
+
+\startxmlsetups mml:image
+ \mathopnolimits{image} \left( \xmlfilter{#1}{/!mml:image/name()} \right)
+\stopxmlsetups
+
+\setupMMLappearance[piece][\c!separator=]
+
+\startxmlsetups mml:piecewise
+ \processaction
+ [\MMLpieceseparator]
+ [ \v!yes=>\def\theMMLpieceseparator{,&},
+ \v!no=>\def\theMMLpieceseparator{&},
+ \s!default=>\def\theMMLpieceseparator{&},
+ \s!unknown=>\def\theMMLpieceseparator{\,\,\hbox{\MMLpieceseparator}\,\,}]
+ \cases{\xmlflush{#1}}
+\stopxmlsetups
+
+\startxmlsetups mml:piece
+ \mmlfirst{#1}\theMMLpieceseparator\mathematics{\mmlsecond{#1}}\crcr
+\stopxmlsetups
+
+\startxmlsetups mml:otherwise
+% \xmlflush{#1}\MMLcPIECEseparator&{\mr otherwise}\crcr
+ \xmlflush{#1}&{\mr otherwise}\crcr
+\stopxmlsetups
+
+% end of piece
+
+\startxmlsetups mml:quotient
+ \lfloor\mmlsecond{#1}/\mmlthird{#1}\rfloor
+\stopxmlsetups
+
+\startxmlsetups mml:factorial
+ \xmlall{#1}{/!factorial}!
+\stopxmlsetups
+
+\setupMMLappearance [divide] [\c!level=\!!maxcard,\c!alternative=\v!a]
+
+\newcount\mmldividelevel
+
+\startxmlsetups mml:divide
+ \advance\mmldividelevel\plusone
+ \doifelse \MMLdividealternative \v!b {
+ \mmlsecond{#1}/\mmlthird{#1}
+ } {
+ \ifnum \mmldividelevel > \MMLdividelevel \relax % threshold
+ \mmlsecond{#1}/\mmlthird{#1}
+ \else
+ \MMLcreset
+ \frac{\MMLcreset\mmlsecond{#1}}{\MMLcreset\mmlthird{#1}}
+ \fi
+ }
+ \advance\mmldividelevel\minusone
+\stopxmlsetups
+
+% min max
+
+\startxmlsetups mml:min \mathopnolimits{min} \xmlsetup{#1}{mml:minmax} \stopxmlsetups
+\startxmlsetups mml:max \mathopnolimits{max} \xmlsetup{#1}{mml:minmax} \stopxmlsetups
+
+\startxmlsetups mml:minmax
+ \xmldoif {#1} {/mml:bvar} {
+ {}_{\xmlfirst{#1}{/mml:bvar}}
+ }
+ \left\{
+ \xmlconcat{#1}{/!(mml:bvar\string|mml:max\string|mml:min)}{\MMLseparator,}
+ \right\}
+\stopxmlsetups
+
+% minus plus
+
+\setupMMLappearance [plus] [\c!alternative=\v!a] % b = no sign -> 3 1/4
+\setupMMLappearance [sign] [\c!reduction=\v!yes]
+
+% alternative b -> geen sign
+
+% branch needed, else (a-b) + (c-d) goes wrong
+% reset check in case of (-x) + 37
+% reset check in case of (-x) + 37
+
+\newcount\mmlpluscounter
+
+\startxmlsetups mml:plus
+ \doifelse \MMLsignreduction \v!yes {
+ \MMLdoL
+ \xmlsetup{#1}{mml:plus:reset}
+ \xmlcommand{#1}{/!mml:plus}{mml:plus:body}
+ \MMLdoR
+ } {
+ \ifnum\xmlcount{#1}{/!mml:plus}=\plusone
+ +\xmlfirst{#1}{/!mml:plus}
+ \else
+ \MMLdoL
+ \xmlconcat{#1}{/!mml:plus}{+}
+ \MMLdoR
+ \fi
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:plus:reset
+ \mmlpluscounter\zerocount
+\stopxmlsetups
+
+\startxmlsetups mml:plus:body
+ \advance\mmlpluscounter\plusone
+ \ifnum\mmlpluscounter>\plusone
+ \xmldoifelse{#1}{/mml:minus} {
+ \ifnum\xmlcount{#1}{/!mml:minus}>\plusone
+ +
+ \fi
+ } {
+ \doifelse {\xmlatt{#1}{type}} {rational} {
+ % fraction
+ } {
+ +
+ }
+ }
+ \fi
+ \xmldirect{#1}
+\stopxmlsetups
+
+\newcount\mmlminuscounter
+
+\startsetups mml:minus
+ \doifelse \MMLsignreduction \v!yes {
+ } {
+ }
+ \ifnum\xmlcount{#1}{/!mml:minus}=\plusone
+ -\xmlfirst{#1}{/!mml:minus}
+ \else
+ \MMLdoL
+ \xmlsetup{#1}{mml:minus:reset}
+ \xmlcommand{#1}{/!mml:minus}{mml:minus:body}
+ \MMLdoR
+ \fi
+\stopsetups
+
+\startxmlsetups mml:minus:reset
+ \mmlminuscounter\zerocount
+\stopxmlsetups
+
+\startxmlsetups mml:minus:body
+ % we can slso use concat here
+ \advance\mmlminuscounter\plusone
+ \ifnum\mmlminuscounter>\plusone
+ -
+ \fi
+ \xmldirect{#1}
+\stopxmlsetups
+
+% power
+
+\setupMMLappearance[power][\c!reduction=\v!yes]
+
+\let\MMLpowerelement\empty
+
+\startxmlsetups mml:power
+ \xmldoifelse {#1} {/mml:apply} {
+ \doifelse \MMLpowerreduction \v!yes {
+ \xmldoifelse {#1} {/(\MMLcfunctionlist)} {
+ \gdef\MMLpowerelement{\mmlthird{#1}}% postpone, no xdef
+ \MMLcreset\mmlsecond{#1}
+ } {
+ \left(\MMLcreset\mmlsecond{#1}\right)^{\MMLcreset\mmlthird{#1}}
+ }
+ } {
+ \left(\MMLcreset\mmlsecond{#1}\right)^{\MMLcreset\mmlthird{#1}}
+ }
+ } {
+ \mmlsecond{#1}^{\MMLcreset\mmlthird{#1}}
+ }
+\stopxmlsetups
+
+% rem
+
+\startxmlsetups mml:rem
+ \xmlconcat{#1}{/!mml:rem}{\mathopnolimits{mod}}
+\stopxmlsetups
+
+\setupMMLappearance [times] [\c!symbol=\v!no,\c!auto=\v!yes] % new, auto catches cn cn cn
+
+\startxmlsetups mml:times
+ \setMMLcreset{\MMLcfunctionlist\string|\MMLcconstructlist}%
+ \doifelse\MMLtimesauto\v!no {
+ \let\MMLtimes@@symbol\MMLtimessymbol
+ } {
+ \xmldoifelse {#1} {/mml:cn[name(1) == 'mml:cn']} {% name(1) is next one
+ \doifinsetelse\MMLtimessymbol{\v!yes,\v!no} {
+ \let\MMLtimes@@symbol\v!yes
+ } {
+ \let\MMLtimes@@symbol\MMLtimessymbol
+ }
+ } {
+ \let\MMLtimes@@symbol\MMLtimessymbol
+ }
+ }
+ \doifelse\MMLtimes@@symbol\v!yes {
+ \xmlconcat{#1}{/!mml:times}{\times}
+ } {
+ \doifelse\MMLtimes@@symbol{dot} {
+ \xmlconcat{#1}{/!mml:times}{\cdot}
+ } {
+ \doifelse\MMLtimes@@symbol{times} {
+ \xmlconcat{#1}{/!mml:times}{\times}
+ } {
+ \xmlall{#1}{/!mml:times}
+ }
+ }
+ }
+\stopxmlsetups
+
+\setupMMLappearance[root][\c!symbol=\v!yes]
+
+\startxmlsetups mml:root
+ \xmldoifelse {#1} {/mml:degree} {
+ \root
+ \doifnot\MMLrootsymbol\v!no{\MMLcreset\xmltext{#1}{/mml:degree}}
+ \of
+ } {
+ \sqrt
+ }
+ {\MMLcreset\xmlall{#1}{/!(mml:degree\string|mml:root)}}
+\stopxmlsetups
+
+% gcd
+
+\startxmlsetups mml:gcd
+ \begingroup
+ \gcd\left(\MMLcreset\xmlconcat{#1}{/!mml:gcd}{\MMLseparator,}\right)
+ \endgroup
+\stopxmlsetups
+
+% and or xor implies, not
+
+\startxmlsetups mml:and \xmlconcat{#1}{/!mml:and} {\wedge} \stopxmlsetups
+\startxmlsetups mml:or \xmlconcat{#1}{/!mml:or} {\vee} \stopxmlsetups
+\startxmlsetups mml:xor \xmlconcat{#1}{/!mml:xor} {\mathopnolimits{xor}} \stopxmlsetups
+\startxmlsetups mml:implies \xmlconcat{#1}{/!mml:implies}{\Rightarrow} \stopxmlsetups
+\startxmlsetups mml:not \neg \xmlall {#1}{/!mml:not} \stopxmlsetups
+
+% forall exists
+
+%D We need to shift left below rotated A.
+
+\startxmlsetups mml:forall
+ \forall \negthinspace \xmlsetup{#1}{mml:forallexists}
+\stopxmlsetups
+
+\startxmlsetups mml:exists
+ \exists \xmlsetup{#1}{mml:forallexists}
+\stopxmlsetups
+
+\def\mmlforallexistslist{mml:bvar\string|mml:forall\string|mml:exists\string|mml:condition}
+
+\startxmlsetups mml:forallexists
+ _{\xmlconcat{#1}{/mml:bvar}{\MMLseparator,}}
+ \xmldoifelse {#1} {/mml:condition} {
+ \thickspace
+ \begingroup
+ \xmlfirst{#1}{/mml:condition}
+ \endgroup
+ \ifcase\xmlcount{#1}{/!(\mmlforallexistslist)}\relax
+ % nothing
+ \or
+ % == snelle volgende
+ \left\vert
+ \MMLcreset \medspace \xmlconcat{#1}{/!(\mmlforallexistslist)}{}
+ \right.
+ \else
+ % special case
+ \left\vert
+ \matrix {
+ \xmlconcat{#1}{/!(\mmlforallexistslist)}{\hfill\crcr}
+ }
+ \right.
+ \fi
+ } {
+ :\xmlfirst{#1}{/!(\mmlforallexistslist)}
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:abs
+ \left\vert \MMLcreset\xmlall{#1}{/!mml:abs} \right\vert
+\stopxmlsetups
+
+\startxmlsetups mml:conjugate % watch extra {}
+ {\overline{\MMLcreset\xmlall{#1}{/!mml:conjugate}}}
+\stopxmlsetups
+
+\startxmlsetups mml:arg
+ \mathopnolimits{arg} \left( \MMLcreset\xmlall{#1}{/!mml:arg} \right)
+\stopxmlsetups
+
+\startxmlsetups mml:real
+ \Re \left( \MMLcreset \xmlall{#1}{/!mml:real} \right)
+\stopxmlsetups
+
+\startxmlsetups mml:imaginary
+ \Im \ left( \MMLcreset \xmlall{#1}{/!mml:imaginary} \right)
+\stopxmlsetups
+
+\startxmlsetups mml:lcm
+ \mathopnolimits{lcm} \left( \xmlconcat{#1}{/!mml:lcm}{\MMLseparator,} \right)
+\stopxmlsetups
+
+\startxmlsetups mml:floor
+ \lfloor \xmlall{#1}{/!mml:floor} \rfloor
+\stopxmlsetups
+
+\startxmlsetups mml:ceiling
+ \lceiling \xmlall{#1}{/!mml:ceiling} \rceiling
+\stopxmlsetups
+
+% relations
+
+% apply attr or eq
+
+\setupMMLappearance[relation][\c!align=\v!no]
+
+\mapXMLvalue {mml:relation} {mml:eq} {=}
+\mapXMLvalue {mml:relation} {mml:neq} {\neq}
+\mapXMLvalue {mml:relation} {mml:gt} {>}
+\mapXMLvalue {mml:relation} {mml:lt} {<}
+\mapXMLvalue {mml:relation} {mml:geq} {\geq}
+\mapXMLvalue {mml:relation} {mml:leq} {\leq}
+\mapXMLvalue {mml:relation} {mml:equivalent} {\equiv}
+\mapXMLvalue {mml:relation} {mml:approx} {\approx}
+\mapXMLvalue {mml:relation} {mml:factorof} {\mid}
+
+\startxmlsetups mml:eq \xmlsetup{#1}{mml:relation} \stopxmlsetups
+\startxmlsetups mml:neq \xmlsetup{#1}{mml:relation} \stopxmlsetups
+\startxmlsetups mml:gt \xmlsetup{#1}{mml:relation} \stopxmlsetups
+\startxmlsetups mml:lt \xmlsetup{#1}{mml:relation} \stopxmlsetups
+\startxmlsetups mml:geq \xmlsetup{#1}{mml:relation} \stopxmlsetups
+\startxmlsetups mml:leq \xmlsetup{#1}{mml:relation} \stopxmlsetups
+\startxmlsetups mml:equivalent \xmlsetup{#1}{mml:relation} \stopxmlsetups
+\startxmlsetups mml:approx \xmlsetup{#1}{mml:relation} \stopxmlsetups
+\startxmlsetups mml:factorof \xmlsetup{#1}{mml:relation} \stopxmlsetups
+
+\startxmlsetups mml:relation
+ \edef\mmlapplyaction{\xmlfilter{#1}{/*/name()}}
+ \MMLcreset \xmlsetup{#1}{mml:relation:\xmlattdef{#1}{align}{\MMLrelationalign}}
+\stopxmlsetups
+
+\startxmlsetups mml:relation:default
+ \xmlconcatrange{#1}{/*}{2}{}{\XMLval{mml:relation}{\mmlapplyaction}{?}}
+\stopxmlsetups
+\startxmlsetups mml:relation:last
+ \eqalign {
+ \xmlconcatrange{#1}{/*}{2}{-2}{&\XMLval{mml:relation}{\mmlapplyaction}{?}\crcr}
+ \mmlprelast{#1}&\XMLval{mml:relation}{\mmlapplyaction}{?}{}\mmllast{#1}
+ }
+\stopxmlsetups
+\startxmlsetups mml:relation:first
+ \eqalign {
+ \mmlsecond{#1}\XMLval{mml:relation}{\mmlapplyaction}{?}{}
+ &\xmlconcatrange{#1}{/*}{3}{}{\crcr\XMLval{mml:relation}{\mmlapplyaction}{?}{}&}
+ }
+\stopxmlsetups
+\startxmlsetups mml:relation:left
+ \eqalign {
+ \xmlconcatrange{#1}{/*}{2}{}{&\XMLval{mml:relation}{\mmlapplyaction}{?}\crcr}
+ }
+\stopxmlsetups
+\startxmlsetups mml:relation:right
+ \eqalign {
+ &\xmlconcatrange{#1}{/*}{2}{}{\crcr\XMLval{mml:relation}{\mmlapplyaction}{?}{}&}
+ }
+\stopxmlsetups
+\startxmlsetups mml:relation:no
+ \xmlsetup{#1}{mml:relation:default}
+\stopxmlsetups
+\startxmlsetups mml:relation:yes
+ \xmlsetup{#1}{mml:relation:left}
+\stopxmlsetups
+
+% personal goody:
+
+\edef\MMLcmainresetlist{\MMLcmainresetlist\string|becomes}
+
+\mapXMLvalue {mml:relation} {mml:becomes} {:=}
+
+\startxmlsetups mml:becomes \xmlsetup{#1}{mml:relation} \stopxmlsetups
+
+% calculus and vector calculus
+
+\startxmlsetups mml:domainofapplication
+ \xmlall{#1}{/!mml:domainofapplication}
+\stopxmlsetups
+
+\setupMMLappearance[int][\c!location=\v!top]
+
+\def\doMMLlimits#1{\doifelsevalue{MML#1\c!location}\v!top\limits\nolimits}
+
+\startxmlsetups mml:int
+ \MMLcreset
+ \xmldoifelse {#1} {/mml:domainofapplication} {
+ \int \doMMLlimits{int}_{\xmlfirst{#1}{/mml:domainofapplication}}\relax
+ } {
+ \xmldoifelse {#1} {/mml:condition} {
+ \int \doMMLlimits{int}_{\xmlfirst{#1}{/mml:condition}}\relax
+ } {
+ \xmldoifelse {#1} {/mml:lowlimit} {
+ \int \doMMLlimits{int}_{\xmlfirst{#1}{/mml:lowlimit}}^{\xmlfirst{#1}{/mml:uplimit}}
+ } {
+ % funny, why do we have lowlimit/uplimit then
+ \xmldoifelse {#1} {/mml:apply/mml:interval} {
+ \int \doMMLlimits{int}_{\xmlindex{#1}{/mml:apply}{2}}^{\xmlindex{#1}{/mml:apply}{3}}
+ } {
+ \int
+ }
+ }
+ }
+ }
+ \MMLcreset
+ \xmldoifelse {#1} {/mml:apply} {
+ \doifelsemmlfunction {#1} { % todo test
+ \xmlfirst{#1}{/mml:apply}
+ } {
+ % if there are too many () now, we need to be more clever
+ \left( \xmlfirst{#1}{/mml:apply} \right)
+ }
+ } {
+ \xmlfirst{#1}{/mml:ci}
+ }
+ \xmldoifelse {#1} {/mml:bvar} {
+ \thinspace {\mr d} \xmlfirst{#1}{/mml:bvar}
+ } {
+ % nothing
+ }
+\stopxmlsetups
+
+\setupMMLappearance[diff][\c!location=\v!top,\c!alternative=\v!a]
+
+% \setupMMLappearance[diff][alternative=b]
+%
+% \startXMLdata
+% <math><apply><apply><diff/><bvar><ci>x</ci></bvar><ci>f</ci></apply><ci>a</ci></apply></math>
+% <math><apply><apply><diff/><bvar><ci>x</ci></bvar><degree>2</degree><ci>f</ci></apply><ci>a</ci></apply></math>
+% \stopXMLdata
+
+% d^y/dx^2
+%
+% \startXMLdata
+% <math><apply><diff/>
+% <bvar><ci>x</ci><cn type="integer">2</cn></bvar>
+% <lambda><bvar><ci>x</ci></bvar><ci>y</ci></lambda>
+% </apply></math>
+% \stopXMLdata
+
+\startxmlsetups mml:diff
+ \MMLcreset
+ \doifelse \MMLdiffalternative \v!a {
+ \xmldoifelse {#1} {/mml:lambda} {
+ % a special case (mathadore/openmath)
+ \frac {
+ d^{\xmlfirst{#1}{/mml:bvar}\xmlfirst{#1}{/mml:cn}}{\xmlfirst{#1}{/mml:lambda}\xmlfirst{#1}{/mml:ci}}
+ } {
+ d{\xmlfirst{#1}{/mml:bvar}\xmlfirst{#1}{/mml:ci}}^{\xmlfirst{#1}{/mml:bvar}\xmlfirst{#1}{/mml:cn}}
+ }
+ } {
+ \xmldoifelse {#1} {/mml:bvar} {
+ \frac {
+ {\mr d}{
+ \xmldoifelse {#1} {/mml:degree} {
+ ^{\xmlconcat{#1}{/mml:degree}\empty}
+ } {
+ \xmldoif {#1} {/mml:bvar/mml:degree} {
+ ^{\xmlconcat{#1}{/mml:bvar/mml:degree}+}
+ }
+ }
+ }
+ \doif \MMLdifflocation \v!top {
+ \xmldoifelse {#1} {/mml:ci} {
+ \xmlfirst{#1}{/mml:ci}
+ } {
+ \MMLcreset
+ \xmlfirst{#1}{/mml:apply}
+ }
+ }
+ } {
+ {\mr d}
+ \xmlfirst{#1}{/mml:bvar/!mml:degree}
+ \xmldoif {#1} {/mml:bvar/mml:degree} {
+ ^{\xmlfirst{#1}{/mml:bvar/mml:degree}}
+ }
+ }
+ \doifnot \MMLdifflocation \v!top {
+ \left(\MMLcreset\xmlfirst{#1}{/(mml:apply\string|mml:ci)}\right)
+ }
+ } {
+ \xmlconcatrange{#1}{/*}{2}{}^\prime
+ }
+ }
+ } {
+ \MMLcreset
+ \xmlfirst{#1}{/(mml:apply\string|mml:ci)}
+ % there can be problems with nested diff's: ^^{} error
+ % so we add an empty group here
+ {}^
+ {
+ \xmldoifelse {#1} {/mml:degree} {
+ \edef\mmldegree{\xmlfirst{#1}{/mml:degree/mml:cn}}
+ \ifx\mmldegree\empty
+ % what to do here
+ \else
+ \dorecurse\mmldegree\prime
+ \fi
+ } {
+ \prime
+ }
+ }
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:partialdiff
+ \xmldoifelse {#1} {/mml:list} {
+ {\mr D}_{
+ \begingroup
+ \setfalse\mmllistdelimiters
+ \xmlall{#1}{/mml:list}
+ \endgroup
+ }
+ \xmlfirst{#1}{/(mml:apply\string|mml:reln\string|mml:ci\string|mml:cn)}
+ } {
+ \xmldoifelse {#1} {/mml:bvar} {
+ \frac {
+ {\mr d}^{
+ \xmldoifelse {#1} {/mml:degree} {
+ \xmlconcat{#1}{/mml:degree}\empty
+ } {
+ \xmlconcat{#1}{/mml:bvar/mml:degree}+
+ }
+ }
+ \MMLcreset
+ \xmlfirst{#1}{/(mml:apply\string|mml:reln\string|mml:ci\string|mml:cn)}
+ } {
+ \xmlfirst{#1}{/mml:bvar}
+ {\mr d}\xmlfirst{#1}{/(mml:apply\string|mml:reln\string|mml:ci\string|mml:cn)}
+ \xmldoif {#1} {/mml:degree} {
+ ^{\xmlfirst{#1}{/mml:degree}}
+ }
+ }
+ } {
+ \xmlfirst{#1}{/(mml:apply\string|mml:reln\string|mml:ci\string|mml:cn)}
+ }
+ }
+\stopxmlsetups
+
+% option: to be discussed with taco/aditya: all math functions \mathentity
+%
+% \defineXMLentity [div] {\mathematics{\triangledown\times}}
+% \defineXMLentity [curl] {\mathematics{\triangledown .}}
+% \defineXMLentity [grad] {\mathematics{\triangledown }}
+
+\startxmlsetups mml:divergence \mathopnolimits{div} \xmlall{#1}{/!mml:divergence} \stopxmlsetups
+\startxmlsetups mml:grad \mathopnolimits{grad} \xmlall{#1}{/!mml:grad} \stopxmlsetups
+\startxmlsetups mml:curl \mathopnolimits{curl} \xmlall{#1}{/!mml:curl} \stopxmlsetups
+\startxmlsetups mml:laplacian \nabla^2 \xmlall{#1}{/!mml:laplacian} \stopxmlsetups
+\startxmlsetups mml:ident \mathopnolimits{identity} \xmlall{#1}{/!mml:ident} \stopxmlsetups
+
+\setupMMLappearance[domain] [symbol=]
+\setupMMLappearance[codomain][symbol=]
+
+\startxmlsetups mml:domain
+ \doifelsenothing \MMLdomainsymbol {
+ \mathopnolimits{domain}\MMLcreset\xmlall{#1}{/!mml:domain}
+ } {
+ \MMLdomainsymbol_{\xmlall{#1}{/!mml:domain}}
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:codomain
+ \doifelsenothing \MMLcodomainsymbol {
+ \mathopnolimits{codomain}\MMLcreset\xmlall{#1}{/!mml:codomain}
+ } {
+ \MMLcodomainsymbol_{\xmlall{#1}{/!mml:codomain}}
+ }
+\stopxmlsetups
+
+% theory of sets
+
+\startxmlsetups mml:set
+ \left\{
+ \xmldoifelse {#1} {/mml:condition} {
+ \xmlfirst{#1}{/mml:bvar}\,\middle\vert\,\xmlfirst{#1}{/mml:condition}
+ } {
+ \xmlconcat{#1}{/!mml:set}{\MMLseparator,}
+ }
+ \right\}
+ \relax % needed
+\stopxmlsetups
+
+\settrue\mmllistdelimiters
+
+\startxmlsetups mml:list
+ \begingroup
+ \ifconditional\mmllistdelimiters\left [\fi
+ \begingroup
+ \settrue\mmllistdelimiters
+ \xmlconcat{#1}{/!mml:list}{\MMLseparator,}
+ \endgroup
+ \ifconditional\mmllistdelimiters\right]\fi
+ \endgroup
+\stopxmlsetups
+
+\startxmlsetups mml:union \mmlsecond{#1} \cup \mmlthird{#1} \stopxmlsetups
+\startxmlsetups mml:intersect \mmlsecond{#1} \cap \mmlthird{#1} \stopxmlsetups
+\startxmlsetups mml:in \mmlsecond{#1} \in \mmlthird{#1} \stopxmlsetups
+\startxmlsetups mml:notin \mmlsecond{#1} {\not\in} \mmlthird{#1} \stopxmlsetups
+\startxmlsetups mml:subset \mmlsecond{#1} \subset \mmlthird{#1} \stopxmlsetups
+\startxmlsetups mml:prsubset \mmlsecond{#1} \subseteq \mmlthird{#1} \stopxmlsetups
+\startxmlsetups mml:notsubset \mmlsecond{#1} {\not\subset} \mmlthird{#1} \stopxmlsetups
+\startxmlsetups mml:notprsubset \mmlsecond{#1} {\not\subseteq} \mmlthird{#1} \stopxmlsetups
+\startxmlsetups mml:setdiff \mmlsecond{#1} \setminus \mmlthird{#1} \stopxmlsetups
+
+\startxmlsetups mml:card
+ \left\vert \xmlall{#1}{/!mml:card} \right\vert
+\stopxmlsetups
+
+\startxmlsetups mml:cartesianproduct
+ \xmlconcat{#1}{/!mml:cartesianproduct}{\times}
+\stopxmlsetups
+
+% sequences and series
+
+\setupMMLappearance[sum] [\c!location=\v!top]
+\setupMMLappearance[product][\c!location=\v!top]
+
+\mapXMLvalue {mml:sumprod} {sum} {\sum}
+\mapXMLvalue {mml:sumprod} {product} {\prod}
+
+\startxmlsetups mml:sum \edef\mmlsumprodname{sum} \xmlsetup{#1}{mml:sumprod} \stopxmlsetups
+\startxmlsetups mml:product \edef\mmlsumprodname{product} \xmlsetup{#1}{mml:sumprod} \stopxmlsetups
+
+\def\mmlstackedsubscripts#1%
+ {\vbox
+ {\baselineskip\zeropoint % hack, taco vragen
+ \halign{$\scriptstyle\hss##\hss$\cr#1\crcr}}}
+
+% unfinished
+
+\startxmlsetups mml:sumprod
+ \begingroup
+ \xmldoifelse {#1} {/(mml:condition\string|mml:bvar\string|mml:lowlimit)} {
+ \def\mmlsumprodlower{
+ _{
+ \xmldoifelse {#1} {/mml:condition} {
+ \mmlstackedsubscripts{\xmlconcat{#1}{/mml:condition}{\crcr}}
+ } {
+ \xmldoif {#1} {/mml:bvar} {
+ \xmlfirst{#1}{/mml:bvar}
+ \xmldoif{#1}{/mml:lowlimit}{=}
+ }
+ \xmlfirst{#1}{/mml:lowlimit}
+ }
+ }
+ }
+ } {
+ \let\mmlsumprodlower\empty
+ }
+ \xmldoifelse {#1} {/mml:uplimit} {
+ \def\mmlsumprodupper{^{\xmlfirst{#1}{/mml:uplimit}}}
+ } {
+ \let\mmlsumprodupper\empty
+ }
+ \xmldoif {#1} {/mml:interval} { % open math converter gives this
+ \edef\mmlintervalfrom{\xmlindex{#1}{/mml:interval}{1}}
+ \edef\mmlintervalto {\xmlindex{#1}{/mml:interval}{2}}
+ \ifx \mmlintervalfrom \empty \else
+ \def\mmlsumprodlower{_{\xmldoif{#1}{/mml:bvar}{\xmlfirst{#1}{/mml:bvar}{=}}\mmlintervalfrom}}
+ \fi
+ \ifx \mmlintervalto \empty \else
+ \def\mmlsumprodupper{^{\mmlintervalto}}
+ \fi
+ }
+ \MMLcreset
+ \XMLval{mml:sumprod}{\mmlsumprodname}{}\doMMLlimits\mmlsumprodname\mmlsumprodupper\mmlsumprodlower
+ \MMLcreset
+ \xmldoifelse {#1} {/mml:lambda/mml:apply} {
+ \xmlfirst{#1}{/mml:lambda/mml:apply}% a bit of open math conversion mess
+ } {
+ \xmlfirst{#1}{/(mml:apply\string|mml:lambda\string|mml:ci)}%
+ }
+ \endgroup
+\stopxmlsetups
+
+\setupMMLappearance[limit][\c!location=\v!top]
+
+\startxmlsetups mml:limit
+ \MMLcreset \lim
+ \doMMLlimits {limit}_{
+ \MMLcreset
+ \xmldoifelse {#1} {/mml:condition} {
+ \xmlfirst{#1}{/mml:condition}
+ } {
+ \xmldoif {#1} {/mml:bvar} {
+ \xmlfirst{#1}{/mml:bvar}\rightarrow
+ }
+ \xmlfirst{#1}{/mml:lowlimit}
+ }
+ }
+ \begingroup
+ % a bit of open math conversion mess, lambda needed for openmath, ok?
+ \MMLcreset
+ \xmlfirst{#1}{/mml:lambda/mml:apply}
+ \xmlfirst{#1}{/(mml:apply\string|mml:lambda)}
+ \endgroup
+\stopxmlsetups
+
+% consider a faster index
+
+\startxmlsetups mml:tendsto
+ \MMLcreset \mmlsecond{#1}
+ \XMLval {mml:tendsto:type} {\xmlattdef{#1}{type}{default}} {\rightarrow}
+ \MMLcreset \mmlthird{#1}
+\stopxmlsetups
+
+\mapXMLvalue {mml:tendsto:type} {above} {\downarrow}
+\mapXMLvalue {mml:tendsto:type} {below} {\uparrow}
+\mapXMLvalue {mml:tendsto:type} {default} {\rightarrow}
+
+% elementary classical functions
+
+\setupMMLappearance[log][\c!location=\v!right]
+
+\startxmlsetups mml:exp
+% {\mr e}^{\xmlfirst{#1}{/mml:apply\string|mml:reln\string|mml:ci\string|mml:cn}}
+ {\mr e}^{\xmlfirst{#1}{/!mml:exp}}
+\stopxmlsetups
+
+\startxmlsetups mml:log
+ \xmldoifelse {#1} {/mml:logbase} {
+ \doifelse \MMLloglocation \v!left {
+ \mathop {
+ {}^{\xmlfirst{#1}{/mml:logbase}}\negthinspace\mathopnolimits{log}
+ }
+ } {
+ \mathopnolimits{log}_{\xmlfirst{#1}{/mml:logbase}}
+ }
+ } {
+ \mathopnolimits{log}
+ }
+ \MMLcreset
+ \xmlsetup{#1}{mml:function}
+\stopxmlsetups
+
+\startxmlsetups mml:ln
+ \mathopnolimits{ln}
+ \xmlsetup{#1}{mml:function}
+\stopxmlsetups
+
+% statistics
+
+\startxmlsetups mml:mean \overline {\mmlsecond{#1}} \stopxmlsetups
+\startxmlsetups mml:sdev \sigma \left(\MMLcreset\mmlsecond{#1}\right) \stopxmlsetups
+\startxmlsetups mml:variance \sigma \left(\MMLcreset\mmlsecond{#1}\right)^2 \stopxmlsetups
+\startxmlsetups mml:median \mathopnolimits{median}\left(\MMLcreset\mmlsecond{#1}\right) \stopxmlsetups
+\startxmlsetups mml:mode \mathopnolimits{mode} \left(\MMLcreset\mmlsecond{#1}\right) \stopxmlsetups
+
+% moments
+
+\startxmlsetups mml:moment
+ \left\langle
+ \xmlfirst{#1}{/(mml:apply\string|mml:reln\string|mml:ci\string|mml:cn)}^{\xmlfirst{#1}{/mml:degree}}
+ \right\rangle
+ \xmldoif {#1} {mml:momentabout} {
+ _{\xmlfirst{#1}{mml:momentabout}}
+ }
+\stopxmlsetups
+
+% linear algebra
+
+\setupMMLappearance [vector] [\c!direction=\v!horizontal,\c!separator={,}]
+
+\startxmlsetups mml:vector
+ \begingroup
+ \ifnum\xmlcount{#1}{/*}>\plusone
+ \doifelse\MMLvectordirection\v!horizontal {
+ \left(\xmlconcat{#1}{/*}{\MMLseparator\MMLvectorseparator}\right)
+ } {
+ \MMLcreset\left(\matrix{\xmlconcat{#1}{/*}{\MMLseparator\MMLvectorseparator}}\right)
+ }
+ \else
+ \overrightarrow{\charhtstrut\mmlfirst{#1}}
+ \fi
+ \endgroup
+\stopxmlsetups
+
+\settrue\MMCdelmatrix % ( ) when true
+
+\startxmlsetups mml:matrix
+ \begingroup
+ \MMLcreset
+ \ifconditional\MMCdelmatrix
+ \left(\matrix{\xmlcommand{#1}{/mml:matrixrow}{mml:matrixrow:do}}\right)
+ \else
+ \settrue\MMCdelmatrix
+ \matrix{\xmlcommand{#1}{/mml:matrixrow}{mml:matrixrow:do}}
+ \fi
+ \endgroup
+\stopxmlsetups
+
+\startxmlsetups mml:matrixrow
+ \begingroup
+ \MMLcreset
+ \left(\xmlsetup{#1}{mml:matrixrow:do}\right)
+ \endgroup
+\stopxmlsetups
+
+\startxmlsetups mml:matrixrow:do
+ \xmlconcat{#1}{/*}{&}\crcr
+\stopxmlsetups
+
+\startxmlsetups mml:determinant
+ \begingroup
+ \setfalse\MMCdelmatrix
+ \left|\mmlsecond{#1}\right|
+ \endgroup
+\stopxmlsetups
+
+\startxmlsetups mml:transpose
+ \mmlsecond{#1}^{\mathopnolimits{T}}
+\stopxmlsetups
+
+\startxmlsetups mml:selector
+ \MMLmathinner{\mmlsecond{#1}_{\MMLcreset\xmlconcatrange{#1}{/*}{3}{}{\MMLseparator,}}}
+\stopxmlsetups
+
+\startxmlsetups mml:vectorproduct \mmlsecond{#1}\times \mmlthird{#1} \stopxmlsetups
+\startxmlsetups mml:scalarproduct \mmlsecond{#1}\cdot \mmlthird{#1} \stopxmlsetups
+\startxmlsetups mml:outerproduct \mmlsecond{#1}\otimes\mmlthird{#1} \stopxmlsetups
+
+% semantic mapping elements
+
+\startxmlsetups mml:semantics
+ \xmlfirst{#1}{/(mml:annotation\string|apply)}
+\stopxmlsetups
+
+\usemodule[m][calcmath]
+
+\startxmlsetups mml:annotation
+ \xmldoifelse {#1} {[oneof(@encoding,'TeX','tex','TEX','ConTeXt','context','CONTEXT','ctx')]} {
+ \begingroup
+ \setcatcodetable\ctxcatcodes
+ \xmlflush{#1}
+ \endgroup
+ } {
+ \xmldoifelse {#1} {[oneof(@encoding,'calcmath','cm')]} {
+ \calcmath{\xmlflush{#1}}
+ } {
+ % unsupported
+ }
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:annotation-xml
+ % maybe diagnostics
+\stopxmlsetups
+
+% misc
+
+\startxmlsetups mml:integers \integers \stopxmlsetups
+\startxmlsetups mml:reals \reals \stopxmlsetups
+\startxmlsetups mml:rationals \rationals \stopxmlsetups
+\startxmlsetups mml:naturalnumbers \naturalnumbers \stopxmlsetups
+\startxmlsetups mml:complexes \complexes \stopxmlsetups
+\startxmlsetups mml:primes \primes \stopxmlsetups
+\startxmlsetups mml:exponentiale \mathopnolimits{e} \stopxmlsetups
+\startxmlsetups mml:imaginaryi \mathopnolimits{i} \stopxmlsetups
+\startxmlsetups mml:notanumber \mathopnolimits{NaN} \stopxmlsetups
+\startxmlsetups mml:true \mathopnolimits{true} \stopxmlsetups
+\startxmlsetups mml:false \mathopnolimits{false} \stopxmlsetups
+\startxmlsetups mml:emptyset \mathopnolimits{\O} \stopxmlsetups
+\startxmlsetups mml:pi \pi \stopxmlsetups
+\startxmlsetups mml:eulergamma \gamma \stopxmlsetups
+\startxmlsetups mml:infinity \infty \stopxmlsetups
+
+% gonio functions
+
+\setupMMLappearance[function][\c!reduction=\v!yes]
+
+% todo: \mfunction which adapts itself when registered as command
+
+\startxmlsetups mml:sin \mathopnolimits {sin}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:sinh \mathopnolimits{sinh}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:cos \mathopnolimits {cos}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:cosh \mathopnolimits{cosh}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:tan \mathopnolimits {tan}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:tanh \mathopnolimits{tanh}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:cot \mathopnolimits {cot}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:coth \mathopnolimits{coth}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:csc \mathopnolimits {csc}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:csch \mathopnolimits{csch}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:sec \mathopnolimits {sec}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:sech \mathopnolimits{sech}\xmlsetup{#1}{mml:function} \stopxmlsetups
+
+\startxmlsetups mml:function
+ \ifconditional\xmlinversefunction^{-1}\fi\setfalse\xmlinversefunction
+ \xmlsetup{#1}{mml:function:argument}
+\stopxmlsetups
+
+\startxmlsetups mml:function:argument
+ \doifelse \MMLfunctionreduction \v!yes {
+ \xmldoifelse {#1} {/mml:apply} {
+ \xmldoifelse {#1} {/mml:apply/(\MMLcfunctionlist\string|mml:divide)}
+ \donefalse
+ \donetrue
+ } {
+ \donefalse
+ }
+ } {
+ \donetrue
+ }
+ % beware, we still flush from 2 up
+ \ifdone
+ \left(
+ \MMLcreset
+ \xmlall{#1}{/[position()>1]}% \xmlconcatrange{#1}{/*}{2}{}\empty
+ \right)
+ \else
+ \MMLcreset
+ \xmlall{#1}{/[position()>1]}
+ \fi
+\stopxmlsetups
+
+% PRESENTATION MATHML
+%
+% there are some rough edges that need to be sorted out
+
+% helpers
+
+\mapXMLvalue {mml} {normal} {\tf}
+\mapXMLvalue {mml} {double-struck} {\bf}
+\mapXMLvalue {mml} {italic} {\it}
+\mapXMLvalue {mml} {fraktur} {\bf}
+\mapXMLvalue {mml} {script} {\tf}
+\mapXMLvalue {mml} {bold} {\bf}
+\mapXMLvalue {mml} {bold-italic} {\bi}
+\mapXMLvalue {mml} {bold-fraktur} {\bf}
+\mapXMLvalue {mml} {bold-script} {\bf}
+\mapXMLvalue {mml} {sans-serif} {\ss}
+\mapXMLvalue {mml} {bold-sans-serif} {\ss\bf}
+\mapXMLvalue {mml} {sans-serif-italic} {\ss\it}
+\mapXMLvalue {mml} {sans-serif-bold-italic} {\ss\bi}
+\mapXMLvalue {mml} {monospace} {\tt}
+
+\starttexdefinition setmmlmathstyle #1
+ \XMLval {mml} {\xmlatt{#1}{mathvariant}} \empty
+\stoptexdefinition
+
+\starttexdefinition applymmlmathcolor #1#2
+ \edef\mmlmathcolor{\xmlatt{#1}{mathcolor}}
+ \ifx \mmlmathcolor \empty
+ #2
+ \else
+ \color[\mmlmathcolor]{#2}
+ \fi
+\stoptexdefinition
+
+% todo: textbackgrounds
+
+\starttexdefinition applymmlmathbackground #1#2
+ \edef\mmlmathbackground{\xmlatt{#1}{mathbackground}}
+ \ifx \mmlmathbackground \empty
+ #2
+ \else
+ \backgroundline[\mmlmathbackground]{#2}
+ \fi
+\stoptexdefinition
+
+\starttexdefinition applymmlsometext #1#2
+ \applymmlmathbackground {#1} {
+ \applymmlmathcolor {#1} {
+ \setmmlmathstyle {#1}
+ \ignorespaces#2\removeunwantedspaces
+ }
+ }
+\stoptexdefinition
+
+% probably bugged:
+
+\starttexdefinition doMMLfiller #1
+ \pushmacro\doMMLfiller
+ \let\doMMLfiller\gobbleoneargument
+ \gdef\dodoMMLfiller{% where used
+ \disablefiller
+ \mathematics{#1}
+ }
+ \hbox {
+ \def\normalorfiller##1##2{
+ \gdef\dodoMMLfiller{\enablefiller#1}%
+ \let\normalorfiller\gobbletwoarguments
+ }
+ \mathematics{#1}
+ }
+ \popmacro\doMMLfiller
+\stoptexdefinition
+
+% setups
+
+\startxmlsetups mml:mi % todo: mathvariant mathsize mathcolor mathbackground
+ \ctxlua{lxml.mml.mi("#1","*")}
+\stopxmlsetups
+
+\startxmlsetups mml:mn % todo: mathvariant mathsize mathcolor mathbackground
+ \begingroup
+ \mr \ctxlua{lxml.mml.mn("#1","*")}% no \hbox, would be ok for . , but spoils rest
+ \endgroup
+\stopxmlsetups
+
+\startxmlsetups mml:mo
+ \ctxlua{lxml.mml.mo("#1","*")}
+\stopxmlsetups
+
+\startxmlsetups mml:mfenced % {} around separator is needed for spacing
+ \def\MMLleft {\left }% weird
+ \def\MMLright{\right}
+ \ctxlua{lxml.mml.mfenced("#1","/*")}
+\stopxmlsetups
+
+\startxmlsetups mml:menclose % notation=.....
+ \edef\mmlmenclosenotation{\xmlattdef{#1}{notation}{longdiv}}
+ \doifelse \mmlmenclosenotation {longdiv} {
+ \overline{\left)\xmlflush{#1}\right.}
+ } {
+ \doifelse \mmlmenclosenotation {actuarial} {
+ \overline{\left.\xmlflush{#1}\right|}
+ } {
+ \doifelse \mmlmenclosenotation {radical} {
+ \sqrt{\xmlflush{#1}}
+ } {
+ \xmlflush{#1}
+ }
+ }
+ }
+\stopxmlsetups
+
+\mapXMLvalue {mml:mfrac:linethickness} {thin} {.2pt}
+\mapXMLvalue {mml:mfrac:linethickness} {medium} {.4pt}
+\mapXMLvalue {mml:mfrac:linethickness} {thick} {.8pt}
+
+\startxmlsetups mml:mfrac % dodo: handle linethickness in lua + unit
+ \begingroup
+ \edef\mmlfraclinethickness{\xmlatt{#1}{linethickness}}
+ \ifx\mmlfraclinethickness\empty
+ \doifelse{\xmlatt{#1}{bevelled}}{true} {
+ \xmlindex{#1}{/*}{1}
+ \mathpunct{\kern-.2ex\left.\middle/\right.\kern-.25ex}
+ \mmlsecond{#1}
+ } {
+ \frac{\mmlfirst{#1}}{\mmlsecond{#1}}
+ }
+ \else
+ \doifXMLvalelse {mml:mfrac:linethickness} \mmlfraclinethickness {
+ \scratchdimen\XMLval{mml:mfrac:linethickness}\mmlfraclinethickness{.4pt}
+ } {
+ \setdimensionwithunit\scratchdimen\mmlfraclinethickness{pt}
+ }
+ {
+ {\mmlfirst{#1}}
+ \above\scratchdimen
+ {\mmlsecond{#1}}
+ }
+ \fi
+ \endgroup
+\stopxmlsetups
+
+\startxmlsetups mml:ms
+ \hbox {
+ \tf % else encoding problems
+ \edef\mmllquote{\xmlatt{#1}{lquote}}
+ \edef\mmlrquote{\xmlatt{#1}{rquote}}
+ \ifx\mmllquote\empty\symbol[leftquotation]\else\mmllquote\fi
+ \applymmlsometext{#1}{\xmlflush{#1}}
+ \ifx\mmlrquote\empty\symbol[rightquotation]\else\mmlrquote\fi
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:mstyle
+ \begingroup
+ \setmmlmathstyle{#1}
+ \xmlflush{#1}
+ \endgroup
+\stopxmlsetups
+
+\startxmlsetups mml:mtext
+ \hbox {
+ \tf % else encoding problems, we can make mr an option
+ \applymmlsometext{#1}{\xmlflush{#1}}
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:merror
+ \hbox{$\displaystyle\xmlflush{#1}$}
+\stopxmlsetups
+
+\startxmlsetups mml:mphantom
+ \phantom{\ignorespaces{}\xmlflush{#1}\unskip} % watch spacing {} hack
+\stopxmlsetups
+
+\startxmlsetups mml:mpadded
+ \xmlflush{#1}
+\stopxmlsetups
+
+% mrow
+
+% \startxmlsetups mml:mrow
+% \begingroup
+% \ifcase\xmlcount{#1}{/mml:mo}\relax
+% \xmlflush{#1}
+% \else % no \let
+% \def\MMLleft {\left }
+% \def\MMLright{\right}
+% \enabledelimiter
+% \checkdelimiters{\xmlall{#1}{/mml:mo}}
+% \fakeleftdelimiter
+% \xmlflush{#1}
+% \fakerightdelimiter
+% \disabledelimiter
+% \fi
+% \endgroup
+% \stopxmlsetups
+
+% option: no fenced
+
+\startxmlsetups mml:mrow
+ \begingroup
+ \ifnum\xmlcount{#1}{/mml:mo}=\plustwo
+ \xmldoifelse {#1} {/mml:mo[position()==1 or position()==\xmlcount{#1}{/*}]} {% we need a {}
+ \def\MMLleft {\left }
+ \def\MMLright{\right}
+ \enabledelimiter
+ \checkdelimiters{\xmlall{#1}{/mml:mo}}
+ \fakeleftdelimiter
+ \xmlflush{#1}
+ \fakerightdelimiter
+ \disabledelimiter
+ } {
+ \xmlflush{#1}
+ }
+ \else
+ \xmlflush{#1}
+ \fi
+ \endgroup
+\stopxmlsetups
+
+\startxmlsetups mml:msqrt
+ \sqrt{\xmlflush{#1}}
+\stopxmlsetups
+
+\startxmlsetups mml:mroot
+ \root{\mmlsecond{#1}}\of{\mmlfirst{#1}}
+\stopxmlsetups
+
+\setupMMLappearance[scripts][\c!alternative=\v!a] % {} rond base
+
+\startxmlsetups mml:msub
+ \doifelse\MMLscriptsalternative\v!a {
+ {\mmlfirst{#1}}_{\mmlsecond{#1}}
+ } {
+ \mmlfirst{#1} _{\mmlsecond{#1}}
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:msup
+ \doifelse\MMLscriptsalternative\v!a {
+ {\mmlfirst{#1}}^{\mmlsecond{#1}}
+ } {
+ \mmlfirst{#1} ^{\mmlsecond{#1}}
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:msubsup
+ \doifelse\MMLscriptsalternative\v!a {
+ {\mmlfirst{#1}}_{\mmlsecond{#1}}^{\mmlthird{#1}}
+ } {
+ \mmlfirst{#1} _{\mmlsecond{#1}}^{\mmlthird{#1}}
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:mover
+ \mathop {
+ \edef\mmlovertoken{\xmlraw{#1}{/mml:mo[position()==2]}}
+ \doifelse{\utfmathclass\mmlovertoken}{accent} {
+ \utfmathcommand\mmlovertoken{\xmlindex{#1}{/*}{1}}
+ } {
+ \vbox {
+ \m@th\ialign {
+ \hss##\hss\crcr
+ \noalign{\kern3\p@}%
+ \disabledelimiter\doMMLfiller{
+ \xmlindex{#1}{/*}{2}
+ }\crcr
+ \noalign{\kern3\p@\nointerlineskip}%
+ \disabledelimiter\doMMLfiller{
+ \xmlindex{#1}{/*}{1}
+ }\crcr
+ }
+ }
+ }
+ }
+ \limits
+\stopxmlsetups
+
+\startxmlsetups mml:munder
+ \mathop {
+ \vtop {
+ \m@th\ialign{
+ \hss##\hss\crcr
+ \disabledelimiter\doMMLfiller{\xmlindex{#1}{/*}{1}}\crcr
+ \noalign{\kern3\p@\nointerlineskip}%
+ \disabledelimiter\doMMLfiller{\xmlindex{#1}{/*}{2}}\crcr
+ \noalign{\kern3\p@}
+ }
+ }
+ }
+ \limits
+\stopxmlsetups
+
+\startxmlsetups mml:munderover
+ \edef\mmlunderovertoken{\xmlraw{#1}{/mml:mo[position()==1]}}
+ \utfmathcommanddefault\mmlunderovertoken{xmlindex}{{#1}{/*}{1}}
+ _{\disablefiller\disabledelimiter\xmlindex{#1}{/*}{2}}
+ ^{\disablefiller\disabledelimiter\xmlindex{#1}{/*}{3}}
+\stopxmlsetups
+
+% tables (mml:mtable, mml:mtr, mml:mlabledtr, mml:mtd)
+
+\startxmlsetups mml:mtable % some more attributes need to be supported
+ \vcenter{\ctxlua{lxml.mml.mtable("#1")}}
+\stopxmlsetups
+
+\startxmlsetups mml:mspace % complete
+ \begingroup
+ \!!widtha \xmlattdef{#1}{width} \!!zeropoint % must be string
+ \!!heighta\xmlattdef{#1}{height}\!!zeropoint
+ \!!deptha \xmlattdef{#1}{depth} \!!zeropoint
+ \ifdim\!!heighta=\zeropoint
+ \ifdim\!!deptha=\zeropoint\else
+ \hbox{\vrule\!!depth\!!deptha\!!height\zeropoint\!!width\zeropoint}%
+ \fi
+ \else
+ \hbox{\vrule\!!depth\zeropoint\!!height\!!heighta\!!width\zeropoint}%
+ \fi
+ \ifdim\!!widtha=\zeropoint\else
+ \hskip\!!widtha
+ \fi
+ \endgroup
+\stopxmlsetups
+
+\startxmlsetups mml:mglyph % probably never ok
+ \begingroup
+ \edef\mmlglyphfontfamily{\xmlatt {#1}{fontfamily}}
+ \edef\mmlglyphalt {\xmlattdef{#1}{alt}{unknown}}
+ \edef\mmlglyphindex {\xmlatt {#1}{index}}
+ \ifx \mmlglyphfontfamily \empty
+ \hbox{\tttf[no fontfamily specified for \mmlglyphalt]}
+ \else\ifx\mmlglyphindex\empty
+ \hbox{\tttf[no index specified for \mmlglyphalt]}
+ \else
+ \getglyph\mmlglyphfontfamily\mmlglyphindex
+ \fi\fi
+ \endgroup
+\stopxmlsetups
+
+\startxmlsetups mml:maligngroup \stopxmlsetups % will be done when needed
+\startxmlsetups mml:malignmark \stopxmlsetups % will be done when needed
+
+\startxmlsetups mml:none \stopxmlsetups
+\startxmlsetups mml:mprescripts \stopxmlsetups
+
+\startxmlsetups mml:mmultiscripts
+ \ctxlua{lxml.mml.mmultiscripts("#1")}
+\stopxmlsetups
+
+\stopmodule
+
+\protect \endinput
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% TODO:
+
+\startmoduletestsection
+
+\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}}
+
+% <apply><divide/>
+% <apply><minus/>
+% <apply><minus/><ci>b</ci></apply>
+% <apply><minus/><ci>b</ci></apply>
+% <apply><root/> <ci>a</ci></apply>
+% </apply>
+% <apply><minus/>
+% <apply><minus/><ci>b</ci><ci>b</ci></apply>
+% <apply><minus/><ci>b</ci></apply>
+% <apply><root/> <ci>a</ci></apply>
+% </apply>
+% </apply>
+
+\startxmlsetups mml: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
+\stopxmlsetups
+
+\stopmoduletestsection