%D \module
%D   [       file=x-newmml,
%D        version=2006.04.09, % reimplementation
%D          title=\CONTEXT\ XML Macros,
%D       subtitle=ChemML,
%D         author=Hans Hagen,
%D           date=\currentdate,
%D      copyright={PRAGMA ADE}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.

%D This used to be an xtag filter using remapping but the
%D following is nore in sync with the new mathml methods.

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

\useXMLfilter[stk]

\unprotect

\def\setupCMLappearance[#1]{\dodoubleargument\getparameters[@@CML#1]}

\defineXMLdirective [chemml] \setupCMLappearance

\defineXMLargument [chem]  \automathematics    % \rm
\defineXMLargument [ichem] \inlinemathematics  % \rm
\defineXMLargument [dchem] \displaymathematics % \rm

\def\doifnotXMLparzero#1#2#3%
  {\ifcase\XMLpar{#1}{#2}{0}\else#3{\XMLpar{#1}{#2}{0}}\fi}

\defineXMLargument [caption] \doCMLcaption

\let\CMLtopcaption\empty
\let\CMLbotcaption\empty

\chardef\CMLcaptionmode\plusone

\def\doCMLcaption#1%
  {\ifcase\CMLcaptionmode
     % can't happen
   \or
     \def\CMLbotcaption{#1}%
     \chardef\CMLcaptionmode\plustwo
   \or
     \def\CMLtopcaption{#1}%
     \chardef\CMLcaptionmode\plusthree
   \fi}

\def\resetCMLcaption
  {\let\CMLtopcaption\empty
   \let\CMLbotcaption\empty
   \chardef\CMLcaptionmode\plusone}

\resetCMLcaption

\def\doCMLtext#1%
  {\ifx\CMLtopcaption\empty
     \setbox0\null
   \else
     \setbox0\hbox{\txx\setstrut\strut\ignorespaces\CMLtopcaption\unskip}%
   \fi
   \setbox2\hbox{\ignorespaces\strut#1\unskip}%
   \ifx\CMLbotcaption\empty
     \setbox4\null
   \else
     \setbox4\hbox{\txx\setstrut\strut\ignorespaces\CMLbotcaption\unskip}%
   \fi
   \scratchdimen=\wd2\advance\scratchdimen-.5em
   \ifdim\wd0>\scratchdimen
     \setbox0\hbox spread .5em{\hss\box0\hss}%
   \fi
   \ifdim\wd4>\scratchdimen
     \setbox4\hbox spread .5em{\hss\box4\hss}%
   \fi
   \setbox6=\vbox
     {\offinterlineskip\halign{\hss##\hss\cr\copy0\cr\copy2\cr\copy4\cr}}%
   \hbox{\lower\ht4\hbox{\lower\dp2\box6}}}

\def\CMLscript#1%
  {$\scriptscriptstyle\ignorespaces#1\unskip$}

% \startsetups cml:flush:all
%     \ignorespaces
%     \XMLallnamed{atom,bond,singlebond,doublebond,triplebond}
%     \removeunwantedspaces
% \stopsetups

\newcounter\currentCMLatom
\newcounter\nofCMLatoms

\defineXMLenvironmentsave
  [atom]
  [n=0,weight=0,protons=0,charge=0]
  {\directsetup{cml:atom:start}}
  {\directsetup{cml:atom:stop}}

\startsetups cml:atom:start
  \removeunwantedspaces
\stopsetups

\startsetups cml:atom:stop
    \increment\currentCMLatom
    \resetCMLcaption
    \doCMLtext {
        \bgroup
        \lohi {
            \doifnotXMLparzero{atom}{protons}\CMLscript
        } {
            \doifnotXMLparzero{atom}{weight}\CMLscript
        }
        \ignorespaces
        \XMLflush{atom}
        \removeunwantedspaces
        \lohi {
            \doifnotXMLparzero{atom}{n}\CMLscript
        } {
            \ifnum\nofCMLatoms=\currentCMLatom\relax
                \doifnotXMLparzero{ion}{charge}\CMLscript
            \else
                \doifnotXMLparzero{atom}{charge}\CMLscript
            \fi
        }
      \egroup
    }
   \ignorespaces
\stopsetups

\defineXMLnested % why not environment
  [molecule]
  [n=0]
  {\directsetup{cml:molecule:start}}
  {\directsetup{cml:molecule:stop}}

\startsetups cml:molecule:start
    \removeunwantedspaces
    \begingroup
    \startsavingXMLelements
    \ignorespaces
\stopsetups

\startsetups cml:molecule:stop
    \removeunwantedspaces
    \stopsavingXMLelements
    \resetCMLcaption
    \XMLfirstnamed{caption}
    \doCMLtext {
        \newcounter\currentCMLatom
        \newcounter\nofCMLatoms
        \doifnotXMLparzero{molecule}{n}\firstofoneargument
        \ignorespaces
        \XMLallnamed{atom,ion,bond,singlebond,doublebond,triplebond}
        \removeunwantedspaces
    }
    \endgroup
    \ignorespaces
\stopsetups

\setupCMLappearance [ion] [\c!alternative=\v!a]

\defineXMLnested
  [ion]
  [n=0,charge=0]
  {\directsetup{cml:ion:start}}
  {\directsetup{cml:ion:stop}}

\startsetups cml:ion:start
    \begingroup
    \startsavingXMLelements
\ignorespaces
\stopsetups

\startsetups cml:ion:stop
    \removeunwantedspaces
    \stopsavingXMLelements
    \resetCMLcaption
    \XMLfirstnamed{caption}
    \doCMLtext {
        \newcounter\currentCMLatom
        \newcounter\nofCMLatoms
        \doifnotXMLparzero{ion}{n}\firstofoneargument
        \doifelse\@@CMLionalternative\v!b {
            [\ignorespaces
            \XMLallnamed{atom,bond,singlebond,doublebond,triplebond}
            \removeunwantedspaces]
            \high {
                \doifnotXMLparzero{ion}{charge}\CMLscript
            }
        } {
            \countXMLnamedstack{atom}
            \edef\nofCMLatoms{\the\scratchcounter}% todo: \nofXMLchildren
            \ignorespaces
            \XMLallnamed{atom,bond,singlebond,doublebond,triplebond}
            \removeunwantedspaces
        }
    }
    \endgroup
    \ignorespaces
\stopsetups

\let\doCMLsymbol\gobbleoneargument
\let\doCMLarrow \gobblethreearguments

\defineXMLenvironment
  [reaction]
  {\directsetup{cml:reaction:start}}
  {\directsetup{cml:reaction:stop}}

\startsetups cml:reaction:start
    \begingroup
    \let\doCMLsymbol\dodoCMLsymbol
    \let\doCMLarrow \dodoCMLarrow
\stopsetups

\startsetups cml:reaction:stop
    \endgroup
\stopsetups

\defineXMLcommand [plus]  {\doCMLsymbol{+}}
\defineXMLcommand [minus] {\doCMLsymbol{-}}
\defineXMLcommand [equal] {\doCMLsymbol{=}}

\def\dodoCMLsymbol#1%
  {\removeunwantedspaces\quad
   \mathop{#1}%
   \quad\kern\zeropoint\ignorespaces}

\defineXMLcommand [gives]       {\resetCMLcaption\doCMLgives}
\defineXMLcommand [equilibrium] {\resetCMLcaption\doCMLequilibrium}
\defineXMLcommand [mesomeric]   {\resetCMLcaption\doCMLmesomeric}

\def\dodoCMLarrow#1%
  {\removeunwantedspaces\quad
   \doCMLtext{$\vcenter{\offinterlineskip\halign{##\cr\hskip3em\cr#1\cr}}$}%
   \quad\kern\zeropoint\ignorespaces}

\def\doCMLgives
  {\doCMLarrow{\rightarrowfill}}

\def\doCMLequilibrium
  {\doCMLarrow{\rightarrowfill\cr\noalign{\nointerlineskip}\leftarrowfill}}

\def\doCMLmesomeric
  {\doCMLarrow{$\leftarrow\hskip-1em$\rightarrowfill}}

\defineXMLcommand [bond]       [n=1] \doCMLbond
\defineXMLcommand [singlebond] [n=1] \doCMLsinglebond
\defineXMLcommand [doublebond] [n=1] \doCMLdoublebond
\defineXMLcommand [triplebond] [n=1] \doCMLtriplebond

\def\doCMLbond
  {\ifcase\XMLop{n}\relax
     \doCMLsinglebond
   \or
     \doCMLdoublebond
   \or
     \doCMLtriplebond
   \fi}

\def\doCMLbond
  {\removeunwantedspaces
   \hrule \!!width \hsize \!!height .1ex\relax % .4pt
   \ignorespaces}

\def\dodoCMLbond#1#2#3%
  {\removeunwantedspaces
   \begingroup
   \setbox\scratchbox\hbox{$M$}%
   \vbox to \ht\scratchbox
     {\hsize\wd\scratchbox
      \vskip.1\wd\scratchbox
      #1\vfill#2\vfill#3%
      \vskip.1\wd\scratchbox}%
   \endgroup
   \ignorespaces}

\def\doCMLsinglebond{\dodoCMLbond\relax    \doCMLbond\relax      }
\def\doCMLdoublebond{\dodoCMLbond\doCMLbond\relax    \doCMLbond}
\def\doCMLtriplebond{\dodoCMLbond\doCMLbond\doCMLbond\doCMLbond}

% extensions (uses m-chemic, which thenneeds to be loaded)

% <dchem>
%   <structure>
%     <component>
%       <graphic>SIX,B</graphic>
%       <graphic>R135</graphic>
%     </component>
%     <component>
%       <graphic>R246</graphic>
%     </component>
%     <component>
%       <graphic>RZ</graphic>
%       <text>A,B,C,D,E,F</text>
%     </component>
%     <component>
%       <graphic>Z</graphic>
%       <oxidation n="3">A</oxidation>
%       <annotation location="tl">
%         <text>B</text>
%         <caption>x</caption>
%       </annotation>
%       <oxidation n="3" sign="+">C</oxidation>
%       <text>D,E,F</text>
%     </component>
%   </structure>
%   <structure>
%     <component>
%       <graphic>SIX,B</graphic>
%       <graphic>r135</graphic>
%     </component>
%     <component>
%       <graphic>R246</graphic>
%     </component>
%     <component>
%       <graphic>RZ</graphic>
%       <text>A,B,C,D,E,F</text>
%     </component>
%   </structure>
% </dchem>

\ifx\XMLttoks \undefined \newtoks \XMLttoks \fi
\ifx\XMLgtoks \undefined \newtoks \XMLgtoks \fi

\ifx\startchemical\undefined
  \def\startchemical   {\hbox{module chemic is not loaded}}
  \let\stopchemical    \relax
  \def\chemical[#1][#2]{}
\fi

\defineXMLenvironment
  [structure]
  {\startchemical
   \ignorespaces}
  {\removeunwantedspaces
   \stopchemical}

\defineXMLenvironment
  [component]
  {\global\XMLgtoks\emptytoks
   \global\XMLttoks\emptytoks
   \defineXMLargument[graphic]{\dogetCMLgraphic}%
   \defineXMLargument[text]   {\dogetCMLtext}%
   \ignorespaces}
  {\removeunwantedspaces
   \expanded{\chemical[\the\XMLgtoks][\the\XMLttoks]}%
   \ignorespaces}

\def\dogetCMLgraphic#1%
  {\doifelsenothing{\the\XMLgtoks}
     {\uppercase{\doglobal\appendtoks #1\to\XMLgtoks}}
     {\uppercase{\doglobal\appendtoks,#1\to\XMLgtoks}}%
   \ignorespaces}

\def\dogetCMLtext#1%
  {\doifelsenothing{\the\XMLttoks}
     {\uppercase{\doglobal\appendtoks #1\to\XMLttoks}}
     {\uppercase{\doglobal\appendtoks,#1\to\XMLttoks}}%
   \ignorespaces}

\defineXMLargument
  [oxidation]
  [sign=,n=1]
  {\doCMLoxidation}

\def\doCMLoxidation#1%
  {\expanded{\dogetCMLtext{\noexpand\chemicaloxidation{\XMLop{sign}}{\XMLop{n}}{#1}}}%
   \ignorespaces}

% \defineXMLenvironment
%   [annotation]
%   [location=]
%   {\defineXMLsave[text]%
%    \defineXMLsave[caption]}
%   {\removeunwantedspaces
%    \processaction
%      [\XMLpar{annotation}{location}{r}]
%      [ t=>\dodoCMLannotation\chemicaltop,
%        b=>\dodoCMLannotation\chemicalbottom,
%        l=>\dodoCMLannotation\chemicalleft,
%        r=>\dodoCMLannotation\chemicalright,
%       lc=>\dodoCMLannotation\chemicalleftcentered,
%       rc=>\dodoCMLannotation\chemicalrightcentered,
%       tl=>\dodoCMLannotation\chemicaltopleft,
%       bl=>\dodoCMLannotation\chemicalbottomleft,
%       tr=>\dodoCMLannotation\chemicaltopright,
%       br=>\dodoCMLannotation\chemicalbottomright,
%       lt=>\dodoCMLannotation\chemicallefttop,
%       lb=>\dodoCMLannotation\chemicalleftbottom,
%       rt=>\dodoCMLannotation\chemicalrighttop,
%       rb=>\dodoCMLannotation\chemicalrightbottom,
%        x=>\dodoCMLannotation\chemicaltighttext,
%       sl=>\dodoCMLannotation\chemicalsmashedleft,
%       sm=>\dodoCMLannotation\chemicalsmashedmiddle,
%       sr=>\dodoCMLannotation\chemicalsmashedright]%
%    \ignorespaces}

% todo: generic mapper t -> top etc

\mapXMLvalue {cml:a:l} {t}  {\dodoCMLannotation\chemicaltop}
\mapXMLvalue {cml:a:l} {b}  {\dodoCMLannotation\chemicalbottom}
\mapXMLvalue {cml:a:l} {l}  {\dodoCMLannotation\chemicalleft}
\mapXMLvalue {cml:a:l} {r}  {\dodoCMLannotation\chemicalright}
\mapXMLvalue {cml:a:l} {lc} {\dodoCMLannotation\chemicalleftcentered}
\mapXMLvalue {cml:a:l} {rc} {\dodoCMLannotation\chemicalrightcentered}
\mapXMLvalue {cml:a:l} {tl} {\dodoCMLannotation\chemicaltopleft}
\mapXMLvalue {cml:a:l} {bl} {\dodoCMLannotation\chemicalbottomleft}
\mapXMLvalue {cml:a:l} {tr} {\dodoCMLannotation\chemicaltopright}
\mapXMLvalue {cml:a:l} {br} {\dodoCMLannotation\chemicalbottomright}
\mapXMLvalue {cml:a:l} {lt} {\dodoCMLannotation\chemicallefttop}
\mapXMLvalue {cml:a:l} {lb} {\dodoCMLannotation\chemicalleftbottom}
\mapXMLvalue {cml:a:l} {rt} {\dodoCMLannotation\chemicalrighttop}
\mapXMLvalue {cml:a:l} {rb} {\dodoCMLannotation\chemicalrightbottom}
\mapXMLvalue {cml:a:l} {x}  {\dodoCMLannotation\chemicaltighttext}
\mapXMLvalue {cml:a:l} {sl} {\dodoCMLannotation\chemicalsmashedleft}
\mapXMLvalue {cml:a:l} {sm} {\dodoCMLannotation\chemicalsmashedmiddle}
\mapXMLvalue {cml:a:l} {sr} {\dodoCMLannotation\chemicalsmashedright}

% \mapXMLvalue {cml:a:l} {cl} {\dodoCMLannotation\chemicalleftcentered}
% \mapXMLvalue {cml:a:l} {cr} {\dodoCMLannotation\chemicalrightcentered}
% \mapXMLvalue {cml:a:l} {lt} {\dodoCMLannotation\chemicaltopleft}
% \mapXMLvalue {cml:a:l} {lb} {\dodoCMLannotation\chemicalbottomleft}
% \mapXMLvalue {cml:a:l} {rt} {\dodoCMLannotation\chemicaltopright}
% \mapXMLvalue {cml:a:l} {rb} {\dodoCMLannotation\chemicalbottomright}
% \mapXMLvalue {cml:a:l} {tl} {\dodoCMLannotation\chemicallefttop}
% \mapXMLvalue {cml:a:l} {bl} {\dodoCMLannotation\chemicalleftbottom}
% \mapXMLvalue {cml:a:l} {tr} {\dodoCMLannotation\chemicalrighttop}
% \mapXMLvalue {cml:a:l} {br} {\dodoCMLannotation\chemicalrightbottom}
% \mapXMLvalue {cml:a:l} {ls} {\dodoCMLannotation\chemicalsmashedleft}
% \mapXMLvalue {cml:a:l} {ms} {\dodoCMLannotation\chemicalsmashedmiddle}
% \mapXMLvalue {cml:a:l} {rs} {\dodoCMLannotation\chemicalsmashedright}

\defineXMLenvironment
  [annotation]
  [location=]
  {\pushXMLmeaning{text}%
   \pushXMLmeaning{caption}%
   \defineXMLsave[text]%
   \defineXMLsave[caption]}
  {\removeunwantedspaces
   \XMLval{cml:a:l}{\XMLpar{annotation}{location}{r}}{\XMLflush{text}}%
   \popXMLmeaning{text}%
   \popXMLmeaning{caption}%
   \ignorespaces}

\def\dodoCMLannotation#1%
  {\expanded{\dogetCMLtext{\noexpand#1{\XMLflush{caption}}{\XMLflush{text}}}}}

\defineXMLenvironment
  [forever]
  {\left[}
  {\right]}

\protect \endinput
