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