chem-str.mkiv /size: 26 Kb    last modification: 2021-10-28 13:50
1%D \module
2%D   [       file=chem-ini,
3%D        version=2009.05.13,
4%D       subtitle=Chemistry,
5%D         author=Hans Hagen \& Alan Braslau,
6%D           date=\currentdate,
7%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
8%C
9%C This module is part of the \CONTEXT\ macro||package and is
10%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
11%C details.
12
13%D The original \PPCHTEX\ code was written in pure \TEX\, although later we made
14%D the move from \PICTEX\ to \METAPOST\. The current implementation is a mix between
15%D \TEX\, \LUA\ and \METAPOST. Although the first objective is to get a compatible
16%D but better implementation, later versions might provide more,
17
18\writestatus{loading}{ConTeXt Chemistry Macros / Structure}
19
20\registerctxluafile{chem-str}{}
21
22% We have a slightly different interface. This is unchanged:
23%
24% \startchemical[axis=on]
25%     \chemical[SIX,ROT2,B,R6,SUB1,FIVE,ROT1,B][1]
26% \stopchemical
27%
28% Here we use chemicalformula instead, so no longer a mix:
29%
30% \startchemicalformula
31%     \chemical{2H_2}{top}{bottom}
32%     \chemical{PLUS}{top}{bottom}
33%     \chemical{O_2}{top}{bottom}
34%     \chemical{GIVES}{top}{bottom}
35%     \chemical{2H_2O}{top}{bottom}
36% \stopchemicalformula
37%
38% \startchemicalformula
39%     \chemical{2H_2}
40%     \chemical{PLUS}
41%     \chemical{O_2}
42%     \chemical{GIVES}
43%     \chemical{2H_2O}
44% \stopchemicalformula
45%
46% The inline variant has only one argument:
47%
48% \chemical{2H_2,PLUS,O_2,GIVES,2H_2O}
49
50\unprotect
51
52\installcorenamespace{chemical}
53\installcorenamespace{chemicalsymbol}
54\installcorenamespace{chemicalframed}
55\installcorenamespace{chemicalsize}
56
57% \installsimplecommandhandler \??chemical {chemical} \??chemical % no \define...
58\installcommandhandler \??chemical {chemical} \??chemical % no \define...
59
60\let\setupchemicals \setupchemical
61\let\definechemicals\definechemical
62
63%D We use a dedicated framed macro instead of inheriting one. This is both
64%D a historical and practical reason (like shared keys with different meaning
65%D that could clash, e.g.\ align).
66
67\defineMPinstance % not really needed as we set in lua
68  [chemistry]
69  [\s!format=metafun,
70  %\s!extensions=\v!yes,      % Should we add extensions and initializations?
71  %\s!initializations=\v!yes, % Would this give EmWidth, etc.?
72   \c!method=\s!double]
73
74\startMPdefinitions{chemistry}
75    loadmodule "chem" ;
76\stopMPdefinitions
77
78\defineframed
79  [\??chemicalframed]
80  [\c!align=\v!normal,
81   \c!strut=\v!no]
82
83\unexpanded\def\setupchemicalframed
84  {\setupframed[\??chemicalframed]}
85
86\unexpanded\def\definechemical % is global (so we don't use the commandhandler)
87  {\dosingleargument\chem_define}
88
89\def\chem_define[#1]#2%
90  {\startnointerference
91   \edef\currentdefinedchemical{#1}%
92   \let\chemical\chem_chemical_nested
93   \clf_undefinechemical{#1}%
94   #2% flush
95   \stopnointerference}
96
97\unexpanded\def\chem_chemical_nested
98  {\dodoubleempty\chem_chemical_nested_indeed}
99
100\def\chem_chemical_nested_indeed[#1][#2]%
101  {\clf_definechemical{\currentdefinedchemical}{#1}{\detokenize{#2}}}
102
103% chemical symbols
104
105\unexpanded\def\definechemicalsymbol
106  {\dodoubleempty\chem_symbol_define}
107
108\def\chem_symbol_define[#1][#2]%
109  {\setvalue{\??chemicalsymbol#1}{#2}}
110
111\unexpanded\def\chemicalsymbol[#1]%
112  {\csname\??chemicalsymbol\ifcsname\??chemicalsymbol#1\endcsname#1\else\s!unknown\fi\endcsname}
113
114\definechemicalsymbol[\s!unknown][] % \char"FFFD empty
115
116% size (small medium big)
117
118\edef\chemicaltoplocation{t}
119\edef\chemicalbotlocation{b}
120
121\unexpanded\def\chemicaltext#1%
122  {\mathematics
123     {\usechemicalstyleandcolor\c!style\c!color
124      \strut
125      \ifcase\currentxfontsize\or\scriptstyle\or\scriptscriptstyle\fi
126      #1}}
127
128\setvalue{\??chemicalsize\v!small }{\txx}
129\setvalue{\??chemicalsize\v!medium}{\tx}
130\setvalue{\??chemicalsize\v!big   }{}
131
132\newtoks       \everychemical
133\newtoks       \everystructurechemical
134\newconditional\indisplaychemical
135
136\newtoks       \t_chem_every_box
137\newbox        \b_chem_result
138\newconditional\c_chem_some_text
139\newdimen      \d_chem_width
140\newdimen      \d_chem_height
141\newdimen      \d_chem_depth
142
143\unexpanded\def\startchemical
144  {\dodoubleempty\chem_start}
145
146\def\chem_start[#1][#2]%
147  {\ifmmode\vcenter\else\vbox\fi % vpack ?
148   \bgroup
149   \synchronizestrut{\chemicalparameter\c!strut}%
150   \dontcomplain
151   \settrue\indisplaychemical
152   \forgetall
153   \ifsecondargument
154     \doifelseassignment{#1}
155       {\setupcurrentchemical[#1]}% same as \currentchemical
156       {\edef\currentchemical{#1}%
157        \setupcurrentchemical[#2]}%
158   \else\iffirstargument
159     \doifelseassignment{#1}
160       {\setupcurrentchemical[#1]}% same as \currentchemical
161       {\edef\currentchemical{#1}}%
162   \fi\fi
163   \the\everystructurechemical
164   \setbox\b_chem_result\hpack\bgroup
165   \clf_startchemical
166     width         {\chemicalparameter\c!width}%
167     height        {\chemicalparameter\c!height}%
168     left          {\chemicalparameter\c!left}%
169     right         {\chemicalparameter\c!right}%
170     top           {\chemicalparameter\c!top}%
171     bottom        {\chemicalparameter\c!bottom}%
172     scale         {\chemicalparameter\c!scale}%
173     rotation      {\chemicalparameter\c!rotation}%
174     symalign      {\chemicalparameter\c!symalign}%
175     axis          {\chemicalparameter\c!axis}% was \MPcolor{...}
176     framecolor    {\chemicalparameter\c!framecolor}%
177     rulethickness {\number\dimexpr\chemicalparameter\c!rulethickness}%
178     offset        {\number\dimexpr\chemicalparameter\c!offset}%
179     unit          {\number\dimexpr\chemicalparameter\c!unit}%
180     factor        {\number\chemicalparameter\c!factor}%
181   \relax
182   \startnointerference}
183
184\unexpanded\def\stopchemical
185  {\stopnointerference
186   \clf_stopchemical
187   \egroup
188   \d_chem_width \wd\b_chem_result
189   \d_chem_height\ht\b_chem_result
190   \d_chem_depth \dp\b_chem_result
191   \the\t_chem_every_box
192   \doifelsenothing{\chemicalparameter\c!frame}\chem_framed_nop\chem_framed_yes
193   \egroup}
194
195\unexpanded\def\chem_framed_yes
196  {\localframedwithsettings
197     [\??chemicalframed]%
198     [\c!frame=\chemicalparameter\c!frame,
199      \c!rulethickness=\chemicalparameter\c!rulethickness,
200      \c!framecolor=\chemicalparameter\c!framecolor]%
201     {\vpack{\box\b_chem_result\vss}}} % remove depth
202
203\unexpanded\def\chem_framed_nop
204  {\directlocalframed
205     [\??chemicalframed]%
206     {\vpack{\box\b_chem_result\vss}}} % remove depth
207
208\let\startstructurechemical\startchemical
209\let\stopstructurechemical \stopchemical
210
211\unexpanded\def\structurechemical
212  {\dotripleempty\strc_chem_indeed}
213
214\appendtoks
215    \let\chemical\structurechemical
216\to\everystructurechemical
217
218\def\strc_chem_indeed
219  {\ifthirdargument
220     \expandafter\strc_chem_indeed_three
221   \else
222     \expandafter\strc_chem_indeed_two
223   \fi}
224
225\def\strc_chem_indeed_three[#1][#2][#3]%
226  {\writestatus\m!chemicals{hyperlinked chemicals not yet supported}% todo reference, for the moment ignored
227   \clf_chemicalcomponent
228      {#2}%
229      {\detokenize{#3}}%
230      {\the\dimexpr\chemicalparameter\c!rulethickness}% todo: scaled points
231      {\chemicalparameter\c!rulecolor}%
232   \relax
233   \ignorespaces}
234
235\def\strc_chem_indeed_two[#1][#2]%
236  {\clf_chemicalcomponent
237      {#1}%
238      {\detokenize{#2}}%
239      {\the\dimexpr\chemicalparameter\c!rulethickness}% todo: scaled points
240      {\chemicalparameter\c!rulecolor}%
241   \relax
242   \ignorespaces}
243
244\appendtoks
245    \setbox\b_chem_result\hpack{\raise\MPlly\box\b_chem_result}%
246    \d_chem_width \wd\b_chem_result
247    \d_chem_height\ht\b_chem_result
248    \d_chem_depth \dp\b_chem_result
249\to \t_chem_every_box
250
251% kind of compatible, but text sizes instead of math sizes (i.e. tx is larger than scriptsize)
252
253\appendtoks
254   \edef\chemicalbodyfont{\chemicalparameter\c!bodyfont}% public?
255   \ifx\chemicalbodyfont\empty
256     \switchtobodyfont[\chemicalbodyfont]%
257   \fi
258   \getvalue{\??chemicalsize\chemicalparameter\c!size}%
259% \to \everystructurechemical
260\to \everychemical
261
262\def\chemicaltoptext#1{\global\settrue\c_chem_some_text\gdef\m_chem_top_text{#1}\ignorespaces}
263\def\chemicalbottext#1{\global\settrue\c_chem_some_text\gdef\m_chem_bot_text{#1}\ignorespaces}
264\def\chemicalmidtext#1{\global\settrue\c_chem_some_text\gdef\m_chem_mid_text{#1}\ignorespaces}
265
266\appendtoks
267    \let\toptext\chemicaltoptext \glet\m_chem_top_text\empty
268    \let\bottext\chemicalbottext \glet\m_chem_bot_text\empty
269    \let\midtext\chemicalmidtext \glet\m_chem_mid_text\empty
270    \global\setfalse\c_chem_some_text
271\to \everystructurechemical
272
273\def\chem_add_texts
274  {\setbox2\hpack to \d_chem_width{\strut\hss\hbox{\strut\m_chem_mid_text}\hss}%
275   \setbox4\hpack to \d_chem_width{\strut\hss\hbox{\strut\m_chem_top_text}\hss}%
276   \setbox6\hpack to \d_chem_width{\strut\hss\hbox{\strut\m_chem_bot_text}\hss}%
277   \setbox\b_chem_result\hpack \bgroup
278     \box\b_chem_result
279     \hskip-\d_chem_width
280     \raise\d_chem_height\hpack{\lower\ht4\box4}%
281     \hskip-\d_chem_width
282     \lower.5\dimexpr\ht2-\dp2\relax\box2%
283     \hskip-\d_chem_width
284     \lower\d_chem_depth \hpack{\raise\dp6\box6}%
285     \hss
286   \egroup} % text on top of chemicals
287
288\appendtoks
289    \ifconditional\c_chem_some_text
290      \chem_add_texts
291      \d_chem_width \wd\b_chem_result
292      \d_chem_height\ht\b_chem_result
293      \d_chem_depth \dp\b_chem_result
294    \fi
295\to \t_chem_every_box
296
297% todo: enspace or emspace
298
299\definechemicalsymbol[space]       [\enspace\quad\enspace]
300\definechemicalsymbol[plus]        [\enspace+\enspace]
301\definechemicalsymbol[minus]       [\enspace-\enspace]
302\definechemicalsymbol[gives]       [\chem_arrow_construct\xrightarrow]
303\definechemicalsymbol[equilibrium] [\chem_arrow_construct\xrightoverleftarrow]
304\definechemicalsymbol[mesomeric]   [\chem_arrow_construct\xleftrightarrow]
305\definechemicalsymbol[opencomplex] [\mathematics{\Bigg[}] % not yet ok
306\definechemicalsymbol[closecomplex][\mathematics{\Bigg]}] % not yet ok
307
308\definechemicalsymbol[SPACE]       [{\chemicalsymbol[space]}]
309\definechemicalsymbol[PLUS]        [{\chemicalsymbol[plus]}]
310\definechemicalsymbol[MINUS]       [{\chemicalsymbol[minus]}]
311\definechemicalsymbol[GIVES]       [{\chemicalsymbol[gives]}]
312\definechemicalsymbol[EQUILIBRIUM] [{\chemicalsymbol[equilibrium]}]
313\definechemicalsymbol[MESOMERIC]   [{\chemicalsymbol[mesomeric]}]
314\definechemicalsymbol[OPENCOMPLEX] [{\chemicalsymbol[opencomplex]}]
315\definechemicalsymbol[CLOSECOMPLEX][{\chemicalsymbol[closecomplex]}]
316
317\def\chem_arrow_construct#1#2#3%
318  {\enspace
319   \mathematics{#1%
320     {\strut\hbox \s!spread 2\emwidth{\hss\clf_inlinechemical{#3}\hss}}%   {\strut\hbox \s!spread 2em{\hss#3\hss}}}%
321     {\strut\hbox \s!spread 2\emwidth{\hss\clf_inlinechemical{#2}\hss}}}%  {\strut\hbox \s!spread 2em{\hss#2\hss}}%
322   \enspace}
323
324% special macros (probably needs some more work)
325
326\let\chem_box_normal_yes\hbox
327\let\chem_box_visual_yes\hbox
328\let\chem_box_visual_nop\relax
329
330\installtextracker
331  {chemistry.boxes}
332  {\let\chem_box_visual_yes\ruledhbox \let\chem_box_visual_nop\ruledhbox}
333  {\let\chem_box_visual_yes\hbox      \let\chem_box_visual_nop\relax    }
334
335\def\chem_top_construct#1#2#3#4%
336  {\hpack\bgroup
337   \setstrut
338   \setbox\scratchboxone\chem_box_visual_yes{\strut#3}%
339   \setbox\scratchboxtwo\chem_box_visual_yes{\strut\molecule{#4}}%
340   \setbox\scratchboxone\chem_box_normal_yes{\raise\dimexpr\dp\scratchboxone+\ht\scratchboxtwo\relax\hbox to \wd\scratchboxtwo{#1\box\scratchboxone#2}}%
341   \smashbox\scratchboxone
342   \box\scratchboxone
343   \box\scratchboxtwo
344   \egroup}
345
346\def\chem_bottom_construct#1#2#3#4%
347  {\hpack\bgroup
348   \setstrut
349   \setbox\scratchboxone\chem_box_visual_yes{\strut#3}%
350   \setbox\scratchboxtwo\chem_box_visual_yes{\strut\molecule{#4}}%
351   \setbox\scratchboxone\chem_box_normal_yes{\lower\dimexpr\dp\scratchboxtwo+\ht\scratchboxone\relax\hbox to \wd\scratchboxtwo{#1\box\scratchboxone#2}}%
352   \smashbox\scratchboxone
353   \box\scratchboxone
354   \box\scratchboxtwo
355   \egroup}
356
357\unexpanded\def\chemicalleft#1#2% redundant boxes thanks to visual
358  {\hbox\bgroup % hpack ?
359   \setstrut
360   \llap{\chem_box_visual_nop{\strut#1}}%
361   \chem_box_visual_nop{\strut#2}%
362   \egroup}
363
364\unexpanded\def\chemicalright#1#2% redundant boxes thanks to visual
365  {\hbox\bgroup % hpack ?
366   \setstrut
367   \chem_box_visual_yes{\strut#2}%
368   \rlap{\chem_box_visual_nop{\strut#1}}%
369   \egroup}
370
371\unexpanded\def\chemicaltop            {\chem_top_construct    \hss   \hss  }
372\unexpanded\def\chemicallefttop        {\chem_top_construct    \relax \hss  }
373\unexpanded\def\chemicalrighttop       {\chem_top_construct    \hss   \relax}
374\unexpanded\def\chemicalbottom         {\chem_bottom_construct \hss   \hss  }
375\unexpanded\def\chemicalleftbottom     {\chem_bottom_construct \relax \hss  }
376\unexpanded\def\chemicalrightbottom    {\chem_bottom_construct \hss   \relax}
377
378\unexpanded\def\chemicaltopleft      #1{\chemicalleft {\chemicalrighttop   {#1}{}}}
379\unexpanded\def\chemicalbottomleft   #1{\chemicalleft {\chemicalrightbottom{#1}{}}}
380\unexpanded\def\chemicaltopright     #1{\chemicalright{\chemicallefttop    {#1}{}}}
381\unexpanded\def\chemicalbottomright  #1{\chemicalright{\chemicalleftbottom {#1}{}}}
382
383% \unexpanded\def\chemicalcentered     #1{\hbox to \fontcharwd\font`C{\setstrut\strut\hss#1\hss}}
384% \unexpanded\def\chemicalleftcentered #1{\hbox to \fontcharwd\font`C{\setstrut\strut    #1\hss}}
385% \unexpanded\def\chemicalrightcentered#1{\hbox to \fontcharwd\font`C{\setstrut\strut\hss#1}}
386
387% \let\chemicalsmashedmiddle\chemicalcentered
388% \let\chemicalsmashedleft  \chemicalleftcentered
389% \let\chemicalsmashedright \chemicalrightcentered
390
391\unexpanded\def\chemicalalignedtext
392  {\ifmmode
393     \expandafter\chem_aligned_text_math
394   \else
395     \expandafter\chem_aligned_text_text
396   \fi}
397
398\let\chemicaltighttext\relax % maybe smaller strut
399
400\def\chem_aligned_text_text#1#2#3%
401  {\dontleavehmode
402   \begingroup
403   \usechemicalstyleandcolor\c!style\c!color
404   \chem_box_visual_yes to \fontcharwd\font`C\bgroup
405     \setstrut\strut
406     #1\molecule{#3}#2%
407   \egroup
408   \endgroup}
409
410\def\chem_aligned_text_math#1#2#3%
411  {\dontleavehmode
412   \begingroup
413   \scratchcounter\normalmathstyle
414   \usechemicalstyleandcolor\c!style\c!color
415   \chem_box_visual_yes to \fontcharwd\font`C\bgroup
416     \setstrut\strut
417     #1\mathematics{\tf\triggermathstyle\scratchcounter\molecule{#3}}#2%
418   \egroup
419   \endgroup}
420
421\unexpanded\def\chemicalcentered     {\chemicalalignedtext\hss  \hss  }
422\unexpanded\def\chemicalleftcentered {\chemicalalignedtext\relax\hss  }
423\unexpanded\def\chemicalrightcentered{\chemicalalignedtext\hss  \relax}
424
425\let\chemicalsmashedmiddle\chemicalcentered
426\let\chemicalsmashedleft  \chemicalleftcentered
427\let\chemicalsmashedright \chemicalrightcentered
428
429\unexpanded\def\chemicaloxidation#1#2#3%
430  {\chemicaltop{\txx\ifcase#2\relax0\else#1\convertnumber{I}{#2}\fi}{#3}}
431
432\unexpanded\def\chemicaloxidationplus {\dotriplegroupempty\chemicaloxidation{\textplus }} % {} needed!
433\unexpanded\def\chemicaloxidationminus{\dotriplegroupempty\chemicaloxidation{\textminus}} % {} needed!
434\unexpanded\def\chemicalforeveropen   {\dotriplegroupempty\chemicalleft     {$\big[$}}    % {} needed!
435\unexpanded\def\chemicalforeverclose  {\dotriplegroupempty\chemicalright    {$\big]$}}    % {} needed!
436\unexpanded\def\chemicaloxidationone  {\chemicaloxidation\relax1}
437\unexpanded\def\chemicaloxidationtwo  {\chemicaloxidation\relax2}
438\unexpanded\def\chemicaloxidationthree{\chemicaloxidation\relax3}
439\unexpanded\def\chemicaloxidationfour {\chemicaloxidation\relax4}
440\unexpanded\def\chemicaloxidationfive {\chemicaloxidation\relax5}
441\unexpanded\def\chemicaloxidationsix  {\chemicaloxidation\relax6}
442\unexpanded\def\chemicaloxidationseven{\chemicaloxidation\relax7}
443
444\unexpanded\def\chemicalbar
445  {\hpack \s!spread .5\emwidth \bgroup
446     \hss
447     \vrule \s!height .9\strutht \s!depth .65\strutdp \s!width .1\exheight
448     \hss
449   \egroup}
450
451\appendtoks
452   \let  |\chemicalbar % \SR{N|NH}
453   \let \+\chemicaloxidationplus
454   \let \-\chemicaloxidationminus
455   \let \[\chemicalforeveropen
456   \let \]\chemicalforeverclose
457   \let \1\chemicaloxidationone
458   \let \2\chemicaloxidationtwo
459   \let \3\chemicaloxidationthree
460   \let \4\chemicaloxidationfour
461   \let \5\chemicaloxidationfive
462   \let \6\chemicaloxidationsix
463   \let \7\chemicaloxidationseven
464   \let \X\chemicaltighttext
465   \let \T\chemicaltop
466   \let \B\chemicalbottom
467   \let \L\chemicalleft
468   \let\LC\chemicalleftcentered
469   \let \R\chemicalright
470   \let\RC\chemicalrightcentered
471   \let\TL\chemicaltopleft
472   \let\BL\chemicalbottomleft
473   \let\TR\chemicaltopright
474   \let\BR\chemicalbottomright
475   \let\LT\chemicallefttop
476   \let\LB\chemicalleftbottom
477   \let\RT\chemicalrighttop
478   \let\RB\chemicalrightbottom
479   \let\SL\chemicalsmashedleft
480   \let\SM\chemicalsmashedmiddle
481   \let\SR\chemicalsmashedright
482\to \everychemical
483
484% Should these also be defined in lower case, so as to be case independent?
485
486\appendtoks
487    \the\everychemical
488\to \everystructurechemical
489
490% inline
491
492% \unexpanded\def\chemical
493%   {\ifinformula
494%      \expandafter\displaychemical
495%    \else
496%      \expandafter\inlinechemical
497%    \fi}
498
499\unexpanded\def\chemical
500  {\ifinformula
501     \expandafter\indisplaychemical
502   \else
503     \expandafter\inlinechemical
504   \fi}
505
506\unexpanded\def\indisplaychemical
507  {\mathstylecommand\displaychemical\inlinechemical\inlinechemical}
508
509\unexpanded\def\inlinechemical#1%
510  {\dontleavehmode
511   \begingroup
512   \scratchcounter\normalmathstyle
513   \usechemicalstyleandcolor\c!style\c!color
514   \hbox{\mathematics{\tf\triggermathstyle\scratchcounter\clf_inlinechemical{#1}}}%
515   \endgroup}
516
517\unexpanded\def\displaychemical
518  {\dotriplegroupempty\chem_display}
519
520\def\chem_display#1#2#3%
521  {\the\everychemical
522   \everychemical\emptytoks
523   \quad
524   \vcenter\bgroup
525     \usechemicalstyleandcolor\c!style\c!color
526     \ifthirdargument
527       \ifsecondargument
528         \halign{\aligntab\hss\alignmark\alignmark\hss\cr#2\cr\molecule{#1}\cr#3\cr}%
529       \else
530         \halign{\aligntab\hss\alignmark\alignmark\hss     \cr\molecule{#1}\cr#2\cr}%
531       \fi
532     \else
533       \hbox{\molecule{#1}}%
534     \fi
535   \egroup
536   \quad}
537
538\unexpanded\def\inlinechemical#1%
539  {\dontleavehmode
540   \hbox{\usechemicalstyleandcolor\c!style\c!color\clf_inlinechemical{#1}}}
541
542\unexpanded\def\chemicalbondrule
543  {\hpack{\vrule\s!height.75\exheight\s!depth-\dimexpr.75\exheight-\linewidth\relax\s!width\emwidth\relax}}
544
545\definechemicalsymbol[i:space]       [\enspace\quad\enspace]
546\definechemicalsymbol[i:plus]        [\enspace\mathematics{+}\enspace]
547\definechemicalsymbol[i:minus]       [\enspace\mathematics{-}\enspace]
548\definechemicalsymbol[i:equals]      [\enspace\mathematics{=}\enspace]
549\definechemicalsymbol[i:gives]       [\enspace\mathematics{\xrightarrow{}{}}\enspace]
550\definechemicalsymbol[i:equilibrium] [\enspace\mathematics{\xrightoverleftarrow{}{}}\enspace]
551\definechemicalsymbol[i:mesomeric]   [\enspace\mathematics{\xleftrightarrow{}{}}\enspace]
552\definechemicalsymbol[i:single]      [\chemicalbondrule]
553\definechemicalsymbol[i:double]      [\hpack{\lower.5ex\chemicalbondrule\hskip-1em\raise.5ex\chemicalbondrule}]
554\definechemicalsymbol[i:triple]      [\hpack{\chemicalbondrule\hskip-1em\lower.5ex\chemicalbondrule\hskip-1em\raise.5ex\chemicalbondrule}]
555
556\unexpanded\def\chemicalsinglebond {\chemicalsymbol[i:single]}
557\unexpanded\def\chemicaldoublebond {\chemicalsymbol[i:double]}
558\unexpanded\def\chemicaltriplebond {\chemicalsymbol[i:triple]}
559\unexpanded\def\chemicalgives      {\chemicalsymbol[i:gives]}
560\unexpanded\def\chemicalmesomeric  {\chemicalsymbol[i:mesomeric]}
561\unexpanded\def\chemicalequilibrium{\chemicalsymbol[i:equilibrium]}
562\unexpanded\def\chemicalplus       {\chemicalsymbol[i:plus]}
563\unexpanded\def\chemicalminus      {\chemicalsymbol[i:minus]}
564\unexpanded\def\chemicalequals     {\chemicalsymbol[i:equals]}
565\unexpanded\def\chemicalspace      {\chemicalsymbol[i:space]}
566\unexpanded\def\chemicalinline   #1{#1}
567
568% display
569
570\newconditional\c_chem_has_top
571\newconditional\c_chem_has_bot
572
573\newtoks\t_chem_top
574\newtoks\t_chem_mid
575\newtoks\t_chem_bot
576
577\newif\ifinchemicalformula
578
579\unexpanded\def\startchemicalformula
580  {\mathortext\vcenter\vbox\bgroup
581   \forgetall
582   \inchemicalformulatrue
583   \the\everychemical
584   \everychemical\emptytoks
585   \t_chem_top\emptytoks % not needed
586   \t_chem_mid\emptytoks % not needed
587   \t_chem_bot\emptytoks % not needed
588   \let\chemical\formulachemical
589   \setfalse\c_chem_has_top
590   \setfalse\c_chem_has_bot}
591
592\unexpanded\def\stopchemicalformula
593  {\tabskip\emwidth\relax
594   \nointerlineskip
595   \ifconditional\c_chem_has_top
596     \ifconditional\c_chem_has_bot
597       \halign{\aligntab\hss\usechemicalstyleandcolor\c!style\c!color\alignmark\alignmark\hss\cr\the\t_chem_top\cr\the\t_chem_mid\cr\the\t_chem_bot\cr}%
598     \else
599       \halign{\aligntab\hss\usechemicalstyleandcolor\c!style\c!color\alignmark\alignmark\hss\cr\the\t_chem_top\cr\the\t_chem_mid\cr}%
600     \fi
601   \else
602     \ifconditional\c_chem_has_bot
603       \halign{\aligntab\hss\usechemicalstyleandcolor\c!style\c!color\alignmark\alignmark\hss\cr\the\t_chem_mid\cr\the\t_chem_bot\cr}%
604     \else
605       \halign{\aligntab\hss\usechemicalstyleandcolor\c!style\c!color\alignmark\alignmark\hss\cr\the\t_chem_mid\cr}%
606     \fi
607   \fi
608   \egroup}
609
610% for the moment we have a special set
611
612\definechemicalsymbol[d:space]       [\enspace\quad\enspace]
613\definechemicalsymbol[d:plus]        [\enspace+\enspace]
614\definechemicalsymbol[d:minus]       [\enspace-\enspace]
615\definechemicalsymbol[d:equals]      [\enspace=\enspace]
616\definechemicalsymbol[d:gives]       [\rightarrowfill]          % \chem_arrow_construct\xrightarrow
617\definechemicalsymbol[d:equilibrium] [\rightoverleftarrowfill]  % \chem_arrow_construct\xrightoverleftarrow
618\definechemicalsymbol[d:mesomeric]   [\leftarrowfill]           % \chem_arrow_construct\xleftrightarrow
619\definechemicalsymbol[d:single]      [\chemicalbondrule]
620\definechemicalsymbol[d:double]      [\hpack{\lower.5ex\chemicalbondrule\hskip-1em\raise.5ex\chemicalbondrule}]
621\definechemicalsymbol[d:triple]      [\hpack{\chemicalbondrule\hskip-1em\lower.5ex\chemicalbondrule\hskip-1em\raise.5ex\chemicalbondrule}]
622\definechemicalsymbol[d:opencomplex] [\mathematics{\Bigg[}]     % not yet ok
623\definechemicalsymbol[d:closecomplex][\mathematics{\Bigg]}]     % not yet ok
624
625\definechemicalsymbol[d:SPACE]       [{\chemicalsymbol[d:space]}]
626\definechemicalsymbol[d:PLUS]        [{\chemicalsymbol[d:plus]}]
627\definechemicalsymbol[d:MINUS]       [{\chemicalsymbol[d:minus]}]
628\definechemicalsymbol[d:EQUALS]      [{\chemicalsymbol[d:equals]}]
629\definechemicalsymbol[d:GIVES]       [{\chemicalsymbol[d:gives]}]
630\definechemicalsymbol[d:EQUILIBRIUM] [{\chemicalsymbol[d:equilibrium]}]
631\definechemicalsymbol[d:MESOMERIC]   [{\chemicalsymbol[d:mesomeric]}]
632\definechemicalsymbol[d:SINGLE]      [{\chemicalsymbol[d:single]}]
633\definechemicalsymbol[d:DOUBLE]      [{\chemicalsymbol[d:double]}]
634\definechemicalsymbol[d:TRIPLE]      [{\chemicalsymbol[d:triple]}]
635\definechemicalsymbol[d:OPENCOMPLEX] [{\chemicalsymbol[d:opencomplex]}]
636\definechemicalsymbol[d:CLOSECOMPLEX][{\chemicalsymbol[d:closecomplex]}]
637
638\unexpanded\def\formulachemical
639  {\relax\dotriplegroupempty\chem_formula}
640
641\def\chem_formula#1#2#3% we could do hboxes and measure
642  {\ifthirdargument
643     \doifelsenothing{#2}\chem_formula_top_nop{\chem_formula_top_yes{#2}}%
644     \doifelsenothing{#3}\chem_formula_bot_nop{\chem_formula_bot_yes{#3}}%
645   \else\ifsecondargument
646     \chem_formula_top_nop
647     \doifelsenothing{#2}\chem_formula_bot_nop{\chem_formula_bot_yes{#2}}%
648   \else
649     \chem_formula_top_nop
650     \chem_formula_bot_nop
651   \fi\fi
652   \ifcsname\??chemicalsymbol d:\detokenize{#1}\endcsname
653     \toksapp\t_chem_mid{\chemicalsymbol[d:#1]\aligntab}%
654   \else
655     \toksapp\t_chem_mid{\molecule{#1}\aligntab}%
656   \fi}
657
658\def\chem_formula_mid#1%
659  {\csname\??chemicalsymbol\detokenize{#1}\endcsname}
660
661\def\chem_formula_top_nop  {\toksapp\t_chem_top{\aligntab}}
662\def\chem_formula_bot_nop  {\toksapp\t_chem_bot{\aligntab}}
663\def\chem_formula_top_yes#1{\toksapp\t_chem_top{\chem_formula_top_indeed{#1}\aligntab}\settrue\c_chem_has_top}
664\def\chem_formula_bot_yes#1{\toksapp\t_chem_bot{\chem_formula_bot_indeed{#1}\aligntab}\settrue\c_chem_has_bot}
665
666\def\chem_formula_top_indeed#1{\strut#1}
667\def\chem_formula_bot_indeed#1{\strut#1}
668
669% Experimental: defaults might change.
670
671\definefloat
672  [\v!chemical]
673  [\v!chemicals]
674
675\setuplabeltext
676  [\v!chemical=]
677
678\setupfloat
679  [\v!chemical]
680  [\c!location=\v!here,
681   \c!inner=\hsize.8\textwidth\dontleavehmode, % brr
682   \c!align={\v!flushleft,\v!lohi}]
683
684\setupcaption
685  [\v!chemical]
686  [\c!location=\v!right,
687   \c!distance=\zeropoint,
688   \c!width=.2\textwidth,
689   \c!align=\v!flushright]
690
691% Can be used as for displayed math: \startplaceformula... to display a chemical formula
692% or a chemical structure:
693%
694% \startplacechemical
695%   \startchemicalformula
696%     \chemical{2H_2}
697%     \chemical{PLUS}
698%     \chemical{O_2}
699%     \chemical{GIVES}
700%     \chemical{2H_2O}
701%   \stopchemicalformula
702% \stopplacechemical
703
704% gone: state option resolution offset (now frame offset) alternative
705
706\setupchemicalframed
707  [\c!align=\v!normal,
708   \c!strut=\v!no,
709   \c!offset=\v!overlay,
710   \c!frame=\v!off]
711
712\definecolor % private color
713  [chemicalframecolor]
714  [r=.75,g=.85,b=.95]
715
716\setupchemical
717  [\c!frame=,
718   \c!width=\v!fit,  % or unitless number, multiplies scale*unit
719   \c!height=\v!fit, % or unitless number, multiplies scale*unit
720   \c!left=\v!fit,   % or unitless number, multiplies scale*unit
721   \c!right=\v!fit,  % or unitless number, multiplies scale*unit
722   \c!top=\v!fit,    % or unitless number, multiplies scale*unit
723   \c!bottom=\v!fit, % or unitless number, multiplies scale*unit
724   \c!bodyfont=,
725   \c!scale=\v!normal, % small, normal or medium, big, or unitless number (multiplies unit)
726   \c!size=\v!medium,
727   \c!textsize=\v!big, % how is textsize used??
728   \c!axis=\v!off,
729   \c!style=\rm,
730   \c!rotation=0,    % unitless number (interpreted as degrees)
731   \c!symalign=\v!auto,
732   \c!location=,     % not yet used (was interaction related in mkii)
733   \c!offset=.25\emwidth,
734   \c!unit=\emwidth,
735   \c!factor=3,
736   \c!color=,
737   \c!strut=\v!yes,
738   \c!framecolor=chemicalframecolor,
739   \c!rulethickness=0.6pt, %1.5\linewidth,
740   \c!rulecolor=]
741
742%D Compatibility:
743
744\definechemical[+R]               {\chemical[RR]}
745\definechemical[-R]               {\chemical[LR]}
746
747\definechemical[CARBON:CB]        {\chemical[NEWMANSTAGGER,C,SB]}
748\definechemical[NEWMANSTAGGER:CB] {\chemical[NEWMANSTAGGER,C,SB]}
749\definechemical[NEWMANECLIPSED:CB]{\chemical[NEWMANECLIPSED,C,SB]}
750\definechemical[CARBON:CB1]       {\chemical[CARBON,C,SB,Z234,1.5MOV1,MIR0,C,SB,Z234]}
751
752\definechemical[NEWMAN]           {\chemical[]}
753\definechemical[STAGGER]          {\chemical[NEWMANSTAGGER]}
754\definechemical[ECLIPSE]          {\chemical[NEWMANECLIPSED]}
755\definechemical[ECLIPSED]         {\chemical[NEWMANECLIPSED]}
756\definechemical[SIX:FRONT]        {\chemical[SIXFRONT]}
757\definechemical[FIVE:FRONT]       {\chemical[FIVEFRONT]}
758
759\protect \endinput
760