x-mathml.mkxl /size: 80 Kb    last modification: 2021-10-28 13:51
1%D \module
2%D   [       file=x-mathml,
3%D        version=2008.05.29, (evolved from pre 2000 code)
4%D          title=\CONTEXT\ XML Modules,
5%D       subtitle=\MATHML,
6%D         author=Hans Hagen,
7%D           date=\currentdate,
8%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
9%C
10%C This module is part of the \CONTEXT\ macro||package and is
11%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
12%C details.
13
14% \xmlfilter{#1}{/*/name()} -> \xmltag
15
16% This implementation looks like a hack ... this is because we deal with all weird
17% cases we ran into, including abuse that was supposed to render ok (even if it
18% didn't in other renderers) .. it was simply expected to work that way. It is also
19% the product of stepwise adaptation to what we run into. And that in turn is often
20% determined by the tools that were used to produce the \XML. Even worse is the
21% cycling between coding that happens in projects: from content\ \MATHML\ to
22% OpenMath to asciimath to presentation \MATHML\ to \unknown\ which all depends on
23% what tools are available to render in a browser (where first \MATHML\ was hardly
24% supported, then became accepted, then was taken over by mathjax, then merged with
25% other input methods and who knopws what comes next in these days where technologies
26% are shortlived and the next best thing is already waiting around the corner.
27%
28% So, consider this module to be under constant construction and clean up. We still
29% use a funny mix of xml, tex and lua. I could rewrite the lot but it also shows
30% how context evolves. I might end up with a lua-only implementation some day, but
31% I must find a real good reason to spend time on it as so far it never paid back.
32% As far as I can tell, publishers have never shown much (real) interest anyway or
33% at least I haven't met one who cared to invest in it. If they run into \MATHML\
34% they just expect it to be supported.
35%
36% This variant is adapted to \LMTX\ and might evolve with upcoming variations of
37% the standard. As with \SVG\ and probably other \XML\ definitions that target a
38% specific domain, \MATHML\ is now more just something for browsers and \HTML\
39% usage (although support fluctuates). It's getting less generic (or at least we
40% see no more structural elements showing up) and with \CSS\ becoming the
41% recomended way to control local optimizations it indeed looks like only browsers
42% are the target, unless we can just ignore all that. Limitations of renderers,
43% specific usage, application determined \XML\ ... where will it end. All we can do
44% is follow and try to keep up, but maybe the more web it becomes, the less \TEX\
45% users need to care (read: can stick to \TEX\ coding).
46%
47% See the \MKII\ and \MKIV\ files for a history and the hacks we had to use in
48% the past.
49
50\writestatus{loading}{ConTeXt XML Macros / MathML Renderer}
51
52\unprotect
53
54\usemodule[x][calcmath]
55%usemodule[x][asciimath]
56
57\startmodule [mathml]
58
59\registerctxluafile{x-mathml}{autosuffix}
60
61\setupxml[\c!entities=\v!yes] % load big entities table
62
63\def\ctxmodulemathml#1{\ctxlua{moduledata.mathml.#1}}
64
65\startxmlsetups xml:mml:define
66    \xmlsetsetup{#1} {(formula|subformula)} {mml:formula}
67    \xmlfilter  {#1} {omt:*/function(remapopenmath)}
68    \xmlfilter  {#1} {mml:bind/function(remapmmlbind)}
69    \xmlfilter  {#1} {mml:csymbol/function(remapmmlcsymbol)}
70    \xmlsetsetup{#1} {mml:*} {mml:*}
71    \xmlsetsetup{#1} {mml:apply/mml:apply/mml:inverse/../..} {mml:apply:inverse}
72    \xmlstrip   {#1} {(mml:mi|mml:mo|mml:mn|mml:csymbol)}
73\stopxmlsetups
74
75\xmlregisterns{omt}{openmath}
76\xmlregisterns{mml}{mathml}
77
78\xmlregistersetup{xml:mml:define}
79
80\xmlmapvalue {mml:math:mode}    {display} {\displaymathematics} % we had this already
81\xmlmapvalue {mml:math:mode}    {inline}  {\inlinemathematics }
82
83\xmlmapvalue {mml:math:display} {block}   {\displaymathematics} % before this showed up
84\xmlmapvalue {mml:math:display} {inline}  {\inlinemathematics }
85
86\xmlmapvalue {mml:math:dir}     {ltr}     {\setfalse\c_math_right_to_left\math_basics_synchronize_direction}
87\xmlmapvalue {mml:math:dir}     {rtl}     {\settrue \c_math_right_to_left\math_basics_synchronize_direction}
88
89\edef\mmlconstantone  {1}
90\edef\mmlconstantfalse{false}
91
92\startxmlsetups mml:math
93    \begingroup
94        \enableautofences
95        \enableautofencemode
96        \xmlval {mml:math:dir} {\xmlatt{#1}{dir}} {}
97        \xmlval {mml:math:display} {\xmlatt{#1}{display}} {
98            \xmlval {mml:math:mode} {\xmlatt{#1}{mode}} {
99                \automathematics
100            }
101        }
102        {
103            \xmlflush{#1}
104        }
105    \endgroup
106\stopxmlsetups
107
108\startxmlsetups mml:imath
109    \inlinemathematics {
110        \enableautofences
111        \enableautofencemode
112        \xmlflush{#1}
113    }
114\stopxmlsetups
115
116\startxmlsetups mml:dmath
117    \displaymathematics {
118        \enableautofences
119        \enableautofencemode
120        \xmlflush{#1}
121    }
122\stopxmlsetups
123
124%D First we define some general formula elements.
125
126\startxmlsetups mml:formula
127    \edef\mmlformulaid      {\xmlatt{#1}{id}}
128    \edef\mmlformulalabel   {\xmlatt{#1}{label}\mmlformulaid}
129    \edef\mmlformulasublabel{\xmlatt{#1}{sublabel}\mmlformulaid}
130    \doifsomething\mmlformulalabel{\placeformula[\mmlformulalabel]{\mmlformulasublabel}}
131    \startformula
132        \xmlfirst{#1}{/mml:math}
133    \stopformula
134\stopxmlsetups
135
136
137\setfalse\mmlignoredelimiter % alternatively we could turn it on/off inside the start/stop and ignore \left\right\middle otherwise
138
139\let\mmlleftdelimiter       \autofenceopen
140\let\mmlmiddledelimiter     \autofencemiddle
141\let\mmlrightdelimiter      \autofenceclose
142\let\mmlleftorrightdelimiter\autofenceboth
143
144\def\mmlchar#1{\char#1 } % used in lua code
145
146%D The rendering macros:
147
148\def\MMLrm{\mr}
149
150\def\MMLseparator#1{\removeunwantedspaces{#1}\ignorespaces} % nils space after separator
151\def\MMLseparator#1{,} % todo, for europe we need to block the space
152
153%D Since I only had the draft of MathML 2 and later 3 as example of rendering, there
154%D are probably a lot of omissions and misinterpretations. At least I learned some
155%D bits and pieces of math rendering.
156%D
157%D The main complications were not so much the math, but to find the most efficient
158%D way to handle elements without spacing beging messed up. The first implementation
159%D was aimed at getting reasonable output, this second implementation is already
160%D better in terms of handling nesting, and I will definitely need a third one that
161%D has more efficient and less ugly code.
162%D
163%D The \TEX\ part is not that complicated and once the preprocessor was okay, the
164%D rest way just a lot of keying and testing. It all comes down to gobbling,
165%D redefining, and not so much to parsing.
166%D
167%D The second implementation expanded the whole math sequence into an internal \TEX\
168%D representation. This is a rather clean and fast process. Filtering and testing
169%D takes place by redefining the internal representation macros.
170%D
171%D The third implementation may look a bit more messy in some respects. This is
172%D because in \TEX\ it's not that trivial to implement a tree handler. We use a
173%D stack for the \type {apply} element and other sequential content. Occasionally we
174%D need to peek into child elements which involves messy code. This implementation
175%D is closer to the normal \XML\ handling in \CONTEXT.
176%D
177%D This fourth variant just improves on the third. It uses some tricks available in
178%D \LUAMETATEX\ where we have extended the math machinery.
179
180%D We start with the parent elements and the option handler.
181
182\protected\def\xmlmathmldirective#1{\dosetvalue{MML#1}}
183
184\xmlinstalldirective{mathml}{xmlmathmldirective}
185
186%D In the styles, options can be set with:
187
188\protected\def\setupMMLappearance[#1]{\dodoubleargument\getparameters[MML#1]} % no @@ because passed to lua
189
190%D We will apply inner math to all bits and pieces made up by an \type {apply}.
191
192\def\MMLmathinner
193  {\ifinner
194     \expandafter\firstofoneargument
195   \else
196     \expandafter\mathinner
197   \fi}
198
199%D Auxiliary MathML macros: (to be generalized)
200
201\def\mmlfirst  #1{\xmlelement{#1}{1}} % we can move these inline if needed
202\def\mmlsecond #1{\xmlelement{#1}{2}}
203\def\mmlthird  #1{\xmlelement{#1}{3}}
204\def\mmlprelast#1{\xmlelement{#1}{-2}}
205\def\mmllast   #1{\xmlelement{#1}{-1}}
206
207\starttexdefinition doifelsemmlfunction #1
208    \xmldoifelse {#1} {/mml:fn} {
209        \firstoftwoarguments
210    } {
211        \xmldoifelse {#1} {/mml:apply/mml:fn} {
212            \firstoftwoarguments
213        } {
214            \xmldoifelse {#1} {/mml:ci[@type=='fn']} {
215                \firstoftwoarguments
216            } {
217                \secondoftwoarguments
218            }
219        }
220    }
221\stoptexdefinition
222
223%D A couple of lists:
224
225\convertargument
226    mml:times|mml:divide|mml:power|%
227    mml:lt|mml:gt|mml:eq|mml:leq|mml:geq|%
228    mml:in|mml:inverse|%
229    mml:fn|%
230    mml:floor|mml:ceiling|%
231    mml:mean|%
232    mml:selector|%
233    mml:abs|mml:int|mml:limit|mml:sum|mml:product|%
234    mml:outerproduct|mml:innerproduct|mml:scalarproduct%
235\to \MMLcmainresetlist
236
237\convertargument
238    mml:sin|mml:arcsin|mml:sinh|mml:arcsinh|%
239    mml:cos|mml:arccos|mml:cosh|mml:arccosh|%
240    mml:tan|mml:arctan|mml:tanh|mml:arctanh|%
241    mml:cot|mml:arccot|mml:coth|mml:arccoth|%
242    mml:csc|mml:arccsc|mml:csch|mml:arccsch|%
243    mml:sec|mml:arcsec|mml:sech|mml:arcsech|%
244    mml:ln|mml:exp|mml:log|%
245    mml:abs|mml:int|mml:limit|mml:sum|mml:product|%
246    mml:fn%
247\to \MMLcfunctionlist
248
249\convertargument
250    mml:sin|mml:arcsin|mml:sinh|mml:arcsinh|%
251    mml:cos|mml:arccos|mml:cosh|mml:arccosh|%
252    mml:tan|mml:arctan|mml:tanh|mml:arctanh|%
253    mml:cot|mml:arccot|mml:coth|mml:arccoth|%
254    mml:csc|mml:arccsc|mml:csch|mml:arccsch|%
255    mml:sec|mml:arcsec|mml:sech|mml:arcsech|%
256    mml:ln|mml:exp|mml:log|%
257    mml:abs%
258\to \MMLcpurefunctionlist
259
260\convertargument
261    mml:diff|mml:partialdiff|mml:root%
262\to \MMLcconstructlist
263
264%D We use inner and grouping (begin/end and no b/e) else we get problems with
265%D 1/2(1+2) and alike. The problem with apply is that we need to take care of
266%D several situations, like:
267%D
268%D \starttyping
269%D <apply> <.../> ...
270%D <apply> <fn> ...
271%D <apply> <apply> <ci> ...
272%D <apply> <apply> <fn> <ci> ...
273%D \stoptyping
274%D
275%D Because we translated version 2 of this renderer into version 3 the following
276%D definitions may be sub optimal or more complex than actually needed.
277
278%D We will more more to lua ...
279
280% simple version
281
282\newcount\@MMLlevel \def\MMLcreset{\@MMLlevel\zerocount}
283
284\let\MMLctempresetlist\empty \def\setMMLcreset{\edef\MMLctempresetlist}
285
286\let\MMLdoL\donothing
287\let\MMLdoR\donothing
288
289\newcount\mmlapplydepth \def\MMLcreset{\mmlapplydepth\zerocount}
290
291\startxmlsetups mml:apply
292    \MMLmathinner {
293      % \xmldoif {#1} {/(\MMLcmainresetlist\string|\MMLctempresetlist)} {
294      %   \MMLcreset
295      % }
296        \edef\mmlapplyopentoken {\xmlatt{#1}{open}}
297        \edef\mmlapplyclosetoken{\xmlatt{#1}{close}}
298        \ifcase\mmlapplydepth
299        \orelse\ifempty\mmlapplyopentoken
300            \def\mmlapplyopentoken {(}
301            \def\mmlapplyclosetoken{)}
302        \fi
303        \advance\mmlapplydepth\plusone
304        \begingroup
305        \ifempty\mmlapplyopentoken
306           \let\MMLdoL\donothing
307           \let\MMLdoR\donothing
308        \else
309           \edef\MMLdoL{\noexpand\left \mmlapplyopentoken }
310           \edef\MMLdoR{\noexpand\right\mmlapplyclosetoken}
311        \fi
312        \let\MMLctempresetlist\empty
313        \xmldoifelse {#1} {/mml:apply} {
314%             % <apply> <apply> ... </apply> <ci> .. </ci> </apply>
315%             \xmldoifelse {#1} {/mml:apply(mml:plus|mml:minus)} {% [a]
316%                 % yet incomplete and rather untested
317%                 % <apply> <apply> <minus/> <tan/> <cos/> </apply> <ci>x</ci> </apply>
318            } {% [b]
319%                 \MMLcreset
320            }
321%             \MMLdoL
322%             \mmlfirst{#1}
323%             \ifconditional\somepostponedMMLactions
324%                 \postponedMMLactions
325%             \else
326%                 \left(\MMLcreset\mmlsecond{#1}\right)
327%             \fi
328%             \MMLdoR
329%         } {
330            \edef\mmlapplyaction{\xmlfilter{#1}{/*/tag()}}
331            \doifelsesetups {mml:apply:mml:\mmlapplyaction} {
332                \xmlsetup{#1}{mml:apply:mml:\mmlapplyaction}
333             } {
334%                 \MMLdoL
335                \xmlsetup{#1}{mml:\mmlapplyaction}
336%                 \MMLdoR
337             }
338%         }
339        \endgroup
340        \advance\mmlapplydepth\minusone
341      }
342\stopxmlsetups
343
344\startxmlsetups mml:apply:mml:apply
345    \xmlflush{#1}
346    \xmlall{#1}{../[position()>1]}
347\stopxmlsetups
348
349\startxmlsetups mml:apply:mml:fn
350    \xmldoifelse {#1} {/mml:fn/mml:ci} {
351        \edef\mmlfnci{\xmlstripped{#1}{/mml:fn/mml:ci}}
352        \doifelsesetups{mmc:fn:\mmlfnci} {
353            \xmlsetup{#1}{mmc:fn:\mmlfnci}
354        } {
355            \MMLcreset
356            \MMLdoL
357            \mmlfirst{#1}
358            \ifnum\xmlcount{#1}{/*}>\plusone
359                \negthinspace % not enough
360                \left(\MMLcreset\xmlconcatrange{#1}{/*}{2}{}{\MMLseparator,}\right)
361            \fi
362            \MMLdoR
363        }
364    } {
365        \MMLcreset
366        \MMLdoL
367        \xmlall{#1}{/*}
368        \MMLdoR
369    }
370\stopxmlsetups
371
372\startxmlsetups mml:apply:mml:csymbol
373    \xmlsetup{#1}{mml:csymbol}% \MMLdoL/MMLdoR to be handled in plugin
374\stopxmlsetups
375
376\startxmlsetups mml:apply:mml:ci
377    \xmlfirst{#1}{/mml:ci}
378    \ifnum\xmlcount{#1}{/*}>\plusone
379       \left(\MMLcreset\xmlconcatrange{#1}{/*}{2}{}{\MMLseparator,}\right)
380    \fi
381\stopxmlsetups
382
383% reln
384
385\startxmlsetups mml:reln
386    \writestatus{XML}{MathML element "reln" is obsolete}
387\stopxmlsetups
388
389% fn
390
391% plusminus ±
392
393\startxmlsetups mmc:fn:\utfchar{"00B1}
394    \MMLdoL
395    \xmlconcat{#1}{/[position()>1]}{\utfchar{"00B1}}
396    \MMLdoR
397\stopxmlsetups
398
399% minusplus
400
401\startxmlsetups mmc:fn:\utfchar{"2213}
402    \MMLdoL
403    \xmlconcat{#1}{/[position()>1]}{\utfchar{"2213}}
404    \MMLdoR
405\stopxmlsetups
406
407\startxmlsetups mmc:fn
408    \begingroup
409        \edef\mmlnoffn{\xmlcount{#1}{/*}}
410        \ifnum\mmlnoffn>\plustwo
411          \def\MMCfnleft {\left(}
412          \def\MMCfnright{\right)}
413        \else
414          \let\MMCfnleft \relax
415          \let\MMCfnright\relax
416        \fi
417        \xmldoifelse {#1} {/mml:ci} {
418            \edef\mmlfnci{\xmltext{#1}{/mml:ci}}
419            \doifelsesetups{mmc:fn:\mmlfnci} {
420                \xmlsetup{#1}{mmc:fn:\mmlfnci}
421            } {
422                \MMLcreset
423                \mmlfirst{#1}
424            }
425        } {
426            \xmldoifelse {#1} {/mml:apply} {
427                \xmldoifelse {#1} {/(mml:plus\string|mml:minus)} {
428                    \left(\mmlfirst{#1}\right)
429                } {
430                    \mmlfirst{#1}
431                }
432                \ifnum\mmlnoffn>\plusone
433                    \left(\xmlall{#1}{/!mml:apply}\right)
434                \fi
435            } {
436                \MMLcreset
437                \negthinspace
438                \MMCfnleft
439                \ifnum\mmlnoffn=\plustwo,\fi
440                \xmlconcat{#1}{/*}{2}{}{\MMLseparator,}
441                \MMCfnright
442            }
443        }
444    \endgroup
445\stopxmlsetups
446
447\startxmlsetups mmc:fn:apply % where used?
448    \xmldoifelse {#1} {/mml:ci} {
449        \edef\mmlfnci{\xmltext{#1}{/mml:ci}}
450        \doifelsesetups{mmc:fn:\mmlfnci} {
451            \xmlsetup{#1}{mmc:fn:\mmlfnci}
452        } {
453            \MMLcreset
454            \mmlfirst{#1}
455            \ifnum\xmlcount{#1}{/*}>\plusone
456                \negthinspace
457                \left(\MMLcreset\xmlconcat{#1}{2}{}{\MMLseparator,}\right)
458            \fi
459        }
460    } {
461        \endgroup
462        \MMLcreset
463        \mmlfirst{#1}
464    }
465\stopxmlsetups
466
467%D The next definition provide a kind of plug-in mechanism (see the open math
468%D extension module).
469
470% http://www.publishers.com/somename
471%
472% called at the lua end
473
474\starttexdefinition mmlapplycsymbol #1#2#3#4
475    % #1=full url, #2=name, #3=encoding, #4=text
476    \doifelse {#3} {text} {
477        \text{#4}
478    } {
479        \doifelsesetups {mml:csymbol:#1} {
480            % full url
481            \fastsetup{mml:csymbol:#1}
482        } {
483            % somename (fallback)
484            \doifelsesetups {mml:csymbol:#2} {
485                \fastsetup{mml:csymbol:#2}
486            } {
487                \xmlval{mmc:cs}{#3}{}% todo
488            }
489        }
490    }
491\stoptexdefinition
492
493\startxmlsetups mml:csymbol
494    \mathml_csymbol{#1}
495\stopxmlsetups
496
497\startxmlsetups mml:csymbol:cdots
498    \cdots
499\stopxmlsetups
500
501% \startxmlsetups mml:csymbol:<url> \stopxmlsetups
502
503%D Alternative b will convert periods into comma's:
504
505\setupMMLappearance[cn]       [\c!alternative=\v!a]
506\setupMMLappearance[polar]    [\c!alternative=\v!a]  % a|b|c
507\setupMMLappearance[float]    [\c!symbol=\v!no]      % \v!yes|dot
508\setupMMLappearance[enotation][\c!symbol=\v!no]      % \v!yes|dot
509\setupMMLappearance[base]     [\c!symbol=\v!numbers] % digits|characters|text|no
510
511\startxmlsetups mml:cs \xmlcommand{#1}{/}{mml:cs:\xmlattdef{#1}{type}{default}} \stopxmlsetups
512\startxmlsetups mml:ci \xmlcommand{#1}{/}{mml:ci:\xmlattdef{#1}{type}{default}} \stopxmlsetups
513\startxmlsetups mml:cn \xmlcommand{#1}{/}{mml:cn:\xmlattdef{#1}{type}{default}} \stopxmlsetups
514
515% helpers cn / todo: \mn{...}
516
517\startxmlsetups mml:cn:default
518    \mathopnolimits{\xmlflush{#1}}
519\stopxmlsetups
520
521% helpers ci
522
523\startxmlsetups mml:ci:default
524    \xmlflush{#1}
525\stopxmlsetups
526
527\startxmlsetups mml:ci:set
528    {\blackboard{\xmlflush{#1}}} % todo
529\stopxmlsetups
530
531\startxmlsetups mml:ci:vector
532    \overrightarrow{\xmlflush{#1}}
533\stopxmlsetups
534
535\startxmlsetups mml:ci:matrix
536    {\bi\xmlflush{#1}}
537\stopxmlsetups
538
539\startxmlsetups mml:ci:function
540    \xmlflush{#1}% \negthinspace
541\stopxmlsetups
542
543\startxmlsetups mml:ci:fn
544    \xmlsetup{#1}{mml:ci:function}
545\stopxmlsetups
546
547\startxmlsetups mml:ci:complex-cartesian
548    \xmlsetup{#1}{mml:cn:complex}
549\stopxmlsetups
550
551\startxmlsetups mml:ci:complex
552    \xmlsetup{#1}{mml:cn:complex}
553\stopxmlsetups
554
555\startxmlsetups mml:ci:complex-polar
556    \xmlsetup{#1}{mml:cn:polar}
557\stopxmlsetups
558
559\startxmlsetups mml:ci:polar
560    \xmlsetup{#1}{mml:cn:polar}
561\stopxmlsetups
562
563% helpers ci
564
565\startxmlsetups mml:cn:default
566    \xmlflush{#1}
567\stopxmlsetups
568
569\startxmlsetups mml:cn:integer
570    \edef\mmlintegerbase{\xmlattdef{#1}{base}{}}
571    \ifx\mmlintegerbase\empty
572        \xmlflush{#1}
573    \else
574        \doifelse \MMLbasesymbol \v!no {
575            \MMLcCNbasedata{\xmlflush{#1}}
576        } {
577            \MMLcCNbasedata{\xmlflush{#1}}\normalsubscript{
578                \hbox {\startimath
579                    \mr
580                    \scriptscriptstyle
581                    \processaction
582                        [\MMLbasesymbol]
583                        [\v!characters=>\MMLcCNbasestring BODH,
584                               \v!text=>\MMLcCNbasestring{BIN}{OCT}{DEC}{HEX},
585                            \s!unknown=>\mmlintegerbase]
586                \stopimath}
587            }
588        }
589    \fi
590\stopxmlsetups
591
592\def\MMLcCNbasedata#1%
593  {\ifnum\mmlintegerbase>10 \relax{\mr#1}\else#1\fi}
594
595\def\MMLcCNbasestring#1#2#3#4%
596  {\ifnum\mmlintegerbase= 2 #1\orelse
597   \ifnum\mmlintegerbase= 8 #2\orelse
598   \ifnum\mmlintegerbase=10 #3\orelse
599   \ifnum\mmlintegerbase=16 #4\else
600         \mmlintegerbase      \fi}
601
602\startxmlsetups mml:cn:polar
603    \xmlsetup{#1}{mml:cn:polar:\MMLpolaralternative}
604\stopxmlsetups
605
606\startxmlsetups mml:cn:polar:a
607    \mathml_cpolar{#1}
608\stopxmlsetups
609
610\startxmlsetups mml:cn:polar:b
611    {\mr e}\normalsuperscript{\xmlsnippet{#1}{1}+\xmlsnippet{#1}{3}\thinspace{\mr i}}
612\stopxmlsetups
613
614\startxmlsetups mml:cn:polar:c
615    \exp\left(\xmlsnippet{#1}{1}+\xmlsnippet{#1}{3}\thinspace{\mr i}\right)
616\stopxmlsetups
617
618\startxmlsetups mml:cn:complex-polar
619    \xmlsetup{#1}{mml:cn:polar}
620\stopxmlsetups
621
622\startxmlsetups mml:cn:complex % todo ( )
623    \left(\xmlsnippet{#1}{1} + \xmlsnippet{#1}{3}\thinspace{\mr i}\right)
624\stopxmlsetups
625
626\startxmlsetups mml:cn:complex-cartesian
627    \xmlsetup{#1}{mml:cn:complex}
628\stopxmlsetups
629
630\startxmlsetups mml:cn:float
631    \doifelse \MMLfloatsymbol \v!no {
632        % make sure that e shows up ok
633        \mathopnolimits{\xmlflush{#1}}
634    } {
635        % we should ignore \entities !
636        \edef\mmlfloatstring{\xmlflush{#1}}
637        \splitstring\mmlfloatstring\at e\to\first\and\last
638        \ifempty\first
639            \mmlfloatstring
640        \orelse\ifempty\last
641            \mmlfloatstring
642        \else
643            \first
644            \doifelse \MMLfloatsymbol {dot} \cdot \times
645            10\normalsuperscript{\last}
646        \fi
647    }
648\stopxmlsetups
649
650\startxmlsetups mml:cn:real
651    \xmlsetup{#1}{mml:cn:float}
652\stopxmlsetups
653
654\startxmlsetups mml:cn:e-notation
655    \doifelse \MMLenotationsymbol \v!no {
656        \xmlsnippet{#1}{1}
657        \unskip\mathopnolimits{e}\ignorespaces
658        \xmlsnippet{#1}{3}
659    } {
660        \xmlsnippet{#1}{1}
661        \doifelse \MMLenotationsymbol {dot} \cdot
662        \times10\normalsuperscript{\xmlsnippet{#1}{3}}
663    }
664\stopxmlsetups
665
666\startxmlsetups mml:cn:logical
667    \mathopnolimits{\xmlflush{#1}}
668\stopxmlsetups
669
670\startxmlsetups mml:cn:rational
671    \xmldoifelse {#1} {/mml:sep} {
672        \mmlfrac
673            {\xmlsnippet{#1}{1}}
674            {\xmlsnippet{#1}{3}}
675    } {
676        \xmlflush{#1}
677    }
678\stopxmlsetups
679
680% interval
681
682\setupMMLappearance[interval][\c!alternative=\v!a,\c!separator={,}]
683
684% when empty element, then it's an apply
685
686\startxmlsetups mml:interval
687    \doifelse {\xmltag{#1}} {apply} {
688        % #1 == apply
689        \let\mmlintervalfirst \mmlsecond
690        \let\mmlintervalsecond\mmlthird
691        \xmlsetup{#1}{mml:interval:\xmlattributedef{#1}{/mml:interval}{closure}{closed}}
692    } {
693        % #1 == interval
694        \let\mmlintervalfirst \mmlfirst
695        \let\mmlintervalsecond\mmlsecond
696        \xmlsetup{#1}{mml:interval:\xmlattdef{#1}{closure}{closed}}
697    }
698\stopxmlsetups
699
700\startxmlsetups mml:interval:closed
701    \left[\mmlintervalfirst{#1}\MMLseparator\MMLintervalseparator\mmlintervalsecond{#1}\right]
702\stopxmlsetups
703
704\startxmlsetups mml:interval:open-closed
705    \doifelse \MMLintervalalternative \v!b {
706        \left<\mmlintervalfirst{#1}\MMLseparator\MMLintervalseparator\mmlintervalsecond{#1}\right]
707     } {
708        \left(\mmlintervalfirst{#1}\MMLseparator\MMLintervalseparator\mmlintervalsecond{#1}\right]
709     }
710\stopxmlsetups
711
712\startxmlsetups mml:interval:closed-open
713    \doifelse \MMLintervalalternative \v!b {
714        \left[\mmlintervalfirst{#1}\MMLseparator\MMLintervalseparator\mmlintervalsecond{#1}\right>
715     } {
716        \left[\mmlintervalfirst{#1}\MMLseparator\MMLintervalseparator\mmlintervalsecond{#1}\right)
717     }
718\stopxmlsetups
719
720\startxmlsetups mml:interval:open
721    \doifelse \MMLintervalalternative \v!b {
722        \left<\mmlintervalfirst{#1}\MMLseparator\MMLintervalseparator\mmlintervalsecond{#1}\right>
723     } {
724        \left(\mmlintervalfirst{#1}\MMLseparator\MMLintervalseparator\mmlintervalsecond{#1}\right)
725     }
726\stopxmlsetups
727
728% inverse
729
730\setfalse\xmlinversefunction
731
732\startxmlsetups mml:apply:inverse
733    \settrue\xmlinversefunction
734    \xmlsetup{#1}{mml:\xmlfilter{#1}{/mml:apply/*[2]/tag()}}
735\stopxmlsetups
736
737% condition
738
739% maybe a fast \xmlnonfirst
740
741% instead of the following we could do \xmlcontent{#1}{/mml:bvar} etc
742
743\startxmlsetups mml:bvar     \xmlflush{#1} \stopxmlsetups
744\startxmlsetups mml:lowlimit \xmlflush{#1} \stopxmlsetups
745\startxmlsetups mml:uplimit  \xmlflush{#1} \stopxmlsetups
746\startxmlsetups mml:degree   \xmlflush{#1} \stopxmlsetups
747\startxmlsetups mml:logbase  \xmlflush{#1} \stopxmlsetups
748\startxmlsetups mml:fn       \xmlflush{#1} \stopxmlsetups
749
750\startxmlsetups mml:condition
751%     \xmldoif {#1} {/mml:bvar} {
752%         \xmlfirst{#1}{/mml:bvar}\mid
753%     }
754    \xmlall{#1}{/!(mml:condition\string|mml:bvar)}
755\stopxmlsetups
756
757% declare
758
759\setupMMLappearance[declare][\c!state=\v!start]
760
761\startxmlsetups mml:declare
762    \doif \MMLdeclarestate \v!start {
763        \mathopnolimits{declare}
764        \mmlfirst{#1}
765        \ifnum\xmlcount{#1}{/*}>\plusone
766            \thickspace
767            \mathopnolimits{as}
768            \thickspace
769        \fi
770        \mmlsecond{#1}
771    }
772\stopxmlsetups
773
774% lambda
775
776\setupMMLappearance[lambda][\c!alternative=b]
777
778\startxmlsetups mml:lambda
779    \begingroup
780    \doifelse \MMLlambdaalternative \v!a {
781        \lambda\left(\xmlconcat{#1}{/!mml:lambda}{\MMLseparator,}\right)
782    } {
783        \ifnum\xmlcount{#1}{/mml:bvar}>\plusone
784            \left(\xmlconcat{#1}{/mml:bvar}{\MMLseparator,}\right)
785        \else
786            \xmlfirst{#1}{/mml:bvar}
787        \fi
788        \mapsto
789        \MMLcreset
790        \xmlall{#1}{/!(mml:bvar|mml:lambda)}
791    }
792    \endgroup
793\stopxmlsetups
794
795% compose
796
797\startxmlsetups mml:compose
798    \begingroup
799    \MMLcreset
800%   \let\MMLcCIfunction\firstofoneargument % brrr ? ? ?
801    \doifelsemmlfunction {#1} {
802       \left(\xmlconcat{#1}{/!mml:compose}{\circ}\right)
803    } {
804       \xmlconcat{#1}{/!mml:compose}{\circ}
805    }
806    \endgroup
807\stopxmlsetups
808
809\startxmlsetups mml:image
810    \mathopnolimits{image} \left( {\mr\xmlfilter{#1}{/!mml:image/tag()}} \right)
811\stopxmlsetups
812
813\setupMMLappearance[piece][\c!separator=]
814
815\startxmlsetups mml:piecewise
816    \processaction
817         [\MMLpieceseparator]
818         [    \v!yes=>\def\theMMLpieceseparator{,&},
819               \v!no=>\def\theMMLpieceseparator{&},
820          \s!default=>\def\theMMLpieceseparator{&},
821          \s!unknown=>\def\theMMLpieceseparator{\,\,\hbox{\MMLpieceseparator}\,\,}]
822    \cases{\xmlflush{#1}}
823\stopxmlsetups
824
825\startxmlsetups mml:piece
826    \mmlfirst{#1}\theMMLpieceseparator\mathematics{\mmlsecond{#1}}\crcr
827\stopxmlsetups
828
829\startxmlsetups mml:otherwise
830%     \xmlflush{#1}\MMLcPIECEseparator&{\mr otherwise}\crcr
831    \xmlflush{#1}&{\mr otherwise}\crcr
832\stopxmlsetups
833
834% end of piece
835
836\startxmlsetups mml:quotient
837    \lfloor\mmlsecond{#1}/\mmlthird{#1}\rfloor
838\stopxmlsetups
839
840\startxmlsetups mml:factorial
841    \xmlall{#1}{/!factorial}!
842\stopxmlsetups
843
844\setupMMLappearance [divide] [\c!level=\!!maxcard,\c!alternative=\v!a]
845
846\newcount\mmldividelevel
847
848\startxmlsetups mml:divide
849    \advance\mmldividelevel\plusone
850    \doifelse \MMLdividealternative \v!b {
851        \mmlsecond{#1}/\mmlthird{#1}
852    } {
853        \ifnum \mmldividelevel > \MMLdividelevel \relax % threshold
854            \mmlsecond{#1}/\mmlthird{#1}
855        \else
856            \MMLcreset
857            \mmlfrac{\MMLcreset\mmlsecond{#1}}{\MMLcreset\mmlthird{#1}}
858        \fi
859    }
860    \advance\mmldividelevel\minusone
861\stopxmlsetups
862
863% min max
864
865\startxmlsetups mml:min \mathopnolimits{min} \xmlsetup{#1}{mml:minmax} \stopxmlsetups
866\startxmlsetups mml:max \mathopnolimits{max} \xmlsetup{#1}{mml:minmax} \stopxmlsetups
867
868\startxmlsetups mml:minmax
869    \xmldoif {#1} {/mml:bvar} {
870        {}\normalsubscript{\xmlfirst{#1}{/mml:bvar}}
871    }
872    \left\{
873    \xmlconcat{#1}{/!(mml:bvar\string|mml:max\string|mml:min)}{\MMLseparator,}
874    \right\}
875\stopxmlsetups
876
877% minus plus
878
879\setupMMLappearance [plus] [\c!alternative=\v!a] % b = no sign -> 3 1/4
880\setupMMLappearance [sign] [\c!reduction=\v!yes]
881
882% alternative b -> geen sign
883
884% branch needed, else (a-b) + (c-d) goes wrong
885% reset check in case of (-x) + 37
886% reset check in case of (-x) + 37
887
888\newcount\mmlpluscounter
889
890\startxmlsetups mml:plus
891    \doifelse \MMLsignreduction \v!yes {
892        \MMLdoL
893        \xmlsetup{#1}{mml:plus:reset}
894        \xmlcommand{#1}{/!mml:plus}{mml:plus:body}
895        \MMLdoR
896    } {
897        \ifnum\xmlcount{#1}{/!mml:plus}=\plusone
898            +\xmlfirst{#1}{/!mml:plus}
899        \else
900            \MMLdoL
901            \xmlconcat{#1}{/!mml:plus}{+}
902            \MMLdoR
903        \fi
904    }
905\stopxmlsetups
906
907\startxmlsetups mml:plus:reset
908    \mmlpluscounter\zerocount
909\stopxmlsetups
910
911\startxmlsetups mml:plus:body
912    \advance\mmlpluscounter\plusone
913    \ifnum\mmlpluscounter>\plusone
914        \xmldoifelse{#1}{/mml:minus} {
915            \ifnum\xmlcount{#1}{/!mml:minus}>\plusone
916                +
917            \fi
918        } {
919            \doifelse {\xmlatt{#1}{type}} {rational} {
920                % fraction
921            } {
922                +
923            }
924        }
925    \fi
926    \xmldirect{#1}
927\stopxmlsetups
928
929\newcount\mmlminuscounter
930
931\startsetups mml:minus
932    \doifelse \MMLsignreduction \v!yes {
933        \ifnum\xmlcount{#1}{/!mml:minus}=\plusone
934            -\xmlfirst{#1}{/!mml:minus}
935        \else
936            \MMLdoL
937            \xmlsetup{#1}{mml:minus:reset}
938            \xmlcommand{#1}{/!mml:minus}{mml:minus:body}
939            \MMLdoR
940        \fi
941    } {
942        \left( % \MMLdoL
943        \ifnum\xmlcount{#1}{/!mml:minus}=\plusone
944            -\xmlfirst{#1}{/!mml:minus}
945        \else
946            \xmlsetup{#1}{mml:minus:reset}
947            \xmlcommand{#1}{/!mml:minus}{mml:minus:body}
948        \fi
949        \right) % \MMLdoR
950    }
951\stopsetups
952
953\startxmlsetups mml:minus:reset
954    \mmlminuscounter\zerocount
955\stopxmlsetups
956
957\startxmlsetups mml:minus:body
958    % we can also use concat here
959    \advance\mmlminuscounter\plusone
960    \ifnum\mmlminuscounter>\plusone
961        -
962    \fi
963    \xmldirect{#1}
964\stopxmlsetups
965
966% power
967
968\setupMMLappearance[power][\c!reduction=\v!yes]
969
970\let\MMLpowerelement\empty
971
972\startxmlsetups mml:power
973    \xmldoifelse {#1} {/mml:apply}  {
974        \doifelse \MMLpowerreduction \v!yes {
975            \xmldoifelse {#1} {/mml:apply/(\MMLcfunctionlist)} {
976                \gdef\MMLpowerelement{\mmlthird{#1}}% postpone, no xdef
977                \MMLcreset\mmlsecond{#1}
978            } {
979                \left(\MMLcreset\mmlsecond{#1}\right)\normalsuperscript{\MMLcreset\mmlthird{#1}}
980            }
981        } {
982            \left(\MMLcreset\mmlsecond{#1}\right)\normalsuperscript{\MMLcreset\mmlthird{#1}}
983        }
984    } {
985        \mmlsecond{#1}\normalsuperscript{\MMLcreset\mmlthird{#1}}
986    }
987\stopxmlsetups
988
989% rem
990
991\startxmlsetups mml:rem
992    \xmlconcat{#1}{/!mml:rem}{\mathopnolimits{mod}}
993\stopxmlsetups
994
995\setupMMLappearance [times] [\c!symbol=\v!no,\c!auto=\v!yes] % new, auto catches cn cn cn
996
997\startxmlsetups mml:times
998    \setMMLcreset{\MMLcfunctionlist\string|\MMLcconstructlist}%
999    \doifelse\MMLtimesauto\v!no {
1000        \let\MMLtimes@@symbol\MMLtimessymbol
1001    } {
1002        \xmldoifelse {#1} {/mml:cn[name(1) == 'mml:cn']} {% name(1) is next one
1003           \doifelseinset\MMLtimessymbol{\v!yes,\v!no} {
1004                \let\MMLtimes@@symbol\v!yes
1005            } {
1006                \let\MMLtimes@@symbol\MMLtimessymbol
1007            }
1008        } {
1009            \let\MMLtimes@@symbol\MMLtimessymbol
1010        }
1011    }
1012    \doifelse\MMLtimes@@symbol\v!yes {
1013        \xmlconcat{#1}{/!mml:times}{\times}
1014    } {
1015        \doifelse\MMLtimes@@symbol{dot} {
1016            \xmlconcat{#1}{/!mml:times}{\cdot}
1017        } {
1018            \doifelse\MMLtimes@@symbol{times} {
1019                \xmlconcat{#1}{/!mml:times}{\times}
1020            } {
1021                \xmlall{#1}{/!mml:times}
1022            }
1023        }
1024    }
1025\stopxmlsetups
1026
1027\setupMMLappearance[root][\c!symbol=\v!yes]
1028
1029\startxmlsetups mml:root
1030    \xmldoifelse {#1} {/mml:degree} {
1031        \root
1032            \doifnot\MMLrootsymbol\v!no{\MMLcreset\xmltext{#1}{/mml:degree}}
1033        \of
1034    } {
1035        \sqrt
1036    }
1037        {\MMLcreset\xmlall{#1}{/!(mml:degree\string|mml:root)}}
1038\stopxmlsetups
1039
1040% gcd
1041
1042\startxmlsetups mml:gcd
1043    \begingroup
1044        \gcd\left(\MMLcreset\xmlconcat{#1}{/!mml:gcd}{\MMLseparator,}\right)
1045    \endgroup
1046\stopxmlsetups
1047
1048% and or xor implies, not
1049
1050\startxmlsetups mml:and          \xmlconcat{#1}{/!mml:and}    {\wedge}               \stopxmlsetups
1051\startxmlsetups mml:or           \xmlconcat{#1}{/!mml:or}     {\vee}                 \stopxmlsetups
1052\startxmlsetups mml:xor          \xmlconcat{#1}{/!mml:xor}    {\mathopnolimits{xor}} \stopxmlsetups
1053\startxmlsetups mml:implies      \xmlconcat{#1}{/!mml:implies}{\Rightarrow}          \stopxmlsetups
1054\startxmlsetups mml:not     \neg \xmlall   {#1}{/!mml:not}                           \stopxmlsetups
1055
1056% forall exists
1057
1058%D We need to shift left below rotated A.
1059
1060\startxmlsetups mml:forall
1061    \forall \negthinspace \xmlsetup{#1}{mml:forallexists}
1062\stopxmlsetups
1063
1064\startxmlsetups mml:exists
1065    \exists \xmlsetup{#1}{mml:forallexists}
1066\stopxmlsetups
1067
1068\def\mmlforallexistslist{mml:bvar\string|mml:forall\string|mml:exists\string|mml:condition}
1069
1070\startxmlsetups mml:forallexists
1071    \normalsubscript{\xmlconcat{#1}{/mml:bvar}{\MMLseparator,}}
1072    \xmldoifelse {#1} {/mml:condition} {
1073        \thickspace
1074        \begingroup
1075            \xmlfirst{#1}{/mml:condition}
1076        \endgroup
1077        \ifcase\xmlcount{#1}{/!(\mmlforallexistslist)}\relax
1078            % nothing
1079        \or
1080            % == snelle volgende
1081            \left\vert
1082                \MMLcreset \medspace \xmlconcat{#1}{/!(\mmlforallexistslist)}{}
1083            \right.
1084        \else
1085            % special case
1086            \left\vert
1087                \matrix {
1088                    \xmlconcat{#1}{/!(\mmlforallexistslist)}{\hfill\crcr}
1089                }
1090            \right.
1091        \fi
1092    } {
1093        :\xmlfirst{#1}{/!(\mmlforallexistslist)}
1094    }
1095\stopxmlsetups
1096
1097\startxmlsetups mml:abs
1098    \left\vert \MMLcreset\xmlall{#1}{/!mml:abs} \right\vert
1099\stopxmlsetups
1100
1101\startxmlsetups mml:conjugate % watch extra {}
1102    {\overline{\MMLcreset\xmlall{#1}{/!mml:conjugate}}}
1103\stopxmlsetups
1104
1105\startxmlsetups mml:arg
1106    \mathopnolimits{arg} \left( \MMLcreset\xmlall{#1}{/!mml:arg} \right)
1107\stopxmlsetups
1108
1109\startxmlsetups mml:real
1110    \Re \left( \MMLcreset \xmlall{#1}{/!mml:real} \right)
1111\stopxmlsetups
1112
1113\startxmlsetups mml:imaginary
1114    \Im \ left( \MMLcreset \xmlall{#1}{/!mml:imaginary} \right)
1115\stopxmlsetups
1116
1117\startxmlsetups mml:lcm
1118    \mathopnolimits{lcm} \left( \xmlconcat{#1}{/!mml:lcm}{\MMLseparator,} \right)
1119\stopxmlsetups
1120
1121\startxmlsetups mml:floor
1122    \lfloor \xmlall{#1}{/!mml:floor} \rfloor
1123\stopxmlsetups
1124
1125\startxmlsetups mml:ceiling
1126    \lceiling \xmlall{#1}{/!mml:ceiling} \rceiling
1127\stopxmlsetups
1128
1129% relations
1130
1131% apply attr or eq
1132
1133\setupMMLappearance[relation][\c!align=\v!no]
1134
1135\xmlmapvalue {mml:relation} {eq}         {=}
1136\xmlmapvalue {mml:relation} {neq}        {\neq}
1137\xmlmapvalue {mml:relation} {gt}         {>}
1138\xmlmapvalue {mml:relation} {lt}         {<}
1139\xmlmapvalue {mml:relation} {geq}        {\geq}
1140\xmlmapvalue {mml:relation} {leq}        {\leq}
1141\xmlmapvalue {mml:relation} {equivalent} {\equiv}
1142\xmlmapvalue {mml:relation} {approx}     {\approx}
1143\xmlmapvalue {mml:relation} {factorof}   {\mid}
1144
1145\startxmlsetups mml:eq         \xmlsetup{#1}{mml:relation} \stopxmlsetups
1146\startxmlsetups mml:neq        \xmlsetup{#1}{mml:relation} \stopxmlsetups
1147\startxmlsetups mml:gt         \xmlsetup{#1}{mml:relation} \stopxmlsetups
1148\startxmlsetups mml:lt         \xmlsetup{#1}{mml:relation} \stopxmlsetups
1149\startxmlsetups mml:geq        \xmlsetup{#1}{mml:relation} \stopxmlsetups
1150\startxmlsetups mml:leq        \xmlsetup{#1}{mml:relation} \stopxmlsetups
1151\startxmlsetups mml:equivalent \xmlsetup{#1}{mml:relation} \stopxmlsetups
1152\startxmlsetups mml:approx     \xmlsetup{#1}{mml:relation} \stopxmlsetups
1153\startxmlsetups mml:factorof   \xmlsetup{#1}{mml:relation} \stopxmlsetups
1154
1155\startxmlsetups mml:relation
1156    \edef\mmlapplyaction{\xmlfilter{#1}{/*/tag()}}
1157    \MMLcreset \xmlsetup{#1}{mml:relation:\xmlattdef{#1}{align}{\MMLrelationalign}}
1158\stopxmlsetups
1159
1160\startxmlsetups mml:relation:default
1161    \xmlconcatrange{#1}{/*}{2}{}{\xmlval{mml:relation}{\mmlapplyaction}{[\mmlapplyaction]}}
1162\stopxmlsetups
1163\startxmlsetups mml:relation:last
1164    \eqalign {
1165        \xmlconcatrange{#1}{/*}{2}{-2}{&\xmlval{mml:relation}{\mmlapplyaction}{[\mmlapplyaction]}\crcr}
1166        \mmlprelast{#1}&\xmlval{mml:relation}{\mmlapplyaction}{[\mmlapplyaction]}{}\mmllast{#1}
1167    }
1168\stopxmlsetups
1169\startxmlsetups mml:relation:first
1170    \eqalign {
1171        \mmlsecond{#1}\xmlval{mml:relation}{\mmlapplyaction}{[\mmlapplyaction]}{}
1172        &\xmlconcatrange{#1}{/*}{3}{}{\crcr\xmlval{mml:relation}{\mmlapplyaction}{[\mmlapplyaction]}{}&}
1173    }
1174\stopxmlsetups
1175\startxmlsetups mml:relation:left
1176    \eqalign {
1177        \xmlconcatrange{#1}{/*}{2}{}{&\xmlval{mml:relation}{\mmlapplyaction}{[\mmlapplyaction]}\crcr}
1178    }
1179\stopxmlsetups
1180\startxmlsetups mml:relation:right
1181    \eqalign {
1182        &\xmlconcatrange{#1}{/*}{2}{}{\crcr\xmlval{mml:relation}{\mmlapplyaction}{[\mmlapplyaction]}{}&}
1183    }
1184\stopxmlsetups
1185\startxmlsetups mml:relation:no
1186    \xmlsetup{#1}{mml:relation:default}
1187\stopxmlsetups
1188\startxmlsetups mml:relation:yes
1189    \xmlsetup{#1}{mml:relation:left}
1190\stopxmlsetups
1191
1192% personal goody:
1193
1194\edef\MMLcmainresetlist{\MMLcmainresetlist\string|becomes}
1195
1196\xmlmapvalue {mml:relation} {mml:becomes} {:=}
1197
1198\startxmlsetups mml:becomes \xmlsetup{#1}{mml:relation} \stopxmlsetups
1199
1200% calculus and vector calculus
1201
1202\startxmlsetups mml:domainofapplication
1203    \xmlall{#1}{/!mml:domainofapplication}
1204\stopxmlsetups
1205
1206\setupMMLappearance[int][\c!location=\v!top]
1207
1208\def\doMMLlimits#1{\doifelsevalue{MML#1\c!location}\v!top\limits\nolimits}
1209
1210\startxmlsetups mml:int
1211    \MMLcreset
1212    \xmldoifelse {#1} {/mml:domainofapplication} {
1213        \int \doMMLlimits{int}\normalsubscript{\xmlfirst{#1}{/mml:domainofapplication}}\relax
1214    } {
1215        \xmldoifelse {#1} {/mml:condition} {
1216            \int \doMMLlimits{int}\normalsubscript{\xmlfirst{#1}{/mml:condition}}\relax
1217        } {
1218            \xmldoifelse {#1} {/mml:lowlimit} {
1219                \int \doMMLlimits{int}\normalsubscript{\xmlfirst{#1}{/mml:lowlimit}}\normalsuperscript{\xmlfirst{#1}{/mml:uplimit}}
1220            } {
1221                % funny, why do we have lowlimit/uplimit then
1222                \xmldoifelse {#1} {/mml:apply/mml:interval} {
1223                    \int \doMMLlimits{int}\normalsubscript{\xmlindex{#1}{/mml:apply}{2}}\normalsuperscript{\xmlindex{#1}{/mml:apply}{3}}
1224                } {
1225                    \int
1226                }
1227            }
1228        }
1229    }
1230    \MMLcreset
1231    \xmldoifelse {#1} {/mml:apply} {
1232        \doifelsemmlfunction {#1} { % todo test
1233            \xmlfirst{#1}{/mml:apply}
1234        } {
1235            % if there are too many () now, we need to be more clever
1236            \left( \xmlfirst{#1}{/mml:apply} \right)
1237        }
1238    } {
1239        \xmlfirst{#1}{/mml:ci}
1240    }
1241    \xmldoifelse {#1} {/mml:bvar} {
1242        \thinspace {\mr d} \xmlfirst{#1}{/mml:bvar}
1243    } {
1244        % nothing
1245    }
1246\stopxmlsetups
1247
1248\setupMMLappearance[diff][\c!location=\v!top,\c!alternative=\v!a]
1249
1250\startxmlsetups mml:diff
1251   \MMLcreset
1252   \doifelse \MMLdiffalternative \v!a {
1253        \xmldoifelse {#1} {/mml:lambda} {
1254            % a special case (mathadore/openmath)
1255            \mmlfrac {
1256                d
1257                \normalsuperscript
1258                {\xmlfirst{#1}{/mml:bvar}\xmlfirst{#1}{/mml:cn}}
1259                {\xmlfirst{#1}{/mml:lambda}\xmlfirst{#1}{/mml:ci}}
1260            } {
1261                d
1262                {\xmlfirst{#1}{/mml:bvar}\xmlfirst{#1}{/mml:ci}}
1263                \normalsuperscript
1264                {\xmlfirst{#1}{/mml:bvar}\xmlfirst{#1}{/mml:cn}}
1265            }
1266        } {
1267            \xmldoifelse {#1} {/mml:bvar} {
1268                \mmlfrac {
1269                    {\mr d}{
1270                        \xmldoifelse {#1} {/mml:degree} {
1271                            \normalsuperscript{\xmlconcat{#1}{/mml:degree}\empty}
1272                        } {
1273                            \xmldoif {#1} {/mml:bvar/mml:degree} {
1274                                \normalsuperscript{\xmlconcat{#1}{/mml:bvar/mml:degree}+}
1275                            }
1276                        }
1277                    }
1278                    \doif \MMLdifflocation \v!top {
1279                        \xmldoifelse {#1} {/mml:ci} {
1280                            \xmlfirst{#1}{/mml:ci}
1281                        } {
1282                            \MMLcreset
1283                            \ifnum\xmlcount{#1}{/mml:apply/*}>\plustwo % hack
1284                                \left(\xmlfirst{#1}{/mml:apply}\right)
1285                            \else
1286                                \xmlfirst{#1}{/mml:apply}
1287                            \fi
1288                        }
1289                    }
1290                } {
1291                    {\mr d}
1292                    \xmlfirst{#1}{/mml:bvar/!mml:degree}
1293                    \xmldoif {#1} {/mml:bvar/mml:degree} {
1294                        \normalsuperscript{\xmlfirst{#1}{/mml:bvar/mml:degree}}
1295                    }
1296                }
1297                \doifnot \MMLdifflocation \v!top {
1298                    \left(\MMLcreset\xmlfirst{#1}{/(mml:apply\string|mml:ci)}\right)
1299                }
1300            } {
1301                % beware, the second {} is needed for the superscript
1302                \xmlconcatrange{#1}{/*}{2}{}{}\normalsuperscript\prime
1303            }
1304        }
1305    } {
1306        \MMLcreset
1307        \xmlfirst{#1}{/(mml:apply\string|mml:ci)}
1308        % there can be problems with nested diff's: \normalsuperscript\normalsuperscript{} error
1309        % so we add an empty group here
1310        {}\normalsuperscript
1311        {
1312            \xmldoifelse {#1} {/mml:degree} {
1313                \edef\mmldegree{\xmlfirst{#1}{/mml:degree/mml:cn}}
1314                \ifempty\mmldegree
1315                    % what to do here
1316                \else
1317                    \dorecurse\mmldegree\prime
1318                \fi
1319            } {
1320                \prime
1321            }
1322        }
1323    }
1324\stopxmlsetups
1325
1326\startxmlsetups mml:partialdiff
1327    \xmldoifelse {#1} {/mml:list} {
1328        {\mr D}\normalsubscript{
1329            \begingroup
1330                \setfalse\mmllistdelimiters
1331                \xmlall{#1}{/mml:list}
1332            \endgroup
1333        }
1334        \xmlfirst{#1}{/(mml:apply\string|mml:reln\string|mml:ci\string|mml:cn)}
1335    } {
1336        \xmldoifelse {#1} {/mml:bvar} {
1337            \mmlfrac {
1338                {\mr d}\normalsuperscript{
1339                    \xmldoifelse {#1} {/mml:degree} {
1340                        \xmlconcat{#1}{/mml:degree}\empty
1341                    } {
1342                        \xmlconcat{#1}{/mml:bvar/mml:degree}+
1343                    }
1344                }
1345                \MMLcreset
1346                \xmlfirst{#1}{/(mml:apply\string|mml:reln\string|mml:ci\string|mml:cn)}
1347            } {
1348                \xmldoif {#1}{/mml:bvar/!mml:degree} {
1349                    \xmlfirst{#1}{/mml:bvar/!mml:degree} \,
1350                }
1351                {\mr d}\xmlfirst{#1}{/(mml:apply\string|mml:reln\string|mml:ci\string|mml:cn)}
1352                \xmldoif {#1} {/mml:bvar/mml:degree} {
1353                    \normalsuperscript{\xmlfirst{#1}{/mml:bvar/mml:degree}}
1354                }
1355            }
1356        } {
1357            \xmlfirst{#1}{/(mml:apply\string|mml:reln\string|mml:ci\string|mml:cn)}
1358        }
1359    }
1360\stopxmlsetups
1361
1362\startxmlsetups mml:divergence \mathopnolimits{div}      \xmlall{#1}{/!mml:divergence} \stopxmlsetups
1363\startxmlsetups mml:grad       \mathopnolimits{grad}     \xmlall{#1}{/!mml:grad}       \stopxmlsetups
1364\startxmlsetups mml:curl       \mathopnolimits{curl}     \xmlall{#1}{/!mml:curl}       \stopxmlsetups
1365\startxmlsetups mml:laplacian  \nabla\normalsuperscript2 \xmlall{#1}{/!mml:laplacian}  \stopxmlsetups
1366\startxmlsetups mml:ident      \mathopnolimits{identity} \xmlall{#1}{/!mml:ident}      \stopxmlsetups
1367
1368\setupMMLappearance[domain]  [symbol=]
1369\setupMMLappearance[codomain][symbol=]
1370
1371\startxmlsetups mml:domain
1372    \doifelsenothing \MMLdomainsymbol {
1373        \mathopnolimits{domain}\MMLcreset\xmlall{#1}{/!mml:domain}
1374    } {
1375        \MMLdomainsymbol\normalsubscript{\xmlall{#1}{/!mml:domain}}
1376    }
1377\stopxmlsetups
1378
1379\startxmlsetups mml:codomain
1380    \doifelsenothing \MMLcodomainsymbol {
1381        \mathopnolimits{codomain}\MMLcreset\xmlall{#1}{/!mml:codomain}
1382    } {
1383        \MMLcodomainsymbol\normalsubscript{\xmlall{#1}{/!mml:codomain}}
1384    }
1385\stopxmlsetups
1386
1387% theory of sets
1388
1389\startxmlsetups mml:set
1390    \left\{
1391    \xmldoifelse {#1} {/mml:condition} {
1392        \xmlfirst{#1}{/mml:bvar}\,\middle\vert\,\xmlfirst{#1}{/mml:condition}
1393    } {
1394        \xmlconcat{#1}{/!mml:set}{\MMLseparator,}
1395    }
1396    \right\}
1397    \relax % needed
1398\stopxmlsetups
1399
1400\settrue\mmllistdelimiters
1401
1402\startxmlsetups mml:list
1403    \begingroup
1404        \ifconditional\mmllistdelimiters\left [\fi
1405        \begingroup
1406            \settrue\mmllistdelimiters
1407            \xmlconcat{#1}{/!mml:list}{\MMLseparator,}
1408        \endgroup
1409        \ifconditional\mmllistdelimiters\right]\fi
1410    \endgroup
1411\stopxmlsetups
1412
1413\startxmlsetups mml:union       \mmlsecond{#1} \cup            \mmlthird{#1} \stopxmlsetups
1414\startxmlsetups mml:intersect   \mmlsecond{#1} \cap            \mmlthird{#1} \stopxmlsetups
1415\startxmlsetups mml:in          \mmlsecond{#1} \in             \mmlthird{#1} \stopxmlsetups
1416\startxmlsetups mml:notin       \mmlsecond{#1} {\not\in}       \mmlthird{#1} \stopxmlsetups
1417\startxmlsetups mml:subset      \mmlsecond{#1} \subset         \mmlthird{#1} \stopxmlsetups
1418\startxmlsetups mml:prsubset    \mmlsecond{#1} \subseteq       \mmlthird{#1} \stopxmlsetups
1419\startxmlsetups mml:notsubset   \mmlsecond{#1} {\not\subset}   \mmlthird{#1} \stopxmlsetups
1420\startxmlsetups mml:notprsubset \mmlsecond{#1} {\not\subseteq} \mmlthird{#1} \stopxmlsetups
1421\startxmlsetups mml:setdiff     \mmlsecond{#1} \setminus       \mmlthird{#1} \stopxmlsetups
1422
1423\startxmlsetups mml:card
1424    \left\vert \xmlall{#1}{/!mml:card} \right\vert
1425\stopxmlsetups
1426
1427\startxmlsetups mml:cartesianproduct
1428    \xmlconcat{#1}{/!mml:cartesianproduct}{\times}
1429\stopxmlsetups
1430
1431% sequences and series
1432
1433\setupMMLappearance[sum]    [\c!location=\v!top]
1434\setupMMLappearance[product][\c!location=\v!top]
1435
1436\xmlmapvalue {mml:sumprod} {sum}     {\sum}
1437\xmlmapvalue {mml:sumprod} {product} {\prod}
1438
1439\startxmlsetups mml:sum     \edef\mmlsumprodname{sum}     \xmlsetup{#1}{mml:sumprod} \stopxmlsetups
1440\startxmlsetups mml:product \edef\mmlsumprodname{product} \xmlsetup{#1}{mml:sumprod} \stopxmlsetups
1441
1442\def\mmlstackedsubscripts#1%
1443  {\vbox
1444     {\baselineskip\zeropoint % hack, taco vragen
1445      \halign{\startimath\scriptstyle\hss\alignmark\alignmark\hss\stopimath\cr#1\crcr}}}
1446
1447% unfinished
1448
1449\startxmlsetups mml:sumprod
1450    \begingroup
1451    \xmldoifelse {#1} {/(mml:condition\string|mml:bvar\string|mml:lowlimit)} {
1452        \def\mmlsumprodlower{
1453            \normalsubscript{
1454                \xmldoifelse {#1} {/mml:condition} {
1455                    \mmlstackedsubscripts{\xmlconcat{#1}{/mml:condition}{\crcr}}
1456                } {
1457                    \xmldoif {#1} {/mml:bvar} {
1458                        \xmlfirst{#1}{/mml:bvar}
1459                        \xmldoif{#1}{/mml:lowlimit}{=}
1460                    }
1461                    \xmlfirst{#1}{/mml:lowlimit}
1462                }
1463            }
1464        }
1465    } {
1466        \let\mmlsumprodlower\empty
1467    }
1468    \xmldoifelse {#1} {/mml:uplimit} {
1469        \def\mmlsumprodupper{\normalsuperscript{\xmlfirst{#1}{/mml:uplimit}}}
1470    } {
1471        \let\mmlsumprodupper\empty
1472    }
1473   \xmldoif {#1} {/mml:interval} { % open math converter gives this
1474        \edef\mmlintervalfrom{\xmlindex{#1}{/mml:interval}{1}}
1475        \edef\mmlintervalto  {\xmlindex{#1}{/mml:interval}{2}}
1476        \ifempty\mmlintervalfrom  \else
1477            \def\mmlsumprodlower{\normalsubscript{\xmldoif{#1}{/mml:bvar}{\xmlfirst{#1}{/mml:bvar}{=}}\mmlintervalfrom}}
1478        \fi
1479        \ifempty\mmlintervalto \else
1480            \def\mmlsumprodupper{\normalsuperscript{\mmlintervalto}}
1481        \fi
1482    }
1483    \MMLcreset
1484    \xmlval{mml:sumprod}{\mmlsumprodname}{}\doMMLlimits\mmlsumprodname\mmlsumprodupper\mmlsumprodlower
1485    \MMLcreset
1486    \xmldoifelse {#1} {/mml:lambda/mml:apply} {
1487        \xmlfirst{#1}{/mml:lambda/mml:apply}% a bit of open math conversion mess
1488    } {
1489        \xmlfirst{#1}{/(mml:apply\string|mml:lambda\string|mml:ci)}%
1490    }
1491    \endgroup
1492\stopxmlsetups
1493
1494\setupMMLappearance[limit][\c!location=\v!top]
1495
1496\startxmlsetups mml:limit
1497    \MMLcreset \lim
1498    \doMMLlimits {limit}\normalsubscript{
1499        \MMLcreset
1500        \xmldoifelse {#1} {/mml:condition} {
1501            \xmlfirst{#1}{/mml:condition}
1502        } {
1503            \xmldoif {#1} {/mml:bvar} {
1504                \xmlfirst{#1}{/mml:bvar}\rightarrow
1505            }
1506            \xmlfirst{#1}{/mml:lowlimit}
1507        }
1508    }
1509    \begingroup
1510        % a bit of open math conversion mess, lambda needed for openmath, ok?
1511        \MMLcreset
1512        \xmlfirst{#1}{/mml:lambda/mml:apply}
1513        \xmlfirst{#1}{/(mml:apply\string|mml:lambda)}
1514    \endgroup
1515\stopxmlsetups
1516
1517% consider a faster index
1518
1519\startxmlsetups mml:tendsto
1520    \MMLcreset \mmlsecond{#1}
1521    \xmlval {mml:tendsto:type} {\xmlattdef{#1}{type}{default}} {\rightarrow}
1522    \MMLcreset \mmlthird{#1}
1523\stopxmlsetups
1524
1525\xmlmapvalue {mml:tendsto:type} {above}   {\downarrow}
1526\xmlmapvalue {mml:tendsto:type} {below}   {\uparrow}
1527\xmlmapvalue {mml:tendsto:type} {default} {\rightarrow}
1528
1529% elementary classical functions
1530
1531\setupMMLappearance[log][\c!location=\v!right]
1532
1533\startxmlsetups mml:exp
1534%   {\mr e}\normalsuperscript{\xmlfirst{#1}{/mml:apply\string|mml:reln\string|mml:ci\string|mml:cn}}
1535    {\mr e}\normalsuperscript{\xmlfirst{#1}{/!mml:exp}}
1536\stopxmlsetups
1537
1538\startxmlsetups mml:log
1539   \xmldoifelse {#1} {/mml:logbase} {
1540        \doifelse \MMLloglocation \v!left {
1541            \mathop {
1542                {}\normalsuperscript{\xmlfirst{#1}{/mml:logbase}}\negthinspace\mathopnolimits{log}
1543            }
1544        } {
1545            \mathopnolimits{log}\normalsubscript{\xmlfirst{#1}{/mml:logbase}}
1546        }
1547%         \MMLcreset
1548        \xmlfirst{#1}{/(mml:apply\string|mml:reln\string|mml:ci\string|mml:cn)}
1549%         \xmlsetup{#1}{mml:function} % todo, we start elsewhere
1550%         \mmlthird{#1}
1551    } {
1552        \mathopnolimits{log}
1553%         \MMLcreset
1554%         \xmlsetup{#1}{mml:function} % todo, we start elsewhere
1555            \xmlfirst{#1}{/(mml:apply\string|mml:reln\string|mml:ci\string|mml:cn)}
1556%         \mmlsecond{#1}
1557    }
1558\stopxmlsetups
1559
1560\startxmlsetups mml:ln
1561    \mathopnolimits{ln}
1562    \xmlsetup{#1}{mml:function}
1563\stopxmlsetups
1564
1565% statistics
1566
1567\startxmlsetups mml:mean     \overline                             {\mmlsecond{#1}}                          \stopxmlsetups
1568\startxmlsetups mml:sdev     \sigma                 \left(\MMLcreset\mmlsecond{#1}\right)                    \stopxmlsetups
1569\startxmlsetups mml:variance \sigma                 \left(\MMLcreset\mmlsecond{#1}\right)\normalsuperscript2 \stopxmlsetups
1570\startxmlsetups mml:median   \mathopnolimits{median}\left(\MMLcreset\mmlsecond{#1}\right)                    \stopxmlsetups
1571\startxmlsetups mml:mode     \mathopnolimits{mode}  \left(\MMLcreset\mmlsecond{#1}\right)                    \stopxmlsetups
1572
1573% moments
1574
1575\startxmlsetups mml:moment
1576    \left\langle
1577        \xmlfirst{#1}{/(mml:apply\string|mml:reln\string|mml:ci\string|mml:cn)}\normalsuperscript{\xmlfirst{#1}{/mml:degree}}
1578    \right\rangle
1579    \xmldoif {#1} {mml:momentabout} {
1580        \normalsubscript{\xmlfirst{#1}{mml:momentabout}}
1581    }
1582\stopxmlsetups
1583
1584% linear algebra
1585
1586\setupMMLappearance [vector] [\c!direction=\v!horizontal,\c!separator={,}]
1587
1588\startxmlsetups mml:vector
1589    \begingroup
1590    \ifnum\xmlcount{#1}{/*}>\plusone
1591        \doifelse\MMLvectordirection\v!horizontal {
1592            \left(\xmlconcat{#1}{/*}{\MMLseparator\MMLvectorseparator}\right)
1593        } {
1594            \MMLcreset\left(\matrix{\xmlconcat{#1}{/*}{\MMLseparator\MMLvectorseparator}}\right)
1595        }
1596    \else
1597      \overrightarrow{\charhtstrut\mmlfirst{#1}}
1598    \fi
1599    \endgroup
1600\stopxmlsetups
1601
1602\settrue\MMCdelmatrix % ( ) when true
1603
1604\startxmlsetups mml:matrix
1605    \begingroup
1606    \MMLcreset
1607    \ifconditional\MMCdelmatrix
1608        \left(\matrix{\xmlcommand{#1}{/mml:matrixrow}{mml:matrixrow:do}}\right)
1609    \else
1610        \settrue\MMCdelmatrix
1611        \matrix{\xmlcommand{#1}{/mml:matrixrow}{mml:matrixrow:do}}
1612    \fi
1613    \endgroup
1614\stopxmlsetups
1615
1616\startxmlsetups mml:matrixrow
1617    \begingroup
1618    \MMLcreset
1619    \left(\xmlsetup{#1}{mml:matrixrow:do}\right)
1620    \endgroup
1621\stopxmlsetups
1622
1623\startxmlsetups mml:matrixrow:do
1624    \xmlconcat{#1}{/*}{&}\crcr
1625\stopxmlsetups
1626
1627\startxmlsetups mml:determinant
1628    \begingroup
1629    \setfalse\MMCdelmatrix
1630    \left|\mmlsecond{#1}\right|
1631    \endgroup
1632\stopxmlsetups
1633
1634\startxmlsetups mml:transpose
1635    \mmlsecond{#1}\normalsuperscript{\mathopnolimits{T}}
1636\stopxmlsetups
1637
1638\startxmlsetups mml:selector
1639    \MMLmathinner{\mmlsecond{#1}\normalsubscript{\MMLcreset\xmlconcatrange{#1}{/*}{3}{}{\MMLseparator,}}}
1640\stopxmlsetups
1641
1642\startxmlsetups mml:vectorproduct \mmlsecond{#1}\times \mmlthird{#1} \stopxmlsetups
1643\startxmlsetups mml:scalarproduct \mmlsecond{#1}\cdot  \mmlthird{#1} \stopxmlsetups
1644\startxmlsetups mml:outerproduct  \mmlsecond{#1}\otimes\mmlthird{#1} \stopxmlsetups
1645
1646% semantic mapping elements
1647
1648\setupMMLappearance[semantics][\c!state=\v!start]
1649
1650\startxmlsetups mml:semantics
1651    \doifelse\MMLsemanticsstate\v!start {
1652        \xmlall{#1}{/mml:annotation}
1653    } {
1654        \xmlall{#1}{/!mml:annotation}
1655    }
1656\stopxmlsetups
1657
1658\startxmlsetups mml:annotation
1659    \xmldoifelse {#1} {.[oneof(@encoding,'TeX','tex','application/x-tex','TEX','ConTeXt','context','CONTEXT','ctx')]} {
1660        \xmlflushcontext{#1}
1661    } {
1662        \xmldoifelse {#1} {.[oneof(@encoding,'calcmath','cm')]} {
1663            \expanded{\calcmath{\xmlflush{#1}}}
1664        } {
1665            \xmldoifelse {#1} {.[oneof(@encoding,'asciimath','am')]} {
1666                \ifdefined\asciimath
1667                    \expanded{\asciimath{\xmlflushpure{#1}}}
1668                \else
1669                    \hbox{\tt no am loaded}
1670                \fi
1671            } {
1672                \xmlall{#1}{../!mml:annotation}
1673            }
1674        }
1675    }
1676\stopxmlsetups
1677
1678\startxmlsetups mml:annotation-xml
1679    % maybe diagnostics
1680\stopxmlsetups
1681
1682% misc
1683
1684\startxmlsetups mml:integers       \integers              \stopxmlsetups
1685\startxmlsetups mml:reals          \reals                 \stopxmlsetups
1686\startxmlsetups mml:rationals      \rationals             \stopxmlsetups
1687\startxmlsetups mml:naturalnumbers \naturalnumbers        \stopxmlsetups
1688\startxmlsetups mml:complexes      \complexes             \stopxmlsetups
1689\startxmlsetups mml:primes         \primes                \stopxmlsetups
1690\startxmlsetups mml:exponentiale   \mathopnolimits{e}     \stopxmlsetups
1691\startxmlsetups mml:imaginaryi     \mathopnolimits{i}     \stopxmlsetups
1692\startxmlsetups mml:notanumber     \mathopnolimits{NaN}   \stopxmlsetups
1693\startxmlsetups mml:true           \mathopnolimits{true}  \stopxmlsetups
1694\startxmlsetups mml:false          \mathopnolimits{false} \stopxmlsetups
1695\startxmlsetups mml:emptyset       \mathopnolimits{Ø}     \stopxmlsetups
1696\startxmlsetups mml:pi             \pi                    \stopxmlsetups
1697\startxmlsetups mml:eulergamma     \gamma                 \stopxmlsetups
1698\startxmlsetups mml:infinity       \infty                 \stopxmlsetups
1699
1700% gonio functions
1701
1702\setupMMLappearance[function][\c!reduction=\v!yes]
1703
1704% todo: \mfunction which adapts itself when registered as command
1705
1706% todo: \def\mmlcfunction#1#2{\mathopnolimits{#2}\xmlsetup{#1}{mml:function}}
1707
1708\startxmlsetups  mml:sin     \mathcommand    {sin}\xmlsetup{#1}{mml:function} \stopxmlsetups
1709\startxmlsetups  mml:sinh    \mathcommand   {sinh}\xmlsetup{#1}{mml:function} \stopxmlsetups
1710\startxmlsetups  mml:cos     \mathcommand    {cos}\xmlsetup{#1}{mml:function} \stopxmlsetups
1711\startxmlsetups  mml:cosh    \mathcommand   {cosh}\xmlsetup{#1}{mml:function} \stopxmlsetups
1712\startxmlsetups  mml:tan     \mathcommand    {tan}\xmlsetup{#1}{mml:function} \stopxmlsetups
1713\startxmlsetups  mml:tanh    \mathcommand   {tanh}\xmlsetup{#1}{mml:function} \stopxmlsetups
1714\startxmlsetups  mml:cot     \mathcommand    {cot}\xmlsetup{#1}{mml:function} \stopxmlsetups
1715\startxmlsetups  mml:coth    \mathcommand   {coth}\xmlsetup{#1}{mml:function} \stopxmlsetups
1716\startxmlsetups  mml:csc     \mathcommand    {csc}\xmlsetup{#1}{mml:function} \stopxmlsetups
1717\startxmlsetups  mml:csch    \mathcommand   {csch}\xmlsetup{#1}{mml:function} \stopxmlsetups
1718\startxmlsetups  mml:sec     \mathcommand    {sec}\xmlsetup{#1}{mml:function} \stopxmlsetups
1719\startxmlsetups  mml:sech    \mathcommand   {sech}\xmlsetup{#1}{mml:function} \stopxmlsetups
1720
1721\startxmlsetups  mml:arcsin  \mathcommand {arcsin}\xmlsetup{#1}{mml:function} \stopxmlsetups
1722\startxmlsetups  mml:arcsinh \mathcommand{arcsinh}\xmlsetup{#1}{mml:function} \stopxmlsetups
1723\startxmlsetups  mml:arccos  \mathcommand {arccos}\xmlsetup{#1}{mml:function} \stopxmlsetups
1724\startxmlsetups  mml:arccosh \mathcommand{arccosh}\xmlsetup{#1}{mml:function} \stopxmlsetups
1725\startxmlsetups  mml:arctan  \mathcommand {arctan}\xmlsetup{#1}{mml:function} \stopxmlsetups
1726\startxmlsetups  mml:arctanh \mathcommand{arctanh}\xmlsetup{#1}{mml:function} \stopxmlsetups
1727\startxmlsetups  mml:arccot  \mathcommand {arccot}\xmlsetup{#1}{mml:function} \stopxmlsetups
1728\startxmlsetups  mml:arccoth \mathcommand{arccoth}\xmlsetup{#1}{mml:function} \stopxmlsetups
1729\startxmlsetups  mml:arccsc  \mathcommand {arccsc}\xmlsetup{#1}{mml:function} \stopxmlsetups
1730\startxmlsetups  mml:arccsch \mathcommand{arccsch}\xmlsetup{#1}{mml:function} \stopxmlsetups
1731\startxmlsetups  mml:arcsec  \mathcommand {arcsec}\xmlsetup{#1}{mml:function} \stopxmlsetups
1732\startxmlsetups  mml:arcsech \mathcommand{arcsech}\xmlsetup{#1}{mml:function} \stopxmlsetups
1733
1734\startxmlsetups mml:function
1735    \ifempty\MMLpowerelement
1736        \ifconditional\xmlinversefunction\normalsuperscript{-1}\fi
1737        \setfalse\xmlinversefunction
1738    \else
1739        \normalsuperscript{\ifconditional\xmlinversefunction-\fi\MMLpowerelement}
1740        \setfalse\xmlinversefunction
1741        \glet\MMLpowerelement\empty
1742    \fi
1743    \xmlsetup{#1}{mml:function:argument}
1744\stopxmlsetups
1745
1746\startxmlsetups mml:function:argument
1747    \doifelse \MMLfunctionreduction \v!yes {
1748        \xmldoifelse {#1} {/mml:apply} {
1749            \xmldoifelse {#1} {/mml:apply/(\MMLcfunctionlist\string|mml:divide)}
1750                \donefalse
1751                \donetrue
1752        } {
1753            \donefalse
1754        }
1755    } {
1756        \donetrue
1757    }
1758    % beware, we still flush from 2 up
1759    \ifdone
1760        \left(
1761            \MMLcreset
1762            \xmlall{#1}{/[position()>1]}% \xmlconcatrange{#1}{/*}{2}{}\empty
1763        \right)
1764    \else
1765        \MMLcreset
1766        \xmlall{#1}{/[position()>1]}
1767    \fi
1768\stopxmlsetups
1769
1770% PRESENTATION MATHML
1771
1772% helpers: maybe we can need a setting for the uprights
1773
1774\xmlmapvalue {mml:s} {normal}                 {\mathupright} % {\mathtf}
1775\xmlmapvalue {mml:s} {double-struck}          {\mathblackboard}
1776\xmlmapvalue {mml:s} {italic}                 {\mathit}
1777\xmlmapvalue {mml:s} {fraktur}                {\mathfraktur}
1778\xmlmapvalue {mml:s} {script}                 {\mathscript}
1779\xmlmapvalue {mml:s} {bold}                   {\mb}          % {\mathbf}
1780\xmlmapvalue {mml:s} {bold-italic}            {\mathbi}
1781\xmlmapvalue {mml:s} {bold-fraktur}           {\mathfraktur\mathbf}
1782\xmlmapvalue {mml:s} {bold-script}            {\mathscript\mathbf}
1783\xmlmapvalue {mml:s} {sans-serif}             {\mathss}
1784\xmlmapvalue {mml:s} {bold-sans-serif}        {\mathss\mathbf}
1785\xmlmapvalue {mml:s} {sans-serif-italic}      {\mathss\mathit}
1786\xmlmapvalue {mml:s} {sans-serif-bold-italic} {\mathss\mathbi}
1787\xmlmapvalue {mml:s} {monospace}              {\mathtt}
1788
1789\xmlmapvalue {mml:l} {-}                      {\let\mmlfrac\tfrac}
1790                                               \let\mmlfrac\frac
1791\xmlmapvalue {mml:l} {+}                      {\let\mmlfrac\sfrac}
1792
1793\xmlmapvalue {mml:d} {true}                   {\displaystyle}
1794\xmlmapvalue {mml:d} {false}                  {\textstyle} % or whatever
1795
1796\starttexdefinition setmmlmathstyle #1
1797    \ifxmlattempty{#1}{displaystyle}\else
1798        \xmlval{mml:d}\xmllastatt\empty
1799    \fi
1800    \ifxmlattempty{#1}{mathvariant}\else
1801        \xmlval{mml:s}\xmllastatt\empty
1802    \fi
1803\stoptexdefinition
1804
1805\starttexdefinition setmmlscriptlevel #1
1806    \ifxmlattempty{#1}{scriptlevel}
1807        \let\mmlfrac\frac
1808    \else
1809        \xmlval{mml:l}\xmllastatt{\let\mmlfrac\frac}
1810    \fi
1811\stoptexdefinition
1812
1813\starttexdefinition setmmlmathcolor #1
1814    \ifxmlattempty{#1}{mathcolor}\else
1815       \directcolor[\xmllastatt]
1816    \fi
1817\stoptexdefinition
1818
1819\starttexdefinition setmmlmathproperties #1
1820 %  \ifxmlatt{#1}{displaystyle}\empty\else
1821    \ifxmlattempty{#1}{displaystyle}\else
1822        \xmlval{mml:d}\xmllastatt\empty
1823    \fi
1824    \ifxmlattempty{#1}{mathvariant}\else
1825        \xmlval{mml:s}\xmllastatt\empty
1826    \fi
1827    \ifxmlattempty{#1}{scriptlevel}
1828        \let\mmlfrac\frac
1829    \else
1830        \xmlval{mml:l}\xmllastatt{\let\mmlfrac\frac}
1831    \fi
1832    \ifxmlattempty{#1}{mathcolor}\else
1833       \directcolor[\xmllastatt]
1834    \fi
1835\stoptexdefinition
1836
1837% todo: textbackgrounds / todo: can be combined with new grouping
1838
1839\starttexdefinition applymmlmathbackground #1#2
1840    \ifxmlattempty{#1}{mathbackground}
1841        #2
1842    \else
1843        \backgroundline[\xmllastatt]{#2}
1844    \fi
1845\stoptexdefinition
1846
1847\starttexdefinition applymmlsometext #1#2
1848    \begingroup
1849        \applymmlmathbackground {#1} {
1850            \setmmlmathcolor {#1}
1851            \setmmlmathstyle {#1}
1852            #2
1853        }
1854    \endgroup
1855\stoptexdefinition
1856
1857% setups
1858
1859\startxmlsetups mml:mi % todo: mathsize (unlikely) mathcolor (easy) mathbackground (easy)
1860    \begingroup
1861        \pushmathstyle % still needed ?
1862        \setmmlmathproperties{#1}
1863        \mathml_mi{#1}
1864        \popmathstyle % still needed ?
1865    \endgroup
1866\stopxmlsetups
1867
1868\startxmlsetups mml:mn
1869    \begingroup
1870        \setmmlmathcolor{#1}
1871        \mathml_mn{#1}
1872    \endgroup
1873\stopxmlsetups
1874
1875% <m:mo>-</m:mo><m:mn>2</m:mn> and <m:mn>1</m:mn><m:mo>-</m:mo><m:mn>2</m:mn>
1876%
1877% spacing between - and 2 is taken care of by tex itself
1878
1879\startxmlsetups mml:mo
1880    \begingroup
1881        \setmmlmathcolor{#1}
1882        \ifxmlatt{#1}{maxsize}{1}
1883            \settrue\mmlignoredelimiter
1884        \orelse\ifxmlatt{#1}{stretchy}{false}
1885            \settrue\mmlignoredelimiter
1886        \fi
1887        \ifxmlattempty{#1}{lspace}\else
1888            \hskip\xmllastatt\relax % todo: check for dimension
1889        \fi
1890        \mathml_mo{#1}
1891        \ifxmlattempty{#1}{rspace}\else
1892            \hskip\xmllastatt\relax % todo: check for dimension
1893        \fi
1894    \endgroup
1895\stopxmlsetups
1896
1897\startxmlsetups mml:mfenced % {} around separator is needed for spacing
1898    \mathml_mfenced{#1}
1899\stopxmlsetups
1900
1901\defineoverlay [mml:enclose:box]                [\useMPgraphic{mml:enclose:box}]
1902\defineoverlay [mml:enclose:roundedbox]         [\useMPgraphic{mml:enclose:roundedbox}]
1903\defineoverlay [mml:enclose:circle]             [\useMPgraphic{mml:enclose:circle}]
1904\defineoverlay [mml:enclose:left]               [\useMPgraphic{mml:enclose:left}]
1905\defineoverlay [mml:enclose:right]              [\useMPgraphic{mml:enclose:right}]
1906\defineoverlay [mml:enclose:top]                [\useMPgraphic{mml:enclose:top}]
1907\defineoverlay [mml:enclose:bottom]             [\useMPgraphic{mml:enclose:bottom}]
1908\defineoverlay [mml:enclose:updiagonalstrike]   [\useMPgraphic{mml:enclose:updiagonalstrike}]
1909\defineoverlay [mml:enclose:downdiagonalstrike] [\useMPgraphic{mml:enclose:downdiagonalstrike}]
1910\defineoverlay [mml:enclose:horizontalstrike]   [\useMPgraphic{mml:enclose:horizontalstrike}]
1911\defineoverlay [mml:enclose:verticalstrike]     [\useMPgraphic{mml:enclose:verticalstrike}]
1912
1913\startuseMPgraphic{mml:enclose:box}
1914    draw OverlayBox withpen pencircle scaled (ExHeight/10) ;
1915\stopuseMPgraphic
1916\startuseMPgraphic{mml:enclose:roundedbox}
1917    draw OverlayBox cornered .5ExHeight withpen pencircle scaled (ExHeight/10) ;
1918\stopuseMPgraphic
1919\startuseMPgraphic{mml:enclose:circle}
1920    draw fullcircle xysized(bbwidth(OverlayBox),bbheight(OverlayBox)) withpen pencircle scaled (ExHeight/10) ;
1921\stopuseMPgraphic
1922\startuseMPgraphic{mml:enclose:left}
1923    draw leftboundary OverlayBox withpen pencircle scaled (ExHeight/10) ;
1924    setbounds currentpicture to OverlayBox ;
1925\stopuseMPgraphic
1926\startuseMPgraphic{mml:enclose:right}
1927    draw rightboundary OverlayBox withpen pencircle scaled (ExHeight/10) ;
1928    setbounds currentpicture to OverlayBox ;
1929\stopuseMPgraphic
1930\startuseMPgraphic{mml:enclose:top}
1931    draw topboundary OverlayBox withpen pencircle scaled (ExHeight/10) ;
1932    setbounds currentpicture to OverlayBox ;
1933\stopuseMPgraphic
1934\startuseMPgraphic{mml:enclose:bottom}
1935    draw bottomboundary OverlayBox withpen pencircle scaled (ExHeight/10) ;
1936    setbounds currentpicture to OverlayBox ;
1937\stopuseMPgraphic
1938\startuseMPgraphic{mml:enclose:updiagonalstrike}
1939    path p ; p := OverlayBox enlarged -.25ExHeight ;
1940    draw llcorner p -- urcorner p withpen pencircle scaled (ExHeight/10) ;
1941    setbounds currentpicture to OverlayBox ;
1942\stopuseMPgraphic
1943\startuseMPgraphic{mml:enclose:downdiagonalstrike}
1944    path p ; p := OverlayBox enlarged -.25ExHeight ;
1945    draw ulcorner p -- lrcorner p withpen pencircle scaled (ExHeight/10) ;
1946    setbounds currentpicture to OverlayBox ;
1947\stopuseMPgraphic
1948\startuseMPgraphic{mml:enclose:horizontalstrike}
1949    path p ; p := OverlayBox enlarged -.25ExHeight ;
1950    draw .5[llcorner p,ulcorner p] -- .5[lrcorner p,urcorner p] withpen pencircle scaled (ExHeight/10) ;
1951    setbounds currentpicture to OverlayBox ;
1952\stopuseMPgraphic
1953\startuseMPgraphic{mml:enclose:verticalstrike}
1954    path p ; p := OverlayBox enlarged -.25ExHeight ;
1955    draw .5[llcorner p,lrcorner p] -- .5[ulcorner p,urcorner p] withpen pencircle scaled (ExHeight/10) ;
1956    setbounds currentpicture to OverlayBox ;
1957\stopuseMPgraphic
1958
1959\startxmlsetups mml:menclose
1960    \edef\mmlmenclosenotation{\mathml_menclosepattern{#1}}
1961    \ifempty\mmlmenclosenotation
1962        \xmlflush{#1}
1963    \else
1964        \doifelse \mmlmenclosenotation {mml:enclose:longdiv} {
1965            \overline{\left)\strut\xmlflush{#1}\right.}
1966        } {
1967            \doifelse \mmlmenclosenotation {mml:enclose:actuarial} {
1968                \overline{\left.\strut\xmlflush{#1}\right\vert}
1969            } {
1970                \doifelse \mmlmenclosenotation {mml:enclose:radical} {
1971                    \sqrt{\xmlflush{#1}}
1972                } {
1973                    % todo: no framed when longdiv, actuarial or radical ? spec ?
1974                    \vcenter {
1975                        \framed
1976                            [frame=off,strut=no,background={\mmlmenclosenotation}] % offset is kind of undefined
1977                            {
1978                             \startpickupmath
1979                                \expanded{\doifelseinset {mml:enclose:longdiv} {\mmlmenclosenotation}} {
1980                                    \overline{\left)\strut\xmlflush{#1}\right.}
1981                                } {
1982                                    \expanded{\doifelseinset {mml:enclose:actuarial} {\mmlmenclosenotation}} {
1983                                        \overline{\left.\strut\xmlflush{#1}\right\vert}
1984                                    } {
1985                                        \expanded{\doifelseinset {mml:enclose:radical} {\mmlmenclosenotation}} {
1986                                            \sqrt{\xmlflush{#1}}
1987                                        } {
1988                                            \expanded{\doifelseinset {mml:enclose:rule} {\mmlmenclosenotation}} {
1989                                                \overline{\strut\xmlflush{#1}}
1990                                            } {
1991                                                \xmlflush{#1}
1992                                            }
1993                                        }
1994                                    }
1995                                }
1996                             \stoppickupmath
1997                            }
1998                    }
1999                }
2000            }
2001        }
2002    \fi
2003\stopxmlsetups
2004
2005\xmlmapvalue {mml:mfrac:linethickness} {thin}   {.2pt}
2006\xmlmapvalue {mml:mfrac:linethickness} {medium} {.4pt}
2007\xmlmapvalue {mml:mfrac:linethickness} {thick}  {.8pt}
2008\xmlmapvalue {mml:mfrac:linethickness} {0}      {0pt}
2009
2010\startxmlsetups mml:mfrac % dodo: handle linethickness in lua + unit
2011    \begingroup
2012    \edef\mmlfraclinethickness{\xmlatt{#1}{linethickness}}
2013    \ifempty\mmlfraclinethickness
2014        \doifelse{\xmlatt{#1}{bevelled}}{true} {
2015            \left.\mmlfirst{#1}\middle/\mmlsecond{#1}\right.% \thinspace\middle/\thinspace
2016        } {
2017            \mmlfrac{\mmlfirst{#1}}{\mmlsecond{#1}}
2018        }
2019    \else % use \ifchknum
2020        \doifelse {\xmlval{mml:mfrac:linethickness}{\mmlfraclinethickness}{}} {} {
2021            \scratchdimen\xmlval{mml:mfrac:linethickness}\mmlfraclinethickness{.4pt}
2022        } {
2023            % probably not yet ok
2024            \setdimensionwithunit\scratchdimen\mmlfraclinethickness{pt}
2025        }
2026        {
2027            {\mmlfirst{#1}}
2028                \above\scratchdimen
2029            {\mmlsecond{#1}}
2030        }
2031    \fi
2032    \endgroup
2033\stopxmlsetups
2034
2035\startxmlsetups mml:ms
2036    \hbox {
2037        \tf % else encoding problems
2038        \ifxmlattempty{#1}{lquote}\symbol[leftquotation]\else\xmllastatt\fi
2039        \applymmlsometext{#1}{\xmlflush{#1}}
2040        \ifxmlattempty{#1}{rquote}\symbol[rightquotation]\else\xmllastatt\fi
2041    }
2042\stopxmlsetups
2043
2044\startxmlsetups mml:mstyle
2045    \begingroup
2046        \pushmathstyle
2047        \setmmlmathstyle{#1}
2048        \setmmlscriptlevel{#1}
2049        \xmlflush{#1}
2050        \popmathstyle
2051    \endgroup
2052\stopxmlsetups
2053
2054\setupMMLappearance[text][\c!alternative=\v!b] % a=normal, b=keep spaces
2055
2056\startxmlsetups mml:mtext
2057    \text {
2058        \applymmlsometext{#1}{
2059            \ifcstok{\MMLtextalternative}\v!a
2060                \ignorespaces
2061                \xmlflush{#1}
2062                \removeunwantedspaces
2063            \else
2064                \xmlflush{#1}
2065            \fi
2066        }
2067    }
2068\stopxmlsetups
2069
2070\startxmlsetups mml:merror
2071    \hbox{\startimath\displaystyle\xmlflush{#1}\stopimath}
2072\stopxmlsetups
2073
2074\startxmlsetups mml:mphantom
2075    \phantom{\triggermathstyle\normalmathstyle\ignorespaces\xmlflush{#1}\removeunwantedspaces}
2076\stopxmlsetups
2077
2078\startxmlsetups mml:mpadded % todo
2079    \xmlflush{#1}
2080\stopxmlsetups
2081
2082% mrow / option: no fenced
2083
2084\startxmlsetups mml:maction
2085    \xmlflush{#1}
2086\stopxmlsetups
2087
2088\startxmlsetups mml:mrow
2089    \begingroup
2090        \xmlflush{#1}
2091    \endgroup
2092\stopxmlsetups
2093
2094\startxmlsetups mml:msqrt
2095    \sqrt{\xmlflush{#1}}
2096\stopxmlsetups
2097
2098\startxmlsetups mml:mroot
2099   \root{\mmlsecond{#1}}\of{\mmlfirst{#1}}
2100\stopxmlsetups
2101
2102\setupMMLappearance[scripts][\c!alternative=\v!a] % {} rond base
2103
2104% brrr no { } when limop .. todo: better in lua
2105% speed up with ifx and setups or just in lua
2106
2107\let\mmlnucleus\relax
2108
2109% maybe make helper
2110% \iftok{\utfmathclass{\xmlraw{#1}{/mml:*[1]}}}{limop}
2111% \ifcstok{\utfmathclass{\xmlraw{#1}{/mml:*[1]}}}\s!limop
2112
2113\startxmlsetups mml:msub
2114    \iftok{\utfmathclass{\xmlraw{#1}{/mml:*[1]}}}{limop}
2115        \mmlfirst{#1}
2116        \normalsubscript{\mmlsecond{#1}}
2117    \orelse\ifcstok{\MMLscriptsalternative}\v!a
2118        {\mmlfirst{#1}}
2119        \normalsubscript{\mmlsecond{#1}}
2120    \else
2121        \mmlfirst{#1}
2122        \normalsubscript{\mmlsecond{#1}}
2123    \fi
2124\stopxmlsetups
2125
2126\startxmlsetups mml:msup
2127    \iftok{\utfmathclass{\xmlraw{#1}{/mml:*[1]}}}{limop}
2128        \mmlfirst{#1}
2129        \normalsuperscript{\mmlsecond{#1}}
2130    \orelse\ifcstok{\MMLscriptsalternative}\v!a
2131        {\mmlfirst{#1}}
2132        \normalsuperscript{\mmlsecond{#1}}
2133    \else
2134        \mmlfirst{#1}
2135        \normalsuperscript{\mmlsecond{#1}}
2136    \fi
2137\stopxmlsetups
2138
2139% use mathclass number
2140
2141\startxmlsetups mml:msubsup
2142    \iftok{\utfmathclass{\xmlraw{#1}{/mml:*[1]}}}{limop}
2143        \mmlfirst{#1}
2144        \normalsubscript{\mmlsecond{#1}}
2145        \normalsuperscript{\mmlthird{#1}}
2146    \orelse\ifcstok{\MMLscriptsalternative}\v!a
2147        {\mmlfirst{#1}}
2148        \normalsubscript{\mmlsecond{#1}}
2149        \normalsuperscript{\mmlthird {#1}}
2150    \else
2151        \mmlfirst{#1}
2152        \normalsubscript{\mmlsecond{#1}}
2153        \normalsuperscript{\mmlthird {#1}}
2154    \fi
2155\stopxmlsetups
2156
2157% helpers
2158
2159\protected\def\mmlexecutecommand#1%
2160  {\ifcsname#1\endcsname
2161     \expandafter\firstoftwoarguments
2162   \else
2163     \expandafter\secondoftwoarguments
2164   \fi
2165   \lastnamedcs}
2166
2167\let\mmlextensible\mathml_extensible
2168
2169\definemathtriplet [\v!mathematics] [mmlovertriplet]   % or will we use a special instance
2170\definemathtriplet [\v!mathematics] [mmlundertriplet]  % or will we use a special instance
2171\definemathtriplet [\v!mathematics] [mmldoubletriplet] % or will we use a special instance
2172
2173% common to munder/mover/munderover : will become core helper (speed up too)
2174
2175\starttexdefinition protected mmlfencedfirst #1
2176    \xmlelement{#1}{1}
2177\stoptexdefinition
2178\starttexdefinition protected mmlfencedsecond #1
2179    \xmlelement{#1}{2}
2180\stoptexdefinition
2181\starttexdefinition protected mmlfencedthird #1
2182    \xmlelement{#1}{3}
2183\stoptexdefinition
2184
2185% mover
2186
2187\starttexdefinition protected mmloverabove #1
2188    \mmlexecutecommand{\utfmathfiller\mmlovertoken} {\mmlfencedsecond{#1}} \relax
2189\stoptexdefinition
2190\starttexdefinition protected mmloverbase #1
2191    \mmlexecutecommand{\utfmathfiller\mmlbasetoken} {\mmlfencedfirst{#1}} \relax
2192\stoptexdefinition
2193\starttexdefinition protected mmloverbasefiller #1
2194    \mmlexecutecommand{e\utfmathcommandfiller\mmlbasetoken} \relax {\mmlfencedsecond{#1}} {}
2195\stoptexdefinition
2196\starttexdefinition protected mmloveraccent #1
2197    \mmlexecutecommand{\utfmathcommandabove\mmlovertoken} \relax {\mmlfencedfirst{#1}}
2198\stoptexdefinition
2199
2200\starttexdefinition protected mmlovertext #1
2201    \mmlovertriplet {\mmloverbase{#1}} {\mmloverabove{#1}} {}
2202\stoptexdefinition
2203\starttexdefinition protected mmloveraccentchecker #1
2204    \edef\mmlovertoken{\mmlextensible{\xmlraw{#1}{/mml:*[2]}}}% /text()
2205    \doifelseutfmathabove\mmlovertoken \mmloveraccent \mmlovertext {#1}
2206\stoptexdefinition
2207
2208\startxmlsetups mml:mover
2209    \edef\mmlbasetoken{\mmlextensible{\xmlraw{#1}{/mml:*[1]}}}% /text()
2210    \doifelseutfmathlimop\mmlbasetoken
2211      {\mmllimopover{#1}}
2212      {\doifelseutfmathfiller\mmlbasetoken \mmloverbasefiller \mmloveraccentchecker {#1}}
2213\stopxmlsetups
2214
2215\starttexdefinition mmllimopover #1
2216    \mmlbasetoken\normalsuperscript{\mmlfencedsecond{#1}}
2217\stoptexdefinition
2218
2219% munder
2220
2221\starttexdefinition protected mmlunderbelow #1
2222    \mmlexecutecommand{\utfmathfiller\mmlundertoken} {\mmlfencedsecond{#1}} \relax
2223\stoptexdefinition
2224\starttexdefinition protected mmlunderbase #1
2225    \mmlexecutecommand{\utfmathfiller\mmlbasetoken} {\mmlfencedfirst{#1}} \relax
2226\stoptexdefinition
2227\starttexdefinition protected mmlunderbasefiller #1
2228    \mmlexecutecommand{e\utfmathcommandfiller\mmlbasetoken} \relax {} {\mmlfencedsecond{#1}}
2229\stoptexdefinition
2230\starttexdefinition protected mmlunderaccent #1
2231    \mmlexecutecommand{\utfmathcommandbelow\mmlundertoken} \relax {\mmlfencedfirst{#1}}
2232\stoptexdefinition
2233
2234\starttexdefinition protected mmlundertext #1
2235    \mmlundertriplet {\mmlunderbase{#1}} {} {\mmlunderbelow{#1}}
2236\stoptexdefinition
2237\starttexdefinition protected mmlunderaccentchecker #1
2238    \edef\mmlundertoken{\mmlextensible{\xmlraw{#1}{/mml:*[2]}}}% /text()
2239    \doifelseutfmathbelow\mmlundertoken \mmlunderaccent \mmlundertext {#1}
2240\stoptexdefinition
2241
2242\startxmlsetups mml:munder
2243    \edef\mmlbasetoken{\mmlextensible{\xmlraw{#1}{/mml:*[1]}}}% /text()
2244    \doifelseutfmathlimop\mmlbasetoken
2245      {\mmllimopunder{#1}}
2246      {\doifelseutfmathfiller\mmlbasetoken \mmlunderbasefiller \mmlunderaccentchecker {#1}}
2247\stopxmlsetups
2248
2249\starttexdefinition mmllimopunder #1
2250    \mmlbasetoken\normalsubscript{\mmlfencedsecond{#1}}
2251\stoptexdefinition
2252
2253% munderover
2254
2255\starttexdefinition protected mmlunderoveraccentcheckerUO #1
2256    \edef\mmlundercommand{\utfmathcommandbelow\mmlundertoken}
2257    \edef\mmlovercommand {\utfmathcommandabove\mmlovertoken}
2258    \edef\mmlbasecommand {\mmlovercommand\mmlundercommand}
2259    \ifcsname\mmlbasecommand\endcsname
2260        \lastnamedcs {\mmlfencedfirst{#1}}
2261    \orelse\ifcsname\mmlundercommand\endcsname
2262        \ifcsname\mmlovercommand\endcsname
2263            \lastnamedcs {\csname\mmlundercommand\endcsname{\mmlfencedfirst{#1}}}
2264        \else
2265            \mmldoubletriplet {\csname\mmlundercommand\endcsname{\mmlfencedfirst{#1}}} {\mmlfencedthird{#1}\mmlfencedthird{#1}} {}
2266        \fi
2267    \orelse\ifcsname\mmlovercommand\endcsname
2268        \mmldoubletriplet {\csname\mmlovercommand\endcsname{\mmlfencedfirst{#1}}} {} {\mmlfencedsecond{#1}}
2269    \else
2270        \mmlunderoveraccentcheckerTT {#1}
2271    \fi
2272\stoptexdefinition
2273\starttexdefinition protected mmlunderoveraccentcheckerUT #1
2274    \edef\mmlundercommand{\utfmathcommandbelow\mmlundertoken}
2275    \edef\mmlbasecommand {\mmlundercommand text}
2276    \ifcsname\mmlbasecommand\endcsname
2277        \lastnamedcs {\mmlfencedfirst{#1}} {\mmlfencedthird{#1}}
2278    \orelse\ifcsname\mmlundercommand\endcsname
2279        \mmldoubletriplet {\csname\mmlundercommand\endcsname{\mmlfencedfirst{#1}}} {\mmlfencedthird{#1}} {}
2280    \else
2281        \mmlunderoveraccentcheckerTT {#1}
2282    \fi
2283\stoptexdefinition
2284\starttexdefinition protected mmlunderoveraccentcheckerOT #1
2285    \edef\mmlovercommand{\utfmathcommandabove\mmlovertoken}
2286    \edef\mmlbasecommand{\mmlovercommand text}
2287    \ifcsname\mmlbasecommand\endcsname
2288        \lastnamedcs {\mmlfencedfirst{#1}} {\mmlfencedsecond{#1}}
2289    \orelse\ifcsname\mmlovercommand\endcsname
2290        \mmldoubletriplet {\csname\mmlovercommand\endcsname{\mmlfencedfirst{#1}}} {} {\mmlfencedsecond{#1}}
2291    \else
2292        \mmlunderoveraccentcheckerTT {#1}
2293    \fi
2294\stoptexdefinition
2295\starttexdefinition protected mmlunderoveraccentcheckerTT #1
2296    \mmldoubletriplet {\mmlfencedfirst{#1}} {\mmlfencedthird{#1}} {\mmlfencedsecond{#1}} \relax
2297\stoptexdefinition
2298\starttexdefinition protected mmlunderoveraccentchecker #1
2299    \edef\mmlundertoken{\mmlextensible{\xmlraw{#1}{/mml:*[2]}}}% /text()
2300    \edef\mmlovertoken {\mmlextensible{\xmlraw{#1}{/mml:*[3]}}}% /text()
2301    \doifelseutfmathbelow\mmlundertoken {
2302        \doifelseutfmathabove\mmlovertoken \mmlunderoveraccentcheckerUO \mmlunderoveraccentcheckerUT {#1}
2303    } {
2304        \doifelseutfmathabove\mmlovertoken \mmlunderoveraccentcheckerOT \mmlunderoveraccentcheckerTT {#1}
2305    }
2306\stoptexdefinition
2307
2308\starttexdefinition protected mmlunderoverbasefiller #1
2309    \mmlexecutecommand{e\utfmathcommandfiller\mmlbasetoken} \relax {\mmlfencedthird{#1}} {\mmlfencedsecond{#1}}
2310\stoptexdefinition
2311
2312\startxmlsetups mml:munderover
2313    \edef\mmlbasetoken{\mmlextensible{\xmlraw{#1}{/mml:*[1]}}}% /text()
2314    \doifelseutfmathlimop\mmlbasetoken
2315      {\mmllimopunderover{#1}}
2316      {\doifelseutfmathfiller\mmlbasetoken \mmlunderoverbasefiller \mmlunderoveraccentchecker {#1}}
2317\stopxmlsetups
2318
2319\starttexdefinition mmllimopunderover #1
2320    \mmlbasetoken\normalsuperscript{\mmlfencedthird{#1}}\normalsubscript{\mmlfencedsecond{#1}}
2321\stoptexdefinition
2322
2323% tables (mml:mtable, mml:mtr, mml:mlabledtr, mml:mtd)
2324
2325\startxmlsetups mml:mtable % some more attributes need to be supported
2326    \vcenter {
2327        \hbox {% needed because otherwise positions make the vcenter wide
2328            \mathml_mtable{#1}
2329        }
2330    }
2331\stopxmlsetups
2332
2333\startxmlsetups mml:mcolumn
2334    \vbox{\mathml_mcolumn{#1}}% needs checking
2335\stopxmlsetups
2336
2337\def\mmlsetfakewidth#1{\setbox\scratchbox\hbox{#1}\scratchdimen\wd\scratchbox}
2338
2339\def\mmlmcolumndigitspace     {\mmlsetfakewidth     {0}\kern\scratchdimen}
2340\def\mmlmcolumndigitrule      {\mmlsetfakewidth     {0}\vrule \s!width \scratchdimen \s!height .2\points \s!depth .2\points\relax}
2341\def\mmlmcolumnsymbolrule     {\mmlsetfakewidth{\times}\vrule \s!width \scratchdimen \s!height .2\points \s!depth .2\points\relax}
2342\def\mmlmcolumnpunctuationrule{\mmlsetfakewidth     {.}\vrule \s!width \scratchdimen \s!height .2\points \s!depth .2\points\relax}
2343
2344\setupMMLappearance[mspace][\c!option=] % \v!test
2345
2346\startxmlsetups mml:mspace
2347    \begingroup
2348        \edef\mmlspacetext{\xmlatt{#1}{spacing}}
2349        \ifempty\mmlspacetext
2350            \scratchwidth \xmlattdef{#1}{width} \!!zeropoint % must be string
2351            \scratchheight\xmlattdef{#1}{height}\!!zeropoint
2352            \scratchdepth \xmlattdef{#1}{depth} \!!zeropoint
2353            \ifdim\scratchheight=\zeropoint
2354                \ifdim\scratchdepth=\zeropoint\else
2355                    \novrule\s!depth\scratchdepth\s!height\zeropoint\s!width\zeropoint
2356                \fi
2357            \else
2358                \novrule\s!depth\zeropoint\s!height\scratchheight\s!width\zeropoint
2359            \fi
2360            \ifdim\scratchwidth=\zeropoint
2361                % maybe we need to do it anyway
2362            \orelse\ifx\MMLmspaceoption\v!test
2363                \hbox to \scratchwidth{\showstruts\strut\hss\lower2\exheight\hbox{\infofont\xmlattdef{#1}{width}}\hss\strut}
2364            \else
2365                \hskip\scratchwidth
2366            \fi
2367        \orelse\ifx\MMLmspaceoption\v!test
2368            \hbox{\showstruts\strut\phantom{\triggermathstyle\normalmathstyle\mmlspacetext}\strut}
2369        \else
2370            \phantom{\triggermathstyle\normalmathstyle\mmlspacetext}
2371        \fi
2372    \endgroup
2373\stopxmlsetups
2374
2375% later we can do a better job by manipulating node lists
2376
2377% \startxmlsetups mml:mline
2378%     % new, rather undefined, we need to capture a few keywords
2379%     \edef\mmllinewidth {\xmlatt{#1}{linethickness}}
2380%     \edef\mmllinetext  {\xmlatt{#1}{spacing}}
2381%     \edef\mmllinelength{\xmlattdef{#1}{length}\!!zeropoint}
2382%     \ifempty\mmllinewidth
2383%         \!!deptha.5\linewidth
2384%     \else
2385%         \!!deptha.5\dimexpr\mmllinewidth\relax
2386%     \fi
2387%     \!!heighta\!!deptha
2388%     \ifempty\mmllinetext
2389%         \ifempty\mmllinelength
2390%             \!!widtha\zeropoint
2391%         \else
2392%             \!!widtha\mmllinelength
2393%         \fi
2394%     \else
2395%         \setbox\scratchbox\hbox{\mathematics{\mathstyle{\mmllinetext}}}% not ok
2396%         \!!widtha\wd\scratchbox
2397%     \fi
2398%     \hbox{\vrule\s!width\!!widtha\s!depth\!!deptha\s!height\!!heighta}
2399% \stopxmlsetups
2400
2401\startxmlsetups mml:mglyph % probably never ok (hbox is needed in order to switch to normal font)
2402    \begingroup
2403    \edef\mmlglyphfontfamily{\xmlatt   {#1}{fontfamily}}
2404    \edef\mmlglyphalt       {\xmlattdef{#1}{alt}{unknown}}
2405    \edef\mmlglyphindex     {\xmlatt   {#1}{index}}
2406    \ifempty\mmlglyphfontfamily
2407        \hbox{\tttf[no fontfamily specified for \mmlglyphalt]}
2408    \orelse\ifempty\mmlglyphindex
2409        \hbox{\tttf[no index specified for \mmlglyphalt]}
2410    \else
2411        \hbox{\getglyph\mmlglyphfontfamily\mmlglyphindex}
2412    \fi
2413    \endgroup
2414\stopxmlsetups
2415
2416\startxmlsetups mml:maligngroup \stopxmlsetups % will be done when needed
2417\startxmlsetups mml:malignmark  \stopxmlsetups % will be done when needed
2418
2419\startxmlsetups mml:none        \stopxmlsetups
2420\startxmlsetups mml:mprescripts \stopxmlsetups
2421
2422\startxmlsetups mml:mmultiscripts
2423    \mathml_mmultiscripts{#1}
2424\stopxmlsetups
2425
2426% goodie
2427
2428\definebuffer[mml]
2429
2430\permanent\protected\def\stopmml{\xmlprocessbuffer{@mml@}{\thedefinedbuffer{mml}}{}}
2431
2432\stopmodule
2433
2434\protect \endinput
2435
2436% TODO:
2437%
2438% <apply><divide/>
2439%     <apply><minus/>
2440%         <apply><minus/><ci>b</ci></apply>
2441%         <apply><minus/><ci>b</ci></apply>
2442%         <apply><root/> <ci>a</ci></apply>
2443%     </apply>
2444%     <apply><minus/>
2445%         <apply><minus/><ci>b</ci><ci>b</ci></apply>
2446%         <apply><minus/><ci>b</ci></apply>
2447%         <apply><root/> <ci>a</ci></apply>
2448%     </apply>
2449% </apply>
2450