diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/substances/substances.sty |
Initial commit
Diffstat (limited to 'macros/latex/contrib/substances/substances.sty')
-rw-r--r-- | macros/latex/contrib/substances/substances.sty | 590 |
1 files changed, 590 insertions, 0 deletions
diff --git a/macros/latex/contrib/substances/substances.sty b/macros/latex/contrib/substances/substances.sty new file mode 100644 index 0000000000..5ef0a4cb68 --- /dev/null +++ b/macros/latex/contrib/substances/substances.sty @@ -0,0 +1,590 @@ +% -------------------------------------------------------------------------- +% the SUBSTANCES package +% +% A Chemical Database +% +% -------------------------------------------------------------------------- +% Clemens Niederberger +% Web: https://bitbucket.org/cgnieder/substances/ +% E-Mail: contact@mychemistry.eu +% -------------------------------------------------------------------------- +% Copyright 2012--2016 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 substances package consists of the files +% - substances.sty, substances-default.def, substances-examples.sub, +% substances_en.tex, substances_en.pdf, README +% -------------------------------------------------------------------------- +% If you have any ideas, questions, suggestions or bugs to report, please +% feel free to contact me. +% -------------------------------------------------------------------------- +\RequirePackage{ expl3 , xparse , l3keys2e , xtemplate } +\ProvidesExplPackage + {substances} + {2016/01/07} + {0.2a} + {A Chemical Database} + +\RequirePackage{chemmacros,chemfig,ghsystem} +\usechemmodule{nomenclature,units} + +% ---------------------------------------------------------------------------- +% variables: +\tl_new:N \l__substances_tmpa_tl +\tl_new:N \l__substances_tmpb_tl + +\prop_new:N \l__substances_properties_pre_prop +\prop_new:N \l__substances_properties_post_prop + +\seq_new:N \l__substances_required_seq +\seq_new:N \l_substances_chemicals_seq + +\clist_new:N \l_substances_chemicals_clist + +\bool_new:N \l__substances_strict_bool +\bool_new:N \l__substances_index_entry_bool +\bool_new:N \l__substances_imakeidx_bool +\bool_new:N \l__substances_multind_bool +\bool_new:N \l__substances_splitidx_bool +\bool_new:N \l__substances_single_name_bool +\bool_new:N \l__substances_single_alt_bool +\bool_set_true:N \l__substances_single_alt_bool + +\tl_new:N \l__substances_style_tl +\tl_set:Nn \l__substances_style_tl {default} + +\cs_generate_variant:Nn \prop_get:NnN { c } + +\AtBeginDocument + { + \@ifpackageloaded {imakeidx} + { \bool_set_true:N \l__substances_imakeidx_bool } { } + \@ifpackageloaded {splitidx} + { \bool_set_true:N \l__substances_splitidx_bool } { } + \@ifpackageloaded {multind} + { \bool_set_true:N \l__substances_multind_bool } { } + } + +% ---------------------------------------------------------------------------- +% messages: +\cs_new_protected:Npn \substances_msg:nnn #1#2#3 + { + \bool_if:NTF \l__substances_strict_bool + { \msg_error:nnnn {substances} {#1} {#2} {#3} } + { \msg_warning:nnnn {substances} {#1} {#2} {#3} } + } + +\cs_new_protected:Npn \substances_msg:nn #1#2 + { + \bool_if:NTF \l__substances_strict_bool + { \msg_error:nnn {substances} {#1} {#2} } + { \msg_warning:nnn {substances} {#1} {#2} } + } + +\msg_new:nnnn {substances} {property-missing} + { Property~`#2'~not~defined~for~substance~`#1'~\msg_line_context:. } + { + You~called~property~`#2'~for~substance~`#1'.~It~seems~though~that~you~ + haven't~defined~it,~yet. + } + +\msg_new:nnnn {substances} {field-missing} + { Property~`#2'~is~not~defined~\msg_line_context:. } + { + You~called~property~`#2'~for~substance~`#1'.~This~property~has~not~been~ + declared,~though.~Perhaps~you've~mispelled? + } + +\msg_new:nnnn {substances} {database-missing} + { + I~ can't~ find~ the~ database~ file~ `\__substances_database:n{#1}'~ + \msg_line_context: . + } + { + You~ requested~ the~ database~ file~ `\__substances_database:n{#1}',~ but~ + apparently~ it~ is~ missing.~ Maybe~ you've~ mispelled? + } + +\msg_new:nnnn {substances} {required-field} + { The~field~`#1'~is~missing~for~substance~`#2'~\msg_line_context:. } + { + You~declared~the~the~substance~`#2'~but~forgot~to~add~the~required~ + property~`#1'. + } + +\msg_new:nnnn {substances} {style-missing} + { I~can't~find~the~file~`substances_#1.def'. } + { + You~specified~the~style~`#1'~which~means~you~want~me~to~load~the~file~ + `substances_#1.def'~but~I~can't~find~it.~Perhaps~you've~mispelled?~ + Anyway~I'm~loading~the~`default'~style~instead. + } + +% ---------------------------------------------------------------------------- +% options +\keys_define:nn { substances / options } + { + strict .bool_set:N = \l__substances_strict_bool , + draft .code:n = \bool_set_true:N \l__substances_strict_bool , + final .code:n = \bool_set_false:N \l__substances_strict_bool , + index .bool_set:N = \l__substances_index_entry_bool , + style .tl_set:N = \l__substances_style_tl + } + +\ProcessKeysOptions { substances / options } + +% ---------------------------------------------------------------------------- +% define new property fields: +\cs_new_protected:Npn \substances_define_property_field:nnnn #1#2#3#4 + { + \bool_if:nT {#1} + { \seq_put_right:Nn \l__substances_required_seq {#2} } + \prop_if_exist:cF { l__substances_#2_prop } + { \prop_new:c { l__substances_#2_prop } } + \tl_if_blank:nTF {#3} + { \prop_put:Nnn \l__substances_properties_pre_prop {#2} { } } + { \prop_put:Nnn \l__substances_properties_pre_prop {#2} {#3} } + \tl_if_blank:nTF {#4} + { \prop_put:Nnn \l__substances_properties_post_prop {#2} { } } + { \prop_put:Nnn \l__substances_properties_post_prop {#2} {#4} } + } + +\NewDocumentCommand \DeclareSubstanceProperty { smO{}O{} } + { \substances_define_property_field:nnnn {#1} {#2} {#3} {#4} } +\@onlypreamble\DeclareSubstanceProperty + +% ---------------------------------------------------------------------------- +% declare new substance entry: +\cs_new_protected:Npn \substances_declare_substance:nn #1#2 + { + \seq_put_right:Nn \l_substances_chemicals_seq {#1} + \clist_put_right:Nn \l_substances_chemicals_clist {#1} + \prop_map_inline:Nn \l__substances_properties_pre_prop + { + \tl_set:Nn \l__substances_tmpa_tl {##2} + \prop_get:NnN \l__substances_properties_post_prop + {##1} + \l__substances_tmpb_tl + \substances_add_property:nnVV {#1} {##1} + \l__substances_tmpa_tl + \l__substances_tmpb_tl + } + \keys_set:nn { substances / #1 } {#2} + \seq_map_inline:Nn \l__substances_required_seq + { + \group_begin: + \bool_set_true:N \l__substances_strict_bool + \prop_if_in:cnF { l__substances_##1_prop } {#1} + { \substances_msg:nnn {required-field} {##1} {#1} } + \group_end: + } + \prop_if_in:NnTF \l__substances_sort_prop {#1} + { + \substances_remove_braces_set:xN + { \prop_item:Nn \l__substances_sort_prop {#1} } + \l__substances_tmpa_tl + } + { + \prop_get:NnN \l__substances_properties_pre_prop + {name} + \l__substances_tmpa_tl + \substances_remove_str_unbrace_set:VnnN + \l__substances_tmpa_tl + {#1} + {name} + \l__substances_tmpa_tl + } + \prop_put:NnV \l__substances_sort_prop {#1} \l__substances_tmpa_tl + \prop_if_in:NnT \l__substances_alt_prop {#1} + { + \prop_if_in:NnTF \l__substances_altsort_prop {#1} + { + \substances_remove_braces_set:xN + { \prop_item:Nn \l__substances_altsort_prop {#1} } + \l__substances_tmpa_tl + } + { + \prop_get:NnN \l__substances_properties_pre_prop {alt} + \l__substances_tmpa_tl + \substances_remove_str_unbrace_set:VnnN + \l__substances_tmpa_tl + {#1} + {alt} + \l__substances_tmpa_tl + } + \prop_put:NnV \l__substances_altsort_prop {#1} \l__substances_tmpa_tl + } + \bool_new:c { g_substances_#1_alt_index_entry_bool } + \bool_new:c { g_substances_#1_name_index_entry_bool } + } + +\cs_new_protected:Npn \substances_add_property:nnnn #1#2#3#4 + { + \keys_define:nn { substances / #1 } + { + #2 .code:n = \prop_put:cnn + { l__substances_#2_prop } {#1} { #3{##1}#4 } + } + } +\cs_generate_variant:Nn \substances_add_property:nnnn { nnVV } + +\NewDocumentCommand \DeclareSubstance { mm } + { \substances_declare_substance:nn {#1} {#2} } +\@onlypreamble\DeclareSubstance + +% ---------------------------------------------------------------------------- +% recover values: +\cs_new_protected:Npn \substances_get_property:nn #1#2 + { + \IfSubstanceFieldTF {#2} + { + \IfSubstancePropertyTF {#1} {#2} + { \prop_item:cn { l__substances_#2_prop } {#1} } + { {??} \substances_msg:nnn {property-missing} {#1} {#2} } + } + { {??} \substances_msg:nnn {field-missing} {#1} {#2} } + } + +% ---------------------------------------------------------------------------- +% some commands for creating user macros or whatever: +\NewDocumentCommand \GetSubstanceProperty { mm } + { \substances_get_property:nn {#1} {#2} } + +\DeclareExpandableDocumentCommand \RetrieveSubstanceProperty { mm } + { \substances_get_property:nn {#1} {#2} } + +\DeclareExpandableDocumentCommand \IfSubstanceFieldTF { mmm } + { \cs_if_exist:cTF { l__substances_#1_prop } {#2} {#3} } + +\DeclareExpandableDocumentCommand \IfSubstanceFieldT { mm } + { \cs_if_exist:cT { l__substances_#1_prop } {#2} } + +\DeclareExpandableDocumentCommand \IfSubstanceFieldF { mm } + { \cs_if_exist:cF { l__substances_#1_prop } {#2} } + +\DeclareExpandableDocumentCommand \IfSubstanceExistTF { mmm } + { \seq_if_in:NnTF \l_substances_chemicals_seq {#1} {#2} {#3} } + +\DeclareExpandableDocumentCommand \IfSubstanceExistT { mm } + { \seq_if_in:NnT \l_substances_chemicals_seq {#1} {#2} } + +\DeclareExpandableDocumentCommand \IfSubstanceExistF { mm } + { \seq_if_in:NnF \l_substances_chemicals_seq {#1} {#2} } + +\DeclareExpandableDocumentCommand \IfSubstancePropertyTF { mmmm } + { + \cs_if_exist:cTF { l__substances_#2_prop } + { \prop_if_in:cnTF { l__substances_#2_prop } {#1} {#3} {#4} } + {#4} + } + +\DeclareExpandableDocumentCommand \IfSubstancePropertyT { mmm } + { + \cs_if_exist:cT { l__substances_#2_prop } + { \prop_if_in:cnT { l__substances_#2_prop } {#1} {#3} } + } + +\DeclareExpandableDocumentCommand \IfSubstancePropertyF { mmm } + { + \cs_if_exist:cTF { l__substances_#2_prop } + { \prop_if_in:cnF { l__substances_#2_prop } {#1} {#3} } + {#3} + } + +\DeclareExpandableDocumentCommand \ForAllSubstancesDo {} + { \seq_map_inline:Nn \l_substances_chemicals_seq } + +\AtBeginDocument + { + \tl_new:N \AllSubstancesSequence + \seq_map_inline:Nn \l_substances_chemicals_seq + { \tl_put_right:Nn \AllSubstancesSequence { {#1} } } + \cs_new_eq:NN \AllSubstancesClist \l_substances_chemicals_clist + } + +% ---------------------------------------------------------------------------- +% user command: +\NewDocumentCommand \chem { soomo } + { + \IfNoValueF {#2} {#2} + \IfNoValueTF {#5} + { + \IfBooleanTF {#1} + { + \IfSubstancePropertyTF {#4} {alt} + { \RetrieveSubstanceProperty {#4} {alt} } + { \RetrieveSubstanceProperty {#4} {name} } + } + { \RetrieveSubstanceProperty {#4} {name} } + } + { \RetrieveSubstanceProperty {#4} {#5} } + \IfNoValueF {#3} {#3} + \SubstanceIndex {#4} + } + +% ---------------------------------------------------------------------------- +% index command to add an entry to the chemicals list if the option +% `index=true' is used: +\cs_new_protected:Npn \substances_index:nn #1#2 + { + \bool_if:NTF \l__substances_imakeidx_bool + { \index [ #1 ] {#2} } + { + \bool_if:NTF \l__substances_splitidx_bool + { \sindex [ #1 ] {#2} } + { + \bool_if:NTF \l__substances_multind_bool + { \index {#1} {#2} } + { \index {#2} } + } + } + } +\cs_generate_variant:Nn \substances_index:nn { no,nx } + +\cs_new_protected:Npn \substances_index_entry:nn #1#2 + { \UseInstance {substances-index} {#1} {#2} } + +\NewDocumentCommand \SubstanceIndex {O{default}m} + { + \bool_if:NT \l__substances_index_entry_bool + { \substances_index_entry:nn {#1} {#2} } + } + +\cs_new_protected:Npn \substances_remove_braces_set:nN #1#2 + { \tl_set:Nn #2 #1 } +\cs_generate_variant:Nn \substances_remove_braces_set:nN {x} + +\cs_new_protected:Npn \substances_remove_str_unbrace_set:nnnN #1#2#3#4 + { + \prop_get:cnN { l__substances_#3_prop } {#2} #4 + \tl_remove_all:Nn #4 {#1} + \substances_remove_braces_set:xN {#4} #4 + } +\cs_generate_variant:Nn \substances_remove_str_unbrace_set:nnnN { V } + +% let's use xtemplate's features for possible customization later: +\DeclareObjectType {substances-index} {1} + +\DeclareTemplateInterface {substances-index} {standard} {1} + { + alternative-entry : boolean = true , + alternative-name : boolean = true + } + +\DeclareTemplateCode {substances-index} {standard} {1} + { + alternative-entry = \l__substances_index_alternative_entry_bool , + alternative-name = \l__substances_index_alternative_name_bool , + } + { + \AssignTemplateKeys + \bool_if:nTF + { + \l__substances_index_alternative_name_bool && + \prop_if_in_p:Nn \l__substances_alt_prop {#1} + } + { + \bool_if:cF { g_substances_#1_name_index_entry_bool } + { + \substances_index:nx { \c_job_name_tl -chem } + { + \SubstanceIndexNameAltEntry + { \prop_item:Nn \l__substances_sort_prop {#1} } + { \GetSubstanceProperty {#1} {name} } + { \GetSubstanceProperty {#1} {alt} } + } + } + \bool_if:NT \l__substances_single_name_bool + { \bool_gset_true:c { g_substances_#1_name_index_entry_bool } } + } + { + \bool_if:cF { g_substances_#1_name_index_entry_bool } + { + \substances_index:nx { \c_job_name_tl -chem } + { + \SubstanceIndexNameEntry + { \prop_item:Nn \l__substances_sort_prop {#1} } + { \GetSubstanceProperty {#1} {name} } + } + } + \bool_if:NT \l__substances_single_name_bool + { \bool_gset_true:c { g_substances_#1_name_index_entry_bool } } + } + \bool_if:nT + { + \l__substances_index_alternative_entry_bool && + \l__substances_index_alternative_name_bool && + \prop_if_in_p:Nn \l__substances_alt_prop {#1} + } + { + \bool_if:cF { g_substances_#1_alt_index_entry_bool } + { + \substances_index:nx { \c_job_name_tl -chem } + { + \SubstanceIndexAltEntry + { \prop_item:Nn \l__substances_altsort_prop {#1} } + { \GetSubstanceProperty {#1} {name} } + { \GetSubstanceProperty {#1} {alt} } + } + \substances_contains_see:NT \SubstanceIndexAltEntry + { \bool_gset_true:c { g_substances_#1_alt_index_entry_bool } } + } + } + } + +\DeclareInstance {substances-index} {default} {standard} { } + +\cs_new:Npn \SubstanceIndexNameEntry #1#2 { #1@#2 } +\cs_new:Npn \SubstanceIndexNameAltEntry #1#2#3 { #1@#2~(#3) } +\cs_new:Npn \SubstanceIndexAltEntry #1#2#3 { #1@#3|see{#2} } + +\cs_new_protected:Npn \substances_contains_see:NT #1#2 + { + \tl_set_rescan:Nnx \l__substances_tmpa_tl {} {\cs_meaning:N #1 } + \tl_if_in:VnT \l__substances_tmpa_tl { |see } {#2} + } + +% ---------------------------------------------------------------------------- +% define some default fields: + +\cs_new_nopar:Npn \@CAS #1-#2-#3\relax { \iupac{#1-#2-#3} } +\NewDocumentCommand \CAS { m } { \@CAS #1 \relax } + +\DeclareSubstanceProperty* {name} [\iupac] +\DeclareSubstanceProperty {sort} +\DeclareSubstanceProperty {alt} [\iupac] +\DeclareSubstanceProperty {altsort} +\DeclareSubstanceProperty {CAS} [\CAS] +\DeclareSubstanceProperty {PubChem} + +% ---------------------------------------------------------------------------- +% load style file +\tl_const:Nn \c__substances_style_extension_tl {def} +\tl_const:Nn \c__substances_style_prefix_tl {substances-} + +\cs_new:Npn \__substances_style:n #1 + { \c__substances_style_prefix_tl#1.\c__substances_style_extension_tl } + +\cs_new_protected:Npn \substances_load_style:n #1 + { + \tl_set:Nx \l__substances_tmpa_tl { \tl_trim_spaces:n {#1} } + \__substances_load_style:V \l__substances_tmpa_tl + } +\cs_generate_variant:Nn \substances_load_style:n { V } + +\cs_new_protected:Npn \__substances_load_style:n #1 + { + \substances_if_style_exist:nTF {#1} + { +% \msg_log:nnn {substances} {loading-style} {#1} + \@onefilewithoptions + {\c__substances_style_prefix_tl#1}[][] + \c__substances_style_extension_tl + } + { \substances_msg:nn {style-missing} {#1} } + } +\cs_generate_variant:Nn \__substances_load_style:n { V } + +\prg_new_conditional:Npnn \substances_if_style_exist:n #1 {T,F,TF} + { + \file_if_exist:nTF + { \__substances_style:n {#1} } + { \prg_return_true: } + { \prg_return_false: } + } + +\cs_new_protected:Npn \__substances_style:nn #1#2 + { + \ProvidesFile { \__substances_style:n {#2} } + \bool_if:nT {#1} { \ExplSyntaxOn } + } + +\bool_new:N \l__substances_inside_style_file_bool + +\NewDocumentCommand \SubstancesStyle {sm} + { + \__substances_style:nn {#1} {#2} + \bool_set_true:N \l__substances_inside_style_file_bool + \AtEndOfPackage + { \bool_set_false:N \l__substances_inside_style_file_bool } + } + +\NewDocumentCommand \LoadSubstancesStyle {m} + { + \bool_if:NTF \l__substances_inside_style_file_bool + { \substances_load_style:n {#1} } + {} + } + +\substances_load_style:V \l__substances_style_tl + +% ---------------------------------------------------------------------------- +% load database file +\tl_const:Nn \c__substances_database_extension_tl {sub} +\tl_const:Nn \c__substances_database_prefix_tl {} + +\cs_new:Npn \__substances_database:n #1 + { \c__substances_database_prefix_tl#1.\c__substances_database_extension_tl } + +\prg_new_conditional:Npnn \substances_if_database_exist:n #1 {T,F,TF} + { + \file_if_exist:nTF + { \__substances_database:n {#1} } + { \prg_return_true: } + { \prg_return_false: } + } + +\cs_new_protected:Npn \__substances_load_database:n #1 + { + \substances_if_database_exist:nTF {#1} + { + \@onefilewithoptions + {\c__substances_database_prefix_tl#1}[][] + \c__substances_database_extension_tl + } + { \substances_msg:nn {database-missing} {#1} } + } +\cs_generate_variant:Nn \__substances_load_database:n { V } + +\cs_new_protected:Npn \substances_load_database:n #1 + { + \tl_set:Nx \l__substances_tmpa_tl { \tl_trim_spaces:n {#1} } + \__substances_load_database:V \l__substances_tmpa_tl + } + +\NewDocumentCommand \LoadSubstances {m} + { \substances_load_database:n {#1} } +\@onlypreamble\LoadSubstances + +\cs_new_protected:Npn \__substances_database:nn #1#2 + { + \ProvidesFile { \__substances_database:n {#2} } + \bool_if:nF {#1} { } + } + +\NewDocumentCommand \SubstancesDatabase {sm} + { \__substances_database:nn {#1} {#2} } + +\tex_endinput:D + +% ---------------------------------------------------------------------------- +% HISTORY: +2012/07/22 v0.1 - first release to CTAN +2012/09/02 v0.1a - small fix due to updated l3kernel +2015/10/21 v0.2 - maintenance: minor fixes, adapt to chemmacros v5 + - change implementation of how style files are loaded + - change implementation of how database files are loaded +2016/01/07 v0.2a - \prop_get:Nn => \prop_item:Nn + +% TODO: |