% -------------------------------------------------------------------------- % the CHEMMACROS package % % comprehensive support for typesetting chemistry documents % % -------------------------------------------------------------------------- % Clemens Niederberger % -------------------------------------------------------------------------- % https://github.org/cgnieder/chemmacros/ % contact@mychemistry.eu % -------------------------------------------------------------------------- % If you have any ideas, questions, suggestions or bugs to report, please % feel free to contact me. % -------------------------------------------------------------------------- % Copyright 2011--2020 Clemens Niederberger % % This work may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.3 % of this license or (at your option) any later version. % The latest version of this license is in % http://www.latex-project.org/lppl.txt % and version 1.3 or later is part of all distributions of LaTeX % version 2005/12/01 or later. % % This work has the LPPL maintenance status `maintained'. % % The Current Maintainer of this work is Clemens Niederberger. % -------------------------------------------------------------------------- % The chemmacros package consists of the following files % - chemmacros.sty, chemmacros4.sty, chemmacros5.sty, % - chemmacros_en.tex, chemmacros_en.pdf, % - quite a number of module files following the naming scheme % chemmacros.module.*.code.tex % - README % -------------------------------------------------------------------------- \RequirePackage{expl3,xparse,l3keys2e} \ExplSyntaxOn % -------------------------------------------------------------------------- % package information: \ProvidesExplPackage {chemmacros5} {\c_chemmacros_date_tl} {\c_chemmacros_version_tl} {\c_chemmacros_info_tl \c_space_tl (CN)} % -------------------------------------------------------------------------- \msg_new:nnn {chemmacros} {package-option} { Unknown~ option~ `#1'!~ Since~ v5.0~ chemmacros~ has~ no~ package~ options~ any~ more! } \msg_new:nnn {chemmacros} {module-not-available} { The~ module~ `#1'~ is~ only~ available~ in~ compatibility~ mode~ #2~ or~ higher. } \cs_generate_variant:Nn \msg_warning:nnn { nnV } \keys_define:nn {chemmacros/package-options} { compatibility .code:n = , unknown .code:n = \msg_warning:nnV {chemmacros} {package-option} \CurrentOption } \ProcessKeysPackageOptions {chemmacros/package-options} % -------------------------------------------------------------------------- % messages: \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} { (chemmacros) \c_space_tl \c_space_tl \c_space_tl \c_space_tl Loading~ module~ `#1'... } % -------------------------------------------------------------------------- % variants of kernel functions: \cs_generate_variant:Nn \tl_if_eq:nnTF {xx,V} \cs_generate_variant:Nn \seq_set_split:Nnn {Nnx} \cs_generate_variant:Nn \prop_item:Nn {NV} \cs_generate_variant:Nn \seq_item:Nn {cV} \cs_generate_variant:Nn \int_to_arabic:n {V} \cs_generate_variant:Nn \tl_replace_once:Nnn {NnV} \cs_generate_variant:Nn \prop_gput:Nnn {cxx,NVf} \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 \vbox_set:Nn {NV} \cs_generate_variant:Nn \keys_define:nn {x} \cs_generate_variant:Nn \keys_set:nn {x,nx} % -------------------------------------------------------------------------- % 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: \tl_const:Nn \c__chemmacros_module_extension_tl {code.tex} \tl_const:Nn \c__chemmacros_module_prefix_tl {chemmacros.module} \seq_new:N \g__chemmacros_loaded_modules_seq \prop_new:N \g__chemmacros_loaded_modules_prop \cs_new_protected:Npn \chemmacros_load_modules:n #1 { \clist_map_inline:nn {#1} { \chemmacros_load_module:n {##1} } } \cs_new_protected:Npn \chemmacros_load_module:n #1 { \tl_set:Nx \l__chemmacros_tmpa_tl { \tl_trim_spaces:n {#1} } \__chemmacros_load_module:V \l__chemmacros_tmpa_tl } \cs_new_protected:Npn \__chemmacros_load_module:n #1 { \chemmacros_if_module_loaded:nF {#1} { \chemmacros_if_module_exist:nTF {#1} { \__chemmacros_use_module_hook:nn {#1} {before} \msg_log:nnn {chemmacros} {loading-module} {#1} \@onefilewithoptions {\c__chemmacros_module_prefix_tl.#1}[][] \c__chemmacros_module_extension_tl \__chemmacros_use_module_hook:nn {#1} {after} } { \msg_error:nnn {chemmacros} {module-missing} {#1} } } } \cs_generate_variant:Nn \__chemmacros_load_module:n { V } \prg_new_conditional:Npnn \chemmacros_if_module_loaded:n #1 {p,T,F,TF} { \seq_if_in:NnTF \g__chemmacros_loaded_modules_seq {#1} { \prg_return_true: } { \prg_return_false: } } \prg_new_conditional:Npnn \chemmacros_if_module_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: } } % -------------------------------------------------------------------------- \ChemCompatibilityFrom{5.1} % module hooks: % #1: module % #2: code \cs_new_protected:Npn \chemmacros_after_module:nn #1#2 { \chemmacros_if_module_loaded:nTF {#1} {#2} { \__chemmacros_add_to_module_hook:nnn {#1} {after} {#2} } } % #1: module % #2: code \cs_new_protected:Npn \chemmacros_before_module:nn #1#2 { \chemmacros_if_module_loaded:nF {#1} { \__chemmacros_add_to_module_hook:nnn {#1} {before} {#2} } } \EndChemCompatibility % #1: module % #2: hook name % #3: code \cs_new_protected:Npn \__chemmacros_add_to_module_hook:nnn #1#2#3 { \chemmacros_if_module_loaded:nF {#1} { \tl_if_exist:cF {g__chemmacros_module_#1_#2_hook_tl} { \tl_new:c {g__chemmacros_module_#1_#2_hook_tl} } \tl_gput_right:cn {g__chemmacros_module_#1_#2_hook_tl} {#3} } } % #1: module % #2: hook name \cs_new_protected:Npn \__chemmacros_use_module_hook:nn #1#2 { \tl_if_exist:cT {g__chemmacros_module_#1_#2_hook_tl} { \tl_use:c {g__chemmacros_module_#1_#2_hook_tl} \tl_gclear:c {g__chemmacros_module_#1_#2_hook_tl} } } % -------------------------------------------------------------------------- \cs_new_protected:Npn \__chemmacros_module:nnnn #1#2#3#4 { \chemmacros_if_compatibility:nnF {>=} {#4} { \msg_warning:nnnn {chemmacros} {module-not-available} {#2} {#4} \file_input_stop: } \seq_gput_right:Nn \g__chemmacros_loaded_modules_seq {#2} \prop_gput:Nnn \g__chemmacros_loaded_modules_prop {#2} {#3} \ProvidesFile {\c__chemmacros_module_prefix_tl.#2.\c__chemmacros_module_extension_tl} [ \c_chemmacros_date_tl \c_space_tl v \c_chemmacros_version_tl \c_space_tl chemmacros~ module~ `#2'~ #3 ] \bool_if:nF {#1} { \ExplSyntaxOn } } % define a chemmacros module: % 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: boolean % #2: name % #3: description \NewDocumentCommand \ChemModule {smmO{5.0}} { \__chemmacros_module:nnnn {#1} {#2} {#3} {#4} } % -------------------------------------------------------------------------- % command for loading modules: \NewDocumentCommand \usechemmodule {m} { \chemmacros_load_modules:n {#1} } % -------------------------------------------------------------------------- % load default modules: \chemmacros_load_modules:n { % required modules: base, errorcheck, lang, greek, chemformula, % preloaded modules: acid-base, symbols, charges, particles, phases , nomenclature } % -------------------------------------------------------------------------- \file_input_stop: % -------------------------------------------------------------------------- Modules: (* = preloaded) - internal modules: - base * - errorcheck * - lang * - greek * - chemformula * - tikz - user modules: - acid-base * - all - charges * - isotopes - mechanisms - newman - nomenclature * - orbital - particles * - phases * - reactions - redox - scheme - spectroscopy - symbols * - thermodynamics - units - xfrac % -------------------------------------------------------------------------- Version history 2015/08/29 - initial release v5.0 2015/09/23 - add module hooks `before' and `after' - allow to give minimal compatibility version to a module: this should be the first version when a module is published and shouldn't be changed any more; loading the corresponding module will abort when compatibility is too low - store loaded modules in a seq and in a prop 2015/10/14 - bug fix in the module hook mechanism - bug fix in \chemmacros_if_module_loaded:n - new `errorcheck' module 2020/02/03 - add temporary string variables