chem-str.mkxl /size: 32 Kb    last modification: 2024-01-16 09:02
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%D NOT YET LMTX'd
19
20\writestatus{loading}{ConTeXt Chemistry Macros / Structure}
21
22\registerctxluafile{chem-str}{}
23
24% We have a slightly different interface. This is unchanged:
25%
26% \startchemical[axis=on]
27%     \chemical[SIX,ROT2,B,R6,SUB1,FIVE,ROT1,B][1]
28% \stopchemical
29%
30% Here we use chemicalformula instead, so no longer a mix:
31%
32% \startchemicalformula
33%     \chemical{2H_2}{top}{bottom}
34%     \chemical{PLUS}{top}{bottom}
35%     \chemical{O_2}{top}{bottom}
36%     \chemical{GIVES}{top}{bottom}
37%     \chemical{2H_2O}{top}{bottom}
38% \stopchemicalformula
39%
40% \startchemicalformula
41%     \chemical{2H_2}
42%     \chemical{PLUS}
43%     \chemical{O_2}
44%     \chemical{GIVES}
45%     \chemical{2H_2O}
46% \stopchemicalformula
47%
48% The inline variant has only one argument:
49%
50% \chemical{2H_2,PLUS,O_2,GIVES,2H_2O}
51
52\unprotect
53
54\installcorenamespace{chemical}
55\installcorenamespace{chemicalsymbol}
56\installcorenamespace{chemicalframed}
57\installcorenamespace{chemicalsize}
58
59% \installsimplecommandhandler \??chemical {chemical} \??chemical % no \define...
60\installcommandhandler \??chemical {chemical} \??chemical % no \define...
61
62\aliased\let\setupchemicals \setupchemical
63\aliased\let\definechemicals\definechemical
64
65%D We use a dedicated framed macro instead of inheriting one. This is both
66%D a historical and practical reason (like shared keys with different meaning
67%D that could clash, e.g.\ align).
68
69\defineMPinstance % not really needed as we set in lua
70  [chemistry]
71  [\s!format=metafun,
72  %\s!extensions=\v!yes,      % Should we add extensions and initializations?
73  %\s!initializations=\v!yes, % Would this give EmWidth, etc.?
74   \c!method=\s!double]
75
76\startMPdefinitions{chemistry}
77    loadmodule "chem" ;
78\stopMPdefinitions
79
80\defineframed
81  [\??chemicalframed]
82  [\c!align=\v!normal,
83   \c!strut=\v!no]
84
85\mutable\lettonothing\currentdefinedchemical
86
87\permanent\protected\def\setupchemicalframed
88  {\setupframed[\??chemicalframed]}
89
90\permanent\protected\tolerant\overloaded\def\definechemical[#1]#:#2% is global (so we don't use the commandhandler)
91  {\startnointerference
92   \cdef\currentdefinedchemical{#1}%
93   \enforced\let\chemical\chem_chemical_nested
94   \clf_undefinechemical{#1}%
95   #2% flush
96   \stopnointerference}
97
98\permanent\tolerant\protected\def\chem_chemical_nested[#1]#*[#2]%
99  {\clf_definechemical{\currentdefinedchemical}{#1}{\detokenize{#2}}}
100
101% chemical symbols
102
103\permanent\tolerant\protected\def\definechemicalsymbol[#1]#*[#2]%
104  {\ifarguments\else\defcsname\??chemicalsymbol#1\endcsname{#2}\fi}
105
106\permanent\protected\def\chemicalsymbol[#1]%
107  {\csname\??chemicalsymbol\ifcsname\??chemicalsymbol#1\endcsname#1\else\s!unknown\fi\endcsname}
108
109\definechemicalsymbol[\s!unknown][] % \char"FFFD empty
110
111% size (small medium big)
112
113% \edef\chemicaltoplocation{t}
114% \edef\chemicalbotlocation{b}
115
116\permanent\protected\def\chemicaltext#1%
117  {\mathematics
118     {\usechemicalstyleandcolor\c!style\c!color
119      \strut
120      \ifcase\currentxfontsize\or\scriptstyle\or\scriptscriptstyle\fi
121      #1}}
122
123\defcsname\??chemicalsize\v!small \endcsname{\txx}
124\defcsname\??chemicalsize\v!medium\endcsname{\tx}
125\defcsname\??chemicalsize\v!big   \endcsname{}
126
127\newtoks       \everychemical
128\newtoks       \everystructurechemical
129
130\newtoks       \t_chem_every_box
131\newbox        \b_chem_result
132\newconditional\c_chem_some_text
133\newdimension  \d_chem_width
134\newdimension  \d_chem_height
135\newdimension  \d_chem_depth
136
137\permanent\tolerant\protected\def\startchemical[#S#1]#*[#S#2]%
138  {\ifmmode\vcenter\else\vbox\fi % vpack ?
139   \bgroup
140   \synchronizestrut{\chemicalparameter\c!strut}%
141   \dontcomplain
142   \forgetall
143   \ifparameter#2\or
144     \ifhastok={#1}%
145       \setupcurrentchemical[#1]% same as \currentchemical
146     \else
147       \cdef\currentchemical{#1}%
148       \setupcurrentchemical[#2]%
149     \fi
150   \orelse\ifparameter#1\or
151     \ifhastok={#1}%
152       \setupcurrentchemical[#1]% same as \currentchemical
153     \else
154       \cdef\currentchemical{#1}%
155     \fi
156   \fi
157   \expand\everystructurechemical
158   \setbox\b_chem_result\hpack\bgroup
159   \clf_startchemical
160     width         {\chemicalparameter\c!width}%
161     height        {\chemicalparameter\c!height}%
162     left          {\chemicalparameter\c!left}%
163     right         {\chemicalparameter\c!right}%
164     top           {\chemicalparameter\c!top}%
165     bottom        {\chemicalparameter\c!bottom}%
166     scale         {\chemicalparameter\c!scale}%
167     rotation      {\chemicalparameter\c!rotation}%
168     symalign      {\chemicalparameter\c!symalign}%
169     axis          {\chemicalparameter\c!axis}% was \MPcolor{...}
170     framecolor    {\chemicalparameter\c!framecolor}%
171     rulethickness \dimexpr\chemicalparameter\c!rulethickness\relax
172     offset        \dimexpr\chemicalparameter\c!offset\relax
173     unit          \dimexpr\chemicalparameter\c!unit\relax
174     factor        \numexpr\chemicalparameter\c!factor\relax
175   \relax
176   \startnointerference}
177
178\permanent\protected\def\stopchemical
179  {\stopnointerference
180   \clf_stopchemical
181   \egroup
182   \d_chem_width \wd\b_chem_result
183   \d_chem_height\ht\b_chem_result
184   \d_chem_depth \dp\b_chem_result
185   \expand\t_chem_every_box
186   \ifempty{\chemicalparameter\c!frame}%
187     \chem_framed_nop
188   \else
189     \chem_framed_yes
190   \fi
191   \egroup}
192
193\protected\def\chem_framed_yes
194  {\localframedwithsettings
195     [\??chemicalframed]%
196     [\c!frame=\chemicalparameter\c!frame,
197      \c!rulethickness=\chemicalparameter\c!rulethickness,
198      \c!framecolor=\chemicalparameter\c!framecolor]%
199     {\vpack{\box\b_chem_result\vss}}} % remove depth
200
201\protected\def\chem_framed_nop
202  {\directlocalframed
203     [\??chemicalframed]%
204     {\vpack{\box\b_chem_result\vss}}} % remove depth
205
206\aliased\let\startstructurechemical\startchemical
207\aliased\let\stopstructurechemical \stopchemical
208
209\appendtoks
210    \enforced\let\chemical\structurechemical
211\to\everystructurechemical
212
213\permanent\tolerant\protected\def\structurechemical[#1]#*[#2]#*[#S#3]%
214  {\ifparameter#3\or
215     \expandafter\strc_chem_indeed_three
216   \else
217     \expandafter\strc_chem_indeed_two
218   \fi[#1][#2][#3]}
219
220\def\strc_chem_indeed_three[#1][#2][#3]%
221  {\writestatus\m!chemicals{hyperlinked chemicals not yet supported}% todo reference, for the moment ignored
222   \clf_chemicalcomponent
223      {#2}%
224      {\detokenize{#3}}%
225      {\the\dimexpr\chemicalparameter\c!rulethickness}% todo: scaled points
226      {\chemicalparameter\c!rulecolor}%
227   \relax
228   \ignorespaces}
229
230\def\strc_chem_indeed_two[#1][#S#2]% why no [#3] here
231  {\clf_chemicalcomponent
232      {#1}%
233      {\detokenize{#2}}%
234      {\the\dimexpr\chemicalparameter\c!rulethickness}% todo: scaled points
235      {\chemicalparameter\c!rulecolor}%
236   \relax
237   \ignorespaces}
238
239\appendtoks
240    \setbox\b_chem_result\hpack{\raise\MPlly\box\b_chem_result}%
241    \d_chem_width \wd\b_chem_result
242    \d_chem_height\ht\b_chem_result
243    \d_chem_depth \dp\b_chem_result
244\to \t_chem_every_box
245
246% kind of compatible, but text sizes instead of math sizes (i.e. tx is larger than scriptsize)
247
248\appendtoks
249    \usebodyfontparameter\chemicalparameter
250  % \edef\m_bodyfont{\chemicalparameter\c!bodyfont}%
251  % \ifempty\m_bodyfont\else
252  %     \switchtobodyfont[\m_bodyfont]%
253  % \fi
254    \begincsname\??chemicalsize\chemicalparameter\c!size\endcsname
255% \to \everystructurechemical
256\to \everychemical
257
258\permanent\protected\def\chemicaltoptext#1{\global\c_chem_some_text\conditionaltrue\gdef\m_chem_top_text{#1}\ignorespaces}
259\permanent\protected\def\chemicalbottext#1{\global\c_chem_some_text\conditionaltrue\gdef\m_chem_bot_text{#1}\ignorespaces}
260\permanent\protected\def\chemicalmidtext#1{\global\c_chem_some_text\conditionaltrue\gdef\m_chem_mid_text{#1}\ignorespaces}
261
262\mutable\lettonothing\toptext
263\mutable\lettonothing\bottext
264\mutable\lettonothing\midtext
265
266\appendtoks
267    \let\toptext\chemicaltoptext \glettonothing\m_chem_top_text
268    \let\bottext\chemicalbottext \glettonothing\m_chem_bot_text
269    \let\midtext\chemicalmidtext \glettonothing\m_chem_mid_text
270    \global\c_chem_some_text\conditionalfalse
271\to \everystructurechemical
272
273\def\chem_add_texts
274  {\setbox\scratchboxone  \hpack to \d_chem_width{\strut\hss\hbox{\strut\m_chem_mid_text}\hss}%
275   \setbox\scratchboxtwo  \hpack to \d_chem_width{\strut\hss\hbox{\strut\m_chem_top_text}\hss}%
276   \setbox\scratchboxthree\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     \kern-\d_chem_width
280     \raise\d_chem_height\hpack{\lower\ht\scratchboxtwo\box\scratchboxtwo}%
281     \kern-\d_chem_width
282     \lower.5\dimexpr\ht\scratchboxone-\dp\scratchboxone\relax\box\scratchboxone
283     \kern-\d_chem_width
284     \lower\d_chem_depth\hpack{\raise\dp\scratchboxthree\box\scratchboxthree}%
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\permanent\protected\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\permanent\protected\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\permanent\protected\def\chemicaltop        {\chem_top_construct   \hss  \hss  }
372\permanent\protected\def\chemicallefttop    {\chem_top_construct   \relax\hss  }
373\permanent\protected\def\chemicalrighttop   {\chem_top_construct   \hss  \relax}
374\permanent\protected\def\chemicalbottom     {\chem_bottom_construct\hss  \hss  }
375\permanent\protected\def\chemicalleftbottom {\chem_bottom_construct\relax\hss  }
376\permanent\protected\def\chemicalrightbottom{\chem_bottom_construct\hss  \relax}
377
378\permanent\protected\def\chemicaltopleft    #1{\chemicalleft {\chemicalrighttop   {#1}{}}}
379\permanent\protected\def\chemicalbottomleft #1{\chemicalleft {\chemicalrightbottom{#1}{}}}
380\permanent\protected\def\chemicaltopright   #1{\chemicalright{\chemicallefttop    {#1}{}}}
381\permanent\protected\def\chemicalbottomright#1{\chemicalright{\chemicalleftbottom {#1}{}}}
382
383% \protected\def\chemicalcentered     #1{\hbox to \scaledfontcharwd\font`C{\setstrut\strut\hss#1\hss}}
384% \protected\def\chemicalleftcentered #1{\hbox to \scaledfontcharwd\font`C{\setstrut\strut    #1\hss}}
385% \protected\def\chemicalrightcentered#1{\hbox to \scaledfontcharwd\font`C{\setstrut\strut\hss#1}}
386
387% \let\chemicalsmashedmiddle\chemicalcentered
388% \let\chemicalsmashedleft  \chemicalleftcentered
389% \let\chemicalsmashedright \chemicalrightcentered
390
391\permanent\protected\def\chemicalalignedtext
392  {\ifmmode
393     \expandafter\chem_aligned_text_math
394   \else
395     \expandafter\chem_aligned_text_text
396   \fi}
397
398\aliased\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 \scaledfontcharwd\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 \scaledfontcharwd\font`C\bgroup
416     \setstrut\strut
417     #1\mathematics{\tf\triggermathstyle\scratchcounter\molecule{#3}}#2%
418   \egroup
419   \endgroup}
420
421\permanent\protected\def\chemicalcentered     {\chemicalalignedtext\hss  \hss  }
422\permanent\protected\def\chemicalleftcentered {\chemicalalignedtext\relax\hss  }
423\permanent\protected\def\chemicalrightcentered{\chemicalalignedtext\hss  \relax}
424
425\aliased\let\chemicalsmashedmiddle\chemicalcentered
426\aliased\let\chemicalsmashedleft  \chemicalleftcentered
427\aliased\let\chemicalsmashedright \chemicalrightcentered
428
429\permanent\protected\def\chemicaloxidation#1#2#3%
430  {\chemicaltop{\txx\ifcase#2\relax0\else#1\convertnumber{I}{#2}\fi}{#3}}
431
432% todo: modernize
433
434\permanent\protected\def\chemicaloxidationplus {\dotriplegroupempty\chemicaloxidation{\textplus }} % {} needed!
435\permanent\protected\def\chemicaloxidationminus{\dotriplegroupempty\chemicaloxidation{\textminus}} % {} needed!
436\permanent\protected\def\chemicalforeveropen   {\dotriplegroupempty\chemicalleft     {$\big[$}}    % {} needed!
437\permanent\protected\def\chemicalforeverclose  {\dotriplegroupempty\chemicalright    {$\big]$}}    % {} needed!
438\permanent\protected\def\chemicaloxidationone  {\chemicaloxidation\relax1}
439\permanent\protected\def\chemicaloxidationtwo  {\chemicaloxidation\relax2}
440\permanent\protected\def\chemicaloxidationthree{\chemicaloxidation\relax3}
441\permanent\protected\def\chemicaloxidationfour {\chemicaloxidation\relax4}
442\permanent\protected\def\chemicaloxidationfive {\chemicaloxidation\relax5}
443\permanent\protected\def\chemicaloxidationsix  {\chemicaloxidation\relax6}
444\permanent\protected\def\chemicaloxidationseven{\chemicaloxidation\relax7}
445
446\permanent\protected\def\chemicalbar
447  {\hpack \s!spread .5\emwidth \bgroup
448     \hss
449     \vrule \s!height .9\strutht \s!depth .65\strutdp \s!width .1\exheight
450     \hss
451   \egroup}
452
453\permanent\let\X\relax
454\permanent\let\T\relax
455\permanent\let\B\relax
456\permanent\let\L\relax
457\permanent\let\M\relax
458\permanent\let\R\relax
459
460\appendtoks
461   \amcode\barasciicode\zerocount
462   \enforced\let|\chemicalbar % \SR{N|NH}
463\to \everychemical
464
465\appendtoks
466   \enforced\let \+\chemicaloxidationplus
467   \enforced\let \-\chemicaloxidationminus
468   \enforced\let \[\chemicalforeveropen
469   \enforced\let \]\chemicalforeverclose
470   \enforced\let \1\chemicaloxidationone
471   \enforced\let \2\chemicaloxidationtwo
472   \enforced\let \3\chemicaloxidationthree
473   \enforced\let \4\chemicaloxidationfour
474   \enforced\let \5\chemicaloxidationfive
475   \enforced\let \6\chemicaloxidationsix
476   \enforced\let \7\chemicaloxidationseven
477   \enforced\let \X\chemicaltighttext
478   \enforced\let \T\chemicaltop
479   \enforced\let \B\chemicalbottom
480   \enforced\let \L\chemicalleft
481   \enforced\let\LC\chemicalleftcentered
482   \enforced\let \R\chemicalright
483   \enforced\let\RC\chemicalrightcentered
484   \enforced\let\TL\chemicaltopleft
485   \enforced\let\BL\chemicalbottomleft
486   \enforced\let\TR\chemicaltopright
487   \enforced\let\BR\chemicalbottomright
488   \enforced\let\LT\chemicallefttop
489   \enforced\let\LB\chemicalleftbottom
490   \enforced\let\RT\chemicalrighttop
491   \enforced\let\RB\chemicalrightbottom
492   \enforced\let\SL\chemicalsmashedleft
493   \enforced\let\SM\chemicalsmashedmiddle
494   \enforced\let\SR\chemicalsmashedright
495\to \everychemical
496
497% Should these also be defined in lower case, so as to be case independent?
498
499\appendtoks
500    \expand\everychemical
501\to \everystructurechemical
502
503% inline
504
505\permanent\protected\def\chemical
506  {\ifinformula
507     \expandafter\indisplaychemical
508   \else
509     \expandafter\inlinechemical
510   \fi}
511
512\permanent\protected\def\indisplaychemical
513  {\mathstylecommand\displaychemical\inlinechemical\inlinechemical}
514
515\permanent\tolerant\protected\def\displaychemical#=#=#=%
516  {\expand\everychemical
517   \everychemical\emptytoks
518   \quad
519   \vcenter\bgroup
520     \usechemicalstyleandcolor\c!style\c!color
521     \ifparameter#3\or
522       \ifparameter#2\or
523         \halign{\aligntab\hss\alignmark\alignmark\hss\cr#2\cr\molecule{#1}\cr#3\cr}%
524       \else
525         \halign{\aligntab\hss\alignmark\alignmark\hss     \cr\molecule{#1}\cr#2\cr}%
526       \fi
527     \else
528       \hbox{\molecule{#1}}%
529     \fi
530   \egroup
531   \quad}
532
533% \permanent\protected\def\inlinechemical#1%
534%   {\dontleavehmode
535%    \hbox{\usechemicalstyleandcolor\c!style\c!color\clf_inlinechemical{#1}}}
536
537\permanent\protected\def\inlinechemical#1%
538  {\dontleavehmode\begingroup
539  %\hbox % will become option
540   \usechemicalstyleandcolor\c!style\c!color\clf_inlinechemical{#1}%
541   \endgroup}
542
543\aliased\let\ic\inlinechemical
544
545\permanent\protected\def\chemicalbondrule
546  {\vrule\s!height.75\exheight\s!depth-\dimexpr.75\exheight-\linewidth\relax\s!width\emwidth\relax}
547
548\permanent\protected\def\chemicalsinglebondrule
549  {\hpack{\chemicalbondrule}}
550
551\permanent\protected\def\chemicaldoublebondrule
552  {\hpack
553     {\lower.5\exheight\chemicalsinglebondrule
554      \kern-\emwidth
555      \raise.5\exheight\chemicalsinglebondrule}}
556
557\permanent\protected\def\chemicaltriplebondrule
558  {\hpack
559     {\chemicalsinglebondrule
560      \kern-\emwidth
561      \lower.5\exheight\chemicalsinglebondrule
562      \kern-\emwidth
563      \raise.5\exheight\chemicalsinglebondrule}}
564
565\definechemicalsymbol[i:space]       [\enspace\quad\enspace]
566\definechemicalsymbol[i:plus]        [\enspace\mathematics{+}\enspace]
567\definechemicalsymbol[i:minus]       [\enspace\mathematics{-}\enspace]
568\definechemicalsymbol[i:equals]      [\enspace\mathematics{=}\enspace]
569\definechemicalsymbol[i:gives]       [\enspace\mathematics{\xrightarrow{}{}}\enspace]
570\definechemicalsymbol[i:equilibrium] [\enspace\mathematics{\xrightoverleftarrow{}{}}\enspace]
571\definechemicalsymbol[i:mesomeric]   [\enspace\mathematics{\xleftrightarrow{}{}}\enspace]
572\definechemicalsymbol[i:single]      [\chemicalsinglebondrule]
573\definechemicalsymbol[i:double]      [\chemicaldoublebondrule]
574\definechemicalsymbol[i:triple]      [\chemicaltriplebondrule]
575
576\permanent\protected\def\chemicalsinglebond {\chemicalsymbol[i:single]}
577\permanent\protected\def\chemicaldoublebond {\chemicalsymbol[i:double]}
578\permanent\protected\def\chemicaltriplebond {\chemicalsymbol[i:triple]}
579\permanent\protected\def\chemicalgives      {\chemicalsymbol[i:gives]}
580\permanent\protected\def\chemicalmesomeric  {\chemicalsymbol[i:mesomeric]}
581\permanent\protected\def\chemicalequilibrium{\chemicalsymbol[i:equilibrium]}
582\permanent\protected\def\chemicalplus       {\chemicalsymbol[i:plus]}
583\permanent\protected\def\chemicalminus      {\chemicalsymbol[i:minus]}
584\permanent\protected\def\chemicalequals     {\chemicalsymbol[i:equals]}
585\permanent\protected\def\chemicalspace      {\chemicalsymbol[i:space]}
586% \permanent\protected\def\chemicalinline   #1{#1}
587% \permanent\protected\def\chemicalspecial  #1{#1}
588
589\permanent\protected\def\chemicalinline#1%
590  {#1}
591
592\permanent\protected\def\chemicalspecial#1%
593  {\penalty\plustenthousand
594   \hskip.1\emwidth\s!plus.1\emwidth\relax
595   #1%
596   \penalty\plusfivehundred
597   \hskip.1\emwidth\s!plus.1\emwidth\relax}
598
599% display
600
601\newconditional\c_chem_has_top
602\newconditional\c_chem_has_bot
603
604\newtoks\t_chem_top
605\newtoks\t_chem_mid
606\newtoks\t_chem_bot
607
608\newif\ifinchemicalformula
609
610\permanent\protected\def\startchemicalformula
611  {\mathortext\vcenter\vbox\bgroup
612   \forgetall
613   \inchemicalformulatrue
614   \expand\everychemical
615   \everychemical\emptytoks
616   \t_chem_top\emptytoks % not needed
617   \t_chem_mid\emptytoks % not needed
618   \t_chem_bot\emptytoks % not needed
619   \enforced\let\chemical\formulachemical
620   \c_chem_has_top\conditionalfalse
621   \c_chem_has_bot\conditionalfalse}
622
623\permanent\protected\def\stopchemicalformula
624  {\tabskip\emwidth\relax
625   \ifvmode\nointerlineskip\fi
626   \ifconditional\c_chem_has_top
627     \ifconditional\c_chem_has_bot
628       \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}%
629     \else
630       \halign{\aligntab\hss\usechemicalstyleandcolor\c!style\c!color\alignmark\alignmark\hss\cr\expand\t_chem_top\cr\expand\t_chem_mid\cr}%
631     \fi
632   \else
633     \ifconditional\c_chem_has_bot
634       \halign{\aligntab\hss\usechemicalstyleandcolor\c!style\c!color\alignmark\alignmark\hss\cr\expand\t_chem_mid\cr\expand\t_chem_bot\cr}%
635     \else
636       \halign{\aligntab\hss\usechemicalstyleandcolor\c!style\c!color\alignmark\alignmark\hss\cr\expand\t_chem_mid\cr}%
637     \fi
638   \fi
639   \egroup}
640
641% for the moment we have a special set .. kind of old
642
643\definechemicalsymbol[d:space]       [\enspace\quad\enspace]
644\definechemicalsymbol[d:plus]        [\enspace+\enspace]
645\definechemicalsymbol[d:minus]       [\enspace-\enspace]
646\definechemicalsymbol[d:equals]      [\enspace=\enspace]
647\definechemicalsymbol[d:gives]       [\cgives]
648\definechemicalsymbol[d:equilibrium] [\cequilibrium]
649\definechemicalsymbol[d:mesomeric]   [\cmesomeric]
650\definechemicalsymbol[d:single]      [\chemicalsinglebondrule]
651\definechemicalsymbol[d:double]      [\chemicaldoublebondrule]
652\definechemicalsymbol[d:triple]      [\chemicaltriplebondrule]
653\definechemicalsymbol[d:opencomplex] [\mathematics{\Bigg[}]     % not yet ok
654\definechemicalsymbol[d:closecomplex][\mathematics{\Bigg]}]     % not yet ok
655
656\definechemicalsymbol[d:SPACE]       [{\chemicalsymbol[d:space]}]
657\definechemicalsymbol[d:PLUS]        [{\chemicalsymbol[d:plus]}]
658\definechemicalsymbol[d:MINUS]       [{\chemicalsymbol[d:minus]}]
659\definechemicalsymbol[d:EQUALS]      [{\chemicalsymbol[d:equals]}]
660\definechemicalsymbol[d:GIVES]       [{\chemicalsymbol[d:gives]}]
661\definechemicalsymbol[d:EQUILIBRIUM] [{\chemicalsymbol[d:equilibrium]}]
662\definechemicalsymbol[d:MESOMERIC]   [{\chemicalsymbol[d:mesomeric]}]
663\definechemicalsymbol[d:SINGLE]      [{\chemicalsymbol[d:single]}]
664\definechemicalsymbol[d:DOUBLE]      [{\chemicalsymbol[d:double]}]
665\definechemicalsymbol[d:TRIPLE]      [{\chemicalsymbol[d:triple]}]
666\definechemicalsymbol[d:OPENCOMPLEX] [{\chemicalsymbol[d:opencomplex]}]
667\definechemicalsymbol[d:CLOSECOMPLEX][{\chemicalsymbol[d:closecomplex]}]
668
669\permanent\tolerant\protected\def\formulachemical#=#=#=%
670  {\relax
671   \ifarguments\or
672     \chem_formula_top_nop
673     \chem_formula_bot_nop
674   \or
675     \chem_formula_top_nop
676     \ifempty{#2}\chem_formula_bot_nop\else\chem_formula_bot_yes{#2}\fi
677   \or
678     \ifempty{#2}\chem_formula_top_nop\else\chem_formula_top_yes{#2}\fi
679     \ifempty{#3}\chem_formula_bot_nop\else\chem_formula_bot_yes{#3}\fi
680   \fi
681   \ifcsname\??chemicalsymbol d:\detokenize{#1}\endcsname
682     \toksapp\t_chem_mid{\chemicalsymbol[d:#1]\aligntab}%
683   \else
684     \toksapp\t_chem_mid{\molecule{#1}\aligntab}%
685   \fi}
686
687\def\chem_formula_mid#1%
688  {\csname\??chemicalsymbol\detokenize{#1}\endcsname}
689
690\def\chem_formula_top_nop  {\toksapp\t_chem_top{\aligntab}}
691\def\chem_formula_bot_nop  {\toksapp\t_chem_bot{\aligntab}}
692\def\chem_formula_top_yes#1{\toksapp\t_chem_top{\chem_formula_top_indeed{#1}\aligntab}\c_chem_has_top\conditionaltrue}
693\def\chem_formula_bot_yes#1{\toksapp\t_chem_bot{\chem_formula_bot_indeed{#1}\aligntab}\c_chem_has_bot\conditionaltrue}
694
695\def\chem_formula_top_indeed#1{\strut#1}
696\def\chem_formula_bot_indeed#1{\strut#1}
697
698% Experimental: defaults might change.
699
700\definefloat
701  [\v!chemical]
702  [\v!chemicals]
703
704\setuplabeltext
705  [\v!chemical=]
706
707\setupfloat
708  [\v!chemical]
709  [\c!location=\v!here,
710   \c!inner=\hsize.8\textwidth\dontleavehmode, % brr
711   \c!align={\v!flushleft,\v!lohi}]
712
713\setupcaption
714  [\v!chemical]
715  [\c!location=\v!right,
716   \c!distance=\zeropoint,
717   \c!width=.2\textwidth,
718   \c!align=\v!flushright]
719
720% Can be used as for displayed math: \startplaceformula... to display a chemical formula
721% or a chemical structure:
722%
723% \startplacechemical
724%   \startchemicalformula
725%     \chemical{2H_2}
726%     \chemical{PLUS}
727%     \chemical{O_2}
728%     \chemical{GIVES}
729%     \chemical{2H_2O}
730%   \stopchemicalformula
731% \stopplacechemical
732
733% gone: state option resolution offset (now frame offset) alternative
734
735\setupchemicalframed
736  [\c!align=\v!normal,
737   \c!strut=\v!no,
738   \c!offset=\v!overlay,
739   \c!frame=\v!off]
740
741\definecolor % private color
742  [chemicalframecolor]
743  [r=.75,g=.85,b=.95]
744
745\setupchemical
746  [\c!frame=,
747   \c!width=\v!fit,  % or unitless number, multiplies scale*unit
748   \c!height=\v!fit, % or unitless number, multiplies scale*unit
749   \c!left=\v!fit,   % or unitless number, multiplies scale*unit
750   \c!right=\v!fit,  % or unitless number, multiplies scale*unit
751   \c!top=\v!fit,    % or unitless number, multiplies scale*unit
752   \c!bottom=\v!fit, % or unitless number, multiplies scale*unit
753   \c!bodyfont=,
754   \c!scale=\v!normal, % small, normal or medium, big, or unitless number (multiplies unit)
755   \c!size=\v!medium,
756   \c!textsize=\v!big, % how is textsize used??
757   \c!axis=\v!off,
758   \c!style=\rm,
759   \c!rotation=0,    % unitless number (interpreted as degrees)
760   \c!symalign=\v!auto,
761   \c!location=,     % not yet used (was interaction related in mkii)
762   \c!offset=.25\emwidth,
763   \c!unit=\emwidth,
764   \c!factor=3,
765   \c!color=,
766   \c!strut=\v!yes,
767   \c!framecolor=chemicalframecolor,
768   \c!rulethickness=0.6pt, %1.5\linewidth,
769   \c!rulecolor=]
770
771%D Compatibility:
772
773% Now we have + - : shortening and L R : rotating
774
775% \definechemical[+R]               {\chemical[RR]} % fails
776% \definechemical[-R]               {\chemical[LR]} % fails
777
778\definechemical[CARBON:CB]        {\chemical[NEWMANSTAGGER,C,SB]}
779\definechemical[NEWMANSTAGGER:CB] {\chemical[NEWMANSTAGGER,C,SB]}
780\definechemical[NEWMANECLIPSED:CB]{\chemical[NEWMANECLIPSED,C,SB]}
781\definechemical[CARBON:CB1]       {\chemical[CARBON,C,SB,Z234,1.5MOV1,MIR0,C,SB,Z234]}
782
783\definechemical[NEWMAN]           {\chemical[]}
784\definechemical[STAGGER]          {\chemical[NEWMANSTAGGER]}
785\definechemical[ECLIPSE]          {\chemical[NEWMANECLIPSED]}
786\definechemical[ECLIPSED]         {\chemical[NEWMANECLIPSED]}
787\definechemical[SIX:FRONT]        {\chemical[SIXFRONT]}
788\definechemical[FIVE:FRONT]       {\chemical[FIVEFRONT]}
789
790%D This is new, more in sycn with math.
791
792\definemathstackers
793  [\v!chemistry]
794  [\v!mathematics]
795  [\c!offset=\v!max,
796%    \c!order=\v!reverse,
797   \c!left=\enspace,
798   \c!right=\enspace,
799   \c!hoffset=.5\mathemwidth]
800
801\definemathextensible [\v!chemistry] [creturns]          ["2190]
802\definemathextensible [\v!chemistry] [cgives]            ["2192]
803\definemathextensible [\v!chemistry] [cmesomeric]        ["2194]
804\definemathextensible [\v!chemistry] [cequilibrium]      ["21C4]
805\definemathextensible [\v!chemistry] [cleaningright]     ["21CB]
806\definemathextensible [\v!chemistry] [cleaningleft]      ["21CC]
807
808\definemathextensible [\v!chemistry] [clongreturns]      ["27F5]
809\definemathextensible [\v!chemistry] [clonggives]        ["27F6]
810\definemathextensible [\v!chemistry] [clongmesomeric]    ["27F7]
811\definemathextensible [\v!chemistry] [clongequilibrium]  ["21C4]
812\definemathextensible [\v!chemistry] [clongleaningright] ["21CB]
813\definemathextensible [\v!chemistry] [clongleaningleft]  ["21CC]
814
815%permanent\protected\def\cplus  {+}
816%permanent\protected\def\cminus {-}
817%permanent\protected\def\cequals{=}
818
819\permanent\protected\def\csinglebond{\mathchemicalbond{\chemicalsinglebondrule}} % todo dedicated class
820\permanent\protected\def\cdoublebond{\mathchemicalbond{\chemicaldoublebondrule}} % idem
821\permanent\protected\def\ctriplebond{\mathchemicalbond{\chemicaltriplebondrule}} % idem
822
823\aliased\let\csingle\csinglebond
824\aliased\let\cdouble\cdoublebond
825\aliased\let\ctriple\ctriplebond
826
827\setmathoptions\mathchemicalbondcode\numexpr
828   \shortinlineclassoptioncode
829\relax
830
831\setmathpostpenalty\mathchemicalbondcode\plusfivehundred
832
833\installcorenamespace {chemistry}
834
835\installswitchcommandhandler \??chemistry {chemistry}
836
837\setupchemistry
838  [\c!spacing=\v!chemistry,
839  %\c!factor=3000, % display
840   \c!filter=\v!yes,
841   \c!scale=800]   % script
842
843\defineformula
844  [\v!chemistry]
845% [setups=chemistry:formula]
846
847\definemathspacing
848  [\v!chemistry]
849  [\v!horizontal]
850  [3000]
851
852\definemathfence
853  [ccomplex]
854  [\c!left="005B,
855   \c!right="005D]
856
857\newtoks \everychemistry
858\newtoks \everydisplaychemistry
859
860\permanent\protected\def\chem_ch{\mathtriplet[\v!chemistry]}
861
862\appendtoks
863    \setmathignore\Umathxscale\plustwo
864    \setmathignore\Umathyscale\plustwo
865    \setmathignore\Umathspacebeforescript\plusone
866    \setmathignore\Umathspaceafterscript \plusone
867    \mathscriptsmode\plusone
868    \scratchcounter\chemistryparameter\c!scale
869    \glyphscriptscale      \numexpr\glyphscriptscale      *\scratchcounter/\plusthousand\relax
870    \glyphscriptscriptscale\numexpr\glyphscriptscriptscale*\scratchcounter/\plusthousand\relax
871    \enforced\let\math_default\math_upright
872    \enforced\let\ch\chem_ch
873\to \everychemistry
874
875\appendtoks
876   \expand\everychemistry
877   \setupmathspacing[\chemistryparameter\c!spacing]%
878 % \Umathxscale\allmathstyles\chemistryparameter\c!factor\relax
879\to \everydisplaychemistry
880
881% this will move to math-ini ... digits inherit from ordinary
882
883\newmuskip\extrafencemuskip
884
885\appendtoks
886    \inherited\setmathspacing \mathchemicalbondcode \mathordinarycode     \allsplitstyles   \tinymuskip
887    \inherited\setmathspacing \mathchemicalbondcode \mathordinarycode     \allunsplitstyles \pettymuskip
888    \inherited\setmathspacing \mathordinarycode     \mathchemicalbondcode \allsplitstyles   \tinymuskip
889    \inherited\setmathspacing \mathordinarycode     \mathchemicalbondcode \allunsplitstyles \pettymuskip
890\to \everychemistry
891
892\appendtoks
893    \inherited\setmathspacing \mathopencode         \mathordinarycode     \allmathstyles    \extrafencemuskip
894    \inherited\setmathspacing \mathordinarycode     \mathclosecode        \allmathstyles    \extrafencemuskip
895    \extrafencemuskip \medmuskip
896\to \everydisplaychemistry
897
898% .. upto here
899
900% \permanent\protected\def\ic#1%
901%   {\im{%
902%      \expand\everychemistry
903%      \mathupright\relax
904%      \clf_ic{#1}%
905%    }}
906
907% \permanent\protected\def\dc#1%
908%   {\dm{%
909%      \expand\everydisplaychemistry
910%      \mathupright\relax
911%      \clf_ic{#1}%
912%    }}
913
914\permanent\protected\def\chem_ic#1%
915  {\expand\everychemistry
916   \mathupright\relax
917   \ifcstok{\chemistryparameter\c!filter}\v!yes
918     \clf_ic{#1}%
919   \else
920     #1\relax
921   \fi}
922
923\permanent\protected\def\chem_dc#1%
924  {\expand\everydisplaychemistry
925   \mathupright\relax
926   \ifcstok{\chemistryparameter\c!filter}\v!yes
927     \clf_ic{#1}%
928   \else
929     #1\relax
930   \fi}
931
932\permanent\protected\def\ic#1%
933 {\relax
934  \ifmmode
935    \mathconstruct{\forceinlinemath\chem_ic{#1}}%
936  \else
937    \startimath\chem_ic{#1}\stopimath
938  \fi}
939
940\permanent\protected\def\dc#1%
941  {\relax\ifmmode
942     \mathconstruct{\forcedisplaymath\chem_dc{#1}}%
943   \else % no grouping
944     \startimath\forcedisplaymath\chem_dc{#1}\stopimath
945   \fi}
946
947\aliased\let\stopchemistry\relax
948
949\permanent\tolerant\protected\def\startchemistry[#1]#:#2\stopchemistry
950  {\begingroup
951   \ifhastok={#1}%
952     \setupcurrentchemistry[#1]%
953   \fi
954   \expand\everydisplaychemistry
955   \startchemistryformula
956     \ifcstok{\chemistryparameter\c!filter}\v!yes
957       \clf_ic{#2}%
958     \else
959       #2\relax
960     \fi
961   \stopchemistryformula
962   \endgroup}
963
964\protect \endinput
965