From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Mon, 2 Sep 2019 13:46:59 +0900 Subject: Initial commit --- macros/latex/contrib/chemnum/chemnum.sty | 2011 ++++++++++++++++++++++++++++++ 1 file changed, 2011 insertions(+) create mode 100644 macros/latex/contrib/chemnum/chemnum.sty (limited to 'macros/latex/contrib/chemnum/chemnum.sty') diff --git a/macros/latex/contrib/chemnum/chemnum.sty b/macros/latex/contrib/chemnum/chemnum.sty new file mode 100644 index 0000000000..659378bf72 --- /dev/null +++ b/macros/latex/contrib/chemnum/chemnum.sty @@ -0,0 +1,2011 @@ +% -------------------------------------------------------------------------- +% the CHEMNUM package +% +% a comprehensive approach for the numbering of chemical compounds +% +% -------------------------------------------------------------------------- +% Clemens Niederberger +% -------------------------------------------------------------------------- +% https://github.org/cgnieder/chemnum/ +% contact@mychemistry.eu +% -------------------------------------------------------------------------- +% If you have any ideas, questions, suggestions or bugs to report, please +% feel free to contact me. +% -------------------------------------------------------------------------- +% Copyright 2011-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. +% -------------------------------------------------------------------------- +\def\chemnumdate{2016/04/14} +\def\chemnumversion{1.2} +\def\chemnuminfo{a comprehensive approach for the numbering of chemical compounds} + +\RequirePackage{expl3}[2016/03/28] +\RequirePackage{xparse,l3keys2e} + +% ---------------------------------------------------------------------------- +% provide the package: +\ProvidesExplPackage{chemnum} + {\chemnumdate} + {\chemnumversion} + {\chemnuminfo\space (CN)} + +% ---------------------------------------------------------------------------- +% required packages: +% language support: +\RequirePackage{translations}[2015/11/07] +% greek alphabet for the labels matching to chemmacros' selection: +\RequirePackage{chemgreek}[2016/02/10] +\RequirePackage{psfrag} + +% ---------------------------------------------------------------------------- +% messages: +\msg_new:nnn {chemnum} {missing-label} + { The~ key~ `#1'~ has~ no~ label~ associated~ \msg_line_context: } + +\msg_new:nnn {chemnum} {erroneous-argument-combination} + { + Apparently~ you've~ used~ both~ the~ `*'~ and~ the~ `+'~ + argument.~ This~ does~ not~ make~ sense.~ I'm~ doing~ + nothing~ \msg_line_context: + } + +\msg_new:nnn {chemnum} {unknown-counter-format} + { + I~ do~ not~ know~ the~ counter~ format~ `#1'.~ I'll~ use~ `arabic'~ + instead~ \msg_line_context: + } + +\msg_new:nnn {chemnum} {compound-not-initiated} + { The~ compound~ `#1'~ has~ not~ been~ initiated~ \msg_line_context: } + +\msg_new:nnn {chemnum} {subcompound-not-initiated} + { + The~ compound~ `#1\l__chemnum_compound_separator_tl #2'~ has~ not~ been~ + initiated~ \msg_line_context: + } + +\msg_new:nnn {chemnum} {log-compound-silent} + { + ................................................. \\ + . ~ \msg_info_text:n {chemnum}: ~ + defined~ new~ compound~ `#1'~with~output~ + `\chemnum_expandable_get_compound_property:nn {#1} + {counter-representation}' . \\ + ................................................. + } + +\msg_new:nnn {chemnum} {log-compound-verbose} + { + ................................................. \\ + . ~ \msg_info_text:n {chemnum}: ~ defined~ new~ compound: \\ + . \c_space_tl \c_space_tl \c_space_tl + ID ~=~ #1 \\ + . \c_space_tl \c_space_tl \c_space_tl + internal~ number ~=~ + \chemnum_expandable_get_compound_property:nn {#1} {number} \\ + . \c_space_tl \c_space_tl \c_space_tl + label ~=~ + \chemnum_expandable_get_compound_property:nn {#1} + {counter-representation} \\ + . \c_space_tl \c_space_tl \c_space_tl + pre~ label~ code ~=~ + \chemnum_expandable_get_compound_property:nn {#1} + {pre-label-code} \\ + . \c_space_tl \c_space_tl \c_space_tl + post~ label~ code ~=~ + \chemnum_expandable_get_compound_property:nn {#1} + {post-label-code} \\ + . \c_space_tl \c_space_tl \c_space_tl + pre~ main~ label~ code ~=~ + \chemnum_expandable_get_compound_property:nn {#1} + {pre-main-label-code} \\ + . \c_space_tl \c_space_tl \c_space_tl + post~ main~ label~ code ~=~ + \chemnum_expandable_get_compound_property:nn {#1} + {post-main-label-code} \\ + . \c_space_tl \c_space_tl \c_space_tl + format ~=~ + \chemnum_expandable_get_compound_property:nn {#1} + {label-format} \\ + ................................................. + } + +\msg_new:nnn {chemnum} {log-subcompound-silent} + { + ................................................. \\ + . ~ \msg_info_text:n {chemnum}: ~ + defined~ new~ subcompound~ `#2'~ with~ output~ + \chemnum_expandable_get_subcompound_property:nnn {#1} {#2} + {counter-representation} \\ + . ~ belonging~ to~ the~ main~ compound~ `#1'. \\ + ................................................. + } + +\msg_new:nnn {chemnum} {log-subcompound-verbose} + { + ................................................. \\ + . ~ \msg_info_text:n {chemnum}: ~ defined~ new~ subcompound: \\ + . \c_space_tl \c_space_tl \c_space_tl + ID ~=~ #2 \\ + . \c_space_tl \c_space_tl \c_space_tl + main~ compound~ ID ~=~ + \chemnum_expandable_get_subcompound_property:nnn {#1} {#2} + {main-compound} \\ + . \c_space_tl \c_space_tl \c_space_tl + internal~ number ~=~ + \chemnum_expandable_get_subcompound_property:nnn {#1} {#2} {number} \\ + . \c_space_tl \c_space_tl \c_space_tl + label ~=~ + \chemnum_expandable_get_subcompound_property:nnn {#1} {#2} + {counter-representation} \\ + ................................................. + } + +\msg_new:nnn {chemnum} {deprecated-command} + { + The~ command~ `\token_to_str:N #1'~ \msg_line_context: \c_space_tl is~ + deprecated.~ Use~ `\token_to_str:N #2'~ instead.~ `\token_to_str:N #1'~ + may~ be~ removed~ in~ future~ versions. + } + +\msg_new:nnn {chemnum} {property-undefined} + { + The~ property~ `#2'~ for~ compound~ `#1'~ is~ undefined~ and~ thus~ + cannot~ be~ set~ \msg_line_context: + } + +% ---------------------------------------------------------------------------- +% deprecated command names: +% #1: old name +% #2: new name +\cs_new_protected:Npn \chemnum_deprecated_command:NN #1#2 + { + \cs_new_protected:Npn #1 + { + \msg_warning:nnnn {chemnum} {deprecated-command} {#1} {#2} + #2 + } + } + +\chemnum_deprecated_command:NN \cmpdsetup \setchemnum +\chemnum_deprecated_command:NN \cmpdinit \initcmpd +\chemnum_deprecated_command:NN \cmpdref \replacecmpd +\chemnum_deprecated_command:NN \cmpdreset \resetcmpd + +% ---------------------------------------------------------------------------- +% variants of kernel functions: +\cs_generate_variant:Nn \prop_gput:Nnn { Nnx , cnx , cnV } +\cs_generate_variant:Nn \prop_put:Nnn { NV , NVV , NVx } +\cs_generate_variant:Nn \prop_if_in:NnTF { NV } +\cs_generate_variant:Nn \quark_if_no_value:nTF { V } +\cs_generate_variant:Nn \quark_if_no_value:nF { V } +\cs_generate_variant:Nn \seq_set_split:Nnn { NV , NVV } +\cs_generate_variant:Nn \seq_use:Nnnn { NVVV } +\cs_generate_variant:Nn \tl_if_eq:nnF { Vx } +\cs_generate_variant:Nn \tl_if_in:nnTF { VV } + +% ---------------------------------------------------------------------------- +% temporary variables: +\tl_new:N \l__chemnum_tmpa_tl +\tl_new:N \l__chemnum_tmpb_tl + +\seq_new:N \l__chemnum_tmpa_seq +\seq_new:N \l__chemnum_tmpb_seq +\seq_new:N \l__chemnum_tmpc_seq +\seq_new:N \l__chemnum_tmpd_seq +\seq_new:N \l__chemnum_tmpe_seq + +\int_new:N \l__chemnum_tmpa_int +\int_new:N \l__chemnum_tmpb_int +\int_new:N \l__chemnum_tmpc_int + +% ---------------------------------------------------------------------------- +% variables: +\prop_new:N \l__chemnum_label_formats_prop + +% the main label counter: +% not very expl3 like but allows `cmpdmain' to be added to the \cl@ +% list, i.e., it can e.g. be reset for every chapter: +\newcounter{cmpdmain} +% counter for internal reference if needed. Will be a unique number in order +% of declaration: +\int_new:N \g__chemnum_main_int +\int_new:N \l__chemnum_compound_replace_int + +\seq_new:N \g__chemnum_initiated_compounds_seq +\seq_new:N \g__chemnum_defined_compounds_seq +\seq_new:N \g__chemnum_compound_defined_subcompounds_seq + +\tl_new:N \l__chemnum_label_format_tl +\tl_set:Nn \l__chemnum_label_format_tl {\bfseries} +\tl_new:N \l__chemnum_local_label_format_tl +\tl_set_eq:NN \l__chemnum_local_label_format_tl \l__chemnum_label_format_tl +\tl_new:N \l__chemnum_default_counter_representation_tl +\tl_set:Nn \l__chemnum_default_counter_representation_tl {arabic} +\tl_new:N \l__chemnum_default_subcounter_representation_tl +\tl_set:Nn \l__chemnum_default_subcounter_representation_tl {alph} +\tl_new:N \l__chemnum_pre_counter_default_tl +\tl_new:N \l__chemnum_post_counter_default_tl +\tl_new:N \l__chemnum_pre_label_default_tl +\tl_new:N \l__chemnum_post_label_default_tl +\tl_new:N \l__chemnum_pre_main_label_default_tl +\tl_new:N \l__chemnum_post_main_label_default_tl +\tl_new:N \l__chemnum_main_separator_tl +\tl_set:Nn \l__chemnum_main_separator_tl {,} +\tl_new:N \l__chemnum_sub_separator_tl +\tl_set:Nn \l__chemnum_sub_separator_tl {,} +\tl_new:N \l__chemnum_compound_separator_tl +\tl_set:Nn \l__chemnum_compound_separator_tl {.} + +\tl_new:N \l__chemnum_sep_list_two_tl +\tl_set:Nn \l__chemnum_sep_list_two_tl { \GetTranslation {chemnum-sep-two} } +\tl_new:N \l__chemnum_sep_list_more_tl +\tl_set:Nn \l__chemnum_sep_list_more_tl {,~} +\tl_new:N \l__chemnum_sep_list_last_two_tl +\tl_set:Nn \l__chemnum_sep_list_last_two_tl { \GetTranslation {chemnum-sep-last-two} } + +\tl_new:N \l__chemnum_sep_sublist_two_tl +\tl_set:Nn \l__chemnum_sep_sublist_two_tl {,} +\tl_new:N \l__chemnum_sep_sublist_more_tl +\tl_set:Nn \l__chemnum_sep_sublist_more_tl {,} +\tl_new:N \l__chemnum_sep_sublist_last_two_tl +\tl_set:Nn \l__chemnum_sep_sublist_last_two_tl {,} +\tl_new:N \l__chemnum_sep_sublist_range_tl +\tl_set:Nn \l__chemnum_sep_sublist_range_tl {--} + +\tl_new:N \l__chemnum_compound_replace_tl +\tl_new:N \l__chemnum_compound_replace_format_tl +\tl_new:N \l__chemnum_compound_replace_local_format_tl +\tl_set:Nn \l__chemnum_compound_replace_format_tl {\sffamily} +\tl_new:N \l__chemnum_compound_replace_tag_tl +\tl_set:Nn \l__chemnum_compound_replace_tag_tl {TMP} +\tl_new:N \l__chemnum_psfrag_texpos_tl +\tl_new:N \l__chemnum_psfrag_local_texpos_tl +\tl_set:Nn \l__chemnum_psfrag_texpos_tl {b} +\tl_new:N \l__chemnum_psfrag_pspos_tl +\tl_new:N \l__chemnum_psfrag_local_pspos_tl +\tl_set:Nn \l__chemnum_psfrag_pspos_tl {b} + +\bool_new:N \l__chemnum_compound_local_bool +\bool_new:N \g__chemnum_initiate_bool +\bool_new:N \g__chemnum_initiate_strict_bool +\bool_new:N \g__chemnum_initiate_sub_bool +\bool_new:N \l__chemnum_log_bool +\bool_set_true:N \l__chemnum_log_bool +\bool_new:N \l__chemnum_log_verbose_bool +\bool_new:N \l__chemnum_compress_subcompounds_bool +\bool_set_true:N \l__chemnum_compress_subcompounds_bool +\bool_new:N \l__chemnum_merge_list_bool +\bool_new:N \l__chemnum_sub_only_bool +\bool_new:N \l__chemnum_sub_all_bool +\bool_new:N \l__chemnum_show_def_bool +\bool_new:N \l__chemnum_show_ref_bool +\bool_new:N \l__chemnum_compound_replace_auto_bool +\bool_set_true:N \l__chemnum_compound_replace_auto_bool +\bool_new:N \l__chemnum_compound_replace_auto_this_bool +\bool_set_true:N \l__chemnum_compound_replace_auto_this_bool +\bool_new:N \l__chemnum_replace_local_bool +\bool_new:N \l__chemnum_hyperlinks_bool + +% ---------------------------------------------------------------------------- +% label formats: + +% #1: name +% #2: function with 1 n-type argument that takes an integer +\cs_new_protected:Npn \chemnum_add_label_format:nn #1#2 + { + \cs_if_exist:cTF { __chemnum_#1_label_format:n } + { \cs_set:cpn { __chemnum_#1_label_format:n } ##1 { #2 {##1} } } + { \cs_new:cpn { __chemnum_#1_label_format:n } ##1 { #2 {##1} } } + \prop_put:Nnx \l__chemnum_label_formats_prop {#1} + { \exp_not:c { __chemnum_#1_label_format:n } } + } + +% a user level command to add new formats +\NewDocumentCommand \newcmpdcounterformat {mm} + { \chemnum_add_label_format:nn {#1} {#2} } + +\newcmpdcounterformat {arabic} { \int_to_arabic:n } +\newcmpdcounterformat {alph} { \int_to_alph:n } +\newcmpdcounterformat {Alph} { \int_to_Alph:n } +\newcmpdcounterformat {roman} { \int_to_roman:n } +\newcmpdcounterformat {Roman} { \int_to_Roman:n } +\newcmpdcounterformat {greek} { \chemgreek_int_to_greek:n } +\newcmpdcounterformat {Greek} { \chemgreek_int_to_Greek:n } + +% ---------------------------------------------------------------------------- +%%% options +% options assigned to group `compound' are only setable with the \cmpd command +% except they're _also_ asigned to the `general' group; likewise options that +% are assigned to the group `general' can only be set with \setchemnum except +% they're also assigned to the `compound' group. +\keys_define:nn {chemnum} + { + local .bool_set:N = \l__chemnum_compound_local_bool , + local .groups:n = {compound} , + % counter: + counter-within .code:n = \@addtoreset{cmpdmain}{#1} , + counter-within .groups:n = {general} , + counter-format .code:n = + \prop_if_in:NnTF \l__chemnum_label_formats_prop {#1} + { + \tl_set:Nn + \l__chemnum_default_counter_representation_tl + {#1} + } + { + \msg_warning:nnn {chemnum} {unknown-counter-format} {#1} + \tl_set:Nn + \l__chemnum_default_counter_representation_tl + {arabic} + } , + counter-format .groups:n = {compound,general} , + sub-counter-format .code:n = + \prop_if_in:NnTF \l__chemnum_label_formats_prop {#1} + { + \tl_set:Nn + \l__chemnum_default_subcounter_representation_tl + {#1} + } + { + \msg_warning:nnn {chemnum} {unknown-counter-format} {#1} + \tl_set:Nn + \l__chemnum_default_subcounter_representation_tl + {arabic} + } , + sub-counter-format .groups:n = {compound,general} , + % label: + pre-label-code .tl_set:N = \l__chemnum_pre_label_default_tl , + pre-label-code .groups:n = {compound} , + post-label-code .tl_set:N = \l__chemnum_post_label_default_tl , + post-label-code .groups:n = {compound} , + pre-main-label-code .tl_set:N = \l__chemnum_pre_main_label_default_tl , + pre-main-label-code .groups:n = {compound} , + post-main-label-code .tl_set:N = \l__chemnum_post_main_label_default_tl , + post-main-label-code .groups:n = {compound} , + main-sub-sep .tl_set:N = \l__chemnum_compound_separator_tl , + main-sub-sep .groups:n = {general,list} , + list-label-sep .tl_set:N = \l__chemnum_main_separator_tl , + list-label-sep .groups:n = {general,list} , + sub-list-label-sep .tl_set:N = \l__chemnum_sub_separator_tl , + sub-list-label-sep .groups:n = {general,list} , + format .code:n = + \tl_set:Nn \l__chemnum_local_label_format_tl {#1} + \bool_if:NF \l__chemnum_compound_local_bool + { \tl_set:Nn \l__chemnum_label_format_tl {#1} } , + format .groups:n = {compound,general} , + sub-only .bool_set:N = \l__chemnum_sub_only_bool , + sub-only .groups:n = {compound,sub-only} , + sub-all .bool_set:N = \l__chemnum_sub_all_bool , + sub-all .groups:n = {compound} , + compress .bool_set:N = + \l__chemnum_compress_subcompounds_bool , + compress .groups:n = {compound,general} , + merge .bool_set:N = + \l__chemnum_merge_list_bool , + merge .groups:n = {general,list} , + % initiation: + init .choice: , + init / true .code:n = + \bool_set_true:N \g__chemnum_initiate_bool + \bool_set_true:N \g__chemnum_initiate_sub_bool + \bool_set_false:N \g__chemnum_initiate_strict_bool , + init / main .code:n = + \bool_set_true:N \g__chemnum_initiate_bool + \bool_set_false:N \g__chemnum_initiate_sub_bool + \bool_set_false:N \g__chemnum_initiate_strict_bool , + init / false .code:n = + \bool_set_false:N \g__chemnum_initiate_bool + \bool_set_false:N \g__chemnum_initiate_sub_bool + \bool_set_false:N \g__chemnum_initiate_strict_bool , + init / strict .code:n = + \bool_set_true:N \g__chemnum_initiate_bool + \bool_set_true:N \g__chemnum_initiate_sub_bool + \bool_set_true:N \g__chemnum_initiate_strict_bool , + init / main-strict .code:n = + \bool_set_true:N \g__chemnum_initiate_bool + \bool_set_false:N \g__chemnum_initiate_sub_bool + \bool_set_true:N \g__chemnum_initiate_strict_bool , + init .default:n = true , + init .groups:n = {general} , + % list processing: + list-sep-two .tl_set:N = \l__chemnum_sep_list_two_tl , + list-sep-two .groups:n = {general,list} , + list-sep-more .tl_set:N = \l__chemnum_sep_list_more_tl , + list-sep-more .groups:n = {general,list} , + list-sep-last-two .tl_set:N = \l__chemnum_sep_list_last_two_tl , + list-sep-last-two .groups:n = {general,list} , + sub-list-sep-two .tl_set:N = \l__chemnum_sep_sublist_two_tl , + sub-list-sep-two .groups:n = {compound,general} , + sub-list-sep-more .tl_set:N = \l__chemnum_sep_sublist_more_tl , + sub-list-sep-more .groups:n = {compound,general} , + sub-list-sep-last-two .tl_set:N = \l__chemnum_sep_sublist_last_two_tl , + sub-list-sep-last-two .groups:n = {compound,general} , + sub-list-sep-range .tl_set:N = \l__chemnum_sep_sublist_range_tl , + sub-list-sep-range .groups:n = {compound,general} , + % logging and other information: + log .choice: , + log / true .code:n = + \bool_set_true:N \l__chemnum_log_bool + \bool_set_false:N \l__chemnum_log_verbose_bool , + log / silent .code:n = + \bool_set_true:N \l__chemnum_log_bool + \bool_set_false:N \l__chemnum_log_verbose_bool , + log / false .code:n = + \bool_set_false:N \l__chemnum_log_bool + \bool_set_false:N \l__chemnum_log_verbose_bool , + log / verbose .code:n = + \bool_set_true:N \l__chemnum_log_bool + \bool_set_true:N \l__chemnum_log_verbose_bool , + log .default:n = true , + log .groups:n = {general} , + show-keys .choice: , + show-keys / true .code:n = + \bool_set_true:N \l__chemnum_show_def_bool + \bool_set_true:N \l__chemnum_show_ref_bool , + show-keys / false .code:n = + \bool_set_false:N \l__chemnum_show_def_bool + \bool_set_false:N \l__chemnum_show_ref_bool , + show-keys / def .code:n = + \bool_set_true:N \l__chemnum_show_def_bool + \bool_set_false:N \l__chemnum_show_ref_bool , + show-keys / ref .code:n = + \bool_set_false:N \l__chemnum_show_def_bool + \bool_set_true:N \l__chemnum_show_ref_bool , + show-keys .default:n = true , + show-keys .groups:n = {general} , + replace .bool_set:N = \l__chemnum_replace_local_bool , + replace .groups:n = {replace} , + replace-auto .bool_set:N = \l__chemnum_compound_replace_auto_bool , + replace-tag .tl_set:N = \l__chemnum_compound_replace_tag_tl , + replace-tag .groups:n = {general} , + tag .code:n = + \tl_set:Nn \l__chemnum_compound_replace_tag_tl {#1} + \bool_set_false:N \l__chemnum_compound_replace_auto_this_bool , + tag .groups:n = {replace} , + replace-tag-nr .code:n = + \int_set:Nn \l__chemnum_compound_replace_int { (#1) - 1 } , + replace-tag-nr .groups:n = {general} , + replace-tag-nr .initial:n = {1} , + replace-style .tl_set:N = \l__chemnum_compound_replace_format_tl , + replace-style .groups:n = {general} , + style .code:n = + \tl_set:Nn \l__chemnum_compound_replace_local_format_tl {#1} + \bool_set_true:N \l__chemnum_replace_local_bool , + style .groups:n = {replace} , + replace-pos .code:n = \__chemnum_set_psfrag_pos:nn #1 , + replace-pos .groups:n = {general} , + pos .code:n = + \bool_set_true:N \l__chemnum_replace_local_bool + \__chemnum_set_psfrag_local_pos:nn #1 , + pos .groups:n = {replace} , + hyperlinks .bool_set:N = \l__chemnum_hyperlinks_bool , + hyperlinks .groups:n = {general} , + } + +% ---------------------------------------------------------------------------- +% #1: int variable that holds the value +% #2: the chosen format +% this command is expandable +\cs_new:Npn \__chemnum_label_format:Nn #1#2 + { + \prop_if_in:NnTF \l__chemnum_label_formats_prop {#2} + { \use:c { __chemnum_#2_label_format:n } {#1} } + { \__chemnum_arabic_label_format:n {#1} } + } +\cs_generate_variant:Nn \__chemnum_label_format:Nn { NV , cV } + +% ---------------------------------------------------------------------------- +% auxiliary file -- we'll use the .aux file +% first let's add dummy definitions so we can hopefully avoid error messages +% if the `chemnum' package is removed from the preamble +\AtBeginDocument + { + \if@filesw + \iow_now:Nn \@auxout + { + \providecommand\chemnum@cmpd[8]{} ^^J + \providecommand\chemnum@subcmpd[4]{} ^^J + \providecommand\chemnum@check{} + } + \fi + } + +% we use this one to trigger a LaTeX rerun warning -- to be precise the +% ``Label(s) may have changed'' warning: +\cs_new_protected:Npn \__chemnum_rerun: + { \AtEndDocument { \def \chemnum@check { \@tempswatrue } } } + +% add the rerun check at the end: +\AtEndDocument { \if@filesw \iow_now:Nn \@auxout { \chemnum@check } \fi } + +% ---------------------------------------------------------------------------- +% initiating new compounds +% - property list that holds +% - ID +% - counter value +% - counter represetation +% - pre-counter-code +% - post-counter-code +% - pre-label-code +% - post-label-code +% - formatting code +% - add to list of initiated compounds + +\cs_new_protected:Npn \chemnum_initiate_compound:n #1 + { + \chemnum_compound_if_initiated:nF {#1} + { \seq_gput_right:Nn \g__chemnum_initiated_compounds_seq {#1} } + } + +% #1: ID +\cs_new_protected:Npn \chemnum_define_compound:n #1 + { + \chemnum_initialize_compound:n {#1} + \chemnum_compound_declare_properties:nn {#1} + { + ID , + number , + counter-representation , + pre-label-code , + post-label-code , + pre-main-label-code , + post-main-label-code , + label-format + } + \chemnum_compound_set_property:nnn {#1} {ID} {#1} + \chemnum_compound_set_property:nnx {#1} {number} + { \int_use:N \c@cmpdmain } + \chemnum_compound_set_property:nnx {#1} {counter-representation} + { + \exp_not:V \l__chemnum_pre_counter_default_tl + \__chemnum_label_format:NV + \c@cmpdmain % \g__chemnum_main_int + \l__chemnum_default_counter_representation_tl + \exp_not:V \l__chemnum_post_counter_default_tl + } + \chemnum_compound_set_property:nnV {#1} {pre-label-code} + \l__chemnum_pre_label_default_tl + \chemnum_compound_set_property:nnV {#1} {post-label-code} + \l__chemnum_post_label_default_tl + \chemnum_compound_set_property:nnV {#1} {pre-main-label-code} + \l__chemnum_pre_main_label_default_tl + \chemnum_compound_set_property:nnV {#1} {post-main-label-code} + \l__chemnum_post_main_label_default_tl + \chemnum_compound_set_property:nnV {#1} {label-format} + \l__chemnum_label_format_tl + } + +\cs_new_protected:Npn \chemnum_finalize_compound:n #1 + { + \chemnum_compound_update_properties:n {#1} + \chemnum_save_compound_to_auxfile:n {#1} + \chemnum_log_main:n {#1} + } + +% TODO: keep? and if: what should it set? +\cs_new_protected:Npn \chemnum_set_compound:n #1 + { + % those should be done: however, they overwrite existing options in any + % case... this would overwrite options that really should stay set. + + % \chemnum_compound_set_property:nnV {#1} {pre-label-code} + % \l__chemnum_pre_label_default_tl + % \chemnum_compound_set_property:nnV {#1} {post-label-code} + % \l__chemnum_post_label_default_tl + % \chemnum_compound_set_property:nnV {#1} {post-main-label-code} + % \l__chemnum_post_main_label_default_tl + % \chemnum_compound_set_property:nnV {#1} {label-format} + % \l__chemnum_label_format_tl + % \chemnum_save_compound_to_auxfile:n {#1} + % \chemnum_compound_update_properties:n {#1} + } + +% we can use this command as a hook through redefinition: +\cs_new_protected:Npn \chemnum_initialize_compound:n #1 + { \chemnum_init_raw_compound:n {#1} } + +\cs_new_protected:Npn \chemnum_init_raw_compound:n #1 + { + \seq_if_in:NnF \g__chemnum_defined_compounds_seq {#1} + { + \seq_gput_right:Nn \g__chemnum_defined_compounds_seq {#1} + \int_gincr:N \g__chemnum_main_int + \stepcounter{cmpdmain} + } + \seq_if_exist:cF { g__chemnum_#1_initiated_subcompounds_seq } + { \seq_new:c { g__chemnum_#1_initiated_subcompounds_seq } } + } + +% #1: main ID +% #2: sub ID +\cs_new_protected:Npn \chemnum_define_subcompound:nn #1#2 + { + \chemnum_initialize_subcompound:nn {#1} {#2} + \chemnum_subcompound_declare_properties:nnn {#1} {#2} + { + ID , + main-compound , + number , + counter-representation + } + \chemnum_subcompound_set_property:nnnn {#1} {#2} {ID} {#2} + \chemnum_subcompound_set_property:nnnn {#1} {#2} {main-compound} {#1} + \chemnum_subcompound_set_property:nnnx {#1} {#2} {number} + { \int_use:c { g__chemnum_compound_#1_subcompound_int } } + \chemnum_subcompound_set_property:nnnx {#1} {#2} {counter-representation} + { + \__chemnum_label_format:cV + { g__chemnum_compound_#1_subcompound_int } + \l__chemnum_default_subcounter_representation_tl + } + } + +\cs_new_protected:Npn \chemnum_finalize_subcompound:nn #1#2 + { + \chemnum_save_subcompound_to_auxfile:nn {#1} {#2} + \chemnum_subcompound_update_properties:nn {#1} {#2} + \chemnum_log_sub:nn {#1} {#2} + } + +\cs_new_protected:Npn \chemnum_initialize_subcompound:nn #1#2 + { + \int_if_exist:cF { g__chemnum_compound_#1_subcompound_int } + { \int_new:c { g__chemnum_compound_#1_subcompound_int } } + \int_gincr:c { g__chemnum_compound_#1_subcompound_int } + \seq_if_exist:cF { g__chemnum_compound_#1_subcompounds_seq } + { \seq_new:c { g__chemnum_compound_#1_subcompounds_seq } } + \prop_if_exist:cF { g__chemnum_compound_#1_subcompounds_prop } + { \prop_new:c { g__chemnum_compound_#1_subcompounds_prop } } + \seq_if_in:cnF { g__chemnum_compound_#1_subcompounds_seq } {#2} + { \seq_gput_right:cn { g__chemnum_compound_#1_subcompounds_seq } {#2} } + \seq_gput_right:Nn \g__chemnum_compound_defined_subcompounds_seq {#1#2} + \prop_gput:cnx { g__chemnum_compound_#1_subcompounds_prop } {#2} + { + \int_use:c { g__chemnum_compound_#1_subcompound_int } : + \__chemnum_label_format:cV + { g__chemnum_compound_#1_subcompound_int } + \l__chemnum_default_subcounter_representation_tl + } + } + +% ---------------------------------------------------------------------------- +\cs_new_protected:Npn \chemnum_log_main:n #1 + { + \bool_if:NT \l__chemnum_log_bool + { + \bool_if:NTF \l__chemnum_log_verbose_bool + { \msg_log:nnn {chemnum} {log-compound-verbose} {#1} } + { \msg_log:nnn {chemnum} {log-compound-silent} {#1} } + } + } + +\cs_new_protected:Npn \chemnum_log_sub:nn #1#2 + { + \bool_if:NT \l__chemnum_log_bool + { + \bool_if:NTF \l__chemnum_log_verbose_bool + { \msg_log:nnnn {chemnum} {log-subcompound-verbose} {#1} {#2} } + { \msg_log:nnnn {chemnum} {log-subcompound-silent} {#1} {#2} } + } + } + +% ---------------------------------------------------------------------------- +% #1: ID +\prg_new_protected_conditional:Npnn \chemnum_compound_if_initiated:n #1 + { T,F,TF } + { + \seq_if_in:NnTF \g__chemnum_initiated_compounds_seq {#1} + { \prg_return_true: } + { \prg_return_false: } + } + +% #1: main ID +% #2: sub ID +\prg_new_protected_conditional:Npnn \chemnum_subcompound_if_initiated:nn #1#2 + { T,F,TF } + { + \seq_if_in:cnTF { g__chemnum_#1_initiated_subcompounds_seq } {#2} + { \prg_return_true: } + { \prg_return_false: } + } + +% #1: ID +\prg_new_protected_conditional:Npnn \chemnum_compound_if_defined:n #1 + { T,F,TF } + { + \seq_if_in:NnTF \g__chemnum_defined_compounds_seq {#1} + { \prg_return_true: } + { \prg_return_false: } + } + +% #1: main ID +% #2: sub ID +\prg_new_protected_conditional:Npnn \chemnum_subcompound_if_defined:nn #1#2 + { T,F,TF } + { + \seq_if_in:NnTF \g__chemnum_compound_defined_subcompounds_seq {#1#2} + { \prg_return_true: } + { \prg_return_false: } + } + +% ---------------------------------------------------------------------------- +% #1: ID +% #2: property to be defined +\cs_new_protected:Npn \chemnum_compound_declare_property:nn #1#2 + { + \seq_if_exist:cF { g__chemnum_compound_#1_properties_seq } + { \seq_new:c { g__chemnum_compound_#1_properties_seq } } + \prop_if_exist:cF { g__chemnum_compound_#1_prop } + { \prop_new:c { g__chemnum_compound_#1_prop } } + \seq_if_in:cnF { g__chemnum_compound_#1_properties_seq } {#2} + { \seq_gput_right:cn { g__chemnum_compound_#1_properties_seq } {#2} } + } + +% #1: ID +% #2: properties to be defined +\cs_new_protected:Npn \chemnum_compound_declare_properties:nn #1#2 + { + \clist_map_inline:nn {#2} + { \chemnum_compound_declare_property:nn {#1} {##1} } + } + +% #1: ID +% #2: property to be set +% #3: value of property +\cs_new_protected:Npn \chemnum_compound_set_property:nnn #1#2#3 + { + \seq_if_in:cnTF { g__chemnum_compound_#1_properties_seq } {#2} + { \prop_gput:cnn { g__chemnum_compound_#1_prop } {#2} {#3} } + { \msg_error:nnn {chemnum} {property-undefined} {#1} {#2} } + } +\cs_generate_variant:Nn \chemnum_compound_set_property:nnn { nnV , nnx } + +% #1: ID +% #2: property to be updated +\cs_new_protected:Npn \chemnum_compound_update_property:nn #1#2 + { + \seq_if_in:cnTF { g__chemnum_compound_#1_properties_seq } {#2} + { + \prop_get:cnN { g__chemnum_compound_#1_prop } {previous-#2} + \l__chemnum_tmpa_tl + \prop_get:cnN { g__chemnum_compound_#1_prop } {#2} + \l__chemnum_tmpb_tl + \tl_if_eq:NNF \l__chemnum_tmpb_tl \l__chemnum_tmpa_tl + { + \prop_gput:cnV { g__chemnum_compound_#1_prop } + {previous-#2} + \l__chemnum_tmpb_tl + } + } + { \msg_error:nnn {chemnum} {property-undefined} {#1} {#2} } + } + +% #1: ID +\cs_new_protected:Npn \chemnum_compound_update_properties:n #1 + { + \seq_map_inline:cn { g__chemnum_compound_#1_properties_seq } + { \chemnum_compound_update_property:nn {#1} {##1} } + } + +% #1: main ID +% #2. sub ID +% #3: property to be defined +\cs_new_protected:Npn \chemnum_subcompound_declare_property:nnn #1#2#3 + { + \seq_if_in:cnF { g__chemnum_compound_#1_#2_properties_seq } {#3} + { \seq_gput_right:cn { g__chemnum_compound_#1_#2_properties_seq } {#3} } + } + +% #1: main ID +% #2. sub ID +% #3: properties to be defined +\cs_new_protected:Npn \chemnum_subcompound_declare_properties:nnn #1#2#3 + { + \seq_if_exist:cF { g__chemnum_compound_#1_#2_properties_seq } + { \seq_new:c { g__chemnum_compound_#1_#2_properties_seq } } + \prop_if_exist:cF { g__chemnum_compound_#1_#2_properties_prop } + { \prop_new:c { g__chemnum_compound_#1_#2_properties_prop } } + \clist_map_inline:nn { #3 } + { \chemnum_subcompound_declare_property:nnn {#1} {#2} {##1} } + } + +% #1: main ID +% #2: sub ID +% #3: property to be set +% #4: value of property +\cs_new_protected:Npn \chemnum_subcompound_set_property:nnnn #1#2#3#4 + { + \seq_if_in:cnTF { g__chemnum_compound_#1_#2_properties_seq } {#3} + { \prop_gput:cnn { g__chemnum_compound_#1_#2_properties_prop } {#3} {#4} } + { \msg_error:nnn {chemnum} {property-undefined} {#1.#2} {#3} } + } +\cs_generate_variant:Nn \chemnum_subcompound_set_property:nnnn { nnnV , nnnx } + +% #1: main ID +% #2. sub ID +% #3: property to be updated +\cs_new_protected:Npn \chemnum_subcompound_update_property:nnn #1#2#3 + { + \seq_if_in:cnTF { g__chemnum_compound_#1_#2_properties_seq } + { + \prop_get:cnN { g__chemnum_compound_#1_#2_properties_prop } {previous-#3} + \l__chemnum_tmpa_tl + \prop_get:cnN { g__chemnum_compound_#1_#2_properties_prop } {#3} + \l__chemnum_tmpb_tl + \tl_if_eq:NNF \l__chemnum_tmpb_tl \l__chemnum_tmpa_tl + { + \prop_gput:cnV { g__chemnum_compound_#1_#2_properties_prop } + {previous-#3} + \l__chemnum_tmpb_tl + } + } + { \msg_error:nnn {chemnum} {property-undefined} {#1.#2} {#3} } + } + +% #1: main ID +% #2: sub ID +\cs_new_protected:Npn \chemnum_subcompound_update_properties:nn #1#2 + { + \seq_map_inline:cn { g__chemnum_compound_#1_#2_properties_seq } + { \chemnum_subcompound_update_property:nnn {#1} {#2} {##1} } + } + +% #1: ID +% #2: property +\cs_new_protected:Npn \chemnum_get_compound_property:nn #1#2 + { \chemnum_get_compound_property_or:nnn {#1} {#2} { } } + +\cs_new_protected:Npn \chemnum_get_compound_property_or:nnn #1#2#3 + { + \prop_get:cnNTF { g__chemnum_compound_#1_prop } {#2} + \l__chemnum_tmpa_tl + { \tl_use:N \l__chemnum_tmpa_tl } + {#3} + } + +\cs_new:Npn \chemnum_expandable_get_compound_property:nn #1#2 + { \prop_item:cn { g__chemnum_compound_#1_prop } {#2} } +\cs_generate_variant:Nn \chemnum_expandable_get_compound_property:nn { V } + +% #1: main ID +% #2: sub ID +% #3: property +\cs_new_protected:Npn \chemnum_get_subcompound_property:nnn #1#2#3 + { \chemnum_get_subcompound_property_or:nnnn {#1} {#2} {#3} { } } + +\cs_new_protected:Npn \chemnum_get_subcompound_property_or:nnnn #1#2#3#4 + { + \prop_get:cnNTF { g__chemnum_compound_#1_#2_properties_prop } {#3} + \l__chemnum_tmpa_tl + { \tl_use:N \l__chemnum_tmpa_tl } + {#4} + } + +\cs_new:Npn \chemnum_expandable_get_subcompound_property:nnn #1#2#3 + { \prop_item:cn { g__chemnum_compound_#1_#2_properties_prop } {#3} } + +% ---------------------------------------------------------------------------- +\DeclareExpandableDocumentCommand \cmpdproperty { mm } + { \chemnum_expandable_get_compound_property:nn {#1} {#2} } + +\DeclareExpandableDocumentCommand \subcmpdproperty { mmm } + { \chemnum_expandable_get_subcompound_property:nnn {#1} {#2} {#3} } + +% ---------------------------------------------------------------------------- +% initiating subcompounds: + +% #1: main ID +% #2: sub ID +\cs_new_protected:Npn \chemnum_initiate_subcompound:nn #1#2 + { + \chemnum_subcompound_if_initiated:nnF {#1} {#2} + { \seq_gput_right:cn { g__chemnum_#1_initiated_subcompounds_seq } {#2} } + } + +% ---------------------------------------------------------------------------- + +% saving compounds to the auxilliary file: +% #1: ID +% #2: counter value +% #3: counter representation +% #4: pre label +% #5: post label +% #6: pre main label +% #7: post main label +% #8: label format +\cs_new_protected:Npn \__chemnum_write_compound_to_auxfile_x:nnnnnnnn #1#2#3#4#5#6#7#8 + { + \if@filesw + \token_if_eq_meaning:NNT \@nodocument \relax + { + \iow_now:Nx \@auxout + { \exp_not:N \chemnum@cmpd {#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8} } + } + \fi + } +\cs_generate_variant:Nn \__chemnum_write_compound_to_auxfile_x:nnnnnnnn { nnnVVVVV } + +\cs_new_protected:Npn \chemnum_save_compound_to_auxfile:n #1 + { + \__chemnum_write_compound_to_auxfile_x:nnnnnnnn {#1} + { \chemnum_expandable_get_compound_property:nn {#1} {number} } + { \chemnum_expandable_get_compound_property:nn {#1} {counter-representation} } + { \chemnum_expandable_get_compound_property:nn {#1} {pre-label-code} } + { \chemnum_expandable_get_compound_property:nn {#1} {post-label-code} } + { \chemnum_expandable_get_compound_property:nn {#1} {pre-main-label-code} } + { \chemnum_expandable_get_compound_property:nn {#1} {post-main-label-code} } + { \chemnum_expandable_get_compound_property:nn {#1} {label-format} } + } + +% #1: main ID +% #2: sub ID +% #2: counter value +% #3: counter representation +\cs_new_protected:Npn \__chemnum_write_subcompound_to_auxfile_x:nnnn #1#2#3#4 + { + \if@filesw + \token_if_eq_meaning:NNT \@nodocument \relax + { + \iow_now:Nx \@auxout + { \exp_not:N \chemnum@subcmpd {#1}{#2}{#3}{#4} } + } + \fi + } + +\cs_new_protected:Npn \chemnum_save_subcompound_to_auxfile:nn #1#2 + { + \__chemnum_write_subcompound_to_auxfile_x:nnnn {#1} {#2} + { + \chemnum_expandable_get_subcompound_property:nnn {#1} {#2} + {number} + } + { + \chemnum_expandable_get_subcompound_property:nnn {#1} {#2} + {counter-representation} + } + } + +% ---------------------------------------------------------------------------- +% #1: ID +% #2: counter value +% #3: counter representation +% #4: pre label +% #5: post label +% #6: pre main label +% #7: post main label +% #8: label format +\cs_new_protected:Npn \chemnum@cmpd #1#2#3#4#5#6#7#8 + { + % \chemnum_initialize_compound:n {#1} + \prop_if_exist:cF { g__chemnum_compound_#1_prop } + { \prop_new:c { g__chemnum_compound_#1_prop } } + \prop_gput:cnn { g__chemnum_compound_#1_prop } + {previous-number} {#2} + \prop_gput:cnn { g__chemnum_compound_#1_prop } + {previous-counter-representation} {#3} + \prop_gput:cnn { g__chemnum_compound_#1_prop } + {previous-pre-label-code} {#4} + \prop_gput:cnn { g__chemnum_compound_#1_prop } + {previous-post-label-code} {#5} + \prop_gput:cnn { g__chemnum_compound_#1_prop } + {previous-pre-main-label-code} {#6} + \prop_gput:cnn { g__chemnum_compound_#1_prop } + {previous-post-main-label-code} {#7} + \prop_gput:cnn { g__chemnum_compound_#1_prop } + {previous-label-format} {#8} + } + +% #1: main ID +% #2: sub ID +% #3: counter value +% #4: counter representation +\cs_new_protected:Npn \chemnum@subcmpd #1#2#3#4 + { + \prop_if_exist:cF { g__chemnum_compound_#1_#2_properties_prop } + { \prop_new:c { g__chemnum_compound_#1_#2_properties_prop } } + \seq_if_exist:cF { g__chemnum_compound_#1_subcompounds_seq } + { \seq_new:c { g__chemnum_compound_#1_subcompounds_seq } } + \seq_if_in:cnF { g__chemnum_compound_#1_subcompounds_seq } {#2} + { \seq_gput_right:cn { g__chemnum_compound_#1_subcompounds_seq } {#2} } + \prop_gput:cnn { g__chemnum_compound_#1_#2_properties_prop } + {previous-number} {#3} + \prop_gput:cnn { g__chemnum_compound_#1_#2_properties_prop } + {previous-counter-representation} {#4} + } + +% ---------------------------------------------------------------------------- +% declaring and writing compounds: + +% #1: options +% #2: ID +\cs_new_protected:Npn \chemnum_declare_compound:nn #1#2 + { + \tl_if_blank:nF {#1} + { \keys_set_groups:nnn {chemnum} {compound} { local=true , #1 } } + \chemnum_compound_if_initiated:nF {#2} + { + \bool_if:NT \g__chemnum_initiate_bool + { + \bool_if:NTF \g__chemnum_initiate_strict_bool + { \msg_error:nnn {chemnum} {compound-not-initiated} {#2} } + { \msg_warning:nnn {chemnum} {compound-not-initiated} {#2} } + } + \bool_if:NT \l__chemnum_show_def_bool + { \cmpdshowdef { #2 } } + \bool_set_false:N \l__chemnum_show_ref_bool + \chemnum_initiate_compound:n {#2} + } + \chemnum_compound_if_defined:nTF {#2} + { \chemnum_set_compound:n {#2} } + { + \chemnum_define_compound:n {#2} + \chemnum_finalize_compound:n {#2} + } + } + +% #1: options +% #2: main ID +% #3: sub ID +\cs_new_protected:Npn \chemnum_declare_subcompound:nnn #1#2#3 + { + % \keys_set:nn {chemnum} {#1} + \chemnum_subcompound_if_initiated:nnF {#2} {#3} + { + \bool_if:NT \g__chemnum_initiate_sub_bool + { + \bool_if:NTF \g__chemnum_initiate_strict_bool + { + \msg_error:nnnn {chemnum} {subcompound-not-initiated} + {#2} {#3} + } + { + \msg_warning:nnnn {chemnum} {subcompound-not-initiated} + {#2} {#3} + } + } + \bool_if:NT \l__chemnum_show_def_bool + { \subcmpdshowdef { #2 } { #3 } } + \bool_set_false:N \l__chemnum_show_ref_bool + \chemnum_initiate_subcompound:nn {#2} {#3} + } + \chemnum_subcompound_if_defined:nnF {#2} {#3} + { + \chemnum_define_subcompound:nn {#2} {#3} + \chemnum_finalize_subcompound:nn {#2} {#3} + } + } + +\cs_new_protected:Npn \chemnum_compound_start:n #1 + { + \bool_if:NF \l__chemnum_sub_only_bool + { \chemnum_get_compound_property:nn {#1} {pre-label-code} } + } + +\cs_new:Npn \chemnum_expandable_compound_start:n #1 + { + \bool_if:NF \l__chemnum_sub_only_bool + { + \chemnum_expandable_get_compound_property:nn {#1} + {previous-pre-label-code} + } + } + +\cs_new_protected:Npn \chemnum_compound_finish:n #1 + { + \bool_if:NF \l__chemnum_sub_only_bool + { \chemnum_get_compound_property:nn {#1} {post-label-code} } + } + +\cs_new:Npn \chemnum_expandable_compound_finish:n #1 + { + \bool_if:NF \l__chemnum_sub_only_bool + { + \chemnum_expandable_get_compound_property:nn {#1} + {previous-post-label-code} + } + } + +% actively write a compound: +% #1: ID +\cs_new_protected:Npn \chemnum_compound_write:n #1 + { + \chemnum_get_compound_property:nn {#1} {pre-main-label-code} + \group_begin: + \bool_if:NTF \l__chemnum_compound_local_bool + { \l__chemnum_local_label_format_tl } + { \chemnum_get_compound_property:nn {#1} {label-format} } + { \chemnum_get_compound_property:nn {#1} {counter-representation} } + \group_end: + \chemnum_get_compound_property:nn {#1} {post-main-label-code} + } + +% actively write a subcompound: +% #1: main ID +% #2: sub ID +\cs_new_protected:Npn \chemnum_subcompound_write:nn #1#2 + { + \group_begin: + \bool_if:NTF \l__chemnum_compound_local_bool + { \l__chemnum_local_label_format_tl } + { \chemnum_get_compound_property:nn {#1} {label-format} } + { + \chemnum_get_subcompound_property:nnn {#1} {#2} + {counter-representation} + } + \group_end: + } + +% this is only provided for use in PDF strings: +\cs_new:Npn \chemnum_expandable_compound_write:n #1 + { + \chemnum_expandable_get_compound_property:nn {#1} {pre-main-label-code} + \chemnum_expandable_get_compound_property:nn {#1} {counter-representation} + \chemnum_expandable_get_compound_property:nn {#1} {post-main-label-code} + } + +\cs_new:Npn \chemnum_expandable_subcompound_write:nn #1#2 + { + \chemnum_expandable_get_subcompound_property:nnn {#1} {#2} + {counter-representation} + } + +% read and write saved values: +% #1: ID +\cs_new_protected:Npn \chemnum_compound_read:n #1 + { + \chemnum_get_compound_property:nn {#1} {previous-pre-main-label-code} + \group_begin: + \chemnum_get_compound_property:nn {#1} {previous-label-format} + { + \chemnum_get_compound_property_or:nnn {#1} + { previous-counter-representation } + { ?? \__chemnum_rerun: } + } + \group_end: + \chemnum_get_compound_property:nn {#1} {previous-post-main-label-code} + + } + +% #1: main ID +% #2: sub ID +\cs_new_protected:Npn \chemnum_subcompound_read:nn #1#2 + { + \group_begin: + \bool_if:NTF \l__chemnum_compound_local_bool + { \l__chemnum_local_label_format_tl } + { \chemnum_get_compound_property:nn {#1} {previous-label-format} } + { + \chemnum_get_subcompound_property_or:nnnn {#1} {#2} + {previous-counter-representation} + { ?? \__chemnum_rerun: } + } + \group_end: + } + +% this is only provided for use in PDF strings: +\cs_new:Npn \chemnum_expandable_compound_read:n #1 + { + \chemnum_expandable_get_compound_property:nn {#1} {previous-pre-main-label-code} + \chemnum_expandable_get_compound_property:nn {#1} {previous-counter-representation} + \chemnum_expandable_get_compound_property:nn {#1} {previous-post-main-label-code} + } + +\cs_new:Npn \chemnum_expandable_subcompound_read:nn #1#2 + { + \chemnum_expandable_get_subcompound_property:nnn {#1} {#2} + {previous-counter-representation} + } + +% #1: boolean: if true register compound but don't write the label +% #2: boolean: if true only read compound +% #3: write == true and read == false +% #4: write == true and read == true +\cs_new:Npn \chemnum_if_write_and_or_read:NNTF #1#2 + { + \bool_if:NTF #1 + { \use_none:nn } + { + \bool_if:NTF #2 + { \use_ii:nn } + { \use_i:nn } + } + } + +% write a label from the entries of \cmpd: +% #1: boolean: if true register compound but don't write the label +% #2: boolean: if true only read compound +% #3: options +% #4: label specifications +\cs_new_protected:Npn \chemnum_single_compound:NNnn #1#2#3#4 + { + \bool_if:NT #1 { \@bsphack } + \group_begin: + \chemnum_split_sub_from_main:VNNnn + \l__chemnum_compound_separator_tl + #1 #2 {#3} {#4} + \group_end: + \bool_if:NT {#1} { \@esphack } + } + +% #1: label separator +% #2: boolean: if true register compound but don't write the label +% #3: boolean: if true only read compound +% #4: options +% #5: label spec +\cs_new_protected:Npn \chemnum_split_sub_from_main:nNNnn #1#2#3#4#5 + { + \cs_set:Npn \__chemnum_split_sub_from_main_aux:nnnw ##1##2##3##4#1##5#1##6 \q_stop + { + \bool_if:NF ##2 { \chemnum_declare_compound:nn {##3} {##4} } + \keys_set_groups:nnn {chemnum} {sub-only} {#4} + \chemnum_if_write_and_or_read:NNTF #2 #3 + { \chemnum_compound_start:n {##4} } + { \chemnum_expandable_compound_start:n {##4} } + % shis is in the compound_write command: + \chemnum_write_main:nnnn {##1} {##2} {##3} {##4} + \bool_if:nT + { + !\l__chemnum_sub_all_bool && + !\tl_if_blank_p:n {##5} + } + { \chemnum_write_sublist:NNnnn ##1 ##2 {##3} {##4} {##5} } + \bool_if:NT \l__chemnum_sub_all_bool + { + \tl_clear:N \l__chemnum_tmpa_tl + \tl_set:Nx \l__chemnum_tmpa_tl + { \seq_use:cn { g__chemnum_compound_##4_subcompounds_seq } { , } } + \tl_if_blank:VF \l__chemnum_tmpa_tl + { + \chemnum_write_sublist:NNnnV ##1 ##2 {##3} {##4} + \l__chemnum_tmpa_tl + } + } + \chemnum_if_write_and_or_read:NNTF #2 #3 + { \chemnum_compound_finish:n {##4} } + { \chemnum_expandable_compound_finish:n {##4} } + } + \__chemnum_split_sub_from_main_aux:nnnw {#2} {#3} {#4} #5#1#1 \q_stop + } +\cs_generate_variant:Nn \chemnum_split_sub_from_main:nNNnn { V } + +\cs_new:Npn \__chemnum_split_sub_from_main_aux:nnnw #1#2#3#4.#5.#6 \q_stop {} + +% \chemnum_write_main:nnnn will write the main label, either with saved +% values (+ variant, boolean #2=true), or only register it (* variant, boolean +% #1=true) +% +% #1: boolean: if true register compound but don't write the label +% #2: boolean: if true only read compound +% #3: options +% #4: label spec +\cs_new_protected:Npn \chemnum_write_main:nnnn #1#2#3#4 + { + \bool_if:NTF #2 + { + \chemnum_hyper_link:nn {#4} + { \chemnum_compound_read:n {#4} } + \bool_if:NT #1 + { \msg_error:nn {chemnum} {erroneous-argument-combination} } + } + { + \bool_if:NT \l__chemnum_show_ref_bool + { \cmpdshowref {#4} } + \bool_if:nF + { #1 || \l__chemnum_sub_only_bool } + { + \chemnum_if_compound_used:nTF {#4} + { \chemnum_hyper_link:nn {#4} } + { + \chemnum_use_compound:n {#4} + \chemnum_hyper_target:nn {#4} + } + { \chemnum_compound_write:n {#4} } + } + } + } + +% ---------------------------------------------------------------------------- +% use this for determining wether we need a hyperlink or hypertarget: +\seq_new:N \g__chemnum_used_compounds_seq + +\prg_new_conditional:Npnn \chemnum_if_compound_used:n #1 {p,T,F,TF} + { + \seq_if_in:NnTF \g__chemnum_used_compounds_seq {#1} + { \prg_return_true: } + { \prg_return_false: } + } + +\cs_new_protected:Npn \chemnum_use_compound:n #1 + { \seq_gput_right:Nn \g__chemnum_used_compounds_seq {#1} } + +% ---------------------------------------------------------------------------- +% hyperlinks: + +\cs_new_eq:NN \chemnum_hyper_target:nn \use_ii:nn +\cs_new_eq:NN \chemnum_hyper_link:nn \use_ii:nn + +\AtBeginDocument + { + % TODO: add boolean which allows en- and disabling the mechanism; disable + % it per default + \@ifpackageloaded {hyperref} + { + \bool_if:NT \l__chemnum_hyperlinks_bool + { + \cs_set_eq:NN \chemnum_hyper_link:nn \hyperlink + \cs_set:Npn \chemnum_hyper_target:nn #1#2 + { \raisebox {3ex} [0pt] { \hypertarget {#1} {} } #2 } + } + } + {} + } + +% ---------------------------------------------------------------------------- +\cs_set_protected:Npn \chemnum_show_key_def:n #1 + { \marginpar { \fbox { \normalfont \ttfamily #1 } } } + +\cs_set_protected:Npn \chemnum_show_key_ref:n #1 + { + \group_begin: + \hbox_unpack:N \c_empty_box % this is \leavevmode + \vbox_to_zero:n + { + \tex_vss:D + \hbox_overlap_right:n + { + \tex_vrule:D \tex_raise:D .75em + \hbox:n + { \underbar { \normalfont \footnotesize \ttfamily #1 } } + } + } + \group_end: + } + +% ---------------------------------------------------------------------------- +\NewDocumentCommand \chemnumshowdef {m} + { \chemnum_show_key_def:n {#1} } +\NewDocumentCommand \chemnumshowref {m} + { \chemnum_show_key_ref:n {#1} } + +\NewDocumentCommand \cmpdshowdef {m} { \chemnumshowdef {#1} } +\NewDocumentCommand \cmpdshowref {m} { \chemnumshowref {#1} } +\NewDocumentCommand \subcmpdshowdef {mm} { \chemnumshowdef {#2~(#1)} } +\NewDocumentCommand \subcmpdshowref {mm} { \chemnumshowref {#2} } + +% ---------------------------------------------------------------------------- +% #1: boolean: if true register compound but don't write the label +% #2: boolean: if true only read compound +% #3: options +% #4: main label id +% #5: sublabel list +\cs_new_protected:Npn \chemnum_write_sublist:NNnnn #1#2#3#4#5 + { + \seq_set_split:NVn + \l__chemnum_tmpc_seq + \l__chemnum_sub_separator_tl + {#5} + \seq_remove_duplicates:N \l__chemnum_tmpc_seq + \seq_map_inline:Nn \l__chemnum_tmpc_seq + { + \bool_if:NF #2 + { \chemnum_declare_subcompound:nnn {#3} {#4} {##1} } + } + \seq_clear:N \l__chemnum_tmpd_seq + % puts the subcompounds ready to be printed in \l__chemnum_tmpd_seq : + \chemnum_sort_subcompounds:NNNnnNN #1#2 + \l__chemnum_tmpc_seq + {#3} + {#4} + \l__chemnum_tmpd_seq % to write the uncompressed list + \l__chemnum_tmpe_seq % for compressing the list, holds the numbers + \bool_if:nTF + { + \l__chemnum_compress_subcompounds_bool + && + \int_compare_p:n { \seq_count:N \l__chemnum_tmpe_seq > 2 } + } + { + % needs a seq with the associated /numbers/! + \chemnum_compress_subcompounds:NNN + \l__chemnum_tmpd_seq % holds the IDs + \l__chemnum_tmpe_seq % holds the numbers + \l__chemnum_tmpc_seq % the new sequence + \seq_use:Nn \l__chemnum_tmpc_seq {} + } + { + \seq_use:NVVV \l__chemnum_tmpd_seq + \l__chemnum_sep_sublist_two_tl + \l__chemnum_sep_sublist_more_tl + \l__chemnum_sep_sublist_last_two_tl + } + } +\cs_generate_variant:Nn \chemnum_write_sublist:NNnnn { NNnnV } + +% #1: boolean: if true register compound but don't write the label +% #2: boolean: if true only read compound +% #3: options +% #4: main ID +% #5: sub ID +\cs_new_protected:Npn \chemnum_write_subcompound:NNnnn #1#2#3#4#5 + { + \bool_if:NTF #2 + { \chemnum_subcompound_read:nn {#4} {#5} } + { + \chemnum_declare_subcompound:nnn {#3} {#4} {#5} + \bool_if:NT \l__chemnum_show_ref_bool + { \subcmpdshowref { #4 } { #5 } } + \bool_if:NF #1 + { \chemnum_subcompound_write:nn {#4} {#5} } + } + } +\cs_generate_variant:Nn \chemnum_write_subcompound:NNnnn { NNnnV } + +%%% The following command sorts the sequence according to the order in which +%%% they've been declared +% #1: boolean: if true register compound but don't write the label +% #2: boolean: if true only read compound +% #3: sub ID sequence +% #4: options +% #5: main ID +% #6: seq variable +% #7: seq variable +\cs_new_protected:Npn \chemnum_sort_subcompounds:NNNnnNN #1#2#3#4#5#6#7 + { + \seq_clear:N #6 + \seq_clear:N #7 + \bool_if:NF #1 + { + \seq_map_inline:cn { g__chemnum_compound_#5_subcompounds_seq } + { + \seq_if_in:NnT #3 {##1} + { + \seq_put_right:Nn #6 + { \chemnum_write_subcompound:NNnnn #1 #2 {#4} {#5} {##1} } + \bool_if:NTF #2 + { + \seq_put_right:Nx #7 + { + \chemnum_expandable_get_subcompound_property:nnn + {#5} {##1} {previous-number} + } + } + { + \seq_put_right:Nx #7 + { + \chemnum_expandable_get_subcompound_property:nnn + {#5} {##1} {number} + } + } + } + } + } + } + +% #1: sub ID sequence +% #2: sub ID sequence that holds the numbers rather than the IDs +% #3: seq variable +\cs_new_protected:Npn \chemnum_compress_subcompounds:NNN #1#2#3 + { + \int_zero:N \l__chemnum_tmpa_int + \int_zero:N \l__chemnum_tmpb_int + \seq_clear:N \l__chemnum_tmpa_seq + \seq_clear:N #3 + \seq_map_inline:Nn #2 + { + \int_incr:N \l__chemnum_tmpa_int + \int_compare:nTF { \l__chemnum_tmpa_int = 1 } + { \seq_put_right:Nn \l__chemnum_tmpa_seq { 1 } } + { + \seq_put_right:Nx \l__chemnum_tmpa_seq + { \int_eval:n { ##1 - \l__chemnum_tmpb_int } } + } + \int_set:Nn \l__chemnum_tmpb_int { ##1 } + } + \int_zero:N \l__chemnum_tmpa_int + \int_set:Nn \l__chemnum_tmpb_int { \seq_count:N #2 } + \int_zero:N \l__chemnum_tmpc_int + \seq_map_inline:Nn \l__chemnum_tmpa_seq + { + \int_incr:N \l__chemnum_tmpa_int + \int_compare:nTF { \l__chemnum_tmpa_int = 1 } + { + \int_add:Nn \l__chemnum_tmpc_int { ##1 } + \seq_put_right:Nx #3 { \seq_item:Nn #1 { 1 } } + } + { + \int_compare:nTF { ##1 = 1 } + { \int_add:Nn \l__chemnum_tmpc_int { ##1 } } + { + \int_compare:nTF { \l__chemnum_tmpc_int > 2 } + { + \seq_put_right:NV #3 \l__chemnum_sep_sublist_range_tl + \seq_put_right:Nx #3 + { \seq_item:Nn #1 { \l__chemnum_tmpa_int - 1 } } + \seq_put_right:NV #3 \l__chemnum_sep_sublist_two_tl + \seq_put_right:Nx #3 + { \seq_item:Nn #1 { \l__chemnum_tmpa_int } } + } + { + \seq_get_right:NN #3 \l__chemnum_tmpa_tl + \tl_if_eq:VxF + \l__chemnum_tmpa_tl + { \seq_item:Nn #1 { \l__chemnum_tmpa_int - 1 } } + { + \seq_put_right:NV #3 \l__chemnum_sep_sublist_two_tl + \seq_put_right:Nx #3 + { \seq_item:Nn #1 { \l__chemnum_tmpa_int - 1 } } + } + \seq_put_right:NV #3 \l__chemnum_sep_sublist_two_tl + \seq_put_right:Nx #3 + { \seq_item:Nn #1 { \l__chemnum_tmpa_int } } + } + \int_set:Nn \l__chemnum_tmpc_int { 1 } + } + \int_compare:nT { \l__chemnum_tmpa_int = \l__chemnum_tmpb_int } + { + \seq_get_right:NN #3 \l__chemnum_tmpa_tl + \tl_if_eq:VxF + \l__chemnum_tmpa_tl + { \seq_item:Nn #1 { \l__chemnum_tmpa_int } } + { + \int_compare:nTF { \l__chemnum_tmpc_int > 2 } + { \seq_put_right:NV #3 \l__chemnum_sep_sublist_range_tl } + { \seq_put_right:NV #3 \l__chemnum_sep_sublist_last_two_tl } + \seq_put_right:Nx #3 + { \seq_item:Nn #1 { \l__chemnum_tmpa_int } } + } + } + } + } + } + +% ---------------------------------------------------------------------------- +% the code level version of the main command: +% #1: boolean: if true register compound but don't write the label +% #2: boolean: if true only read compound +% #3: options +% #4: list of IDs +\cs_new_protected:Npn \chemnum_cmpd:nnnn #1#2#3#4 + { + \group_begin: + \keys_set_groups:nnn {chemnum} {list} {#3} + \seq_set_split:NVn + \l__chemnum_tmpa_seq + \l__chemnum_main_separator_tl + {#4} + \seq_remove_duplicates:N \l__chemnum_tmpa_seq + \chemnum_sort_main_labels:N \l__chemnum_tmpa_seq + \seq_clear:N \l__chemnum_tmpb_seq + \seq_map_inline:Nn \l__chemnum_tmpa_seq + { + \seq_put_right:Nn \l__chemnum_tmpb_seq + { \chemnum_single_compound:NNnn #1 #2 {#3} {##1} } + } + \bool_if:NTF #1 % starred call of \cmpd + { \seq_use:Nn \l__chemnum_tmpb_seq {} } + { + \seq_use:NVVV \l__chemnum_tmpb_seq + \l__chemnum_sep_list_two_tl + \l__chemnum_sep_list_more_tl + \l__chemnum_sep_list_last_two_tl + } + \group_end: + } + +% #1: first variable +% #2: second variable +% #3: main/sub separator +% #4: complete label +\cs_new_protected:Npn \chemnum_separate_main_sub:NNnn #1#2#3#4 + { + \cs_set:Npn \__chemnum_remove_sub:w ##1#3##2 \q_stop + { \exp_not:n { ##1 } } + \cs_set:Npn \__chemnum_get_sub:w ##1#3##2#3##3 \q_stop + { + \tl_if_blank:nF {##2} { \exp_not:n { ##2 } } + } + \tl_set:Nx #1 { \__chemnum_remove_sub:w #4#3 \q_stop } + \tl_set:Nx #2 { \__chemnum_get_sub:w #4#3#3 \q_stop } + } +\cs_generate_variant:Nn \chemnum_separate_main_sub:NNnn { NNV } + +% sorting and merging of the main label list: +% #1: seq that holds the label list +\cs_new_protected:Npn \chemnum_sort_main_labels:N #1 + { + \prop_clear:N \l__chemnum_tmpa_prop + \seq_clear:N \l__chemnum_tmpb_seq + \seq_clear:N \l__chemnum_tmpc_seq + % build property list that holds entries of #1: + \seq_map_inline:Nn #1 + { + \chemnum_separate_main_sub:NNVn + \l__chemnum_tmpa_tl % main part + \l__chemnum_tmpb_tl % sub part + \l__chemnum_compound_separator_tl + {##1} + \bool_if:NTF \l__chemnum_merge_list_bool + { + \prop_get:NVNTF \l__chemnum_tmpa_prop + \l__chemnum_tmpa_tl + \l__chemnum_tmpc_tl + { + \prop_put:NVx \l__chemnum_tmpa_prop + \l__chemnum_tmpa_tl + { + \exp_not:V \l__chemnum_tmpc_tl + \exp_not:V \l__chemnum_sub_separator_tl + \exp_not:V \l__chemnum_tmpb_tl + } + } + { + \prop_put:NVV \l__chemnum_tmpa_prop + \l__chemnum_tmpa_tl + \l__chemnum_tmpb_tl + } + } + { + \prop_get:NVNTF \l__chemnum_tmpa_prop + \l__chemnum_tmpa_tl + \l__chemnum_tmpc_tl + { + \prop_put:NVx \l__chemnum_tmpa_prop + \l__chemnum_tmpa_tl + { + \exp_not:V \l__chemnum_tmpc_tl + \exp_not:V \l__chemnum_main_separator_tl + \exp_not:n {##1} + } + } + { + \prop_put:NVn \l__chemnum_tmpa_prop + \l__chemnum_tmpa_tl + {##1} + } + } + } + % merge = true: + % \l__chemnum_tmpa_prop now holds all main labels with possible sublabel + % lists + % merge = false + % \l__chemnum_tmpa_prop now holds all main labels with all occurences of + % the respective main label as property + % + % build sequence that holds entries of #1 in order of already defined + % labels: + \seq_map_inline:Nn \g__chemnum_defined_compounds_seq + { + \bool_if:NTF \l__chemnum_merge_list_bool + { + \prop_get:NnNT \l__chemnum_tmpa_prop {##1} \l__chemnum_tmpa_tl + { + \tl_if_in:VVTF + \l__chemnum_tmpa_tl + \l__chemnum_sub_separator_tl + { + \seq_put_right:Nx \l__chemnum_tmpb_seq + { + \exp_not:n { ##1 } + \tl_if_blank:VF \l__chemnum_tmpa_tl + { + \exp_not:V \l__chemnum_compound_separator_tl + { \exp_not:V \l__chemnum_tmpa_tl } + } + } + } + { + \seq_put_right:Nx \l__chemnum_tmpb_seq + { + \exp_not:n { ##1 } + \tl_if_blank:VF \l__chemnum_tmpa_tl + { + \exp_not:V \l__chemnum_compound_separator_tl + \exp_not:V \l__chemnum_tmpa_tl + } + } + } + \seq_if_in:NnF \l__chemnum_tmpc_seq {##1} + { \seq_put_right:Nn \l__chemnum_tmpc_seq {##1} } + } + } + { + \prop_get:NnNT \l__chemnum_tmpa_prop {##1} \l__chemnum_tmpa_tl + { + \tl_if_in:VVTF + \l__chemnum_tmpa_tl + \l__chemnum_main_separator_tl + { + \seq_set_split:NVV \l__chemnum_tmpc_seq + \l__chemnum_main_separator_tl + \l__chemnum_tmpa_tl + \seq_map_inline:Nn \l__chemnum_tmpc_seq + { \seq_put_right:Nn \l__chemnum_tmpb_seq {####1} } + } + { \seq_put_right:NV \l__chemnum_tmpb_seq \l__chemnum_tmpa_tl } + } + } + } + % \l__chemnum_tmpb_seq now holds all labels that are already defined + % merge = true : + % the same \l__chemnum_tmpc_seq which only holds the /main/ labels + \bool_if:NTF \l__chemnum_merge_list_bool + { + \seq_map_inline:Nn #1 + { + \chemnum_separate_main_sub:NNVn + \l__chemnum_tmpa_tl % main part + \l__chemnum_tmpb_tl % sub part + \l__chemnum_compound_separator_tl + {##1} + % check if existing main label is present, otherwise add entry + \seq_if_in:NVF \l__chemnum_tmpc_seq \l__chemnum_tmpa_tl + { + \prop_get:NVNT \l__chemnum_tmpa_prop + \l__chemnum_tmpa_tl + \l__chemnum_tmpc_tl + { + \seq_put_right:Nx \l__chemnum_tmpb_seq + { + \exp_not:V \l__chemnum_tmpa_tl + \tl_if_blank:VF \l__chemnum_tmpc_tl + { + \exp_not:V \l__chemnum_compound_separator_tl + \exp_not:V \l__chemnum_tmpc_tl + } + } + \seq_put_right:NV \l__chemnum_tmpc_seq \l__chemnum_tmpa_tl + } + } + } + } + { + \seq_map_inline:Nn #1 + { + \seq_if_in:NnF \l__chemnum_tmpb_seq {##1} + { \seq_put_right:Nn \l__chemnum_tmpb_seq {##1} } + } + } + \seq_set_eq:NN #1 \l__chemnum_tmpb_seq + } + +% %-----------------------------------------------------------------------------% +% % REPLACE TAG IN EPS PICTURE WITH LABEL +% % works similar to \schemeref command of the chemscheme package +% % \cmpdref-[][]{