%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% - chemnum - chemnum.sty                                                   - %
% - a comprehensive numbering method for chemical compounds                 - %
% --------------------------------------------------------------------------- %
% - Clemens NIEDERBERGER                                                    - %
% - 2011/09/03                                                              - %
% --------------------------------------------------------------------------- %
% - http://www.mychemistry.eu/                                              - %
% - contact@mychemistry.eu                                                  - %
% --------------------------------------------------------------------------- %
% - If you have any ideas, questions, suggestions or bugs to report, please - %
% - feel free to contact me.                                                - %
% --------------------------------------------------------------------------- %
% - Copyright 2011 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_doc_de.tex,        - %
% - chemnum_doc_en.tex, bsp.tex, scheme-tmp.eps, scheme-bla.eps README and  - %
% - the derived files chemnum_doc_de.pdf and chemnum_doc_en.pdf             - %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\RequirePackage { expl3 , xparse , etoolbox , psfrag }

\ProvidesExplPackage {chemnum} {2011/09/03} {0.3a} {Numbering chemical compounds}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% CHECK FOR SUPPORT
% this part of the code is based on the corresponding part of siunitx.sty
% l3 support:
\cs_if_exist:NTF \msg_set:nnnn
  {
    \msg_set:nnnn { chemnum } { support-outdated }
      { Support~package~#1~too~old. }
      {
        Please~install~an~up~to~date~version~of~#1. \\
        Best~would~be~to~update~both~l3kernel~and~l3packages~bundles. \\
        Loading~chemnum~will~abort!
      }
  }
  {
    \PackageError { chemnum } { Support~bundle~l3kernel~too~old. }
      {
        Please~install~an~up~to~date~version~of~the~l3kernel~bundle. \\
        Loading~chemnum~will~abort!
      }
    \tex_endinput:D
  }
\@ifpackagelater { expl3 } { 2011/06/04 }
  { }
  {
    \msg_error:nnx { chemnum } { support-outdated } { expl3 }
    \tex_endinput:D
  }

\@ifpackagelater { xparse } { 2011/06/04 }
  { }
  {
    \msg_error:nnx { chemnum } { support-outdated } { xparse }
    \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 = <value>" is used
\msg_set:nnnn { chemnum } { package-loaded }
  { Package~#1~already~loaded. }
  {
    The~package~#1~has~already~been~loaded. \\
    \tl_if_blank:nF { #2 } { Option~#2~will~not~be~used. }
  }

% textgreek support and package options:
\bool_new:N \l_chemnum_textgreek_bool

\cs_new:Npn \chemnum_load_package:nn #1#2
  {
    \bool_if:cT { l_chemnum_#2_bool }
      {
        \AtEndPreamble
          {
            \exp_args:No \file_if_exist:nTF { #2 . sty }
              {
                \tl_if_blank:nTF { #1 }
                  { \RequirePackage { #2 } }
                  {
                    \@ifpackageloaded { #2 }
                      {
                        \msg_warning:nnxx
                          { chemnum } { package-loaded } { #2 } { #1 }
                      }
                      { \RequirePackage [ #1 ] { #2 } }
                  }
              }
              {
                \msg_warning:nnx { chemnum } { support-missing } { #2 }
                \bool_set_false:c { l_chemnum_#2_bool }
              }
          }
      }
  }

\cs_new:Npn \chemnum_package_options:n #1
  { \keys_set:nn { chemnum / package } { #1 } }

\keys_define:nn { chemnum / package } {
  textgreek .choice: ,
  textgreek .choice_code:n      =
    \chemnum_load_package:nn \l_keys_choice_tl { textgreek } ,
  textgreek .generate_choices:n = { artemisia , cbgreek , euler } ,
  textgreek .default:n          = cbgreek
}

\DeclareOption { textgreek }
  {
    \bool_set_true:N \l_chemnum_textgreek_bool
    \chemnum_package_options:n { textgreek }
  }
\DeclareOption { textgreek = artemisia }
  {
    \bool_set_true:N \l_chemnum_textgreek_bool
    \chemnum_package_options:n { textgreek = artemisia }
  }
\DeclareOption { textgreek = cbgreek }
  {
    \bool_set_true:N \l_chemnum_textgreek_bool
    \chemnum_package_options:n { textgreek = cbgreek }
  }
\DeclareOption { textgreek = euler }
  {
    \bool_set_true:N \l_chemnum_textgreek_bool
    \chemnum_package_options:n { textgreek = euler }
  }
\DeclareOption { textgreek = false }
  { \bool_set_false:N \l_chemnum_textgreek_bool }

\ExecuteOptions { textgreek }
\ProcessOptions \scan_stop:

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% TOOLS
\int_new:N \g_chemnum_cmpd_main_int
\prop_new:N \g_chemnum_label_prop
\int_new:N \g_chemnum_cmpd_int
\tl_new:N \l_chemnum_tmpa_tl
\tl_new:N \l_chemnum_tmpb_tl
\clist_new:N \g_chemnum_cmpd_save_clist

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% READ FROM PREVIOUS RUN, SAVE FOR NEXT RUN
% save all labels in a clist
\cs_new:Npn \chemnum_cmpd_save:n #1
  { \clist_gput_right:Nn \g_chemnum_cmpd_save_clist { #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 <jobname>.cmpd file to make them
% available at the next run
\AtEndDocument
  {
    \iow_open:Nn \chemnum_aux_file { ./ \c_job_name_tl . cmpd }
    \clist_map_inline:Nn \g_chemnum_cmpd_save_clist
      {
        \iow_now:Nx \chemnum_aux_file
          {
            \use:c { cs_new_nopar: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_nopar: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_nopar: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_nopar:Npn \chemnum_cmpd_style_value:n { \bfseries }

% error message
\msg_set:nnn { chemnum } { cmpd-style } { The~value~of~"cmpd-style~=~<style>"~needs~to~be~a~(or~more)~macro~\msg_line_context: . }

% set style %TODO
\cs_new_nopar:Npn \chemnum_cmpd_set_style:n #1
%   {
%     \tl_clear:N \l_chemnum_style_tmp_tl
%     \tl_map_variable:nNn { #1 } \l_chemnum_style_tmp_tl
%       {
%         \exp_args:No \token_if_cs:NTF \l_chemnum_style_tmp_tl
%           { \bool_set_true:N \l_chemnum_cmpd_style_is_macro_bool }
%           { \bool_set_false:N \l_chemnum_cmpd_style_is_macro_bool }
%       }
%     \bool_if:NTF \l_chemnum_cmpd_style_is_macro_bool
      { \cs_set_nopar:Npn \chemnum_cmpd_style_value:n { #1 } }
%       { \msg_error:nnx { chemnum } { cmpd-style } { #1 } }
%   }

% use style
\cs_new_nopar:Npn \chemnum_cmpd_use_style:n #1
  { \group_begin: \chemnum_cmpd_style_value: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~=~<odelim><cdelim>"~needs~two~tokens~or~token~groups~as~a~value~
    \msg_line_context: .
  }

% set compound delimiters
\cs_new_nopar: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_length: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_nopar: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_nopar: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_convert_to_symbols:nnn {#1} { 24 }
          {
            {  1 } { \exp_not:o \textalpha }
            {  2 } { \exp_not:o \textbeta }
            {  3 } { \exp_not:o \textgamma }
            {  4 } { \exp_not:o \textdelta }
            {  5 } { \exp_not:o \textepsilon }
            {  6 } { \exp_not:o \textzeta }
            {  7 } { \exp_not:o \texteta }
            {  8 } { \exp_not:o \texttheta }
            {  9 } { \exp_not:o \textiota }
            { 10 } { \exp_not:o \textkappa }
            { 11 } { \exp_not:o \textlambda }
            { 12 } { \exp_not:o \textmugreek }
            { 13 } { \exp_not:o \textnu }
            { 14 } { \exp_not:o \textxi }
            { 15 } { \exp_not:o \textomikron }
            { 16 } { \exp_not:o \textpi }
            { 17 } { \exp_not:o \textrho }
            { 18 } { \exp_not:o \textsigma }
            { 19 } { \exp_not:o \texttau }
            { 20 } { \exp_not:o \textupsilon }
            { 21 } { \exp_not:o \textphi }
            { 22 } { \exp_not:o \textchi }
            { 23 } { \exp_not:o \textpsi }
            { 24 } { \exp_not:o \textomega }
          }
      }
  }
  {
    \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:Npn \int_to_Greek:n #1
      {
        \int_convert_to_symbols:nnn { #1 } { 24 }
          {
            {  1 } { \exp_not:o \textAlpha }
            {  2 } { \exp_not:o \textBeta }
            {  3 } { \exp_not:o \textGamma }
            {  4 } { \exp_not:o \textDelta }
            {  5 } { \exp_not:o \textEpsilon }
            {  6 } { \exp_not:o \textZeta }
            {  7 } { \exp_not:o \textEta }
            {  8 } { \exp_not:o \textTheta }
            {  9 } { \exp_not:o \textIota }
            { 10 } { \exp_not:o \textKappa }
            { 11 } { \exp_not:o \textLambda }
            { 12 } { \exp_not:o \textMu }
            { 13 } { \exp_not:o \textNu }
            { 14 } { \exp_not:o \textXi }
            { 15 } { \exp_not:o \textOmikron }
            { 16 } { \exp_not:o \textPi }
            { 17 } { \exp_not:o \textRho }
            { 18 } { \exp_not:o \textSigma }
            { 19 } { \exp_not:o \textTau }
            { 20 } { \exp_not:o \textUpsilon }
            { 21 } { \exp_not:o \textPhi }
            { 22 } { \exp_not:o \textChi }
            { 23 } { \exp_not:o \textPsi }
            { 24 } { \exp_not:o \textOmega }
          }
      }
  }
  {
    \cs_set_eq:NN \int_to_Greek:n \int_to_Alph:n
  }

% define \int_to_Symbol function
\cs_new:Npn \int_to_Symbol:n #1
  {
    \int_convert_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_nopar: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_length: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: }
        \exp_args:No \tl_if_blank:nF { \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
\tl_new:N \l_chemnum_cmpd_name_tl

\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

\tl_new:N \l_chemnum_cmpd_labelsep_tl
\tl_set:Nn \l_chemnum_cmpd_labelsep_tl { . }

\tl_new:N \l_chemnum_sublabel_range_marker_tl
% \char_make_other:N \:
\tl_set:Nn \l_chemnum_sublabel_range_marker_tl { .. }
% \catcode 58 = 11 \relax

\tl_new:N \l_chemnum_sub_range_sep_tl
\tl_set:Nn \l_chemnum_sub_range_sep_tl { - }

%-----------------------------------------------------------------------------%
% property keys for compounds
\keys_define:nn { chemnum } {
  cmpd-style         .code:n             = \chemnum_cmpd_set_style:n { #1 } ,
  cmpd-style         .default:n          = \textbf ,
  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-sep           .tl_set:N           = \l_chemnum_cmpd_separator_tl ,
  cmpd-sep           .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 ,
  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-marker         .code:n             = \chemnum_subcmpdsep:n { #1 } ,
  sub-marker         .default:n          = . ,
  sub-range-marker   .code:n             =
    \chemnum_sublabel_range_marker:n { #1 } ,
  sub-range-marker   .default:n          = { .. } ,
  sub-range-sep      .tl_set:N           = \l_chemnum_sub_range_sep_tl ,
  sub-range-sep      .default:n          = { - } ,
  sub-list          .code:n             =
    {
      \tl_set:Nn \l_chemnum_cmpd_sublabel_list_tl { #1 }
      \bool_set_true:N \l_chemnum_sublabel_list_bool
    }
}

%-----------------------------------------------------------------------------%
% list separators, delimiters, prefix and suffix
\bool_new:N \l_chemnum_list_last_sep_US_bool
\bool_set_true:N \l_chemnum_list_last_sep_US_bool

\tl_new:N \l_chemnum_list_separator_tl
\tl_set:Nn \l_chemnum_list_separator_tl { , }

\tl_new:N \l_chemunm_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_nopar: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_length: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-sep           .tl_set:N  = \l_chemnum_list_separator_tl ,
  list-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-lang .choice: ,
  list-lang / US .code:n =
    {
      \bool_set_true:N \l_chemnum_list_last_sep_US_bool
      \tl_set:Nn \l_chemnum_list_last_separator_lang_tl { and }
    } ,
  list-lang / GB .code:n =
    {
      \bool_set_false:N \l_chemnum_list_last_sep_US_bool
      \tl_set:Nn \l_chemnum_list_last_separator_lang_tl { and }
    } ,
  list-lang / DE .code:n =
    {
      \bool_set_false:N \l_chemnum_list_last_sep_US_bool
      \tl_set:Nn \l_chemnum_list_last_separator_lang_tl { und }
    } ,
  list-lang / FR .code:n =
    {
      \bool_set_false:N \l_chemnum_list_last_sep_US_bool
      \tl_set:Nn \l_chemnum_list_last_separator_lang_tl { et }
    } ,
  list-lang / IT .code:n =
    {
      \bool_set_false:N \l_chemnum_list_last_sep_US_bool
      \tl_set:Nn \l_chemnum_list_last_separator_lang_tl { e }
    } ,
  list-lang / ES .code:n =
    {
      \bool_set_false:N \l_chemnum_list_last_sep_US_bool
      \tl_set:Nn \l_chemnum_list_last_separator_lang_tl { y }
    } ,
  list-lang .default:n = US
}

%-----------------------------------------------------------------------------%
% label and sublabel declaration
\cs_new: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_nopar: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:Npn \chemnum_cmpd_sub_declare:nn #1#2
  {
    \cs_if_exist:cF { chemnum_cmpd_#1_#2: }
      {
        \chemnum_cmpd_save:n { #1 _ #2 }
        \cs_new_nopar:cpx { chemnum_cmpd_#1_#2: } { }
        \int_gincr:c { g_chemnum_cmpd_#1_int }
        \cs_gset_nopar:cx { chemnum_cmpd_#1_#2: }
          {
            \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: }
      }
  }

%-----------------------------------------------------------------------------%
% label and sublabel initiation
\cs_new: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 }
              {
                \cs_if_exist:cF { chemnum_cmpd_ #1 _ #2 _init: }
                  {
                    \bool_if:NTF \l_chemnum_cmpd_init_strict_bool
                      {
                        \msg_error:nnx   { chemnum } { cmpd-sub-init }
                          { #1 \l_chemnum_cmpd_labelsep_tl #2 }
                      }
                      {
                        \msg_warning:nnx { chemnum } { cmpd-sub-init }
                          { #1 \l_chemnum_cmpd_labelsep_tl #2 }
                      }
                  }
              }
          }
      }
      {
        \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

% actual separating
\cs_new_nopar: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_nopar:Npn \chemnum_cmpd_labelsep:n #1 \q_stop {
  \tl_clear:N \l_chemnum_labelsep_tmp_tl
  \exp_args:Noo \tl_if_in:nnTF { #1 } { \l_chemnum_cmpd_labelsep_tl }
    { 
      \tl_set:Nn \l_chemnum_labelsep_tmp_tl { #1 }
      \exp_args:NNo \tl_replace_once:Nnn \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_new_nopar: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_nopar: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 range
\cs_new_nopar: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 } }
}

\cs_new_nopar:Npn \chemnum_cmpd_sublabelsep:n #1 \q_stop {
  \tl_clear:N \l_chemnum_sublabelsep_tmp_tl
  \exp_args:Noo \tl_if_in:nnTF { #1 } { \l_chemnum_sublabel_range_marker_tl }
    { 
      \tl_set:Nn \l_chemnum_sublabelsep_tmp_tl { #1 }
      \exp_args:NNo \tl_replace_once:Nnn \l_chemnum_sublabelsep_tmp_tl
        { \l_chemnum_sublabel_range_marker_tl }
        { \q_nil }
      \exp_after:wN \chemnum_cmpd_sublabelsep_aux_ii:n
        \l_chemnum_sublabelsep_tmp_tl \q_stop
    }
    { \chemnum_cmpd_sublabelsep_aux_i:n { #1 } }
}

\cs_new_nopar:Npn \chemnum_cmpd_sublabelsep_aux_i:n #1 {
  \tl_set:Nn \l_chemnum_cmpd_sub_one_label_tl { #1 }
  \tl_clear:N \l_chemnum_cmpd_sub_two_label_tl
}

\cs_new_nopar:Npn \chemnum_cmpd_sublabelsep_aux_ii:n #1 \q_nil #2 \q_stop {
  \tl_set:Nn \l_chemnum_cmpd_sub_one_label_tl { #1 }
  \tl_set:Nn \l_chemnum_cmpd_sub_two_label_tl { #2 }
}

\cs_if_exist:NF \cs_if_eq:ccF
  { \cs_generate_variant:Nn \cs_if_eq:NNF { ccF } }

%-----------------------------------------------------------------------------%
% print compound label
\cs_new_nopar: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: <main label> #2: <sub label> #3: <invisible> #4: <no delim>
\cs_new_nopar:Npn \chemnum_cmpd_aux_i: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 } }
    \tl_if_blank:nF { #2 }
      {
        \cs_if_exist:cF { g_chemnum_cmpd_#1_int }
          { \int_new:c { g_chemnum_cmpd_#1_int } }
        \bool_if:NF \l_chemnum_cmpd_ref_bool
          { \chemnum_cmpd_sub_declare:nn { #1 } { #2 } }
      }
    \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_cmpd_print:n
          {
            \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
                        \bool_if:NTF \l_chemnum_cmpd_ref_bool
                          { \use:c { chemnum_cmpd_ #1 _ #2 _ref: } }
                          { \use:c { chemnum_cmpd_ #1 _ #2 : } }
                      }
                  }
              }
          }
      }
  }

\cs_generate_variant:Nn \chemnum_cmpd_aux_i:nnnn { oonn }

%-----------------------------------------------------------------------------%
% create compound label
% #1: label name #2: star (invisible) #3: minus (no delimiters)
\cs_new_nopar: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
    \chemnum_cmpd_aux_i:oonn
      { \l_chemnum_cmpd_main_label_tl }
      { \l_chemnum_cmpd_sub_label_tl }
      { #2 }
      { #3 }
  \group_end:
}

\cs_generate_variant:Nn \chemnum_cmpd:nnn { onn }

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 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*+-[<key-value-list>]{<(possibly comma separated list of) compound
% label(s)>}
\NewDocumentCommand \cmpd { s t+ t- o m }
  {
    \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 } }
      \clist_map_variable:nNn { #5 } \l_chemnum_tmpa_tl
        {
          \tl_if_blank:VF \l_chemnum_tmpa_tl
            { \int_incr:N \l_chemnum_list_items_int }
        }
      \clist_map_variable:nNn { #5 } \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:onn
                    { \l_chemnum_tmpa_tl }
                    { \BooleanTrue }
                    { \BooleanFalse }
                  \IfBooleanT #3
                    {
                      \msg_error:nnx { chemnum }
                        { fatal-combination } { minus }
                    }
                }
                { 
                  \IfBooleanTF #3
                    {
                      \chemnum_cmpd:onn
                        { \l_chemnum_tmpa_tl }
                        { \BooleanFalse }
                        { \BooleanTrue }
                    }
                    {
                      \chemnum_cmpd:onn
                        { \l_chemnum_tmpa_tl }
                        { \BooleanFalse }
                        { \BooleanFalse }
                    }
                  \if_int_compare:w
                    \l_chemnum_list_separate_int = \l_chemnum_list_items_int
                    \if_int_compare:w \l_chemnum_list_items_int = 1 \else:
                      \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
                    \fi:
                  \else:
                    \if_int_compare:w \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
                        }
                        {
                          \if_int_compare:w \l_chemnum_list_separate_int = 1
                          \else:
                            \bool_if:NT \l_chemnum_list_last_sep_US_bool
                              { \l_chemnum_list_separator_tl }
                          \fi:
                          \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
                        }
                    \else:
                      \tl_use:N \l_chemnum_list_separator_tl
                      \l_chemnum_list_space_tl
                    \fi:
                  \fi:
                }
            }
        }
    \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
\clist_new:N \l_chemnum_cmpd_init_clist

% 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 ,
  strict   .default:n  = true ,
  sub-init .bool_set:N = \l_chemnum_cmpd_sub_init_bool ,
  sub-init .default:n  = true
}

% 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-sub-init }
  {
    You~used~\token_to_str:N \cmpdinit \c_space_tl and~"sub-init~=~true"~
    but~didn't~initiate~sub-compound~"#1"~\msg_line_context: .
  }

% initialize (and maybe declare) labels
\cs_new_nopar: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_nopar: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
          {
            \cs_if_exist:cF
              {
                chemnum_cmpd_ 
                \l_chemnum_cmpd_main_label_tl
                _
                \l_chemnum_cmpd_sub_label_tl
                _init:
              }
              {
                \cs_new_nopar:cpn
                  {
                    chemnum_cmpd_
                    \l_chemnum_cmpd_main_label_tl
                    _
                    \l_chemnum_cmpd_sub_label_tl
                    _init:
                  }
                  { }
              }
          }
      }
    \bool_if:NT \l_chemnum_cmpd_init_declare_bool
      {
        \chemnum_cmpd:onn
          { \l_chemnum_tmpa_tl }
          { \BooleanTrue }
          { \BooleanFalse }
      }
  }

% \cmpdinit*[strict=<bool>]{<comma separated list of label names>}
\NewDocumentCommand \cmpdinit { s o m }
  {
    \bool_set_false:N \l_chemnum_cmpd_init_strict_bool
    \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 / init } { #2 } }
    \clist_map_function:nN { #3 } \chemnum_cmpd_init:n
  }

%-----------------------------------------------------------------------------%
% RESET LABEL NUMBERS
% \cmpdreset[<number>]
\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{<key-value-list>}
\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-[<keyval>][<tag>]{<label name>}
\tl_new:N \l_chemnum_cmpdref_tl
\int_new:N \l_chemnum_cmpdref_int
\tl_new:N \l_chemnum_cmpdref_marker_tl
\tl_set:Nn \l_chemnum_cmpdref_marker_tl { TMP }

\keys_define:nn { chemnum }
  {
    ref-tag .tl_set:N  = \l_chemnum_cmpdref_marker_tl ,
    ref-tag .default:n = { TMP }
  }

\NewDocumentCommand \cmpdref { t- o o m }
  {
%     \group_begin:
      \IfBooleanT { #1 }
        { \cmpdsetup { cmpd-delim = } }
%       \IfNoValueF { #2 }
%         { \keys_set:nn { chemnum } { #2 } }
      \IfNoValueTF { #3 }
        {
          \int_incr:N \l_chemnum_cmpdref_int
          \tl_set:No \l_chemnum_cmpdref_tl
            {
              \tl_use:N \l_chemnum_cmpdref_marker_tl
              \int_use:N \l_chemnum_cmpdref_int
            }
        }
        {
          \tl_set:Nn \l_chemnum_cmpdref_tl { #3 }
        }
      \IfNoValueTF { #2 }
        {
          \psfrag { \l_chemnum_cmpdref_tl } [ b ] [ b ] { \cmpd { #4 } }
        }
        {
          \psfrag { \l_chemnum_cmpdref_tl } [ b ] [ b ] { \cmpd [ #2 ] { #4 } }
        }
%     \group_end:
  }

\tex_endinput:D

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
HISTORY:
 2011/06/27 version 0.1
 2011/06/29 version 0.1a - bugfixes
 2011/07/17 version 0.2  - instead of two commands (\cmpd and \cmpdlist ) only 
                         one (\cmpd) for both tasks
                         - setup with a keyval system
                         - possibility to initiate sublabels
                         - choices "greek" and "Greek" for the cmpd-counter
                         keys, choice "symbol" changed to "Symbol"
                         - package option "textgreek = <value>" to control
                         usage of the textgreek package
                         - former \cmpd+ is now \cmpd-
                         - new \cmpd+ added which reads label from
                         <jobname>.cmpd
                         - bugfix: wrong declaration in \cmpdinit and \cmpd
                         when used with line break fixed
                         - bugfix: error when \cmpd was used in vertical mode
                         fixed
                         - bugfix: corrected up to date support test
                         - bugfix: wrong output in \cmpd* list removed
                         - commented and cleaned up code
 2011/08/02 version 0.3  - keys "cmpd-all", "sub-list", "sub-range-sep" and
                         "sub-range-marker" added, key "cmpd-sub-counter"
                         renamed into "sub-counter", key "sub-cmpd-sep"
                         renamed into "sub-marker"
                         - \cmpdref-[<keyval>][<tag>]{<label name>} added
                         - key "ref-tag" added
                         - cleaned up code
 2011/09/03 version 0.3a - it is now impossible to use the (conflicting or 
                         better: senseless) \cmpd*+ and \cmpd*- command
                         versions. An error message is produced.
                         - made sure code has no more than 80 tokens per line
                         to improve readability on small screens
                         - bug (unwanted whitespace) in \cmpdsetup fixed
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
TODO:
 - Bug: wenn als "sub-marker" ":" von einer anderen Datei gesetzt wird, wird
   der Key nicht erkannt -> catcode Problem: entweder temporär catcode von ":"
   wieder auf 12 setzen oder den Marker prinzipiell auf 11?
 - einen Key "hide-main" oder "sub-only" hinzufügen?
 - Bug: Key "cmpd-style" wenn zB \color{<farbe>} eingegeben: Fehler beim Test
   auf Makro; Test entfernen?
 - \cmpdref: Reihenfolge der optionalen Argumente vertauschen?