%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % - chemnum - chemnum.sty % - a comprehensive approach for the numbering of chemical compounds % ----------------------------------------------------------------------------- % - Clemens NIEDERBERGER % - contact@mychemistry.eu % ----------------------------------------------------------------------------- % - If you have any ideas, questions, suggestions or bugs to report, please % - feel free to contact me. % ----------------------------------------------------------------------------- % - Copyright 2011-2013 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. % - % - This work consists of the files % - chemnum.sty, chemnum_de.tex, chemnum_en.tex, chemnum_it.tex % - scheme-tmp.ps, scheme-bla.ps, % - README % - chemnum_de.pdf, chemnum_en.pdf, chemnum_it.pdf %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \RequirePackage { expl3 , xparse , l3keys2e , etoolbox , psfrag } \ProvidesExplPackage {chemnum} {2013/06/05} {0.6b} {a comprehensive approach for the numbering of chemical compounds} % -------------------------------------------------------------------------- % check expl3 version: \@ifpackagelater { expl3 } { 2012/11/21 } { } { \PackageError { chemnum } { Support~package~expl3~too~old } { You~need~to~update~your~installation~of~the~bundles~'l3kernel'~and~ 'l3packages'.\MessageBreak Loading~chemnum~will~abort! } \tex_endinput:D } % -------------------------------------------------------------------------- % error for missing packages \msg_set:nnnn { chemnum } { support-missing } { Support~package~#1~missing. } { Support~package~#1~seems~to~be~missing. \\ Please~install~an~up~to~date~version~of~#1. \\ } % warning, if textgreek has already been loaded AND option % "textgreek = " is used \msg_set:nnnn { chemnum } { textgreek-loaded } { The~package~textgreek~has~already~been~loaded. \\ \tl_if_blank:nF { #1 } { Option~#1~will~not~be~used. } } { The~package~textgreek~has~already~been~loaded. \\ \tl_if_blank:nF { #1 } { Option~#1~will~not~be~used. } } % textgreek support and package options: \bool_new:N \l__chemnum_textgreek_bool \bool_set_false:N \l__chemnum_textgreek_bool \cs_new_protected:Npn \__chemnum_load_textgreek:n #1 { \AtEndPreamble { \file_if_exist:nTF { textgreek . sty } { \@ifpackageloaded { textgreek } { \msg_warning:nnx { chemnum } { textgreek-loaded } { #1 } } { \RequirePackage [ #1 ] { textgreek } } \bool_set_true:N \l__chemnum_textgreek_bool } { \msg_warning:nnx { chemnum } { support-missing } { textgreek } \bool_set_false:N \l__chemnum_textgreek_bool } } } \cs_new:Npn \__chemnum_package_options:n #1 { \keys_set:nn { chemnum / package } { #1 } } \keys_define:nn { chemnum / package } { textgreek .choice: , textgreek / artemisia .code:n = \__chemnum_load_textgreek:n { #1 } , textgreek / cbgreek .code:n = \__chemnum_load_textgreek:n { #1 } , textgreek / euler .code:n = \__chemnum_load_textgreek:n { #1 } , textgreek / false .code:n = { \bool_set_false:N \l__chemnum_textgreek_bool } , textgreek .default:n = cbgreek } \ProcessKeysOptions { chemnum / package } \AtBeginDocument{ \bool_if:NTF \l__chemnum_textgreek_bool { \cs_new_eq:NN \__chemnum_alpha: \textalpha \cs_new_eq:NN \__chemnum_beta: \textbeta \cs_new_eq:NN \__chemnum_gamma: \textgamma \cs_new_eq:NN \__chemnum_delta: \textdelta \cs_new_eq:NN \__chemnum_epsilon: \textepsilon \cs_new_eq:NN \__chemnum_zeta: \textzeta \cs_new_eq:NN \__chemnum_eta: \texteta \cs_new_eq:NN \__chemnum_theta: \texttheta \cs_new_eq:NN \__chemnum_iota: \textiota \cs_new_eq:NN \__chemnum_kappa: \textkappa \cs_new_eq:NN \__chemnum_lambda: \textlambda \cs_new_eq:NN \__chemnum_mu: \textmugreek \cs_new_eq:NN \__chemnum_nu: \textnu \cs_new_eq:NN \__chemnum_xi: \textxi \cs_new_eq:NN \__chemnum_omikron: \textomikron \cs_new_eq:NN \__chemnum_pi: \textpi \cs_new_eq:NN \__chemnum_rho: \textrho \cs_new_eq:NN \__chemnum_sigma: \textsigma \cs_new_eq:NN \__chemnum_tau: \texttau \cs_new_eq:NN \__chemnum_upsilon: \textupsilon \cs_new_eq:NN \__chemnum_phi: \textphi \cs_new_eq:NN \__chemnum_chi: \textchi \cs_new_eq:NN \__chemnum_psi: \textpsi \cs_new_eq:NN \__chemnum_omega: \textomega \cs_new_eq:NN \__chemnum_Alpha: \textAlpha \cs_new_eq:NN \__chemnum_Beta: \textBeta \cs_new_eq:NN \__chemnum_Gamma: \textGamma \cs_new_eq:NN \__chemnum_Delta: \textDelta \cs_new_eq:NN \__chemnum_Epsilon: \textEpsilon \cs_new_eq:NN \__chemnum_Zeta: \textZeta \cs_new_eq:NN \__chemnum_Eta: \textEta \cs_new_eq:NN \__chemnum_Theta: \textTheta \cs_new_eq:NN \__chemnum_Iota: \textIota \cs_new_eq:NN \__chemnum_Kappa: \textKappa \cs_new_eq:NN \__chemnum_Lambda: \textLambda \cs_new_eq:NN \__chemnum_Mu: \textMugreek \cs_new_eq:NN \__chemnum_Nu: \textNu \cs_new_eq:NN \__chemnum_Xi: \textXi \cs_new_eq:NN \__chemnum_Omikron: \textOmikron \cs_new_eq:NN \__chemnum_Pi: \textPi \cs_new_eq:NN \__chemnum_Rho: \textRho \cs_new_eq:NN \__chemnum_Sigma: \textSigma \cs_new_eq:NN \__chemnum_Tau: \textTau \cs_new_eq:NN \__chemnum_Upsilon: \textUpsilon \cs_new_eq:NN \__chemnum_Phi: \textPhi \cs_new_eq:NN \__chemnum_Chi: \textChi \cs_new_eq:NN \__chemnum_Psi: \textPsi \cs_new_eq:NN \__chemnum_Omega: \textOmega } { \RequirePackage { bm }% abhängig machen von textoption bold \cs_new:Npn \__chemnum_bm:n #1 { \bool_if:NTF \l__chemnum_cmpd_bold_bool { \bm { #1 } } { #1 } } \cs_new:Npn \__chemnum_alpha: { \ensuremath { \__chemnum_bm:n { \mathrm { \alpha } } } } \cs_new:Npn \__chemnum_beta: { \ensuremath { \__chemnum_bm:n { \mathrm { \beta } } } } \cs_new:Npn \__chemnum_gamma: { \ensuremath { \__chemnum_bm:n { \mathrm { \gamma } } } } \cs_new:Npn \__chemnum_delta: { \ensuremath { \__chemnum_bm:n { \mathrm { \delta } } } } \cs_new:Npn \__chemnum_epsilon: { \ensuremath { \__chemnum_bm:n { \mathrm { \varepsilon } } } } \cs_new:Npn \__chemnum_zeta: { \ensuremath { \__chemnum_bm:n { \mathrm { \zeta } } } } \cs_new:Npn \__chemnum_eta: { \ensuremath { \__chemnum_bm:n { \mathrm { \eta } } } } \cs_new:Npn \__chemnum_theta: { \ensuremath { \__chemnum_bm:n { \mathrm { \theta } } } } \cs_new:Npn \__chemnum_iota: { \ensuremath { \__chemnum_bm:n { \mathrm { \iota } } } } \cs_new:Npn \__chemnum_kappa: { \ensuremath { \__chemnum_bm:n { \mathrm { \kappa } } } } \cs_new:Npn \__chemnum_lambda: { \ensuremath { \__chemnum_bm:n { \mathrm { \lampda } } } } \cs_new:Npn \__chemnum_mu: { \ensuremath { \__chemnum_bm:n { \mathrm { \mu } } } } \cs_new:Npn \__chemnum_nu: { \ensuremath { \__chemnum_bm:n { \mathrm { \nu } } } } \cs_new:Npn \__chemnum_xi: { \ensuremath { \__chemnum_bm:n { \mathrm { \xi } } } } \cs_new:Npn \__chemnum_omikron: { \ensuremath { \__chemnum_bm:n { \mathrm { o } } } } \cs_new:Npn \__chemnum_pi: { \ensuremath { \__chemnum_bm:n { \mathrm { \pi } } } } \cs_new:Npn \__chemnum_rho: { \ensuremath { \__chemnum_bm:n { \mathrm { \rho } } } } \cs_new:Npn \__chemnum_sigma: { \ensuremath { \__chemnum_bm:n { \mathrm { \sigma } } } } \cs_new:Npn \__chemnum_tau: { \ensuremath { \__chemnum_bm:n { \mathrm { \tau } } } } \cs_new:Npn \__chemnum_upsilon: { \ensuremath { \__chemnum_bm:n { \mathrm { \upsilon } } } } \cs_new:Npn \__chemnum_phi: { \ensuremath { \__chemnum_bm:n { \mathrm { \varphi } } } } \cs_new:Npn \__chemnum_chi: { \ensuremath { \__chemnum_bm:n { \mathrm { \chi } } } } \cs_new:Npn \__chemnum_psi: { \ensuremath { \__chemnum_bm:n { \mathrm { \psi } } } } \cs_new:Npn \__chemnum_omega: { \ensuremath { \__chemnum_bm:n { \mathrm { \omega } } } } \cs_new:Npn \__chemnum_Alpha: { \ensuremath { \__chemnum_bm:n { \mathrm { A } } } } \cs_new:Npn \__chemnum_Beta: { \ensuremath { \__chemnum_bm:n { \mathrm { B } } } } \cs_new:Npn \__chemnum_Gamma: { \ensuremath { \__chemnum_bm:n { \mathrm { \Gamma } } } } \cs_new:Npn \__chemnum_Delta: { \ensuremath { \__chemnum_bm:n { \mathrm { \Delta } } } } \cs_new:Npn \__chemnum_Epsilon: { \ensuremath { \__chemnum_bm:n { \mathrm { E } } } } \cs_new:Npn \__chemnum_Zeta: { \ensuremath { \__chemnum_bm:n { \mathrm { Z } } } } \cs_new:Npn \__chemnum_Eta: { \ensuremath { \__chemnum_bm:n { \mathrm { H } } } } \cs_new:Npn \__chemnum_Theta: { \ensuremath { \__chemnum_bm:n { \mathrm { \Theta } } } } \cs_new:Npn \__chemnum_Iota: { \ensuremath { \__chemnum_bm:n { \mathrm { I } } } } \cs_new:Npn \__chemnum_Kappa: { \ensuremath { \__chemnum_bm:n { \mathrm { K } } } } \cs_new:Npn \__chemnum_Lambda: { \ensuremath { \__chemnum_bm:n { \mathrm { \Lambda } } } } \cs_new:Npn \__chemnum_Mu: { \ensuremath { \__chemnum_bm:n { \mathrm { M } } } } \cs_new:Npn \__chemnum_Nu: { \ensuremath { \__chemnum_bm:n { \mathrm { N } } } } \cs_new:Npn \__chemnum_Xi: { \ensuremath { \__chemnum_bm:n { \mathrm { \Xi } } } } \cs_new:Npn \__chemnum_Omikron: { \ensuremath { \__chemnum_bm:n { \mathrm { O } } } } \cs_new:Npn \__chemnum_Pi: { \ensuremath { \__chemnum_bm:n { \mathrm { \Pi } } } } \cs_new:Npn \__chemnum_Rho: { \ensuremath { \__chemnum_bm:n { \mathrm { P } } } } \cs_new:Npn \__chemnum_Sigma: { \ensuremath { \__chemnum_bm:n { \mathrm { \Sigma } } } } \cs_new:Npn \__chemnum_Tau: { \ensuremath { \__chemnum_bm:n { \mathrm { T } } } } \cs_new:Npn \__chemnum_Upsilon: { \ensuremath { \__chemnum_bm:n { \mathrm { \Upsilon } } } } \cs_new:Npn \__chemnum_Phi: { \ensuremath { \__chemnum_bm:n { \mathrm { \Phi } } } } \cs_new:Npn \__chemnum_Chi: { \ensuremath { \__chemnum_bm:n { \mathrm { X } } } } \cs_new:Npn \__chemnum_Psi: { \ensuremath { \__chemnum_bm:n { \mathrm { \Psi } } } } \cs_new:Npn \__chemnum_Omega: { \ensuremath { \__chemnum_bm:n { \mathrm { \Omega } } } } } } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % TOOLS \int_new:N \g__chemnum_cmpd_main_int \prop_new:N \g__chemnum_label_prop \int_new:N \g__chemnum_cmpd_int \int_new:N \l__chemnum_tmpa_int \tl_new:N \l__chemnum_tmpa_tl \tl_new:N \l__chemnum_tmpb_tl \tl_new:N \l__chemnum_tmpc_tl \seq_new:N \g__chemnum_cmpd_saved_seq %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % READ FROM PREVIOUS RUN, SAVE FOR NEXT RUN % save all labels in a clist \cs_new_protected:Npn \chemnum_cmpd_save:n #1 { \seq_gput_right:Nn \g__chemnum_cmpd_saved_seq { #1 } } \msg_set:nnn { chemnum } { missing-cmpd-file } { The~file~ \c_job_name_tl .cmpd~hasn't~been~available~yet. \\ Please~rerun~to~get~referencing~compound~labels~right. } \file_if_exist:nTF { ./ \c_job_name_tl . cmpd } { \file_input:n { ./ \c_job_name_tl . cmpd } } { \msg_warning:nn { chemnum }{ missing-cmpd-file } } % write ref commands for all labels in .cmpd file to make them % available at the next run \AtEndDocument { \iow_new:N \__chemnum_aux_file: \iow_open:Nn \__chemnum_aux_file: { ./ \c_job_name_tl . cmpd } \seq_map_inline:Nn \g__chemnum_cmpd_saved_seq { \iow_now:Nx \__chemnum_aux_file: { \use:c { cs_new:cpn } { chemnum_cmpd_ #1 _ref: } { \exp_not:f { \use:c { chemnum_cmpd_ #1 : } } } } \cs_if_exist:cT { chemnum_cmpd_ #1 _min: } { \iow_now:Nx \__chemnum_aux_file: { \use:c { cs_new:cpn } { chemnum_cmpd_ #1 _min_ref: } { \exp_not:f { \use:c { chemnum_cmpd_ #1 _min: } } } } } \cs_if_exist:cT { chemnum_cmpd_ #1 _max: } { \iow_now:Nx \__chemnum_aux_file: { \use:c { cs_new:cpn } { chemnum_cmpd_ #1 _max_ref: } { \exp_not:f { \use:c { chemnum_cmpd_ #1 _max: } } } } } } \iow_close:N \__chemnum_aux_file: } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % COMPOUND LABELS % STYLE OF COMPOUND LABEL \tl_new:N \l__chemnum_style_tmp_tl \bool_new:N \l__chemnum_cmpd_style_is_macro_bool % default style \cs_new:Npn \chemnum_cmpd_style:n #1 { #1 } % set style \cs_new_protected:Npn \__chemnum_cmpd_set_style:n #1 { \cs_set:Npn \chemnum_cmpd_style:n { #1 } } % use style \bool_new:N \l__chemnum_cmpd_bold_bool \bool_set_true:N \l__chemnum_cmpd_bold_bool \cs_new_protected:Npn \__chemnum_cmpd_use_style:n #1 { \group_begin: \bool_if:NT \l__chemnum_cmpd_bold_bool { \bfseries } \chemnum_cmpd_style:n { #1 } \group_end: } %-----------------------------------------------------------------------------% % prefix, suffix, delimiters, format and separator of compound label \tl_new:N \l__chemnum_cmpd_prefix_tl \tl_new:N \l__chemnum_cmpd_suffix_tl \tl_new:N \l__chemnum_cmpd_space_tl \tl_set:Nn \l__chemnum_cmpd_space_tl { \penalty\@m\ } \tl_new:N \l__chemnum_cmpd_separator_tl \tl_new:N \l__chemnum_cmpd_odelim_tl \tl_new:N \l__chemnum_cmpd_cdelim_tl % error message for wrong argument length of delim-keys \msg_set:nnn { chemnum } { delimiters } { "#1-delim~=~"~needs~two~tokens~or~token~groups~as~a~value~ \msg_line_context: . } % set compound delimiters \cs_new_protected:Npn \__chemnum_cmpd_delim:n #1 { \tl_if_blank:nTF { #1 } { \tl_clear:N \l__chemnum_cmpd_odelim_tl \tl_clear:N \l__chemnum_cmpd_cdelim_tl } { \int_compare:nNnTF { \tl_count:n { #1 } } = 2 { \tl_set:Nx \l__chemnum_cmpd_odelim_tl { \tl_head:n { #1 } } \tl_set:Nx \l__chemnum_cmpd_cdelim_tl { \tl_tail:n { #1 } } } { \msg_error:nnx { chemnum } { delimiters } { cmpd } } } } % format of numbering \cs_new:Npn \__chemnum_cmpd_kind:nn #1#2 { \cs:w int_to_#1:n \cs_end: #2 } % default format \tl_new:N \l__chemnum_cmpd_kind_value_tl \tl_set:Nn \l__chemnum_cmpd_kind_value_tl { arabic } % format of sub-numbering \cs_new:Npn \__chemnum_cmpd_sub_kind:nn #1#2 { \cs:w int_to_ #1 :n \cs_end: #2 } \cs_generate_variant:Nn \__chemnum_cmpd_sub_kind:nn { Nc } % default format \tl_new:N \l__chemnum_cmpd_sub_kind_value_tl \tl_set:Nn \l__chemnum_cmpd_sub_kind_value_tl { alph } %-----------------------------------------------------------------------------% % add greek letters and symbols as numbering format % define \int_to_greek function \cs_new:Npn \int_to_greek:n { } % \bool_if:NTF \l__chemnum_textgreek_bool % { \cs_set:Npn \int_to_greek:n #1 { \int_to_symbols:nnn {#1} { 24 } { { 1 } { \exp_not:o \__chemnum_alpha: } { 2 } { \exp_not:o \__chemnum_beta: } { 3 } { \exp_not:o \__chemnum_gamma: } { 4 } { \exp_not:o \__chemnum_delta: } { 5 } { \exp_not:o \__chemnum_epsilon: } { 6 } { \exp_not:o \__chemnum_zeta: } { 7 } { \exp_not:o \__chemnum_eta: } { 8 } { \exp_not:o \__chemnum_theta: } { 9 } { \exp_not:o \__chemnum_iota: } { 10 } { \exp_not:o \__chemnum_kappa: } { 11 } { \exp_not:o \__chemnum_lambda: } { 12 } { \exp_not:o \__chemnum_mu: } { 13 } { \exp_not:o \__chemnum_nu: } { 14 } { \exp_not:o \__chemnum_xi: } { 15 } { \exp_not:o \__chemnum_omikron: } { 16 } { \exp_not:o \__chemnum_pi: } { 17 } { \exp_not:o \__chemnum_rho: } { 18 } { \exp_not:o \__chemnum_sigma: } { 19 } { \exp_not:o \__chemnum_tau: } { 20 } { \exp_not:o \__chemnum_upsilon: } { 21 } { \exp_not:o \__chemnum_phi: } { 22 } { \exp_not:o \__chemnum_chi: } { 23 } { \exp_not:o \__chemnum_psi: } { 24 } { \exp_not:o \__chemnum_omega: } } } % } % { % \cs_set_eq:NN \int_to_greek:n \int_to_alph:n % } % define \int_to_Greek function \cs_new:Npn \int_to_Greek:n { } \bool_if:NTF \l__chemnum_textgreek_bool { \cs_set_protected:Npn \int_to_Greek:n #1 { \int_to_symbols:nnn { #1 } { 24 } { { 1 } { \exp_not:o \__chemnum_Alpha: } { 2 } { \exp_not:o \__chemnum_Beta: } { 3 } { \exp_not:o \__chemnum_Gamma: } { 4 } { \exp_not:o \__chemnum_Delta: } { 5 } { \exp_not:o \__chemnum_Epsilon: } { 6 } { \exp_not:o \__chemnum_Zeta: } { 7 } { \exp_not:o \__chemnum_Eta: } { 8 } { \exp_not:o \__chemnum_Theta: } { 9 } { \exp_not:o \__chemnum_Iota: } { 10 } { \exp_not:o \__chemnum_Kappa: } { 11 } { \exp_not:o \__chemnum_Lambda: } { 12 } { \exp_not:o \__chemnum_Mu: } { 13 } { \exp_not:o \__chemnum_Nu: } { 14 } { \exp_not:o \__chemnum_Xi: } { 15 } { \exp_not:o \__chemnum_Omikron: } { 16 } { \exp_not:o \__chemnum_Pi: } { 17 } { \exp_not:o \__chemnum_Rho: } { 18 } { \exp_not:o \__chemnum_Sigma: } { 19 } { \exp_not:o \__chemnum_Tau: } { 20 } { \exp_not:o \__chemnum_Upsilon: } { 21 } { \exp_not:o \__chemnum_Phi: } { 22 } { \exp_not:o \__chemnum_Chi: } { 23 } { \exp_not:o \__chemnum_Psi: } { 24 } { \exp_not:o \__chemnum_Omega: } } } } { \cs_set_eq:NN \int_to_Greek:n \int_to_Alph:n } % define \int_to_Symbol function \cs_new_protected:Npn \int_to_Symbol:n #1 { \int_to_symbols:nnn { #1 } { 9 } { { 1 } {\exp_not:o \textasteriskcentered } { 2 } {\exp_not:o \textdagger} { 3 } {\exp_not:o \textdaggerdbl} { 4 } {\exp_not:o \textsection} { 5 } {\exp_not:o \textparagraph} { 6 } {\exp_not:o \textbardbl} { 7 } {\exp_not:o \textasteriskcentered \textasteriskcentered} { 8 } {\exp_not:o \textdagger \textdagger} { 9 } {\exp_not:o \textdaggerdbl \textdaggerdbl} } } %-----------------------------------------------------------------------------% % lists of sublabels \clist_new:N \l__chemnum_sublabel_clist \tl_new:N \l__chemnum_sublabel_list_sep_tl \tl_set:Nn \l__chemnum_sublabel_list_sep_tl { , } \tl_new:N \l__chemnum_cmpd_sublabel_list_tl \int_new:N \l__chemnum_sublabel_list_current_int \int_new:N \l__chemnum_sublabel_list_length_int \bool_new:N \l__chemnum_sublabel_list_bool \cs_new_protected:Npn \__chemnum_cmpd_sublabel_list:nn #1#2 { \clist_clear:N \l__chemnum_sublabel_clist \clist_set_eq:NN \l__chemnum_sublabel_clist #2 \int_set:Nn \l__chemnum_sublabel_list_length_int { \clist_count:N \l__chemnum_sublabel_clist } \clist_map_variable:NNn \l__chemnum_sublabel_clist \l__chemnum_tmpb_tl { \int_incr:N \l__chemnum_sublabel_list_current_int \exp_after:wN \__chemnum_cmpd_sublabelsep:n \l__chemnum_tmpb_tl \q_stop \use:c { chemnum_cmpd_#1_ \l__chemnum_cmpd_sub_one_label_tl _ref: } \tl_if_blank:VF \l__chemnum_cmpd_sub_two_label_tl { \tl_use:N \l__chemnum_sub_range_sep_tl \use:c { chemnum_cmpd_#1_ \l__chemnum_cmpd_sub_two_label_tl _ref: } } \int_compare:nT { \l__chemnum_sublabel_list_current_int < \l__chemnum_sublabel_list_length_int } { \tl_use:N \l__chemnum_sublabel_list_sep_tl } } } %-----------------------------------------------------------------------------% % variables \bool_new:N \l__chemnum_cmpd_name_bool \bool_set_false:N \l__chemnum_cmpd_name_bool \bool_new:N \l__chemnum_cmpd_all_bool \bool_set_false:N \l__chemnum_cmpd_all_bool \bool_new:N \l__chemnum_cmpd_range_bool \bool_set_false:N \l__chemnum_cmpd_range_bool \bool_new:N \l__chemnum_sub_label_only_bool \bool_set_false:N \l__chemnum_sub_label_only_bool \tl_new:N \l__chemnum_cmpd_name_tl \tl_new:N \l__chemnum_cmpd_labelsep_tl \tl_set:Nn \l__chemnum_cmpd_labelsep_tl { . } \tl_new:N \l__chemnum_sublist_input_separator_tl \tl_set:Nn \l__chemnum_sublist_input_separator_tl { , } \tl_new:N \l__chemnum_sublist_output_separator_tl \tl_set:Nn \l__chemnum_sublist_output_separator_tl { , } \tl_new:N \l__chemnum_sublabel_range_marker_tl \tl_set:Nn \l__chemnum_sublabel_range_marker_tl { .. } \tl_new:N \l__chemnum_sub_range_sep_tl \tl_set:Nn \l__chemnum_sub_range_sep_tl { -- } %-----------------------------------------------------------------------------% % hyperref support \tl_new:N \l__chemnum_cmpd_hyper_name_tl \bool_new:N \l__chemnum_use_hyperref_bool \bool_new:N \l__chemnum_hypertarget_bool \bool_new:N \l__chemnum_hyperlink_bool \cs_new_eq:NN \__chemnum_make_hyper:nn \use_ii:nn % #1: main label, #2: sub labels, #3: invisible \cs_new_protected:Npn \__chemnum_hyperref:nnn #1#2#3 { \bool_if:nF { #3 || !\l__chemnum_use_hyperref_bool } { \bool_if:NT \l__chemnum_hypertarget_bool { \cs_set:Npn \__chemnum_make_hyper:nn ##1##2 { \raisebox { 3ex } [ 0pt ] { \hypertarget { ##1 } { } } ##2 } } \bool_if:NT \l__chemnum_hyperlink_bool { \cs_set_eq:NN \__chemnum_make_hyper:nn \hyperlink } \bool_if:nT { !\l__chemnum_hypertarget_bool && !\l__chemnum_hyperlink_bool } { \tl_if_blank:nTF { #2 } { % no sublabel \tl_set:Nn \l__chemnum_cmpd_hyper_name_tl { chemnum_cmpd_#1 } \cs_if_exist:cTF { chemnum_cmpd_#1_hyper: } { \bool_set_false:N \l__chemnum_hypertarget_bool \cs_set_eq:NN \__chemnum_make_hyper:nn \hyperlink } { \bool_set_true:N \l__chemnum_hypertarget_bool \cs_set:Npn \__chemnum_make_hyper:nn ##1##2 { \raisebox { 3ex } [ 0pt ] { \hypertarget { ##1 } { } } ##2 } \cs_new:cpn { chemnum_cmpd_#1_hyper: } { } } } { \__chemnum_cmpd_sublist:n { #2 } \int_compare:nT { \l__chemnum_cmpd_sublist_length_int < 2 } { % no sublabel list \__chemnum_cmpd_subrange_separate:n { #2 } \tl_if_blank:VT \l__chemnum_tmpc_tl { % no sublabel range \tl_set:Nn \l__chemnum_cmpd_hyper_name_tl { chemnum_cmpd_#1_ \l__chemnum_tmpb_tl } \cs_if_exist:cTF { chemnum_cmpd_#1_ \l__chemnum_tmpb_tl _hyper: } { \bool_set_false:N \l__chemnum_hypertarget_bool \cs_set_eq:NN \__chemnum_make_hyper:nn \hyperlink } { \bool_set_true:N \l__chemnum_hypertarget_bool \cs_set:Npn \__chemnum_make_hyper:nn ##1##2 { \raisebox { 3ex } [ 0pt ] { \hypertarget { ##1 } { } } ##2 } \cs_new:cpn { chemnum_cmpd_#1_ \l__chemnum_tmpb_tl _hyper: } { } } } } } } } } %-----------------------------------------------------------------------------% % property keys for compounds \keys_define:nn { chemnum } { cmpd-style .code:n = \__chemnum_cmpd_set_style:n { #1 } , cmpd-weight .choice: , cmpd-weight / bold .code:n = \bool_set_true:N \l__chemnum_cmpd_bold_bool , cmpd-weight / normal .code:n = \bool_set_false:N \l__chemnum_cmpd_bold_bool , cmpd-label .code:n = { \bool_set_true:N \l__chemnum_cmpd_name_bool \tl_set:Nn \l__chemnum_cmpd_name_tl { #1 } } , cmpd-prefix .tl_set:N = \l__chemnum_cmpd_prefix_tl , cmpd-prefix .default:n = { } , cmpd-suffix .tl_set:N = \l__chemnum_cmpd_suffix_tl , cmpd-suffix .default:n = { } , cmpd-space .tl_set:N = \l__chemnum_cmpd_space_tl , cmpd-space .default:n = { \penalty\@m\ }, cmpd-delim .code:n = \__chemnum_cmpd_delim:n { #1 }, cmpd-delim .default:n = { ( } { ) } , cmpd-odelim .tl_set:N = \l__chemnum_cmpd_odelim_tl , cmpd-odelim .default:n = { } , cmpd-cdelim .tl_set:N = \l__chemnum_cmpd_cdelim_tl , cmpd-cdelim .default:n = { } , cmpd-all .bool_set:N = \l__chemnum_cmpd_all_bool , cmpd-all .default:n = true , cmpd-counter .choice: , cmpd-counter .choice_code:n = \tl_set_eq:NN \l__chemnum_cmpd_kind_value_tl \l_keys_choice_tl , cmpd-counter .generate_choices:n = { arabic , alph , Alph , greek, Greek , roman , Roman , Symbol } , cmpd-counter .default:n = arabic , hyper-use .choice: , hyper-use / true .code:n = { \bool_set_true:N \l__chemnum_use_hyperref_bool \bool_set_false:N \l__chemnum_hypertarget_bool \bool_set_false:N \l__chemnum_hyperlink_bool } , hyper-use / false .code:n = { \bool_set_false:N \l__chemnum_use_hyperref_bool \bool_set_false:N \l__chemnum_hypertarget_bool \bool_set_false:N \l__chemnum_hyperlink_bool } , hyper-use .default:n = true , hyper-target .code:n = { \tl_set:Nn \l__chemnum_cmpd_hyper_name_tl { #1 } \bool_set_true:N \l__chemnum_use_hyperref_bool \bool_set_true:N \l__chemnum_hypertarget_bool \bool_set_false:N \l__chemnum_hyperlink_bool } , hyper-link .code:n = { \tl_set:Nn \l__chemnum_cmpd_hyper_name_tl { #1 } \bool_set_true:N \l__chemnum_use_hyperref_bool \bool_set_false:N \l__chemnum_hypertarget_bool \bool_set_true:N \l__chemnum_hyperlink_bool } , sub-counter .choice: , sub-counter .choice_code:n = \tl_set_eq:NN \l__chemnum_cmpd_sub_kind_value_tl \l_keys_choice_tl , sub-counter .generate_choices:n = { arabic , alph , Alph , greek , Greek , roman , Roman , Symbol } , sub-counter .default:n = alph , sub-input-sep .code:n = \__chemnum_subcmpdsep:n { #1 } , sub-input-sep .default:n = . , sub-output-sep .tl_set:N = \l__chemnum_cmpd_separator_tl , sub-output-sep .default:n = { } , sublist-input-sep .tl_set:N = \l__chemnum_sublist_input_separator_tl , sublist-input-sep .default:n = { , } , sublist-output-sep .tl_set:N = \l__chemnum_sublist_output_separator_tl , sublist-output-sep .default:n = { , } , sub-only .bool_set:N = \l__chemnum_sub_label_only_bool , sub-only .default:n = true , subrange-output-sep .tl_set:N = \l__chemnum_sub_range_sep_tl , subrange-output-sep .default:n = { -- } , subrange-input-sep .code:n = \__chemnum_sublabel_range_marker:n { #1 } , subrange-input-sep .default:n = { .. } } %-----------------------------------------------------------------------------% % list separators, delimiters, prefix and suffix \bool_new:N \l__chemnum_no_serial_comma_bool \bool_set_false:N \l__chemnum_no_serial_comma_bool \tl_new:N \l__chemnum_list_input_separator_tl \tl_set:Nn \l__chemnum_list_input_separator_tl { , } \tl_new:N \l__chemnum_list_separator_tl \tl_set:Nn \l__chemnum_list_separator_tl { , } \tl_new:N \l__chemnum_list_space_tl \tl_set:Nn \l__chemnum_list_space_tl { \penalty\@m\ } \tl_new:N \l__chemnum_list_last_separator_lang_tl \tl_set:Nn \l__chemnum_list_last_separator_lang_tl { and } \tl_new:N \l__chemnum_list_last_separator_tl \tl_set:Nn \l__chemnum_list_last_separator_tl { \tl_use:N \l__chemnum_list_last_separator_lang_tl } \tl_new:N \l__chemnum_list_prefix_tl { } \tl_set:Nn \l__chemnum_list_prefix_tl { } \tl_new:N \l__chemnum_list_suffix_tl { } \tl_set:Nn \l__chemnum_list_suffix_tl { } \tl_new:N \l__chemnum_list_odelim_tl { } \tl_new:N \l__chemnum_list_cdelim_tl { } \cs_new_protected:Npn \__chemnum_list_delim:n #1 { \tl_if_blank:nTF { #1 } { \tl_clear:N \l__chemnum_list_odelim_tl \tl_clear:N \l__chemnum_list_cdelim_tl }{ \int_compare:nNnTF { \tl_count:n { #1 } } = 2 { \tl_set:Nx \l__chemnum_list_odelim_tl { \tl_head:n { #1 } } \tl_set:Nx \l__chemnum_list_cdelim_tl { \tl_tail:n { #1 } } }{ \msg_error:nnx { chemnum } { delimiters } { list } } } } %-----------------------------------------------------------------------------% % property keys for lists \keys_define:nn { chemnum } { list-prefix .tl_set:N = \l__chemnum_list_prefix_tl , list-prefix .default:n = { } , list-suffix .tl_set:N = \l__chemnum_list_suffix_tl , list-suffix .default:n = { } , list-delim .code:n = \__chemnum_list_delim:n { #1 } , list-delim .default:n = { ( } { ) } , list-odelim .tl_set:N = \l__chemnum_list_odelim_tl , list-odelim .default:n = { } , list-cdelim .tl_set:N = \l__chemnum_list_cdelim_tl , list-cdelim .default:n = { } , list-space .tl_set:N = \l__chemnum_list_space_tl , list-space .default:n = { \penalty\@m\ } , list-input-sep .tl_set:N = \l__chemnum_list_input_separator_tl , list-input-sep .default:n = { , } , list-output-sep .tl_set:N = \l__chemnum_list_separator_tl , list-output-sep .default:n = { , } , list-last-sep .tl_set:N = \l__chemnum_list_last_separator_tl , list-last-sep .default:n = \l__chemnum_list_last_separator_lang_tl , list-serial-comma .choice: , list-serial-comma / true .code:n = \bool_set_false:N \l__chemnum_no_serial_comma_bool , list-serial-comma / false .code:n = \bool_set_true:N \l__chemnum_no_serial_comma_bool , list-serial-comma .default:n = true , list-lang .choice: , list-lang / US .code:n = { \bool_set_false:N \l__chemnum_no_serial_comma_bool \tl_set:Nn \l__chemnum_list_last_separator_lang_tl { and } } , list-lang / GB .code:n = { \bool_set_true:N \l__chemnum_no_serial_comma_bool \tl_set:Nn \l__chemnum_list_last_separator_lang_tl { and } } , list-lang / DE .code:n = { \bool_set_true:N \l__chemnum_no_serial_comma_bool \tl_set:Nn \l__chemnum_list_last_separator_lang_tl { und } } , list-lang / FR .code:n = { \bool_set_true:N \l__chemnum_no_serial_comma_bool \tl_set:Nn \l__chemnum_list_last_separator_lang_tl { et } } , list-lang / IT .code:n = { \bool_set_true:N \l__chemnum_no_serial_comma_bool \tl_set:Nn \l__chemnum_list_last_separator_lang_tl { e } } , list-lang / ES .code:n = { \bool_set_true:N \l__chemnum_no_serial_comma_bool \tl_set:Nn \l__chemnum_list_last_separator_lang_tl { y } } , list-lang .default:n = US } %-----------------------------------------------------------------------------% % label and sublabel declaration \cs_new_protected:Npn \__chemnum_cmpd_declare:n #1 { \cs_if_exist:cF { chemnum_cmpd_#1: } { \int_gincr:N \g__chemnum_cmpd_main_int \prop_gput:Nnx \g__chemnum_label_prop { #1 } { \int_use:N \g__chemnum_cmpd_main_int } \chemnum_cmpd_save:n { #1 } \bool_if:NF \l__chemnum_cmpd_name_bool { \int_gincr:N \g__chemnum_cmpd_int } \cs_new:cpx { chemnum_cmpd_#1: } { \bool_if:NTF \l__chemnum_cmpd_name_bool { \l__chemnum_cmpd_name_tl } { \__chemnum_cmpd_kind:nn \l__chemnum_cmpd_kind_value_tl \g__chemnum_cmpd_int } } } } \cs_new_protected:Npn \__chemnum_cmpd_sub_declare:nn #1#2 { \cs_if_exist:cF { chemnum_cmpd_#1_#2: } { \chemnum_cmpd_save:n { #1 _ #2 } \cs_new:cpx { chemnum_cmpd_#1_#2: } { } \int_gincr:c { g_chemnum_cmpd_#1_int } % why is the next line working when \cs_gset:cpx doesn't? % (in case ":" is part of #1) \exp_after:wN \cs_gset:Npx \cs:w chemnum_cmpd_#1_#2: \cs_end: { \__chemnum_cmpd_sub_kind:Nc \l__chemnum_cmpd_sub_kind_value_tl { g_chemnum_cmpd_#1_int } } \int_compare:nT { \int_use:c { g_chemnum_cmpd_#1_int } = 1 } { \cs_gset_eq:cc { chemnum_cmpd_#1_min: } { chemnum_cmpd_#1_#2: } } \cs_gset_eq:cc { chemnum_cmpd_#1_max: } { chemnum_cmpd_#1_#2: } } } \cs_generate_variant:Nn \__chemnum_cmpd_sub_declare:nn { no } \cs_new_protected:Npn \__chemnum_cmpd_sub_initiate:nn #1#2 { \cs_if_exist:cF { chemnum_cmpd_ #1 _ #2 _init: } { \bool_if:NTF \l__chemnum_cmpd_init_strict_bool { \msg_error:nnx { chemnum } { cmpd-init-sub } { #1 \l__chemnum_cmpd_labelsep_tl #2 } } { \msg_warning:nnx { chemnum } { cmpd-init-sub } { #1 \l__chemnum_cmpd_labelsep_tl #2 } } } } %-----------------------------------------------------------------------------% % label and sublabel initiation \cs_new_protected:Npn \__chemnum_cmpd_initiate:nn #1#2 { \cs_if_exist:cTF { chemnum_cmpd_#1_init: } { \bool_if:NT \l__chemnum_cmpd_sub_init_bool { \tl_if_blank:nF { #2 } { \__chemnum_cmpd_sublist:n { #2 } \tl_map_inline:Nn \l__chemnum_cmpd_sublist_tl { \__chemnum_cmpd_subrange_separate:n { ##1 } \__chemnum_cmpd_sub_initiate:nn { #1 } { \l__chemnum_tmpb_tl } \tl_if_blank:VF \l__chemnum_tmpc_tl { \__chemnum_cmpd_sub_initiate:nn { #1 } { \l__chemnum_tmpc_tl } } } } } } { \bool_if:NTF \l__chemnum_cmpd_init_strict_bool { \msg_error:nnx { chemnum } { cmpd-init } { #1 } } { \msg_warning:nnx { chemnum } { cmpd-init } { #1 } } } } %-----------------------------------------------------------------------------% % sub label separator % error message if no separator is chosen \msg_set:nnnn { chemnum } { sub-label-separator } { Missing~separator~token~as~value~for~the~key~sub-cmpd-sep \c_space_tl \msg_line_context: ! } { You~used~the~key~sub-cmpd-sep \c_space_tl \msg_line_context: ~but~left~the~ argument~empty.\\ This~can't~work.~Please~select~a~token~as~separator. } %-----------------------------------------------------------------------------% % variables \tl_new:N \l__chemnum_cmpd_main_label_tl \tl_new:N \l__chemnum_cmpd_sub_label_tl \tl_new:N \l__chemnum_labelsep_tmp_tl % set sublabel-separator \cs_new_protected:Npn \__chemnum_subcmpdsep:n #1 { \tl_if_blank:nTF { #1 } { \msg_error:nn { chemnum } { sub-label-separator } } { \tl_set:Nn \l__chemnum_cmpd_labelsep_tl { #1 } } } \cs_new_protected:Npn \__chemnum_sublabel_range_marker:n #1 { \tl_if_blank:nTF { #1 } { \msg_error:nn { chemnum } { sub-label-range_sep } } { \tl_set:Nn \l__chemnum_sublabel_range_marker_tl { #1 } } } % actual separating \cs_new_protected:Npn \__chemnum_cmpd_labelsep:n #1 \q_stop { \tl_clear:N \l__chemnum_labelsep_tmp_tl \tl_if_in:oVTF { #1 } \l__chemnum_cmpd_labelsep_tl { \tl_set:Nn \l__chemnum_labelsep_tmp_tl { #1 } \tl_replace_once:NVn \l__chemnum_labelsep_tmp_tl \l__chemnum_cmpd_labelsep_tl { \q_nil } \exp_after:wN \__chemnum_cmpd_labelsep_aux_ii:n \l__chemnum_labelsep_tmp_tl \q_stop } { \__chemnum_cmpd_labelsep_aux_i:n { #1 } } } \cs_generate_variant:Nn \tl_if_in:nnTF { oV } \cs_generate_variant:Nn \tl_replace_once:Nnn { NV } \cs_new_protected:Npn \__chemnum_cmpd_labelsep_aux_i:n #1 { \tl_set:Nn \l__chemnum_cmpd_main_label_tl { #1 } \tl_clear:N \l__chemnum_cmpd_sub_label_tl } \cs_new_protected:Npn \__chemnum_cmpd_labelsep_aux_ii:n #1 \q_nil #2 \q_stop { \tl_set:Nn \l__chemnum_cmpd_main_label_tl { #1 } \tl_set:Nn \l__chemnum_cmpd_sub_label_tl { #2 } } % sublabel separating to display a list and/or range \tl_new:N \l__chemnum_cmpd_sublist_tl \int_new:N \l__chemnum_cmpd_sublist_length_int \NewDocumentCommand \__chemnum_cmpd_sublist:n { > { \exp_args:No \SplitList { \l__chemnum_sublist_input_separator_tl } } m } { \tl_set:Nn \l__chemnum_cmpd_sublist_tl { #1 } \int_zero:N \l__chemnum_cmpd_sublist_length_int \tl_map_inline:Nn \l__chemnum_cmpd_sublist_tl { \int_incr:N \l__chemnum_cmpd_sublist_length_int } } \cs_new_protected:Npn \__chemnum_cmpd_subrange_separate:n #1 { \tl_clear:N \l__chemnum_tmpb_tl \tl_clear:N \l__chemnum_tmpc_tl \tl_if_in:noTF { #1 } { \l__chemnum_sublabel_range_marker_tl } { \tl_set:Nn \l__chemnum_tmpb_tl { #1 } \tl_replace_once:NVn \l__chemnum_tmpb_tl \l__chemnum_sublabel_range_marker_tl { \q_nil } \exp_after:wN \__chemnum_cmpd_subrange_separate_aux:w \l__chemnum_tmpb_tl \q_stop } { \tl_set:Nn \l__chemnum_tmpb_tl { #1 } } } \cs_new_protected:Npn \__chemnum_cmpd_subrange_separate_aux:w #1 \q_nil #2 \q_stop { \tl_set:Nn \l__chemnum_tmpb_tl { #1 } \tl_set:Nn \l__chemnum_tmpc_tl { #2 } } %-----------------------------------------------------------------------------% % print compound label \cs_new_protected:Npn \__chemnum_cmpd_print:n #1 { \tl_if_blank:VF \l__chemnum_cmpd_prefix_tl { \tl_use:N \l__chemnum_cmpd_prefix_tl \tl_use:N \l__chemnum_cmpd_space_tl } \tl_use:N \l__chemnum_cmpd_odelim_tl \__chemnum_cmpd_use_style:n { #1 } \tl_use:N \l__chemnum_cmpd_cdelim_tl \tl_if_blank:VF \l__chemnum_cmpd_suffix_tl { \tl_use:N \l__chemnum_cmpd_space_tl \tl_use:N \l__chemnum_cmpd_suffix_tl } } %-----------------------------------------------------------------------------% % main internal compound label command % #1:
#2: #3: #4: % #2 may be a list of sublabels \cs_new_protected:Npn \__chemnum_cmpd_aux:nnnn #1#2#3#4 { \bool_if:NT \l__chemnum_cmpd_initiated_bool { \__chemnum_cmpd_initiate:nn { #1 } { #2 } } \bool_if:NF \l__chemnum_cmpd_ref_bool { \__chemnum_cmpd_declare:n { #1 } } \__chemnum_hyperref:nnn { #1 } { #2 } { #3 } \tl_if_blank:nF { #2 } { \cs_if_exist:cF { g_chemnum_cmpd_#1_int } { \int_new:c { g_chemnum_cmpd_#1_int } } \__chemnum_cmpd_sublist:n { #2 } \bool_if:NF \l__chemnum_cmpd_ref_bool { \tl_map_inline:Nn \l__chemnum_cmpd_sublist_tl { \__chemnum_cmpd_subrange_separate:n { ##1 } \__chemnum_cmpd_sub_declare:no { #1 } { \l__chemnum_tmpb_tl } \tl_if_blank:VF \l__chemnum_tmpc_tl { \__chemnum_cmpd_sub_declare:no { #1 } { \l__chemnum_tmpc_tl } } } } } \bool_if:NTF #3 { \mode_if_horizontal:T { \tex_unskip:D } } { \bool_if:NT #4 { \tl_clear:N \l__chemnum_cmpd_odelim_tl \tl_clear:N \l__chemnum_cmpd_cdelim_tl } \__chemnum_make_hyper:nn { \l__chemnum_cmpd_hyper_name_tl } { \__chemnum_cmpd_print:n { \bool_if:NF \l__chemnum_sub_label_only_bool { \bool_if:NTF \l__chemnum_cmpd_ref_bool { \use:c { chemnum_cmpd_ #1 _ref: } } { \use:c { chemnum_cmpd_ #1 : } } } \bool_if:NTF \l__chemnum_cmpd_all_bool { \tl_use:N \l__chemnum_cmpd_separator_tl \use:c { chemnum_cmpd_ #1 _min_ref: } \cs_if_eq:ccF { chemnum_cmpd_ #1 _min_ref: } { chemnum_cmpd_ #1 _max_ref: } { \tl_use:N \l__chemnum_sub_range_sep_tl \use:c { chemnum_cmpd_ #1 _max_ref: } } } { \bool_if:NTF \l__chemnum_sublabel_list_bool { \__chemnum_cmpd_sublabel_list:nn { #1 } { \l__chemnum_cmpd_sublabel_list_tl } } { \tl_if_blank:nF { #2 } { \tl_use:N \l__chemnum_cmpd_separator_tl \int_zero:N \l__chemnum_tmpa_int \tl_map_inline:Nn \l__chemnum_cmpd_sublist_tl { \int_incr:N \l__chemnum_tmpa_int \__chemnum_cmpd_subrange_separate:n { ##1 } \bool_if:NTF \l__chemnum_cmpd_ref_bool { \use:c { chemnum_cmpd_ #1 _ \l__chemnum_tmpb_tl _ref: } } { \use:c { chemnum_cmpd_ #1 _ \l__chemnum_tmpb_tl : } } \tl_if_blank:VF \l__chemnum_tmpc_tl { \tl_use:N \l__chemnum_sub_range_sep_tl \bool_if:NTF \l__chemnum_cmpd_ref_bool { \use:c { chemnum_cmpd_ #1 _ \l__chemnum_tmpc_tl _ref: } } { \use:c { chemnum_cmpd_ #1 _ \l__chemnum_tmpc_tl : } } } \int_compare:nF { \l__chemnum_tmpa_int = \l__chemnum_cmpd_sublist_length_int } { \l__chemnum_sublist_output_separator_tl } } } } } } } } } \cs_generate_variant:Nn \__chemnum_cmpd_aux:nnnn { VV } %-----------------------------------------------------------------------------% % create compound label % #1: label name #2: star (invisible) #3: minus (no delimiters) \cs_new_protected:Npn \__chemnum_cmpd:nnn #1#2#3 { \group_begin: \tl_clear:N \l__chemnum_cmpd_main_label_tl \tl_clear:N \l__chemnum_cmpd_sub_label_tl \__chemnum_cmpd_labelsep:n #1 \q_stop \tl_remove_all:Nn \l__chemnum_cmpd_sub_label_tl { ~ } \__chemnum_cmpd_aux:VVnn \l__chemnum_cmpd_main_label_tl \l__chemnum_cmpd_sub_label_tl { #2 } { #3 } \group_end: } \cs_generate_variant:Nn \__chemnum_cmpd:nnn { V } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % DOCUMENT COMMANDS % variables: \int_new:N \l__chemnum_list_items_int \int_new:N \l__chemnum_list_separate_int \tl_new:N \l__chemnum_list_last_sep_empty_tl \tl_set:Nn \l__chemnum_list_last_sep_empty_tl { empty } \bool_new:N \l__chemnum_cmpd_ref_bool \msg_set:nnnn { chemnum } { fatal-combination } { You~can't~use \c_space_tl \token_to_str:N \cmpd \c_space_tl with~star~and~#1 \c_space_tl \msg_line_context: . } { You~used \c_space_tl \token_to_str:N \cmpd \c_space_tl with~both~star~and~#1 \c_space_tl \msg_line_context: .\\ ~This~is~not~possible~since~it~doesn't~make~any~sense. } %-----------------------------------------------------------------------------% % MAIN COMMAND % \cmpd*+-[]{<(possibly comma separated list of) compound % label(s)>} \NewDocumentCommand \__chemnum_input_separator:n { > { \exp_args:No \SplitList { \l__chemnum_list_input_separator_tl } } m } { \tl_set:Nn \l__chemnum_tmpb_tl { #1 } } \NewDocumentCommand \cmpd { s t+ t- o m } { \cmpd_main:nnnnn { #1 } { #2 } { #3 } { #4 } { #5 } } \cs_new_protected:Npn \cmpd_main:nnnnn #1#2#3#4#5 { \IfBooleanT #2 { \bool_set_true:N \l__chemnum_cmpd_ref_bool \IfBooleanT #1 { \msg_error:nnx { chemnum } { fatal-combination } { plus } } } \tl_clear:N \l__chemnum_tmpa_tl \group_begin: \int_zero:N \l__chemnum_list_items_int \int_zero:N \l__chemnum_list_separate_int \IfNoValueF { #4 } { \keys_set:nn { chemnum } { #4 } } \__chemnum_input_separator:n { #5 } \tl_map_variable:NNn \l__chemnum_tmpb_tl \l__chemnum_tmpa_tl { \tl_if_blank:VF \l__chemnum_tmpa_tl { \int_incr:N \l__chemnum_list_items_int } } \tl_map_variable:NNn \l__chemnum_tmpb_tl \l__chemnum_tmpa_tl { \tl_remove_all:Nn \l__chemnum_tmpa_tl { ~ } \tl_if_blank:VF \l__chemnum_tmpa_tl { \int_incr:N \l__chemnum_list_separate_int \IfBooleanF #1 { \if_int_compare:w \l__chemnum_list_separate_int = 1 \if_int_compare:w \l__chemnum_list_items_int = 1 \else: \tl_use:N \l__chemnum_list_prefix_tl \tl_if_blank:VF { \l__chemnum_list_prefix_tl } { \l__chemnum_list_space_tl } \tl_use:N \l__chemnum_list_odelim_tl \fi: \fi: } \IfBooleanTF #1 { \__chemnum_cmpd:Vnn \l__chemnum_tmpa_tl { \BooleanTrue } { \BooleanFalse } \IfBooleanT #3 { \msg_error:nnx { chemnum } { fatal-combination } { minus } } } { \IfBooleanTF #3 { \__chemnum_cmpd:Vnn \l__chemnum_tmpa_tl { \BooleanFalse } { \BooleanTrue } } { \__chemnum_cmpd:Vnn \l__chemnum_tmpa_tl { \BooleanFalse } { \BooleanFalse } } \int_compare:nTF { \l__chemnum_list_separate_int = \l__chemnum_list_items_int } { \int_compare:nNnF { \l__chemnum_list_items_int } = { 1 } { \tl_use:N \l__chemnum_list_cdelim_tl \tl_if_blank:VF { \l__chemnum_list_suffix_tl } { \l__chemnum_list_space_tl } \tl_use:N \l__chemnum_list_suffix_tl } } { \int_compare:nTF { \l__chemnum_list_separate_int = \int_eval:n { \l__chemnum_list_items_int - 1 } } { \tl_if_eq:NNTF \l__chemnum_list_last_separator_tl \l__chemnum_list_last_sep_empty_tl { \tl_use:N \l__chemnum_list_separator_tl \l__chemnum_list_space_tl } { \int_compare:nNnF { \l__chemnum_list_separate_int } = { 1 } { \bool_if:NF \l__chemnum_no_serial_comma_bool { \l__chemnum_list_separator_tl } } \tl_if_blank:VF \l__chemnum_list_last_separator_tl { \l__chemnum_list_space_tl } \tl_use:N \l__chemnum_list_last_separator_tl \l__chemnum_list_space_tl } } { \tl_use:N \l__chemnum_list_separator_tl \l__chemnum_list_space_tl } } } } } \group_end: \bool_set_false:N \l__chemnum_cmpd_ref_bool } %-----------------------------------------------------------------------------% % INITIALISING LABELS \bool_new:N \l__chemnum_cmpd_initiated_bool \bool_new:N \l__chemnum_cmpd_init_strict_bool \bool_new:N \l__chemnum_cmpd_sub_init_bool \bool_new:N \l__chemnum_cmpd_init_declare_bool \tl_new:N \l__chemnum_cmpd_init_separator_tl \tl_set:Nn \l__chemnum_cmpd_init_separator_tl { , } % property keys for \cmpdinit command % strict=true will produce an error instead of a warning \keys_define:nn { chemnum } { init-strict .bool_set:N = \l__chemnum_cmpd_init_strict_bool , init-strict .default:n = true , init-sub .bool_set:N = \l__chemnum_cmpd_sub_init_bool , init-sub .default:n = true , init-input-sep .tl_set:N = \l__chemnum_cmpd_init_separator_tl , init-input-sep .default:n = { , } } % warning/error messages \msg_set:nnn { chemnum } { cmpd-init } { You~used~\token_to_str:N \cmpdinit \c_space_tl but~didn't~initiate~ compound~"#1"~\msg_line_context: . } \msg_set:nnn { chemnum } { cmpd-init-sub } { You~used~\token_to_str:N \cmpdinit \c_space_tl and~"init-sub~=~true"~ but~didn't~initiate~sub-compound~"#1"~\msg_line_context: . } % initialize (and maybe declare) labels \cs_new_protected:Npn \__chemnum_cmpd_init:n #1 { \tl_clear:N \l__chemnum_tmpa_tl \tl_set:Nn \l__chemnum_tmpa_tl { #1 } \tl_remove_all:Nn \l__chemnum_tmpa_tl { ~ } \tl_clear:N \l__chemnum_cmpd_main_label_tl \tl_clear:N \l__chemnum_cmpd_sub_label_tl \exp_after:wN \__chemnum_cmpd_labelsep:n \l__chemnum_tmpa_tl \q_stop \cs_if_exist:cF { chemnum_cmpd_ \l__chemnum_cmpd_main_label_tl _init: } { \cs_new_protected:cpn { chemnum_cmpd_ \l__chemnum_cmpd_main_label_tl _init: } { } } \bool_if:NT \l__chemnum_cmpd_sub_init_bool { \tl_if_blank:VF \l__chemnum_cmpd_sub_label_tl { \__chemnum_cmpd_sublist:V \l__chemnum_cmpd_sub_label_tl \tl_map_inline:Nn \l__chemnum_cmpd_sublist_tl { \cs_if_exist:cF { chemnum_cmpd_ \l__chemnum_cmpd_main_label_tl _ ##1 _init: } { \cs_new_protected:cpn { chemnum_cmpd_ \l__chemnum_cmpd_main_label_tl _ ##1 _init: } { } } } } } \bool_if:NT \l__chemnum_cmpd_init_declare_bool { \__chemnum_cmpd:Vnn \l__chemnum_tmpa_tl { \BooleanTrue } { \BooleanFalse } } } \cs_generate_variant:Nn \__chemnum_cmpd_sublist:n { V } % \cmpdinit*[strict=]{} \NewDocumentCommand \cmpdinit { s o m } { \bool_set_true:N \l__chemnum_cmpd_initiated_bool \IfBooleanTF #1 { \bool_set_false:N \l__chemnum_cmpd_init_declare_bool } { \bool_set_true:N \l__chemnum_cmpd_init_declare_bool } \IfNoValueF { #2 } { \keys_set:nn { chemnum } { #2 } } \__chemnum_input_separator:n { #3 } \tl_map_function:NN \l__chemnum_tmpb_tl \__chemnum_cmpd_init:n } %-----------------------------------------------------------------------------% % RESET LABEL NUMBERS % \cmpdreset[] \NewDocumentCommand \cmpdreset { o } { \IfNoValueTF { #1 } { \int_zero:N \g__chemnum_cmpd_int } { \int_set:Nn \g__chemnum_cmpd_int { #1 - 1 } } } %-----------------------------------------------------------------------------% % CHEMNUM SETUP COMMAND % \cmpdsetup{} \NewDocumentCommand \cmpdsetup { m } { \keys_set:nn { chemnum } { #1 } \tex_ignorespaces:D } %-----------------------------------------------------------------------------% % REPLACE TAG IN EPS PICTURE WITH LABEL % works similar to \schemeref command of the chemscheme package % \cmpdref-[][]{