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