chem-str.mkxl /size: 32 Kb    last modification: 2025-02-21 11:03
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 {\chemicalparameter\c!rulethickness}%
172     offset        {\chemicalparameter\c!offset}%
173     unit          {\chemicalparameter\c!unit}%
174     factor        {\chemicalparameter\c!factor}%
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      {\todimension{\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      {\todimension{\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{(\ht\scratchboxone-\dp\scratchboxone)/2}\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{\dp\scratchboxone+\ht\scratchboxtwo}\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{\dp\scratchboxtwo+\ht\scratchboxone}\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
547     \s!height.75\exheight
548     \s!depth {\linewidth-.75\exheight}%
549     \s!width \emwidth
550   \relax}
551
552\permanent\protected\def\chemicalsinglebondrule
553  {\hpack{\chemicalbondrule}}
554
555\permanent\protected\def\chemicaldoublebondrule
556  {\hpack
557     {\lower.5\exheight\chemicalsinglebondrule
558      \kern-\emwidth
559      \raise.5\exheight\chemicalsinglebondrule}}
560
561\permanent\protected\def\chemicaltriplebondrule
562  {\hpack
563     {\chemicalsinglebondrule
564      \kern-\emwidth
565      \lower.5\exheight\chemicalsinglebondrule
566      \kern-\emwidth
567      \raise.5\exheight\chemicalsinglebondrule}}
568
569\definechemicalsymbol[i:space]       [\enspace\quad\enspace]
570\definechemicalsymbol[i:plus]        [\enspace\mathematics{+}\enspace]
571\definechemicalsymbol[i:minus]       [\enspace\mathematics{-}\enspace]
572\definechemicalsymbol[i:equals]      [\enspace\mathematics{=}\enspace]
573\definechemicalsymbol[i:gives]       [\enspace\mathematics{\xrightarrow{}{}}\enspace]
574\definechemicalsymbol[i:equilibrium] [\enspace\mathematics{\xrightoverleftarrow{}{}}\enspace]
575\definechemicalsymbol[i:mesomeric]   [\enspace\mathematics{\xleftrightarrow{}{}}\enspace]
576\definechemicalsymbol[i:single]      [\chemicalsinglebondrule]
577\definechemicalsymbol[i:double]      [\chemicaldoublebondrule]
578\definechemicalsymbol[i:triple]      [\chemicaltriplebondrule]
579
580\permanent\protected\def\chemicalsinglebond {\chemicalsymbol[i:single]}
581\permanent\protected\def\chemicaldoublebond {\chemicalsymbol[i:double]}
582\permanent\protected\def\chemicaltriplebond {\chemicalsymbol[i:triple]}
583\permanent\protected\def\chemicalgives      {\chemicalsymbol[i:gives]}
584\permanent\protected\def\chemicalmesomeric  {\chemicalsymbol[i:mesomeric]}
585\permanent\protected\def\chemicalequilibrium{\chemicalsymbol[i:equilibrium]}
586\permanent\protected\def\chemicalplus       {\chemicalsymbol[i:plus]}
587\permanent\protected\def\chemicalminus      {\chemicalsymbol[i:minus]}
588\permanent\protected\def\chemicalequals     {\chemicalsymbol[i:equals]}
589\permanent\protected\def\chemicalspace      {\chemicalsymbol[i:space]}
590% \permanent\protected\def\chemicalinline   #1{#1}
591% \permanent\protected\def\chemicalspecial  #1{#1}
592
593\permanent\protected\def\chemicalinline#1%
594  {#1}
595
596\permanent\protected\def\chemicalspecial#1%
597  {\penalty\plustenthousand
598   \hskip.1\emwidth\s!plus.1\emwidth\relax
599   #1%
600   \penalty\plusfivehundred
601   \hskip.1\emwidth\s!plus.1\emwidth\relax}
602
603% display
604
605\newconditional\c_chem_has_top
606\newconditional\c_chem_has_bot
607
608\newtoks\t_chem_top
609\newtoks\t_chem_mid
610\newtoks\t_chem_bot
611
612\newif\ifinchemicalformula
613
614\permanent\protected\def\startchemicalformula
615  {\mathortext\vcenter\vbox\bgroup
616   \forgetall
617   \inchemicalformulatrue
618   \expand\everychemical
619   \everychemical\emptytoks
620   \t_chem_top\emptytoks % not needed
621   \t_chem_mid\emptytoks % not needed
622   \t_chem_bot\emptytoks % not needed
623   \enforced\let\chemical\formulachemical
624   \c_chem_has_top\conditionalfalse
625   \c_chem_has_bot\conditionalfalse}
626
627\permanent\protected\def\stopchemicalformula
628  {\tabskip\emwidth\relax
629   \ifvmode\nointerlineskip\fi
630   \ifconditional\c_chem_has_top
631     \ifconditional\c_chem_has_bot
632       \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}%
633     \else
634       \halign{\aligntab\hss\usechemicalstyleandcolor\c!style\c!color\alignmark\alignmark\hss\cr\expand\t_chem_top\cr\expand\t_chem_mid\cr}%
635     \fi
636   \else
637     \ifconditional\c_chem_has_bot
638       \halign{\aligntab\hss\usechemicalstyleandcolor\c!style\c!color\alignmark\alignmark\hss\cr\expand\t_chem_mid\cr\expand\t_chem_bot\cr}%
639     \else
640       \halign{\aligntab\hss\usechemicalstyleandcolor\c!style\c!color\alignmark\alignmark\hss\cr\expand\t_chem_mid\cr}%
641     \fi
642   \fi
643   \egroup}
644
645% for the moment we have a special set .. kind of old
646
647\definechemicalsymbol[d:space]       [\enspace\quad\enspace]
648\definechemicalsymbol[d:plus]        [\enspace+\enspace]
649\definechemicalsymbol[d:minus]       [\enspace-\enspace]
650\definechemicalsymbol[d:equals]      [\enspace=\enspace]
651\definechemicalsymbol[d:gives]       [\cgives]
652\definechemicalsymbol[d:equilibrium] [\cequilibrium]
653\definechemicalsymbol[d:mesomeric]   [\cmesomeric]
654\definechemicalsymbol[d:single]      [\chemicalsinglebondrule]
655\definechemicalsymbol[d:double]      [\chemicaldoublebondrule]
656\definechemicalsymbol[d:triple]      [\chemicaltriplebondrule]
657\definechemicalsymbol[d:opencomplex] [\mathematics{\Bigg[}]     % not yet ok
658\definechemicalsymbol[d:closecomplex][\mathematics{\Bigg]}]     % not yet ok
659
660\definechemicalsymbol[d:SPACE]       [{\chemicalsymbol[d:space]}]
661\definechemicalsymbol[d:PLUS]        [{\chemicalsymbol[d:plus]}]
662\definechemicalsymbol[d:MINUS]       [{\chemicalsymbol[d:minus]}]
663\definechemicalsymbol[d:EQUALS]      [{\chemicalsymbol[d:equals]}]
664\definechemicalsymbol[d:GIVES]       [{\chemicalsymbol[d:gives]}]
665\definechemicalsymbol[d:EQUILIBRIUM] [{\chemicalsymbol[d:equilibrium]}]
666\definechemicalsymbol[d:MESOMERIC]   [{\chemicalsymbol[d:mesomeric]}]
667\definechemicalsymbol[d:SINGLE]      [{\chemicalsymbol[d:single]}]
668\definechemicalsymbol[d:DOUBLE]      [{\chemicalsymbol[d:double]}]
669\definechemicalsymbol[d:TRIPLE]      [{\chemicalsymbol[d:triple]}]
670\definechemicalsymbol[d:OPENCOMPLEX] [{\chemicalsymbol[d:opencomplex]}]
671\definechemicalsymbol[d:CLOSECOMPLEX][{\chemicalsymbol[d:closecomplex]}]
672
673\permanent\tolerant\protected\def\formulachemical#=#=#=%
674  {\relax
675   \ifarguments\or
676     \chem_formula_top_nop
677     \chem_formula_bot_nop
678   \or
679     \chem_formula_top_nop
680     \ifempty{#2}\chem_formula_bot_nop\else\chem_formula_bot_yes{#2}\fi
681   \or
682     \ifempty{#2}\chem_formula_top_nop\else\chem_formula_top_yes{#2}\fi
683     \ifempty{#3}\chem_formula_bot_nop\else\chem_formula_bot_yes{#3}\fi
684   \fi
685   \ifcsname\??chemicalsymbol d:\detokenize{#1}\endcsname
686     \toksapp\t_chem_mid{\chemicalsymbol[d:#1]\aligntab}%
687   \else
688     \toksapp\t_chem_mid{\molecule{#1}\aligntab}%
689   \fi}
690
691\def\chem_formula_mid#1%
692  {\csname\??chemicalsymbol\detokenize{#1}\endcsname}
693
694\def\chem_formula_top_nop  {\toksapp\t_chem_top{\aligntab}}
695\def\chem_formula_bot_nop  {\toksapp\t_chem_bot{\aligntab}}
696\def\chem_formula_top_yes#1{\toksapp\t_chem_top{\chem_formula_top_indeed{#1}\aligntab}\c_chem_has_top\conditionaltrue}
697\def\chem_formula_bot_yes#1{\toksapp\t_chem_bot{\chem_formula_bot_indeed{#1}\aligntab}\c_chem_has_bot\conditionaltrue}
698
699\def\chem_formula_top_indeed#1{\strut#1}
700\def\chem_formula_bot_indeed#1{\strut#1}
701
702% Experimental: defaults might change.
703
704\definefloat
705  [\v!chemical]
706  [\v!chemicals]
707
708\setuplabeltext
709  [\v!chemical=]
710
711\setupfloat
712  [\v!chemical]
713  [\c!location=\v!here,
714   \c!inner=\hsize.8\textwidth\dontleavehmode, % brr
715   \c!align={\v!flushleft,\v!lohi}]
716
717\setupcaption
718  [\v!chemical]
719  [\c!location=\v!right,
720   \c!distance=\zeropoint,
721   \c!width=.2\textwidth,
722   \c!align=\v!flushright]
723
724% Can be used as for displayed math: \startplaceformula... to display a chemical formula
725% or a chemical structure:
726%
727% \startplacechemical
728%   \startchemicalformula
729%     \chemical{2H_2}
730%     \chemical{PLUS}
731%     \chemical{O_2}
732%     \chemical{GIVES}
733%     \chemical{2H_2O}
734%   \stopchemicalformula
735% \stopplacechemical
736
737% gone: state option resolution offset (now frame offset) alternative
738
739\setupchemicalframed
740  [\c!align=\v!normal,
741   \c!strut=\v!no,
742   \c!offset=\v!overlay,
743   \c!frame=\v!off]
744
745\definecolor % private color
746  [chemicalframecolor]
747  [r=.75,g=.85,b=.95]
748
749\setupchemical
750  [\c!frame=,
751   \c!width=\v!fit,  % or unitless number, multiplies scale*unit
752   \c!height=\v!fit, % or unitless number, multiplies scale*unit
753   \c!left=\v!fit,   % or unitless number, multiplies scale*unit
754   \c!right=\v!fit,  % or unitless number, multiplies scale*unit
755   \c!top=\v!fit,    % or unitless number, multiplies scale*unit
756   \c!bottom=\v!fit, % or unitless number, multiplies scale*unit
757   \c!bodyfont=,
758   \c!scale=\v!normal, % small, normal or medium, big, or unitless number (multiplies unit)
759   \c!size=\v!medium,
760   \c!textsize=\v!big, % how is textsize used??
761   \c!axis=\v!off,
762   \c!style=\rm,
763   \c!rotation=0,    % unitless number (interpreted as degrees)
764   \c!symalign=\v!auto,
765   \c!location=,     % not yet used (was interaction related in mkii)
766   \c!offset=.25\emwidth,
767   \c!unit=\emwidth,
768   \c!factor=3,
769   \c!color=,
770   \c!strut=\v!yes,
771   \c!framecolor=chemicalframecolor,
772   \c!rulethickness=0.6pt, %1.5\linewidth,
773   \c!rulecolor=]
774
775%D Compatibility:
776
777% Now we have + - : shortening and L R : rotating
778
779% \definechemical[+R]               {\chemical[RR]} % fails
780% \definechemical[-R]               {\chemical[LR]} % fails
781
782\definechemical[CARBON:CB]        {\chemical[NEWMANSTAGGER,C,SB]}
783\definechemical[NEWMANSTAGGER:CB] {\chemical[NEWMANSTAGGER,C,SB]}
784\definechemical[NEWMANECLIPSED:CB]{\chemical[NEWMANECLIPSED,C,SB]}
785\definechemical[CARBON:CB1]       {\chemical[CARBON,C,SB,Z234,1.5MOV1,MIR0,C,SB,Z234]}
786
787\definechemical[NEWMAN]           {\chemical[]}
788\definechemical[STAGGER]          {\chemical[NEWMANSTAGGER]}
789\definechemical[ECLIPSE]          {\chemical[NEWMANECLIPSED]}
790\definechemical[ECLIPSED]         {\chemical[NEWMANECLIPSED]}
791\definechemical[SIX:FRONT]        {\chemical[SIXFRONT]}
792\definechemical[FIVE:FRONT]       {\chemical[FIVEFRONT]}
793
794%D This is new, more in sycn with math.
795
796\definemathstackers
797  [\v!chemistry]
798  [\v!mathematics]
799  [\c!offset=\v!max,
800%    \c!order=\v!reverse,
801   \c!left=\enspace,
802   \c!right=\enspace,
803   \c!hoffset=.5\mathemwidth]
804
805\definemathextensible [\v!chemistry] [creturns]          ["2190]
806\definemathextensible [\v!chemistry] [cgives]            ["2192]
807\definemathextensible [\v!chemistry] [cmesomeric]        ["2194]
808\definemathextensible [\v!chemistry] [cequilibrium]      ["21C4]
809\definemathextensible [\v!chemistry] [cleaningright]     ["21CB]
810\definemathextensible [\v!chemistry] [cleaningleft]      ["21CC]
811
812\definemathextensible [\v!chemistry] [clongreturns]      ["27F5]
813\definemathextensible [\v!chemistry] [clonggives]        ["27F6]
814\definemathextensible [\v!chemistry] [clongmesomeric]    ["27F7]
815\definemathextensible [\v!chemistry] [clongequilibrium]  ["21C4]
816\definemathextensible [\v!chemistry] [clongleaningright] ["21CB]
817\definemathextensible [\v!chemistry] [clongleaningleft]  ["21CC]
818
819%permanent\protected\def\cplus  {+}
820%permanent\protected\def\cminus {-}
821%permanent\protected\def\cequals{=}
822
823\permanent\protected\def\csinglebond{\mathchemicalbond{\chemicalsinglebondrule}} % todo dedicated class
824\permanent\protected\def\cdoublebond{\mathchemicalbond{\chemicaldoublebondrule}} % idem
825\permanent\protected\def\ctriplebond{\mathchemicalbond{\chemicaltriplebondrule}} % idem
826
827\aliased\let\csingle\csinglebond
828\aliased\let\cdouble\cdoublebond
829\aliased\let\ctriple\ctriplebond
830
831\setmathoptions\mathchemicalbondcode\numexpr
832   \shortinlineclassoptioncode
833\relax
834
835\setmathpostpenalty\mathchemicalbondcode\plusfivehundred
836
837\installcorenamespace {chemistry}
838
839\installswitchcommandhandler \??chemistry {chemistry}
840
841\setupchemistry
842  [\c!spacing=\v!chemistry,
843  %\c!factor=3000, % display
844   \c!filter=\v!yes,
845   \c!scale=800]   % script
846
847\defineformula
848  [\v!chemistry]
849% [setups=chemistry:formula]
850
851\definemathspacing
852  [\v!chemistry]
853  [\v!horizontal]
854  [3000]
855
856\definemathfence
857  [ccomplex]
858  [\c!left="005B,
859   \c!right="005D]
860
861\newtoks \everychemistry
862\newtoks \everydisplaychemistry
863
864\permanent\protected\def\chem_ch{\mathtriplet[\v!chemistry]}
865
866\appendtoks
867    \setmathignore\Umathxscale\plustwo
868    \setmathignore\Umathyscale\plustwo
869    \setmathignore\Umathspacebeforescript \plusone % alternatively we can set the factors
870    \setmathignore\Umathspacebetweenscript\plusone
871    \setmathignore\Umathspaceafterscript  \plusone
872    \bitwiseflip\mathscriptsmode\plusone
873    \scratchcounter\chemistryparameter\c!scale
874    \glyphscriptscale      {\glyphscriptscale      *\scratchcounter/\plusthousand}%
875    \glyphscriptscriptscale{\glyphscriptscriptscale*\scratchcounter/\plusthousand}%
876    \enforced\let\math_default\math_upright
877    \enforced\let\ch\chem_ch
878\to \everychemistry
879
880\appendtoks
881   \expand\everychemistry
882   \setupmathspacing[\chemistryparameter\c!spacing]%
883 % \Umathxscale\allmathstyles\chemistryparameter\c!factor\relax
884\to \everydisplaychemistry
885
886% this will move to math-ini ... digits inherit from ordinary
887
888\newmuskip\extrafencemuskip
889
890\appendtoks
891    \inherited\setmathspacing \mathchemicalbondcode \mathordinarycode     \allsplitstyles   \tinymuskip
892    \inherited\setmathspacing \mathchemicalbondcode \mathordinarycode     \allunsplitstyles \pettymuskip
893    \inherited\setmathspacing \mathordinarycode     \mathchemicalbondcode \allsplitstyles   \tinymuskip
894    \inherited\setmathspacing \mathordinarycode     \mathchemicalbondcode \allunsplitstyles \pettymuskip
895\to \everychemistry
896
897\appendtoks
898    \inherited\setmathspacing \mathopencode         \mathordinarycode     \allmathstyles    \extrafencemuskip
899    \inherited\setmathspacing \mathordinarycode     \mathclosecode        \allmathstyles    \extrafencemuskip
900    \extrafencemuskip \medmuskip
901\to \everydisplaychemistry
902
903% .. upto here
904
905% \permanent\protected\def\ic#1%
906%   {\im{%
907%      \expand\everychemistry
908%      \mathupright\relax
909%      \clf_ic{#1}%
910%    }}
911
912% \permanent\protected\def\dc#1%
913%   {\dm{%
914%      \expand\everydisplaychemistry
915%      \mathupright\relax
916%      \clf_ic{#1}%
917%    }}
918
919\permanent\protected\def\chem_ic#1%
920  {\expand\everychemistry
921   \mathupright\relax
922   \ifcstok{\chemistryparameter\c!filter}\v!yes
923     \clf_ic{#1}%
924   \else
925     #1\relax
926   \fi}
927
928\permanent\protected\def\chem_dc#1%
929  {\expand\everydisplaychemistry
930   \mathupright\relax
931   \ifcstok{\chemistryparameter\c!filter}\v!yes
932     \clf_ic{#1}%
933   \else
934     #1\relax
935   \fi}
936
937\permanent\protected\def\ic#1%
938 {\relax
939  \ifmmode
940    \mathconstruct{\forceinlinemath\chem_ic{#1}}%
941  \else
942    \startimath\chem_ic{#1}\stopimath
943  \fi}
944
945\permanent\protected\def\dc#1%
946  {\relax\ifmmode
947     \mathconstruct{\forcedisplaymath\chem_dc{#1}}%
948   \else % no grouping
949     \startimath\forcedisplaymath\chem_dc{#1}\stopimath
950   \fi}
951
952\aliased\let\stopchemistry\relax
953
954\permanent\tolerant\protected\def\startchemistry[#1]#:#2\stopchemistry
955  {\begingroup
956   \ifhastok={#1}%
957     \setupcurrentchemistry[#1]%
958   \fi
959   \expand\everydisplaychemistry
960   \startchemistryformula
961     \ifcstok{\chemistryparameter\c!filter}\v!yes
962       \clf_ic{#2}%
963     \else
964       #2\relax
965     \fi
966   \stopchemistryformula
967   \endgroup}
968
969\protect \endinput
970