%D \module
%D   [       file=xtag-mml,
%D        version=2000.12.20,
%D          title=\CONTEXT\ XML Macros,
%D       subtitle=MathML,
%D         author=Hans Hagen,
%D           date=\currentdate,
%D      copyright={PRAGMA / Hans Hagen \& Ton Otten}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.

\writestatus{loading}{ConTeXt XML Macros / MathML}

% I will reimplement this one without mapping since we now have more
% tricks available

\useXMLfilter[map]

%\enablemathpunctuation

% First some general formula element definitions.

\defineXMLenvironment [formula] [label=,sublabel=]
  {\dostartXMLformula\placeformula}
  {\dostopXMLformula}

\defineXMLenvironment [subformula] [label=,sublabel=]
  {\dostartXMLformula\placesubformula}
  {\dostopXMLformula}

\def\dostartXMLformula#1%
  {\doifelsenothingXMLop{label}
     {\startformula}
     {\expanded{#1[\XMLop{label}]{\XMLop{sublabel}}}\startformula}}

\def\dostopXMLformula
  {\stopformula}

% Since I only had the draft of mml 2 as example of
% rendering, there are probably a lot of omissions and
% misinterpretations. At least I learned some bits and
% pieces of math rendering.
%
% The main complications were not so much the math, but to
% find the most efficient way to handle elements without
% spacing beging messed up. The first implementation was
% aimed at getting reasonable output, this second
% implementation is already better in terms of handling
% nesting, and I will definitely need a third one that has
% more efficient and less ugly code.
%
% The TeX part is not that complicated and once the
% preprocessor was okay, the rest way just a lot of keying
% and testing. It all comes down to gobbling, redefining,
% and not so much to parsing.

\unprotect

\def\setupMMLappearance[#1]{\dodoubleargument\getparameters[@@MML#1]}

\defineXMLdirective [mathml] \setupMMLappearance

\defineXMLargument [math]  \doXMLmath
\defineXMLargument [imath] \doXMLimath
\defineXMLargument [dmath] \doXMLdmath
\defineXMLargument [m]     \doXMLimath

\unexpanded\def\doXMLmath {\ifhmode\@EA\doXMLimath\else\@EA\doXMLdmath\fi}
\unexpanded\def\doXMLimath{\XMLremapdata[mml]{$}{$}}
\unexpanded\def\doXMLdmath{\XMLremapdata[mml]{\dostartformula{}}{\dostopformula}}

\ifx\XMLRtoks\undefined \newtoks\XMLRtoks \fi

\def\convertasciiafter#1#2%
  {\defconvertedargument\asciiafter{#2}%
   \@EA#1\@EA{\asciiafter}}

\def\checkMMLoperator#1% #2
  {\unspaceargument#1\to\ascii
   \doifXMLentityelse\ascii{\getXMLentity\ascii}} % {#2}

% this will be done in a more safe way

\def\MMLtodo#1{\enspace\hbox{\rm#1}\enspace}

% this goes to core-mat

\def\normalorfiller   #1#2{#1}
\def\normalordelimiter#1#2{#2}

\def\enabledelimiter {\let\normalordelimiter\secondoftwoarguments}
\def\disabledelimiter{\let\normalordelimiter\firstoftwoarguments}

\def\enablefiller    {\let\normalorfiller\secondoftwoarguments}
\def\disablefiller   {\let\normalorfiller\firstoftwoarguments}

\def\mathopnolimits#1{\mathop{\rm#1}\nolimits}

% Auxiliary macros

\bgroup \obeylines

\gdef\defineMMLentity% % needed !
  {\bgroup\obeylines\xdefineMMLentity}

\gdef\xdefineMMLentity #1 #2 #3 #4
  {\egroup\dodefineMMLentity{#1}{#2}{#3}{#4}}

\global\let\dodefineMMLentity\gobblefourarguments

\gdef\defineMMLsynonym% % needed !
  {\bgroup\obeylines\xdefineMMLsynonym}

\gdef\xdefineMMLsynonym #1 #2
  {\egroup\dodefineMMLsynonym{#1}{#2}}

\global\let\dodefineMMLsynonym\gobbletwoarguments

\egroup

% some more

\def\showMMLentity#1%
  {\bgroup
   \doifXMLentityelse{#1}
     {\let\left\empty\let\right\empty\mathematics{\getXMLentity{#1}{}}}
     {\getXMLentity{unknown}}%
   \egroup}

\newbox\unknownXMLentity
\setbox\unknownXMLentity\hbox{\inframed[\c!strut=\v!no,\c!offset=1pt]{\ttx ?}}

\defineXMLentity [unknown] {\copy\unknownXMLentity}

% the definitions

\ifx\blackboard\undefined
  \def\blackboard{\ifx\Bbb\undefined\else\expandafter\Bbb\fi}
\fi

% basic entities, greek

\defineXMLentity [alpha]      {\mathematics \alpha}
\defineXMLentity [beta]       {\mathematics \beta}
\defineXMLentity [gamma]      {\mathematics \gamma}
\defineXMLentity [delta]      {\mathematics \delta}
\defineXMLentity [epsilon]    {\mathematics \epsilon}
\defineXMLentity [zeta]       {\mathematics \zeta}
\defineXMLentity [eta]        {\mathematics \eta}
\defineXMLentity [theta]      {\mathematics \theta}
\defineXMLentity [iota]       {\mathematics \iota}
\defineXMLentity [kappa]      {\mathematics \kappa}
\defineXMLentity [lambda]     {\mathematics \lambda}
\defineXMLentity [theta]      {\mathematics \theta}
\defineXMLentity [mu]         {\mathematics \mu}
\defineXMLentity [nu]         {\mathematics \nu}
\defineXMLentity [xi]         {\mathematics \xi}
\defineXMLentity [pi]         {\mathematics \pi}
\defineXMLentity [rho]        {\mathematics \rho}
\defineXMLentity [sigma]      {\mathematics \sigma}
\defineXMLentity [tau]        {\mathematics \tau}
\defineXMLentity [upsilon]    {\mathematics \upsilon}
\defineXMLentity [phi]        {\mathematics \phi}
\defineXMLentity [chi]        {\mathematics \chi}
\defineXMLentity [psi]        {\mathematics \psi}
\defineXMLentity [omega]      {\mathematics \omega}

\defineXMLentity [varepsilon] {\mathematics \varepsilon}
\defineXMLentity [vartheta]   {\mathematics \vartheta}
\defineXMLentity [varpi]      {\mathematics \varpi}
\defineXMLentity [varrho]     {\mathematics \varrho}
\defineXMLentity [varsigma]   {\mathematics \varsigma}
\defineXMLentity [varphi]     {\mathematics \varphi}

\defineXMLentity [epsilonv]   {\mathematics \varepsilon}
\defineXMLentity [thetav]     {\mathematics \vartheta}
\defineXMLentity [piv]        {\mathematics \varpi}
\defineXMLentity [rhov]       {\mathematics \varrho}
\defineXMLentity [sigmav]     {\mathematics \varsigma}
\defineXMLentity [phiv]       {\mathematics \varphi}

\defineXMLentity [epsi]       {\mathematics \epsilon}
\defineXMLentity [epsiv]      {\mathematics \varepsilon}

\defineXMLentity [Alpha]      {A}
\defineXMLentity [Beta]       {B}
\defineXMLentity [Gamma]      {\mathematics \Gamma}
\defineXMLentity [Delta]      {\mathematics \Delta}
\defineXMLentity [Epsilon]    {E}
\defineXMLentity [Zeta]       {Z}
\defineXMLentity [Eta]        {N}
\defineXMLentity [Theta]      {\mathematics \Theta}
\defineXMLentity [Iota]       {I}
\defineXMLentity [Kappa]      {K}
\defineXMLentity [Lambda]     {\mathematics \Lambda}
\defineXMLentity [Mu]         {M}
\defineXMLentity [Nu]         {N}
\defineXMLentity [Xi]         {\mathematics \Xi}
\defineXMLentity [Pi]         {\mathematics \Pi}
\defineXMLentity [Ro]         {R}
\defineXMLentity [Sigma]      {\mathematics \Sigma}
\defineXMLentity [Tau]        {T}
\defineXMLentity [Upsilon]    {\mathematics \Upsilon}
\defineXMLentity [Phi]        {\mathematics \Phi}
\defineXMLentity [Chi]        {X}
\defineXMLentity [Psi]        {\mathematics \Psi}
\defineXMLentity [Omega]      {\mathematics \Omega}

% basic entities, hebrew

\defineXMLentity [aleph]            {\mathematics \aleph}

% basic entities, functions

\defineXMLentity [abs]              {\mathopnolimits{abs}}
\defineXMLentity [arg]              {\mathopnolimits{arg}}
\defineXMLentity [codomain]         {\mathopnolimits{codomain}}
\defineXMLentity [curl]             {\mathopnolimits{curl}}
\defineXMLentity [determinant]      {\mathopnolimits{det}}
\defineXMLentity [divergence]       {\mathopnolimits{div}}
\defineXMLentity [domain]           {\mathopnolimits{domain}}
\defineXMLentity [false]            {\mathopnolimits{false}}
\defineXMLentity [gcd]              {\mathopnolimits{gcd}}
\defineXMLentity [grad]             {\mathopnolimits{grad}}
\defineXMLentity [identity]         {\mathopnolimits{id}}
\defineXMLentity [image]            {\mathopnolimits{image}}
\defineXMLentity [lcm]              {\mathopnolimits{lcm}}
\defineXMLentity [max]              {\mathopnolimits{max}}
\defineXMLentity [median]           {\mathopnolimits{median}}
\defineXMLentity [min]              {\mathopnolimits{min}}
\defineXMLentity [mode]             {\mathopnolimits{mode}}
\defineXMLentity [mod]              {\mathopnolimits{mod}}
\defineXMLentity [notanumber]       {\mathopnolimits{NaN}}
\defineXMLentity [otherwise]        {\mathopnolimits{otherwise}}
\defineXMLentity [true]             {\mathopnolimits{true}}
\defineXMLentity [declare]          {\mathopnolimits{declare}}
\defineXMLentity [as]               {\mathopnolimits{as}}
\defineXMLentity [polar]            {\mathopnolimits{Polar}}

\defineXMLentity [mathematicald]        {d}

\defineXMLentity [imaginaryi]           {{\rm i}}
\defineXMLentity [differentiald]        {\partial}
\defineXMLentity [exponentiale]         {{\rm e}}
\defineXMLentity [capitaldifferentiald] {D}

\defineXMLentity [ii]                   {\getXMLentity{imaginaryi}}
\defineXMLentity [dd]                   {\getXMLentity{differentiald}}
\defineXMLentity [ee]                   {\getXMLentity{exponentiale}}
\defineXMLentity [DD]                   {\getMMLentity{capitaldifferentiald}}

\defineXMLentity [ImaginaryI]           {\getXMLentity{imaginaryi}}
\defineXMLentity [DifferentialD]        {\getXMLentity{differentiald}}
\defineXMLentity [ExponentialE]         {\getXMLentity{exponentiale}}
\defineXMLentity [CapitalDifferentialD] {\getXMLentity{differentiald}}

\defineXMLentity [NaN]                  {\getXMLentity{notanumber}}
\defineXMLentity [NotANumber]           {\getXMLentity{notanumber}}

\defineXMLentity [and]              {\wedge}
\defineXMLentity [exists]           {\exists}
\defineXMLentity [forall]           {\forall}
\defineXMLentity [implies]          {\Rightarrow}
\defineXMLentity [not]              {\neg}
\defineXMLentity [or]               {\vee}
\defineXMLentity [xor]              {\mathopnolimits{xor}}

\defineXMLentity [imaginary]        {\Im}
\defineXMLentity [real]             {\Re}

\defineXMLentity [lceiling]         {\lceil}
\defineXMLentity [rceiling]         {\rceil}

\defineXMLentity [lfloor]           {\lfloor}
\defineXMLentity [rfloor]           {\rfloor}

\defineXMLentity [ne]               {\neq}
\defineXMLentity [neq]              {\neq}
\defineXMLentity [gt]               {>}
\defineXMLentity [lt]               {<}
\defineXMLentity [ge]               {\geq}
\defineXMLentity [geq]              {\geq}
\defineXMLentity [le]               {\leq}
\defineXMLentity [leq]              {\leq}

\defineXMLentity [equivalent]       {\equiv}
\defineXMLentity [equiv]            {\equiv}
\defineXMLentity [approx]           {\approx}

\defineXMLentity [factorof]         {\mid}
\defineXMLentity [mapsto]           {\mapsto}

\defineXMLentity [int]              {\int}
\defineXMLentity [prime]            {\prime}
\defineXMLentity [laplacian]        {\nabla^2}
\defineXMLentity [partial]          {\partial}

\defineXMLentity [union]            {\cup}
\defineXMLentity [intersect]        {\cap}
\defineXMLentity [in]               {\in}
\defineXMLentity [notin]            {\not\in}
\defineXMLentity [subset]           {\subset}
\defineXMLentity [prsubset]         {\subseteq}
\defineXMLentity [notsubset]        {\not\subset}
\defineXMLentity [notprsubset]      {\not\subseteq}
\defineXMLentity [setdiff]          {\setminus}

\defineXMLentity [card]             {\vert}
\defineXMLentity [cartesianproduct] {\times}

\defineXMLentity [sum]              {\sum}
\defineXMLentity [prod]             {\prod}
\defineXMLentity [product]          {\prod}
\defineXMLentity [lim]              {\lim}

\defineXMLentity [exp]              {\mathopnolimits{exp}} % {\exp}
\defineXMLentity [ln]               {\mathopnolimits{ln}}  % {\ln}
\defineXMLentity [log]              {\mathopnolimits{log}} % {\log}

\defineXMLentity [sin]              {\mathopnolimits{sin}}
\defineXMLentity [arcsin]           {\mathopnolimits{arcsin}}
\defineXMLentity [sinh]             {\mathopnolimits{sinh}}
\defineXMLentity [arcsinh]          {\mathopnolimits{arcsinh}}
\defineXMLentity [cos]              {\mathopnolimits{cos}}
\defineXMLentity [arccos]           {\mathopnolimits{arccos}}
\defineXMLentity [cosh]             {\mathopnolimits{cosh}}
\defineXMLentity [arccosh]          {\mathopnolimits{arccosh}}
\defineXMLentity [tan]              {\mathopnolimits{tan}}
\defineXMLentity [arctan]           {\mathopnolimits{arctan}}
\defineXMLentity [tanh]             {\mathopnolimits{tanh}}
\defineXMLentity [arctanh]          {\mathopnolimits{arctanh}}
\defineXMLentity [cot]              {\mathopnolimits{cot}}
\defineXMLentity [arccot]           {\mathopnolimits{arccot}}
\defineXMLentity [coth]             {\mathopnolimits{coth}}
\defineXMLentity [arccoth]          {\mathopnolimits{arccoth}}
\defineXMLentity [csc]              {\mathopnolimits{csc}}
\defineXMLentity [arccsc]           {\mathopnolimits{arccsc}}
\defineXMLentity [csch]             {\mathopnolimits{csch}}
\defineXMLentity [arccsch]          {\mathopnolimits{arccsch}}
\defineXMLentity [sec]              {\mathopnolimits{sec}}
\defineXMLentity [arcsec]           {\mathopnolimits{arcsec}}
\defineXMLentity [sech]             {\mathopnolimits{sech}}
\defineXMLentity [arcsech]          {\mathopnolimits{arcsech}}

\defineXMLentity [transpose]        {^{\rm T}}

\defineXMLentity [plusminus]        {\pm}
\defineXMLentity [minusplus]        {\mp}

\defineXMLentity [vectorproduct]    {\times}
\defineXMLentity [scalarproduct]    {\cdot}
\defineXMLentity [outerproduct]     {\otimes}

\defineXMLentity [integers]         {\integers}
\defineXMLentity [reals]            {\reals}
\defineXMLentity [rationals]        {\rationals}
\defineXMLentity [naturalnumbers]   {\naturalnumbers}
\defineXMLentity [complexes]        {\complexes}
\defineXMLentity [primes]           {\primes}

\defineXMLentity [emptyset]         {\emptyset}
\defineXMLentity [pi]               {\pi}
\defineXMLentity [eulergamma]       {\gamma}
\defineXMLentity [infinity]         {\mathematics{\infty}}

\defineXMLentity [InvisibleTimes]   {}
\defineXMLentity [InvisibleComma]   {}
\defineXMLentity [ApplyFunction]    {}

\defineXMLentity [it]               {\getXMLentity{InvisibleTines}}
\defineXMLentity [ic]               {\getXMLentity{InvisibleComma}}
\defineXMLentity [af]               {\getXMLentity{ApplyFunction}}

\defineXMLentity [PlusMinus]        {\getXMLentity{plusminus}}

\defineXMLentity [infin]            {\getXMLentity{infinity}}
\defineXMLentity [infty]            {\getXMLentity{infinity}}
\defineXMLentity [part]             {\getXMLentity{differentiald}}

\defineXMLentity [RightArrow] {\normalorfiller\rightarrow\rightarrowfill}
\defineXMLentity [LeftArrow]  {\normalorfiller\leftarrow\leftarrowfill}
\defineXMLentity [UnderBrace] {\normalorfiller\empty\upbracefill}
\defineXMLentity [OverBrace]  {\normalorfiller\empty\downbracefill}
\defineXMLentity [UnderBar]   {\normalorfiller\hrule\hrulefill}
\defineXMLentity [OverBar]    {\normalorfiller\hrule\hrulefill}
\defineXMLentity [Hat]        {\normalorfiller\empty\empty} % todo

\defineXMLentity [downarrow]  {\mathortext\downarrow\empty}
\defineXMLentity [uparrow]    {\mathortext\uparrow\empty}

\defineXMLentity [Tab]              {\hskip4em}
\defineXMLentity [NewLine]          {\mathortext\empty\crlf}
\defineXMLentity [IndentingNewLine] {\mathortext\empty\crlf}

\defineXMLentity [NoBreak]          {\nobreak}
\defineXMLentity [GoodBreak]        {\goodbreak}
\defineXMLentity [BadBreak]         {\nobreak}

\defineXMLentity [Space]            {\getXMLentity{MediumSpace}}
\defineXMLentity [NonBreakingSpace] {\getXMLentity{MediumSpace}}
\defineXMLentity [ZeroWidthSpace]   {}

\def\somespaceentity#1#2%
  {\mathortext
     {\mskip#1mu}
     {\ifvmode\dontleavehmode\else\unskip\fi\hskip#2em\strut\hskip\zeropoint\ignorespaces}%
   \relax}

\defineXMLentity [VeryThinSpace]         {\somespaceentity {2}{.125}}
\defineXMLentity [ThinSpace]             {\somespaceentity {3}{.25}}
\defineXMLentity [MediumSpace]           {\somespaceentity {4}{.5}}
\defineXMLentity [ThickSpace]            {\somespaceentity {5}{1}}
\defineXMLentity [NegativeVeryThinSpace] {\somespaceentity{-2}{-.125}}
\defineXMLentity [NegativeThinSpace]     {\somespaceentity{-3}{-.25}}
\defineXMLentity [NegativeMediumSpace]   {\somespaceentity{-4}{-.5}}
\defineXMLentity [NegativeThickSpace]    {\somespaceentity{-5}{-1}}

\defineXMLentity [NegVeryThinSpace] {\getXMLentity{NegativeVeryThinSpace}}
\defineXMLentity [NegThinSpace]     {\getXMLentity{NegativeThinSpace}}
\defineXMLentity [NegMediumSpace]   {\getXMLentity{NegativeMediumSpace}}
\defineXMLentity [NegThickSpace]    {\getXMLentity{NegativeThickSpace}}

\defineXMLentity [nbsp]    {\getXMLentity{NonBreakingSpace}}
\defineXMLentity [thinsp]  {\getXMLentity{ThinSpace}}
\defineXMLentity [medsp]   {\getXMLentity{MediumSpace}}
\defineXMLentity [thicksp] {\getXMLentity{ThickSpace}}

\defineXMLentity [larr]         {\getXMLentity{LeftArrow}}
\defineXMLentity [rarr]         {\getXMLentity{RightArrow}}

\defineXMLentity [lbrace]       {\normalordelimiter{\{}{\left \{}}
\defineXMLentity [rbrace]       {\normalordelimiter{\}}{\right\}}}
\defineXMLentity [lbracket]     {\normalordelimiter{[}{\left [}}
\defineXMLentity [rbracket]     {\normalordelimiter{]}{\right]}}
\defineXMLentity [lparenthesis] {\normalordelimiter{(}{\left (}}
\defineXMLentity [rparenthesis] {\normalordelimiter{)}{\right)}}
\defineXMLentity [langle]       {\normalordelimiter{\langle}{\left \langle}}
\defineXMLentity [rangle]       {\normalordelimiter{\rangle}{\right\rangle}}

\defineXMLentity [lang]         {\getXMLentity{langle}}
\defineXMLentity [rang]         {\getXMLentity{rangle}}
\defineXMLentity [lbrack]       {\getXMLentity{lbracket}}
\defineXMLentity [rbrack]       {\getXMLentity{rbracket}}
\defineXMLentity [lparent]      {\getXMLentity{lparenthesis}}
\defineXMLentity [rparent]      {\getXMLentity{rparenthesis}}

\defineXMLentity [\letterleftbrace ] {\getXMLentity{lbrace}}
\defineXMLentity [\letterrightbrace] {\getXMLentity{rbrace}}

\defineXMLentity [{[}] {\getXMLentity{lbracket}}
\defineXMLentity [{]}] {\getXMLentity{rbracket}}
\defineXMLentity [{(}] {\getXMLentity{lparenthesis}}
\defineXMLentity [{)}] {\getXMLentity{rparenthesis}}

\defineXMLentity [times]  {\times}
\defineXMLentity [minus]  {-}
\defineXMLentity [plus]   {+}
\defineXMLentity [plusmn] {\pm}

\defineXMLentity [nabla]  {\nabla}

\def\myspecialnormalvert{\mathematics{\vert}} % temp hack, should stretch

\defineXMLentity [,] {{,}}
\defineXMLentity [.] {{.}}
\defineXMLentity [+] {+}
\defineXMLentity [-] {-}
\defineXMLentity [(] {(}
\defineXMLentity [)] {)}
\defineXMLentity [<] {\mathematics{<}}
\defineXMLentity [>] {\mathematics{>}}
\defineXMLentity [|] {\myspecialnormalvert}
\defineXMLentity [/] {/}
\defineXMLentity [*] {\times}
\defineXMLentity [=] {=}

\defineXMLentity [++] {++}
\defineXMLentity [--] {--}
\defineXMLentity [//] {//}
\defineXMLentity [**] {\times\times}
\defineXMLentity [==] {==}

\defineXMLentity [quot]  {"}

\defineXMLentity [triangle]       {\mathematics\triangle}
\defineXMLentity [otimes]         {\mathematics\otimes}
\defineXMLentity [oplus]          {\mathematics\oplus}
\defineXMLentity [cup]            {\mathematics\cup}
\defineXMLentity [cap]            {\mathematics\cap}
\defineXMLentity [sdot]           {\mathematics\cdot}
\defineXMLentity [dot]            {\mathematics\cdot}
\defineXMLentity [sim]            {\mathematics\sim}
\defineXMLentity [circ]           {\mathematics\circ}
\defineXMLentity [dagger]         {\mathematics\dagger}
\defineXMLentity [cdots]          {\mathematics\cdots}

\defineXMLentity [...]            {\getXMLentity{cdots}}
\defineXMLentity [continued]      {\getXMLentity{cdots}}

\defineXMLentity [sub]            {\getXMLentity{subset}}
\defineXMLentity [sube]           {\getXMLentity{prsubset}}
\defineXMLentity [notprsubset]    {\getXMLentity{notprsubset}}

\defineXMLentity [ndash]          {\endash}
\defineXMLentity [mdash]          {\emdash}

\defineXMLentity [tex-bar]        {\mathematics{\vert}}
\defineXMLentity [tex-dollar]     {\dollar}
\defineXMLentity [tex-backslash]  {\backslash}
\defineXMLentity [tex-leftbrace]  {\mathematics{\{}}
\defineXMLentity [tex-rightbrace] {\mathematics{\}}}

\protect \endinput
