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