diff options
author | Karl Berry <karl@freefriends.org> | 2022-01-17 20:55:11 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2022-01-17 20:55:11 +0000 |
commit | 1fc36ea6203e28039e852897fda29426365f8116 (patch) | |
tree | dd90594985d0271c1458a48c48c78e7f5f162a6d /Master/texmf-dist/tex/latex/chemmacros/chemmacros.sty | |
parent | cfbda5f99f31e4fa8bb06f60ee3511be9154b2fc (diff) |
chemmacros (17jan22)
git-svn-id: svn://tug.org/texlive/trunk@61631 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/latex/chemmacros/chemmacros.sty')
-rw-r--r-- | Master/texmf-dist/tex/latex/chemmacros/chemmacros.sty | 6802 |
1 files changed, 6657 insertions, 145 deletions
diff --git a/Master/texmf-dist/tex/latex/chemmacros/chemmacros.sty b/Master/texmf-dist/tex/latex/chemmacros/chemmacros.sty index e56c6284763..5fcbd0a3180 100644 --- a/Master/texmf-dist/tex/latex/chemmacros/chemmacros.sty +++ b/Master/texmf-dist/tex/latex/chemmacros/chemmacros.sty @@ -12,29 +12,29 @@ % If you have any ideas, questions, suggestions or bugs to report, please % feel free to contact me. % -------------------------------------------------------------------------- -% Copyright 2011--2020 Clemens Niederberger +% Copyright 2011--2022 Clemens Niederberger % % This work may be distributed and/or modified under the -% conditions of the LaTeX Project Public License, either version 1.3c +% conditions of the LaTeX Project Public License, either version 1.3 % of this license or (at your option) any later version. % The latest version of this license is in % http://www.latex-project.org/lppl.txt -% and version 1.3c or later is part of all distributions of LaTeX -% version 2008/05/04 or later. +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. % % This work has the LPPL maintenance status `maintained'. % % The Current Maintainer of this work is Clemens Niederberger. % -------------------------------------------------------------------------- -\RequirePackage{expl3,xparse,l3keys2e} +\RequirePackage{l3keys2e} \ExplSyntaxOn % -------------------------------------------------------------------------- % package information: -\tl_const:Nn \c_chemmacros_date_tl {2020/11/21} -\tl_const:Nn \c_chemmacros_version_major_number_tl {5} -\tl_const:Nn \c_chemmacros_version_minor_number_tl {11} -\tl_const:Nn \c_chemmacros_version_subrelease_tl {a} +\tl_const:Nn \c_chemmacros_date_tl {2022/01/16} +\tl_const:Nn \c_chemmacros_version_major_number_tl {6} +\tl_const:Nn \c_chemmacros_version_minor_number_tl {0} +\tl_const:Nn \c_chemmacros_version_subrelease_tl {} \tl_const:Nx \c_chemmacros_version_number_tl { \c_chemmacros_version_major_number_tl . @@ -55,218 +55,6730 @@ {\c_chemmacros_info_tl \c_space_tl (CN)} % -------------------------------------------------------------------------- -% set compatibility -\tl_new:N \l__chemmacros_compatibility_version_tl -\tl_set_eq:NN \l__chemmacros_compatibility_version_tl \c_chemmacros_version_tl +% variants of kernel functions: +\cs_generate_variant:Nn \tl_if_eq:nnTF {x,xx,V} +\cs_generate_variant:Nn \tl_replace_once:Nnn {NnV} +\cs_generate_variant:Nn \tl_tail:n {e} -\keys_define:nn {chemmacros/compatibility} +\cs_generate_variant:Nn \seq_set_split:Nnn {Nnx} +\cs_generate_variant:Nn \seq_item:Nn {cV,NV} +\cs_generate_variant:Nn \seq_put_right:Nn {Ne} + +\cs_generate_variant:Nn \prop_item:Nn {NV} +\cs_generate_variant:Nn \prop_gput:Nnn {cxx,NVf} + +\cs_generate_variant:Nn \int_to_arabic:n {V} + +\cs_generate_variant:Nn \msg_error:nnnnn {nnnx} +\cs_generate_variant:Nn \msg_error:nnnn {nnnx} +\cs_generate_variant:Nn \msg_error:nnn {nnV} +\cs_generate_variant:Nn \msg_warning:nnn {nnV} +\cs_generate_variant:Nn \msg_warning:nnnn {nnV} +\cs_generate_variant:Nn \msg_show:nnnn {nnnV} + +\cs_generate_variant:Nn \vbox_set:Nn {NV} + +\cs_generate_variant:Nn \keys_define:nn {x} +\cs_generate_variant:Nn \keys_set:nn {x,nx} + +\cs_generate_variant:Nn \str_if_eq:nnF {xx} + +% -------------------------------------------------------------------------- +% load-time messages: +\msg_new:nnn {chemmacros} {load-time-option} + { + `#1'~ is~ a~ load-time~ option! \\ + You~ cannot~ set~ it~ with~ \token_to_str:N \chemsetup ! \\ + You~ need~ to~ use~ \token_to_str:N \usepackage [#1] {chemmacros} . + } + +\msg_new:nnn {chemmacros} {unknown-option} + { + Unknown~ option~ `#1' \\ + I~ dont'~ know~ the~ option~ `#1'.~ Please~ make~ sure~ there~ is~ no~ + typo.~ Check~ the~ manual~ for~ help. + } + +\msg_new:nnn {chemmacros} {module-mechanism} + { + The~ module~ mechanism~ has~ changed~ with~ v6! \\ + ==== ======= ========== ==== ======== ===== === \\ + *~ All~ modules~ have~ been~ integrated~ into~ \\ + the~ main~ package~ and~ thus~ are~ preloaded~ \\ + already~ (unless~ you~ have~ loaded~ \\ + `chemmacros'~ with~ the~ `minimal'~ option). \\ + *~ The~ new~ default~ corresponds~ to~ the~ \\ + earlier~ setting~ `modules=all'. + \tl_if_blank:nF {#1} + { \\ The~ command~ \token_to_str:N #1 is~ deprecated. } + } + +\cs_new_protected:Npn \__chemmacros_loadtime_error:n #1 + { \msg_error:nnV {chemmacros} {#1} \l_keys_key_str } + +\cs_new_protected:Npn \__chemmacros_loadtime_warning:n #1 + { \msg_warning:nnV {chemmacros} {#1} \l_keys_key_str } + +\clist_new:N \l_chemmacros_modules_clist +\clist_set:Nn \l_chemmacros_modules_clist + { + base, errorcheck, lang, greek, chemformula, charges, acid-base, symbols, + particles, phases, nomenclature, tikz, xfrac, translations + } + +\clist_const:Nn \c_chemmacros_all_modules_clist + { + base, errorcheck, lang, greek, chemformula, charges, acid-base, symbols, + particles, phases, nomenclature, tikz, isotopes, mechanisms, newman, + orbital, polymers, reactions, redox, xfrac, scheme, spectroscopy, + thermodynamics, units, reactants, translations + } + +\keys_define:nn {chemmacros/package-options} + { + minimal .bool_set:N = \l__chemmacros_minimal_bool , + minimal .initial:n = false , + modules .code:n = + \clist_if_in:NF \l_chemmacros_modules_clist + { \clist_put_right:Nn \l_chemmacros_modules_clist {#1} } , + unknown .code:n = \__chemmacros_loadtime_warning:n {unknown-option} + } + +\ProcessKeysPackageOptions {chemmacros/package-options} + +\keys_define:nn {chemmacros} + { + minimal .code:n = \__chemmacros_loadtime_error:n {load-time-option} , + modules .code:n = + \msg_warning:nn {chemmacros} {module-mechanism} + \__chemmacros_loadtime_warning:n {load-time-option} , + package-options / minimal .meta:nn = {chemmacros} {minimal} , + package-options / modules .meta:nn = {chemmacros} {modules} + } + +\NewDocumentCommand \usechemmodule {m} + { \msg_warning:nnn {chemmacros} {module-mechanism} {\usechemmodule} } + +\bool_if:NF \l__chemmacros_minimal_bool + { + \clist_set_eq:NN + \l_chemmacros_modules_clist + \c_chemmacros_all_modules_clist + } + +% -------------------------------------------------------------------------- +% temporary variables: +\tl_new:N \l__chemmacros_tmpa_tl +\tl_new:N \l__chemmacros_tmpb_tl +\tl_new:N \l__chemmacros_tmpc_tl +\tl_new:N \l__chemmacros_tmpd_tl + +\bool_new:N \l__chemmacros_tmpa_bool +\bool_new:N \l__chemmacros_tmpb_bool +\bool_new:N \l__chemmacros_tmpc_bool + +\dim_new:N \l__chemmacros_tmpa_dim +\dim_new:N \l__chemmacros_tmpb_dim +\dim_new:N \l__chemmacros_tmpc_dim + +\seq_new:N \l__chemmacros_tmpa_seq +\seq_new:N \l__chemmacros_tmpb_seq +\seq_new:N \l__chemmacros_tmpc_seq + +\int_new:N \l__chemmacros_tmpa_int +\int_new:N \l__chemmacros_tmpb_int +\int_new:N \l__chemmacros_tmpc_int + +\box_new:N \l__chemmacros_tmpa_box +\box_new:N \l__chemmacros_tmpb_box +\box_new:N \l__chemmacros_tmpc_box + +\clist_new:N \l__chemmacros_tmpa_clist +\clist_new:N \l__chemmacros_tmpb_clist +\clist_new:N \l__chemmacros_tmpc_clist + +\str_new:N \l__chemmacros_tmpa_str +\str_new:N \l__chemmacros_tmpb_str +\str_new:N \l__chemmacros_tmpc_str + +% ---------------------------------------------------------------------------- +% module mechanism: +\msg_new:nnn {chemmacros} {module-missing} + { + You've~ requested~ the~ chemmacros~ module~ `#1'~ but~ it~ appears~ to~ + be~ missing~ on~ your~ system.~ Maybe~ you've~ misspelled~ the~ name?~ + Loading~ the~ module~ will~ abort~ \msg_line_context: + } + +\msg_new:nnn {chemmacros} {loading-module} + { Loading~ the~ chemmacros~ module~ `#1'~ ... } + +\msg_new:nnn {chemmacros} {wrong-module-name} + { The~ module~ file~ name~ is~ `#2'~ but~ it~ provides~ module~ `#1'. } + +\msg_new:nnn {chemmacros} {forbidden-module} + { + You've~ requested~ the~ chemmacros~ module~ `modules'~ \msg_line_context: .~ + This~ module~ is~ a~ pseudo~ module~ which~ may~ not~ be~ loaded~ through~ + the~ module~ loading~ mechansim. + } + +% ---------------------------------------------------------------------------- +\prg_new_conditional:Npnn \chemmacros_package_if_loaded:n #1 {p,T,F,TF} + { + \cs_if_exist:cTF {ver@#1.sty} + { \prg_return_true: } + { \prg_return_false: } + } + +% ---------------------------------------------------------------------------- +% this is for external file modules called "styles": +\tl_const:Nn \c__chemmacros_module_extension_tl {code.tex} +\tl_const:Nn \c__chemmacros_module_prefix_tl {chemmacros} + +\tl_new:N \g__chemmacros_modules_loaded_tl + +\cs_new_protected:Npn \chemmacros_modules_load:n #1 + { \clist_map_inline:nn {#1} { \chemmacros_module_load:n {##1} } } + +\cs_new_protected:Npn \chemmacros_module_load:n #1 + { + \tl_set:Nx \l_tmpa_tl { \tl_trim_spaces:n {#1} } + \str_if_eq:VnTF \l_tmpa_tl {modules} + { \msg_error:nn {chemmacros} {forbidden-module} } + { \__chemmacros_module_load:V \l_tmpa_tl } + } + +\cs_new_protected:Npn \__chemmacros_module_load:n #1 + { + \chemmacros_module_if_loaded:nF {#1} + { + \chemmacros_module_if_exist:nTF {#1} + { + \__chemmacros_module_hook_use:nn {#1} {before} + \msg_info:nnn {chemmacros} {loading-module} {#1} + \@onefilewithoptions + {\c__chemmacros_module_prefix_tl.#1}[][] + \c__chemmacros_module_extension_tl + \__chemmacros_module_hook_use:nn {#1} {after} + } + { \msg_error:nnn {chemmacros} {module-missing} {#1} } + } + } +\cs_generate_variant:Nn \__chemmacros_module_load:n {V} + +\prg_new_conditional:Npnn \chemmacros_module_if_loaded:n #1 {p,T,F,TF} + { + \tl_if_in:NnTF \g__chemmacros_modules_loaded_tl {#1} + { \prg_return_true: } + { \prg_return_false: } + } + +\prg_new_conditional:Npnn \chemmacros_module_if_exist:n #1 {p,T,F,TF} + { + \file_if_exist:nTF + {\c__chemmacros_module_prefix_tl.#1.\c__chemmacros_module_extension_tl} + { \prg_return_true: } + { \prg_return_false: } + } + +% -------------------------------------------------------------------------- +% module hooks: +% #1: module +% #2: code +\cs_new_protected:Npn \chemmacros_module_after:nn #1#2 + { + \chemmacros_module_if_loaded:nTF {#1} + {#2} + { \__chemmacros_add_to_module_hook:nnn {#1} {after} {#2} } + } + +% #1: module +% #2: code +\cs_new_protected:Npn \chemmacros_module_before:nn #1#2 + { + % TODO: error in T case? + \chemmacros_module_if_loaded:nF {#1} + { \__chemmacros_add_to_module_hook:nnn {#1} {before} {#2} } + } + +% #1: module +% #2: hook name +% #3: code +\cs_new_protected:Npn \__chemmacros_add_to_module_hook:nnn #1#2#3 + { + \chemmacros_module_if_loaded:nF {#1} + { + \tl_if_exist:cF {g__chemmacros_module_hook_#1_#2_tl} + { \tl_new:c {g__chemmacros_module_hook_#1_#2_tl} } + \tl_gput_right:cn {g__chemmacros_module_hook_#1_#2_tl} {#3} + } + } + +% #1: module +% #2: hook name +\cs_new_protected:Npn \__chemmacros_module_hook_use:nn #1#2 + { + \tl_if_exist:cT {g__chemmacros_module_hook_#1_#2_tl} + { + \tl_use:c {g__chemmacros_module_hook_#1_#2_tl} + \tl_gclear:c {g__chemmacros_module_hook_#1_#2_tl} + } + } +\cs_generate_variant:Nn \__chemmacros_module_hook_use:nn {V} + +% -------------------------------------------------------------------------- +\tl_new:N \l__chemmacros_module_date_tl +\tl_new:N \l__chemmacros_module_version_tl + +\tl_set_eq:NN \l__chemmacros_module_date_tl \c_chemmacros_date_tl +\tl_set_eq:NN \l__chemmacros_module_version_tl \c_chemmacros_version_tl + +\cs_new_protected:Npn \__chemmacros_module:nn #1#2 + { + \tl_gput_right:Nn \g__chemmacros_modules_loaded_tl {{#1}} + \str_if_eq:xxF + {\c__chemmacros_module_prefix_tl.#1.\c__chemmacros_module_extension_tl} + {\@currname.\@currext} + { + \msg_error:nnnxx {chemmacros} {wrong-module-name} + {#1} + {\@currname.\@currext} + } + \ProvidesFile + {\c__chemmacros_module_prefix_tl.#1.\c__chemmacros_module_extension_tl} + [ + \l__chemmacros_module_date_tl + \c_space_tl + v \l__chemmacros_module_version_tl + \c_space_tl + chemmacros~ style~ file~ `#1'~ (#2) + ] + } + +% -------------------------------------------------------------------------- +% define internal chemmacros modules: +\tl_new:N \g_chemmacros_module_tl +\tl_new:N \g__chemmacros_module_stop_tl + +\cs_new_protected:Npn \chemmacros_stop_module:n #1 + { \tl_gput_right:Nn \g__chemmacros_module_stop_tl {{#1}} } + +% #1: name +% #2: description +\cs_new_protected:Npn \ChemModule #1#2 + { + \str_if_in:NnT \g__chemmacros_module_stop_tl {{#1}} + { \__chemmacros_gobble_module:w } + \msg_log:nnnn {chemmacros} {loading-module} {#1} {#2} + \msg_term:nnnn {chemmacros} {loading-module} {#1} {#2} + \tl_gput_right:Nn \g__chemmacros_modules_loaded_tl {{#1}} + \tl_gset:Nn \g_chemmacros_module_tl {#1} + \__chemmacros_module_hook_use:nn {#1} {before} + } + +\cs_new_protected:Npn \ChemModuleEnd + { \__chemmacros_module_hook_use:Vn \g_chemmacros_module_tl {after} } + +\cs_new_protected:Npn \__chemmacros_gobble_module:w #1 \ChemModuleEnd {} + +\clist_map_inline:Nn \c_chemmacros_all_modules_clist + { + \clist_if_in:NnF \l_chemmacros_modules_clist {#1} + { \chemmacros_stop_module:n {#1} } + } + +% -------------------------------------------------------------------------- +\ChemModule{base}{2022/01/10 basic chemmacros module} + +% -------------------------------------------------------------------------- +\msg_new:nnn {chemmacros} {command-deprecated} + { + The~ command~ \token_to_str:N #1 \c_space_tl is~ deprecated.~ Use~ + \token_to_str:N #2 \c_space_tl instead. + } + +% define a deprecated command with hints to the corresponding new one: +\cs_new_protected:Npn \chemmacros_define_deprecated:NN #1#2 + { + \cs_set_protected:Npn #1 + { \msg_warning:nnnn {chemmacros} {command-deprecated} {#1} {#2} #2 } + } + +\NewDocumentCommand \DeclareChemDeprecated {mm} + { \chemmacros_define_deprecated:NN #1 #2 } + +% -------------------------------------------------------------------------- +% define a macro set: +% \NewChem... \RenewChem... \DeclareChem... \ProvideChem... +% #1: macro names +% #2: arg spec +% #3: internal command call +\cs_new_protected:Npn \chemmacros_new_macroset:nnn #1#2#3 + { + \exp_args:Nc \NewDocumentCommand + { + NewChem + \str_uppercase:f { \tl_head:n {#1} } + \tl_tail:n {#1} + } + {#2} + { + \cs_if_free:NTF ##1 + { #3 } + { \msg_error:nnn {chemmacros} {new-#1} {##1} } + } + \exp_args:Nc \NewDocumentCommand + { + RenewChem + \str_uppercase:f { \tl_head:n {#1} } + \tl_tail:n {#1} + } + {#2} + { + \cs_if_free:NTF ##1 + { \msg_error:nnn {chemmacros} {renew-#1} {##1} } + { #3 } + } + \exp_args:Nc \NewDocumentCommand + { + DeclareChem + \str_uppercase:f { \tl_head:n {#1} } + \tl_tail:n {#1} + } + {#2} + {#3} + \exp_args:Nc \NewDocumentCommand + { + ProvideChem + \str_uppercase:f { \tl_head:n {#1} } + \tl_tail:n {#1} + } + {#2} + { \cs_if_free:NT ##1 { #3 } } + \msg_new:nnn {chemmacros} {new-#1} + { + You've~ tried~ to~ define~ a~ #1~ with~ \token_to_str:N + \NewChem #1 ,~ but~ the~ command~ sequence~ \token_to_str:N ##1 + \c_space_tl already~ exists.~ Please~ choose~ another~ name. + } + \msg_new:nnn {chemmacros} {renew-#1} + { + You've~ tried~ to~ renew~ the~ #1~ \token_to_str:N ##1 ,~ but~ + it~ doesn't~ exist. + } + } + +\cs_new_protected:Npn \chemmacros_new_environment_macroset:nnn #1#2#3 + { + \exp_args:Nc \NewDocumentCommand {NewChem#1} {#2} + { + \bool_lazy_and:nnTF + { \cs_if_free_p:c {##1} } + { \cs_if_free_p:c {end##1} } + {#3} + { \msg_error:nnn {chemmacros} {new-#1} {##1} } + } + \exp_args:Nc \NewDocumentCommand {RenewChem#1} {#2} + { + \bool_lazy_or:nnTF + { \cs_if_free_p:c {##1} } + { \cs_if_free_p:c {end##1} } + { \msg_error:nnn {chemmacros} {renew-#1} {##1} } + {#3} + } + \exp_args:Nc \NewDocumentCommand {DeclareChem#1} {#2} {#3} + \exp_args:Nc \NewDocumentCommand {ProvideChem#1} {#2} + { + \bool_lazy_and:nT + { \cs_if_free_p:c {##1} } + { \cs_if_free_p:c {end##1} } + {#3} + } + \msg_new:nnn {chemmacros} {new-#1} + { + You've~ tried~ to~ define~ a~ #1~ with~ \token_to_str:N + \NewChem #1 ,~ but~ the~ command~ sequence~ \exp_not:c {##1} + \c_space_tl already~ exists.~ Please~ choose~ another~ name. + } + \msg_new:nnn {chemmacros} {renew-#1} + { You've~ tried~ to~ renew~ the~ #1~ ##1,~ but~ it~ doesn't~ exist. } + } + +\NewDocumentCommand \NewChemMacroset {smmm} + { + \IfBooleanTF {#1} + { \chemmacros_new_environment_macroset:nnn {#2} {#3} {#4} } + { \chemmacros_new_macroset:nnn {#2} {#3} {#4} } + } + +% -------------------------------------------------------------------------- +\cs_new_protected:Npn \chemmacros_define_keys:nn #1#2 + { \keys_define:nn {chemmacros/#1} {#2} } +\cs_generate_variant:Nn \chemmacros_define_keys:nn {x} + +\cs_new_protected:Npn \chemmacros_set_keys:nn #1#2 + { \keys_set:nn {chemmacros/#1} {#2} } +\cs_generate_variant:Nn \chemmacros_set_keys:nn {x,nx} + +\cs_new_protected:Npn \chemmacros_set_keys_groups:nnn #1#2#3 + { \keys_set_groups:nnn {chemmacros/#1} {#2} {#3} } + +\cs_new_protected:Npn \chemmacros_set_keys_filter:nnn #1#2#3 + { \keys_set_filter:nnn {chemmacros/#1} {#2} {#3} } + +\cs_new_protected:Npn \chemmacros_define_global_keys:n #1 + { \keys_define:nn {chemmacros} {#1} } + +\cs_new_protected:Npn \chemmacros_set_global_keys:n #1 + { \keys_set:nn {chemmacros} {#1} } + +% -------------------------------------------------------------------------- +% basic tools: +\cs_new:Npn \chemmacros_remove_backslash:N #1 + { \exp_after:wN \use_none:n \token_to_str:N #1 } + +\cs_new_eq:NN \chemmacros_ignore_spaces: \tex_ignorespaces:D + +\cs_new_protected:Npn \chemmacros_nobreak: { \tex_penalty:D 10000 \scan_stop: } +\cs_new_protected:Npn \chemmacros_allow_break: { \tex_penalty:D \c_zero_int } +\cs_new_protected:Npn \chemmacros_skip_nobreak:N #1 + { + \chemmacros_nobreak: + \skip_horizontal:N #1 + \chemmacros_nobreak: + } + +% this is used at least in the `isotope' module +\prg_new_conditional:Npnn \chemmacros_if_is_int:n #1 {p,T,F,TF} + { + \if_charcode:w ! \if_int_compare:w 9 < 1#1 ! \else: _ \fi: + \prg_return_true: + \else: + \prg_return_false: + \fi: + } + +\prg_new_conditional:Npnn \chemmacros_if_loaded:nn #1#2 {p,T,F,TF} + { + \use:c {chemmacros_if_#1_loaded:nTF} {#2} + { \prg_return_true: } + { \prg_return_false: } + } + +\prg_new_conditional:Npnn \chemmacros_if_package_loaded:n #1 {p,T,F,TF} + { + \cs_if_exist:cTF {ver@#1.sty} + { \prg_return_true: } + { \prg_return_false: } + } + +\prg_new_conditional:Npnn \chemmacros_if_class_loaded:n #1 {p,T,F,TF} + { + \cs_if_exist:cTF {ver@#1.cls} + { \prg_return_true: } + { \prg_return_false: } + } + +% this is still true \AtBeginDocument: +\prg_new_conditional:Npnn \chemmacros_if_preamble: {p,T,F,TF} + { + \cs_if_eq:NNTF \@onlypreamble \@notprerr + { \prg_return_false: } + { \prg_return_true: } + } + +% this is still false \AtBeginDocument: +\prg_new_conditional:Npnn \chemmacros_if_document: {p,T,F,TF} + { + \bool_if:NTF \l__chemmacros_in_document_bool + { \prg_return_true: } + { \prg_return_false: } + } +\cs_new_protected:Npn \chemmacros_cs_if_free_new:Npn #1 + { + \cs_if_exist:NF #1 + { \cs_new:Npn #1 } + } +\cs_generate_variant:Nn \chemmacros_cs_if_free_new:Npn {c} + +\cs_new_protected:Npn \chemmacros_cs_if_free_new_protected:Npn #1 + { + \cs_if_exist:NF #1 + { \cs_new_protected:Npn #1 } + } +\cs_generate_variant:Nn \chemmacros_cs_if_free_new_protected:Npn {c} + +% #1: counter +% #2: singular +% #3: plural +% #4: Singular +% #5: Plural +\cs_new_protected:Npn \chemmacros_add_cleveref_support:nnnnn #1#2#3#4#5 + { + \hook_gput_code:nnn {package/cleveref/after} {chemmacros} + { + \cs_if_exist:cF {cref@#1@name} + { + \legacy_if:nTF {@cref@capitalise} + { \crefname {#1} {#4} {#5} } + { \crefname {#1} {#2} {#3} } + \Crefname {#1} {#4} {#5} + } + } + } +\cs_generate_variant:Nn \chemmacros_add_cleveref_support:nnnnn {nnnx,nnnxx,nnnnx} + +% #1: counter +% #2: singular +% #3: Singular (optional) +% #4: plural +% #5: Plural (optional) +\NewDocumentCommand \ChemCleverefSupport {mmomo} + { + \IfNoValueTF {#3} + { + \IfNoValueTF {#5} + { + \chemmacros_add_cleveref_support:nnnnn + {#1} + {#2} + {#4} + { \text_titlecase:n {#2} } + { \text_titlecase:n {#4} } + } + { + \chemmacros_add_cleveref_support:nnnnn + {#1} + {#2} + {#4} + { \text_titlecase:n {#2} } + {#5} + } + } + { + \IfNoValueTF {#5} + { + \chemmacros_add_cleveref_support:nnnnn + {#1} + {#2} + {#4} + {#3} + { \text_titlecase:n {#4} } + } + { \chemmacros_add_cleveref_support:nnnnn {#1} {#2} {#4} {#3} {#5} } + } + } +\@onlypreamble\ChemCleverefSupport + +% #1: id +% #2: mid sentence +% #3: begin sentence +\cs_new_protected:Npn \chemmacros_add_fancyref_support:nnn #1#2#3 { - compatibility .code:n = - \str_case:nnTF {#1} + \hook_gput_code:nnn {package/fancyref/after} {chemmacros} + { + \chemmacros_cs_if_free_new:cpn {fancyref#1labelprefix} {#1} + \chemmacros_cs_if_free_new:cpn {fref#1name} {#2} + \chemmacros_cs_if_free_new:cpn {Fref#1name} {#3} + \exp_args:Nnx \frefformat {vario} { \exp_not:c {fancyref#1labelprefix} } + { \use:c {fref#1name} \fancyrefdefaultspacing ##1##3 } + \exp_args:Nnx \Frefformat {vario} { \exp_not:c {fancyref#1labelprefix} } + { \use:c {Fref#1name} \fancyrefdefaultspacing ##1##3 } + \exp_args:Nnx \frefformat {plain} { \exp_not:c {fancyref#1labelprefix} } + { \use:c {fref#1name} \fancyrefdefaultspacing ##1 } + \exp_args:Nnx \Frefformat {plain} { \exp_not:c {fancyref#1labelprefix} } + { \use:c {Fref#1name} \fancyrefdefaultspacing ##1 } + } + } +\cs_generate_variant:Nn \chemmacros_add_fancyref_support:nnn {nnx} + +% #1: id +% #2: mid sentence +% #3: begin sentence (optional) +\NewDocumentCommand \ChemFancyrefSupport {mmo} + { + \IfNoValueTF {#3} + { \chemmacros_add_fancyref_support:nnn {#1} {#2} { \text_titlecase:n {#3} } } + { \chemmacros_add_fancyref_support:nnn {#1} {#2} {#3} } + } +\@onlypreamble\ChemFancyrefSupport + +% -------------------------------------------------------------------------- +% some checks at begin document: +\bool_new:N \l__chemmacros_in_document_bool +\bool_new:N \l__chemmacros_chemstyle_bool + +\hook_gput_code:nnn {begindocument/before} {chemmacros} + { + \bool_set_true:N \l__chemmacros_in_document_bool + \chemmacros_if_package_loaded:nT {chemstyle} + { \bool_set_true:N \l__chemmacros_chemstyle_bool } + } + +% -------------------------------------------------------------------------- +% detection and handling of bold face: +\RequirePackage{bm} + +\prg_new_protected_conditional:Npnn \chemmacros_if_bold: {T,F,TF} + { + \seq_if_in:NVTF \l__chemmacros_if_bf_seq \f@series + { \prg_return_true: } + { \prg_return_false: } + } + +\seq_new:N \l__chemmacros_if_bf_seq + +\seq_set_split:Nnn \l__chemmacros_if_bf_seq { , } + { + b , bc , bm , bx , bux , + eb , ebc , ebx , mb , + sb , sbc , sbx , + ub , ubc , ubx + } + +\cs_new_protected:Npn \chemmacros_bold:n #1 + { + \chemmacros_if_bold:TF + { + \mode_if_math:TF + { \bm {#1} } + { \textbf {#1} } + } + {#1} + } + +\cs_new_protected:Npn \chemmacros_detect_bold:n + { \error \chemmacros_bold:n } + +% -------------------------------------------------------------------------- +\RequirePackage{amstext} + +\cs_new_protected:Npn \chemmacros_text:n #1 + { \mode_if_math:TF { \text {#1} } {#1} } +\cs_generate_variant:Nn \chemmacros_text:n {V} + +\cs_new_protected:Npn \chemmacros_math:n #1 + { \chemmacros_text:n { \c_math_toggle_token #1 \c_math_toggle_token } } +\cs_generate_variant:Nn \chemmacros_math:n {V} + +% -------------------------------------------------------------------------- +% a setup command: +\NewDocumentCommand \chemsetup {om} + { + \IfNoValueTF {#1} + { \keys_set:nn {chemmacros} {#2} } + { \keys_set:nn {chemmacros/#1} {#2} } + } + +% -------------------------------------------------------------------------- + +% load package #1 and add its options to chemmacros +% this requires that package #1 defines its options with l3keys using its +% name as module +\cs_new_protected:Npn \chemmacros_integrate_package:nnn #1#2#3 + { + \tl_if_blank:nTF {#3} + { + \tl_if_blank:nTF {#1} + { \RequirePackage {#2} } + { \RequirePackage [#1] {#2} } + } + { + \tl_if_blank:nTF {#1} + { \RequirePackage {#2} [#3] } + { \RequirePackage [#1] {#2} [#3] } + } + \chemmacros_define_global_keys:n + { + #2 .choice: , + #2 / unknown .code:n = + \keys_set:no {#2} { \l_keys_key_tl = ##1 } + } + } + +% -------------------------------------------------------------------------- + +\bool_new:N \l__chemmacros_hyperref_bool + +\hook_gput_code:nnn {begindocument/end} {chemmacros} + { + \chemmacros_if_package_loaded:nT {hyperref} + { \bool_set_true:N \l__chemmacros_hyperref_bool } + } + +\ChemModuleEnd +\ChemModule{errorcheck}{2022/01/16 error checking for unloaded modules} + +\msg_new:nnn {chemmacros} {undefined} + { + The~ #1~ `#2'~ is~ undefined.~ You~ need~ to~ load~ the~ + `#3'~ module. + } + +\cs_new_protected:Npn \chemmacros_requires_module:nNn #1#2#3 + { + \chemmacros_module_if_loaded:nF {#3} + { + \cs_if_free:NT #2 + { + \str_case:nn {#1} + { + {command} { + \cs_set:Npn #2 + { + \msg_error:nnnxn {chemmacros} {undefined} + {#1} + { \token_to_str:N #2 } + {#3} + } + \chemmacros_module_before:nn {#3} { \cs_undefine:N #2 } + } + {environment} { + \cs_set:Npn #2 + { + \msg_error:nnnxn {chemmacros} {undefined} + {#1} + { \tl_tail:e { \token_to_str:N #2 } } + {#3} + } + \chemmacros_module_before:nn {#3} { \cs_undefine:N #2 } + } + } + } + } + } +\cs_generate_variant:Nn \chemmacros_requires_module:nNn {nc} + +\cs_new_protected:Npn \chemmacros_command_requires_module:Nn #1#2 + { \chemmacros_requires_module:nNn {command} #1 {#2} } + +\cs_new_protected:Npn \chemmacros_environment_requires_module:nn #1#2 + { \chemmacros_requires_module:ncn {environment} {#1} {#2} } + +% -------------------------------------------------------------------------- +% add checking for the most common user commands and environments: +% isotopes module +\chemmacros_command_requires_module:Nn \isotope {isotopes} + +% mechanisms module +\chemmacros_command_requires_module:Nn \mech {mechanisms} + +% newman module +\chemmacros_command_requires_module:Nn \newman {newman} + +% orbital module +\chemmacros_command_requires_module:Nn \orbital {orbital} + +% polymers module +\chemmacros_command_requires_module:Nn \makepolymerdelims {polymers} + +% reactions module +\chemmacros_environment_requires_module:nn {reaction} {reactions} +\chemmacros_environment_requires_module:nn {reaction*} {reactions} +\chemmacros_environment_requires_module:nn {reactions} {reactions} +\chemmacros_environment_requires_module:nn {reactions*} {reactions} +\chemmacros_command_requires_module:Nn \listofreactions {reactions} +\chemmacros_command_requires_module:Nn \AddRxnDesc {reactions} + +% redox module +\chemmacros_command_requires_module:Nn \ox {redox} +\chemmacros_command_requires_module:Nn \OX {redox} +\chemmacros_command_requires_module:Nn \redox {redox} + +% scheme module +\chemmacros_environment_requires_module:nn {scheme} {scheme} +\chemmacros_command_requires_module:Nn \listschemename {scheme} +\chemmacros_command_requires_module:Nn \schemename {scheme} +\chemmacros_command_requires_module:Nn \listofschemes {scheme} + +\hook_gput_code:nnn {package/chemscheme/before} {chemmacros} + { + \cs_undefine:N \scheme + \cs_undefine:N \endscheme + \cs_undefine:N \listschemename + \cs_undefine:N \schemename + \cs_undefine:N \listofschemes + } + +% spectroscopy module +\chemmacros_command_requires_module:Nn \NMR {spectroscopy} +\chemmacros_environment_requires_module:nn {experimental} {spectroscopy} + +% thermodynamics module +\chemmacros_command_requires_module:Nn \state {thermodynamics} +\chemmacros_command_requires_module:Nn \enthalpy {thermodynamics} +\chemmacros_command_requires_module:Nn \entropy {thermodynamics} +\chemmacros_command_requires_module:Nn \gibbs {thermodynamics} + +% xfrac module +\chemmacros_command_requires_module:Nn \chemfrac {xfrac} + +% -------------------------------------------------------------------------- + +\ChemModuleEnd +\ChemModule{lang}{2020/11/29 language settings for chemmacros} + +\RequirePackage{translations} + +\msg_new:nnn {chemmacros} {language-not-defined} + { + You~ chose~ the~ language~ `#1'~ which~ is~ not~ defined~ by~ chemmacros.~ + `english'~ is~ used~ instead.~ If~ you~ just~ mistyped~ try~ again!~ + Otherwise~ contact~ the~ author~ and~ he'll~ probably~ add~ your~ language. + } + +% -------------------------------------------------------------------------- +% language settings: +\bool_new:N \l__chemmacros_language_auto_bool +\bool_set_true:N \l__chemmacros_language_auto_bool +% this token list will hold the chosen language for chemmacros; since the +% language is either chosen automatically or by option it is only available at +% begin document +\tl_new:N \l_chemmacros_language_tl +\tl_set:Nn \l_chemmacros_language_tl {english} +\tl_new:N \l__chemmacros_current_language_tl + +\tl_const:Nn \c__chemmacros_keyword_prefix_tl {chem-keyword-} + +\prop_new:N \g_chemmacros_translations_prop + +% translate the key #1 +\cs_new:Npn \chemmacros_translate:n #1 + { + \bool_if:NTF \l__chemmacros_language_auto_bool + { \GetTranslation { \c__chemmacros_keyword_prefix_tl #1 } } + { + \GetTranslationFor + {\l_chemmacros_language_tl} + { \c__chemmacros_keyword_prefix_tl #1 } + } + } + +\DeclareExpandableDocumentCommand \ChemTranslate {m} + { \chemmacros_translate:n {#1} } + +\chemmacros_define_global_keys:n + { + language .value_required:n = true , + language .code:n = + \tl_if_eq:nnTF {#1} {auto} + { \bool_set_true:N \l__chemmacros_language_auto_bool } { - {newest} {} - {latest} {} + \bool_set_false:N \l__chemmacros_language_auto_bool + \tl_set:Nn \l__chemmacros_current_language_tl {#1} + } , + language .initial:n = auto + } + +\hook_gput_code:nnn {begindocument} {package/chemmacros} + { + \bool_if:NTF \l__chemmacros_language_auto_bool + { + \tl_set:Nx \l_chemmacros_language_tl + { \@trnslt@language{\@trnslt@current@language} } + } + { + \tl_set_eq:NN + \l_chemmacros_language_tl + \l__chemmacros_current_language_tl + } + } + +% -------------------------------------------------------------------------- +\cs_new_protected:Npn \__chemmacros_declare_translation:nw #1#2=#3\q_stop + { + \tl_set:Nx \l__chemmacros_tmpa_tl { \tl_trim_spaces:n {#2} } + \tl_set:Nx \l__chemmacros_tmpb_tl { \tl_trim_spaces:n {#3} } + \use:x + { + \chemmacros_declare_translation:nnn + { \exp_not:n {#1} } + { \exp_not:V \l__chemmacros_tmpa_tl } + { \exp_not:V \l__chemmacros_tmpb_tl } + } + } + +% #1: key +% #2: lang +% #3: translation +\cs_new_protected:Npn \chemmacros_declare_translation:nnn #1#2#3 + { + \declaretranslation + {#2} + { \c__chemmacros_keyword_prefix_tl #1 } + {#3} + \prop_gput:Nnn \g_chemmacros_translations_prop {#1(#2)} {#3} + } +\cs_generate_variant:Nn \chemmacros_declare_translation:nnn {V} + +% #1: key +% #2: csv list: { <lang1> = <translation1> , <lang2> = <translation2> } +\cs_new_protected:Npn \chemmacros_declare_translations:nn #1#2 + { + \clist_map_inline:nn {#2} + { \__chemmacros_declare_translation:nw {#1} ##1 \q_stop } + } + +\NewDocumentCommand \DeclareChemTranslations {mm} + { \chemmacros_declare_translations:nn {#1} {#2} } +\@onlypreamble \DeclareChemTranslations + +\NewDocumentCommand \DeclareChemTranslation {mmm} + { \chemmacros_declare_translation:nnn {#1} {#2} {#3} } +\@onlypreamble \DeclareChemTranslation + +\cs_new:Npn \__chemmacros_parse_translate_list_entry:nnn #1#2#3 {} + +\cs_new_protected:Npn \__chemmacros_parse_translate_list_entry:www #1(#2)\q_mark#3\q_stop + { \__chemmacros_parse_translate_list_entry:nnn {#1} {#2} {#3} } + +\cs_new_protected:Npn \chemmacros_for_all_translations_do:n #1 + { + \cs_set:Npn \__chemmacros_parse_translate_list_entry:nnn ##1##2##3 {#1} + \prop_map_inline:Nn \g_chemmacros_translations_prop + { \__chemmacros_parse_translate_list_entry:www ##1 \q_mark ##2 \q_stop } + } + +\NewDocumentCommand \ForAllChemTranslationsDo {+m} + { \chemmacros_for_all_translations_do:n {#1} } + +% -------------------------------------------------------------------------- +\ChemModuleEnd +\ChemModule{greek}{2020/11/29 upright greek symbols} + +\DeclareHookRule {begindocument/end} {chemmacros} {after} {chemgreek} +\RequirePackage{chemgreek} + +\msg_new:nnn {chemmacros} {no-greek} + { + You~ haven't~ loaded~ any~ package~ for~ upright~ Greek~ letters~ or~ no~ + unique~ choice~ was~ possible.~ Either~ load~ one~ of~ packages~ + specified~ in~ the~ manual~ or~ select~ a~ chemgreek~ mapping~ manually. + } + +\msg_new:nnn {chemmacros} {greek-undefined} + { + The~ chemgreek~ mapping~ `#1'~ you~ chose~ \msg_line_context: \c_space_tl + is~ not~ defined.~ Please~ choose~ another~ one. + } + +% chemgreek selects a mapping if an unambiguous choice is possible, otherwise +% selects `default'. Warn the user in this case: + +\hook_gput_code:nnn {begindocument/end} {chemmacros} + { + \bool_lazy_or:nnT + { \chemgreek_if_mapping_active_p:n {default} } + { \chemgreek_if_mapping_active_p:n {var-default} } + { \msg_warning:nn {chemmacros} {no-greek} } + } + +% an option for manual selection: +\chemmacros_define_global_keys:n + { greek .code:n = \chemmacros_choose_chemgreek_mapping:n {#1} } + +\cs_new_protected:Npn \chemmacros_choose_chemgreek_mapping:n #1 + { + \chemgreek_if_mapping_exists:nTF {#1} + { + \chemgreek_load_mapping_package:n {#1} + \chemgreek_activate_mapping:n {#1} + } + { \msg_warning:nnn {chemmacros} {greek-undefined} {#1} } + } + +% -------------------------------------------------------------------------- +\ChemModuleEnd +\ChemModule{chemformula}{2020/11/29 integration of chemical formulas} + +\RequirePackage{amstext} + +\msg_new:nnn {chemmacros} {unknown-formula-method} + { + You~ chose~ the~ formula~ method~ `#1'~ which~ is~ not~ available.~ + I'm~ falling~ back~ to~ `chemformula'~ now. + } + +\msg_new:nnn {chemmacros} {default-formula-method} + { + You~ haven't~ chosen~ a~ formula~ method~ so~ I'm~ assuming~ the~ default~ + method~ `chemformula'. + } + +\msg_new:nnn {chemmacros} {formula-conflict} + { + You~ have~ loaded~ multiple~ formula~ method~ packages~ but~ haven't~ + chosen~ which~ method~ to~ use!~ I~ will~ use~ `chemformula'. \\ + You~ should~ decide~ for~ only~ one~ of~ the~ packages~ for~ having~ a~ + consistent~ layout. + } + +% -------------------------------------------------------------------------- +% generic functions for usage in other packages; those are to be set in each +% method setup: +\cs_new_protected:Npn \chemmacros_reaction:n #1 {#1} +\cs_new_protected:Npn \chemmacros_chemformula:n #1 {#1} +\cs_generate_variant:Nn \chemmacros_chemformula:n { x,V } + +\cs_new_protected:Npn \chemmacros@formula #1 { \chemmacros_chemformula:n {#1} } +\cs_new_protected:Npn \chemmacros@reaction #1 { \chemmacros_reaction:n {#1} } + +% -------------------------------------------------------------------------- +% setup, check and define each method: +\bool_new:N \l__chemmacros_formula_method_set_bool + +\tl_new:N \g_chemmacros_formula_method_tl +\tl_gset:Nn \g_chemmacros_formula_method_tl {chemformula} + +\prop_new:N \l__chemmacros_method_packages_prop + +% #1: package/method name +% #2: preparations +\cs_new_protected:Npn \chemmacros_add_method_package:nn #1#2 + { \prop_put:Nnn \l__chemmacros_method_packages_prop {#1} {#2} } + +\cs_new_protected:Npn \chemmacros_setup_method_package:n #1 + { + \prop_item:Nn \l__chemmacros_method_packages_prop {#1} + \tl_gset:Nn \g_chemmacros_formula_method_tl {#1} + } + +\prg_new_conditional:Npnn \chemmacros_if_method_package:n #1 {p,T,F,TF} + { + \prop_if_in:NnTF \l__chemmacros_method_packages_prop {#1} + { \prg_return_true: } + { \prg_return_false: } + } + +\cs_new_protected:Npn \chemmacros_check_formula_method: + { + \bool_if:NF \l__chemmacros_formula_method_set_bool + { + \bool_set_false:N \l__chemmacros_tmpa_bool + \prop_map_inline:Nn \l__chemmacros_method_packages_prop + { + \chemmacros_if_package_loaded:nT {##1} + { + \bool_if:NTF \l__chemmacros_tmpa_bool + { + \msg_warning:nn {chemmacros} {formula-conflict} + \chemmacros_set_formula_method:n {chemformula} + } + { \chemmacros_set_formula_method:n {##1} } + \bool_set_true:N \l__chemmacros_tmpa_bool + } + } + \bool_if:NF \l__chemmacros_tmpa_bool + { + \msg_info:nn {chemmacros} {default-formula-method} + \chemmacros_set_formula_method:n {chemformula} + } + } + } + +\cs_new_protected:Npn \chemmacros_set_formula_method:n #1 + { + \chemmacros_if_method_package:nTF {#1} + { \chemmacros_setup_method_package:n {#1} } + { + \msg_warning:nnn {chemmacros} {unknown-formula-method} {#1} + \chemmacros_setup_method_package:n {chemformula} + } + \bool_set_true:N \l__chemmacros_formula_method_set_bool + } +\cs_generate_variant:Nn \chemmacros_set_formula_method:n {V} + +% -------------------------------------------------------------------------- +% add formula methods: +\chemmacros_add_method_package:nn {chemformula} + { + \chemmacros_integrate_package:nnn {} {chemformula} {2015/09/08} + \cs_set_protected:Npn \chemmacros_chemformula:n #1 + { \chemformula_chcpd:nn {} {#1} } + \cs_set_protected:Npn \chemmacros_reaction:n #1 + { \chemformula_ch:nn {} {#1} } + } + +\chemmacros_add_method_package:nn {mhchem} + { + \chemmacros_integrate_package:nnn {version=4} {mhchem} {} + \cs_set_protected:Npn \chemmacros_chemformula:n #1 { \ce {#1} } + \cs_set_protected:Npn \chemmacros_reaction:n #1 { \ce {#1} } + \chemmacros_module_after:nn {charges} + { + \cs_set_protected:Npn \chemmacros_elpair:n #1 { \ce{#1} : } + \cs_set_protected:Npn \chemmacros_plus: { + } + \cs_set_protected:Npn \chemmacros_minus: { - } + \cs_set_protected:Npn \chemmacros_formal_plus: { \ensuremath{\oplus} } + \cs_set_protected:Npn \chemmacros_formal_minus: { \ensuremath{\ominus} } + \cs_set_protected:Npn \fplus { \ensuremath{\oplus} } + \cs_set_protected:Npn \fminus { \ensuremath{\ominus} } + } + } + +\chemmacros_add_method_package:nn {chemist} + { + \RequirePackage {chemist} + \cs_set_protected:Npn \chemmacros_chemformula:n #1 + { \chemmacros_text:n { \ChemForm {#1} } } + \cs_set_protected:Npn \chemmacros_reaction:n #1 + { \chemmacros_text:n { \ChemForm {#1} } } + \chemmacros_module_after:nn {charges} + { + \cs_set_protected:Npn \chemmacros_elpair:n #1 + { \chemmacros_text:n { \ChemForm {#1} : } } + \cs_set_protected:Npn \chemmacros_plus: { + } + \cs_set_protected:Npn \chemmacros_minus: { - } + \cs_set_protected:Npn \chemmacros_formal_plus: { \ensuremath{\oplus} } + \cs_set_protected:Npn \chemmacros_formal_minus: { \ensuremath{\ominus} } + \cs_set_protected:Npn \fplus { \ensuremath{\oplus} } + \cs_set_protected:Npn \fminus { \ensuremath{\ominus} } + } + } + +\chemmacros_add_method_package:nn {chemfig} + { + \RequirePackage {chemfig} + \cs_set_protected:Npn \chemmacros_chemformula:n #1 + { \printatom {#1} } + \cs_set_protected:Npn \chemmacros_reaction:n #1 + { \printatom {#1} } + \chemmacros_module_after:nn {charges} + { + \cs_set_protected:Npn \chemmacros_elpair:n #1 + { \Lewis { 0: , \printatom {#1} } } + \cs_set_protected:Npn \chemmacros_plus: { + } + \cs_set_protected:Npn \chemmacros_minus: { - } + \cs_set_protected:Npn \chemmacros_formal_plus: { \ensuremath{\oplus} } + \cs_set_protected:Npn \chemmacros_formal_minus: { \ensuremath{\ominus} } + \cs_set_protected:Npn \fplus { \ensuremath{\oplus} } + \cs_set_protected:Npn \fminus { \ensuremath{\ominus} } + } + } + +% -------------------------------------------------------------------------- +\chemmacros_define_global_keys:n + { formula .code:n = \chemmacros_set_formula_method:n {#1} } + +\hook_gput_code:nnn {begindocument/before} {chemmacros} + { + \bool_if:NF \l__chemmacros_formula_method_set_bool + { + \msg_info:nn {chemmacros} {default-formula-method} + \chemmacros_set_formula_method:n {chemformula} + } + } + +% -------------------------------------------------------------------------- +\ChemModuleEnd +\ChemModule{charges}{2020/11/29 charges} + +% -------------------------------------------------------------------------- +% circled charge signs: they are defined in the `chemformula' package: +% use directly: +\cs_new_protected:Npn \fplus { { \chemformula_fplus: } } +\cs_new_protected:Npn \fminus { { \chemformula_fminus: } } + +% change output depending on circled-option +\bool_new:N \l__chemmacros_circled_bool +\bool_set_true:N \l__chemmacros_circled_bool +\bool_new:N \l__chemmacros_circled_formal_bool +\bool_set_true:N \l__chemmacros_circled_formal_bool +\bool_new:N \l__chemmacros_circled_chem_bool +\bool_set_true:N \l__chemmacros_circled_chem_bool + + +\chemmacros_define_keys:nn {charges} + { + circletype .choice: , + circletype / math .code:n = + { + \bool_set_false:N \l__chemmacros_circled_chem_bool + \chemmacros_if_package_loaded:nT {chemformula} + { \bool_set_false:N \l_chemformula_formal_chem_bool } + } , + circletype / chem .code:n = + { + \bool_set_true:N \l__chemmacros_circled_chem_bool + \chemmacros_if_package_loaded:nT {chemformula} + { \bool_set_true:N \l_chemformula_formal_chem_bool } + } , + circletype .value_required:n = true , + circled .choice: , + circled / none .code:n = + { + \bool_set_false:N \l__chemmacros_circled_bool + \bool_set_false:N \l__chemmacros_circled_formal_bool + \chemmacros_if_package_loaded:nT {chemformula} + { \bool_set_false:N \l_chemformula_formal_charges_bool } + } , + circled / formal .code:n = + { + \bool_set_true:N \l__chemmacros_circled_bool + \bool_set_true:N \l__chemmacros_circled_formal_bool + \chemmacros_if_package_loaded:nT {chemformula} + { \bool_set_false:N \l_chemformula_formal_charges_bool } + } , + circled / all .code:n = + { + \bool_set_true:N \l__chemmacros_circled_bool + \bool_set_false:N \l__chemmacros_circled_formal_bool + \chemmacros_if_package_loaded:nT {chemformula} + { \bool_set_true:N \l_chemformula_formal_charges_bool } + } , + circled .default:n = all + } + +\cs_new_protected:Npn \chemmacros_plus: { \chemformula_plus: } +\cs_new_protected:Npn \chemmacros_minus: { \chemformula_minus: } + +\cs_new_protected:Npn \chemmacros_formal_plus: { \chemformula_formal_plus: } +\cs_new_protected:Npn \chemmacros_formal_minus: { \chemformula_formal_minus: } + +\cs_new_protected:Npn \chemmacros_charge:n #1 + { \chemmacros_chemformula:n { {}^{#1} } } + +\cs_new_protected:Npn \chemmacros_new_charge_command:Nn #1#2 + { + \DeclareDocumentCommand #1 {o} + { + \IfNoValueTF {##1} + { \chemmacros_charge:n {#2} } + { \chemmacros_charge:n {##1#2} } + } + } + +\tl_new:N \l__chemmacros_partial_charge_format_tl +\tl_set:Nn \l__chemmacros_partial_charge_format_tl { \tiny } + +\cs_new_protected:Npn \chemmacros_new_partial_charge_command:Nn #1#2 + { + \cs_new_protected:Npn #1 + { + \mbox { + \l__chemmacros_partial_charge_format_tl + \c_math_toggle_token \delta #2 \c_math_toggle_token } + } + } + +\NewChemMacroset {Charge} {mm} + { \chemmacros_new_charge_command:Nn #1 {#2} } + +\NewChemMacroset {PartialCharge} {mm} + { \chemmacros_new_partial_charge_command:Nn #1 {#2} } + +\cs_new_protected:Npn \scrm + { \ensuremath { \scriptstyle \chemmacros_minus: } } +\cs_new_protected:Npn \scrp + { \ensuremath { \scriptstyle \chemmacros_plus: } } +\cs_new_protected:Npn \fscrm + { \ensuremath { \scriptstyle \chemmacros_formal_minus: } } +\cs_new_protected:Npn \fscrp + { \ensuremath { \scriptstyle \chemmacros_formal_plus: } } +\cs_new_protected:Npn \fsscrm + { \ensuremath { \scriptscriptstyle \chemmacros_formal_minus: } } +\cs_new_protected:Npn \fsscrp + { \ensuremath { \scriptscriptstyle \chemmacros_formal_plus: } } + +\chemmacros_define_keys:nn {charges} + { + partial-format .tl_set:N = \l__chemmacros_partial_charge_format_tl + } + +% -------------------------------------------------------------------------- +\NewChemCharge \mch { \chemmacros_minus: } +\NewChemCharge \pch { \chemmacros_plus: } +\NewChemCharge \fmch { \chemmacros_formal_minus: } +\NewChemCharge \fpch { \chemmacros_formal_plus: } + +% partial charges: +\NewChemPartialCharge \delm { \chemmacros_minus: } +\NewChemPartialCharge \delp { \chemmacros_plus: } +\NewChemPartialCharge \fdelm { \chemmacros_formal_minus: } +\NewChemPartialCharge \fdelp { \chemmacros_formal_plus: } + +% -------------------------------------------------------------------------- +\ChemModuleEnd +\ChemModule{acid-base}{2022/01/13 acid/base} + +% -------------------------------------------------------------------------- +% equilibrium constants: + +\tl_new:N \l__chemmacros_equilibrium_constant_tl +\tl_set:Nn \l__chemmacros_equilibrium_constant_tl {K} +\prop_new:N \l__chemmacros_eq_constants_prop + +\prg_new_conditional:Npnn \chemmacros_if_eq_constant:Nn #1#2 {T,F,TF} + { + \cs_if_exist:NTF #1 + { + \tl_if_eq:xnTF + { \prop_item:Nn \l__chemmacros_eq_constants_prop {#1} } + {#2} + { \prg_return_true: } + { \prg_return_false: } + } + { \prg_return_false: } + } + +% #1: cs +% #2: translation id and option name +% #3: default translation +\cs_new_protected:Npn \chemmacros_define_eq_constant:Nnn #1#2#3 + { + \chemmacros_if_eq_constant:NnF {#1} {#2} + { + \cs_new_protected:Npn #1 {} + \prop_put:Nnn \l__chemmacros_eq_constants_prop {#1} {#2} + \tl_new:c {l__chemmacros_#2_tl} + \chemmacros_define_keys:nn {acid-base} + { #2 .tl_set:c = l__chemmacros_#2_tl } + } + \tl_set:cn + {l__chemmacros_#2_tl} + { \chemmacros_translate:n {#2} } + \chemmacros_declare_translation:nnn {#2} {fallback} {#3} + \cs_set_protected:Npn #1 + { + \ensuremath + { + \chemmacros_bold:n + { + \l__chemmacros_equilibrium_constant_tl + \c_math_subscript_token + { \tl_use:c {l__chemmacros_#2_tl} } + } + } + } + } + +\NewChemMacroset {EqConstant} {mmm} + { \chemmacros_define_eq_constant:Nnn #1 {#2} {#3} } + +\NewChemEqConstant \Ka {K-acid} { \mathrm{a} } +\NewChemEqConstant \Kb {K-base} { \mathrm{b} } +\NewChemEqConstant \Kw {K-water} { \mathrm{w} } + +\chemmacros_define_keys:nn {acid-base} + { eq-constant .tl_set:N = \l__chemmacros_equilibrium_constant_tl } + +\chemmacros_define_keys:nn {acid-base} + { + p-style .choice: , + p-style / slanted .code:n = \cs_set_eq:NN \chemmacros_p_style:n \textsl , + p-style / italics .code:n = \cs_set_eq:NN \chemmacros_p_style:n \textit , + p-style / upright .code:n = \cs_set_eq:NN \chemmacros_p_style:n \textup , + p-style .initial:n = upright + } + +\cs_new_protected:Npn \chemmacros_p:n #1 + { + \group_begin: + \chemmacros_text:n { - \tl_set_eq:NN - \l__chemmacros_compatibility_version_tl - \c_chemmacros_version_tl + \chemmacros_p_style:n {p} + \ensuremath {#1} } - { \tl_set:Nn \l__chemmacros_compatibility_version_tl {#1} } , - unknown .code:n = - \PassOptionsToPackage{\CurrentOption}{chemmacros4} - \PassOptionsToPackage{\CurrentOption}{chemmacros5} + \group_end: } -\ProcessKeysPackageOptions {chemmacros/compatibility} +\NewDocumentCommand \p {m} { \chemmacros_p:n {#1} } +\NewDocumentCommand \pH {} { \chemmacros_p:n { \chemmacros_chemformula:n {H} } } +\NewDocumentCommand \pOH {} { \chemmacros_p:n { \chemmacros_chemformula:n {OH} } } + +\NewDocumentCommand \pKa {o} + { + \chemmacros_p:n + { + \Ka \IfNoValueF {#1} + { {} \c_math_subscript_token { \chemmacros_bold:n {#1} } } + } + } + +\NewDocumentCommand \pKb {o} + { + \chemmacros_p:n + { + \Kb \IfNoValueF {#1} + { {} \c_math_subscript_token { \chemmacros_bold:n {#1} } } + } + } % -------------------------------------------------------------------------- -% compare version numbers -% #1: version -% #2: relation -% #3: version -% #4: true -% #5: false -\prg_new_conditional:Npnn \chemmacros_if_version:nnn #1#2#3 {p,T,F,TF} +\ChemModuleEnd +\ChemModule{symbols}{2020/11/29 symbols} + +\RequirePackage{amstext} + +% --------------------------------------------------------------------------- +% transition state symbol +\cs_new_protected:Npn \__chemmacros_transition_state: { - \fp_compare:nTF + \text { - ( - \chemmacros_get_major_version:n {#1} * 1e6 + - \chemmacros_get_minor_version:n {#1} * 1e3 + - 0 \chemmacros_get_subrelease:n {#1} - ) - #2 - ( - \chemmacros_get_major_version:n {#3} * 1e6 + - \chemmacros_get_minor_version:n {#3} * 1e3 + - 0 \chemmacros_get_subrelease:n {#3} - ) + \skip_horizontal:n { .1ex } + \hbox_overlap_right:n + { \rule { .6ex } { 0pt } \rule { .05ex } { 1.3ex } } + \hbox_overlap_right:n { \rule [ .4ex ] { 1.3ex } { .05ex } } + \rule [ .85ex ] { 1.3ex } { .05ex } + \skip_horizontal:n { .1ex } + } + } + +\cs_new_protected:Npn \chemmacros_transition_state: + { + \ensuremath + { + \mathchoice + { \displaystyle } + { \textstyle } + { \scriptstyle } + { \scriptscriptstyle } + \__chemmacros_transition_state: + } + } + +% \DeclareDocumentCommand? +\cs_new_eq:NN \transitionstatesymbol \chemmacros_transition_state: + +% \standardstate as defined by the chemstyle package. Thanks to Joseph Wright +% the `chemstyle' provides it with \providecommand so it doesn't matter which +% package defines it first +\ProvideDocumentCommand \standardstate {} + { { \ensuremath { \chemmacros_standardstate: } } } + +\cs_new_protected:Npn \chemmacros_standardstate: + { \mathpalette \chemmacros_standardstate_aux: \circ } + +\cs_new_protected:Npn \chemmacros_standardstate_aux: #1#2 + { + \ooalign + { + \tex_hfil:D + \c_math_toggle_token #1- \c_math_toggle_token + \tex_hfil:D + \tex_cr:D + \tex_hfil:D + \c_math_toggle_token #1#2 \c_math_toggle_token + \tex_hfil:D + \tex_cr:D + } + } + +\cs_new_protected:Npn \changestate { \ensuremath { \mathop{} \! \chemDelta } } + +% -------------------------------------------------------------------------- +\ChemModuleEnd +\ChemModule{particles}{2020/11/29 particles} + +% -------------------------------------------------------------------------- +% particles +\cs_new_protected:Nn \chemmacros_define_particle:Nn + { + \tl_set_rescan:Nnn \l__chemmacros_tmpa_tl { \ExplSyntaxOff } {#2} + \use:x + { + \cs_set_protected:Npn \exp_not:N #1 + { \chemmacros_chemformula:n { \exp_not:V \l__chemmacros_tmpa_tl } } + } + } + +\NewChemMacroset {Particle} {mm} + { \chemmacros_define_particle:Nn #1 {#2} } + +% -------------------------------------------------------------------------- +% nucleophiles +\cs_new_protected:Npn \chemmacros_elpair:n #1 + { + \bool_if:NTF \l__chemmacros_elpair_dots_bool + { \chlewis { 0: } {#1} } + { \chlewis { 0| } {#1} } + } + +\bool_new:N \l__chemmacros_nucleophile_elpair_bool +\bool_new:N \l__chemmacros_elpair_dots_bool + +\dim_new:N \l__chemmacros_nucleophile_dim +\dim_set:Nn \l__chemmacros_nucleophile_dim { .1em } + +\chemmacros_define_keys:nn {particles} + { space .dim_set:N = \l__chemmacros_nucleophile_dim } + +\chemmacros_define_keys:nn {particles} + { + elpair .choice: , + elpair / false .code:n = + { \bool_set_false:N \l__chemmacros_nucleophile_elpair_bool } , + elpair / dots .code:n = + { + \bool_set_true:N \l__chemmacros_nucleophile_elpair_bool + \bool_set_true:N \l__chemmacros_elpair_dots_bool + } , + elpair / dash .code:n = + { + \bool_set_true:N \l__chemmacros_nucleophile_elpair_bool + \bool_set_false:N \l__chemmacros_elpair_dots_bool + } , + elpair .default:n = dots + } + +\cs_new_protected:Npn \chemmacros_declare_nucleophile:Nn #1#2 + { + \cs_set_protected:cpn {__chemmacros_ \chemmacros_remove_backslash:N #1:} + { + \bool_if:NTF \l__chemmacros_nucleophile_elpair_bool + { + \chemmacros_elpair:n { #2 } + \skip_horizontal:N \l__chemmacros_nucleophile_dim + \chemmacros_chemformula:n { {}^{-} } + } + { \chemmacros_chemformula:n { #2^{-} } } + } + \DeclareDocumentCommand #1 {o} + { + \group_begin: + \IfNoValueF {##1} + { \chemmacros_set_keys:nn {particles} {##1} } + \use:c {__chemmacros_ \chemmacros_remove_backslash:N #1:} + \group_end: } + } + +\NewChemMacroset {Nucleophile} {mm} + { \chemmacros_declare_nucleophile:Nn #1 {#2} } + +% -------------------------------------------------------------------------- +% particles: +\NewChemParticle \el { e^- } +\NewChemParticle \prt { p^+ } +\NewChemParticle \ntr { n^0 } + +% ions, molecules +% proton, hydroxide, hydronium/oxonium, water: +\NewChemParticle \Hpl { H^+ } +\NewChemParticle \Hyd { OH^- } +\NewChemParticle \Oxo { H_3O^+ } +\NewChemParticle \water { H_2O } + +% electrophile: +\NewChemParticle \El { E^+ } + +% nucleophiles: +\NewChemNucleophile \Nuc {Nu} +\NewChemNucleophile \ba {ba} + +% -------------------------------------------------------------------------- +\ChemModuleEnd +\ChemModule{phases}{2020/11/29 phase descriptors} + +\bool_new:N \l__chemmacros_phases_sub_bool +\dim_new:N \l__chemmacros_phases_space_dim +\dim_set:Nn \l__chemmacros_phases_space_dim { .1333 em } + +\chemmacros_define_keys:nn {phases} + { + pos .choice: , + pos / sub .code:n = \bool_set_true:N \l__chemmacros_phases_sub_bool , + pos / side .code:n = \bool_set_false:N \l__chemmacros_phases_sub_bool , + space .dim_set:N = \l__chemmacros_phases_space_dim + } + +\NewChemMacroset {Phase} {mm} + { \chemmacros_define_phase:Nn #1 {#2} } + +\cs_new_protected:Npn \chemmacros_define_phase:Nn #1#2 + { + \tl_set:Nx \l__chemmacros_tmpa_tl { phase-\chemmacros_remove_backslash:N #1 } + \chemmacros_declare_translation:Vnn + \l__chemmacros_tmpa_tl + {fallback} + {#2} + \__chemmacros_define_phase:Nx #1 + { \exp_not:N \chemmacros_translate:n { \exp_not:V \l__chemmacros_tmpa_tl } } + } + +\cs_new_protected:Npn \__chemmacros_define_phase:Nn #1#2 + { + \cs_if_exist:NF #1 { \cs_new:Npn #1 {} } + \DeclareDocumentCommand #1 {o} + { \chemmacros_phase:n { #2 \IfNoValueF {##1} {,~##1} } } + } +\cs_generate_variant:Nn \__chemmacros_define_phase:Nn { Nx } + +\cs_new_protected:Npn \chemmacros_phase:n #1 + { + \mode_leave_vertical: + \bool_if:NTF \l__chemmacros_phases_sub_bool + { \chemformula_subscript:n { (#1) } } + { + \skip_horizontal:N \l__chemmacros_phases_space_dim + \chemmacros_text:n { (#1) } + } + } + +% -------------------------------------------------------------------------- +\NewDocumentCommand \phase {m} { \chemmacros_phase:n {#1} } + +\NewChemPhase \sld {s} +\NewChemPhase \lqd {l} +\NewChemPhase \gas {g} +\NewChemPhase \aq {aq} + +% -------------------------------------------------------------------------- +\ChemModuleEnd +\ChemModule{nomenclature}{2022/01/10 chemical names} + +\bool_new:N \l__chemmacros_iupac_restricted_bool +\bool_new:N \l__chemmacros_iupac_strict_bool + +\msg_new:nnn {chemmacros} {new-iupac} + { + You've~ tried~ to~ define~ a~ iupac~ naming~ command~ with~ + \token_to_str:N \NewChemIUPAC ,~ but~ the~ iupac~ command~ + \token_to_str:N #1 \c_space_tl already~ exists.~ Choose~ another~ name~ + or~ use~ \token_to_str:N \RenewChemIUPAC . + } + +\msg_new:nnn {chemmacros} {renew-iupac} + { + You've~ tried~ to~ renew~ the~ iupac~ command~ \token_to_str:N #1 ,~ but~ + it~ doesn't~ exist.~ Use~ \token_to_str:N \NewChemIUPAC \c_space_tl + instead. + } + +\msg_new:nnn {chemmacros} {let-iupac} + { + You've~ tried~ to~ let~ the~ iupac~ command~ \token_to_str:N #1 + \c_space_tl to~ the~ iupac~ command~ \token_to_str:N #2 ,~ but~ the~ + latter~ doesn't~ exist.~ Use~ \token_to_str:N \NewChemIUPAC \c_space_tl + instead~ or~declare~ \token_to_str:N #2 \c_space_tl first. + } + +\msg_new:nnn {chemmacros} {new-iupac-shorthand} + { + You've~ tried~ to~ define~ a~ iupac~ shorthand~ with~ \token_to_str:N + \NewChemIUPACShorthand ,~ but~ the~ shorthand~ \token_to_str:N #1 + \c_space_tl already~ exists.~ Please~ choose~ another~ token. + } + +\msg_new:nnn {chemmacros} {renew-iupac-shorthand} + { + You've~ tried~ to~ renew~ the~ iupac~ shorthand~ \token_to_str:N #1 ,~ + but~ this~ shorthand~ doesn't~ exist,~ yet. + } + +\msg_new:nnn {chemmacros} {show-iupac} + { \\ >~ \token_to_str:N #1=iupac~macro: \\ -> #2 } + +\msg_new:nnn {chemmacros} {no-iupac-command} + { \\ >~ \token_to_str:N #1=not~ defined~ as~ iupac~ macro } + +% -------------------------------------------------------------------------- +\prop_new:N \l__chemmacros_iupac_prop + +\cs_new_protected:Npn \__chemmacros_iupac_name:NN #1#2 + { \str_set:Nx #2 { \chemmacros_remove_backslash:N #1 } } + +\cs_new_protected:Npn \__chemmacros_define_iupac:Nn #1#2 + { + \__chemmacros_iupac_name:NN #1 \l__chemmacros_tmpa_str + \prop_put:NVn \l__chemmacros_iupac_prop + \l__chemmacros_tmpa_str + {#2} + \chemmacros_make_iupac: + } +\cs_generate_variant:Nn \__chemmacros_define_iupac:Nn {NV} + +\cs_new_protected:Npn \__chemmacros_let_iupac:NN #1#2 + { + \__chemmacros_iupac_name:NN #1 \l__chemmacros_tmpa_str + \__chemmacros_iupac_name:NN #2 \l__chemmacros_tmpb_str + \tl_set:Nx \l__chemmacros_tmpa_tl + { \prop_item:NV \l__chemmacros_iupac_prop \l__chemmacros_tmpb_str } + \__chemmacros_define_iupac:NV #1 \l__chemmacros_tmpa_tl + } + +\cs_new_protected:Npn \chemmacros_show_iupac:N #1 + { + \group_begin: + \__chemmacros_iupac_name:NN #1 \l__chemmacros_tmpa_str + \tl_set:Nx \l__chemmacros_tmpa_tl + { \prop_item:NV \l__chemmacros_iupac_prop \l__chemmacros_tmpa_str } + \tl_if_empty:NTF \l__chemmacros_tmpa_tl + { \msg_show:nnn {chemmacros} {no-iupac-command} {#1} } + { \msg_show:nnnV {chemmacros} {show-iupac} {#1} \l__chemmacros_tmpa_tl } + \group_end: + } + +\prg_new_protected_conditional:Npnn \chemmacros_if_iupac:N #1 {T,F,TF} + { + \__chemmacros_iupac_name:NN #1 \l__chemmacros_tmpa_str + \prop_if_in:NVTF \l__chemmacros_iupac_prop \l__chemmacros_tmpa_str { \prg_return_true: } { \prg_return_false: } } -\cs_generate_variant:Nn \chemmacros_if_version:nnnTF {fnf} -\cs_new:Npn \__chemmacros_get_minor_version:w #1.#2.#3 \q_stop +\cs_new_protected:Npn \chemmacros_new_iupac:Nn #1#2 { - \tl_if_blank:nTF {#2} {0} { - \tl_map_function:nN {#2} \__chemmacros_get_minor_number:n - } + \chemmacros_if_iupac:NTF #1 + { \msg_error:nnn {chemmacros} {new-iupac} {#1} } + { \__chemmacros_define_iupac:Nn #1 {#2} } + } + +\cs_new_protected:Npn \chemmacros_provide_iupac:Nn #1#2 + { + \chemmacros_if_iupac:NF #1 + { \__chemmacros_define_iupac:Nn #1 {#2} } + } + +\cs_new_protected:Npn \chemmacros_define_iupac:Nn #1#2 + { \__chemmacros_define_iupac:Nn #1 {#2} } + +\cs_new_protected:Npn \chemmacros_renew_iupac:Nn #1#2 + { + \chemmacros_if_iupac:NTF #1 + { \__chemmacros_define_iupac:Nn #1 {#2} } + { \msg_error:nnn {chemmacros} {renew-iupac} {#1} } } -\cs_new:Npn \chemmacros_get_minor_version:n #1 - { \__chemmacros_get_minor_version:w #1.. \q_stop } +\cs_new_protected:Npn \chemmacros_let_iupac:NN #1#2 + { + \chemmacros_if_iupac:NTF #2 + { \__chemmacros_let_iupac:NN #1#2 } + { \msg_error:nnnn {chemmacros} {let-iupac} {#1} {#2} } + } -\cs_new:Npn \__chemmacros_get_minor_number:n #1 +\cs_new_protected:Npn \chemmacros_make_iupac: { - \str_case:nn {#1} + \chemmacros_if_document:T { - {0} {0} - {1} {1} - {2} {2} - {3} {3} - {4} {4} - {5} {5} - {6} {6} - {7} {7} - {8} {8} - {9} {9} + \bool_if:NTF \l__chemmacros_inside_iupac_bool + { + \prop_map_inline:Nn \l__chemmacros_iupac_prop + { \cs_set_protected:cpn {##1} {##2} } + } + { + \bool_if:NF \l__chemmacros_iupac_restricted_bool + { + \bool_if:NTF \l__chemmacros_iupac_strict_bool + { + \prop_map_inline:Nn \l__chemmacros_iupac_prop + { \cs_set_protected:cpn {##1} {##2} } + } + { + \prop_map_inline:Nn \l__chemmacros_iupac_prop + { + \cs_if_exist:cF {##1} + { \cs_set_protected:cpn {##1} {##2} } + } + } + } + } + } + } + +\hook_gput_code:nnn {begindocument/end} {chemmacros} + { \chemmacros_make_iupac: } + +\NewDocumentCommand \DeclareChemIUPAC {mm} + { \chemmacros_define_iupac:Nn #1 {#2} } + +\NewDocumentCommand \NewChemIUPAC {mm} + { \chemmacros_new_iupac:Nn #1 {#2} } + +\NewDocumentCommand \RenewChemIUPAC {mm} + { \chemmacros_renew_iupac:Nn #1 {#2} } + +\NewDocumentCommand \ProvideChemIUPAC {mm} + { \chemmacros_provide_iupac:Nn #1 {#2} } + +\NewDocumentCommand \LetChemIUPAC {mm} + { \chemmacros_let_iupac:NN #1 #2 } + +% -------------------------------------------------------------------------- +\chemmacros_define_keys:nn {nomenclature} + { + iupac .choice: , + iupac / restricted .code:n = + \bool_set_true:N \l__chemmacros_iupac_restricted_bool + \bool_set_false:N \l__chemmacros_iupac_strict_bool , + iupac / auto .code:n = + \bool_set_false:N \l__chemmacros_iupac_restricted_bool + \bool_set_false:N \l__chemmacros_iupac_strict_bool , + iupac / strict .code:n = + \bool_set_false:N \l__chemmacros_iupac_restricted_bool + \bool_set_true:N \l__chemmacros_iupac_strict_bool , + iupac .initial:n = auto + } + +% -------------------------------------------------------------------------- +% stereo descriptors and other nomenclature commands +% Cahn-Ingold-Prelog +\dim_new:N \l__chemmacros_cip_kern_dim +\dim_set:Nn \l__chemmacros_cip_kern_dim {.075em} + +\chemmacros_define_keys:nn {nomenclature} + { cip-kern .dim_set:N = \l__chemmacros_cip_kern_dim } + +\tl_new:N \l__chemmacros_cip_inner_tl +\tl_new:N \l__chemmacros_cip_outer_tl +\tl_new:N \l__chemmacros_cip_number_tl + +\chemmacros_define_keys:nn {nomenclature} + { + cip-inner-format .tl_set:N = \l__chemmacros_cip_inner_tl , + cip-inner-format .initial:n = \itshape , + cip-outer-format .tl_set:N = \l__chemmacros_cip_outer_tl , + cip-outer-format .initial:n = \upshape , + cip-number-format .tl_set:N = \l__chemmacros_cip_number_tl , + cip-number-format .initial:n = \upshape + } + +\cs_new_protected:Npn \__chemmacros_cip:n #1 + { + \tl_set:Nn \l__chemmacros_tmpa_tl {#1} + \int_step_inline:nnnn {0} {1} {9} + { + \tl_replace_all:Nnn \l__chemmacros_tmpa_tl + {##1} + { { \l__chemmacros_cip_number_tl ##1} } } + { \l__chemmacros_cip_inner_tl \l__chemmacros_tmpa_tl } } -\cs_new:Npn \__chemmacros_get_major_version:w #1.#2.#3 \q_stop - { \tl_if_blank:nTF {#1} {0} {#1} } +\cs_new_protected:Npn \chemmacros_cip:n #1 + { + \int_zero:N \l__chemmacros_tmpa_int + \group_begin: + \l__chemmacros_cip_outer_tl ( + \clist_map_inline:nn + {#1} + { + \int_incr:N \l__chemmacros_tmpa_int + \__chemmacros_cip:n {##1} + \int_compare:nT + { \l__chemmacros_tmpa_int < \clist_count:n {#1} } + { , } + } + ) + \group_end: + \tex_kern:D \l__chemmacros_cip_kern_dim + } -\cs_new:Npn \chemmacros_get_major_version:n #1 - { \__chemmacros_get_major_version:w #1.. \q_stop } +\DeclareChemIUPAC \cip { \chemmacros_cip:n } -\cs_new:Npn \__chemmacros_get_subrelease:w #1.#2.#3 \q_stop +% remember: TikZ needs : to be other +\cs_new_protected:Npn \chemmacros_sconf:n #1 { - \tl_if_blank:nTF {#2} {0} { - \tl_map_function:nN {#2} \__chemmacros_get_subrelease_number:n - } + \group_begin: + \chemmacros_tikz:nn + { baseline,text~ height=1.5ex,text~ depth=.25ex } + { + \chemmacros_tikz_node:n {anchor=base} (chemmacros@@Sconf) {#1} ; + \chemmacros_tikz_draw:n {->,thick,rotate=90} + ($(chemmacros@@Sconf.center)+(20\c_chemmacros_other_colon_tl.8em)$) + arc (20\c_chemmacros_other_colon_tl340\c_chemmacros_other_colon_tl.8em); + } + \group_end: } -\cs_new:Npn \chemmacros_get_subrelease:n #1 - { \__chemmacros_get_subrelease:w #1.. \q_stop } +\cs_new_protected:Npn \chemmacros_rconf:n #1 + { + \group_begin: + \tikz[baseline,text~ height=1.5ex,text~ depth=.25ex] + { + \chemmacros_tikz_node:n {anchor=base} (chemmacros@@Rconf) {#1} ; + \chemmacros_tikz_draw:n {<-,thick,rotate=90} + ($(chemmacros@@Rconf.center)+(20\c_chemmacros_other_colon_tl.8em)$) + arc (20\c_chemmacros_other_colon_tl340\c_chemmacros_other_colon_tl.8em) ; + } + \group_end: + } + +\NewDocumentCommand \Sconf { O{S} } { \chemmacros_sconf:n {#1} } +\NewDocumentCommand \Rconf { O{R} } { \chemmacros_rconf:n {#1} } + +% coordination chemistry +\bool_new:N \l__chemmacros_bridge_super_bool + +\chemmacros_define_keys:nn {nomenclature} + { + bridge-number .choice: , + bridge-number / sub .code:n = + \bool_set_false:N \l__chemmacros_bridge_super_bool , + bridge-number / super .code:n = + \bool_set_true:N \l__chemmacros_bridge_super_bool , + coord-use-hyphen .bool_set:N = \l__chemmacros_coord_use_hyphen_bool , + coord-use-hyphen .initial:n = true + } -\cs_new:Npn \__chemmacros_get_subrelease_number:n #1 +% #1: boolean - if true hyphen is turned on +% #2: boolean - if true superscript will be used +% #3: symbol +% #4: sub-/superscript +\cs_new_protected:Npn \chemmacros_coordination_symbol:nnnn #1#2#3#4 { - \str_case:nnF {#1} + \chemmacros_chemformula:n {#3} + \tl_if_blank:nF {#4} { - {0} {} - {1} {} - {2} {} - {3} {} - {4} {} - {5} {} - {6} {} - {7} {} - {8} {} - {9} {} + \bool_if:nTF {#2} + { \chemmacros_chemformula:n { {}^{#4} } } + { \chemmacros_chemformula:n { {}_{#4} } } } - { \int_from_alph:n {#1} } + \bool_if:nT + {#1} + { \chemmacros_break_point_hyphen: } + } + +\cs_new_protected:Npn \chemmacros_hapto:n #1 + { + \chemmacros_coordination_symbol:nnnn + { \l__chemmacros_coord_use_hyphen_bool } + { \c_true_bool } + { \chemeta } + {#1} + } + +\cs_new_protected:Npn \chemmacros_dento:n #1 + { + \chemmacros_coordination_symbol:nnnn + { \l__chemmacros_coord_use_hyphen_bool } + { \c_true_bool } + { \chemkappa } + {#1} + } + +\cs_new_protected:Npn \chemmacros_bridge:n #1 + { + \chemmacros_coordination_symbol:nnnn + { \l__chemmacros_coord_use_hyphen_bool } + { \l__chemmacros_bridge_super_bool } + { \chemmu } + {#1} + } + +% \iupac (basically the same as bpchem's \IUPAC) +% - allows multiple breaking points as compound names can get really long and +% especially in multicolumn documents can span more than two lines +% - add a (very) little space before the hyphen and a little negative space +% after it +% - add a little space at breaking points if not broken +% - enables all naming commands regardless if they're definied otherwise or not +\cs_new_protected:Npn \chemmacros_allow_hyphens: + { + \chemmacros_nobreak: + \skip_horizontal:N \c_zero_skip } -% check compatibility -% #1: relation -% #2: number -% #3: true -% #4: false -\prg_new_conditional:Npnn \chemmacros_if_compatibility:nn #1#2 {p,T,F,TF} +% #1: pre break +% #2: post break +% #3: no break +\cs_new_protected:Npn \__chemmacros_peek_if_dash:TF #1#2 { - \chemmacros_if_version:fnfTF - { \l__chemmacros_compatibility_version_tl } + \peek_charcode:NTF - {#1} {#2} + } + +\cs_new_protected:Npn \__chemmacros_peek_if_paren:TF #1#2 + { % ( + \peek_charcode:NTF ) + {#1} + { % [ + \peek_charcode:NTF ] + {#1} + {#2} + } + } + +\cs_new_protected:Npn \__chemmacros_break_point_insert:nnn #1#2#3 + { + \mode_if_math:TF + {#3} + { + \peek_meaning:NTF \group_end: + {#3} + { + \__chemmacros_peek_if_dash:TF + {#3} + { + \__chemmacros_peek_if_paren:TF + {#3} + { + \chemmacros_nobreak: + \tex_discretionary:D {#1} {#2} {#3} + \chemmacros_allow_hyphens: + } + } + } + } + } + +\dim_new:N \l__chemmacros_iupac_hyphen_pre_dim +\dim_set:Nn \l__chemmacros_iupac_hyphen_pre_dim { .01em } +\dim_new:N \l__chemmacros_iupac_hyphen_post_dim +\dim_set:Nn \l__chemmacros_iupac_hyphen_post_dim { -.03em } +\dim_new:N \l__chemmacros_iupac_break_dim +\dim_set:Nn \l__chemmacros_iupac_break_dim { .03em } +\skip_new:N \l__chemmacros_iupac_break_skip +\skip_set:Nn \l__chemmacros_iupac_break_skip { .03em plus .07em } + +\chemmacros_define_keys:nn {nomenclature} + { + hyphen-pre-space .dim_set:N = \l__chemmacros_iupac_hyphen_pre_dim , + hyphen-post-space .dim_set:N = \l__chemmacros_iupac_hyphen_post_dim , + break-space .skip_set:N = \l__chemmacros_iupac_break_skip + } + +\cs_new_protected:Npn \chemmacros_break_point_hyphen: + { + \__chemmacros_break_point_insert:nnn + { \tex_kern:D \l__chemmacros_iupac_hyphen_pre_dim - } + { } + { + \tex_kern:D \l__chemmacros_iupac_hyphen_pre_dim + - + \tex_kern:D \l__chemmacros_iupac_hyphen_post_dim + } + } + +\cs_new_protected:Npn \chemmacros_break_point: + { + \__chemmacros_break_point_insert:nnn + {-} + { } + { + \mode_if_math:TF + { | } + { \tex_kern:D \l__chemmacros_iupac_break_dim } + } + } + +\cs_new_protected:Npn \chemmacros_break_point_opening_paren: + { \__chemmacros_break_point_insert:nnn { - } { ( } { ( } } + +\cs_new_protected:Npn \chemmacros_break_point_closing_paren: + { \__chemmacros_break_point_insert:nnn { )- } { } { ) } } + +\cs_new_protected:Npn \chemmacros_break_point_opening_bracket: + { \__chemmacros_break_point_insert:nnn { - } { [ } { [ } } + +\cs_new_protected:Npn \chemmacros_break_point_closing_bracket: + { \__chemmacros_break_point_insert:nnn { ]- } { } { ] } } + +\cs_new_protected:Npn \chemmacros_superscript:n #1 + { \mode_if_math:TF { \sp {#1} } { \textsuperscript {#1} } } + +\bool_new:N \l__chemmacros_inside_iupac_bool + +\seq_new:N \l__chemmacros_iupac_shorthands_seq +\prop_new:N \l__chemmacros_iupac_shorthands_prop + +% #1: token +% #2: definition +\cs_new_protected:Npn \chemmacros_define_iupac_shorthand:NN #1#2 + { + \seq_if_in:NnF \l__chemmacros_iupac_shorthands_seq {#1} + { \seq_put_right:Nn \l__chemmacros_iupac_shorthands_seq {#1} } + \prop_put:Nnn \l__chemmacros_iupac_shorthands_prop {#1} + { \char_set_active_eq:NN #1#2 } + } + +\cs_new_protected:Npn \chemmacros_remove_shorthand:N #1 + { + \chemmacros_define_iupac_shorthand:NN #1 \c_empty_tl + \seq_remove_all:Nn \l__chemmacros_iupac_shorthands_seq {#1} + \prop_remove:Nn \l__chemmacros_iupac_shorthands_prop {#1} + } + +\prg_new_conditional:Npnn \chemmacros_if_iupac_shorthand:N #1 {p,T,F,TF} + { + \seq_if_in:NnTF \l__chemmacros_iupac_shorthands_seq {#1} { \prg_return_true: } { \prg_return_false: } } -\cs_generate_variant:Nn \chemmacros_if_compatibility:nnT {nV} -% user checks: -\NewExpandableDocumentCommand \IfChemCompatibilityTF {mm+m+m} - { \chemmacros_if_compatibility:nnTF {#1} {#2} {#3} {#4} } +\cs_new_protected:Npn \chemmacros_for_all_iupac_shorthands_do:n #1 + { \seq_map_inline:Nn \l__chemmacros_iupac_shorthands_seq {#1} } + +\cs_new_protected:Npn \chemmacros_activate_iupac_shorthand:N #1 + { \chemmacros_if_iupac_shorthand:NT #1 { \char_set_catcode_active:N #1 } } + +\cs_new_protected:Npn \chemmacros_activate_iupac_shorthands:n #1 + { \tl_map_inline:nn {#1} { \chemmacros_activate_iupac_shorthand:N ##1 } } + +\cs_new_protected:Npn \chemmacros_activate_all_iupac_shorthands: + { + \chemmacros_for_all_iupac_shorthands_do:n + { \chemmacros_activate_iupac_shorthand:N ##1 } + } + +\cs_new_protected:Npn \chemmacros_make_shorthands: + { + \chemmacros_if_document:T + { + \chemmacros_for_all_iupac_shorthands_do:n + { \prop_item:Nn \l__chemmacros_iupac_shorthands_prop {##1} } + } + } + +\NewDocumentCommand \ChemMakeIupacShorthands {} + { \chemmacros_make_shorthands: } + +\NewDocumentCommand \DeclareChemIUPACShorthand {mm} + { \chemmacros_define_iupac_shorthand:NN #1#2 } + +\NewDocumentCommand \NewChemIUPACShorthand {mm} + { + \chemmacros_if_iupac_shorthand:NTF #1 + { \msg_error:nnn {chemmacros} {new-iupac-shorthand} {#1} } + { \chemmacros_define_iupac_shorthand:NN #1#2 } + } + +\NewDocumentCommand \ProvideChemIUPACShorthand {mm} + { + \chemmacros_if_iupac_shorthand:NTF #1 + { \chemmacros_define_iupac_shorthand:NN #1#2 } + } + +\NewDocumentCommand \RenewChemIUPACShorthand {mm} + { + \chemmacros_if_iupac_shorthand:NTF #1 + { \chemmacros_define_iupac_shorthand:NN #1#2 } + { \msg_error:nnn {chemmacros} {renew-iupac-shorthand} {#1} } + } + +\NewDocumentCommand \RemoveChemIUPACShorthand {m} + { \chemmacros_remove_shorthand:N #1 } + +\NewChemIUPACShorthand ^ \chemmacros_superscript:n +\NewChemIUPACShorthand | \chemmacros_break_point: +\NewChemIUPACShorthand - \chemmacros_break_point_hyphen: +\NewChemIUPACShorthand ( \chemmacros_break_point_opening_paren: +\NewChemIUPACShorthand ) \chemmacros_break_point_closing_paren: +\NewChemIUPACShorthand [ \chemmacros_break_point_opening_bracket: +\NewChemIUPACShorthand ] \chemmacros_break_point_closing_bracket: +\NewChemIUPAC \chemprime { \ensuremath {{}^{\prime}} } +\NewChemIUPACShorthand ' \chemprime +\NewChemIUPAC \nonbreakinghyphen { \mbox{-} \nobreak \hspace{0pt} } +\NewChemIUPACShorthand = \nonbreakinghyphen + +\cs_new_protected:Npn \chemmacros_iupac:nn #1#2 + { + \group_begin: + \bool_set_true:N \l__chemmacros_inside_iupac_bool + \bool_set_true:N \l__chemmacros_in_document_bool + \chemmacros_set_keys:nn {nomenclature} {#1} + \chemmacros_make_iupac: + \chemmacros_make_shorthands: + \tl_set_rescan:Nnn \l__chemmacros_tmpa_tl + { \chemmacros_activate_all_iupac_shorthands: } + {#2} + \l__chemmacros_tmpa_tl + \group_end: + } + +\cs_new_protected:Npn \chemmacros_iupac:n #1 { \chemmacros_iupac:nn {} {#1} } +\cs_generate_variant:Nn \chemmacros_iupac:n {e} + +\NewDocumentCommand \iupac {O{}m} { \chemmacros_iupac:nn {#1} {#2} } + +% -------------------------------------------------------------------------- +% R(ectus)/S(inister): +\NewChemIUPAC \rectus { \cip {R} } +\NewChemIUPAC \sinister { \cip {S} } + +\LetChemIUPAC \R \rectus +\LetChemIUPAC \S \sinister + +% E(ntgegen)/Z(usammen) +\NewChemIUPAC \entgegen { \cip {E} } +\NewChemIUPAC \zusammen { \cip {Z} } + +\LetChemIUPAC \E \entgegen +\LetChemIUPAC \Z \zusammen + +% cis/trans +\NewChemIUPAC \cis { \textit {cis} } +\NewChemIUPAC \trans { \textit {trans} } + +% fac/mer +\NewChemIUPAC \fac { \textit {fac} } +\NewChemIUPAC \mer { \textit {mer} } + +% n +\NewChemIUPAC \normal { \textit {n} } + +% tert +\NewChemIUPAC \tert { \textit {tert} } + +% Italian descriptors - I forgot what they mean +\NewChemIUPAC \sin { \textit {sin} } +\NewChemIUPAC \ter { \textit {ter} } + +% Fischer +\NewChemIUPAC \dexter { \textsc {d} } +\NewChemIUPAC \laevus { \textsc {l} } + +\LetChemIUPAC \D \dexter +\LetChemIUPAC \L \laevus + +% ortho/meta/para +\NewChemIUPAC \ortho { \textit {o} } +\NewChemIUPAC \meta { \textit {m} } +\NewChemIUPAC \para { \textit {p} } + +% syn/anti +\NewChemIUPAC \syn { \textit {syn} } +\NewChemIUPAC \anti { \textit {anti} } + +% coordination chemistry: +\NewChemIUPAC \hapto { \chemmacros_hapto:n } +\NewChemIUPAC \dento { \chemmacros_dento:n } +\NewChemIUPAC \bridge { \chemmacros_bridge:n } + +% attachments to heteroatoms / added hydrogen +\NewChemIUPAC \hydrogen { \textit {H} } +\NewChemIUPAC \oxygen { \textit {O} } +\NewChemIUPAC \nitrogen { \textit {N} } +\NewChemIUPAC \sulfur { \textit {S} } +\NewChemIUPAC \phosphorus { \textit {P} } + +% atoms: +\LetChemIUPAC \H \hydrogen +\LetChemIUPAC \O \oxygen +\LetChemIUPAC \N \nitrogen +\LetChemIUPAC \Sf \sulfur +\LetChemIUPAC \P \phosphorus + +% greek letters +\NewChemIUPAC \a { \chemalpha } +\NewChemIUPAC \b { \chembeta } +\NewChemIUPAC \g { \chemgamma } +\NewChemIUPAC \d { \chemdelta } +\NewChemIUPAC \k { \chemkappa } +\NewChemIUPAC \m { \chemmu } +\NewChemIUPAC \n { \chemeta } +\NewChemIUPAC \w { \chemomega } + +% -------------------------------------------------------------------------- +% latin phrases +\tl_new:N \l__chemmacros_latin_format_tl + +\NewChemMacroset {Latin} {mm} + { \chemmacros_define_latin:Nn #1 {#2} } + +\chemmacros_define_keys:nn {nomenclature} + { + format .tl_set:N = \l__chemmacros_latin_format_tl , + format .initial:n = \emph , + } + +\cs_new_protected:Npn \chemmacros_write_latin:n #1 + { + \group_begin: + \l__chemmacros_latin_format_tl {#1} + \group_end: + } + +\cs_new_protected:Npn \chemmacros_latin:n #1 + { \chemmacros_write_latin:n {#1} } + +\cs_new_protected:Npn \chemmacros_define_latin:Nn #1#2 + { \DeclareDocumentCommand #1 {O{}} { \latin [##1] {#2} } } -\NewExpandableDocumentCommand \IfChemCompatibilityT {mm+m} - { \chemmacros_if_compatibility:nnT {#1} {#2} {#3} } +\NewDocumentCommand \latin {O{}m} + { + \group_begin: + \chemmacros_set_keys:nn {nomenclature} {#1} + \chemmacros_latin:n {#2} + \group_end: + } -\NewExpandableDocumentCommand \IfChemCompatibilityF {mm+m} - { \chemmacros_if_compatibility:nnF {#1} {#2} {#3} } +\cs_undefine:N \invacuo +\NewChemLatin \invacuo {in~vacuo} +\NewChemLatin \abinitio {ab~initio} +\NewChemLatin \insitu {in~situ} % -------------------------------------------------------------------------- -% compatibility coding: -\cs_new_protected:Npn \ChemCompatibility #1#2 \EndChemCompatibility - { \chemmacros_if_compatibility:nnT {=} {#1} {#2} } +% hyperref support +% ?? unsure about adding IUPAC commands +\hook_gput_code:nnn {package/hyperref/after} {chemmacros} + { + \pdfstringdefDisableCommands + { + % \cs_set:Npn \- { - } % maybe not a good idea... + % \cs_set:Npn \| { } + % \cs_set:Npn \pH { pH } + % \cs_set:Npn \pOH { pOH } + \cs_set:Npn \iupac #1 {#1} + \cs_set:Npn \cip #1 {(#1)} + \cs_set:Npn \cis {cis} + \cs_set:Npn \trans {trans} + \cs_set:Npn \tert {tert} + \cs_set:Npn \ortho {o} + \cs_set:Npn \meta {m} + \cs_set:Npn \para {p} + \cs_set:Npn \syn {syn} + \cs_set:Npn \anti {anti} + \cs_set:Npn \R {(R)} + \cs_set:Npn \S {(S)} + \cs_set:Npn \E {(E)} + \cs_set:Npn \Z {(Z)} + \cs_set:Npn \D {D} + \cs_set:Npn \L {L} + \cs_set:Npn \H {H} + \cs_set:Npn \O {O} + \cs_set:Npn \N {N} + \cs_set:Npn \Sf {S} + \cs_set:Npn \P {P} + \cs_set:Npn \dexter {D} + \cs_set:Npn \laevus {L} + \cs_set:Npn \rectus {(R)} + \cs_set:Npn \sinister {(S)} + \cs_set:Npn \entgegen {(E)} + \cs_set:Npn \zusammen {(Z)} + \cs_set:Npn \hydrogen {H} + \cs_set:Npn \oxygen {O} + \cs_set:Npn \nitrogen {N} + \cs_set:Npn \sulfur {S} + \cs_set:Npn \phosphorus {P} + \cs_set:Npn \chemprime {'} + } + } -\cs_new_protected:Npn \ChemCompatibilityFrom #1#2 \EndChemCompatibility - { \chemmacros_if_compatibility:nnT {>=} {#1} {#2} } +% -------------------------------------------------------------------------- +\ChemModuleEnd +\ChemModule{tikz}{2020/11/29 upright greek symbols} + +\ExplSyntaxOff +\RequirePackage{tikz} +\usetikzlibrary{calc,decorations.pathmorphing} +\ExplSyntaxOn + +\tl_const:Nx \c_chemmacros_other_colon_tl { \token_to_str:N : } + +% -------------------------------------------------------------------------- +% TikZ drawings - helper macros +\cs_new_protected:Npn \chemmacros_tikz_picture:nn #1#2 + { \tikzpicture[{#1}] #2 \endtikzpicture } +\cs_new_protected:Npn \chemmacros_tikz:nn #1#2 { \tikz[{#1}] {#2} } +\cs_new_protected:Npn \chemmacros_tikz_draw:n #1 { \draw[{#1}] } +\cs_new_protected:Npn \chemmacros_tikz_node:n #1 { \node[{#1}] } +\cs_new_protected:Npn \chemmacros_tikz_shade:n #1 { \shade[{#1}] } +\cs_new_protected:Npn \chemmacros_tikz_shadedraw:n #1 { \shadedraw[{#1}] } +\cs_new_protected:Npn \chemmacros_tikz_node_in_draw:n #1 { node[{#1}] } + +\cs_generate_variant:Nn \chemmacros_tikz_picture:nn {xn} +\cs_generate_variant:Nn \chemmacros_tikz_draw:n {x} +\cs_generate_variant:Nn \chemmacros_tikz_node:n {x} +\cs_generate_variant:Nn \chemmacros_tikz_shade:n {x} +\cs_generate_variant:Nn \chemmacros_tikz_shadedraw:n {x} +\cs_generate_variant:Nn \chemmacros_tikz_node_in_draw:n {x} + +% -------------------------------------------------------------------------- +% arrow tips for electron movement +\dim_new:N \l__chemmacros_el_length_dim + +% full tip for pairs +\pgfarrowsdeclare { el } { el } + { + \dim_set:Nn \l__chemmacros_el_length_dim + { 2.5pt + 2.5\pgflinewidth } + \pgfarrowsleftextend { -\l__chemmacros_el_length_dim } + \pgfarrowsrightextend { .5\pgflinewidth } + } + { + \dim_set:Nn \l__chemmacros_el_length_dim + { 2.5pt + 2.5\pgflinewidth } + \pgfsetdash {} { 0pt } + \pgfsetroundjoin + \pgfsetroundcap + \pgfpathmoveto { \pgfpoint { 0pt } { 0pt } } + \pgfpathlineto + { + \pgfpoint + { -\l__chemmacros_el_length_dim } + { .3\l__chemmacros_el_length_dim } + } + \pgfpathlineto + { \pgfpoint { -.5\l__chemmacros_el_length_dim } { 0pt } } + \pgfpathlineto + { + \pgfpoint + { -\l__chemmacros_el_length_dim } + { -.3\l__chemmacros_el_length_dim } + } + \pgfpathlineto { \pgfpoint { 0pt } { 0pt } } + \pgfusepathqfillstroke + } + +% half tip on the left +\pgfarrowsdeclare { left~el } { left~el } + { + \dim_set:Nn \l__chemmacros_el_length_dim + { 2.5pt + 2.5\pgflinewidth } + \pgfarrowsleftextend { -\l__chemmacros_el_length_dim } + \pgfarrowsrightextend { .5\pgflinewidth } + } + { + \dim_set:Nn \l__chemmacros_el_length_dim + { 2.5pt + 2.5\pgflinewidth } + \pgfsetdash {} { 0pt } + \pgfsetroundjoin + \pgfsetroundcap + \pgfpathmoveto { \pgfpoint { 0pt } { 0pt } } + \pgfpathlineto + { + \pgfpoint + { -\l__chemmacros_el_length_dim } + { .3\l__chemmacros_el_length_dim } + } + \pgfpathlineto { \pgfpoint { -.5\l__chemmacros_el_length_dim } { 0pt } } + \pgfpathlineto { \pgfpoint { 0pt } { 0pt } } + \pgfusepathqfillstroke + } + +% half tip in the right +\pgfarrowsdeclare { right~el } { right~el } + { + \dim_set:Nn \l__chemmacros_el_length_dim + { 2.5pt + 2.5\pgflinewidth } + \pgfarrowsleftextend { -\l__chemmacros_el_length_dim } + \pgfarrowsrightextend { .5\pgflinewidth } + } + { + \dim_set:Nn \l__chemmacros_el_length_dim + { 2.5pt + 2.5\pgflinewidth } + \pgfsetdash {} { 0pt } + \pgfsetroundjoin + \pgfsetroundcap + \pgfpathmoveto { \pgfpoint { 0pt } { 0pt } } + \pgfpathlineto + { + \pgfpoint + { -\l__chemmacros_el_length_dim } + { -.3\l__chemmacros_el_length_dim } + } + \pgfpathlineto { \pgfpoint { -.5\l__chemmacros_el_length_dim } { 0pt } } + \pgfpathlineto { \pgfpoint { 0pt } { 0pt } } + \pgfusepathqfillstroke + } +% -------------------------------------------------------------------------- +% http://tex.stackexchange.com/a/25689/ +\pgfdeclaredecoration{wave}{initial}{ + \state{initial}[ + width = +0pt , + next~ state = sine, + persistent~ precomputation = { + \pgfmathsetmacro\matchinglength{ + \pgfdecoratedinputsegmentlength / + int(\pgfdecoratedinputsegmentlength/\pgfdecorationsegmentlength) + } + \setlength{\pgfdecorationsegmentlength}{\matchinglength pt} + } + ]{} + \state{sine}[width=\pgfdecorationsegmentlength]{ + \pgfpathsine{ + \pgfpoint + {0.25\pgfdecorationsegmentlength} + {0.5\pgfdecorationsegmentamplitude} + } + \pgfpathcosine{ + \pgfpoint + {0.25\pgfdecorationsegmentlength} + {-0.5\pgfdecorationsegmentamplitude} + } + \pgfpathsine{ + \pgfpoint + {0.25\pgfdecorationsegmentlength} + {-0.5\pgfdecorationsegmentamplitude} + } + \pgfpathcosine{ + \pgfpoint + {0.25\pgfdecorationsegmentlength} + {0.5\pgfdecorationsegmentamplitude} + } + } + \state{final}{} +} + +% -------------------------------------------------------------------------- +\ChemModuleEnd +\ChemModule{isotopes}{2020/11/29 a macro to easily print element isotopes} + +\RequirePackage{elements} -\cs_new_protected:Npn \ChemCompatibilityTo #1#2 \EndChemCompatibility - { \chemmacros_if_compatibility:nnT {<} {#1} {#2} } +\msg_new:nnn {chemmacros} {no-isotope} + { The~ isotope~ #2~ is~ not~ defined~ for~ element~ #1. } + +% -------------------------------------------------------------------------- +\tl_new:N \l__chemmacros_isotope_tl +\tl_new:N \l__chemmacros_isotope_list_tl +\seq_new:N \l__chemmacros_isotope_seq +\seq_new:N \l__chemmacros_check_isotopes_seq -\cs_new_protected:Npn \ChemCompatibilityBetween #1#2#3 \EndChemCompatibility +% #1: atomic number|element symbol|element name +% #2: tokenlist variable +\cs_new_protected:Npn \chemmacros_get_atom_number:nN #1#2 + { + \chemmacros_if_is_int:nTF {#1} + { \tl_set:Nn #2 {#1} } + { + \cs_if_exist:cTF { @elements@atom@number@ \str_lowercase:n {#1} } + { \tl_set:Nx #2 { \use:c { @elements@atom@number@ \str_lowercase:n {#1} } } } + { \tl_set:Nx #2 { \use:c { @elements@atom@name@num@ \str_lowercase:n {#1} } } } + } + } +\cs_generate_variant:Nn \chemmacros_get_atom_number:nN { V } + +% #1: atomic number|element symbol|element name +% #2: tl to store the result in +\cs_new_protected:Npn \chemmacros_get_isotope_list:nN #1#2 + { + \chemmacros_get_atom_number:nN {#1} \l__chemmacros_isotope_tl + \tl_set:Nx #2 + { + \use:c + { + @elements@atom@isotopes@ + \int_to_roman:n {\l__chemmacros_isotope_tl} + } + } + } + +% #1: atomic number|element symbol|element name +% #2: tokenlist variable +\cs_new_protected:Npn \chemmacros_get_element_symbol:nN #1#2 + { + \chemmacros_get_atom_number:nN {#1} \l__chemmacros_isotope_tl + \tl_set:Nx #2 + { + \use:c + { + @elements@atom@symbol@num@ + \int_to_roman:n {\l__chemmacros_isotope_tl} + } + } + } + +% #1: atomic number|element symbol|element name +% #2: isotope number +\prg_new_protected_conditional:Npnn \chemmacros_check_isotope:nn #1#2 {T,F,TF} + { + \chemmacros_get_isotopes:nN {#1} \l__chemmacros_check_isotopes_seq + \seq_if_in:NnTF \l__chemmacros_check_isotopes_seq {#2} + { \prg_return_true: } + { \prg_return_false: } + } +\cs_generate_variant:Nn \chemmacros_check_isotope:nnF { V } + +% #1: atomic number|element symbol|element name +% #2: tl to store the result in +\cs_new_protected:Npn \chemmacros_get_main_isotope:nN #1#2 + { + \chemmacros_get_isotope_list:nN {#1} \l__chemmacros_isotope_list_tl + \seq_set_split:NnV \l__chemmacros_isotope_seq {,} \l__chemmacros_isotope_list_tl + \seq_map_inline:Nn \l__chemmacros_isotope_seq + { + \chemmacros_read_isotope:nNN {##1} + \l__chemmacros_tmpa_bool + #2 + \bool_if:NT \l__chemmacros_tmpa_bool + { \seq_map_break: } + } + } +\cs_generate_variant:Nn \chemmacros_get_main_isotope:nN { V } + +% #1: atomic number|element symbol|element name +% #2: seq to store the results in +\cs_new_protected:Npn \chemmacros_get_isotopes:nN #1#2 + { + \seq_clear:N #2 + \chemmacros_get_isotope_list:nN {#1} \l__chemmacros_tmpa_tl + \seq_set_split:NnV \l__chemmacros_isotope_seq {,} \l__chemmacros_tmpa_tl + \seq_map_inline:Nn \l__chemmacros_isotope_seq + { + \chemmacros_read_isotope:nNN {##1} + \l__chemmacros_tmpa_bool + \l__chemmacros_tmpa_tl + \seq_put_right:NV #2 \l__chemmacros_tmpa_tl + } + } + +% #1: boolean variable +% #2: tokenlist variable +% #3: isotope list entry +\cs_new_protected:Npn \chemmacros_read_isotope:nNN #1#2#3 + { \__chemmacros_read_isotope:NNw #2#3 !#1!! \q_stop } + +% \__chemmacros_read_isotope:NNw N N !!1!! \q_stop +% \__chemmacros_read_isotope:NNw N N !1!! \q_stop +\cs_new_protected:Npn \__chemmacros_read_isotope:NNw #1#2#3!#4!#5!#6 \q_stop + { + \tl_if_blank:nTF {#5} + { + \tl_set:Nn #2 {#4} + \bool_set_false:N #1 + } + { + \tl_set:Nn #2 {#5} + \bool_set_true:N #1 + } + } + +% -------------------------------------------------------------------------- +% #1: boolean: hide atomic number? +% #2: nucleons, element symbol +\cs_new_protected:Npn \chemmacros_isotope:nn #1#2 + { \__chemmacros_isotope:nww {#1} #2,, \q_stop } + +\cs_new_protected:Npn \__chemmacros_isotope:nww #1#2,#3,#4 \q_stop + { + \tl_if_blank:nTF {#3} + { + \chemmacros_get_element_symbol:nN {#2} \l__chemmacros_tmpa_tl + \chemmacros_get_main_isotope:nN {#2} \l__chemmacros_tmpb_tl + \chemmacros_get_atom_number:nN {#2} \l__chemmacros_tmpc_tl + \bool_if:nTF {#1} + { + \chemmacros_isotope_write:VnV + \l__chemmacros_tmpb_tl + { } + \l__chemmacros_tmpa_tl + } + { + \chemmacros_isotope_write:VVV + \l__chemmacros_tmpb_tl + \l__chemmacros_tmpc_tl + \l__chemmacros_tmpa_tl + } + } + { + \chemmacros_get_element_symbol:nN {#3} \l__chemmacros_tmpa_tl + \chemmacros_get_atom_number:nN {#3} \l__chemmacros_tmpb_tl + \chemmacros_check_isotope:VnF + \l__chemmacros_tmpa_tl + {#2} + { + \chemmacros_get_element_symbol:nN {#3} \l__chemmacros_tmpa_tl + \msg_warning:nnVn {chemmacros} {no-isotope} + \l__chemmacros_tmpa_tl + {#2} + } + \chemmacros_get_element_symbol:nN {#3} \l__chemmacros_tmpa_tl + \bool_if:nTF {#1} + { \chemmacros_isotope_write:nnV {#2} { } \l__chemmacros_tmpa_tl } + { + \chemmacros_isotope_write:nVV {#2} + \l__chemmacros_tmpb_tl + \l__chemmacros_tmpa_tl + } + } + } + +\bool_new:N \l__chemmacros_isotope_super_bool +\tl_new:N \l__chemmacros_isotope_side_connect_tl + +\chemmacros_define_keys:nn {isotopes} + { + format .choice: , + format / super .code:n = + \bool_set_true:N \l__chemmacros_isotope_super_bool , + format / side .code:n = + \bool_set_false:N \l__chemmacros_isotope_super_bool , + format .initial:n = super , + side-connect .tl_set:N = \l__chemmacros_isotope_side_connect_tl , + side-connect .initial:n = - + } + +% #1: nucleons +% #2: atomic number +% #3: element symbol +\cs_new_protected:Npn \chemmacros_isotope_write:nnn #1#2#3 + { + \bool_if:NTF \l__chemmacros_isotope_super_bool + { \chemmacros_chemformula:n { ^{#1}_{#2}#3 } } + { + \chemmacros_chemformula:n {#3} + \tl_use:N \l__chemmacros_isotope_side_connect_tl + #1 + } + } +\cs_generate_variant:Nn \chemmacros_isotope_write:nnn { VnV , VVV , nnV , nVV } + +% TODO: option for the layout of the written isotope: ^{12}_6C vs C-12 + +\NewDocumentCommand \isotope { sm } + { \chemmacros_isotope:nn {#1} {#2} } + +% -------------------------------------------------------------------------- +\ChemModuleEnd +\ChemModule{mechanisms}{2020/11/29 reaction mechanisms} + +\RequirePackage{amstext} + +% -------------------------------------------------------------------------- +% reaction mechanisms +% \mech[<type>] +% <type> - substitutions: {}, 1, 2, se, 1e, 2e, ar +% - eliminations: e, e1, e2, cb +\tl_new:N \l__chemmacros_mechanisms_type_tl +\tl_new:N \l__chemmacros_mechanisms_mol_tl +\tl_new:N \l__chemmacros_mechanisms_ar_tl + +\cs_new_protected:Npn \__chemmacros_set_mechanisms:nnn #1#2#3 + { + \tl_set:Nn \l__chemmacros_mechanisms_type_tl {#1} + \tl_set:Nn \l__chemmacros_mechanisms_mol_tl {#2} + \tl_set:Nn \l__chemmacros_mechanisms_ar_tl {#3} + } + +\chemmacros_define_keys:nn {mechanisms} + { + type .choice: , + type / .code:n = + { + \__chemmacros_set_mechanisms:nnn {S} + { + \c_math_toggle_token + \c_math_subscript_token { \text {N} } + \c_math_toggle_token + } + { } + } , + type / 1 .code:n = + { + \__chemmacros_set_mechanisms:nnn {S} + { + \c_math_toggle_token + \c_math_subscript_token { \text {N} } + \c_math_toggle_token + 1 + } + { } + } , + type / 2 .code:n = + { + \__chemmacros_set_mechanisms:nnn {S} + { + \c_math_toggle_token + \c_math_subscript_token { \text {N} } + \c_math_toggle_token + 2 + } + { } + } , + type / se .code:n = + { + \__chemmacros_set_mechanisms:nnn {S} + { + \c_math_toggle_token + \c_math_subscript_token { \text {E} } + \c_math_toggle_token + } + { } + } , + type / 1e .code:n = + { + \__chemmacros_set_mechanisms:nnn {S} + { + \c_math_toggle_token + \c_math_subscript_token { \text {E} } + \c_math_toggle_token + 1 + } + { } + } , + type / 2e .code:n = + { + \__chemmacros_set_mechanisms:nnn {S} + { + \c_math_toggle_token + \c_math_subscript_token { \text {E} } + \c_math_toggle_token + 2 + } + { } + } , + type / ar .code:n = + { + \__chemmacros_set_mechanisms:nnn {S} + { + \c_math_toggle_token + \c_math_subscript_token { \text {E} } + \c_math_toggle_token + } + { Ar - } + } , + type / e .code:n = + { \__chemmacros_set_mechanisms:nnn {E} { } { } } , + type / e1 .code:n = + { \__chemmacros_set_mechanisms:nnn {E} {1} { } } , + type / e2 .code:n = + { \__chemmacros_set_mechanisms:nnn {E} {2} { } } , + type / cb .code:n = + { + \__chemmacros_set_mechanisms:nnn {E} + { + 1 + \c_math_toggle_token + \c_math_subscript_token { \text {cb} } + \c_math_toggle_token + } + { } + } , + type .default:n = + } + +\cs_new_protected:Npn \chemmacros_mechanisms:n #1 + { + \tl_if_blank:nTF {#1} + { \chemmacros_set_keys:nn {mechanisms} { type } } + { \chemmacros_set_keys:nn {mechanisms} { type = #1 } } + \mbox + { + \tl_use:N \l__chemmacros_mechanisms_ar_tl + \tl_use:N \l__chemmacros_mechanisms_type_tl + \tl_use:N \l__chemmacros_mechanisms_mol_tl + } + } + +\NewDocumentCommand \mech {o} + { + \IfNoValueTF {#1} + { \chemmacros_mechanisms:n { } } + { \chemmacros_mechanisms:n {#1} } + } + +% -------------------------------------------------------------------------- +\ChemModuleEnd +\ChemModule{newman}{2020/11/29 newman projections} + +% Newman projections +\fp_new:N \l__chemmacros_newman_rel_angle_fp +\fp_zero:N \l__chemmacros_newman_rel_angle_fp +\fp_new:N \l__chemmacros_newman_tmp_angle_fp +\fp_new:N \l__chemmacros_newman_abs_angle_fp +\fp_zero:N \l__chemmacros_newman_abs_angle_fp +\fp_new:N \l__chemmacros_newman_scale_fp +\fp_set:Nn \l__chemmacros_newman_scale_fp {1} +\fp_new:N \l__chemmacros_newman_x_fp +\fp_new:N \l__chemmacros_newman_y_fp + +\tl_new:N \l__chemmacros_newman_tikz_ring_tl +\tl_new:N \l__chemmacros_newman_tikz_front_tl +\tl_new:N \l__chemmacros_newman_tikz_back_tl + +\bool_new:N \l__chemmacros_newman_tikz_back_bool + +\chemmacros_define_keys:nn {newman} + { + ring .tl_set:N = \l__chemmacros_newman_tikz_ring_tl , + atoms .tl_set:N = \l__chemmacros_newman_tikz_front_tl , + back-atoms .code:n = + { + \bool_set_true:N \l__chemmacros_newman_tikz_back_bool + \tl_set:Nn \l__chemmacros_newman_tikz_back_tl { #1 } + } , + scale .fp_set:N = \l__chemmacros_newman_scale_fp , + scale .default:n = 1 , + angle .fp_set:N = \l__chemmacros_newman_abs_angle_fp , + angle .default:n = 0 + } + +% \newman[<keyval>](<angle>){<1>,<2>,<3>,<4>,<5>,<6>} +\NewDocumentCommand \newman {od()m} + { + \group_begin: + \IfNoValueF {#1} { \chemmacros_set_keys:nn {newman} {#1} } + \IfNoValueTF {#2} + { \chemmacros_newman:nn { } {#3} } + { \chemmacros_newman:nn {#2} {#3} } + \group_end: + } + +% #1: angle +% #2: csv list of atoms +\cs_new_protected:Npn \chemmacros_newman:nn #1#2 + { \__chemmacros_newman_feed_atoms:nw {#1}#2 ,,,,,, \q_stop } + +\cs_new_protected:Npn \__chemmacros_newman_feed_atoms:nw #1#2,#3,#4,#5,#6,#7,#8 \q_stop + { \chemmacros_newman_atoms:nnnnnnn {#1} {#2} {#3} {#4} {#5} {#6} {#7} } + +% place atoms: +% #1: angle +% #2 - #7: atoms +\cs_new_protected:Npn \chemmacros_newman_atoms:nnnnnnn #1#2#3#4#5#6#7 + { + \tl_if_blank:nTF {#1} + { + \fp_set_eq:NN + \l__chemmacros_newman_rel_angle_fp + \l__chemmacros_newman_abs_angle_fp + } + { \fp_set:Nn \l__chemmacros_newman_rel_angle_fp {#1} } + \chemmacros_tikz_picture:xn + { + scale = \fp_to_decimal:N \l__chemmacros_newman_scale_fp , + chemmacros_newman_atom_front / .style = + { + inner~sep = 0pt , + outer~sep = 0pt , + \exp_not:V \l__chemmacros_newman_tikz_front_tl + }, + chemmacros_newman_atom_back / .style = + { + inner~sep = 0pt , + outer~sep = 0pt , + \bool_if:NTF \l__chemmacros_newman_tikz_back_bool + { \exp_not:V \l__chemmacros_newman_tikz_back_tl } + { \exp_not:V \l__chemmacros_newman_tikz_front_tl } + } + } + { + \chemmacros_tikz_draw:x + { \exp_not:V \l__chemmacros_newman_tikz_ring_tl } + (0pt,0pt) circle (\fp_to_dim:N \l__chemmacros_newman_scale_fp * 15) ; + \chemmacros_newman_back_node:nn {30} {#6} + \chemmacros_newman_back_node:nn {150} {#7} + \chemmacros_newman_back_node:nn {270} {#5} + \chemmacros_newman_front_node:nn {90} {#2} + \chemmacros_newman_front_node:nn {210} {#3} + \chemmacros_newman_front_node:nn {330} {#4} + } + } + +% provide cartesian coordiantes from polar coordinates +% #1: fp variable for x +% #2: fp variable for y +% #3: angle +% #4: radius +\cs_new_protected:Npn \chemmacros_polar_to_cartesian:NNnn #1#2#3#4 + { + \fp_set:Nn #1 { #4 * cos( #3 / 180 * pi ) }% x + \fp_set:Nn #2 { #4 * sin( #3 / 180 * pi ) }% y + } + +% place back nodes +\cs_new_protected:Npn \chemmacros_newman_back_node:nn #1#2 + { + \group_begin: + \fp_add:Nn \l__chemmacros_newman_rel_angle_fp { #1 } + \chemmacros_polar_to_cartesian:NNnn + \l__chemmacros_newman_x_fp + \l__chemmacros_newman_y_fp + { \l__chemmacros_newman_rel_angle_fp } + { \l__chemmacros_newman_scale_fp } + \chemmacros_tikz_draw:x + { \exp_not:V \l__chemmacros_newman_tikz_ring_tl } + ( + 15 * \fp_to_dim:N \l__chemmacros_newman_x_fp , + 15 * \fp_to_dim:N \l__chemmacros_newman_y_fp + ) + -- + ( + 30 * \fp_to_dim:N \l__chemmacros_newman_x_fp , + 30 * \fp_to_dim:N \l__chemmacros_newman_y_fp + ) ; + \chemmacros_polar_to_cartesian:NNnn + \l__chemmacros_newman_x_fp + \l__chemmacros_newman_y_fp + { \l__chemmacros_newman_rel_angle_fp } + { \l__chemmacros_newman_scale_fp } + \chemmacros_tikz_node:x + { + chemmacros_newman_atom_back, + anchor = -180 + \fp_to_int:N \l__chemmacros_newman_rel_angle_fp + } + at + ( + 31 * \fp_to_dim:N \l__chemmacros_newman_x_fp , + 31 * \fp_to_dim:N \l__chemmacros_newman_y_fp + ) + { #2 } ; + \group_end: + } +\cs_generate_variant:Nn \chemmacros_newman_back_node:nn { nf } + +% place front nodes: +\cs_new_protected:Npn \chemmacros_newman_front_node:nn #1#2 + { + \chemmacros_polar_to_cartesian:NNnn + \l__chemmacros_newman_x_fp + \l__chemmacros_newman_y_fp + { #1 } + { \l__chemmacros_newman_scale_fp } + \chemmacros_tikz_draw:x + { \exp_not:V \l__chemmacros_newman_tikz_ring_tl } + (0pt,0pt) -- ++ + ( + 30 * \fp_to_dim:N \l__chemmacros_newman_x_fp , + 30 * \fp_to_dim:N \l__chemmacros_newman_y_fp + ) ; + \chemmacros_polar_to_cartesian:NNnn + \l__chemmacros_newman_x_fp + \l__chemmacros_newman_y_fp + { #1 } + { \l__chemmacros_newman_scale_fp } + \chemmacros_tikz_node:x + { chemmacros_newman_atom_front, anchor = -180 + #1 } + at + ( + 31 * \fp_to_dim:N \l__chemmacros_newman_x_fp , + 31 * \fp_to_dim:N \l__chemmacros_newman_y_fp + ) + { #2 } ; + } +\cs_generate_variant:Nn \chemmacros_newman_front_node:nn { nf } + +% -------------------------------------------------------------------------- +\ChemModuleEnd +\ChemModule{orbital}{2020/11/29 drawing orbital shapes} + +% \orbital[<keyval>]{<type>} +% variables: +\bool_new:N \l__chemmacros_orbital_type_s_bool +\bool_new:N \l__chemmacros_orbital_type_p_bool +\bool_new:N \l__chemmacros_orbital_type_sp_bool +\bool_new:N \l__chemmacros_orbital_type_sptwo_bool +\bool_new:N \l__chemmacros_orbital_type_spthree_bool +\bool_new:N \l__chemmacros_orbital_s_phase_bool +\bool_set_true:N \l__chemmacros_orbital_s_phase_bool +\bool_new:N \l__chemmacros_orbital_p_phase_bool +\bool_set_true:N \l__chemmacros_orbital_p_phase_bool +\bool_new:N \l__chemmacros_orbital_sp_phase_bool +\bool_set_true:N \l__chemmacros_orbital_sp_phase_bool +\bool_new:N \l__chemmacros_orbital_sptwo_phase_bool +\bool_set_true:N \l__chemmacros_orbital_sptwo_phase_bool +\bool_new:N \l__chemmacros_orbital_spthree_phase_bool +\bool_set_true:N \l__chemmacros_orbital_spthree_phase_bool +\bool_new:N \l__chemmacros_orbital_p_half_bool +\bool_new:N \l__chemmacros_orbital_overlay_bool +\bool_new:N \l__chemmacros_orbital_opacity_bool + +\tl_new:N \l__chemmacros_orbital_s_color_tl +\tl_set:Nn \l__chemmacros_orbital_s_color_tl {black} +\tl_new:N \l__chemmacros_orbital_s_phase_color_tl +\tl_new:N \l__chemmacros_orbital_p_color_tl +\tl_set:Nn \l__chemmacros_orbital_p_color_tl {black} +\tl_new:N \l__chemmacros_orbital_p_pphase_color_tl +\tl_new:N \l__chemmacros_orbital_p_mphase_color_tl +\tl_new:N \l__chemmacros_orbital_sp_color_tl +\tl_set:Nn \l__chemmacros_orbital_sp_color_tl {black} +\tl_new:N \l__chemmacros_orbital_sp_pphase_color_tl +\tl_new:N \l__chemmacros_orbital_sp_mphase_color_tl +\tl_new:N \l__chemmacros_orbital_sptwo_color_tl +\tl_set:Nn \l__chemmacros_orbital_sptwo_color_tl {black} +\tl_new:N \l__chemmacros_orbital_sptwo_pphase_color_tl +\tl_new:N \l__chemmacros_orbital_sptwo_mphase_color_tl +\tl_new:N \l__chemmacros_orbital_spthree_color_tl +\tl_set:Nn \l__chemmacros_orbital_spthree_color_tl {black} +\tl_new:N \l__chemmacros_orbital_spthree_pphase_color_tl +\tl_new:N \l__chemmacros_orbital_spthree_mphase_color_tl +\tl_new:N \l__chemmacros_orbital_s_scale_tl +\tl_set:Nn \l__chemmacros_orbital_s_scale_tl {1} +\tl_new:N \l__chemmacros_orbital_p_scale_tl +\tl_set:Nn \l__chemmacros_orbital_p_scale_tl {1} +\tl_new:N \l__chemmacros_orbital_sp_scale_tl +\tl_set:Nn \l__chemmacros_orbital_sp_scale_tl {1} +\tl_new:N \l__chemmacros_orbital_sptwo_scale_tl +\tl_set:Nn \l__chemmacros_orbital_sptwo_scale_tl {1} +\tl_new:N \l__chemmacros_orbital_spthree_scale_tl +\tl_set:Nn \l__chemmacros_orbital_spthree_scale_tl {1} + +\fp_new:N \l__chemmacros_orbital_angle_fp +\fp_set:Nn \l__chemmacros_orbital_angle_fp {90} +\fp_new:N \l__chemmacros_orbital_opacity_fp +\fp_set:Nn \l__chemmacros_orbital_opacity_fp {0.5} + +\cs_new:Npn \__chemmacros_orbital_options: + { + \__chemmacros_orbital_overlay: , \__chemmacros_orbital_opacity: , + inner~sep=0 , outer~sep=0 , line~width=.2pt , + rotate = { \fp_use:N \l__chemmacros_orbital_angle_fp - 90 } , + baseline , + minimum~size = 0 + } + +\cs_new:Npn \__chemmacros_orbital_overlay: + { \bool_if:NT \l__chemmacros_orbital_overlay_bool {overlay} } + +\cs_new:Npn \__chemmacros_orbital_opacity: + { + \bool_if:NT \l__chemmacros_orbital_opacity_bool + { opacity = { \fp_use:N \l__chemmacros_orbital_opacity_fp } } + } + +% -------------------------------------------------------------------------- +% s-orbitals +\cs_new_protected:Npn \__chemmacros_orbital_type_s: + { + \bool_set_true:N \l__chemmacros_orbital_type_s_bool + \bool_set_false:N \l__chemmacros_orbital_type_p_bool + \bool_set_false:N \l__chemmacros_orbital_type_sp_bool + \bool_set_false:N \l__chemmacros_orbital_type_sptwo_bool + \bool_set_false:N \l__chemmacros_orbital_type_spthree_bool + } + +\chemmacros_define_keys:nn {orbital/s} + { + phase .choice: , + phase / + .code:n = + { \bool_set_true:N \l__chemmacros_orbital_s_phase_bool } , + phase / - .code:n = + { \bool_set_false:N \l__chemmacros_orbital_s_phase_bool } , + scale .tl_set:N = \l__chemmacros_orbital_s_scale_tl , + color .tl_set:N = \l__chemmacros_orbital_s_color_tl + } + +\cs_new_protected:Npn \__chemmacros_orbital_s_draw:n #1 + { + \chemmacros_set_keys:nn {orbital/s} {#1} + \bool_if:NTF \l__chemmacros_orbital_s_phase_bool + { + \tl_if_in:NnTF \l__chemmacros_orbital_s_color_tl { ! } + { + \tl_set:Nn \l__chemmacros_orbital_s_phase_color_tl + { \tl_use:N \l__chemmacros_orbital_s_color_tl } + } + { + \tl_set:Nn \l__chemmacros_orbital_s_phase_color_tl + { \tl_use:N \l__chemmacros_orbital_s_color_tl ! 90 } + } + } + { + \tl_set:Nn \l__chemmacros_orbital_s_phase_color_tl + { black ! 5 } + } + \chemmacros_tikz_picture:xn + { \__chemmacros_orbital_options: } + { + \chemmacros_tikz_shade:x + { ball~color = \exp_not:V \l__chemmacros_orbital_s_phase_color_tl } + (0pt,0pt) circle (\exp_not:V \l__chemmacros_orbital_s_scale_tl * .6em) ; + } + } + +% -------------------------------------------------------------------------- +% p-orbitals +\cs_new_protected:Npn \__chemmacros_orbital_type_p: + { + \bool_set_false:N \l__chemmacros_orbital_type_s_bool + \bool_set_true:N \l__chemmacros_orbital_type_p_bool + \bool_set_false:N \l__chemmacros_orbital_type_sp_bool + \bool_set_false:N \l__chemmacros_orbital_type_sptwo_bool + \bool_set_false:N \l__chemmacros_orbital_type_spthree_bool + } + +\chemmacros_define_keys:nn {orbital/p} + { + phase .choice: , + phase / + .code:n = + { \bool_set_true:N \l__chemmacros_orbital_p_phase_bool } , + phase / - .code:n = + { \bool_set_false:N \l__chemmacros_orbital_p_phase_bool } , + scale .tl_set:N = \l__chemmacros_orbital_p_scale_tl , + angle .fp_set:N = \l__chemmacros_orbital_angle_fp , + color .tl_set:N = \l__chemmacros_orbital_p_color_tl , + half .bool_set:N = \l__chemmacros_orbital_p_half_bool , + half .default:n = true + } + +\cs_new_protected:Npn \__chemmacros_orbital_p_draw:n #1 + { + \chemmacros_set_keys:nn {orbital/p} {#1} + \bool_if:NTF \l__chemmacros_orbital_p_phase_bool + { + \tl_if_in:NnTF \l__chemmacros_orbital_p_color_tl { ! } + { + \tl_set:Nn \l__chemmacros_orbital_p_pphase_color_tl + { \tl_use:N \l__chemmacros_orbital_p_color_tl } + } + { + \tl_set:Nn \l__chemmacros_orbital_p_pphase_color_tl + { \tl_use:N \l__chemmacros_orbital_p_color_tl ! 90 } + } + \tl_set:Nn \l__chemmacros_orbital_p_mphase_color_tl + { black ! 5 } + + } + { + \tl_if_in:NnTF \l__chemmacros_orbital_p_color_tl { ! } + { + \tl_set:Nn \l__chemmacros_orbital_p_mphase_color_tl + { \tl_use:N \l__chemmacros_orbital_p_color_tl } + } + { + \tl_set:Nn \l__chemmacros_orbital_p_mphase_color_tl + { \tl_use:N \l__chemmacros_orbital_p_color_tl ! 90 } + } + \tl_set:Nn \l__chemmacros_orbital_p_pphase_color_tl + { black ! 5 } + } + \chemmacros_tikz_picture:xn + { \__chemmacros_orbital_options: } + { + \chemmacros_tikz_shadedraw:x + { + draw = \exp_not:V \l__chemmacros_orbital_p_pphase_color_tl , + ball~color = \exp_not:V \l__chemmacros_orbital_p_pphase_color_tl + } + (0pt,0pt) .. controls ++ + ( + - \l__chemmacros_orbital_p_scale_tl * 2em , + \l__chemmacros_orbital_p_scale_tl * 2em + ) + and ++ + ( + \l__chemmacros_orbital_p_scale_tl * 2em , + \l__chemmacros_orbital_p_scale_tl * 2em + ) + .. (0pt,0pt); + \bool_if:NF \l__chemmacros_orbital_p_half_bool + { + \chemmacros_tikz_shadedraw:x + { + draw = \exp_not:V \l__chemmacros_orbital_p_mphase_color_tl , + ball~color = \exp_not:V \l__chemmacros_orbital_p_mphase_color_tl + } + (0pt,0pt) .. controls ++ + ( + - \l__chemmacros_orbital_p_scale_tl * 2em , + - \l__chemmacros_orbital_p_scale_tl * 2em + ) + and ++ + ( + \l__chemmacros_orbital_p_scale_tl * 2em , + - \l__chemmacros_orbital_p_scale_tl * 2em + ) + .. (0pt,0pt); + } + } + } + +% -------------------------------------------------------------------------- +% sp-orbitals +\cs_new_protected:Npn \__chemmacros_orbital_type_sp: + { + \bool_set_false:N \l__chemmacros_orbital_type_s_bool + \bool_set_false:N \l__chemmacros_orbital_type_p_bool + \bool_set_true:N \l__chemmacros_orbital_type_sp_bool + \bool_set_false:N \l__chemmacros_orbital_type_sptwo_bool + \bool_set_false:N \l__chemmacros_orbital_type_spthree_bool + } + +\chemmacros_define_keys:nn {orbital/sp} + { + phase .choice: , + phase / + .code:n = + { \bool_set_true:N \l__chemmacros_orbital_sp_phase_bool } , + phase / - .code:n = + { \bool_set_false:N \l__chemmacros_orbital_sp_phase_bool } , + scale .tl_set:N = \l__chemmacros_orbital_sp_scale_tl , + angle .fp_set:N = \l__chemmacros_orbital_angle_fp , + color .tl_set:N = \l__chemmacros_orbital_sp_color_tl + } + +\cs_new_protected:Npn \__chemmacros_orbital_sp_draw:n #1 + { + \chemmacros_set_keys:nn {orbital/sp} {#1} + \bool_if:NTF \l__chemmacros_orbital_sp_phase_bool + { + \tl_if_in:NnTF \l__chemmacros_orbital_sp_color_tl { ! } + { + \tl_set:Nn \l__chemmacros_orbital_sp_pphase_color_tl + { \tl_use:N \l__chemmacros_orbital_sp_color_tl } + } + { + \tl_set:Nn \l__chemmacros_orbital_sp_pphase_color_tl + { \tl_use:N \l__chemmacros_orbital_sp_color_tl ! 90 } + } + \tl_set:Nn \l__chemmacros_orbital_sp_mphase_color_tl + { black ! 5 } + + } + { + \tl_if_in:NnTF \l__chemmacros_orbital_sp_color_tl { ! } + { + \tl_set:Nn \l__chemmacros_orbital_sp_mphase_color_tl + { \tl_use:N \l__chemmacros_orbital_sp_color_tl } + } + { + \tl_set:Nn \l__chemmacros_orbital_sp_mphase_color_tl + { \tl_use:N \l__chemmacros_orbital_sp_color_tl ! 90 } + } + \tl_set:Nn \l__chemmacros_orbital_sp_pphase_color_tl + { black ! 5 } + } + \chemmacros_tikz_picture:xn + { \__chemmacros_orbital_options: } + { + \chemmacros_tikz_shadedraw:x + { + draw = \exp_not:V \l__chemmacros_orbital_sp_pphase_color_tl , + ball~color = \exp_not:V \l__chemmacros_orbital_sp_pphase_color_tl + } + (0pt,0pt) .. controls ++ + ( + - \l__chemmacros_orbital_sp_scale_tl * 2em , + \l__chemmacros_orbital_sp_scale_tl * 2em + ) + and ++ + ( + \l__chemmacros_orbital_sp_scale_tl * 2em , + \l__chemmacros_orbital_sp_scale_tl * 2em + ) + .. (0pt,0pt); + \chemmacros_tikz_shadedraw:x + { + draw = \exp_not:V \l__chemmacros_orbital_sp_mphase_color_tl , + ball~color = \exp_not:V \l__chemmacros_orbital_sp_mphase_color_tl + } + (0pt,0pt) .. controls ++ + ( + - \l__chemmacros_orbital_sp_scale_tl * .6em , + - \l__chemmacros_orbital_sp_scale_tl * .6em + ) + and ++ + ( + \l__chemmacros_orbital_sp_scale_tl * .6em , + - \l__chemmacros_orbital_sp_scale_tl * .6em + ) + .. (0pt,0pt); + } + } + +% -------------------------------------------------------------------------- +% sp2-orbitals +\cs_new_protected:Npn \__chemmacros_orbital_type_sptwo: + { + \bool_set_false:N \l__chemmacros_orbital_type_s_bool + \bool_set_false:N \l__chemmacros_orbital_type_p_bool + \bool_set_false:N \l__chemmacros_orbital_type_sp_bool + \bool_set_true:N \l__chemmacros_orbital_type_sptwo_bool + \bool_set_false:N \l__chemmacros_orbital_type_spthree_bool + } + +\chemmacros_define_keys:nn {orbital/sp2} + { + phase .choice: , + phase / + .code:n = + { \bool_set_true:N \l__chemmacros_orbital_sptwo_phase_bool } , + phase / - .code:n = + { \bool_set_false:N \l__chemmacros_orbital_sptwo_phase_bool } , + scale .tl_set:N = \l__chemmacros_orbital_sptwo_scale_tl , + angle .fp_set:N = \l__chemmacros_orbital_angle_fp , + color .tl_set:N = \l__chemmacros_orbital_sptwo_color_tl + } + +\cs_new_protected:Npn \__chemmacros_orbital_sptwo_draw:n #1 + { + \chemmacros_set_keys:nn {orbital/sp2} {#1} + \bool_if:NTF \l__chemmacros_orbital_sptwo_phase_bool + { + \tl_if_in:NnTF \l__chemmacros_orbital_sptwo_color_tl { ! } + { + \tl_set:Nn \l__chemmacros_orbital_sptwo_pphase_color_tl + { \tl_use:N \l__chemmacros_orbital_sptwo_color_tl } + } + { + \tl_set:Nn \l__chemmacros_orbital_sptwo_pphase_color_tl + { \tl_use:N \l__chemmacros_orbital_sptwo_color_tl ! 90 } + } + \tl_set:Nn \l__chemmacros_orbital_sptwo_mphase_color_tl + { black ! 5 } + + } + { + \tl_if_in:NnTF \l__chemmacros_orbital_sptwo_color_tl { ! } + { + \tl_set:Nn \l__chemmacros_orbital_sptwo_mphase_color_tl + { \tl_use:N \l__chemmacros_orbital_sptwo_color_tl } + } + { + \tl_set:Nn \l__chemmacros_orbital_sptwo_mphase_color_tl + { \tl_use:N \l__chemmacros_orbital_sptwo_color_tl ! 90 } + } + \tl_set:Nn \l__chemmacros_orbital_sptwo_pphase_color_tl + { black ! 5 } + } + \chemmacros_tikz_picture:xn + { \__chemmacros_orbital_options: } + { + \chemmacros_tikz_shadedraw:x + { + draw = \exp_not:V \l__chemmacros_orbital_sptwo_pphase_color_tl , + ball~color = \exp_not:V \l__chemmacros_orbital_sptwo_pphase_color_tl + } + (0pt,0pt) .. controls ++ + ( + - \l__chemmacros_orbital_sptwo_scale_tl * 2em , + \l__chemmacros_orbital_sptwo_scale_tl * 2em + ) + and ++ + ( + \l__chemmacros_orbital_sptwo_scale_tl * 2em , + \l__chemmacros_orbital_sptwo_scale_tl * 2em + ) + .. (0pt,0pt); + \chemmacros_tikz_shadedraw:x + { + draw = \exp_not:V \l__chemmacros_orbital_sptwo_mphase_color_tl , + ball~color = \exp_not:V \l__chemmacros_orbital_sptwo_mphase_color_tl + } + (0pt,0pt) .. controls ++ + ( + - \l__chemmacros_orbital_sptwo_scale_tl * .8em , + - \l__chemmacros_orbital_sptwo_scale_tl * .8em + ) + and ++ + ( + \l__chemmacros_orbital_sptwo_scale_tl * .8em , + - \l__chemmacros_orbital_sptwo_scale_tl * .8em + ) + .. (0pt,0pt); + } + } + +% -------------------------------------------------------------------------- +% sp3-orbitals +\cs_new_protected:Npn \__chemmacros_orbital_type_spthree: + { + \bool_set_false:N \l__chemmacros_orbital_type_s_bool + \bool_set_false:N \l__chemmacros_orbital_type_p_bool + \bool_set_false:N \l__chemmacros_orbital_type_sp_bool + \bool_set_false:N \l__chemmacros_orbital_type_sptwo_bool + \bool_set_true:N \l__chemmacros_orbital_type_spthree_bool + } + +\chemmacros_define_keys:nn {orbital/sp3} + { + phase .choice: , + phase / + .code:n = + { \bool_set_true:N \l__chemmacros_orbital_spthree_phase_bool } , + phase / - .code:n = + { \bool_set_false:N \l__chemmacros_orbital_spthree_phase_bool } , + scale .tl_set:N = \l__chemmacros_orbital_spthree_scale_tl , + angle .fp_set:N = \l__chemmacros_orbital_angle_fp , + color .tl_set:N = \l__chemmacros_orbital_spthree_color_tl + } + +\cs_new_protected:Npn \__chemmacros_orbital_spthree_draw:n #1 + { + \chemmacros_set_keys:nn {orbital/sp3} {#1} + \bool_if:NTF \l__chemmacros_orbital_spthree_phase_bool + { + \tl_if_in:NnTF \l__chemmacros_orbital_spthree_color_tl {!} + { + \tl_set:Nn \l__chemmacros_orbital_spthree_pphase_color_tl + { \tl_use:N \l__chemmacros_orbital_spthree_color_tl } + } + { + \tl_set:Nn \l__chemmacros_orbital_spthree_pphase_color_tl + { \tl_use:N \l__chemmacros_orbital_spthree_color_tl ! 90 } + } + \tl_set:Nn \l__chemmacros_orbital_spthree_mphase_color_tl {black!5} + } + { + \tl_if_in:NnTF \l__chemmacros_orbital_spthree_color_tl {!} + { + \tl_set:Nn \l__chemmacros_orbital_spthree_mphase_color_tl + { \tl_use:N \l__chemmacros_orbital_spthree_color_tl } + } + { + \tl_set:Nn \l__chemmacros_orbital_spthree_mphase_color_tl + { \tl_use:N \l__chemmacros_orbital_spthree_color_tl ! 90 } + } + \tl_set:Nn \l__chemmacros_orbital_spthree_pphase_color_tl {black!5} + } + \chemmacros_tikz_picture:xn + { \__chemmacros_orbital_options: } + { + \chemmacros_tikz_shadedraw:x + { + draw = \exp_not:V \l__chemmacros_orbital_spthree_pphase_color_tl , + ball~color = \exp_not:V \l__chemmacros_orbital_spthree_pphase_color_tl + } + (0pt,0pt) .. controls ++ + ( + - \l__chemmacros_orbital_spthree_scale_tl * 2em , + \l__chemmacros_orbital_spthree_scale_tl * 2em + ) + and ++ + ( + \l__chemmacros_orbital_spthree_scale_tl * 2em , + \l__chemmacros_orbital_spthree_scale_tl * 2em + ) + .. (0pt,0pt); + \chemmacros_tikz_shadedraw:x + { + draw = \exp_not:V \l__chemmacros_orbital_spthree_mphase_color_tl , + ball~color = \exp_not:V \l__chemmacros_orbital_spthree_mphase_color_tl + } + (0pt,0pt) .. controls ++ + ( + - \l__chemmacros_orbital_spthree_scale_tl * 1em , + - \l__chemmacros_orbital_spthree_scale_tl * 1em + ) + and ++ + ( + \l__chemmacros_orbital_spthree_scale_tl * 1em , + - \l__chemmacros_orbital_spthree_scale_tl * 1em + ) + .. (0pt,0pt); + } + } + +% -------------------------------------------------------------------------- +% main command +\chemmacros_define_keys:nn {orbital} + { + overlay .bool_set:N = \l__chemmacros_orbital_overlay_bool , + overlay .default:n = true , + opacity .code:n = + { + \fp_compare:nTF { #1 = 1 } + { \bool_set_false:N \l__chemmacros_orbital_opacity_bool } + { \bool_set_true:N \l__chemmacros_orbital_opacity_bool } + \fp_set:Nn \l__chemmacros_orbital_opacity_fp {#1} + } + } + +\chemmacros_define_keys:nn {orbital/type} + { + s .code:n = { \__chemmacros_orbital_type_s: } , + p .code:n = { \__chemmacros_orbital_type_p: } , + sp .code:n = { \__chemmacros_orbital_type_sp: } , + sp2 .code:n = { \__chemmacros_orbital_type_sptwo: } , + sp3 .code:n = { \__chemmacros_orbital_type_spthree: } + } + +\cs_new_protected:Npn \chemmacros_orbital:n #1 + { + \bool_if:NT \l__chemmacros_orbital_type_s_bool + { \__chemmacros_orbital_s_draw:n {#1} } + \bool_if:NT \l__chemmacros_orbital_type_p_bool + { \__chemmacros_orbital_p_draw:n {#1} } + \bool_if:NT \l__chemmacros_orbital_type_sp_bool + { \__chemmacros_orbital_sp_draw:n {#1} } + \bool_if:NT \l__chemmacros_orbital_type_sptwo_bool + { \__chemmacros_orbital_sptwo_draw:n {#1} } + \bool_if:NT \l__chemmacros_orbital_type_spthree_bool + { \__chemmacros_orbital_spthree_draw:n {#1} } + } + +\NewDocumentCommand \orbital {om} + { + \group_begin: + \chemmacros_set_keys:nn {orbital/type} {#2} + \IfNoValueTF {#1} + { \chemmacros_orbital:n { } } + { \chemmacros_orbital:n {#1} } + \group_end: + } +% -------------------------------------------------------------------------- +\ChemModuleEnd +\ChemModule{polymers}{2020/11/29 polymers} + +% -------------------------------------------------------------------------- +% copolymers +\NewChemIUPAC \copolymer { \textit {co} } +\LetChemIUPAC \co \copolymer + +\NewChemIUPAC \statistical { \textit {stat} } +\LetChemIUPAC \stat \statistical + +\NewChemIUPAC \random { \textit {ran} } +\LetChemIUPAC \ran \random + +\NewChemIUPAC \alternating { \textit {alt} } +\LetChemIUPAC \alt \alternating + +\NewChemIUPAC \periodic { \textit {per} } +\LetChemIUPAC \per \periodic + +\NewChemIUPAC \block { \textit {block} } +\NewChemIUPAC \graft { \textit {graft} } + +% -------------------------------------------------------------------------- +% non-linear (co)polymers +\NewChemIUPAC \blend { \textit {blend} } +\NewChemIUPAC \comb { \textit {comb} } + +\NewChemIUPAC \complex { \textit {compl} } +\LetChemIUPAC \compl \complex + +\NewChemIUPAC \cyclic { \textit {cyclo} } +\LetChemIUPAC \cyclo \cyclic + +\NewChemIUPAC \branch { \textit {branch} } +\NewChemIUPAC \network { \textit {net} } +\LetChemIUPAC \net \network + +\NewChemIUPAC \ipnetwork { \textit {ipn} } +\LetChemIUPAC \ipn \ipnetwork + +\NewChemIUPAC \sipnetwork { \textit {sipn} } +\LetChemIUPAC \sipn \sipnetwork + +\NewChemIUPAC \star { \textit {star} } + +% -------------------------------------------------------------------------- + +\tl_new:N \l__chemmacros_polymer_delimiter_left_tl +\tl_new:N \l__chemmacros_polymer_delimiter_right_tl + +\tl_new:N \l__chemmacros_polymer_subscript_tl +\tl_new:N \l__chemmacros_polymer_superscript_tl + +\dim_new:N \l__chemmacros_polymer_delimiter_height_dim +\dim_new:N \l__chemmacros_polymer_delimiter_depth_dim + +\cs_new_protected:Npn \__chemmacros_set_polymer_delimiters:NN #1#2 + { + \tl_set:Nn \l__chemmacros_polymer_delimiter_left_tl {#1} + \tl_set:Nn \l__chemmacros_polymer_delimiter_right_tl {#2} + } + +% #1: height +% #2: depth +% #3: opening node +% #4: closing node +% #5: subscript +% #6: superscript +\cs_new_protected:Npn \chemmacros_make_polymer_braces:nnnnnn #1#2#3#4#5#6 + { + \dim_set:Nn \l__chemmacros_polymer_delimiter_height_dim { (#1+#2)/2 } + \dim_set:Nn \l__chemmacros_polymer_delimiter_depth_dim { (#1-#2)/2 } + \chemmacros_tikz_picture:nn {remember~ picture, overlay } + { + \chemmacros_tikz_node:n + { at = (#3) , yshift = \l__chemmacros_polymer_delimiter_depth_dim } + { + \c_math_toggle_token + \tex_left:D \l__chemmacros_polymer_delimiter_left_tl + \tex_vrule:D + height \l__chemmacros_polymer_delimiter_height_dim + depth \l__chemmacros_polymer_delimiter_height_dim + width \c_zero_dim + \tex_right:D . + \c_math_toggle_token + } ; + \chemmacros_tikz_node:n + { at = (#4) , yshift = \l__chemmacros_polymer_delimiter_depth_dim } + { + \c_math_toggle_token + \tex_left:D . + \tex_vrule:D + height \l__chemmacros_polymer_delimiter_height_dim + depth \l__chemmacros_polymer_delimiter_height_dim + width \c_zero_dim + \tex_right:D \l__chemmacros_polymer_delimiter_right_tl + \c_math_subscript_token + { \hbox_overlap_right:n { \smash {#5} } } + \c_math_superscript_token + { \hbox_overlap_right:n { \smash {#6} } } + \c_math_toggle_token + } ; + } + } +\cs_generate_variant:Nn \chemmacros_make_polymer_braces:nnnnnn {nnnnVV} + +\chemmacros_define_keys:nn {polymers} + { + delimiters .code:n = \__chemmacros_set_polymer_delimiters:NN #1 , + delimiters .initial:n = [] , + superscript .tl_set:N = \l__chemmacros_polymer_superscript_tl , + subscript .tl_set:N = \l__chemmacros_polymer_subscript_tl , + subscript .initial:n = $n$ + } + +\NewDocumentCommand \makepolymerdelims {O{}momm} + { + \group_begin: + \chemmacros_set_keys:nn {polymers} {#1} + \IfNoValueTF {#3} + { + \chemmacros_make_polymer_braces:nnnnVV {#2} {#2} {#4} {#5} + \l__chemmacros_polymer_subscript_tl + \l__chemmacros_polymer_superscript_tl + } + { + \chemmacros_make_polymer_braces:nnnnVV {#2} {#3} {#4} {#5} + \l__chemmacros_polymer_subscript_tl + \l__chemmacros_polymer_superscript_tl + } + \group_end: + } + +% -------------------------------------------------------------------------- +\ChemModuleEnd +\ChemModule{reactions}{2022/01/13 reaction environments} + +\RequirePackage{mathtools} + +% -------------------------------------------------------------------------- +\cs_new_protected:Npn \__chemmacros_record_for_lor:nnnnn #1#2#3#4#5 + { + \tl_if_eq:nnT {#1} {reaction} + { + \group_begin: + % we need to prevent \Hy@make@anchor from being written to the lor + % file: + \bool_if:NT \l__chemmacros_hyperref_bool + { \cs_set:Npn \Hy@make@anchor {} } + \addcontentsline {lor} {reaction} + { + \tl_use:N \l__chemmacros_reaction_lorname_tl + \tl_use:N \c_space_tl + #2 #3 #4 #5 + \tl_use:N \g__chemmacros_reaction_description_tl + } + \tl_gclear:N \g__chemmacros_reaction_description_tl + \group_end: + } + } + +% redefine mathtools' command \MT_define_tagform:nwnn to ensure we add an +% entry to the list of reactions even if the user redefines the reaction tag +% this should probably be done via patching... +\hook_gput_code:nnn {package/mathtools/after} {chemmacros} + { + \cs_set_protected:Npn \MT_define_tagform:nwnn #1[#2]#3#4 + { + \@namedef{MT_tagform_#1:n}##1 + { + % this is the original part: + \maketag@@@{#3\ignorespaces#2{##1}\unskip\@@italiccorr#4} + % this is added => this disturbs hyperref: + \__chemmacros_record_for_lor:nnnnn + {#1} {#3} {#2} {##1} {#4} + } + } + } + +\tl_new:N \g__chemmacros_reaction_description_tl + +\cs_new_protected:Npn \chemmacros_add_reaction_description:n #1 + { + \tl_if_blank:nF {#1} + { \tl_gset:Nn \g__chemmacros_reaction_description_tl {:~#1} } + } + +\NewDocumentCommand \AddRxnDesc {m} + { \chemmacros_add_reaction_description:n {#1} } + +% define \listofreactions +\tl_new:N \l__chemmacros_reaction_lorname_tl +\tl_new:N \reactionlistname +\tl_new:N \l__chemmacros_reaction_heading_tl + +\cs_new:Npn \__chemmacros_reaction_heading:n #1 + { \l__chemmacros_reaction_heading_tl {#1} } +\cs_generate_variant:Nn \__chemmacros_reaction_heading:n { V } + +\tl_set:Nn \l__chemmacros_reaction_lorname_tl + { \chemmacros_translate:n {Reaction} } + +\tl_set:Nn \reactionlistname { \chemmacros_translate:n {list-of-reactions} } + +\chemmacros_define_keys:nn {reactions} + { + list-name .tl_set:N = \reactionlistname , + list-entry .tl_set:N = \l__chemmacros_reaction_lorname_tl , + list-heading-cmd .code:n = + \cs_set_protected:Npn \__chemmacros_reaction_heading:n ##1 {#1} + } + +\cs_if_exist:NTF \chapter + { \chemmacros_set_keys:nn {reactions} { list-heading-cmd = \chapter* {#1} } } + { \chemmacros_set_keys:nn {reactions} { list-heading-cmd = \section* {#1} } } + +\cs_new_protected:Npn \listofreactions + { + \__chemmacros_reaction_heading:V \reactionlistname + \@starttoc {lor} + } + +\cs_new_eq:NN \l@reaction \l@figure + +\bool_new:N \l__chemmacros_reactions_tocbasic_bool +\cs_if_exist:NT \KOMAClassName + { \bool_set_true:N \l__chemmacros_reactions_tocbasic_bool } + +\tl_new:N \l__chemmacros_reactions_tag_open_tl +\tl_new:N \l__chemmacros_reactions_tag_close_tl +\tl_new:N \l__chemmacros_reactions_before_tag_tl + +\chemmacros_define_keys:nn {reactions} + { + tocbasic .bool_set:N = \l__chemmacros_reactions_tocbasic_bool , + tag-open .tl_set:N = \l__chemmacros_reactions_tag_open_tl , + tag-open .initial:n = \{ , + tag-close .tl_set:N = \l__chemmacros_reactions_tag_close_tl , + tag-close .initial:n = \} , + before-tag .tl_set:N = \l__chemmacros_reactions_before_tag_tl + } + +\hook_gput_code:nnn {package/tocbasic/after} {chemmacros} + { + \bool_lazy_or:nnT + { \chemmacros_if_package_loaded_p:n {tocbasic} } + { \l__chemmacros_reactions_tocbasic_bool } + { + \RequirePackage {tocbasic} + \addtotoclist [float] {lor} + \cs_set_protected:Npn \listofreactions { \listoftoc {lor} } + \cs_new:Npn \listoflorname { \reactionlistname } + } + } + +\ChemCleverefSupport {reaction} + { \chemmacros_translate:n {reaction} } + [ \chemmacros_translate:n {Reaction} ] + { \chemmacros_translate:n {reactions} } + [ \chemmacros_translate:n {Reactions} ] + +\hook_gput_code:nnn {package/cleveref/after} {chemmacros} + { + \creflabelformat {reaction} + { + #2 + \l__chemmacros_reactions_tag_open_tl + #1 + \l__chemmacros_reactions_tag_close_tl + #3 + } + } + +\ChemFancyrefSupport {rct} + { \chemmacros_translate:n {reaction} } + [ \chemmacros_translate:n {Reaction} ] + +% create new tagform +\newtagform {reaction} + [\l__chemmacros_reactions_before_tag_tl] + {\l__chemmacros_reactions_tag_open_tl} + {\l__chemmacros_reactions_tag_close_tl} + +\newcounter {chemmacros_save_reaction} +\newcounter {reaction} + +\cs_new_protected:Npn \__chemmacros_begin_reaction: + { + \patchcmd \thereaction {reaction} {equation} {} {} + \cs_set_eq:NN \theequation \thereaction + \cs_set_eq:NN \r@equation \r@reaction + \cs_set_eq:NN \p@equation \p@reaction + \cs_set:Npn \theHequation { R . \theHsection . \theequation } + \setcounter {chemmacros_save_reaction} { \value {equation} } + \setcounter {equation} { \value {reaction} } + \chemmacros_if_package_loaded:nT {cleveref} + { \crefalias {equation} {reaction} } + \usetagform {reaction} + } + +% switch back to equation tags +\cs_new_protected:Npn \__chemmacros_end_reaction: + { + \setcounter {reaction} { \value {equation} } + \setcounter {equation} { \value {chemmacros_save_reaction} } + } + +\tl_new:N \l__chemmacros_reactions_args_tl + +\cs_new_protected:Npn \__chemmacros_reactions_build_args:n #1 + { \tl_put_right:Nn \l__chemmacros_reactions_args_tl { {## #1} } } + +\cs_new_protected:Npn \chemmacros_define_reaction:nnn #1#2#3 + { + \int_compare:nNnT {#3+0} > {0} + { + \tl_clear:N \l__chemmacros_reactions_args_tl + \int_step_function:nnnN {2} {1} {#3+1} \__chemmacros_reactions_build_args:n + } + \chemmacros_declare_reaction_env:nnnV {#1} {#2} {#3} \l__chemmacros_reactions_args_tl + } + +% #1: chem +% #2: math +% #3: args number +% #4: argument list ({#2}{#3}...) +\cs_new_protected:Npn \chemmacros_declare_reaction_env:nnnn #1#2#3#4 + { + \exp_args:Nnx \DeclareDocumentEnvironment {#1} + { \int_compare:nT { #3+0 = 0 } {!} O{} \prg_replicate:nn {#3+0} {m} } + { + \chemmacros_add_reaction_description:n {##1} + \__chemmacros_begin_reaction: + \chemmacros_reaction_read:nnw {#2} {#4} + } + { + \__chemmacros_end_reaction: + \ignorespacesafterend + } + } +\cs_generate_variant:Nn \chemmacros_declare_reaction_env:nnnn {nnnV} + +\cs_new_protected:Npn \chemmacros_reaction_read:nnw #1#2#3 \end + { + \tl_clear:N \l__chemmacros_tmpa_tl + \seq_clear:N \l__chemmacros_tmpc_seq + \seq_set_split:Nnn \l__chemmacros_tmpa_seq {\\} {#3} + \int_set:Nn \l__chemmacros_tmpa_int + { \seq_count:N \l__chemmacros_tmpa_seq } + \int_zero:N \l__chemmacros_tmpb_int + \seq_map_inline:Nn \l__chemmacros_tmpa_seq + { + \int_incr:N \l__chemmacros_tmpb_int + \seq_clear:N \l__chemmacros_tmpc_seq + \seq_set_split:Nnn \l__chemmacros_tmpb_seq {&} {##1} + \seq_map_inline:Nn \l__chemmacros_tmpb_seq + { + \seq_put_right:Nn \l__chemmacros_tmpc_seq + { \chemmacros_reaction:n {####1} } + } + \tl_put_right:Nx \l__chemmacros_tmpa_tl + { \seq_use:Nn \l__chemmacros_tmpc_seq {&} } + \int_compare:nF + { \l__chemmacros_tmpa_int = \l__chemmacros_tmpb_int } + { \tl_put_right:Nn \l__chemmacros_tmpa_tl {\\} } + } + \chemmacros_reaction_write:nnV {#1} {#2} \l__chemmacros_tmpa_tl + \end + } + +\cs_new_protected:Npn \chemmacros_reaction_write:nnn #1#2#3 + { + \begin{#1}#2 + #3 + \end{#1} + } +\cs_generate_variant:Nn \chemmacros_reaction_write:nnn { nnV } + +\NewChemMacroset* {Reaction} {mO{}m} + { \chemmacros_define_reaction:nnn {#1} {#3} {#2} } + +\NewChemReaction {reaction} {equation} +\NewChemReaction {reaction*} {equation*} +\NewChemReaction {reactions} {align} +\NewChemReaction {reactions*} {align*} + +% -------------------------------------------------------------------------- +\ChemModuleEnd +\ChemModule{redox}{2020/11/29 oxidation numbers, redox reactions} + +\RequirePackage{mathtools,relsize} + +\msg_new:nnn {chemmacros} {redox} + { \token_to_str:N #1 \c_space_tl : ~ #2 ~ \msg_line_context: . } + + +% -------------------------------------------------------------------------- +% oxidation numbers +% \ox{<number>,<atom>} +\bool_new:N \l__chemmacros_ox_sign_bool +\bool_new:N \l__chemmacros_ox_integer_bool +\bool_new:N \l__chemmacros_ox_explicit_sign_bool +\bool_new:N \l__chemmacros_ox_explicit_zero_sign_bool +\bool_new:N \l__chemmacros_ox_format_roman_bool +\bool_new:N \l__chemmacros_ox_decimal_marker_comma_bool +\bool_new:N \l__chemmacros_ox_parse_bool +\bool_new:N \l__chemmacros_ox_side_bool +\bool_new:N \l__chemmacros_ox_super_bool +\bool_new:N \l__chemmacros_ox_top_bool +\bool_new:N \l__chemmacros_ox_align_center_bool + +\tl_new:N \l__chemmacros_ox_format_tl + +\int_new:N \l__chemmacros_ox_number_int +\fp_new:N \l__chemmacros_ox_number_fp + +\cs_new_protected:Npn \__chemmacros_ox_format:n #1 + { { \l__chemmacros_ox_format_tl {#1} } } + +\cs_new_protected:Npn \__chemmacros_ox_process_number:n #1 + { + \bool_if:NTF \l__chemmacros_ox_parse_bool + { + \tl_if_in:nnTF {#1} { / } + { \__chemmacros_ox_fraction:w #1 \q_stop } + { + \__chemmacros_ox_sign:n {#1} + \__chemmacros_ox_value:n {#1} + } + } + {#1} + } + +\cs_new_protected:Npn \__chemmacros_ox_fraction:w #1/#2 \q_stop + { + \group_begin: + \bool_set_false:N \l__chemmacros_ox_format_roman_bool + \__chemmacros_ox_sign:n {#1} + \bool_if:NTF \l__chemmacros_ox_side_bool + { \chemmacros_ox_text_frac:nn } + { \chemmacros_ox_super_frac:nn } + { \__chemmacros_ox_value:n {#1} } + {#2} + \group_end: + } + +\cs_new_protected:Npn \__chemmacros_ox_sign:n #1 { \bool_lazy_and:nnT - { \chemmacros_if_compatibility_p:nn {>=} {#1} } - { \chemmacros_if_compatibility_p:nn {<} {#2} } - {#3} + { \fp_compare_p:n { #1 > 0 } } + { \l__chemmacros_ox_explicit_sign_bool } + { \c_math_toggle_token + \c_math_toggle_token } + \bool_lazy_all:nT + { + { \fp_compare_p:n { #1 = 0 } } + { \l__chemmacros_ox_explicit_sign_bool } + { \l__chemmacros_ox_explicit_zero_sign_bool } + } + { \c_math_toggle_token \pm \c_math_toggle_token } + \fp_compare:nT { #1 < 0 } + { \c_math_toggle_token - \c_math_toggle_token } + } + +\cs_new_protected:Npn \__chemmacros_ox_value:n #1 + { + \fp_set:Nn \l__chemmacros_ox_number_fp { abs(#1) } + \__chemmacros_ox_is_integer:n { \l__chemmacros_ox_number_fp } + \bool_if:NTF \l__chemmacros_ox_format_roman_bool + { \__chemmacros_fp_to_Roman:n { \l__chemmacros_ox_number_fp } } + { + \bool_if:NTF \l__chemmacros_ox_integer_bool + { + \c_math_toggle_token + \__chemmacros_fp_to_arabic:n { \l__chemmacros_ox_number_fp } + \c_math_toggle_token + } + { + \c_math_toggle_token + \fp_use:N \l__chemmacros_ox_number_fp + \c_math_toggle_token + } + } + } + +\cs_new_protected:Npn \__chemmacros_ox_is_integer:n #1 + { + \fp_compare:nNnTF {#1} = { round((#1) + 1 , 0 ) - 1 } + { \bool_set_true:N \l__chemmacros_ox_integer_bool } + { + \bool_set_false:N \l__chemmacros_ox_integer_bool + \bool_set_false:N \l__chemmacros_ox_format_roman_bool + } + } + +\cs_new_protected:Npn \__chemmacros_fp_to_Roman:n #1 + { + \group_begin: + \fp_compare:nNnTF {#1} = { 0 } + {0} + { \int_to_Roman:n { \fp_to_int:n {#1} } } + \group_end: + } + +\cs_new_protected:Npn \__chemmacros_fp_to_arabic:n #1 + { + \group_begin: + \bool_if:NTF \l__chemmacros_ox_decimal_marker_comma_bool + { + \tl_set:Nx \l__chemmacros_tmpa_tl { \fp_to_decimal:n {#1} } + \tl_replace_once:Nnn \l__chemmacros_tmpa_tl {.} { {,} } + \tl_use:N \l__chemmacros_tmpa_tl + } + { \fp_to_decimal:n {#1} } + \group_end: + } + +\tl_new:N \l__chemmacros_ox_side_connect_tl + +\cs_new_protected:Npn \__chemmacros_ox_write:nn #1#2 + { + \tl_if_blank:nT {#1} + { \msg_error:nnn {chemmacros} {redox} {\ox} {oxidation~number~missing} } + \tl_if_blank:nT {#2} + { \msg_error:nnn {chemmacros} {redox} {\ox} {oxidation-atom~missing} } + \hbox_set:Nn \l__chemmacros_tmpa_box + { + \chemmacros_text:n + { + \__chemmacros_ox_format:n + { \relsize {-3} \__chemmacros_ox_process_number:n {#1} } + } + } + \hbox_set:Nn \l__chemmacros_tmpb_box { \chemmacros_chemformula:n {#2} } + \chemmacros_math:n + { + \bool_if:NT \l__chemmacros_ox_super_bool + { + \box_use:N \l__chemmacros_tmpb_box + \c_math_superscript_token { \box_use:N \l__chemmacros_tmpa_box } + } + \bool_if:NT \l__chemmacros_ox_side_bool + { + \chemmacros_text:n + { + \box_use:N \l__chemmacros_tmpb_box + \tl_use:N \l__chemmacros_ox_side_connect_tl + ( + \__chemmacros_ox_format:n + { \__chemmacros_ox_process_number:n {#1} } + ) + } + } + \bool_if:NT \l__chemmacros_ox_top_bool + { + \bool_if:NF \l__chemmacros_ox_align_center_bool + { + \hbox_set_to_wd:Nnn \l__chemmacros_tmpa_box + { \box_wd:N \l__chemmacros_tmpb_box } + { \rlap { \hbox_unpack:N \l__chemmacros_tmpa_box } \hfil } + } + \overset + { + \bool_if:NTF \l__chemmacros_ox_align_center_bool + { \clap } + { \use:n } + { \box_use:N \l__chemmacros_tmpa_box } + } + { \box_use:N \l__chemmacros_tmpb_box } + } + } + } + +\cs_new_protected:Npn \__chemmacros_ox_pos_top: + { + \bool_set_true:N \l__chemmacros_ox_top_bool + \bool_set_false:N \l__chemmacros_ox_super_bool + \bool_set_false:N \l__chemmacros_ox_side_bool + } + +\cs_new_protected:Npn \__chemmacros_ox_pos_super: + { + \bool_set_false:N \l__chemmacros_ox_top_bool + \bool_set_true:N \l__chemmacros_ox_super_bool + \bool_set_false:N \l__chemmacros_ox_side_bool + } + +\cs_new_protected:Npn \__chemmacros_ox_pos_side: + { + \bool_set_false:N \l__chemmacros_ox_top_bool + \bool_set_false:N \l__chemmacros_ox_super_bool + \bool_set_true:N \l__chemmacros_ox_side_bool + } + +\chemmacros_define_keys:nn {redox} + { + pos .choice: , + pos / top .code:n = \__chemmacros_ox_pos_top: , + pos / super .code:n = \__chemmacros_ox_pos_super: , + pos / side .code:n = \__chemmacros_ox_pos_side: , + pos .initial:n = super , + side-connect .tl_set:N = \l__chemmacros_ox_side_connect_tl , + side-connect .initial:n = \, , + text-frac .code:n = + \cs_set_protected:Npn \chemmacros_ox_text_frac:nn ##1##2 {#1} , + text-frac .initial:n = \chemfrac[text]{#1}{#2} , + super-frac .code:n = + \cs_set_protected:Npn \chemmacros_ox_super_frac:nn ##1##2 {#1} , + super-frac .initial:n = \chemfrac[superscript]{#1}{#2} , + roman .bool_set:N = \l__chemmacros_ox_format_roman_bool , + roman .default:n = true , + roman .initial:n = true , + parse .bool_set:N = \l__chemmacros_ox_parse_bool , + parse .default:n = true , + parse .initial:n = true , + explicit-sign .bool_set:N = \l__chemmacros_ox_explicit_sign_bool , + explicit-sign .default:n = true , + decimal-marker .choice: , + decimal-marker / comma .code:n = + { \bool_set_true:N \l__chemmacros_ox_decimal_marker_comma_bool } , + decimal-marker / point .code:n = + { \bool_set_false:N \l__chemmacros_ox_decimal_marker_comma_bool } , + decimal-marker .initial:n = point , + align .choice: , + align / center .code:n = + \bool_set_true:N \l__chemmacros_ox_align_center_bool , + align / right .code:n = + \bool_set_false:N \l__chemmacros_ox_align_center_bool , + align .initial:n = center , + explicit-zero-sign .bool_set:N = \l__chemmacros_ox_explicit_zero_sign_bool , + explicit-zero-sign .default:n = true , + format .tl_set:N = \l__chemmacros_ox_format_tl + } + + +% \ox[<keyval>]{<num>,<atom>} +% \ox*[<keyval>]{<num>,<atom>} => always number on the top +\cs_new_protected:Npn \chemmacros_ox:nnnn #1#2#3#4 + { + \group_begin: + \chemmacros_set_keys:nn {redox} {#2} + \tl_if_blank:nF {#1} { \__chemmacros_ox_pos_top: } + \__chemmacros_ox_write:nn {#3} {#4} + \group_end: + } + +\NewDocumentCommand \ox { sO{}>{\SplitArgument{1}{,}}m } + { + \IfBooleanTF {#1} + { \chemmacros_ox:nnnn {#1} {#2} #3 } + { \chemmacros_ox:nnnn { } {#2} #3 } + } + +% --------------------------------------------------------------------------- +% redox reactions +\tl_new:N \l__chemmacros_redox_begin_tl +\tl_new:N \l__chemmacros_redox_end_tl +\tl_new:N \l__chemmacros_redox_tikz_tl +\tl_new:N \l__chemmacros_redox_shift_tl +\tl_new:N \l__chemmacros_redox_anchor_tl +\tl_new:N \l__chemmacros_redox_side_tl + +\fp_new:N \l__chemmacros_redox_shift_fp + +\dim_new:N \l__chemmacros_redox_sep_dim +\dim_new:N \l__chemmacros_redox_sep_default_dim +\dim_set:Nn \l__chemmacros_redox_sep_default_dim {.2em} +\dim_new:N \l__chemmacros_redox_dist_dim +\dim_set:Nn \l__chemmacros_redox_dist_dim {.6em} + +% place and name nodes: +% \OX{<name>,<atom>} +\NewDocumentCommand \OX { >{\SplitArgument{1}{,}}m } + { \chemmacros_redox_partner:nn #1 } + +% TODO: add option to make `#2' be parsed as chem formula +\cs_new_protected:Npn \chemmacros_redox_partner:nn #1#2 + { + \legacy_if:nTF {measuring@} + { + \group_begin: + \tikz[baseline=(#1.base)] { \node [inner~sep=0pt] (#1) {#2} ; } + \group_end: + } + { + \tl_if_blank:nT {#1} + { \msg_error:nnnn {chemmacros} {redox} {\OX} {node~name~missing} } + \tl_if_blank:nT {#2} + { \msg_error:nnnn {chemmacros} {redox} {\OX} {atom~missing} } + \tikz[baseline=(#1.base),remember~picture] + { \node [inner~sep=0pt] (#1) {#2} ; } + } + } + +\cs_new_protected:Npn \__chemmacros_redox_coordinates:nn #1#2 + { + \tl_set:Nn \l__chemmacros_redox_begin_tl {#1} + \tl_set:Nn \l__chemmacros_redox_end_tl {#2} + } + +\cs_new_protected:Npn \chemmacros_redox:nnnnn #1#2#3#4#5 + { + \tl_clear:N \l__chemmacros_redox_begin_tl + \tl_clear:N \l__chemmacros_redox_end_tl + \tl_clear:N \l__chemmacros_redox_tikz_tl + \__chemmacros_redox_coordinates:nn {#1} {#2} + \tl_if_blank:nF {#3} + { \tl_set:Nn \l__chemmacros_redox_tikz_tl {#3} } + \tl_if_blank:nTF {#4} + { + \fp_set:Nn \l__chemmacros_redox_shift_fp {1} + \tl_set:Nn \l__chemmacros_redox_anchor_tl {above} + \tl_set:Nn \l__chemmacros_redox_side_tl {north} + \dim_set_eq:NN + \l__chemmacros_redox_sep_dim + \l__chemmacros_redox_sep_default_dim + } + { + \fp_compare:nNnTF {#4} < {0} + { + \tl_set:Nn \l__chemmacros_redox_anchor_tl {below} + \tl_set:Nn \l__chemmacros_redox_side_tl {south} + \exp_args:NNo \dim_set:Nn \l__chemmacros_redox_sep_dim + { - \l__chemmacros_redox_sep_default_dim } + } + { + \tl_set:Nn \l__chemmacros_redox_anchor_tl {above} + \tl_set:Nn \l__chemmacros_redox_side_tl {north} + \dim_set_eq:NN + \l__chemmacros_redox_sep_dim + \l__chemmacros_redox_sep_default_dim + } + \fp_set:Nn \l__chemmacros_redox_shift_fp {#4} + } + \tl_set:Nx \l__chemmacros_redox_shift_tl + { \fp_to_decimal:N \l__chemmacros_redox_shift_fp } + \tikz[remember~picture,overlay] + { + \chemmacros_tikz_draw:x { \exp_not:V \l__chemmacros_redox_tikz_tl } + ($ + (\l__chemmacros_redox_begin_tl . + \l__chemmacros_redox_side_tl)+(0,\l__chemmacros_redox_sep_dim) + $) + -- + ++(0,\l__chemmacros_redox_shift_tl * \l__chemmacros_redox_dist_dim) -| + node [pos=.25,\l__chemmacros_redox_anchor_tl] { {#5} } + ($ + (\l__chemmacros_redox_end_tl . + \l__chemmacros_redox_side_tl)+(0,\l__chemmacros_redox_sep_dim) + $) ; + } + } + +\NewDocumentCommand \redox { >{\SplitArgument{1}{,}}r()oom } + { + \IfNoValueT {#1} + { + \msg_error:nnnn {chemmacros} {redox} {\redox} + {You~need~to~specify~coordinates} + } + \IfNoValueTF {#2} + { \chemmacros_redox:nnnnn #1 { } { } {#4} } + { + \IfNoValueTF {#3} + { \chemmacros_redox:nnnnn #1 {#2} { } {#4} } + { \chemmacros_redox:nnnnn #1 {#2} {#3} {#4} } + } + } + +% redox-keys +\chemmacros_define_keys:nn {redox} + { + dist .dim_set:N = \l__chemmacros_redox_dist_dim , + dist .initial:n = {.6em} , + sep .dim_set:N = \l__chemmacros_redox_sep_default_dim , + sep .initial:n = {.2em} + } + +% -------------------------------------------------------------------------- +\ChemModuleEnd +\ChemModule{xfrac}{2020/11/29 use xfrac package with chemmacros} + +\RequirePackage{xfrac} + +% -------------------------------------------------------------------------- + +% #1: type +% #2: numerator +% #3: denominator +\cs_new_protected:Npn \chemmacros_frac:nnn #1#2#3 + { + \IfInstanceExistTF {xfrac} {chemmacros-frac-\f@family-#1} + { \sfrac [chemmacros-frac-\f@family-#1] {#2} {#3} } + { \sfrac [chemmacros-frac-default-#1]{#2} {#3} } + } + +\NewDocumentCommand \chemfrac {O{text}mm} + { \chemmacros_frac:nnn {#1} {#2} {#3} } + +% -------------------------------------------------------------------------- + +% default: +\DeclareInstance {xfrac} {chemmacros-frac-cmr-superscript} {text} + { + numerator-top-sep = -.1ex , + slash-left-kern = -.2em , + slash-right-kern = -.2em , + slash-symbol-font = cmr + } + +\DeclareInstance {xfrac} {chemmacros-frac-cmr-text} {text} + { + numerator-top-sep = 0ex , + slash-left-kern = -.2em , + slash-right-kern = -.2em , + slash-symbol-font = cmr + } + +% computer modern (same as default): +\DeclareInstance {xfrac} {chemmacros-frac-cmr-superscript} {text} + { + numerator-top-sep = -.1ex , + slash-left-kern = -.2em , + slash-right-kern = -.2em , + slash-symbol-font = cmr + } + +\DeclareInstance {xfrac} {chemmacros-frac-cmr-text} {text} + { + numerator-top-sep = 0ex , + slash-left-kern = -.2em , + slash-right-kern = -.2em , + slash-symbol-font = cmr + } + +% Linux Libertine T lining: +\DeclareInstance {xfrac} {chemmacros-frac-LinuxLibertineT-TLF-text} {text} + { + numerator-top-sep = 0ex , + slash-left-kern = 0em , + slash-right-kern = .05em , + slash-symbol-font = LinuxLibertineT-TLF + } + +\DeclareInstance {xfrac} {chemmacros-frac-LinuxLibertineT-TLF-superscript} {text} + { + scale-factor = 1.2 , + denominator-bot-sep = -.1ex , + numerator-top-sep = -.1ex , + slash-left-kern = .1em , + slash-right-kern = .1em , + slash-symbol-font = LinuxLibertineT-TLF + } + +% Linux Libertine T oldstyle: +\DeclareInstance {xfrac} {chemmacros-frac-LinuxLibertineT-TOsF-text} {text} + { + denominator-bot-sep = .1ex , + numerator-top-sep = -.2ex , + slash-left-kern = 0em , + slash-right-kern = 0em , + slash-symbol-font = LinuxLibertineT-TOsF + } + +\DeclareInstance {xfrac} {chemmacros-frac-LinuxLibertineT-TOsF-superscript} {text} + { + scale-factor = 1.2 , + denominator-bot-sep = -.1ex , + numerator-top-sep = -.2ex , + slash-left-kern = 0em , + slash-right-kern = .1em , + slash-symbol-font = LinuxLibertineT-TOsF + } + +% lmodern: +\DeclareInstance {xfrac} {chemmacros-frac-lmr-superscript} {text} + { + slash-left-kern = -.2em , + slash-right-kern = -.2em , + slash-symbol-font = lmr + } + +\DeclareInstance {xfrac} {chemmacros-frac-lmr-text} {text} + { + slash-left-kern = -.2em , + slash-right-kern = -.2em , + slash-symbol-font = lmr + } + +% -------------------------------------------------------------------------- +\ChemModuleEnd +\ChemModule{scheme}{2022/01/13 a scheme floating environment} + +\RequirePackage {chemnum} +\RequirePackage {etoolbox} + +\msg_new:nnn {chemmacros} {patch-failed} + { + Patching~ \token_to_str:N #1 \c_space_tl failed.~ + Please~ inform~ the~ chemmacros~ package~ authors. + } + +\bool_new:N \l__chemmacros_float_def_bool +\tl_new:N \l__chemmacros_float_method_tl +\seq_new:N \l__chemmacros_float_methods_seq +\prop_new:N \l__chemmacros_float_methods_prop +\prop_new:N \l__chemmacros_float_definitions_prop + +\msg_new:nnn {chemmacros} {float-method} + { Detected~ float~ defining~ method~ `#1'. } + +% -------------------------------------------------------------------------- +% #1: name +% #2: check +\cs_new_protected:Npn \chemmacros_define_float_method:nnn #1#2#3 + { + \seq_put_right:Nn \l__chemmacros_float_methods_seq {#1} + \prop_put:Nnn \l__chemmacros_float_methods_prop {#1} {#2} + \prop_put:Nnn \l__chemmacros_float_definitions_prop {#1} + { \cs_set_protected:Npn \__chemmacros_define_float:nn ##1##2 {#3} } + } + +% the order in which the methods are defined determines in which order the +% methods will be checked at begin document: +\chemmacros_define_float_method:nnn {KOMA} + { \cs_if_exist_p:N \KOMAClassName } + { + \bool_lazy_or:nnTF + { \chemmacros_if_class_loaded_p:n {scrbook} } + { \chemmacros_if_class_loaded_p:n {scrreprt} } + { \DeclareNewTOC[ counterwithin = chapter, } + { \DeclareNewTOC[ } + type = #1 , + types = #1s , + float , + tocentryindent = 1.5em , + tocentrynumwidth = 2.3em , + name = \chemmacros_translate:n {#1-name} , + listname = { \exp_not:N \chemmacros_translate:n {#1-list} } + ]{#2} + } + +\chemmacros_define_float_method:nnn {memoir} + { \chemmacros_if_class_loaded_p:n {memoir} } + { + \newfloat [chapter] {#1} {#2} {\chemmacros_translate:n {#1-name}} + \cs_set:cpn {the#1} {\thechapter.\arabic {#1}} + \newlistof {listof#1s} {#2} {\chemmacros_translate:n {#1-list}} + \newlistentry [chapter] {#1} {#2} {0} + \cftsetindents {#1} {0em} {2.3em} + \tl_put_right:Nn \@memfront@floats + { \counterwithout {#1} {chapter} } + \tl_put_right:Nn \@memmain@floats + { \counterwithin {#1} {chapter} } + \tl_put_right:Nn \@memback@floats + { + \counterwithin {#1} {chapter} + \setcounter {#1} {0} + } + \legacy_if:nT {artopt} + { \counterwithout {#1} {chapter} } + \apptocmd \insertchapterspace + { \addtocontents {#2} { \protect \addvspace {10pt} } } + {} + {} + } + +\chemmacros_define_float_method:nnn {tocbasic} + { \chemmacros_if_package_loaded_p:n {tocbasic} } + { + \DeclareNewTOC[ + type = #1 , + types = #1s , + float , + name = \chemmacros_translate:n {#1-name} , + listname = {\exp_not:N \chemmacros_translate:n {#1-list}} + ]{#2} + } + +\chemmacros_define_float_method:nnn {newfloat} + { \chemmacros_if_package_loaded_p:n {newfloat} } + { + \DeclareFloatingEnvironment[{ + fileext = #2 , + listname = {\exp_not:N \chemmacros_translate:n {#1-list}} , + name = \chemmacros_translate:n {#1-name} + }]{#1} + } + +\chemmacros_define_float_method:nnn {floatrow} + { \chemmacros_if_package_loaded_p:n {floatrow} } + { + \DeclareNewFloatType{#1}{% + fileext = #2, + placement = htp, + name = \chemmacros_translate:n {#1-name} + } + \cs_new_protected:cpn {listof#1s} + { \listof {#1} {\chemmacros_translate:n {#1-list}} } + } + +\chemmacros_define_float_method:nnn {float} + { \chemmacros_if_package_loaded_p:n {float} } + { + \newfloat {#1} {htp} {#2} + \floatname {#1} {\chemmacros_translate:n {#1-name}} + \cs_new_protected:cpn {listof#1s} + { \listof {#1} {\chemmacros_translate:n {#1-list}} } + } + +% -------------------------------------------------------------------------- +% checks if one of the above defined methods is active. The first one found +% will be used. +\cs_new_protected:Npn \chemmacros_check_float_method:n #1 + { + \prop_get:NnNT \l__chemmacros_float_methods_prop {#1} + \l__chemmacros_tmpa_tl + { + \bool_lazy_and:nnT + { !\l__chemmacros_float_def_bool } + { \l__chemmacros_tmpa_tl } + { + \bool_set_true:N \l__chemmacros_float_def_bool + \tl_set:Nn \l__chemmacros_float_method_tl {#1} + \msg_info:nnn {chemmacros} {float-method} {#1} + } + } + } + +\cs_new_protected:Npn \chemmacros_check_float_methods: + { + \seq_map_function:NN + \l__chemmacros_float_methods_seq + \chemmacros_check_float_method:n + } + +\hook_gput_code:nnn {begindocument/before} {chemmacros} + { + \chemmacros_if_package_loaded:nF {chemscheme} + { + \chemmacros_check_float_methods: + \chemmacros_define_float:nn {scheme} {los} + } + } + +% -------------------------------------------------------------------------- +\ChemCleverefSupport {scheme} + { \chemmacros_translate:n {scheme} } + [ \chemmacros_translate:n {Scheme} ] + { \chemmacros_translate:n {schemes} } + [ \chemmacros_translate:n {Schemes} ] + +\ChemFancyrefSupport {sch} + { \chemmacros_translate:n {scheme} } + [ \chemmacros_translate:n {Scheme} ] + +% -------------------------------------------------------------------------- +% #1: env name +\cs_new_protected:Npn \chemmacros_define_float:nn #1#2 + { + \bool_lazy_and:nnT + { !\cs_if_exist_p:c {#1} } + { !\cs_if_exist_p:c {end#1} } + { + \bool_if:NTF \l__chemmacros_float_def_bool + { + \prop_get:NVN \l__chemmacros_float_definitions_prop + \l__chemmacros_float_method_tl + \l__chemmacros_tmpa_tl + \tl_use:N \l__chemmacros_tmpa_tl + \__chemmacros_define_float:nn {#1} {#2} + } + { + \bool_lazy_or:nnTF + { \chemmacros_if_class_loaded_p:n {book} } + { \chemmacros_if_class_loaded_p:n {report} } + { + \newcounter {#1} [chapter] + \cs_set:cpn {the#1} + { \ifnum \c@chapter>\z@ \thechapter.\fi \arabic {#1} } + } + { + \newcounter {#1} + \cs_set:cpn {the#1} { \arabic {#1} } + } + \cs_new:cpn {fps@#1} {tbp} + \cs_new:cpn {ftype@#1} {8} + \cs_new:cpn {ext@#1} {#2} + \cs_new:cpx {fnum@#1} { + \exp_not:c {#1name} + \exp_not:N \nobreakspace + \exp_not:c {the#1}} + \cs_new:cpn {#1name} {\chemmacros_translate:n {#1-name}} + \cs_new:cpn {list#1name} {\chemmacros_translate:n {#1-list}} + \newenvironment {#1} + {\@float{#1}} + {\end@float} + \newenvironment {#1*} + {\@dblfloat{#1}} + {\end@dblfloat} + \bool_lazy_or:nnTF + { \chemmacros_if_class_loaded_p:n {book} } + { \chemmacros_if_class_loaded_p:n {report} } + { + \cs_new_protected:cpn {listof#1s} + { + \legacy_if:nTF {@twocolumn} + { \@restonecoltrue\onecolumn } + { \@restonecolfalse } + \chapter* { \use:c {list#1name} } + \use:x + { + \exp_not:N \@mkboth + { \exp_not:N \MakeUppercase \exp_not:c {list#1name} } + { \exp_not:N \MakeUppercase \exp_not:c {list#1name} } + } + \@starttoc {#2} + \legacy_if:nT {@restonecol} { \twocolumn } + } + \patchcmd \@chapter + { \addtocontents } + { \addtocontents {#2} { \protect \addvspace {10\p@} } \addtocontents } + {} + { \msg_warning:nnn {chemmacros} {patch-failed} { \@chapter } } + } + { + \cs_new_protected:cpn {listof#1s} + { + \section* {\use:c {list#1name}} + \use:x + { + \exp_not:N \@mkboth + { \exp_not:N \MakeUppercase \exp_not:c {list#1name} } + { \exp_not:N \MakeUppercase \exp_not:c {list#1name} } + } + \@starttoc {#2} + } + } + \cs_new_eq:cN {l@#1} \l@figure + } + } + \cs_set:cpn {#1name} {\chemmacros_translate:n {#1-name}} + \cs_set:cpn {list#1name} {\chemmacros_translate:n {#1-list}} + } + +% -------------------------------------------------------------------------- +\ChemModuleEnd +\ChemModule{spectroscopy}{2021/07/24 environment for spectroscopic data} + +\RequirePackage{siunitx} + +% spectroscopy +\tl_new:N \g__chemmacros_nmr_isotope_tl +\tl_new:N \l__chemmacros_nmr_isotope_default_tl +\tl_set:Nn \l__chemmacros_nmr_isotope_default_tl { 1 } +\tl_new:N \l__chemmacros_nmr_coupling_nuclei_tl +\tl_new:N \l__chemmacros_nmr_coupling_nuclei_pre_tl +\tl_set:Nn \l__chemmacros_nmr_coupling_nuclei_pre_tl { ( } +\tl_new:N \l__chemmacros_nmr_coupling_nuclei_post_tl +\tl_set:Nn \l__chemmacros_nmr_coupling_nuclei_post_tl { ) } +\tl_new:N \l__chemmacros_nmr_coupling_bonds_tl +\tl_new:N \l__chemmacros_nmr_coupling_bonds_pre_tl +\tl_new:N \l__chemmacros_nmr_coupling_bonds_post_tl +\tl_set:Nn \l__chemmacros_nmr_coupling_bonds_pre_tl { } +\tl_set:Nn \l__chemmacros_nmr_coupling_bonds_post_tl { \! } +\tl_new:N \l__chemmacros_nmr_coupling_symbol_tl +\tl_set:Nn \l__chemmacros_nmr_coupling_symbol_tl { J } +\tl_new:N \g__chemmacros_nmr_element_coupled_tl +\tl_new:N \g__chemmacros_nmr_element_tl +\tl_new:N \l__chemmacros_nmr_element_default_tl +\tl_set:Nn \l__chemmacros_nmr_element_default_tl { H } +\tl_new:N \l__chemmacros_nmr_format_tl +\tl_new:N \l__chemmacros_nmr_delta_tl +\tl_new:N \l__chemmacros_nmr_coupling_unit_tl +\tl_set:Nn \l__chemmacros_nmr_coupling_unit_tl { \hertz } +\tl_new:N \l__chemmacros_nmr_unit_tl +\tl_set:Nn \l__chemmacros_nmr_unit_tl { \mega\hertz } +\tl_new:N \l__chemmacros_nmr_list_setup_tl +\tl_set:Nn \l__chemmacros_nmr_list_setup_tl + { + \topsep\z@skip \partopsep\z@skip + \itemsep\z@ \parsep\z@ \itemindent\z@ + \leftmargin\z@ + } +\tl_new:N \l__chemmacros_nmr_position_tl +\tl_new:N \l__chemmacros_nmr_element_method_connector_tl +\tl_set:Nn \l__chemmacros_nmr_element_method_connector_tl {-} +\tl_new:N \l__chemmacros_nmr_method_tl +\tl_set:Nn \l__chemmacros_nmr_method_tl {NMR} + +\bool_new:N \l__chemmacros_nmr_coupling_nuclei_sub_bool +\bool_new:N \l__chemmacros_nmr_frequency_bool +\bool_new:N \l__chemmacros_nmr_solvent_bool +\bool_new:N \l__chemmacros_nmr_delimiters_bool +\bool_new:N \l__chemmacros_nmr_comma_bool +\bool_new:N \l__chemmacros_nmr_inner_bool +\bool_new:N \l__chemmacros_nmr_position_side_bool +\bool_new:N \l__chemmacros_nmr_parse_bool +\bool_set_true:N \l__chemmacros_nmr_parse_bool +\bool_new:N \l__chemmacros_nmr_list_bool +\bool_new:N \l__chemmacros_nmr_use_equal_bool +\bool_new:N \l__chemmacros_nmr_custom_command_active_bool +\bool_new:N \l__chemmacros_nmr_custom_command_used_bool + +\skip_new:N \l__chemmacros_nmr_space_skip +\skip_set:Nn \l__chemmacros_nmr_space_skip { .16667em } + +\cs_new_protected:Npn \__chemmacros_nmr_nucleus:nn #1#2 + { + \tl_gset:Nn \g__chemmacros_nmr_isotope_tl {#1} + \tl_if_in:nnTF {#2} {[} % ] + { \__chemmacros_nmr_element:w #2 \q_stop } + { + \tl_gset:No \g__chemmacros_nmr_element_tl {#2} + \tl_gclear:N \g__chemmacros_nmr_element_coupled_tl + } + } +\cs_generate_variant:Nn \__chemmacros_nmr_nucleus:nn { VV } + +\cs_new_protected:Npn \__chemmacros_nmr_nucleus:w #1,#2 \q_stop + { + \tl_gset:Nn \g__chemmacros_nmr_isotope_tl {#1} + \tl_if_in:nnTF {#2} {[} % ] + { \__chemmacros_nmr_element:w #2 \q_stop } + { + \tl_gset:No \g__chemmacros_nmr_element_tl {#2} + \tl_gclear:N \g__chemmacros_nmr_element_coupled_tl + } + } + +\cs_new_protected:Npn \__chemmacros_nmr_element:w #1[#2] \q_stop + { + \tl_gset:Nn \g__chemmacros_nmr_element_tl {#1} + \tl_gset:Nn \g__chemmacros_nmr_element_coupled_tl {#2} + } + +\cs_new_protected:Npn \__chemmacros_nmr_default_nucleus:w #1,#2 \q_stop + { + \tl_set:Nn \l__chemmacros_nmr_isotope_default_tl {#1} + \tl_set:Nn \l__chemmacros_nmr_element_default_tl {#2} + } + +\tl_new:N \l__chemmacros_nmr_base_format_tl + +\chemmacros_define_keys:nn {spectroscopy} + { nmr-base-format .tl_set:N = \l__chemmacros_nmr_base_format_tl } + +\cs_new_protected:Npn \__chemmacros_nmr_base:nn #1#2 + { + \group_begin: + \tl_use:N \l__chemmacros_nmr_base_format_tl + \tl_if_blank:VF \g__chemmacros_nmr_element_coupled_tl + { + \tl_put_left:Nn \g__chemmacros_nmr_element_coupled_tl { \{ } + \tl_put_right:Nn \g__chemmacros_nmr_element_coupled_tl { \} } + } + \tl_put_left:Nn \g__chemmacros_nmr_element_coupled_tl {#2} + \chemmacros_chemformula:n { ^{#1} } + \tl_if_blank:VF \g__chemmacros_nmr_element_coupled_tl + { + \bool_if:NTF \l__chemmacros_nmr_parse_bool + { \chemmacros_chemformula:V \g__chemmacros_nmr_element_coupled_tl } + { \g__chemmacros_nmr_element_coupled_tl } + } + \tl_use:N \l__chemmacros_nmr_element_method_connector_tl + \tl_use:N \l__chemmacros_nmr_method_tl + \group_end: + } + +\cs_generate_variant:Nn \__chemmacros_nmr_base:nn { VV } + +\cs_new_protected:Npn \__chemmacros_nmr_frequency:n #1 + { + \tl_if_in:nnTF {#1} {,} + { \__chemmacros_nmr_frequency_aux_i:w #1 \q_stop } + { \__chemmacros_nmr_frequency_aux_ii:n {#1} } + } + +\cs_new_protected:Npn \__chemmacros_nmr_frequency_aux_i:w #1,#2 \q_stop + { \SI {#1} {#2} } + +\cs_new_protected:Npn \__chemmacros_nmr_frequency_aux_ii:n #1 + { \SI {#1} { \tl_use:N \l__chemmacros_nmr_unit_tl } } + +\cs_new_eq:NN \__chemmacros_nmr_number:n \use:n +\cs_new_eq:NN \__chemmacros_nmr_position:n \use:n + +\chemmacros_define_keys:nn {spectroscopy} + { + unit .tl_set:N = \l__chemmacros_nmr_unit_tl , + unit .default:n = \mega\hertz , + nucleus .code:n = + { \__chemmacros_nmr_default_nucleus:w #1 \q_stop } , + nucleus .default:n = {1,H} , + format .tl_set:N = \l__chemmacros_nmr_format_tl , + method .tl_set:N = \l__chemmacros_nmr_method_tl , + connector .tl_set:N = \l__chemmacros_nmr_element_method_connector_tl , + pos-number .choice: , + pos-number / sub .code:n = + \tl_set:Nn \l__chemmacros_nmr_position_tl {_} + \bool_set_false:N \l__chemmacros_nmr_position_side_bool , + pos-number / super .code:n = + \tl_set:Nn \l__chemmacros_nmr_position_tl {^} + \bool_set_false:N \l__chemmacros_nmr_position_side_bool , + pos-number / side .code:n = + \tl_set:Nn \l__chemmacros_nmr_position_tl {-} + \bool_set_true:N \l__chemmacros_nmr_position_side_bool , + pos-number / .initial:n = side , + coupling-unit .tl_set:N = \l__chemmacros_nmr_coupling_unit_tl , + coupling-pos .choice: , + coupling-pos / sub .code:n = + \bool_set_true:N \l__chemmacros_nmr_coupling_nuclei_sub_bool , + coupling-pos / side .code:n = + \bool_set_false:N \l__chemmacros_nmr_coupling_nuclei_sub_bool , + coupling-nuclei-pre .tl_set:N = + \l__chemmacros_nmr_coupling_nuclei_pre_tl , + coupling-nuclei-post .tl_set:N = + \l__chemmacros_nmr_coupling_nuclei_post_tl , + coupling-bonds-pre .tl_set:N = + \l__chemmacros_nmr_coupling_bonds_pre_tl , + coupling-bonds-post .tl_set:N = + \l__chemmacros_nmr_coupling_bonds_post_tl , + coupling-symbol .tl_set:N = + \l__chemmacros_nmr_coupling_symbol_tl , + atom-number-cs .code:n = + \cs_set_eq:NN \__chemmacros_nmr_number:n #1 , + atom-number-space .skip_set:N = \l__chemmacros_nmr_space_skip , + coupling-pos-cs .code:n = + \cs_set_eq:NN \__chemmacros_nmr_position:n #1 , + parse .bool_set:N = \l__chemmacros_nmr_parse_bool , + delta .code:n = + \tl_set:Nn \l__chemmacros_nmr_delta_tl {\,#1} , + list .bool_set:N = \l__chemmacros_nmr_list_bool , + list .default:n = true , + list-setup .tl_set:N = \l__chemmacros_nmr_list_setup_tl , + use-equal .bool_set:N = \l__chemmacros_nmr_use_equal_bool , + use-equal .default:n = true + } + +\cs_new_protected:Npn \chemmacros_define_nmr:Nn #1#2 + { + \cs_if_exist:NTF #1 + { + \RenewDocumentCommand #1 {s} + { \IfBooleanTF {##1} { \NMR*{#2} } { \NMR{#2} } } + } + { + \NewDocumentCommand #1 {s} + { \IfBooleanTF {##1} { \NMR*{#2} } { \NMR{#2} } } + } + } + +\NewChemMacroset {NMR} {mm} + { \chemmacros_define_nmr:Nn #1 {#2} } + +\NewDocumentCommand \NMR { sG{}D(){}O{} } + { + \IfBooleanTF {#1} + { \chemmacros_nmr:nnnn {*} {#2} {#3} {#4} } + { \chemmacros_nmr:nnnn { } {#2} {#3} {#4} } + } + +\hook_gput_code:nnn {begindocument} {chemmacros} + { + % \NMR{<num>,<elem>}(<num>,<unit>)[<solvent>] ALL arguments are optional + % \NMR* same but without ": $\delta$" at end + \cs_new_protected:Npn \chemmacros_nmr:nnnn #1#2#3#4 + { + \bool_if:NT \l__chemmacros_nmr_list_bool { \item \scan_stop: } + \group_begin: + \mode_leave_vertical: + \bool_set_false:N \l__chemmacros_nmr_frequency_bool + \bool_set_false:N \l__chemmacros_nmr_solvent_bool + \tl_if_empty:nF {#3} + { \bool_set_true:N \l__chemmacros_nmr_frequency_bool } + \tl_if_empty:nF {#4} + { \bool_set_true:N \l__chemmacros_nmr_solvent_bool } + \bool_lazy_or:nnT + { \l__chemmacros_nmr_frequency_bool } + { \l__chemmacros_nmr_solvent_bool } + { \bool_set_true:N \l__chemmacros_nmr_delimiters_bool } + \bool_lazy_and:nnT + { \l__chemmacros_nmr_frequency_bool } + { \l__chemmacros_nmr_solvent_bool } + { \bool_set_true:N \l__chemmacros_nmr_comma_bool } + \tl_if_empty:nTF {#2} + { + \__chemmacros_nmr_nucleus:VV + \l__chemmacros_nmr_isotope_default_tl + \l__chemmacros_nmr_element_default_tl + } + { \__chemmacros_nmr_nucleus:w #2 \q_stop } + \mode_if_math:TF + { + \text + { + \group_begin: + \tl_use:N \l__chemmacros_nmr_format_tl + \__chemmacros_nmr_base:VV + \g__chemmacros_nmr_isotope_tl + \g__chemmacros_nmr_element_tl + \bool_if:NT \l__chemmacros_nmr_delimiters_bool + { ~ ( } + \bool_if:NT \l__chemmacros_nmr_frequency_bool + { \__chemmacros_nmr_frequency:n {#3} } + \bool_if:NT \l__chemmacros_nmr_comma_bool + { , ~ } + \bool_if:NT \l__chemmacros_nmr_solvent_bool + { \chemmacros_chemformula:n {#4} } + \bool_if:NT \l__chemmacros_nmr_delimiters_bool + { ) } + \tl_if_blank:nT {#1} {:~} + \group_end: + } + \tl_if_blank:nT {#1} + { + \delta + \text { \l__chemmacros_nmr_delta_tl } + \bool_if:NT \l__chemmacros_nmr_use_equal_bool {=} + } + } + { + \group_begin: + \tl_use:N \l__chemmacros_nmr_format_tl + \__chemmacros_nmr_base:VV + \g__chemmacros_nmr_isotope_tl + \g__chemmacros_nmr_element_tl + \bool_if:NT \l__chemmacros_nmr_delimiters_bool + {~(} + \bool_if:NT \l__chemmacros_nmr_frequency_bool + { \__chemmacros_nmr_frequency:n {#3} } + \bool_if:NT \l__chemmacros_nmr_comma_bool + {,~} + \bool_if:NT \l__chemmacros_nmr_solvent_bool + { + \bool_if:NTF \l__chemmacros_nmr_parse_bool + { \chemmacros_chemformula:n {#4} } + {#4} + } + \bool_if:NT \l__chemmacros_nmr_delimiters_bool + {)} + \tl_if_blank:nT {#1} {:} + \group_end: + \tl_if_blank:nT {#1} + { + \tl_use:N \c_space_tl + \c_math_toggle_token + \delta + \c_math_toggle_token + \l__chemmacros_nmr_delta_tl + \bool_if:NT \l__chemmacros_nmr_use_equal_bool {~=} + } + } + \group_end: + } + } + +\NewDocumentCommand \chemmacros_data:w { smo } + { + \bool_if:NT \l__chemmacros_nmr_list_bool { \item } + { + \tl_use:N \l__chemmacros_nmr_format_tl #2 + \IfNoValueF {#3} { ~ ( #3 ) } + \IfBooleanT {#1} { \bool_if:NT \l__chemmacros_nmr_use_equal_bool { : } } + } + \IfBooleanF {#1} { \bool_if:NT \l__chemmacros_nmr_use_equal_bool { ~ = } } + } + +\cs_new_protected:Npn \chemmacros_val:n #1 + { + \tl_if_in:nnTF {#1} {--} + { \chemmacros_val_aux:w #1 \q_nil } + { \num {#1} } + } + +\cs_new_protected:Npn \chemmacros_val_aux:w #1--#2 \q_nil + { \numrange {#1} {#2} } + +\NewDocumentEnvironment {experimental} {o} + { + \group_begin: + \IfNoValueF {#1} { \chemmacros_set_keys:nn {spectroscopy} {#1} } + \bool_set_true:N \l__chemmacros_nmr_inner_bool + \cs_set_eq:NN \# \chemmacros_nmr_number:n + \cs_set_eq:NN \pos \chemmacros_nmr_position:n + \cs_set_eq:NN \J \chemmacros_nmr_coupling:w + \cs_set_eq:NN \data \chemmacros_data:w + \cs_set_eq:NN \val \chemmacros_val:n + \bool_if:NT \l__chemmacros_nmr_list_bool + { \list {} { \l__chemmacros_nmr_list_setup_tl } } + } + { + \bool_if:NT \l__chemmacros_nmr_list_bool + { \endlist } + \group_end: + \chemmacros_ignore_spaces: + } + +\cs_new_protected:Npn \chemmacros_nmr_number:n #1 + { + \__chemmacros_nmr_number:n {#1} + \chemmacros_skip_nobreak:N \l__chemmacros_nmr_space_skip + \chemmacros_chemformula:V \g__chemmacros_nmr_element_tl + } + +\cs_new_protected:Npn \chemmacros_nmr_position:n #1 + { + \chemmacros_chemformula:x + { + \exp_not:V \g__chemmacros_nmr_element_tl + \bool_if:NF \l__chemmacros_nmr_position_side_bool + { + \exp_not:V \l__chemmacros_nmr_position_tl + \exp_not:n { _{#1} } + } + } + \bool_if:NT \l__chemmacros_nmr_position_side_bool + { + \tl_use:N \l__chemmacros_nmr_position_tl + \__chemmacros_nmr_position:n {#1} + } + } + +\cs_new_protected:Npn \chemmacros_nmr_coupling:w + { + \tl_clear:N \l__chemmacros_nmr_coupling_nuclei_tl + \tl_clear:N \l__chemmacros_nmr_coupling_bonds_tl + \peek_meaning:NTF ( + { \__chemmacros_nmr_coupling:w } + { \__chemmacros_nmr_coupling_aux_i:w } + } + +\cs_new_protected:Npn \__chemmacros_nmr_coupling:w (#1;#2) + { + \tl_set:Nn \l__chemmacros_nmr_coupling_bonds_tl + { + \l__chemmacros_nmr_coupling_bonds_pre_tl + #1 + \l__chemmacros_nmr_coupling_bonds_post_tl + } + \bool_if:NTF \l__chemmacros_nmr_coupling_nuclei_sub_bool + { + \tl_set:Nn \l__chemmacros_nmr_coupling_nuclei_tl + { + \c_math_subscript_token + { + \l__chemmacros_nmr_coupling_nuclei_pre_tl + \chemmacros_chemformula:n {#2} + \l__chemmacros_nmr_coupling_nuclei_post_tl + } + } + } + { + \tl_set:Nn \l__chemmacros_nmr_coupling_nuclei_tl + { + \l__chemmacros_nmr_coupling_nuclei_pre_tl + \chemmacros_chemformula:n {#2} + \l__chemmacros_nmr_coupling_nuclei_post_tl + } + } + \__chemmacros_nmr_coupling_aux_i:w + } + +\cs_new_protected:Npn \__chemmacros_nmr_coupling_aux_i:w + { + \peek_meaning:NTF [ + { \__chemmacros_nmr_coupling_aux_ii:w } + { \__chemmacros_nmr_coupling_aux_iii:n } + } + +\cs_new_protected:Npn \__chemmacros_nmr_coupling_aux_ii:w [#1]#2 + { + \group_begin: + \sisetup + { + list-final-separator={,~}, + list-pair-separator={,~}, + list-units=single + } + \c_math_toggle_token + ^{ \l__chemmacros_nmr_coupling_bonds_tl } + \l__chemmacros_nmr_coupling_symbol_tl + \l__chemmacros_nmr_coupling_nuclei_tl = \qtylist {#2} {#1} + \c_math_toggle_token + \group_end: + } + +\cs_new_protected:Npn \__chemmacros_nmr_coupling_aux_iii:n #1 + { + \group_begin: + \sisetup + { + list-final-separator={,~}, + list-pair-separator={,~}, + list-units=single + } + \c_math_toggle_token + ^{ \l__chemmacros_nmr_coupling_bonds_tl } + \l__chemmacros_nmr_coupling_symbol_tl + \l__chemmacros_nmr_coupling_nuclei_tl + = \exp_args:Nno \qtylist {#1} { \l__chemmacros_nmr_coupling_unit_tl } + \c_math_toggle_token + \group_end: } % -------------------------------------------------------------------------- -% messages: -\msg_new:nnn {chemmacros} {too-low-compatibility} +\ChemModuleEnd +\ChemModule{thermodynamics}{2021/07/24 thermodynamics} + +\RequirePackage {siunitx} + +\tl_new:N \l__chemmacros_state_pre_tl +\tl_new:N \l__chemmacros_state_post_tl +\tl_new:N \l__chemmacros_state_sp_left_tl +\tl_new:N \l__chemmacros_state_sb_left_tl +\tl_new:N \l__chemmacros_state_sp_right_tl +\tl_new:N \l__chemmacros_state_sb_right_tl +\tl_new:N \l__chemmacros_state_sb_pos_tl +\tl_new:N \l__chemmacros_state_symbol_tl +\tl_new:N \l__chemmacros_state_unit_tl + +\tl_set:Nn \l__chemmacros_state_pre_tl { \changestate } +\tl_set:Nn \l__chemmacros_state_sp_right_tl { \standardstate } +\tl_set:Nn \l__chemmacros_state_sb_pos_tl {left} + +\chemmacros_define_keys:nn {thermodynamics} { - Compatibility~ for~ versions~ below~ v4.7~ is~ not~ supported!~ You~ - requested~ version~ v #1.~ Loading~ v4.7~ instead. + pre .tl_set:N = \l__chemmacros_state_pre_tl , + post .tl_set:N = \l__chemmacros_state_post_tl , + superscript-left .tl_set:N = \l__chemmacros_state_sp_left_tl , + superscript-right .tl_set:N = \l__chemmacros_state_sp_right_tl , + superscript .meta:n = { superscript-right = #1 } , + subscript-left .tl_set:N = \l__chemmacros_state_sb_left_tl , + subscript-right .tl_set:N = \l__chemmacros_state_sb_right_tl , + subscript .meta:n = { subscript-left = #1 } , + unit .tl_set:N = \l__chemmacros_state_unit_tl , + unit .groups:n = {variables} } -\msg_new:nnn {chemmacros} {too-high-compatibility} +\cs_new_protected:Npn \chemmacros_state:nn #1#2 { - You~ requested~ compatibility~ mode~ v #1~ while~ the~ current~ version~ - of~ chemmacros~ is~ v \c_chemmacros_version_tl .~ Falling~ back~ - to~ v \c_chemmacros_version_number_tl ! + % pre (\Delta) + % post + % superscript-left + % superscript-right (\standardstate) + % subscript-left + % subscript-right + \group_begin: + \chemmacros_set_keys:nn {thermodynamics} {#1} + \ensuremath + { + \chemmacros_text:V \l__chemmacros_state_pre_tl + \c_math_superscript_token + { \chemmacros_text:V \l__chemmacros_state_sp_left_tl } + \c_math_subscript_token + { \chemmacros_text:V \l__chemmacros_state_sb_left_tl } + #2 + \c_math_superscript_token + { \chemmacros_text:V \l__chemmacros_state_sp_right_tl } + \c_math_subscript_token + { \chemmacros_text:V \l__chemmacros_state_sb_right_tl } + \chemmacros_text:V \l__chemmacros_state_post_tl + } + \group_end: } +\cs_generate_variant:Nn \chemmacros_state:nn { nV } -\msg_new:nnn {chemmacros} {low-compatibility} +\DeclareDocumentCommand \state { O{}m } + { \chemmacros_state:nn {#1} {#2} } + +\cs_new_protected:Npn \chemmacros_declare_state:Nn #1#2 { - You~ requested~ compatibility~ mode~ v #1~ while~ the~ current~ version~ - of~ chemmacros~ is~ v \c_chemmacros_version_tl .~ Not~ all~ features~ - or~ fixes~ will~ be~ available! + \chemmacros_define_keys:xn + {thermodynamics/\chemmacros_remove_backslash:N #1} + { + pre .meta:nn = {chemmacros/thermodynamics} { pre = ##1 } , + post .meta:nn = {chemmacros/thermodynamics} { post = ##1 } , + superscript-left .meta:nn = {chemmacros/thermodynamics} { superscript-left = ##1 } , + superscript-right .meta:nn = {chemmacros/thermodynamics} { superscript-right = ##1 } , + superscript .meta:n = { superscript-right = ##1 } , + subscript-left .meta:nn = {chemmacros/thermodynamics} { subscript-left = ##1 } , + subscript-right .meta:nn = {chemmacros/thermodynamics} { subscript-right = ##1 } , + subscript .meta:n = { subscript-left = ##1 } , + subscript-pos .choices:nn = + { left , right } + { \tl_set_eq:NN \l__chemmacros_state_sb_pos_tl \l_keys_choice_tl } , + symbol .tl_set:N = \l__chemmacros_state_symbol_tl , + unit .tl_set:N = \l__chemmacros_state_unit_tl + } + \DeclareDocumentCommand #1 { sO{}D(){}m } + { + \group_begin: + \chemmacros_set_keys:xn + {thermodynamics/\chemmacros_remove_backslash:N #1} + {#2} + \tl_if_blank:nF {##3} + { + \chemmacros_set_keys:nx {thermodynamics} + { subscript-\l__chemmacros_state_sb_pos_tl = \exp_not:n {##3} } + } + \ensuremath + { + \chemmacros_state:nV {##2} \l__chemmacros_state_symbol_tl + \chemmacros_set_keys_groups:nnn {thermodynamics} {variables} {##2} + \IfBooleanF {##1} { = \qty {##4} { \l__chemmacros_state_unit_tl } } + } + \group_end: + } } +\NewChemMacroset {State} {mm} + { \chemmacros_declare_state:Nn #1 {#2} } + % -------------------------------------------------------------------------- -% let's see that the max number is the newest (=current) version -\chemmacros_if_compatibility:nnT {>} { \c_chemmacros_version_tl } +% predefined: +\NewChemState \enthalpy { symbol = H , unit = \kilo\joule\per\mole } +\NewChemState \entropy { symbol = S , unit = \joule\per\kelvin\per\mole , pre = } +\NewChemState \gibbs { symbol = G , unit = \kilo\joule\per\mole } + +% -------------------------------------------------------------------------- +\ChemModuleEnd +\ChemModule{units}{2022/01/16 chemical units} + +\RequirePackage{siunitx} + +% -------------------------------------------------------------------------- +\DeclareSIUnit \angstrom {\SIUnitSymbolAngstrom} +\DeclareSIUnit \atm {atm} +\DeclareSIUnit \atmosphere {atm} +\DeclareSIUnit \atomicmassunit {u} +\DeclareSIUnit \bar {bar} +\DeclareSIUnit \calory {cal} +\DeclareSIUnit \cal {cal} +\DeclareSIUnit \elementarycharge {\text{\ensuremath{e}}} +\DeclareSIUnit \mmHg {mmHg} +\DeclareSIUnit \moLar {\mole\per\liter} +\DeclareSIUnit \MolMass {\gram\per\mole} +\DeclareSIUnit \normal {\textsc{n}} +\DeclareSIUnit \torr {Torr} + +\hook_gput_code:nnn {begindocument/before} {chemmacros} + { + \chemmacros_if_package_loaded:nF {chemstyle} + { + \DeclareSIUnit {\cmc } {\cubic\centi\metre} + \DeclareSIUnit {\molar} {\mole\per\cubic\deci\metre} + \DeclareSIUnit {\Molar} {\textsc{m}} + } + } + +% -------------------------------------------------------------------------- +\ChemModuleEnd +\ChemModule{reactants}{2021/07/24 typeset reactants and data} +% idea and main development of this module: Sonja K. + +\RequirePackage {chemnum} + +\cs_generate_variant:Nn \chemnum_cmpd:nnnn {nnne} +\cs_generate_variant:Nn \chemnum_init:nn {ne} +\cs_generate_variant:Nn \chemnum_get_subcompound:nn {nV} + +% -------------------------------------------------------------------------- +\msg_new:nnn {chemmacros} {reactant-name} + { + The~ reactant~ `#1'~ has~ been~ defined~ without~ a~ name!~ + \msg_line_context: + } + +\msg_new:nnn {chemmacros} {undefined-key} + { + The~ reactant~ key~ `#1'~ has~ not~ been~ defined~ using~ + \token_to_str:N \DeclareChemReactant \c_space_tl \msg_line_context: + } + +\msg_new:nnn {chemmacros} {double-defined-key} + { + The~ reactant~ key~ `#1'~ has~ already~ been~ defined~ using~ + \token_to_str:N \DeclareChemReactant \c_space_tl \msg_line_context: + } + +\msg_new:nnn {chemmacros} {double-defined-key-acronym} + { + The~ reactant~ key~ `#1'~ has~ already~ been~ defined~ using~ + \token_to_str:N \DeclareAcronym \c_space_tl \msg_line_context: + } + +\msg_new:nnn {chemmacros} {incompatible-equivalents} + { + Incompatible~ options~ `equivalents=false'~ and~ `main=equiv'~ detected.~ + `equivalents=false'~ will~ be~ ignored~ \msg_line_context: + } + +\msg_new:nnn {chemmacros} {acronym-support} + { + \token_to_str:N #1 is~ only~ available~ when~ setting~ the~ + `acronym-support'~ option~ accordingly~ \msg_line_context: + } + +\msg_new:nnn {chemmacros} {missing-printreactants-style} + { + \token_to_str:N \printreactants \c_space_tl\token_to_str:N was~ used~ without~ a~ + `printreactants-style'~ option,~ thus~ no~ list~ is~ printed~ \msg_line_context: + } + +\msg_new:nnn {chemmacros} {package-not-loaded} + { The~ command~ \token_to_str:N #1 requires~ the~ package~ `#2'. } + +% -------------------------------------------------------------------------- +\seq_new:N \l__chemmacros_reactants_tmpa_seq + +\bool_new:N \l__chemmacros_reactants_switch_bool +\bool_new:N \l__chemmacros_reactants_initiate_bool +\bool_new:N \l__chemmacros_reactants_equivalents_bool + +\bool_new:N \l__chemmacros_reactants_nmo_bool +\bool_new:N \l__chemmacros_reactants_mno_bool +\bool_new:N \l__chemmacros_reactants_mon_bool + +\bool_new:N \l__chemmacros_reactants_snm_bool +\bool_new:N \l__chemmacros_reactants_smn_bool + +\bool_new:N \l__chemmacros_reactants_acronym_support_bool +\bool_new:N \l__chemmacros_reactants_printreactants_style_bool + +\str_new:N \l__chemmacros_reactants_acronym_support_str +\str_new:N \l__chemmacros_reactants_printreactants_style_str +\str_new:N \l__chemmacros_reactants_main_str +\str_new:N \l__chemmacros_reactants_name_str + +\tl_new:N \l__chemmacros_mass_unit_tl +\tl_new:N \l__chemmacros_volume_unit_tl +\tl_new:N \l__chemmacros_amount_unit_tl +\tl_new:N \l__chemmacros_concentration_unit_tl +\tl_new:N \l__chemmacros_equiv_unit_tl +\tl_new:N \l__chemmacros_fraction_unit_tl +\tl_new:N \l__chemmacros_purity_unit_tl +\tl_new:N \l__chemmacros_solution_name_tl + +\chemmacros_define_keys:nn {reactants} + { + mass-unit .tl_set:N = \l__chemmacros_mass_unit_tl , + mass-unit .initial:n = \gram , + %% + volume-unit .tl_set:N = \l__chemmacros_volume_unit_tl , + volume-unit .initial:n = \milli\liter , + %% + amount-unit .tl_set:N = \l__chemmacros_amount_unit_tl , + amount-unit .initial:n = \milli\mole , + %% + concentration-unit .tl_set:N = \l__chemmacros_concentration_unit_tl , + concentration-unit .initial:n = \Molar , + %% + equiv-unit .tl_set:N = \l__chemmacros_equiv_unit_tl , + equiv-unit .initial:n = eq , + %% + fraction-unit .tl_set:N = \l__chemmacros_fraction_unit_tl , + fraction-unit .initial:n = w/w \percent , + %% + purity-unit .tl_set:N = \l__chemmacros_purity_unit_tl , + purity-unit .initial:n = \percent , + %% + solution-name .tl_set:N = \l__chemmacros_solution_name_tl , + solution-name .initial:n = \chemmacros_translate:n {solution} , + %% + switch .bool_set:N = \l__chemmacros_reactants_switch_bool , + switch .initial:n = false , + %% + initiate .bool_set:N = \l__chemmacros_reactants_initiate_bool , + initiate .initial:n = false , + %% + equivalents .bool_set_inverse:N = \l__chemmacros_reactants_equivalents_bool , + equivalents .initial:n = true, + %% + reactant-output-style .choice: , + reactant-output-style / name-main-other .code:n = + \bool_set_true:N \l__chemmacros_reactants_nmo_bool + \bool_set_false:N \l__chemmacros_reactants_mno_bool + \bool_set_false:N \l__chemmacros_reactants_mon_bool , + reactant-output-style / main-name-other .code:n = + \bool_set_false:N \l__chemmacros_reactants_nmo_bool + \bool_set_true:N \l__chemmacros_reactants_mno_bool + \bool_set_false:N \l__chemmacros_reactants_mon_bool , + reactant-output-style / main-other-name .code:n = + \bool_set_false:N \l__chemmacros_reactants_nmo_bool + \bool_set_false:N \l__chemmacros_reactants_mno_bool + \bool_set_true:N \l__chemmacros_reactants_mon_bool , + reactant-output-style .initial:n = name-main-other , + %% + solvent-output-style .choice: , + solvent-output-style / main-name .code:n = + \bool_set_false:N \l__chemmacros_reactants_snm_bool + \bool_set_true:N \l__chemmacros_reactants_smn_bool , + solvent-output-style / name-main .code:n = + \bool_set_true:N \l__chemmacros_reactants_snm_bool + \bool_set_false:N \l__chemmacros_reactants_smn_bool , + solvent-output-style .initial:n = main-name , + %% + main .choice: , + main / amount .code:n = + \str_set:Nn \l__chemmacros_reactants_main_str {amount} , + main / equiv .code:n = + \str_set:Nn \l__chemmacros_reactants_main_str {equiv} , + main / default .code:n = + \str_set:Nn \l__chemmacros_reactants_main_str {default} , + main .initial:n = default , + %% + acronym-support .choice: , + acronym-support / glossaries-extra .code:n = + \bool_set_true:N \l__chemmacros_reactants_acronym_support_bool + \str_set:Nn \l__chemmacros_reactants_acronym_support_str {glossaries} + \RequirePackage [acronyms] {glossaries-extra} , + acronym-support / acro .code:n = + \bool_set_true:N \l__chemmacros_reactants_acronym_support_bool + \str_set:Nn \l__chemmacros_reactants_acronym_support_str {acro} + \RequirePackage {acro} , + acronym-support / none .code:n = + \bool_set_false:N \l__chemmacros_reactants_acronym_support_bool + \str_clear:N \l__chemmacros_reactants_acronym_support_str , + acronym-support .initial:n = none , + %% + printreactants-style .choice: , + printreactants-style / xltabular .code:n = + \bool_set_true:N \l__chemmacros_reactants_printreactants_style_bool + \str_set:Nn \l__chemmacros_reactants_printreactants_style_str {xltabular} + \RequirePackage {xltabular} , + printreactants-style / longtable .code:n = + \bool_set_true:N \l__chemmacros_reactants_printreactants_style_bool + \str_set:Nn \l__chemmacros_reactants_printreactants_style_str {longtable} + \RequirePackage {longtable} , + printreactants-style / none .code:n = + \bool_set_false:N \l__chemmacros_reactants_printreactants_style_bool + \str_clear:N \l__chemmacros_reactants_printreactants_style_str , + printreactants-style .initial:n = none + } + +% -------------------------------------------------------------------------- +% #1: key +% #2: properties +\NewDocumentCommand \DeclareChemReactant {mm} + { \chemmacros_declare_reactant:nn {#1} {#2} } + +% #1: key +% #2: properties +\cs_new_protected:Npn \chemmacros_declare_reactant:nn #1#2 + { + \cs_if_exist:cT + {l__chemmacros_reactants_#1_prop} + {\msg_error:nnn {chemmacros} {double-defined-key} {#1} } + \prop_new:c {l__chemmacros_reactants_#1_prop} + \__chemmacros_reactants_set_properties:nn {#1} {#2} + % check if name given: + \__chemmacros_reactants_if_property:nnF {#1} {name} + { \msg_error:nnn {chemmacros} {reactant-name} {#1} } + % check if number given; else use key: + \__chemmacros_reactants_if_property:nnF {#1} {number} + { \__chemmacros_reactants_set_properties:nn {#1} { number = #1 } } + \bool_if:NT \l__chemmacros_reactants_initiate_bool + { + \hook_gput_code:nnn {begindocument} {chemmacros} + { \chemnum_init:ne {} { \__chemmacros_reactants_item:nn {#1} {number} } } + } + \bool_if:NT \l__chemmacros_reactants_acronym_support_bool + { + \str_case:Vn \l__chemmacros_reactants_acronym_support_str + { + {glossaries} + { + \chemmacros_if_package_loaded:nTF {glossaries-extra} + { + \__chemmacros_reactants_if_property:nnT {#1} {short} + { + \exp_args:Nnxx + \newacronym + {#1} + { \__chemmacros_reactants_item:nn {#1} {short} } + { \__chemmacros_reactants_item:nn {#1} {name} } + } + } + { + \msg_error:nnnn + {chemmacros} + {package-not-loaded} + { \printreactants } + {glossaries-extra} + } + } + {acro} + { + \__chemmacros_reactants_if_property:nnT {#1} {short} + { + \chemmacros_if_package_loaded:nTF {acro} + { + \acro_if_defined:nT {#1} + { \msg_error:nnn {chemmacros} {double-defined-key-acronym} {#1} } + \exp_args:Nnx + \DeclareAcronym {#1} { + short = \__chemmacros_reactants_item:nn {#1} {short} , + long = \__chemmacros_reactants_item:nn {#1} {name} + } + } + { + \msg_error:nnnn + {chemmacros} + {package-not-loaded} + { \printreactants } + {acro} + } + } + } + } + } + } + +% #1: key +% #2: properties +\cs_new_protected:Npn \__chemmacros_reactants_set_properties:nn #1#2 + { + \cs_set_protected:Npn \__chemmacros_reactants_property:nn ##1##2 + { + \str_case:nnF {##1} + { {name} { \__chemmacros_reactants_put:nnn {#1} {##1} {##2} } } + { \__chemmacros_reactants_put:nnn {#1} {##1} {##2} } + } + \cs_set_protected:Npn \__chemmacros_reactants_property:n ##1 + { \__chemmacros_reactants_put:nnn {#1} {##1} {} } + \keyval_parse:NNn + \__chemmacros_reactants_property:n + \__chemmacros_reactants_property:nn + {#2} + } + +% #1: key +% #2: property +\prg_new_conditional:Npnn \__chemmacros_reactants_if_property:nn #1#2 {p,T,F,TF} { - \tl_set_eq:NN - \l__chemmacros_compatibility_version_tl - \c_chemmacros_version_tl + \prop_if_in:cnTF {l__chemmacros_reactants_#1_prop} {#2} + { \prg_return_true: } + { \prg_return_false: } } +% #1: key +% #2: property +\cs_new:Npn \__chemmacros_reactants_item:nn #1#2 + { \prop_item:cn {l__chemmacros_reactants_#1_prop} {#2} } + +% #1: key +% #2: property +% #3: value +\cs_new_protected:Npn \__chemmacros_reactants_put:nnn #1#2#3 + { \prop_put:cnn {l__chemmacros_reactants_#1_prop} {#2} {#3} } + % -------------------------------------------------------------------------- -% compatibility too low: -\chemmacros_if_compatibility:nnT {<} {4.7} +% #1: boolean > no name +% #2: boolean: if true, allow no properties and use cmpd+ +% #3: properties and options +% #4: key +\NewDocumentCommand \reactant {st+O{}m} + { + \group_begin: + \str_set:Nn \l__chemmacros_reactants_name_str {regular} + \chemmacros_reactant:nnnn {#1} {#2} {#3} {#4} + \group_end: + } + +% #1: boolean > no name +% #2: boolean: if true, allow no properties and use cmpd+ +% #3: properties and options +% #4: key +\NewDocumentCommand \reactants {st+O{}m} + { + \group_begin: + \bool_if:NTF \l__chemmacros_reactants_acronym_support_bool + { + \str_set:Nn \l__chemmacros_reactants_name_str {short} + \chemmacros_reactant:nnnn {#1} {#2} {#3} {#4} + } + { \msg_error:nnn {chemmacros} {acronym-support} { \reactants } } + \group_end: + } + +% #1: boolean > no name +% #2: boolean: if true, allow no properties and use cmpd+ +% #3: properties and options +% #4: key +\NewDocumentCommand \reactantl {st+O{}m} + { + \group_begin: + \bool_if:NTF \l__chemmacros_reactants_acronym_support_bool + { + \str_set:Nn \l__chemmacros_reactants_name_str {long} + \chemmacros_reactant:nnnn {#1} {#2} {#3} {#4} + } + { \msg_error:nnn {chemmacros} {acronym-support} { \reactantl } } + \group_end: + } + +% #1: boolean > no name +% #2: boolean: if true, allow no properties and use cmpd+ +% #3: properties and options +% #4: key +\NewDocumentCommand \Reactant {st+O{}m} + { + \group_begin: + \str_set:Nn \l__chemmacros_reactants_name_str {upper} + \chemmacros_reactant:nnnn {#1} {#2} {#3} {#4} + \group_end: + } + + +% #1: boolean > no name +% #2: boolean: if true, allow no properties and use cmpd+ +% #3: properties and options +% #4: key +\cs_new_protected:Npn \chemmacros_reactant:nnnn #1#2#3#4 + { + \group_begin: + \bool_if:NT \l__chemmacros_reactants_nmo_bool + { + \__chemmacros_reactants_set_properties:nn {#4} {#3} + % name: + \chemmacros_reactants_name:nnnn {#1} {#3} {#4} {#2} + \chemmacros_reactants_if_any:nT {#4} {~(} + % main: + \__chemmacros_reactants_mainproperty:nn {#3} {#4} + \bool_lazy_and:nnT + { \chemmacros_reactants_if_main_p:n {#4} } + { \chemmacros_reactants_if_other_p:n {#4} } + {,~} + % others: + \chemmacros_reactants_properties:nn {#3} {#4} + \chemmacros_reactants_if_any:nT {#4} {)} + } + \bool_if:NT \l__chemmacros_reactants_mno_bool + { + \__chemmacros_reactants_set_properties:nn {#4} {#3} + % main: + \__chemmacros_reactants_mainproperty:nn {#3} {#4} + \chemmacros_reactants_if_main:nT {#4} {~} + % name: + \chemmacros_reactants_name:nnnn {#1} {#3} {#4} {#2} + % others: + \chemmacros_reactants_if_other:nT {#4} {~(} + \chemmacros_reactants_properties:nn {#3} {#4} + \chemmacros_reactants_if_other:nT {#4} {)} + } + \bool_if:NT \l__chemmacros_reactants_mon_bool + { + \__chemmacros_reactants_set_properties:nn {#4} {#3} + % main: + \__chemmacros_reactants_mainproperty:nn {#3} {#4} + \chemmacros_reactants_if_main:nT {#4} {~} + % others: + \chemmacros_reactants_if_other:nT {#4} {(} + \chemmacros_reactants_properties:nn {#3} {#4} + \chemmacros_reactants_if_other:nT {#4} {)~} + % name + \chemmacros_reactants_name:nnnn {#1} {#3} {#4} {#2} + } + \group_end: + } + +% #1: key +\prg_new_conditional:Npnn \chemmacros_reactants_if_main:n #1 {p,T,F,TF} + { + \bool_lazy_or:nnTF + { \__chemmacros_reactants_if_property_p:nn {#1} {mass} } + { \__chemmacros_reactants_if_property_p:nn {#1} {volume} } + { \prg_return_true: } + { + \str_case:VnF \l__chemmacros_reactants_main_str + { + {amount} { + \__chemmacros_reactants_if_property:nnTF {#1} {amount} + { \prg_return_true: } + { \prg_return_false: } + } + {equiv} { + \__chemmacros_reactants_if_property:nnTF {#1} {equiv} + { \prg_return_true: } + { \prg_return_false: } + } + } + { \prg_return_false: } + } + } + +% #1: key +\prg_new_conditional:Npnn \chemmacros_reactants_if_other:n #1 {p,T,F,TF} + { + \bool_lazy_any:nTF + { + { \__chemmacros_reactants_if_property_p:nn {#1} {fraction} } + { \__chemmacros_reactants_if_property_p:nn {#1} {purity} } + { \__chemmacros_reactants_if_property_p:nn {#1} {concentration} } + { \__chemmacros_reactants_if_property_p:nn {#1} {solvent} } + } + { \prg_return_true: } + { + \str_case:VnF \l__chemmacros_reactants_main_str + { + {default} { + \bool_lazy_or:nnTF + { \__chemmacros_reactants_if_property_p:nn {#1} {amount} } + { + \bool_lazy_and_p:nn + { \__chemmacros_reactants_if_property_p:nn {#1} {equiv} } + { !\l__chemmacros_reactants_equivalents_bool } + } + { \prg_return_true: } + { \prg_return_false: } + } + {amount} { + \bool_if:NTF \l__chemmacros_reactants_equivalents_bool + { \prg_return_false: } + { + \__chemmacros_reactants_if_property:nnTF {#1} {equiv} + { \prg_return_true: } + { \prg_return_false: } + } + } + {equiv} { + \__chemmacros_reactants_if_property:nnTF {#1} {amount} + { \prg_return_true: } + { \prg_return_false: } + } + } + { \prg_return_false: } + } + } + +% #1: key +\prg_new_conditional:Npnn \chemmacros_reactants_if_any:n #1 {T,F,TF} + { + \bool_lazy_any:nTF + { + { \__chemmacros_reactants_if_property_p:nn {#1} {mass} } + { \__chemmacros_reactants_if_property_p:nn {#1} {volume} } + { \__chemmacros_reactants_if_property_p:nn {#1} {fraction} } + { \__chemmacros_reactants_if_property_p:nn {#1} {amount} } + { \__chemmacros_reactants_if_property_p:nn {#1} {equiv} } + { \__chemmacros_reactants_if_property_p:nn {#1} {purity} } + { \__chemmacros_reactants_if_property_p:nn {#1} {concentration} } + { \__chemmacros_reactants_if_property_p:nn {#1} {solvent} } + } + { \prg_return_true: } + { \prg_return_false: } + } + +% #1: boolean > no name +% #2: options and keys +% #3: key +% #4: boolean: if true, allow no properties and use cmpd+ +\cs_new_protected:Npn \chemmacros_reactants_name:nnnn #1#2#3#4 + { + \group_begin: + \keys_set_known:nn {chemmacros/reactants} {#2} + \bool_lazy_or:nnT + { \bool_lazy_and_p:nn {#1} { !\l__chemmacros_reactants_switch_bool } } + { !#1 } + { + \str_case:Vn \l__chemmacros_reactants_name_str + { + {regular} + { \__chemmacros_reactants_item:nn {#3} {name} } + {upper} + { \__chemmacros_reactants_item:nn {#3} {upper-name} } + {short} + { + \str_case:Vn \l__chemmacros_reactants_acronym_support_str + { + {glossaries} { \glsxtrshort {#3} } + {acro} { \acs {#3} } + } + } + {long} + { + \str_case:Vn \l__chemmacros_reactants_acronym_support_str + { + {glossaries} { \glsxtrlong {#3} } + {acro} { \acl {#3} } + } + } + } + } + \bool_if:nF {#1} { \nobreakspace } + \bool_lazy_or:nnT + { \bool_lazy_and_p:nn {#1} { \l__chemmacros_reactants_switch_bool } } + { !#1 } + { + \chemnum_cmpd:nnne + { \c_false_bool } + {#4} + { } + { \__chemmacros_reactants_item:nn {#3} {number} } + % what is this for? + % it causes problems when #3 is a combination of main and sub: + % \bool_if:nF {#4} + % { + % \chemnum_compound_if_initiated:nF {#3} + % { \msg_warning:nnn {chemmacros} {undefined-key} {#3} } + % } + } + \group_end: + } + +% #1: options and properties +% #2: key +\cs_new_protected:Npn \chemmacros_reactants_properties:nn #1#2 + { + \group_begin: + \seq_clear:N \l__chemmacros_tmpa_seq + \__chemmacros_reactants_set_properties:nn {#2} {#1} + \keys_set_known:nn {chemmacros/reactants} {#1} + \bool_lazy_any:nT + { + { \__chemmacros_reactants_if_property_p:nn {#2} {mass} } + { \__chemmacros_reactants_if_property_p:nn {#2} {volume} } + { \__chemmacros_reactants_if_property_p:nn {#2} {fraction} } + { \__chemmacros_reactants_if_property_p:nn {#2} {amount} } + { \__chemmacros_reactants_if_property_p:nn {#2} {equiv} } + { \__chemmacros_reactants_if_property_p:nn {#2} {purity} } + { \__chemmacros_reactants_if_property_p:nn {#2} {concentration} } + { \__chemmacros_reactants_if_property_p:nn {#2} {solvent} } + { \__chemmacros_reactants_if_property_p:nn {#2} {fraction-unit} } + { \__chemmacros_reactants_if_property_p:nn {#2} {amount-unit} } + { \__chemmacros_reactants_if_property_p:nn {#2} {equiv-unit} } + { \__chemmacros_reactants_if_property_p:nn {#2} {purity-unit} } + { \__chemmacros_reactants_if_property_p:nn {#2} {concentration-unit} } + } + { + \__chemmacros_reactants_change_unit:nnN + {#2} + {fraction-unit} + \l__chemmacros_fraction_unit_tl + \__chemmacros_reactants_change_unit:nnN + {#2} + {amount-unit} + \l__chemmacros_amount_unit_tl + \bool_if:NF \l__chemmacros_reactants_equivalents_bool + { + \__chemmacros_reactants_change_unit:nnN + {#2} + {equiv-unit} + \l__chemmacros_equiv_unit_tl + } + \__chemmacros_reactants_change_unit:nnN + {#2} + {purity-unit} + \l__chemmacros_purity_unit_tl + \__chemmacros_reactants_change_unit:nnN + {#2} + {concentration-unit} + \l__chemmacros_concentration_unit_tl + \__chemmacros_reactants_add_property:NnnV \l__chemmacros_tmpa_seq + {#2} + {fraction} + \l__chemmacros_fraction_unit_tl + \str_if_eq:VnF \l__chemmacros_reactants_main_str {amount} + { + \__chemmacros_reactants_add_property:NnnV \l__chemmacros_tmpa_seq + {#2} + {amount} + \l__chemmacros_amount_unit_tl + } + \bool_if:NTF \l__chemmacros_reactants_equivalents_bool + { + \str_if_eq:VnT \l__chemmacros_reactants_main_str {equiv} + { \msg_warning:nnn {chemmacros} {incompatible-equivalents} {#1} } + } + { + \str_if_eq:VnF \l__chemmacros_reactants_main_str {equiv} + { + \__chemmacros_reactants_add_property:NnnV \l__chemmacros_tmpa_seq + {#2} + {equiv} + \l__chemmacros_equiv_unit_tl + } + } + \__chemmacros_reactants_add_property:NnnV \l__chemmacros_tmpa_seq + {#2} + {purity} + \l__chemmacros_purity_unit_tl + \__chemmacros_reactants_add_property:NnnV \l__chemmacros_tmpa_seq + {#2} + {concentration} + \l__chemmacros_concentration_unit_tl + \seq_use:Nn \l__chemmacros_tmpa_seq {,~} + \__chemmacros_reactants_add_solvent:Nnn + {#2} + {solvent} + \l__chemmacros_solution_name_tl + } + \group_end: + } + +% #1: options and properties +% #2: key +\cs_new_protected:Npn \__chemmacros_reactants_mainproperty:nn #1#2 + { + \group_begin: + \seq_clear:N \l__chemmacros_tmpa_seq + \__chemmacros_reactants_set_properties:nn {#2} {#1} + \keys_set_known:nn {chemmacros/reactants} {#1} + \bool_lazy_or:nnT + { \__chemmacros_reactants_if_property_p:nn {#2} {mass-unit} } + { \__chemmacros_reactants_if_property_p:nn {#2} {volume-unit} } + { + \__chemmacros_reactants_change_unit:nnN + {#2} + {mass-unit} + \l__chemmacros_mass_unit_tl + \__chemmacros_reactants_change_unit:nnN + {#2} + {volume-unit} + \l__chemmacros_volume_unit_tl + } + \bool_lazy_and:nnT + { \str_if_eq_p:Vn \l__chemmacros_reactants_main_str {amount} } + { \__chemmacros_reactants_if_property_p:nn {#2} {amount-unit} } + { + \__chemmacros_reactants_change_unit:nnN + {#2} + {amount-unit} + \l__chemmacros_amount_unit_tl + } + \bool_lazy_and:nnT + { \str_if_eq_p:Vn \l__chemmacros_reactants_main_str {equiv} } + { \__chemmacros_reactants_if_property_p:nn {#2} {equiv-unit} } + { + \__chemmacros_reactants_change_unit:nnN + {#2} + {equiv-unit} + \l__chemmacros_equiv_unit_tl + } + \__chemmacros_reactants_add_property:NnnV \l__chemmacros_tmpa_seq + {#2} + {mass} + \l__chemmacros_mass_unit_tl + \__chemmacros_reactants_add_property:NnnV \l__chemmacros_tmpa_seq + {#2} + {volume} + \l__chemmacros_volume_unit_tl + \str_if_eq:VnT \l__chemmacros_reactants_main_str {amount} + { + \__chemmacros_reactants_add_property:NnnV \l__chemmacros_tmpa_seq + {#2} + {amount} + \l__chemmacros_amount_unit_tl + } + \str_if_eq:VnT \l__chemmacros_reactants_main_str {equiv} + { + \__chemmacros_reactants_add_property:NnnV \l__chemmacros_tmpa_seq + {#2} + {equiv} + \l__chemmacros_equiv_unit_tl + } + \seq_if_empty:NF \l__chemmacros_tmpa_seq + { \seq_use:Nn \l__chemmacros_tmpa_seq {,~} } + \group_end: + } + +% #1: seq variable +% #2: key +% #3: property +% #4: unit +\cs_new_protected:Npn \__chemmacros_reactants_add_property:Nnnn #1#2#3#4 + { + \__chemmacros_reactants_if_property:nnT {#2} {#3} + { + \seq_put_right:Ne #1 + { \qty { \__chemmacros_reactants_item:nn {#2} {#3} } { \exp_not:n {#4} } } + } + } +\cs_generate_variant:Nn \__chemmacros_reactants_add_property:Nnnn {NnnV} + +% #1: key +% #2: property (name of solvent) +% #3: linking text +\cs_new_protected:Npn \__chemmacros_reactants_add_solvent:Nnn #1#2#3 + { + \__chemmacros_reactants_if_property:nnT {#1} {#2} + { + \c_space_tl + \l__chemmacros_solution_name_tl + \c_space_tl + \__chemmacros_reactants_item:nn {#1} {#2} + } + } +\cs_generate_variant:Nn \__chemmacros_reactants_add_solvent:Nnn {NnV} + +% #1: key +% #2: property +% #3: new unit +\cs_new_protected:Npn \__chemmacros_reactants_change_unit:nnN #1#2#3 + { + \__chemmacros_reactants_if_property:nnT {#1} {#2} + { \prop_get:cnN {l__chemmacros_reactants_#1_prop} {#2} #3 } + } + +% #1: properties and options +% #2: key +\NewDocumentCommand \solvent {O{}m} + { + \group_begin: + \str_set:Nn \l__chemmacros_reactants_name_str {regular} + \chemmacros_solvent:nn {#1} {#2} + \group_end: + } + +% #1: properties and options +% #2: key +\NewDocumentCommand \solvents {O{}m} + { + \group_begin: + \bool_if:NTF \l__chemmacros_reactants_acronym_support_bool + { + \str_set:Nn \l__chemmacros_reactants_name_str {short} + \chemmacros_solvent:nn {#1} {#2} + } + { \msg_error:nnn {chemmacros} {acronym-support} { \solvents } } + \group_end: + } + +% #1: properties and options +% #2: key +\NewDocumentCommand \solventl {O{}m} + { + \group_begin: + \bool_if:NTF \l__chemmacros_reactants_acronym_support_bool + { + \str_set:Nn \l__chemmacros_reactants_name_str {long} + \chemmacros_solvent:nn {#1} {#2} + } + { \msg_error:nnn {chemmacros} {acronym-support} { \solventl } } + \group_end: + } + +% #1: properties and options +% #2: key +\NewDocumentCommand \Solvent {O{}m} + { + \group_begin: + \str_set:Nn \l__chemmacros_reactants_name_str {upper} + \chemmacros_solvent:nn {#1} {#2} + \group_end: + } + + +% #1: options and properties +% #3: key +\cs_new_protected:Npn \chemmacros_solvent:nn #1#2 + { + \group_begin: + \bool_if:NT \l__chemmacros_reactants_snm_bool + { + \__chemmacros_reactants_set_properties:nn {#2} {#1} + \chemmacros_solvent_name:nn {#1} {#2} + \chemmacros_reactants_if_main:nT {#2} {~(} + \chemmacros_solvent_properties:nn {#1} {#2} + \chemmacros_reactants_if_main:nT {#2} {)} + } + \bool_if:NT \l__chemmacros_reactants_smn_bool + { + \__chemmacros_reactants_set_properties:nn {#2} {#1} + \chemmacros_solvent_properties:nn {#1} {#2} + \chemmacros_reactants_if_main:nT {#2} {~} + \chemmacros_solvent_name:nn {#1} {#2} + } + \group_end: + } + +% #1: options and properties +% #3: key +\cs_new_protected:Npn \chemmacros_solvent_properties:nn #1#2 { - \msg_warning:nnx {chemmacros} {too-low-compatibility} - { \l__chemmacros_compatibility_version_tl } + \group_begin: + \__chemmacros_reactants_set_properties:nn {#2} {#1} + \keys_set_known:nn {chemmacros/reactants} {#1} + \bool_lazy_or:nnT + { \__chemmacros_reactants_if_property_p:nn {#2} {volume} } + { \__chemmacros_reactants_if_property_p:nn {#2} {volume-unit} } + { + \__chemmacros_reactants_change_unit:nnN {#2} + {volume-unit} + \l__chemmacros_volume_unit_tl + \qty + { \__chemmacros_reactants_item:nn {#2} {volume} } + { \l__chemmacros_volume_unit_tl } + + } + \group_end: } -% not the newest version: -\chemmacros_if_compatibility:nnT {<} { \c_chemmacros_version_tl } +% #1: options +% #2: key +\cs_new_protected:Npn \chemmacros_solvent_name:nn #1#2 { - \msg_warning:nnx {chemmacros} {low-compatibility} - { \l__chemmacros_compatibility_version_tl } + \group_begin: + \keys_set_known:nn {chemmacros/reactants} {#1} + \str_case:Vn \l__chemmacros_reactants_name_str + { + {regular} + { \__chemmacros_reactants_item:nn {#2} {name} } + {upper} + { \__chemmacros_reactants_item:nn {#2} {upper-name} } + {short} + { + \str_case:Vn \l__chemmacros_reactants_acronym_support_str + { + {glossaries} { \glsxtrshort {#2} } + {acro} { \acs {#2} } + } + } + {long} + { + \str_case:Vn \l__chemmacros_reactants_acronym_support_str + { + {glossaries} { \glsxtrlong {#2} } + {acro} { \acl {#2} } + } + } + } + \group_end: + } + +% -------------------------------------------------------------------------- + +% #1: full ID +\DeclareExpandableDocumentCommand \reactantplain {m} + { + \chemmacros_if_package_loaded:nF {hyperref} + { + \msg_expandable_error:nnnn + {chemmacros} + {package-not-loaded} + { \reactantplain } + {hyperref} + } + \__chemmacros_reactants_if_property:nnF {#1} {bookmark} + { \msg_expandable_error:nnn {chemmacros} {reactant-bookmark} {#1} } + \texorpdfstring + { \__chemmacros_reactants_item:nn {#1} {name} ~ \cmpd+ {#1} } + { \__chemmacros_reactants_item:nn {#1} {bookmark} \space \cmpdplain {#1} } + } + +% #1: full ID +\DeclareExpandableDocumentCommand \Reactantplain {m} + { + \chemmacros_if_package_loaded:nF {hyperref} + { + \msg_expandable_error:nnnn + {chemmacros} + {package-not-loaded} + { \reactantplain } + {hyperref} + } + \__chemmacros_reactants_if_property:nnF {#1} {upper-bookmark} + { \msg_expandable_error:nnn {chemmacros} {reactant-bookmark} {#1} } + \texorpdfstring + { \__chemmacros_reactants_item:nn {#1} {upper-name} ~ \cmpd+ {#1} } + { \__chemmacros_reactants_item:nn {#1} {upper-bookmark} \space \cmpdplain {#1} } + } + + +% #1: main Id +% #2: sub ID +\DeclareExpandableDocumentCommand \submainreactantplain {mm} + { + \chemmacros_if_package_loaded:nF {hyperref} + { + \msg_expandable_error:nnnn + {chemmacros} + {package-not-loaded} + { \submainreactantplain } + {hyperref} + } + \__chemmacros_reactants_if_property:nnF + { #1 \l_chemnum_compound_separator_tl #2 } + {bookmark} + { \msg_expandable_error:nnn {chemmacros} {reactant-bookmark} {#1.#2} } + \texorpdfstring + { + \__chemmacros_reactants_item:nn + { #1 \l_chemnum_compound_separator_tl #2 } + {name} + \c_space_tl + \cmpd+ {#1.#2} + } + { + \__chemmacros_reactants_item:nn + { #1 \l_chemnum_compound_separator_tl #2 } + {bookmark} + \space \submaincmpdplain {#1} {#2} + } + } + + +% #1: main Id +% #2: sub ID +\DeclareExpandableDocumentCommand \Submainreactantplain {mm} + { + \chemmacros_if_package_loaded:nF {hyperref} + { + \msg_expandable_error:nnnn + {chemmacros} + {package-not-loaded} + { \submainreactantplain } + {hyperref} + } + \__chemmacros_reactants_if_property:nnF + { #1 \l_chemnum_compound_separator_tl #2 } + {upper-bookmark} + { \msg_expandable_error:nnn {chemmacros} {reactant-bookmark} {#1.#2} } + \texorpdfstring + { + \__chemmacros_reactants_item:nn + { #1 \l_chemnum_compound_separator_tl #2 } + {upper-name} + \c_space_tl + \cmpd+ {#1.#2} + } + { + \__chemmacros_reactants_item:nn + { #1 \l_chemnum_compound_separator_tl #2 } + {upper-bookmark} + \space \submaincmpdplain {#1} {#2} + } } + +% #1: full ID +\DeclareExpandableDocumentCommand \solventplain {m} + { + \chemmacros_if_package_loaded:nF {hyperref} + { + \msg_expandable_error:nnnn + {chemmacros} + {package-not-loaded} + { \solventplain } + {hyperref} + } + \__chemmacros_reactants_if_property:nnF {#1} {bookmark} + { \msg_expandable_error:nnn {chemmacros} {reactant-bookmark} {#1} } + \texorpdfstring + { \__chemmacros_reactants_item:nn {#1} {name} ~ } + { \__chemmacros_reactants_item:nn {#1} {bookmark} ~ } + } + +% #1: full ID +\DeclareExpandableDocumentCommand \Solventplain {m} + { + \chemmacros_if_package_loaded:nF {hyperref} + { + \msg_expandable_error:nnnn + {chemmacros} + {package-not-loaded} + { \solventplain } + {hyperref} + } + \__chemmacros_reactants_if_property:nnF {#1} {upper-bookmark} + { \msg_expandable_error:nnn {chemmacros} {reactant-bookmark} {#1} } + \texorpdfstring + { \__chemmacros_reactants_item:nn {#1} {upper-name} ~ } + { \__chemmacros_reactants_item:nn {#1} {upper-bookmark} ~ } + } + % -------------------------------------------------------------------------- -\chemmacros_if_compatibility:nnTF {<} {5.0} - { \RequirePackage{chemmacros4} } - { \RequirePackage{chemmacros5} } +% #1: star: include ID in table +\NewDocumentCommand \printreactants {s} + { + \group_begin: + \chemmacros_set_keys:nn {reactants} { switch = false } + \int_step_variable:nNn + { \seq_count:N \g_chemnum_initiated_compounds_seq } + \l__chemmacros_reactants_tmpa_tl + { + \seq_put_right:Nx + \l__chemmacros_reactants_tmpa_seq + { + \chemnum_cmpd:nnne { \c_false_bool } { \c_true_bool } {} + { + \seq_item:NV + \g_chemnum_initiated_compounds_seq + \l__chemmacros_reactants_tmpa_tl + } + & + \bool_if:nT {#1} + { + \seq_item:NV + \g_chemnum_initiated_compounds_seq + \l__chemmacros_reactants_tmpa_tl + & + } + % TODO: expl3-command ?? + \solvent + { + \seq_item:NV + \g_chemnum_initiated_compounds_seq + \l__chemmacros_reactants_tmpa_tl + } + \tabularnewline + } + \tl_set:Nx + \l__chemmacros_reactants_tmpb_tl + { + \seq_item:NV + \g_chemnum_initiated_compounds_seq + \l__chemmacros_reactants_tmpa_tl + } + \chemmacros_reactants_list_subreactant:Vn + \l__chemmacros_reactants_tmpb_tl + {#1} + } + % TODO: longtable ? + % table customizable? + % first draft of two styles + \par + \noindent + \bool_if:NTF \l__chemmacros_reactants_printreactants_style_bool + { + \str_case:Vn \l__chemmacros_reactants_printreactants_style_str + { + {xltabular} + { + \chemmacros_if_package_loaded:nTF {xltabular} + { + \bool_if:nTF {#1} + { + \begin + {xltabular} + { \textwidth } + { @{}ll>{\raggedright\arraybackslash}X@{} } + } + { + \begin + {xltabular} + { \textwidth } + { @{}l>{\raggedright\arraybackslash}X@{} } + } + \seq_use:Nn \l__chemmacros_reactants_tmpa_seq { } + \end{xltabular} + } + { + \msg_expandable_error:nnnn + {chemmacros} + {package-not-loaded} + { \printreactants } + {xltabular} + } + } + {longtable} + { + \chemmacros_if_package_loaded:nTF {longtable} + { + \bool_if:nTF {#1} + { + \begin + {longtable}[l] + { @{}ll>{\raggedright\arraybackslash}p{0.6\textwidth}@{} } + } + { + \begin + {longtable}[l] + { @{}l>{\raggedright\arraybackslash}p{0.9\textwidth}@{} } + } + \seq_use:Nn \l__chemmacros_reactants_tmpa_seq { } + \end{longtable} + } + { + \msg_expandable_error:nnnn + {chemmacros} + {package-not-loaded} + { \printreactants } + {longtable} + } + } + } + } + { + \msg_warning:nn {chemmacros} {missing-printreactants-style} + } + \group_end: + } + +% #1: full ID +% #2: star, include ID in table +\cs_new_protected:Npn \chemmacros_reactants_list_subreactant:nn #1#2 + { + \chemnum_if_subcompounds:nT {#1} + { + \int_step_variable:nNn + { \chemnum_count_subcompounds:n {#1} } + \l__chemmacros_reactants_tmpa_tl + { + \seq_put_right:Nx + \l__chemmacros_reactants_tmpa_seq + { + \chemnum_cmpd:nnne { \c_false_bool } { \c_true_bool } {} + { + \exp_not:n {#1} + \exp_not:V \l_chemnum_compound_separator_tl + \chemnum_get_subcompound:nV + {#1} + \l__chemmacros_reactants_tmpa_tl + } + & + \bool_if:nT {#2} + { + #1 + \l_chemnum_compound_separator_tl + \chemnum_get_subcompound:nV + {#1} + \l__chemmacros_reactants_tmpa_tl + & + } + % TODO: expl3-command ?? + \solvent + { + #1 + \l_chemnum_compound_separator_tl + \chemnum_get_subcompound:nV + {#1} + \l__chemmacros_reactants_tmpa_tl + } + \tabularnewline + } + } + } + } +\cs_generate_variant:Nn \chemmacros_reactants_list_subreactant:nn {V} + +% -------------------------------------------------------------------------- +\ChemModuleEnd +\ChemModule{translations}{2022/01/16 translations for defined keys at one place} + +% -------------------------------------------------------------------------- +\chemmacros_declare_translations:nn {K-acid} + { + German = \mathrm {s} , + Danish = \mathrm {s} , + Dutch = \mathrm {z} + } + +\chemmacros_declare_translations:nn {K-acid} + { Danish = \mathrm {v} } + +% -------------------------------------------------------------------------- +\chemmacros_declare_translations:nn {phase-sld} + { + fallback = s , + German = f + } + +\chemmacros_declare_translations:nn {phase-lqd} + { + fallback = l , + German = f\/l + } + +\chemmacros_declare_translations:nn {phase-gas} + { fallback = g } + +\chemmacros_declare_translations:nn {phase-aq} + { fallback = aq } + +% -------------------------------------------------------------------------- +\chemmacros_declare_translations:nn {solution} + { + fallback = solution~ in , + English = solution~ in , + German = L\"osung~ in , + } + +% -------------------------------------------------------------------------- +\chemmacros_declare_translations:nn {list-of-reactions} + { + fallback = List~ of~ Reactions , + English = List~ of~ Reactions , + German = Reaktionsverzeichnis , + Italian = Elenco~ delle~ reazioni , + French = Table~ des~ r\'{e}actions , + Dutch = Lijst~ van~ reacties , + Norwegian = Reaksjonsliste , + Nynorsk = Reaksjonsliste , + Danish = Reaktionsliste + } + +\chemmacros_declare_translations:nn {reaction} + { + fallback = reaction , + English = reaction , + German = Reaktion , + Italian = reazione , + French = r\'{e}action , + Dutch = reactie , + Norwegian = reaksjon , + Nynorsk = reaksjon , + Danish = reaktion + } + +\chemmacros_declare_translations:nn {reactions} + { + fallback = reactions , + English = reactions , + German = Reaktionen , + Italian = reazioni , + French = r\'{e}actions , + Dutch = reacties , + Norwegian = reaksjoner , + Nynorsk = reaksjonar , + Danish = reaktioner + } + +\chemmacros_declare_translations:nn {Reaction} + { + fallback = Reaction , + English = Reaction , + German = Reaktion , + Italian = Reazione , + French = R\'{e}action , + Dutch = Reactie , + Norwegian = Reaksjon , + Nynorsk = Reaksjon , + Danish = Reaktion + } + +\chemmacros_declare_translations:nn {Reactions} + { + fallback = Reactions , + English = Reactions , + German = Reaktionen , + Italian = Reazioni , + French = R\'{e}actions , + Dutch = Reacties , + Norwegian = Reaksjoner , + Nynorsk = Reaksjonar , + Danish = Reaktioner + } + +% -------------------------------------------------------------------------- +\chemmacros_declare_translations:nn {scheme-name} + { + fallback = Scheme , + English = Scheme , + German = Schema , + Norwegian = Skjema , + Nynorsk = Skjema , + Danish = Skema + } + +\chemmacros_declare_translations:nn {scheme-list} + { + fallback = List~ of~ Schemes , + English = List~ of~ Schemes , + German = Verzeichnis~ der~ Schemata , + Norwegian = Skjemaliste , + Nynorsk = Skjemaliste , + Danish = Skemaliste + } + +\chemmacros_declare_translations:nn {scheme} + { + fallback = scheme , + English = scheme , + German = Schema , + Norwegian = skjema , + Nynorsk = skjema , + Danish = skema + } + +\chemmacros_declare_translations:nn {Scheme} + { + fallback = Scheme , + English = Scheme , + German = Schema , + Norwegian = Skjema , + Nynorsk = Skjema , + Danish = Skema + } + +\chemmacros_declare_translations:nn {schemes} + { + fallback = schemes , + English = schemes , + German = Schemata , + Norwegian = skjema , + Nynorsk = skjema , + Danish = skemaer + } + +\chemmacros_declare_translations:nn {Schemes} + { + fallback = Schemes , + English = Schemes , + German = Schemata , + Norwegian = Skjema , + Nynorsk = Skjema , + Danish = Skemaer + } -\file_input_stop: % -------------------------------------------------------------------------- -2020/02/03 - lazy boolean evaluation - - prefer the kernel commands to \chemmacros_leave_vmode: and - \chemmacros_tex_if: +\ChemModuleEnd |