% -------------------------------------------------------------------------- % the CHEMMACROS package v6.2a 2022/03/12 % % comprehensive support for typesetting chemistry documents % % -------------------------------------------------------------------------- % Web: https://github.org/cgnieder/chemmacros/ % E-Mail: chemmacros@cnltx.de % -------------------------------------------------------------------------- % If you have any ideas, questions, suggestions or bugs to report, please % feel free to contact us. % -------------------------------------------------------------------------- % Copyright 2011--2021 Clemens Niederberger % 2022-- Clemens Niederberger & Sonja K. % % This work may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.3c % 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. % % This work has the LPPL maintenance status `maintained'. % % The Current Maintainers of this work are Clemens Niederberger and Sonja K. % -------------------------------------------------------------------------- \RequirePackage {l3keys2e} \DeclareRelease {v4} {2015-02-08} {chemmacros-2015-02-08.sty} \DeclareRelease {v5} {2020-03-07} {chemmacros-2020-03-07.sty} \ExplSyntaxOn % -------------------------------------------------------------------------- % package information: \tl_const:Nn \c_chemmacros_date_tl {2022/03/11} \tl_const:Nn \c_chemmacros_version_major_number_tl {6} \tl_const:Nn \c_chemmacros_version_minor_number_tl {2} \tl_const:Nn \c_chemmacros_version_subrelease_tl {a} \tl_const:Nx \c_chemmacros_version_number_tl { \c_chemmacros_version_major_number_tl . \c_chemmacros_version_minor_number_tl } \tl_const:Nx \c_chemmacros_version_tl { \c_chemmacros_version_number_tl \c_chemmacros_version_subrelease_tl } \tl_const:Nn \c_chemmacros_info_tl {comprehensive~ support~ for~ typesetting~ chemistry~ documents} \ProvidesExplPackage {chemmacros} {\c_chemmacros_date_tl} {\c_chemmacros_version_tl} {\c_chemmacros_info_tl \c_space_tl (CN~ &~ SK)} \DeclareCurrentRelease{}{\c_chemmacros_date_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} \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,nnnxx} \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, formula, charges, acid-base, symbols, particles, phases, nomenclature, tikz, xfrac, translations } \clist_const:Nn \c_chemmacros_all_modules_clist { base, errorcheck, lang, greek, formula, charges, acid-base, symbols, particles, phases, nomenclature, tikz, isotopes, mechanisms, newman, orbital, polymers, reactions, redox, xfrac, scheme, spectroscopy, thermodynamics, units, reactants, translations } \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}} } \keys_define:nn {chemmacros/load-time} { minimal .bool_set:N = \l__chemmacros_minimal_bool , minimal .initial:n = false , modules .code:n = \clist_if_in:NnF \l_chemmacros_modules_clist {#1} { \clist_put_right:Nn \l_chemmacros_modules_clist {#1} } , stop .code:n = \clist_map_inline:nn {#1} { \chemmacros_stop_module:n {##1} } , unknown .code:n = \__chemmacros_loadtime_warning:n {unknown-option} } \ProcessKeysPackageOptions {chemmacros/load-time} \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} , load-time / minimal .meta:nn = {chemmacros} {minimal} , load-time / 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. } \msg_new:nnn {chemmacros} {before-module} { The~ module~ `#1'~ has~ already~ been~ loaded.~ The~ code~ cannot~ be~ inserted~ before~ it~ \msg_line_context: } % ---------------------------------------------------------------------------- \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: } } % ---------------------------------------------------------------------------- % deprecation & removal \msg_new:nnn {chemmacros} {deprecated} { On~ line~ \msg_line_number: : \\ The~ #1~ `#2'~ is~ deprecated.~ Use~ #1~ `#3'~ instead . } \msg_new:nnn {chemmacros} {deprecated-function} { The~ command~ #1~ is~ deprecated.~ Use~ #2 instead . } \msg_new:nnn {chemmacros} {removed-function} { The~ command~ #1~ has~ been~ removed. } \msg_new:nnn {chemmacros} {removed} { On~ line~ \msg_line_number: : \\ The~ #1~ `#2'~ has~ been~ removed~ from~ chemmacros. \\ If~ you~ need~ it~ back~ please~ open~ an~ issue~ on~ \\ https://github.com/cgnieder/chemmacros/issues \tl_if_blank:nF {#3} { \\ #3 } } % #1: type % #2: old % #3: new \cs_new_protected:Npn \__chemmacros_deprecation_warning:nnn #1#2#3 { \msg_warning:nnnnn {chemmacros} {deprecated} {#1} {#2} {#3} } \cs_generate_variant:Nn \__chemmacros_deprecation_warning:nnn {nne,nV} % #1: type % #2: old % #3: additional text \cs_new_protected:Npn \chemmacros_removal_warning:nnn #1#2#3 { \msg_warning:nnnnn {chemmacros} {removed} {#1} {#2} {#3} } \cs_generate_variant:Nn \chemmacros_removal_warning:nnn {nV} % #1: type % #2: old \cs_new_protected:Npn \chemmacros_removal_warning:nn #1#2 { \msg_warning:nnnn {chemmacros} {removed} {#1} {#2} } \cs_generate_variant:Nn \chemmacros_removal_warning:nn {nV} % #1: new \cs_new_protected:Npn \chemmacros_deprecate_option:n #1 { \__chemmacros_deprecation_warning:nVn {option} \l_keys_key_str {#1} } \cs_new_protected:Npn \chemmacros_deprecate_option: { \__chemmacros_deprecation_warning:nV {option} \l_keys_key_str } % #1: additional text \cs_new_protected:Npn \chemmacros_remove_option:n #1 { \chemmacros_removal_warning:nVn {option} \l_keys_key_str {#1} } \cs_new_protected:Npn \chemmacros_remove_option: { \chemmacros_removal_warning:nV {option} \l_keys_key_str } % #1: old % #2: new \cs_new_protected:Npn \chemmacros_deprecate_function:NN #1#2 { \cs_set_protected:Npn #1 { \msg_error:nnnn {chemmacros} {deprecated-function} {#1} {#2} #2 } } % #1: old \cs_new_protected:Npn \chemmacros_remove_function:N #1 { \cs_set_protected:Npn #1 { \msg_error:nnn {chemmacros} {removed-function} {#1} } } \NewDocumentCommand \DeclareChemDeprecated {mm} { \chemmacros_deprecate_function:NN #1 #2 } % ---------------------------------------------------------------------------- % 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.style} \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_log:nnn {chemmacros} {loading-module} {#1} \msg_term: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 { \chemmacros_module_if_loaded:nTF {#1} { \msg_error:nnn {chemmacros} {before-module} {#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} % -------------------------------------------------------------------------- \cs_new_protected:Npn \__chemmacros_module:nn #1#2 { \str_if_in:NnT \g__chemmacros_module_stop_tl {{#1}} { \file_input_stop: } \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} } \tl_if_blank:nTF {#2} { \ProvidesFile {\c__chemmacros_module_prefix_tl.#1.\c__chemmacros_module_extension_tl} } { \ProvidesFile {\c__chemmacros_module_prefix_tl.#1.\c__chemmacros_module_extension_tl} [#2] } } % define a chemmacros style: % standard modules are written in the expl3 programming environment, the % starred version only uses a 2e programming environment, i.e., with @ as a % letter % #1: name % #2: description \NewDocumentCommand \ChemStyle {smo} { \IfNoValueTF {#3} { \__chemmacros_module:nn {#2} {#3} } { \__chemmacros_module:nn {#2} {} } \bool_if:nF {#1} { \ExplSyntaxOn } } % command for loading styles: \NewDocumentCommand \usechemstyle {m} { \chemmacros_modules_load:n {#1} } % -------------------------------------------------------------------------- % define internal chemmacros modules: \tl_new:N \g_chemmacros_module_tl % #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:nnn {chemmacros} {loading-module} {#1} \msg_term:nnn {chemmacros} {loading-module} {#1} \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} {patch-failed} { I~ failed~ to~ patch~ \token_to_str:N #1 .~ Please~ contact~ the~ package~ author. } % -------------------------------------------------------------------------- % 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 {e,ne} \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} % -------------------------------------------------------------------------- \cs_new_protected:Npn \chemmacros_patch_cmd:Nnn #1#2#3 { \patchcmd #1 {#2} {#3} {} { \msg_warning:nnn {chemmacros} {patch-failed} {#1} } } % -------------------------------------------------------------------------- % #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 { \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} } % -------------------------------------------------------------------------- \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/23 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} % reactants module \chemmacros_command_requires_module:Nn \DeclareChemReactant {reactants} \chemmacros_command_requires_module:Nn \reactant {reactants} \chemmacros_command_requires_module:Nn \reactants {reactants} \chemmacros_command_requires_module:Nn \reactantl {reactants} \chemmacros_command_requires_module:Nn \Reactant {reactants} \chemmacros_command_requires_module:Nn \solvent {reactants} \chemmacros_command_requires_module:Nn \solvents {reactants} \chemmacros_command_requires_module:Nn \solventl {reactants} \chemmacros_command_requires_module:Nn \Solvent {reactants} \chemmacros_command_requires_module:Nn \reactantplain {reactants} \chemmacros_command_requires_module:Nn \Reactantplain {reactants} \chemmacros_command_requires_module:Nn \submainreactantplain {reactants} \chemmacros_command_requires_module:Nn \Submainreactantplain {reactants} \chemmacros_command_requires_module:Nn \solventplain {reactants} \chemmacros_command_requires_module:Nn \Solventplain {reactants} \chemmacros_command_requires_module:Nn \printreactants {reactants} % 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}{2022/03/05 language settings for chemmacros} \RequirePackage{translations} \hook_gset_rule:nnnn {begindocument/before} {translations} {before} {chemmacros} \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. } \msg_new:nnn {chemmacros} {missing-translation} { The~ tranlation~ for~ key~ `#1'~ and~ language~ `#2'~ is~ missing~ \mgs_context_line: } \msg_new:nnn {chemmacros} {missing-translation-alt} { The~ tranlation~ for~ key~ `#2'~ and~ language~ `#1'~ is~ missing~ \mgs_context_line: } % -------------------------------------------------------------------------- % 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 } { \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 } } % -------------------------------------------------------------------------- % #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: { = , = } \cs_new_protected:Npn \chemmacros_declare_translations:nn #1#2 { \keyval_parse:nnn { \msg_warning:nnnn {chemmacros} {missing-translation} {#1} } { \chemmacros_declare_translation:nnn {#1} } {#2} } % #1: lang % #2: key % #3: translation \cs_new_protected:Npn \chemmacros_add_translation:nnn #1#2#3 { \chemmacros_declare_translation:nnn {#2} {#1} {#3} } % #1: language % #2: csv list: { = , = } \cs_new_protected:Npn \chemmacros_add_translations:nn #1#2 { \keyval_parse:nnn { \msg_warning:nnnn {chemmacros} {missing-translation-alt} {#1} } { \chemmacros_add_translation:nnn {#1} } {#2} } % #1: key % #2: lang % #3: translation \NewDocumentCommand \DeclareChemTranslations {mm} { \chemmacros_declare_translations:nn {#1} {#2} } \@onlypreamble \DeclareChemTranslations % #1: key % #2: csv list: { = , = } \NewDocumentCommand \DeclareChemTranslation {mmm} { \chemmacros_declare_translation:nnn {#1} {#2} {#3} } \@onlypreamble \DeclareChemTranslation % #1: lang % #2: csv list: { = , = } \NewDocumentCommand \AddChemTranslations {mm} { \chemmacros_add_translations:nn {#1} {#2} } \@onlypreamble \AddChemTranslations % #1: lang % #2: key % #3: translation \NewDocumentCommand \AddChemTranslation {mmm} { \chemmacros_add_translation:nnn {#1} {#2} {#3} } \@onlypreamble \AddChemTranslation % -------------------------------------------------------------------------- \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{formula}{2022/01/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-method} { Using~ the~ formula~ method~ `#1'. } \msg_new:nnn {chemmacros} {formula-conflict} { You~ have~ loaded~ both~ `chemformula'~ and~ `mhchem'~ as~ formula~ package~ but~ haven't~ chosen~ which~ formula~ 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_formula:n #1 {#1} \cs_generate_variant:Nn \chemmacros_formula:n { x,V,e } \chemmacros_deprecate_function:NN \chemmacros_chemformula:n \chemmacros_formula:n \cs_new_protected:Npn \chemmacros@formula #1 { \chemmacros_formula: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_formula_methods_prop % #1: package/method name % #2: preparations \cs_new_protected:Npn \chemmacros_add_formula_method:nn #1#2 { \prop_put:Nnn \l__chemmacros_formula_methods_prop {#1} {#2} } \cs_new_protected:Npn \chemmacros_setup_formula_method:n #1 { \prop_item:Nn \l__chemmacros_formula_methods_prop {#1} \tl_gset:Nn \g_chemmacros_formula_method_tl {#1} } \prg_new_conditional:Npnn \chemmacros_if_formula_method:n #1 {p,T,F,TF} { \prop_if_in:NnTF \l__chemmacros_formula_methods_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 \clist_map_inline:nn {chemformula,mhchem} { \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_formula_method:nTF {#1} { \chemmacros_setup_formula_method:n {#1} } { \msg_warning:nnn {chemmacros} {unknown-formula-method} {#1} \chemmacros_setup_formula_method: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_formula_method:nn {chemformula} { \chemmacros_integrate_package:nnn {} {chemformula} {2022/01/23} \cs_set_protected:Npn \chemmacros_formula:n #1 { \chemformula_chcpd:nn {} {#1} } \cs_set_protected:Npn \chemmacros_reaction:n #1 { \chemformula_ch:nn {} {#1} } } \chemmacros_add_formula_method:nn {mhchem} { \chemmacros_integrate_package:nnn {version=4} {mhchem} {} \cs_set_protected:Npn \chemmacros_formula: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_formula_method:nn {chemist} { \RequirePackage {chemist} \cs_set_protected:Npn \chemmacros_formula: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_formula_method:nn {chemfig} { \RequirePackage {chemfig} \cs_set_protected:Npn \chemmacros_formula:n #1 { \printatom {#1} } \cs_set_protected:Npn \chemmacros_reaction:n #1 { \schemestart #1 \schemestop } \chemmacros_module_after:nn {charges} { \cs_set_protected:Npn \chemmacros_elpair:n #1 { \Charge { 0=\: } {#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} { \chemmacros_check_formula_method: } % -------------------------------------------------------------------------- \ChemModuleEnd \ChemModule{charges}{2022/01/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_formula: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/29 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 { \chemmacros_p_style:n {p} \ensuremath {#1} } \group_end: } \NewDocumentCommand \p {m} { \chemmacros_p:n {#1} } \NewDocumentCommand \pH {} { \chemmacros_p:n { \chemmacros_formula:n {H} } } \NewDocumentCommand \pOH {} { \chemmacros_p:n { \chemmacros_formula: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} } } } } % -------------------------------------------------------------------------- \ChemModuleEnd \ChemModule{symbols}{2020/11/29 symbols} \RequirePackage{amstext} % --------------------------------------------------------------------------- % transition state symbol \cs_new_protected:Npn \__chemmacros_transition_state: { \text { \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: \circ } \cs_new_protected:Npn \__chemmacros_standardstate: #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}{2022/01/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_formula: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_formula:n { {}^{-} } } { \chemmacros_formula: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}{2022/03/03 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 { \ensuremath { \c_math_subscript_token { \chemmacros_text: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/29 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_new_protected:Npn \chemmacros_new_iupac:Nn #1#2 { \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_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_protected:Npn \chemmacros_make_iupac: { \chemmacros_if_document:T { \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 } % -------------------------------------------------------------------------- % 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} \tl_new:N \l__chemmacros_cip_inner_tl \tl_new:N \l__chemmacros_cip_outer_tl \tl_new:N \l__chemmacros_cip_number_tl \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_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 } \DeclareChemIUPAC \cip { \chemmacros_cip:n } % remember: TikZ needs : to be other \cs_new_protected:Npn \chemmacros_sconf:n #1 { \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_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 % #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 { \chemmacros_formula:n {#3} \tl_if_blank:nF {#4} { \bool_if:nTF {#2} { \chemmacros_formula:n { {}^{#4} } } { \chemmacros_formula:n { {}_{#4} } } } \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 } % #1: pre break % #2: post break % #3: no break \cs_new_protected:Npn \__chemmacros_peek_if_dash:TF #1#2 { \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 } \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_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 } % -------------------------------------------------------------------------- \tl_new:N \l__chemmacros_iupac_format_tl \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_iupac_format_tl { \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} } % -------------------------------------------------------------------------- \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 % 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} } \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} } } \NewDocumentCommand \latin {O{}m} { \group_begin: \chemmacros_set_keys:nn {nomenclature} {#1} \chemmacros_latin:n {#2} \group_end: } \cs_undefine:N \invacuo \NewChemLatin \invacuo {in~vacuo} \NewChemLatin \abinitio {ab~initio} \NewChemLatin \insitu {in~situ} % -------------------------------------------------------------------------- \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 , iupac-format .tl_set:N = \l__chemmacros_iupac_format_tl , cip-kern .dim_set:N = \l__chemmacros_cip_kern_dim , 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 , 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 , 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 , latin-format .tl_set:N = \l__chemmacros_latin_format_tl , latin-format .initial:n = \emph , format .code:n = \chemmacros_deprecate_option:n {latin-format} } % -------------------------------------------------------------------------- % 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 {'} } } % -------------------------------------------------------------------------- \ChemModuleEnd \ChemModule{tikz}{2020/11/29 ease usage of TikZ in chemmacros} \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}{2022/01/29 a macro to easily print element isotopes} \RequirePackage{elements} \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 % #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_formula:n { ^{#1}_{#2}#3 } } { \chemmacros_formula:n {#3} \tl_use:N \l__chemmacros_isotope_side_connect_tl #1 } } \cs_generate_variant:Nn \chemmacros_isotope_write:nnn {VnV,VVV,nnV,nVV} \NewDocumentCommand \isotope {sm} { \chemmacros_isotope:nn {#1} {#2} } % -------------------------------------------------------------------------- \ChemModuleEnd \ChemModule{mechanisms}{2020/11/29 reaction mechanisms} \RequirePackage{amstext} % -------------------------------------------------------------------------- % reaction mechanisms % \mech[] % - 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[](){<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[]{} % 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/03/11 reaction environments} \newcounter {reaction} \hook_gput_code:nnn {package/hyperref/after} {chemmacros} { \cs_if_exist:NTF \chapter { \cs_set:Npn \theHreaction { \theHchapter . \thereaction } } { \cs_set:Npn \theHreaction { \theHsection . \thereaction } } } \bool_new:N \l__chemmacros_reactions_counter_bool \bool_new:N \l__chemmacros_reactions_tocbasic_bool \cs_new_eq:NN \l@reaction \l@figure \cs_if_exist:NT \KOMAClassName { \bool_set_true:N \l__chemmacros_reactions_tocbasic_bool } \tl_new:N \g__chemmacros_reaction_description_tl \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 \tl_new:N \l__chemmacros_reaction_lorname_tl \tl_new:N \reactionlistname \tl_new:N \reactionautorefname \tl_new:N \l__chemmacros_reactions_args_tl % -------------------------------------------------------------------------- \RequirePackage{mathtools} % 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... \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: } } \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 (but disturbs hyperref): \__chemmacros_record_for_lor:nnnnn {#1} {#3} {#2} {##1} {#4} } } } % -------------------------------------------------------------------------- % create new tagform \newtagform {reaction} [\l__chemmacros_reactions_before_tag_tl] {\l__chemmacros_reactions_tag_open_tl} {\l__chemmacros_reactions_tag_close_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 \cs_new_protected:Npn \__chemmacros_reaction_heading:n #1 {#1} \cs_generate_variant:Nn \__chemmacros_reaction_heading:n {V} \cs_new_protected:Npn \listofreactions { \__chemmacros_reaction_heading:V \reactionlistname \@starttoc {lor} } \hook_gput_code:nnn {package/tocbasic/after} {chemmacros} { \addtotoclist [float] {lor} \cs_set_protected:Npn \listofreactions { \listoftoc {lor} } \cs_new:Npn \listoflorname { \reactionlistname } } % -------------------------------------------------------------------------- % cleveref: \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} { \l__chemmacros_reactions_tag_open_tl #2 #1 #3 \l__chemmacros_reactions_tag_close_tl } } % fancyref: \hook_gput_code:nnn {package/fancyref/after} {chemmacros} { \cs_set:Npn \fancyrefrctlabelprefix {rct} \cs_set:Npn \frefrctname { \chemmacros_translate:n {reaction} } \cs_set:Npn \Frefrctname { \chemmacros_translate:n {Reaction} } \frefformat {vario} { \fancyrefrctlabelprefix } { \frefrctname \fancyrefdefaultspacing \textup { \l__chemmacros_reactions_tag_open_tl #1 \l__chemmacros_reactions_tag_close_tl } #3 } \Frefformat {vario} { \fancyrefrctlabelprefix } { \Frefrctname \fancyrefdefaultspacing \textup { \l__chemmacros_reactions_tag_open_tl #1 \l__chemmacros_reactions_tag_close_tl } #3 } \frefformat {plain} { \fancyrefrctlabelprefix } { \frefrctname \fancyrefdefaultspacing #1 } \Frefformat {plain} { \fancyrefrctlabelprefix } { \Frefrctname \fancyrefdefaultspacing #1 } } % -------------------------------------------------------------------------- % begin and end reaction environments: switch to reaction counter: \cs_new_protected:Npn \__chemmacros_begin_reaction: { \bool_if:NT \l__chemmacros_reactions_counter_bool { \chemmacros_patch_cmd:Nnn \thereaction {reaction} {equation} \cs_set_eq:NN \r@equation \r@reaction \cs_set_eq:NN \p@equation \p@reaction \cs_set_eq:NN \c@equation \c@reaction \cs_set_eq:NN \theequation \thereaction \chemmacros_if_package_loaded:nT {cleveref} { \crefalias {equation} {reaction} } % this only works if nobody steps counters inside reactions: \bool_if:NT \l__chemmacros_hyperref_bool { \chemmacros_patch_cmd:Nnn \hyper@refstepcounter { \This@name } { \This@name {reaction} \@gobble } \chemmacros_patch_cmd:Nnn \hyper@refstepcounter { \hyper@makecurrent } { \hyper@makecurrent {reaction} \@gobble } } \usetagform {reaction} } } \cs_new_protected:Npn \__chemmacros_end_reaction: { } % -------------------------------------------------------------------------- \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 { \tl_clear:N \l__chemmacros_reactions_args_tl \int_compare:nNnT {#3+0} > {0} { \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} \chemmacros_define_keys:nn {reactions} { list-name .tl_set:N = \reactionlistname , list-name .initial:n = \chemmacros_translate:n {list-of-reactions} , autoref-name .tl_set:N = \reactionautorefname , autoref-name .initial:n = \chemmacros_translate:n {Reaction} , list-entry .tl_set:N = \l__chemmacros_reaction_lorname_tl , list-entry .initial:n = \chemmacros_translate:n {Reaction} , list-heading-cmd .cs_set:Np = \__chemmacros_reaction_heading:n #1 , tocbasic .code:n = \chemmacros_deprecate_option: , own-counter .bool_set:N = \l__chemmacros_reactions_counter_bool , own-counter .initial:n = true , 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 } \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} } } \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}{2022/01/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{,} \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 { \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_formula: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[]{,} % \ox*[]{,} => 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{,} \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/02/05 a scheme floating environment} \RequirePackage {chemnum} \RequirePackage {etoolbox} \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} { Using~ float~ defining~ method~ `#1'. } \msg_new:nnn {chemmacros} {unknown-method} { The~ float~ method~ `#1'~ is~ not~ known~ \msg_line_contect: .~ Ckeck~ for~ a~ typo. } % -------------------------------------------------------------------------- % #1: name % #2: check % #3: code \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 { \msg_info:nnn {chemmacros} {float-method} {#1} #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}} } } \chemmacros_define_float_method:nnn {traditional} { \c_false_bool } { \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 } } \chemmacros_patch_cmd:Nnn \@chapter { \addtocontents } { \addtocontents {#2} { \protect \addvspace {10\p@} } \addtocontents } } { \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 } % -------------------------------------------------------------------------- \chemmacros_define_keys:nn {scheme} { float-method .code:n = \seq_if_in:NnTF \l__chemmacros_float_methods_seq {#1} { \bool_set_true:N \l__chemmacros_float_def_bool \tl_set:Nn \l__chemmacros_float_method_tl {#1} } { \msg_error:nnn {chemmacros} {unknown-method} {#1} } } % -------------------------------------------------------------------------- % 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_if:nT { \l__chemmacros_tmpa_tl } { \bool_set_true:N \l__chemmacros_float_def_bool \tl_set:Nn \l__chemmacros_float_method_tl {#1} } } } \cs_new_protected:Npn \chemmacros_check_float_methods: { \bool_if:NF \l__chemmacros_float_def_bool { \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} } } % #1: env name % #2: file ending \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} } { \prop_get:NnN \l__chemmacros_float_definitions_prop {traditional} \l__chemmacros_tmpa_tl \tl_use:N \l__chemmacros_tmpa_tl \__chemmacros_define_float:nn {#1} {#2} } \cs_set:cpn {#1name} {\chemmacros_translate:n {#1-name}} \cs_set:cpn {list#1name} {\chemmacros_translate:n {#1-list}} } } % -------------------------------------------------------------------------- \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} ] % -------------------------------------------------------------------------- \ChemModuleEnd \ChemModule{spectroscopy}{2022/01/29 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_formula:n { ^{#1} } \tl_if_blank:VF \g__chemmacros_nmr_element_coupled_tl { \bool_if:NTF \l__chemmacros_nmr_parse_bool { \chemmacros_formula: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{,}(,)[] 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_formula: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_formula: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_formula:V \g__chemmacros_nmr_element_tl } \cs_new_protected:Npn \chemmacros_nmr_position:n #1 { \chemmacros_formula:e { \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_formula: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_formula: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: } % -------------------------------------------------------------------------- \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} { 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} } \cs_new_protected:Npn \chemmacros_state:nnnnnn #1#2#3#4#5#6 { \group_begin: \chemmacros_set_keys:ne {thermodynamics} { \exp_not:n {#1} , \tl_if_novalue:nF {#2} { subscript-left = \exp_not:n {#2} , } \tl_if_novalue:nF {#3} { superscript-left = \exp_not:n {#3} , } \tl_if_novalue:nF {#5} { subscript-right = \exp_not:n {#5} , } \tl_if_novalue:nF {#6} { superscript-right = \exp_not:n {#6} } } \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 } #4 \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:nnnnnn {nVVVVV} \exp_args:NNe \NewDocumentCommand \state { O{}e{\char_generate:nn {`_}{8}^}me{\char_generate:nn {`_}{8}^} } { \use:c {chemmacros_state:nnnnnn} {#1} {#2} {#3} {#4} {#5} {#6} } \cs_new_protected:Npn \chemmacros_declare_state:Nn #1#2 { \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:en {thermodynamics/\chemmacros_remove_backslash:N #1} {#2} \tl_if_blank:nF {##3} { \chemmacros_set_keys:ne {thermodynamics} { subscript-\l__chemmacros_state_sb_pos_tl = \exp_not:n {##3} } } \ensuremath { \chemmacros_state:nVVVVV {##2} \c_novalue_tl \c_novalue_tl \l__chemmacros_state_symbol_tl \c_novalue_tl \c_novalue_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} } % -------------------------------------------------------------------------- % 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} { \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} } % -------------------------------------------------------------------------- % #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 { \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: } % #1: options % #2: key \cs_new_protected:Npn \chemmacros_solvent_name:nn #1#2 { \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} ~ } } % -------------------------------------------------------------------------- % #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/02/24 translations for defined keys at one place} \chemmacros_add_translations:nn {fallback} { phase-sld = s , phase-lqd = l , phase-gas = g , phase-aq = aq , solution = solution~ in , list-of-reactions = List~ of~ Reactions , reaction = reaction , reactions = reactions , Reaction = Reaction , Reactions = Reactions , scheme-name = Scheme , scheme-list = List~ of~ Schemes , scheme = scheme , schemes = schemes , Scheme = Scheme , Schemes = Schemes } \chemmacros_add_translations:nn {German} { K-acid = \mathrm {s} , phase-sld = f , phase-lqd = f\/l , solution = L\"osung~ in , list-of-reactions = Reaktionsverzeichnis , reaction = Reaktion , reactions = Reaktionen , Reaction = Reaktion , Reactions = Reaktionen , scheme-name = Schema , scheme-list = Verzeichnis~ der~ Schemata , scheme = Schema , schemes = Schemata , Scheme = Schema , Schemes = Schemata } \chemmacros_add_translations:nn {Danish} { K-acid = \mathrm {s} , K-water = \mathrm {v} , list-of-reactions = Reaktionsliste , reaction = reaktion , reactions = reaktioner , Reaction = Reaktion , Reactions = Reaktioner , scheme-name = Skema , scheme-list = Skemaliste , scheme = skema , schemes = skemaer , Scheme = Skema , Schemes = Skemaer } \chemmacros_add_translations:nn {Dutch} { K-acid = \mathrm {z} , list-of-reactions = Lijst~ van~ reacties , reaction = reactie , reactions = reacties , Reaction = Reactie , Reactions = Reacties } \chemmacros_add_translations:nn {Italian} { list-of-reactions = Elenco~ delle~ reazioni , reaction = reazione , reactions = reazioni , Reaction = Reazione , Reactions = Reazioni } \chemmacros_add_translations:nn {French} { list-of-reactions = Table~ des~ r\'{e}actions , reaction = r\'{e}action , reactions = r\'{e}actions , Reaction = R\'{e}action , Reactions = R\'{e}actions } \chemmacros_add_translations:nn {Norwegian} { list-of-reactions = Reaksjonsliste , reaction = reaksjon , reactions = reaksjoner , Reaction = Reaksjon , Reactions = Reaksjoner , scheme-name = Skjema , scheme-list = Skjemaliste , scheme = skjema , schemes = skjema , Scheme = Skjema , Schemes = Skjema } \chemmacros_add_translations:nn {Nynorsk} { reactions = reaksjonar , Reactions = Reaksjonar } \ChemModuleEnd