%D \module
%D   [       file=chem-ini,
%D        version=2009.05.13,
%D       subtitle=Chemistry,
%D         author=Hans Hagen \& Alan Braslau,
%D           date=\currentdate,
%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
%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 The original \PPCHTEX\ code was written in pure \TEX\, although later we made
%D the move from \PICTEX\ to \METAPOST\. The current implementation is a mix between
%D \TEX\, \LUA\ and \METAPOST. Although the first objective is to get a compatible
%D but better implementation, later versions might provide more,

%D NOT YET LMTX'd

\writestatus{loading}{ConTeXt Chemistry Macros / Structure}

\registerctxluafile{chem-str}{}

% We have a slightly different interface. This is unchanged:
%
% \startchemical[axis=on]
%     \chemical[SIX,ROT2,B,R6,SUB1,FIVE,ROT1,B][1]
% \stopchemical
%
% Here we use chemicalformula instead, so no longer a mix:
%
% \startchemicalformula
%     \chemical{2H_2}{top}{bottom}
%     \chemical{PLUS}{top}{bottom}
%     \chemical{O_2}{top}{bottom}
%     \chemical{GIVES}{top}{bottom}
%     \chemical{2H_2O}{top}{bottom}
% \stopchemicalformula
%
% \startchemicalformula
%     \chemical{2H_2}
%     \chemical{PLUS}
%     \chemical{O_2}
%     \chemical{GIVES}
%     \chemical{2H_2O}
% \stopchemicalformula
%
% The inline variant has only one argument:
%
% \chemical{2H_2,PLUS,O_2,GIVES,2H_2O}

\unprotect

\installcorenamespace{chemical}
\installcorenamespace{chemicalsymbol}
\installcorenamespace{chemicalframed}
\installcorenamespace{chemicalsize}

% \installsimplecommandhandler \??chemical {chemical} \??chemical % no \define...
\installcommandhandler \??chemical {chemical} \??chemical % no \define...

\aliased\let\setupchemicals \setupchemical
\aliased\let\definechemicals\definechemical

%D We use a dedicated framed macro instead of inheriting one. This is both
%D a historical and practical reason (like shared keys with different meaning
%D that could clash, e.g.\ align).

\defineMPinstance % not really needed as we set in lua
  [chemistry]
  [\s!format=metafun,
  %\s!extensions=\v!yes,      % Should we add extensions and initializations?
  %\s!initializations=\v!yes, % Would this give EmWidth, etc.?
   \c!method=\s!double]

\startMPdefinitions{chemistry}
    loadmodule "chem" ;
\stopMPdefinitions

\defineframed
  [\??chemicalframed]
  [\c!align=\v!normal,
   \c!strut=\v!no]

\mutable\lettonothing\currentdefinedchemical

\permanent\protected\def\setupchemicalframed
  {\setupframed[\??chemicalframed]}

\permanent\protected\tolerant\overloaded\def\definechemical[#1]#:#2% is global (so we don't use the commandhandler)
  {\startnointerference
   \cdef\currentdefinedchemical{#1}%
   \enforced\let\chemical\chem_chemical_nested
   \clf_undefinechemical{#1}%
   #2% flush
   \stopnointerference}

\permanent\tolerant\protected\def\chem_chemical_nested[#1]#*[#2]%
  {\clf_definechemical{\currentdefinedchemical}{#1}{\detokenize{#2}}}

% chemical symbols

\permanent\tolerant\protected\def\definechemicalsymbol[#1]#*[#2]%
  {\ifarguments\else\defcsname\??chemicalsymbol#1\endcsname{#2}\fi}

\permanent\protected\def\chemicalsymbol[#1]%
  {\csname\??chemicalsymbol\ifcsname\??chemicalsymbol#1\endcsname#1\else\s!unknown\fi\endcsname}

\definechemicalsymbol[\s!unknown][] % \char"FFFD empty

% size (small medium big)

% \edef\chemicaltoplocation{t}
% \edef\chemicalbotlocation{b}

\permanent\protected\def\chemicaltext#1%
  {\mathematics
     {\usechemicalstyleandcolor\c!style\c!color
      \strut
      \ifcase\currentxfontsize\or\scriptstyle\or\scriptscriptstyle\fi
      #1}}

\defcsname\??chemicalsize\v!small \endcsname{\txx}
\defcsname\??chemicalsize\v!medium\endcsname{\tx}
\defcsname\??chemicalsize\v!big   \endcsname{}

\newtoks       \everychemical
\newtoks       \everystructurechemical

\newtoks       \t_chem_every_box
\newbox        \b_chem_result
\newconditional\c_chem_some_text
\newdimension  \d_chem_width
\newdimension  \d_chem_height
\newdimension  \d_chem_depth

\permanent\tolerant\protected\def\startchemical[#S#1]#*[#S#2]%
  {\ifmmode\vcenter\else\vbox\fi % vpack ?
   \bgroup
   \synchronizestrut{\chemicalparameter\c!strut}%
   \dontcomplain
   \forgetall
   \ifparameter#2\or
     \ifhastok={#1}%
       \setupcurrentchemical[#1]% same as \currentchemical
     \else
       \cdef\currentchemical{#1}%
       \setupcurrentchemical[#2]%
     \fi
   \orelse\ifparameter#1\or
     \ifhastok={#1}%
       \setupcurrentchemical[#1]% same as \currentchemical
     \else
       \cdef\currentchemical{#1}%
     \fi
   \fi
   \expand\everystructurechemical
   \setbox\b_chem_result\hpack\bgroup
   \clf_startchemical
     width         {\chemicalparameter\c!width}%
     height        {\chemicalparameter\c!height}%
     left          {\chemicalparameter\c!left}%
     right         {\chemicalparameter\c!right}%
     top           {\chemicalparameter\c!top}%
     bottom        {\chemicalparameter\c!bottom}%
     scale         {\chemicalparameter\c!scale}%
     rotation      {\chemicalparameter\c!rotation}%
     symalign      {\chemicalparameter\c!symalign}%
     axis          {\chemicalparameter\c!axis}% was \MPcolor{...}
     framecolor    {\chemicalparameter\c!framecolor}%
     rulethickness {\chemicalparameter\c!rulethickness}%
     offset        {\chemicalparameter\c!offset}%
     unit          {\chemicalparameter\c!unit}%
     factor        {\chemicalparameter\c!factor}%
   \relax
   \startnointerference}

\permanent\protected\def\stopchemical
  {\stopnointerference
   \clf_stopchemical
   \egroup
   \d_chem_width \wd\b_chem_result
   \d_chem_height\ht\b_chem_result
   \d_chem_depth \dp\b_chem_result
   \expand\t_chem_every_box
   \ifempty{\chemicalparameter\c!frame}%
     \chem_framed_nop
   \else
     \chem_framed_yes
   \fi
   \egroup}

\protected\def\chem_framed_yes
  {\localframedwithsettings
     [\??chemicalframed]%
     [\c!frame=\chemicalparameter\c!frame,
      \c!rulethickness=\chemicalparameter\c!rulethickness,
      \c!framecolor=\chemicalparameter\c!framecolor]%
     {\vpack{\box\b_chem_result\vss}}} % remove depth

\protected\def\chem_framed_nop
  {\directlocalframed
     [\??chemicalframed]%
     {\vpack{\box\b_chem_result\vss}}} % remove depth

\aliased\let\startstructurechemical\startchemical
\aliased\let\stopstructurechemical \stopchemical

\appendtoks
    \enforced\let\chemical\structurechemical
\to\everystructurechemical

\permanent\tolerant\protected\def\structurechemical[#1]#*[#2]#*[#S#3]%
  {\ifparameter#3\or
     \expandafter\strc_chem_indeed_three
   \else
     \expandafter\strc_chem_indeed_two
   \fi[#1][#2][#3]}

\def\strc_chem_indeed_three[#1][#2][#3]%
  {\writestatus\m!chemicals{hyperlinked chemicals not yet supported}% todo reference, for the moment ignored
   \clf_chemicalcomponent
      {#2}%
      {\detokenize{#3}}%
      {\todimension{\chemicalparameter\c!rulethickness}}% todo: scaled points
      {\chemicalparameter\c!rulecolor}%
   \relax
   \ignorespaces}

\def\strc_chem_indeed_two[#1][#S#2]% why no [#3] here
  {\clf_chemicalcomponent
      {#1}%
      {\detokenize{#2}}%
      {\todimension{\chemicalparameter\c!rulethickness}}% todo: scaled points
      {\chemicalparameter\c!rulecolor}%
   \relax
   \ignorespaces}

\appendtoks
    \setbox\b_chem_result\hpack{\raise\MPlly\box\b_chem_result}%
    \d_chem_width \wd\b_chem_result
    \d_chem_height\ht\b_chem_result
    \d_chem_depth \dp\b_chem_result
\to \t_chem_every_box

% kind of compatible, but text sizes instead of math sizes (i.e. tx is larger than scriptsize)

\appendtoks
    \usebodyfontparameter\chemicalparameter
  % \edef\m_bodyfont{\chemicalparameter\c!bodyfont}%
  % \ifempty\m_bodyfont\else
  %     \switchtobodyfont[\m_bodyfont]%
  % \fi
    \begincsname\??chemicalsize\chemicalparameter\c!size\endcsname
% \to \everystructurechemical
\to \everychemical

\lettonothing\m_chem_top_text
\lettonothing\m_chem_bot_text
\lettonothing\m_chem_mid_text

\permanent\protected\def\chemicaltoptext#1{\global\c_chem_some_text\conditionaltrue\gdef\m_chem_top_text{#1}\ignorespaces}
\permanent\protected\def\chemicalbottext#1{\global\c_chem_some_text\conditionaltrue\gdef\m_chem_bot_text{#1}\ignorespaces}
\permanent\protected\def\chemicalmidtext#1{\global\c_chem_some_text\conditionaltrue\gdef\m_chem_mid_text{#1}\ignorespaces}

\mutable\lettonothing\toptext
\mutable\lettonothing\bottext
\mutable\lettonothing\midtext

\appendtoks
    \let\toptext\chemicaltoptext \glettonothing\m_chem_top_text
    \let\bottext\chemicalbottext \glettonothing\m_chem_bot_text
    \let\midtext\chemicalmidtext \glettonothing\m_chem_mid_text
    \global\c_chem_some_text\conditionalfalse
\to \everystructurechemical

\def\chem_add_texts
  {\setbox\scratchboxone  \hpack to \d_chem_width{\strut\hss\hbox{\strut\m_chem_mid_text}\hss}%
   \setbox\scratchboxtwo  \hpack to \d_chem_width{\strut\hss\hbox{\strut\m_chem_top_text}\hss}%
   \setbox\scratchboxthree\hpack to \d_chem_width{\strut\hss\hbox{\strut\m_chem_bot_text}\hss}%
   \setbox\b_chem_result\hpack \bgroup
     \box\b_chem_result
     \kern-\d_chem_width
     \raise\d_chem_height\hpack{\lower\ht\scratchboxtwo\box\scratchboxtwo}%
     \kern-\d_chem_width
     \lower{(\ht\scratchboxone-\dp\scratchboxone)/2}\box\scratchboxone
     \kern-\d_chem_width
     \lower\d_chem_depth\hpack{\raise\dp\scratchboxthree\box\scratchboxthree}%
     \hss
   \egroup} % text on top of chemicals

\appendtoks
    \ifconditional\c_chem_some_text
      \chem_add_texts
      \d_chem_width \wd\b_chem_result
      \d_chem_height\ht\b_chem_result
      \d_chem_depth \dp\b_chem_result
    \fi
\to \t_chem_every_box

% todo: enspace or emspace

\definechemicalsymbol[space]       [\enspace\quad\enspace]
\definechemicalsymbol[plus]        [\enspace+\enspace]
\definechemicalsymbol[minus]       [\enspace-\enspace]
\definechemicalsymbol[gives]       [\chem_arrow_construct\xrightarrow]
\definechemicalsymbol[equilibrium] [\chem_arrow_construct\xrightoverleftarrow]
\definechemicalsymbol[mesomeric]   [\chem_arrow_construct\xleftrightarrow]
\definechemicalsymbol[opencomplex] [\mathematics{\Bigg[}] % not yet ok
\definechemicalsymbol[closecomplex][\mathematics{\Bigg]}] % not yet ok

\definechemicalsymbol[SPACE]       [{\chemicalsymbol[space]}]
\definechemicalsymbol[PLUS]        [{\chemicalsymbol[plus]}]
\definechemicalsymbol[MINUS]       [{\chemicalsymbol[minus]}]
\definechemicalsymbol[GIVES]       [{\chemicalsymbol[gives]}]
\definechemicalsymbol[EQUILIBRIUM] [{\chemicalsymbol[equilibrium]}]
\definechemicalsymbol[MESOMERIC]   [{\chemicalsymbol[mesomeric]}]
\definechemicalsymbol[OPENCOMPLEX] [{\chemicalsymbol[opencomplex]}]
\definechemicalsymbol[CLOSECOMPLEX][{\chemicalsymbol[closecomplex]}]

\def\chem_arrow_construct#1#2#3%
  {\enspace
   \mathematics{#1%
     {\strut\hbox \s!spread 2\emwidth{\hss\clf_inlinechemical{#3}\hss}}%   {\strut\hbox \s!spread 2em{\hss#3\hss}}}%
     {\strut\hbox \s!spread 2\emwidth{\hss\clf_inlinechemical{#2}\hss}}}%  {\strut\hbox \s!spread 2em{\hss#2\hss}}%
   \enspace}

% special macros (probably needs some more work)

\let\chem_box_normal_yes\hbox
\let\chem_box_visual_yes\hbox
\let\chem_box_visual_nop\relax

\installtextracker
  {chemistry.boxes}
  {\let\chem_box_visual_yes\ruledhbox \let\chem_box_visual_nop\ruledhbox}
  {\let\chem_box_visual_yes\hbox      \let\chem_box_visual_nop\relax    }

\def\chem_top_construct#1#2#3#4%
  {\hpack\bgroup
   \setstrut
   \setbox\scratchboxone\chem_box_visual_yes{\strut#3}%
   \setbox\scratchboxtwo\chem_box_visual_yes{\strut\molecule{#4}}%
   \setbox\scratchboxone\chem_box_normal_yes{\raise{\dp\scratchboxone+\ht\scratchboxtwo}\hbox to \wd\scratchboxtwo{#1\box\scratchboxone#2}}%
   \smashbox\scratchboxone
   \box\scratchboxone
   \box\scratchboxtwo
   \egroup}

\def\chem_bottom_construct#1#2#3#4%
  {\hpack\bgroup
   \setstrut
   \setbox\scratchboxone\chem_box_visual_yes{\strut#3}%
   \setbox\scratchboxtwo\chem_box_visual_yes{\strut\molecule{#4}}%
   \setbox\scratchboxone\chem_box_normal_yes{\lower{\dp\scratchboxtwo+\ht\scratchboxone}\hbox to \wd\scratchboxtwo{#1\box\scratchboxone#2}}%
   \smashbox\scratchboxone
   \box\scratchboxone
   \box\scratchboxtwo
   \egroup}

\permanent\protected\def\chemicalleft#1#2% redundant boxes thanks to visual
  {\hbox\bgroup % hpack ?
   \setstrut
   \llap{\chem_box_visual_nop{\strut#1}}%
   \chem_box_visual_nop{\strut#2}%
   \egroup}

\permanent\protected\def\chemicalright#1#2% redundant boxes thanks to visual
  {\hbox\bgroup % hpack ?
   \setstrut
   \chem_box_visual_yes{\strut#2}%
   \rlap{\chem_box_visual_nop{\strut#1}}%
   \egroup}

\permanent\protected\def\chemicaltop        {\chem_top_construct   \hss  \hss  }
\permanent\protected\def\chemicallefttop    {\chem_top_construct   \relax\hss  }
\permanent\protected\def\chemicalrighttop   {\chem_top_construct   \hss  \relax}
\permanent\protected\def\chemicalbottom     {\chem_bottom_construct\hss  \hss  }
\permanent\protected\def\chemicalleftbottom {\chem_bottom_construct\relax\hss  }
\permanent\protected\def\chemicalrightbottom{\chem_bottom_construct\hss  \relax}

\permanent\protected\def\chemicaltopleft    #1{\chemicalleft {\chemicalrighttop   {#1}{}}}
\permanent\protected\def\chemicalbottomleft #1{\chemicalleft {\chemicalrightbottom{#1}{}}}
\permanent\protected\def\chemicaltopright   #1{\chemicalright{\chemicallefttop    {#1}{}}}
\permanent\protected\def\chemicalbottomright#1{\chemicalright{\chemicalleftbottom {#1}{}}}

% \protected\def\chemicalcentered     #1{\hbox to \scaledfontcharwd\font`C{\setstrut\strut\hss#1\hss}}
% \protected\def\chemicalleftcentered #1{\hbox to \scaledfontcharwd\font`C{\setstrut\strut    #1\hss}}
% \protected\def\chemicalrightcentered#1{\hbox to \scaledfontcharwd\font`C{\setstrut\strut\hss#1}}

% \let\chemicalsmashedmiddle\chemicalcentered
% \let\chemicalsmashedleft  \chemicalleftcentered
% \let\chemicalsmashedright \chemicalrightcentered

\permanent\protected\def\chemicalalignedtext
  {\ifmmode
     \expandafter\chem_aligned_text_math
   \else
     \expandafter\chem_aligned_text_text
   \fi}

\aliased\let\chemicaltighttext\relax % maybe smaller strut

\def\chem_aligned_text_text#1#2#3%
  {\dontleavehmode
   \begingroup
   \usechemicalstyleandcolor\c!style\c!color
   \chem_box_visual_yes to \scaledfontcharwd\font`C\bgroup
     \setstrut\strut
     #1\molecule{#3}#2%
   \egroup
   \endgroup}

\def\chem_aligned_text_math#1#2#3%
  {\dontleavehmode
   \begingroup
   \scratchcounter\normalmathstyle
   \usechemicalstyleandcolor\c!style\c!color
   \chem_box_visual_yes to \scaledfontcharwd\font`C\bgroup
     \setstrut\strut
     #1\mathematics{\tf\triggermathstyle\scratchcounter\molecule{#3}}#2%
   \egroup
   \endgroup}

\permanent\protected\def\chemicalcentered     {\chemicalalignedtext\hss  \hss  }
\permanent\protected\def\chemicalleftcentered {\chemicalalignedtext\relax\hss  }
\permanent\protected\def\chemicalrightcentered{\chemicalalignedtext\hss  \relax}

\aliased\let\chemicalsmashedmiddle\chemicalcentered
\aliased\let\chemicalsmashedleft  \chemicalleftcentered
\aliased\let\chemicalsmashedright \chemicalrightcentered

\permanent\protected\def\chemicaloxidation#1#2#3%
  {\chemicaltop{\txx\ifcase#2\relax0\else#1\convertnumber{I}{#2}\fi}{#3}}

% todo: modernize

\permanent\protected\def\chemicaloxidationplus {\dotriplegroupempty\chemicaloxidation{\textplus }} % {} needed!
\permanent\protected\def\chemicaloxidationminus{\dotriplegroupempty\chemicaloxidation{\textminus}} % {} needed!
\permanent\protected\def\chemicalforeveropen   {\dotriplegroupempty\chemicalleft     {$\big[$}}    % {} needed!
\permanent\protected\def\chemicalforeverclose  {\dotriplegroupempty\chemicalright    {$\big]$}}    % {} needed!
\permanent\protected\def\chemicaloxidationone  {\chemicaloxidation\relax1}
\permanent\protected\def\chemicaloxidationtwo  {\chemicaloxidation\relax2}
\permanent\protected\def\chemicaloxidationthree{\chemicaloxidation\relax3}
\permanent\protected\def\chemicaloxidationfour {\chemicaloxidation\relax4}
\permanent\protected\def\chemicaloxidationfive {\chemicaloxidation\relax5}
\permanent\protected\def\chemicaloxidationsix  {\chemicaloxidation\relax6}
\permanent\protected\def\chemicaloxidationseven{\chemicaloxidation\relax7}

\permanent\protected\def\chemicalbar
  {\hpack \s!spread .5\emwidth \bgroup
     \hss
     \vrule \s!height .9\strutht \s!depth .65\strutdp \s!width .1\exheight
     \hss
   \egroup}

\permanent\let\X\relax
\permanent\let\T\relax
\permanent\let\B\relax
\permanent\let\L\relax
\permanent\let\M\relax
\permanent\let\R\relax

\appendtoks
   \amcode\barasciicode\zerocount
   \enforced\let|\chemicalbar % \SR{N|NH}
\to \everychemical

\appendtoks
   \enforced\let \+\chemicaloxidationplus
   \enforced\let \-\chemicaloxidationminus
   \enforced\let \[\chemicalforeveropen
   \enforced\let \]\chemicalforeverclose
   \enforced\let \1\chemicaloxidationone
   \enforced\let \2\chemicaloxidationtwo
   \enforced\let \3\chemicaloxidationthree
   \enforced\let \4\chemicaloxidationfour
   \enforced\let \5\chemicaloxidationfive
   \enforced\let \6\chemicaloxidationsix
   \enforced\let \7\chemicaloxidationseven
   \enforced\let \X\chemicaltighttext
   \enforced\let \T\chemicaltop
   \enforced\let \B\chemicalbottom
   \enforced\let \L\chemicalleft
   \enforced\let\LC\chemicalleftcentered
   \enforced\let \R\chemicalright
   \enforced\let\RC\chemicalrightcentered
   \enforced\let\TL\chemicaltopleft
   \enforced\let\BL\chemicalbottomleft
   \enforced\let\TR\chemicaltopright
   \enforced\let\BR\chemicalbottomright
   \enforced\let\LT\chemicallefttop
   \enforced\let\LB\chemicalleftbottom
   \enforced\let\RT\chemicalrighttop
   \enforced\let\RB\chemicalrightbottom
   \enforced\let\SL\chemicalsmashedleft
   \enforced\let\SM\chemicalsmashedmiddle
   \enforced\let\SR\chemicalsmashedright
\to \everychemical

% Should these also be defined in lower case, so as to be case independent?

\appendtoks
    \expand\everychemical
\to \everystructurechemical

% inline

\permanent\protected\def\chemical
  {\ifinformula
     \expandafter\indisplaychemical
   \else
     \expandafter\inlinechemical
   \fi}

\permanent\protected\def\indisplaychemical
  {\mathstylecommand\displaychemical\inlinechemical\inlinechemical}

\permanent\tolerant\protected\def\displaychemical#=#=#=%
  {\expand\everychemical
   \everychemical\emptytoks
   \quad
   \vcenter\bgroup
     \usechemicalstyleandcolor\c!style\c!color
     \ifparameter#3\or
       \ifparameter#2\or
         \halign{\aligntab\hss\alignmark\alignmark\hss\cr#2\cr\molecule{#1}\cr#3\cr}%
       \else
         \halign{\aligntab\hss\alignmark\alignmark\hss     \cr\molecule{#1}\cr#2\cr}%
       \fi
     \else
       \hbox{\molecule{#1}}%
     \fi
   \egroup
   \quad}

% \permanent\protected\def\inlinechemical#1%
%   {\dontleavehmode
%    \hbox{\usechemicalstyleandcolor\c!style\c!color\clf_inlinechemical{#1}}}

\permanent\protected\def\inlinechemical#1%
  {\dontleavehmode\begingroup
  %\hbox % will become option
   \usechemicalstyleandcolor\c!style\c!color\clf_inlinechemical{#1}%
   \endgroup}

\aliased\let\ic\inlinechemical

\permanent\protected\def\chemicalbondrule
  {\vrule
     \s!height.75\exheight
     \s!depth {\linewidth-.75\exheight}%
     \s!width \emwidth
   \relax}

\permanent\protected\def\chemicalsinglebondrule
  {\hpack{\chemicalbondrule}}

\permanent\protected\def\chemicaldoublebondrule
  {\hpack
     {\lower.5\exheight\chemicalsinglebondrule
      \kern-\emwidth
      \raise.5\exheight\chemicalsinglebondrule}}

\permanent\protected\def\chemicaltriplebondrule
  {\hpack
     {\chemicalsinglebondrule
      \kern-\emwidth
      \lower.5\exheight\chemicalsinglebondrule
      \kern-\emwidth
      \raise.5\exheight\chemicalsinglebondrule}}

\definechemicalsymbol[i:space]       [\enspace\quad\enspace]
\definechemicalsymbol[i:plus]        [\enspace\mathematics{+}\enspace]
\definechemicalsymbol[i:minus]       [\enspace\mathematics{-}\enspace]
\definechemicalsymbol[i:equals]      [\enspace\mathematics{=}\enspace]
\definechemicalsymbol[i:gives]       [\enspace\mathematics{\xrightarrow{}{}}\enspace]
\definechemicalsymbol[i:equilibrium] [\enspace\mathematics{\xrightoverleftarrow{}{}}\enspace]
\definechemicalsymbol[i:mesomeric]   [\enspace\mathematics{\xleftrightarrow{}{}}\enspace]
\definechemicalsymbol[i:single]      [\chemicalsinglebondrule]
\definechemicalsymbol[i:double]      [\chemicaldoublebondrule]
\definechemicalsymbol[i:triple]      [\chemicaltriplebondrule]

\permanent\protected\def\chemicalsinglebond {\chemicalsymbol[i:single]}
\permanent\protected\def\chemicaldoublebond {\chemicalsymbol[i:double]}
\permanent\protected\def\chemicaltriplebond {\chemicalsymbol[i:triple]}
\permanent\protected\def\chemicalgives      {\chemicalsymbol[i:gives]}
\permanent\protected\def\chemicalmesomeric  {\chemicalsymbol[i:mesomeric]}
\permanent\protected\def\chemicalequilibrium{\chemicalsymbol[i:equilibrium]}
\permanent\protected\def\chemicalplus       {\chemicalsymbol[i:plus]}
\permanent\protected\def\chemicalminus      {\chemicalsymbol[i:minus]}
\permanent\protected\def\chemicalequals     {\chemicalsymbol[i:equals]}
\permanent\protected\def\chemicalspace      {\chemicalsymbol[i:space]}
% \permanent\protected\def\chemicalinline   #1{#1}
% \permanent\protected\def\chemicalspecial  #1{#1}

\permanent\protected\def\chemicalinline#1%
  {#1}

\permanent\protected\def\chemicalspecial#1%
  {\penalty\plustenthousand
   \hskip.1\emwidth\s!plus.1\emwidth\relax
   #1%
   \penalty\plusfivehundred
   \hskip.1\emwidth\s!plus.1\emwidth\relax}

% display

\newconditional\c_chem_has_top
\newconditional\c_chem_has_bot

\newtoks\t_chem_top
\newtoks\t_chem_mid
\newtoks\t_chem_bot

\newif\ifinchemicalformula

\permanent\protected\def\startchemicalformula
  {\mathortext\vcenter\vbox\bgroup
   \forgetall
   \inchemicalformulatrue
   \expand\everychemical
   \everychemical\emptytoks
   \t_chem_top\emptytoks % not needed
   \t_chem_mid\emptytoks % not needed
   \t_chem_bot\emptytoks % not needed
   \enforced\let\chemical\formulachemical
   \c_chem_has_top\conditionalfalse
   \c_chem_has_bot\conditionalfalse}

\permanent\protected\def\stopchemicalformula
  {\tabskip\emwidth\relax
   \ifvmode\nointerlineskip\fi
   \ifconditional\c_chem_has_top
     \ifconditional\c_chem_has_bot
       \halign{\aligntab\hss\usechemicalstyleandcolor\c!style\c!color\alignmark\alignmark\hss\cr\expand\t_chem_top\cr\expand\t_chem_mid\cr\expand\t_chem_bot\cr}%
     \else
       \halign{\aligntab\hss\usechemicalstyleandcolor\c!style\c!color\alignmark\alignmark\hss\cr\expand\t_chem_top\cr\expand\t_chem_mid\cr}%
     \fi
   \else
     \ifconditional\c_chem_has_bot
       \halign{\aligntab\hss\usechemicalstyleandcolor\c!style\c!color\alignmark\alignmark\hss\cr\expand\t_chem_mid\cr\expand\t_chem_bot\cr}%
     \else
       \halign{\aligntab\hss\usechemicalstyleandcolor\c!style\c!color\alignmark\alignmark\hss\cr\expand\t_chem_mid\cr}%
     \fi
   \fi
   \egroup}

% for the moment we have a special set .. kind of old

\definechemicalsymbol[d:space]       [\enspace\quad\enspace]
\definechemicalsymbol[d:plus]        [\enspace+\enspace]
\definechemicalsymbol[d:minus]       [\enspace-\enspace]
\definechemicalsymbol[d:equals]      [\enspace=\enspace]
\definechemicalsymbol[d:gives]       [\cgives]
\definechemicalsymbol[d:equilibrium] [\cequilibrium]
\definechemicalsymbol[d:mesomeric]   [\cmesomeric]
\definechemicalsymbol[d:single]      [\chemicalsinglebondrule]
\definechemicalsymbol[d:double]      [\chemicaldoublebondrule]
\definechemicalsymbol[d:triple]      [\chemicaltriplebondrule]
\definechemicalsymbol[d:opencomplex] [\mathematics{\Bigg[}]     % not yet ok
\definechemicalsymbol[d:closecomplex][\mathematics{\Bigg]}]     % not yet ok

\definechemicalsymbol[d:SPACE]       [{\chemicalsymbol[d:space]}]
\definechemicalsymbol[d:PLUS]        [{\chemicalsymbol[d:plus]}]
\definechemicalsymbol[d:MINUS]       [{\chemicalsymbol[d:minus]}]
\definechemicalsymbol[d:EQUALS]      [{\chemicalsymbol[d:equals]}]
\definechemicalsymbol[d:GIVES]       [{\chemicalsymbol[d:gives]}]
\definechemicalsymbol[d:EQUILIBRIUM] [{\chemicalsymbol[d:equilibrium]}]
\definechemicalsymbol[d:MESOMERIC]   [{\chemicalsymbol[d:mesomeric]}]
\definechemicalsymbol[d:SINGLE]      [{\chemicalsymbol[d:single]}]
\definechemicalsymbol[d:DOUBLE]      [{\chemicalsymbol[d:double]}]
\definechemicalsymbol[d:TRIPLE]      [{\chemicalsymbol[d:triple]}]
\definechemicalsymbol[d:OPENCOMPLEX] [{\chemicalsymbol[d:opencomplex]}]
\definechemicalsymbol[d:CLOSECOMPLEX][{\chemicalsymbol[d:closecomplex]}]

\permanent\tolerant\protected\def\formulachemical#=#=#=%
  {\relax
   \ifarguments\or
     \chem_formula_top_nop
     \chem_formula_bot_nop
   \or
     \chem_formula_top_nop
     \ifempty{#2}\chem_formula_bot_nop\else\chem_formula_bot_yes{#2}\fi
   \or
     \ifempty{#2}\chem_formula_top_nop\else\chem_formula_top_yes{#2}\fi
     \ifempty{#3}\chem_formula_bot_nop\else\chem_formula_bot_yes{#3}\fi
   \fi
   \ifcsname\??chemicalsymbol d:\detokenize{#1}\endcsname
     \toksapp\t_chem_mid{\chemicalsymbol[d:#1]\aligntab}%
   \else
     \toksapp\t_chem_mid{\molecule{#1}\aligntab}%
   \fi}

\def\chem_formula_mid#1%
  {\csname\??chemicalsymbol\detokenize{#1}\endcsname}

\def\chem_formula_top_nop  {\toksapp\t_chem_top{\aligntab}}
\def\chem_formula_bot_nop  {\toksapp\t_chem_bot{\aligntab}}
\def\chem_formula_top_yes#1{\toksapp\t_chem_top{\chem_formula_top_indeed{#1}\aligntab}\c_chem_has_top\conditionaltrue}
\def\chem_formula_bot_yes#1{\toksapp\t_chem_bot{\chem_formula_bot_indeed{#1}\aligntab}\c_chem_has_bot\conditionaltrue}

\def\chem_formula_top_indeed#1{\strut#1}
\def\chem_formula_bot_indeed#1{\strut#1}

% Experimental: defaults might change.

\definefloat
  [\v!chemical]
  [\v!chemicals]

\setuplabeltext
  [\v!chemical=]

\setupfloat
  [\v!chemical]
  [\c!location=\v!here,
   \c!inner=\hsize.8\textwidth\dontleavehmode, % brr
   \c!align={\v!flushleft,\v!lohi}]

\setupcaption
  [\v!chemical]
  [\c!location=\v!right,
   \c!distance=\zeropoint,
   \c!width=.2\textwidth,
   \c!align=\v!flushright]

% Can be used as for displayed math: \startplaceformula... to display a chemical formula
% or a chemical structure:
%
% \startplacechemical
%   \startchemicalformula
%     \chemical{2H_2}
%     \chemical{PLUS}
%     \chemical{O_2}
%     \chemical{GIVES}
%     \chemical{2H_2O}
%   \stopchemicalformula
% \stopplacechemical

% gone: state option resolution offset (now frame offset) alternative

\setupchemicalframed
  [\c!align=\v!normal,
   \c!strut=\v!no,
   \c!offset=\v!overlay,
   \c!frame=\v!off]

\definecolor % private color
  [chemicalframecolor]
  [r=.75,g=.85,b=.95]

\setupchemical
  [\c!frame=,
   \c!width=\v!fit,  % or unitless number, multiplies scale*unit
   \c!height=\v!fit, % or unitless number, multiplies scale*unit
   \c!left=\v!fit,   % or unitless number, multiplies scale*unit
   \c!right=\v!fit,  % or unitless number, multiplies scale*unit
   \c!top=\v!fit,    % or unitless number, multiplies scale*unit
   \c!bottom=\v!fit, % or unitless number, multiplies scale*unit
   \c!bodyfont=,
   \c!scale=\v!normal, % small, normal or medium, big, or unitless number (multiplies unit)
   \c!size=\v!medium,
   \c!textsize=\v!big, % how is textsize used??
   \c!axis=\v!off,
   \c!style=\rm,
   \c!rotation=0,    % unitless number (interpreted as degrees)
   \c!symalign=\v!auto,
   \c!location=,     % not yet used (was interaction related in mkii)
   \c!offset=.25\emwidth,
   \c!unit=\emwidth,
   \c!factor=3,
   \c!color=,
   \c!strut=\v!yes,
   \c!framecolor=chemicalframecolor,
   \c!rulethickness=0.6pt, %1.5\linewidth,
   \c!rulecolor=]

%D Compatibility:

% Now we have + - : shortening and L R : rotating

% \definechemical[+R]               {\chemical[RR]} % fails
% \definechemical[-R]               {\chemical[LR]} % fails

\definechemical[CARBON:CB]        {\chemical[NEWMANSTAGGER,C,SB]}
\definechemical[NEWMANSTAGGER:CB] {\chemical[NEWMANSTAGGER,C,SB]}
\definechemical[NEWMANECLIPSED:CB]{\chemical[NEWMANECLIPSED,C,SB]}
\definechemical[CARBON:CB1]       {\chemical[CARBON,C,SB,Z234,1.5MOV1,MIR0,C,SB,Z234]}

\definechemical[NEWMAN]           {\chemical[]}
\definechemical[STAGGER]          {\chemical[NEWMANSTAGGER]}
\definechemical[ECLIPSE]          {\chemical[NEWMANECLIPSED]}
\definechemical[ECLIPSED]         {\chemical[NEWMANECLIPSED]}
\definechemical[SIX:FRONT]        {\chemical[SIXFRONT]}
\definechemical[FIVE:FRONT]       {\chemical[FIVEFRONT]}

%D This is new, more in sycn with math.

\definemathstackers
  [\v!chemistry]
  [\v!mathematics]
  [\c!offset=\v!max,
%    \c!order=\v!reverse,
   \c!left=\enspace,
   \c!right=\enspace,
   \c!hoffset=.5\mathemwidth]

\definemathextensible [\v!chemistry] [creturns]          ["2190]
\definemathextensible [\v!chemistry] [cgives]            ["2192]
\definemathextensible [\v!chemistry] [cmesomeric]        ["2194]
\definemathextensible [\v!chemistry] [cequilibrium]      ["21C4]
\definemathextensible [\v!chemistry] [cleaningright]     ["21CB]
\definemathextensible [\v!chemistry] [cleaningleft]      ["21CC]

\definemathextensible [\v!chemistry] [clongreturns]      ["27F5]
\definemathextensible [\v!chemistry] [clonggives]        ["27F6]
\definemathextensible [\v!chemistry] [clongmesomeric]    ["27F7]
\definemathextensible [\v!chemistry] [clongequilibrium]  ["21C4]
\definemathextensible [\v!chemistry] [clongleaningright] ["21CB]
\definemathextensible [\v!chemistry] [clongleaningleft]  ["21CC]

%permanent\protected\def\cplus  {+}
%permanent\protected\def\cminus {-}
%permanent\protected\def\cequals{=}

\permanent\protected\def\csinglebond{\mathchemicalbond{\chemicalsinglebondrule}} % todo dedicated class
\permanent\protected\def\cdoublebond{\mathchemicalbond{\chemicaldoublebondrule}} % idem
\permanent\protected\def\ctriplebond{\mathchemicalbond{\chemicaltriplebondrule}} % idem

\aliased\let\csingle\csinglebond
\aliased\let\cdouble\cdoublebond
\aliased\let\ctriple\ctriplebond

\setmathoptions\mathchemicalbondcode\numexpr
   \shortinlineclassoptioncode
\relax

\setmathpostpenalty\mathchemicalbondcode\plusfivehundred

\installcorenamespace {chemistry}

\installswitchcommandhandler \??chemistry {chemistry}

\setupchemistry
  [\c!spacing=\v!chemistry,
  %\c!factor=3000, % display
   \c!filter=\v!yes,
   \c!scale=800]   % script

\defineformula
  [\v!chemistry]
% [setups=chemistry:formula]

\definemathspacing
  [\v!chemistry]
  [\v!horizontal]
  [3000]

\definemathfence
  [ccomplex]
  [\c!left="005B,
   \c!right="005D]

\newtoks \everychemistry
\newtoks \everydisplaychemistry

\permanent\protected\def\chem_ch{\mathtriplet[\v!chemistry]}

%D Maybe we should reserve it with \permanent:

\ifdefined\ch \else \mutable\lettonothing\ch \fi

\appendtoks
    \setmathignore\Umathxscale\plustwo
    \setmathignore\Umathyscale\plustwo
    \setmathignore\Umathspacebeforescript \plusone % alternatively we can set the factors
    \setmathignore\Umathspacebetweenscript\plusone
    \setmathignore\Umathspaceafterscript  \plusone
    \bitwiseflip\mathscriptsmode\plusone
    \scratchcounter\chemistryparameter\c!scale
    \glyphscriptscale      {\glyphscriptscale      *\scratchcounter/\plusthousand}%
    \glyphscriptscriptscale{\glyphscriptscriptscale*\scratchcounter/\plusthousand}%
    \enforced\let\math_default\math_upright
    \enforced\let\ch\chem_ch
\to \everychemistry

\appendtoks
   \expand\everychemistry
   \setupmathspacing[\chemistryparameter\c!spacing]%
 % \Umathxscale\allmathstyles\chemistryparameter\c!factor\relax
\to \everydisplaychemistry

% this will move to math-ini ... digits inherit from ordinary

\newmuskip\extrafencemuskip

\appendtoks
    \inherited\setmathspacing \mathchemicalbondcode \mathordinarycode     \allsplitstyles   \tinymuskip
    \inherited\setmathspacing \mathchemicalbondcode \mathordinarycode     \allunsplitstyles \pettymuskip
    \inherited\setmathspacing \mathordinarycode     \mathchemicalbondcode \allsplitstyles   \tinymuskip
    \inherited\setmathspacing \mathordinarycode     \mathchemicalbondcode \allunsplitstyles \pettymuskip
\to \everychemistry

\appendtoks
    \inherited\setmathspacing \mathopencode         \mathordinarycode     \allmathstyles    \extrafencemuskip
    \inherited\setmathspacing \mathordinarycode     \mathclosecode        \allmathstyles    \extrafencemuskip
    \extrafencemuskip \medmuskip
\to \everydisplaychemistry

% .. upto here

% \permanent\protected\def\ic#1%
%   {\im{%
%      \expand\everychemistry
%      \mathupright\relax
%      \clf_ic{#1}%
%    }}

% \permanent\protected\def\dc#1%
%   {\dm{%
%      \expand\everydisplaychemistry
%      \mathupright\relax
%      \clf_ic{#1}%
%    }}

\permanent\protected\def\chem_ic#1%
  {\expand\everychemistry
   \mathupright\relax
   \ifcstok{\chemistryparameter\c!filter}\v!yes
     \clf_ic{#1}%
   \else
     #1\relax
   \fi}

\permanent\protected\def\chem_dc#1%
  {\expand\everydisplaychemistry
   \mathupright\relax
   \ifcstok{\chemistryparameter\c!filter}\v!yes
     \clf_ic{#1}%
   \else
     #1\relax
   \fi}

\permanent\protected\def\ic#1%
 {\relax
  \ifmmode
    \mathconstruct{\forceinlinemath\chem_ic{#1}}%
  \else
    \startimath\chem_ic{#1}\stopimath
  \fi}

\permanent\protected\def\dc#1%
  {\relax\ifmmode
     \mathconstruct{\forcedisplaymath\chem_dc{#1}}%
   \else % no grouping
     \startimath\forcedisplaymath\chem_dc{#1}\stopimath
   \fi}

\aliased\let\stopchemistry\relax

\permanent\tolerant\protected\def\startchemistry[#1]#:#2\stopchemistry
  {\begingroup
   \ifhastok={#1}%
     \setupcurrentchemistry[#1]%
   \fi
   \expand\everydisplaychemistry
   \startchemistryformula
     \ifcstok{\chemistryparameter\c!filter}\v!yes
       \clf_ic{#2}%
     \else
       #2\relax
     \fi
   \stopchemistryformula
   \endgroup}

\protect \endinput