%%%==============================================================================
%% Copyright 2023-present by Alceu Frigeri
%%
%% This work may be distributed and/or modified under the conditions of
%%
%% * The [LaTeX Project Public License](http://www.latex-project.org/lppl.txt),
%%   version 1.3c (or later), and/or
%% * The [GNU Affero General Public License](https://www.gnu.org/licenses/agpl-3.0.html),
%%   version 3 (or later)
%%
%% This work has the LPPL maintenance status *maintained*.
%%
%% The Current Maintainer of this work is Alceu Frigeri
%%
%% This is version {1.20} {2025/12/17}
%%
%% The list of files that compose this work can be found in the README.md file at
%% https://ctan.org/pkg/codedescribe
%%
%%%==============================================================================
\NeedsTeXFormat{LaTeX2e}[2022/06/01]

%%%%%%%
%%%
%%% Just an attempt at having my package's info in a regular way
%%%   \pkginfograb_set:nn {<pkg-name>} { props} sets package info
%%%
%%%   \pkginfograbProvidesExplPackage {<pkg-name>} { props} sets package info
%%%     and calls \ProvidesExplPackage
%%%
%%%%%%%
\RequirePackage{pkginfograb}
\pkginfograbProvidesExplPackage {codedescribe}
  {
     name        = {codedescribe} ,
     prefix      = {codedesc} ,
     date        = {2025/12/17} ,
     version     = {1.20} ,
     description = {LaTeX Code Description/Documentation}
  }
%%%%%%%
%%% End of cut-n-paste
%%%%%%%

\use:c {@reversemargintrue}


%% bbding is need for those hollow stars...
\RequirePackage{xcolor,pifont}
\RequirePackage{xpeekahead,codecmm}

\cs_generate_variant:Nn \tl_set:Nn {Ne}
\cs_generate_variant:Nn \keys_set:nn {ne}
\cs_generate_variant:Nn \keys_define:nn {ne}
\cs_generate_variant:Nn \keys_precompile:nnN {nV}
\cs_generate_variant:Nn \tl_to_str:n {o , e}
\cs_generate_variant:Nn \msg_error:nnnnn {nnnne}
\cs_generate_variant:Nn \cs_set:Nn {cV}
\cs_generate_variant:Nn \cs_gset:Nn {cV}


    %%%%%%%
    %%% prep. for an eventual `side notes` parametrization
    %%%%%%%
\cs_set_eq:NN \__codedesc_note_fmt: \scriptsize

\bool_new:N \l__codedesc_loadlisting_bool
\bool_set_true:N \l__codedesc_loadlisting_bool
\bool_new:N \l__codedesc_indexdefault_bool

\tl_set:Nn \l__codedesc_colors_bright_tl {default}

%% instead of using kernel scratch variables.
\tl_new:N \l__codedesc_tmpa_tl
\tl_new:N \l__codedesc_tmpb_tl
\tl_new:N \l__codedescribe_tmpc_tl
\seq_new:N \l__codedesc_tmpa_seq
\seq_new:N \l__codedesc_tmpb_seq
\coffin_new:N \l__codedesc_tmpa_coffin
\coffin_new:N \l__codedesc_tmpb_coffin

\tl_new:N \l__codedesc_scheme_tmp_tl

    %%%%%%%
    %%% label sets (package option)
    %%%%%%%
\prop_new_linked:N \l__codedesc_labelsets_prop
\seq_new:N \l__codedesc_labelsets_seq

    %%%%%%%
    %%% This one comes first because can be called while loading.
    %%%%%%%
\msg_new:nnnn {codedesc} {locale-err}
  {
    (ID:#1)~label~set~(#2)~not~defined! ~valid~ones:~#3
  }
  {
    You~tried~to~use~a~non~defined~label~set:#2.
    ~Error~Code~ ID:<#1>.
    ~Valid~ sets: ~ #3
  }

\keys_define:nn {codedescribe / labels}
  {
    new .usage:n = general , 
    new .tl_set:N = \l__codedesc_new_label_tl ,
    new .value_required:n = true ,
    
    update .usage:n = general , 
    update .tl_set:N = \l__codedesc_update_label_tl ,
    update .value_required:n = true ,
    
    note .usage:n = general , 
    note .tl_set:N = \l__codedesc_note_label_tl ,
    note .value_required:n = true ,

    remark .usage:n = general , 
    remark .tl_set:N = \l__codedesc_remark_label_tl ,
    remark .value_required:n = true ,

    or .usage:n = general , 
    or .tl_set:N = \l__codedesc_or_label_tl ,
    or .value_required:n = true ,

    and .usage:n = general , 
    and .tl_set:N = \l__codedesc_and_label_tl ,
    and .value_required:n = true ,

    months .usage:n = general , 
    months .code:n = 
      { \seq_set_from_clist:Nn \l__codedesc_months_label_seq {#1} } ,
    months .value_required:n = true ,
  }
  
\cs_new_protected:Npn \__codedesc_setlabels:n #1
  {
    \keys_set:Nn {codedescribe / labels}{#1}
  }

\cs_new_protected:Npn \__codedesc_new_labelset:nn #1#2
  {
    \keys_precompile:nnN {codedescribe / labels} {#2} \l__codedesc_tmpa_tl
    \prop_put:NnV \l__codedesc_labelsets_prop {#1} \l__codedesc_tmpa_tl
    \seq_put_right:Nn \l__codedesc_labelsets_seq {#1}
  }

\cs_new_protected:Npn \__codedesc_select_labelset:n #1
  {
    \prop_get:NnNTF \l__codedesc_labelsets_prop {#1} \l__codedesc_tmpa_tl
      { \l__codedesc_tmpa_tl }
      {
        \msg_error:nnnne {codedesc} {locale-err}
          {locale01} {#1} { \seq_use:Nn \l__codedesc_labelsets_seq {,~} } 
      }
  }

\cs_new_eq:NN \newlabelset    \__codedesc_new_labelset:nn
\cs_new_eq:NN \selectlabelset \__codedesc_select_labelset:n
\cs_new_eq:NN \setcodelabels  \__codedesc_setlabels:n


    %%%%%%%
    %%% language set are to be defined at codedescsets
    %%%%%%%
\RequirePackage{codedescsets}

    %%%%%%%
    %%% Default label set
    %%%%%%%
\__codedesc_select_labelset:n {english}


\bool_new:N \l__codedesc_descnotes_inseq_bool
%\bool_set_false:N \l__codedesc_descnotes_inseq_bool
\bool_new:N \l__codedesc_normal_margin_bool
\bool_set_true:N \l__codedesc_normal_margin_bool

\keys_define:nn { codedescribe }
  {
    nolisting .usage:n    = load ,
  	nolisting .bool_set_inverse:N = \l__codedesc_loadlisting_bool ,
    nolisting .default:n  = {true} ,
    
    no~ listing .usage:n    = load ,
  	no~ listing .bool_set_inverse:N = \l__codedesc_loadlisting_bool ,
    no~ listing .default:n  = {true} ,
    
    index .usage:n    = load ,
  	index .bool_set:N = \l__codedesc_indexdefault_bool ,
    index .default:n  = {true} ,
    
    describe~ keys .usage:n  = load ,
    describe~ keys .value_required:n = true ,
    describe~ keys .choice: ,
    describe~ keys / group
      .code:n = { \bool_set_false:N \l__codedesc_descnotes_inseq_bool } ,
    describe~ keys / as~ is
      .code:n = { \bool_set_true:N \l__codedesc_descnotes_inseq_bool } ,
    describe~ keys / in~ sequence
      .code:n = { \bool_set_true:N \l__codedesc_descnotes_inseq_bool } ,

    load~ xtra~ dialects .usage:n    = load ,
  	load~ xtra~ dialects .code:n    =  { \PassOptionsToPackage{\CurrentOption}{codelisting} } ,
    load~ xtra~ dialects .value_forbidden:n  = true ,
    
    TeX~ dialects  .usage:n   =  general ,
    TeX~ dialects  .code:n    =  { \PassOptionsToPackage{\CurrentOption}{codelisting} } ,
    TeX~ dialects  .value_required:n = true ,
    
    base~ skip .usage:n   = load ,
    base~ skip .code:n  =
      {
        \__codecmm_set_skips:n {#1}
      } ,
    base~ skip .value_required:n = true ,
    
    label~ set .usage:n = load ,
    label~ set .code:n = 
      { \__codedesc_select_labelset:n {#1} } ,
    label~ set .value_required:n = true ,
    
    colors .usage:n = load ,
    colors .choices:nn =
      { default , black , brighter , darker }
      { \tl_set_eq:NN \l__codedesc_colors_bright_tl \l_keys_choice_tl } ,
    colors .value_required:n = true ,

    listing~ colors .usage:n = load ,
    listing~ colors .code:n    =  { \PassOptionsToPackage{\CurrentOption}{codelisting} } ,
    listing~ colors .value_required:n = true ,
    
    silence .usage:n = load ,
    silence .code:n =  
      { \hfuzz=#1 } ,
    silence .default:n = 18.89999pt ,
    
    strict .usage:n    = load ,
    strict .code:n = 
      {
        \msg_redirect_module:nnn {codedesc}      { warning } { error }
      } ,

    info grab .usage:n    = load ,
  	info grab .bool_set:N = \l__codedesc_infograb_aliases_bool ,
    info grab .default:n  = {true} ,
  }
\ProcessKeyOptions [codedescribe ]

\bool_if:NT \l__codedesc_loadlisting_bool
  { \RequirePackage{codelisting} }


\bool_if:NT \l__codedesc_infograb_aliases_bool
  { \pkginfograb_set_aliases: }


\msg_new:nnnn {codedesc} {key choice}
  {
    (ID:#1)~Choice~'#2'~not~defined!~Possible~values:~ #3
  }
  {
    You~tried~to~select~a~non~defined~value:#2.
    ~Possible~values:~#3
    ~Error~Code~ ID:<#1>.
  }



\msg_new:nnnn {codedesc} {format-err}
  {
    (ID:#1)~Format~Key~(#2)~not~defined!
  }
  {
    You~tried~to~use~a~non~defined~format~key:#2.
    ~Error~Code~ ID:<#1>.
  }

\msg_new:nnnn {codedesc} {group-err}
  {
    (ID:#1)~Format~group~(#2)~not~defined!
  }
  {
    You~tried~to~use~a~non~defined~format~group:#2.
    ~Error~Code~ ID:<#1>.
  }

\msg_new:nnnn {codedesc} {object-err}
  {
    (ID:#1)~Objetc~Type~(#2)~not~defined!
  }
  {
    You~tried~to~use~a~non~defined~object~type:#2.
    ~Error~Code~ ID:<#1>.
  }

\msg_new:nnnn {codedesc} {nested-env}
  {
    (ID:#1)~You~tried~to~nest~\{#2\}~inside~of~\{#3\}. ~Better~ not.
  }
  {
    You~tried~to~begin~\{#2\}~inside~of~\{#3\}.~ Better~ not.
    ~Error~Code~ ID:<#1>.
  }

\msg_new:nnnn {codedesc} {out of scope}
  {
    (ID:#1)~You~tried~to~use~\{#2\}~outside~of~\{#3\} 
  }
  {
    You~tried~to~use~\{#2\}~outside~of~\{#3\}.
    ~Error~Code~ ID:<#1>.
  }


\msg_new:nnnn {codedesc} {syntax dup}
  {
    (ID:#1)~You~declared~the~codesyntax~env~ multiple~times
  }
  {
    (ID:#1)~You~declared~the~codesyntax~env~multiple~times.
    Only~ the~ last~ one~ will~ prevail.
    ~Error~Code~ ID:<#1>.
  }

\msg_new:nnnn {codedesc} {deprecated env}
  {
    (ID:#1)~The~ environment~#2~is~ deprecated~ use~ #3 ~ instead
  }
  {
    You~tried~to~use~a~deprecated~ environment:#2.
    Use~ #3~ instead.
    ~Error~Code~ ID:<#1>.
  }



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


    %%%%%%%
    %%% Color schemes (package option)
    %%%%%%%
\cs_new_protected:Npn \__codedesc_set_colors:n #1
  {
    \__codecmm_color_set:ne {c__codedesc_none_color}       { \l__codedesc_scheme_error_tl  ! \fp_eval:n{ 45 + 15 * #1 } ! black ! 100 }
  	\__codecmm_color_set:ne {c__codedesc_verb_color}       { \l__codedesc_scheme_verb_tl   ! \fp_eval:n{ 35 * #1 }      ! black ! 100 }
  	\__codecmm_color_set:ne {c__codedesc_marg_color}       { \l__codedesc_scheme_args_tl   ! \fp_eval:n{ 45 + 15 * #1 } ! black ! 100 }
  	\__codecmm_color_set:ne {c__codedesc_oarg_color}       { \l__codedesc_scheme_args_tl   ! \fp_eval:n{ 65 + 15 * #1 } ! black ! 100 }
  
  	\__codecmm_color_set:ne {c__codedesc_code_color}       { \l__codedesc_scheme_code_tl   ! \fp_eval:n{ 35 * #1 }      ! black ! 100 }
  	\__codecmm_color_set:ne {c__codedesc_syntax_color}     { \l__codedesc_scheme_code_tl   ! \fp_eval:n{ 40 * #1 }      ! black ! 100 }
  	\__codecmm_color_set:ne {c__codedesc_keys_color}       { \l__codedesc_scheme_keys_tl   ! \fp_eval:n{ 35 * #1 }      ! black ! 100 }
  	\__codecmm_color_set:ne {c__codedesc_options_color}    { \l__codedesc_scheme_keys_tl   ! \fp_eval:n{ 35 * #1 }      ! black ! 100 }
  	\__codecmm_color_set:ne {c__codedesc_values_color}     { \l__codedesc_scheme_values_tl ! \fp_eval:n{ 35 * #1 }      ! black ! 100 }
  	\__codecmm_color_set:ne {c__codedesc_defaultval_color} { \l__codedesc_scheme_values_tl ! \fp_eval:n{ 40 * #1 }      ! black ! 100 }
  	\__codecmm_color_set:ne {c__codedesc_env_color}        { \l__codedesc_scheme_env_tl    ! \fp_eval:n{ 35 * #1 }      ! black ! 100 }
  	\__codecmm_color_set:ne {c__codedesc_pkg_color}        { \l__codedesc_scheme_pack_tl   ! \fp_eval:n{ 35 * #1 }      ! black ! 100 }
  }    
\cs_generate_variant:Nn  \__codedesc_set_colors:n {V}


\cs_new_protected:Npn \__codedesc_set_brightness:n #1
  {
    \str_case:enF {#1}
      {
        {default}
          { \__codedesc_set_colors:n {1} }
        {black}
          { \__codedesc_set_colors:n {0} }        
        {brighter}
          { \__codedesc_set_colors:n {2} }
        {darker}
          { \__codedesc_set_colors:n {0.70} }
      } %% fail-safe: default
      { \__codedesc_set_colors:n {1} }
  }
\cs_generate_variant:Nn  \__codedesc_set_brightness:n {V}


\keys_define:nn { codedesc / color scheme } 
  {
    error   .usage:n              = general ,
    error   .tl_set:N             = \l__codedesc_scheme_error_tl ,
    error   .default:n            = red ,

    verb    .usage:n              = general ,
    verb    .tl_set:N             = \l__codedesc_scheme_verb_tl ,
    verb    .default:n            = black ,
  
    args    .usage:n              = general ,
    args    .tl_set:N             = \l__codedesc_scheme_args_tl ,
    args    .default:n            = gray ,
    
    code    .usage:n              = general ,
    code    .tl_set:N             = \l__codedesc_scheme_code_tl ,
    code    .default:n            = blue ,
    
    keys    .usage:n              = general ,
    keys    .tl_set:N             = \l__codedesc_scheme_keys_tl ,
    keys    .default:n            = teal ,
    
    values  .usage:n              = general ,
    values  .tl_set:N             = \l__codedesc_scheme_values_tl ,
    values  .default:n            = green ,
      
    env     .usage:n              = general ,
    env     .tl_set:N             = \l__codedesc_scheme_env_tl ,
    env     .default:n            = green ,

    pack    .usage:n              = general ,
    pack    .tl_set:N             = \l__codedesc_scheme_pack_tl ,
    pack    .default:n            = green ,
    
    brightness  .usage:n          = general ,
    brightness  .tl_set:N         = \l__codedesc_scheme_bright_tl ,
    brightness  .default:n        = 1 ,
    
    default     .usage:n           = general ,
    default     .value_forbidden:n = true ,
    default     .meta:n            = 
      { error , verb , args , code , keys , values , env , pack , brightness } ,
    
    scheme  .usage:n              = general ,
    scheme  .choice: ,
    scheme / default
      .meta:n = default ,
  }


\cs_new_protected:Npn \__codedesc_set_color_scheme:n #1
  {
    \keys_set:nn { codedesc / color scheme } {#1}
    \__codedesc_set_colors:n \l__codedesc_scheme_bright_tl    
  }

\keys_set:nn { codedesc / color scheme } {default}
\__codedesc_set_brightness:n \l__codedesc_colors_bright_tl


    %%%%%%%
    %%% group/object formats
    %%%%%%%

\tl_new:N \l__codedesc_tmpfont_tl
\tl_new:N \l__codedesc_tmpfsize_tl
\tl_new:N \l__codedesc_tmpfmt_tl
\tl_new:N \l__codedesc_tmpshape_tl
\tl_new:N \l__codedesc_tmpcolor_tl
\tl_new:N \l__codedesc_tmplbracket_tl
\tl_new:N \l__codedesc_tmprbracket_tl
\tl_new:N \l__codedesc_tmpindxgrp_tl
\tl_new:N \l__codedesc_tmpindx_tl
\tl_new:N \l__codedesc_tmpshapepreadj_tl
\tl_new:N \l__codedesc_tmpshapeposadj_tl
\tl_new:N \l__codedesc_makefmt_tmp_tl

\keys_define:nn { codedesc / scratch_def }
{
  font            .usage:n            = general ,
  font            .value_required:n   = true ,
  font            .code:n             = 
    { \tl_set:Nn \l__codedesc_tmpfont_tl { font = #1 , } },
  
  fsize           .usage:n            = general ,
  fsize           .value_required:n   = true ,
  fsize           .code:n             = 
    { \tl_set:Nn \l__codedesc_tmpfsize_tl { fsize = #1 , } } ,

  meta            .usage:n            = general ,
  meta            .value_forbidden:n  = true ,
  meta            .code:n             =
    { \tl_set:Nn \l__codedesc_tmpfmt_tl {meta , } } ,
  
  xmeta           .usage:n            = general ,
  xmeta           .value_forbidden:n  = true ,
  xmeta           .code:n             =
    { \tl_set:Nn \l__codedesc_tmpfmt_tl {xmeta , } } ,
  
  code            .usage:n            = general ,
  code            .value_forbidden:n  = true ,
  code            .code:n             =
    { \tl_set:Nn \l__codedesc_tmpfmt_tl {code , } } ,
  
  verb            .usage:n            = general ,
  verb            .value_forbidden:n  = true ,
  verb            .code:n             =
    { \tl_set:Nn \l__codedesc_tmpfmt_tl {verb , } } ,
  
  xverb           .usage:n            = general ,
  xverb           .value_forbidden:n  = true ,
  xverb           .code:n             =
    { \tl_set:Nn \l__codedesc_tmpfmt_tl {xverb , } } ,
  
  nofmt           .usage:n            = general ,
  nofmt           .value_forbidden:n  = true ,
  nofmt           .code:n             = 
    {\tl_clear:N \l__codedesc_tmpfmt_tl } ,

  no~fmt          .usage:n            = general ,
  no~fmt          .value_forbidden:n  = true ,
  no~fmt          .code:n             = 
    {\tl_clear:N \l__codedesc_tmpfmt_tl } ,
    
  format          .usage:n            = general ,
  format          .value_required:n   = true ,
  format          .choice: , 
  format / meta 
    .code:n = { \tl_set:Nn \l__codedesc_tmpfmt_tl {meta , } } ,
  format / xmeta 
    .code:n = { \tl_set:Nn \l__codedesc_tmpfmt_tl {xmeta , } } ,
  format / code 
    .code:n = { \tl_set:Nn \l__codedesc_tmpfmt_tl {code , } } ,
  format / verb 
    .code:n = { \tl_set:Nn \l__codedesc_tmpfmt_tl {verb , } } ,
  format / xverb
    .code:n = { \tl_set:Nn \l__codedesc_tmpfmt_tl {xverb , } } ,
  format / nofmt
    .code:n = { \tl_clear:N \l__codedesc_tmpfmt_tl } ,
  format / no~fmt
    .code:n = { \tl_clear:N \l__codedesc_tmpfmt_tl } ,
  format / none
    .code:n = { \tl_clear:N \l__codedesc_tmpfmt_tl } ,
  format / unknown .code:n =
    {
     \msg_error:nneee { codedesc } {key choice} {format02}{\l_keys_value_tl}{meta,~xmeta,~code,~verb,~xverb,~nofmt,~none}
    },    

  slshape         .usage:n            = general ,
  slshape         .value_forbidden:n  = true ,
  slshape         .code:n             =
    { \tl_set:Nn \l__codedesc_tmpshape_tl { slshape , } } ,
  
  itshape         .usage:n            = general ,
  itshape         .value_forbidden:n  = true ,
  itshape         .code:n             =
    { \tl_set:Nn \l__codedesc_tmpshape_tl { itshape , } } ,
  
  noshape         .usage:n            = general ,
  noshape         .value_forbidden:n  = true ,
  noshape         .code:n             =
    { \tl_clear:N \l__codedesc_tmpshape_tl } ,

  shape           .usage:n            = general , 
  shape           .value_required:n   = true ,
  shape           .choice: , 
  shape / none    
    .code:n = { \tl_clear:N \l__codedesc_tmpshape_tl } ,
  shape / noshape
    .code:n = { \tl_clear:N \l__codedesc_tmpshape_tl } ,
  shape / italic
    .code:n = { \tl_set:Nn \l__codedesc_tmpshape_tl { itshape , } } ,
  shape / itshape
    .code:n = { \tl_set:Nn \l__codedesc_tmpshape_tl { itshape , } } ,
  shape / slanted
    .code:n = { \tl_set:Nn \l__codedesc_tmpshape_tl { slshape , } } ,
  shape / slshape
    .code:n = { \tl_set:Nn \l__codedesc_tmpshape_tl { slshape , } } ,
  shape / unknown .code:n =
    {
     \msg_error:nneee { codedesc } {key choice} {shape02}{\l_keys_value_tl}{italic,~itshape,~slanted,~slshape,~noshape,~none}
    },    
    
  shape~ preadj   .usage:n            = general , 
  shape~ preadj   .value_required:n   = true ,
  shape~ preadj   .choice: , 
  shape~ preadj / none  
    .code:n = { \tl_clear:N \l__codedesc_tmpshapepreadj_tl },
  shape~ preadj / very ~ thin 
    .code:n = { \tl_set:Nn  \l__codedesc_tmpshapepreadj_tl { shape~ preadj = very~ thin  , } },
  shape~ preadj / thin  
    .code:n = { \tl_set:Nn  \l__codedesc_tmpshapepreadj_tl { shape~ preadj = thin  , } },
  shape~ preadj / mid   
    .code:n = { \tl_set:Nn  \l__codedesc_tmpshapepreadj_tl { shape~ preadj = mid  , } },
    
  shape~ posadj   .usage:n            = general , 
  shape~ posadj   .value_required:n   = true ,
  shape~ posadj   .choice: , 
  shape~ posadj / none  
    .code:n = { \tl_clear:N \l__codedesc_tmpshapeposadj_tl },
  shape~ posadj / very ~ thin 
    .code:n = { \tl_set:Nn  \l__codedesc_tmpshapeposadj_tl { shape~ posadj = very~ thin  , } },
  shape~ posadj / thin  
    .code:n = { \tl_set:Nn  \l__codedesc_tmpshapeposadj_tl { shape~ posadj = thin  , } },
  shape~ posadj / mid   
    .code:n = { \tl_set:Nn  \l__codedesc_tmpshapeposadj_tl { shape~ posadj = mid  , } },

  color           .usage:n            = general ,
  color           .value_required:n   = true ,
  color           .code:n             = 
    { \tl_set:Nn \l__codedesc_tmpcolor_tl { color = #1  , } },
  
  lbracket        .usage:n            = general ,
  lbracket        .value_required:n   = true ,
  lbracket        .code:n             =  
    { \tl_set:Nn \l__codedesc_tmplbracket_tl { lbracket = #1  , } } ,

  rbracket        .usage:n            = general ,
  rbracket        .value_required:n   = true ,
  rbracket        .code:n             = 
    { \tl_set:Nn \l__codedesc_tmprbracket_tl { rbracket = #1  , } } ,

  index~ group    .usage:n            = general ,
  index~ group    .value_required:n   = true ,
  index~ group    .code:n             = 
    { \tl_set:Nn \l__codedesc_tmpindxgrp_tl { index~group = {#1}  , } } ,

  index           .usage:n            = general , 
  index           .value_forbidden:n  = true ,
  index           .code:n             =
    { \tl_set:Nn \l__codedesc_tmpindx_tl { index  , } } ,

  no~ index       .usage:n            = general , 
  no~ index       .value_forbidden:n  = true ,
  no~ index       .code:n             =
    { \tl_set:Nn \l__codedesc_tmpindx_tl { no~ index  , } } ,
  
	unknown   .code:n = 
    {
     \msg_error:nnxx { codedesc } {format-err} {format}{\l_keys_key_str}
    },    

}


\keys_define:nn { codedesc / grp_scratch }
  {
    unknown .code:n = {}
  }


\tl_new:N \l__codedesc_keyconstruct_tmpa_tl
\tl_new:N \l__codedesc_keyconstruct_tmpb_tl
\tl_new:N \g__codedesc_keyconstruct_tmpc_tl
\tl_const:Nn \c__codedesc_comma_tl { , }

\cs_new_protected:Npn \__codedesc_keys_construct:nn #1#2
  {
    \tl_put_right:Nn \l__codedesc_keyconstruct_tmpa_tl {#1 #2}
  }
\cs_generate_variant:Nn   \__codedesc_keys_construct:nn {eV}


\cs_new_protected:Npn \__codedesc_group_define:nn #1#2
  {
    \group_begin:           
      \keys_set:nn { codedesc / grp_scratch } {#1}
      \keys_set:nn { codedesc / scratch_def } {#2}
      
      \tl_set:Ne \l__codedesc_keyconstruct_tmpa_tl
        {
          \l__codedesc_tmpfmt_tl
          \l__codedesc_tmpshape_tl
          \l__codedesc_tmpcolor_tl
          \l__codedesc_tmplbracket_tl
          \l__codedesc_tmprbracket_tl      
          \l__codedesc_tmpshapepreadj_tl
          \l__codedesc_tmpshapeposadj_tl
          \l__codedesc_tmpindxgrp_tl
          \l__codedesc_tmpindx_tl
          \exp_not:o \l__codedesc_tmpfont_tl
          \exp_not:o \l__codedesc_tmpfsize_tl
        }

      \keys_precompile:nVN { codedesc / scratch_def }  
        \l__codedesc_keyconstruct_tmpa_tl
        \l__codedesc_keyconstruct_tmpb_tl

    %%%%%%%
    %%% \keys_define:nn is LOCAL !!!
    %%%%%%%      
      \tl_gset:NV \g__codedesc_keyconstruct_tmpc_tl \l__codedesc_keyconstruct_tmpb_tl
      
      \keys_set:nV { codedesc / make fmt } \l__codedesc_keyconstruct_tmpa_tl
      \cs_gset:cV {__codedesc_grpfmt_ #1:} \l__codedesc_makefmt_tmp_tl

    \group_end:
    \__codedesc_grp_scratch_def:nV {#1} \g__codedesc_keyconstruct_tmpc_tl
  }


\cs_new_protected:Npn \__codedesc_group_dup:nn #1#2
  {
    \group_begin:
      \keys_precompile:nnN { codedesc / grp_scratch } {#2}
        \l__codedesc_keyconstruct_tmpb_tl
      \tl_gset:NV \g__codedesc_keyconstruct_tmpc_tl \l__codedesc_keyconstruct_tmpb_tl
    \group_end:

    \__codedesc_grp_scratch_def:nV {#1} \g__codedesc_keyconstruct_tmpc_tl
  }


\cs_new_protected:Npn \__codedesc_grp_scratch_def:nn #1#2
  {
    \keys_define:nn { codedesc / grp_scratch } 
      { #1 .code:n = {#2} }    
  }
\cs_generate_variant:Nn \__codedesc_grp_scratch_def:nn {nV}

\cs_new_protected:Npn \__codedesc_object_define:nnn #1#2#3
  {
    \tl_if_blank:nTF {#3}
      {
        \keys_define:ne { codedesc / format } 
          { 
            #1 .code:n = 
              \exp_not:c { __codedesc_grpfmt_ #2 : } 
          }
      }
      {
        \__codedesc_group_define:nn { #1_objfmt } {#3}
        \keys_define:ne { codedesc / format } 
          { 
            #1 .code:n = 
              \exp_not:c { __codedesc_grpfmt_ #2 : } 
              \exp_not:c { __codedesc_grpfmt_ #1_objfmt : } 
          }
      }
  }



    %%%%%%%
    %%% group/object format effective commands
    %%%%%%%
    
\keys_define:nn { codedesc / make fmt }
{
  fsize .usage:n = general , 
  fsize .value_required:n = true ,
  fsize .code:n  = { 
    \tl_put_right:Nn \l__codedesc_makefmt_tmp_tl 
      {
        \cs_set_eq:NN \__codedesc_metasize_tl: #1
      }
   } ,

  font .usage:n = general , 
  font .value_required:n = true ,
  font .code:n  = { 
    \tl_put_right:Nn \l__codedesc_makefmt_tmp_tl 
      {
        \cs_set_eq:NN \__codedesc_metafont_tl: #1
      }
   } ,

  meta .usage:n = general , 
  meta .value_forbidden:n = true ,
  meta .code:n  = { 
    \tl_put_right:Nn \l__codedesc_makefmt_tmp_tl 
      {
        \cs_set_eq:NN \__codedesc_typeset:n  \__codedesc_meta:n 
        \cs_set_eq:NN \__codedesc_typeset:V  \__codedesc_meta:V 
      }
   } ,

  xmeta .usage:n = general , 
  xmeta .value_forbidden:n = true ,
  xmeta .code:n  = { 
    \tl_put_right:Nn \l__codedesc_makefmt_tmp_tl 
      {
        \cs_set_eq:NN \__codedesc_typeset:n  \__codedesc_meta*:n 
        \cs_set_eq:NN \__codedesc_typeset:V  \__codedesc_meta*:V
      }
   } ,

  verb .usage:n = general , 
  verb .value_forbidden:n = true ,
  verb .code:n  = { 
    \tl_put_right:Nn \l__codedesc_makefmt_tmp_tl 
      {
        \cs_set_eq:NN \__codedesc_typeset:n \tl_to_str:n
        \cs_set_eq:NN \__codedesc_typeset:V \tl_to_str:V
      }
   } ,
   
  xverb .usage:n = general , 
  xverb .value_forbidden:n = true ,
  xverb .code:n  = { 
    \tl_put_right:Nn \l__codedesc_makefmt_tmp_tl 
      {
        \cs_set_eq:NN \__codedesc_typeset:n \__codedesc_verb_nospc_typeset:n
        \cs_set_eq:NN \__codedesc_typeset:V \__codedesc_verb_nospc_typeset:V
      }
   } ,
   
  code .usage:n = general , 
  code .value_forbidden:n = true ,
  code .code:n  = { 
    \tl_put_right:Nn \l__codedesc_makefmt_tmp_tl 
      {
        \cs_set_eq:NN \__codedesc_typeset:n \__codedesc_macro_typeset:n
        \cs_set_eq:NN \__codedesc_typeset:V \__codedesc_macro_typeset:V
      }
   } ,
   
  slshape .usage:n = general , 
  slshape .value_forbidden:n = true ,
  slshape .code:n  = { 
     \tl_put_right:Nn \l__codedesc_makefmt_tmp_tl 
      {
       \cs_set_eq:NN \__codedesc_metashape: \slshape
      }
   } ,
   
  itshape .usage:n = general , 
  itshape .value_forbidden:n = true ,
  itshape .code:n  = { 
    \tl_put_right:Nn \l__codedesc_makefmt_tmp_tl 
      {
        \cs_set_eq:NN \__codedesc_metashape: \itshape
      }
   } , 
   
  shape~ preadj .usage:n = general , 
  shape~ preadj .value_required:n = true ,
  shape~ preadj .choices:nn = 
    { very~ thin , thin , mid }
    { 
      \str_case:enTF \l_keys_choice_str
        {
          {very~ thin}
            {
              \tl_put_right:Nn \l__codedesc_makefmt_tmp_tl 
              {
               \cs_set:Npn \__codedesc_shape_preadj: 
                 { \skip_horizontal:N \l__codecmm_verythin_skip } 
              }               
            }
          {thin}
            {
              \tl_put_right:Nn \l__codedesc_makefmt_tmp_tl 
              {
               \cs_set:Npn \__codedesc_shape_preadj: 
                 { \skip_horizontal:N \l__codecmm_thin_skip } 
              }               
            }
          {mid}
            {
              \tl_put_right:Nn \l__codedesc_makefmt_tmp_tl 
              {
               \cs_set:Npn \__codedesc_shape_preadj: 
                 { \skip_horizontal:N \l__codecmm_midthin_skip } 
              }               
            }
        }
        {}{}
    } , 

  shape~ posadj .usage:n = general , 
  shape~ posadj .value_required:n = true ,
  shape~ posadj .choices:nn = 
    { very~ thin , thin , mid }
    { 
      \str_case:enTF \l_keys_choice_str
        {
          {very ~ thin}
            {
              \tl_put_right:Nn \l__codedesc_makefmt_tmp_tl 
              {
               \cs_set:Npn \__codedesc_shape_posadj: 
                 { \skip_horizontal:N \l__codecmm_verythin_skip } 
              }               
            }
          {thin}
            {
              \tl_put_right:Nn \l__codedesc_makefmt_tmp_tl 
              {
               \cs_set:Npn \__codedesc_shape_posadj: 
                 { \skip_horizontal:N \l__codecmm_thin_skip } 
              }               
            }
          {mid}
            {
              \tl_put_right:Nn \l__codedesc_makefmt_tmp_tl 
              {
               \cs_set:Npn \__codedesc_shape_posadj: 
                 { \skip_horizontal:N \l__codecmm_midthin_skip } 
              }               
            }
        }
        {}{}
    } , 

  
  index .usage:n = general ,
  index .value_forbidden:n = true ,
  index .code:n = { 
    \tl_put_right:Nn \l__codedesc_makefmt_tmp_tl 
      {
        \bool_set_true:N \l__codedesc_index_bool
      }
  } ,

  no~ index .usage:n = general ,
  no~ index .value_forbidden:n = true ,
  no~ index .code:n = { 
    \tl_put_right:Nn \l__codedesc_makefmt_tmp_tl 
      {
        \bool_set_false:N \l__codedesc_index_bool
      }
  } ,

  index~ group .usage:n = general ,
  index~ group .value_required:n = true ,
  index~ group .code:n = { 
    \tl_if_empty:nTF { #1 }
      {
        \tl_put_right:Nn \l__codedesc_makefmt_tmp_tl 
          {
            \tl_clear:N \l__codedesc_indexgrp_tl
          }
      }
      {
        \tl_put_right:Nn \l__codedesc_makefmt_tmp_tl 
          {
            \tl_set:Nn \l__codedesc_indexgrp_tl { #1 ! } 
          }
      }
  } ,

  
  lbracket .usage:n = general ,
  lbracket .value_required:n = true ,
  lbracket .code:n = { 
    \tl_put_right:Nn \l__codedesc_makefmt_tmp_tl 
      {
        \tl_set:Nn \l__codedesc_Lbracket_tl { #1 } 
      }
  } ,

  rbracket .usage:n = general ,
  rbracket .value_required:n = true ,
  rbracket .code:n = { 
    \tl_put_right:Nn \l__codedesc_makefmt_tmp_tl 
      {
        \tl_set:Nn \l__codedesc_Rbracket_tl { #1 } 
      }
  } ,

  color .usage:n = general ,
  color .value_required:n = true ,
  color .code:n = {
    \tl_put_right:Nn \l__codedesc_makefmt_tmp_tl 
      {
        \cs_set:Npn \__codedesc_metacolor: { \__codecmm_color_select:n{#1} }
      }
  } ,
}

 

    %%%%%%%
    %%% group/object formats pre-set
    %%%%%%%

\__codedesc_group_define:nn     {meta}      {meta,color=c__codedesc_marg_color}
\__codedesc_object_define:nnn   {meta}      {meta}    {}
\__codedesc_object_define:nnn   {arg}       {meta}    {}
\__codedesc_object_define:nnn   {marg}      {meta}    {lbracket={\{},rbracket={\}}}

\__codedesc_group_define:nn     {verb}      {color=c__codedesc_verb_color}
\__codedesc_object_define:nnn   {verb}      {verb}    {verb}
\__codedesc_object_define:nnn   {xverb}     {verb}    {xverb}

\__codedesc_group_define:nn     {oarg}      {meta,color=c__codedesc_oarg_color}
\__codedesc_object_define:nnn   {oarg}      {oarg}    {lbracket={[},rbracket={]}}
\__codedesc_object_define:nnn   {parg}      {oarg}    {lbracket={(},rbracket={)}}
\__codedesc_object_define:nnn   {xarg}      {oarg}    {lbracket={<},rbracket={>}}

\__codedesc_group_define:nn     {code}      {code,color=c__codedesc_code_color}
\__codedesc_object_define:nnn   {code}      {code}    {}
\__codedesc_object_define:nnn   {macro}     {code}    {}
\__codedesc_object_define:nnn   {function}  {code}    {}

\__codedesc_group_define:nn     {syntax}    {color=c__codedesc_syntax_color}
\__codedesc_object_define:nnn   {syntax}    {syntax}  {}

%\__codedesc_group_define:nn {keyval} {slshape,color=c__codedesc_keyval_color}
%\__codedesc_object_define:nnn {keyval}{keyval}{}
%\__codedesc_object_define:nnn {key}{keyval}{}
%\__codedesc_object_define:nnn {keys}{keyval}{}
%\__codedesc_object_define:nnn {value}{keyval}{}
%\__codedesc_object_define:nnn {values}{keyval}{}

\__codedesc_group_define:nn     {keys}      {slshape,color=c__codedesc_keys_color}
\__codedesc_object_define:nnn   {keyval}    {keys}    {}
\__codedesc_object_define:nnn   {key}       {keys}    {}
\__codedesc_object_define:nnn   {keys}      {keys}    {}

\__codedesc_group_define:nn     {values}    {slshape,color=c__codedesc_values_color}
\__codedesc_object_define:nnn   {value}     {values}  {}
\__codedesc_object_define:nnn   {values}    {values}  {}

\__codedesc_group_define:nn     {option}    {color=c__codedesc_options_color}
\__codedesc_object_define:nnn   {option}    {option}  {}

\__codedesc_group_define:nn     {defaultval}{color=c__codedesc_defaultval_color}
\__codedesc_object_define:nnn   {defaultval}{defaultval}{}

\__codedesc_group_define:nn     {env}       {slshape,color=c__codedesc_env_color}
\__codedesc_object_define:nnn   {env}       {env}     {}

\__codedesc_group_define:nn     {pkg}       {slshape,color=c__codedesc_pkg_color}
\__codedesc_object_define:nnn   {pkg}       {pkg}     {}
\__codedesc_object_define:nnn   {pack}      {pkg}     {}

\bool_if:NTF \l__codedesc_indexdefault_bool
  {
    \__codedesc_group_define:nn {code}    {index,index~group=command(s)}
    \__codedesc_group_define:nn {keys}    {index,index~group=key(s)}
    \__codedesc_group_define:nn {option}  {index,index~group=option(s)}
    \__codedesc_group_define:nn {env}     {index,index~group=enviroment(s)}
  }
  {}

    %%%%%%%
    %%% codedescribe/tsobj common keys
    %%%%%%%

\keys_define:nn { codedesc / format }
{
  strut .usage:n = general,
  strut .code:n = 
    {
      \tl_set:Nn \l__codedesc_strut_tl { \strut }
    },  

    index .usage:n = general ,
    index .value_forbidden:n = true ,
    index .code:n = 
      { 
        \bool_set_true:N \l__codedesc_index_bool
      } ,
    
    no~ index .usage:n = general ,
    no~ index .value_forbidden:n = true ,
    no~ index .code:n = 
      { 
        \bool_set_false:N \l__codedesc_index_bool
      } ,
    
    index~ group .usage:n = general ,
    index~ group .value_required:n = true ,
    index~ group .code: n = 
      { 
        \tl_if_empty:nTF { #1 }
          {
            \tl_clear:N \l__codedesc_indexgrp_tl
          }
          {
            \tl_set:Nn \l__codedesc_indexgrp_tl { #1 ! } 
          }
      } ,
     
    index~ prefix .usage:n = general ,
    index~ prefix .value_required:n = true ,
    index~ prefix .tl_set:N = \l__codedesc_indexprefix_tl ,

  unknown.usage:n = general,
	unknown.code:n = 
    {
     \cs_set:Npn \__codedesc_metacolor: { \__codecmm_color_select:n{c__codedesc_none_color} }
     \msg_error:nnxx { codedesc } {object-err} {format}{\l_keys_key_str}
    },    
}

    %%%%%%%
    %%% codedescribe keys
    %%%%%%%

\keys_define:nn {}
  { codedesc / desc format .inherit:n = codedesc / format }
\keys_define:nn { codedesc / desc format }  
  {
    new.usage:n = general,
    new.code:n =
      {
        \bool_set_true:N \l__codedesc_descnotes_bool
        \bool_set_true:N \l__codedesc_descdate_new_bool 
        \seq_put_right:Nn \l__codedesc_descdate_new_seq {#1}
        \seq_put_right:Nn \l__codedesc_newdescnotes_seq {\l__codedesc_new_label_tl :~ #1}
      },
      
    update.usage:n = general,
    update.code:n =
      {
        \bool_set_true:N \l__codedesc_descnotes_bool
        \bool_set_true:N \l__codedesc_descdate_update_bool 
        \seq_put_right:Nn \l__codedesc_descdate_update_seq {#1}
        \seq_put_right:Nn \l__codedesc_newdescnotes_seq {\l__codedesc_update_label_tl :~ #1}
      },
      
    note.usage:n = general,
    note.code:n =
      {
        \bool_set_true:N \l__codedesc_descnotes_bool
        \bool_set_true:N \l__codedesc_sidenote_bool 
        \seq_put_right:Nn \l__codedesc_sidenote_seq {#1}
        \seq_put_right:Nn \l__codedesc_newdescnotes_seq {\l__codedesc_note_label_tl :~ #1}
      },
  
    rulecolor.usage:n = general,
    rulecolor.code:n = 
      {
        \cs_set:Npn \__codedesc_rulecolor: { \__codecmm_color_select:n{#1} }
      },

    EXP.usage:n = general,
    EXP.code:n = 
      {
        \tl_set:Nn \l__codedesc_exp_tl { ~\hfill{\__codedesc_note_fmt:\ding{72}} }
      },

    rEXP.usage:n = general,
    rEXP.code:n = 
      {
        \tl_set:Nn \l__codedesc_exp_tl { ~\hfill{\__codedesc_note_fmt:\ding{73}} }
      },

    force~ margin .usage:n = general ,
    force~ margin .code:n  =
      {
        \bool_set_false:N \l__codedesc_normal_margin_bool
      } ,
      
    unknown.usage:n = general,
  	unknown.code:n = 
      {
       \cs_set:Npn \__codedesc_metacolor: { \__codecmm_color_select:n{c__codedesc_none_color} }
       \msg_error:nnxx { codedesc } {object-err} {desc ~ format}{\l_keys_key_str}
      },    
  }


    %%%%%%%
    %%% tsobj and friends keys
    %%%%%%%

\keys_define:nn {}
  { codedesc / list format .inherit:n = codedesc / format }
\keys_define:nn { codedesc / list format }  
  {
    
    mid~ sep.usage:n = general,
    mid~ sep.code:n = 
      {
        \tl_set:Nn \l__codedesc_sep_tl { ~ #1 ~ }
      },

    sep.usage:n = general,
    sep.code:n = 
      {
        \tl_set:Nn \l__codedesc_lastsep_tl { ~ #1 ~ }
      },

    or.usage:n = general,
    or.code:n = 
      {
        \tl_set:Nn \l__codedesc_lastsep_tl { ~ \l__codedesc_or_label_tl{} ~ }
      },

    comma.usage:n = general,
    comma.code:n = 
      {
        \tl_set:Nn \l__codedesc_lastsep_tl { , ~ }
      },

    meta~ or .usage:n = general,
    meta~ or .code:n =
      {
        \tl_set:Nn \l__codedesc_sep_tl { \ensuremath| }
        \tl_set:Nn \l__codedesc_lastsep_tl { \ensuremath| }
        \tl_set:Nn \l__codedesc_Lbrace_tl {\ensuremath\langle}
        \tl_set:Nn \l__codedesc_Rbrace_tl {\ensuremath\rangle}
      },
      
    bnf~ or .usage:n = general,
    bnf~ or .code:n =
      {
        \tl_set:Nn \l__codedesc_sep_tl { \ensuremath| }
        \tl_set:Nn \l__codedesc_lastsep_tl { \ensuremath| }
        \tl_set:Nn \l__codedesc_Lbrace_tl {[}
        \tl_set:Nn \l__codedesc_Rbrace_tl {]}
      },
  
    par~ or .usage:n = general,
    par~ or .code:n =
      {
        \tl_set:Nn \l__codedesc_sep_tl { \ensuremath| }
        \tl_set:Nn \l__codedesc_lastsep_tl { \ensuremath| }
        \tl_set:Nn \l__codedesc_Lbrace_tl {(}
        \tl_set:Nn \l__codedesc_Rbrace_tl {)}
      },
  
    unknown.usage:n = general,
  	unknown.code:n = 
      {
       \cs_set:Npn \__codedesc_metacolor: { \__codecmm_color_select:n{c__codedesc_none_color} }
       \msg_error:nnxx { codedesc } {object-err} {list ~ format}{\l_keys_key_str}
      },    
  }

    %%%%%%%
    %%% variables/commands initializing
    %%%%%%%

\cs_new_protected:Npn \__codedesc_metafmt_clear:
  {
    \cs_set_eq:NN    \__codedesc_metasize_tl: \small
    \cs_set_eq:NN    \__codedesc_metafont_tl: \ttfamily

    \cs_set_eq:NN \__codedesc_metashape: \relax
    \cs_set_eq:NN \__codedesc_metacolor: \relax
    
    \cs_set_eq:NN \__codedesc_shape_preadj: \relax
    \cs_set_eq:NN \__codedesc_shape_posadj: \relax

    \cs_set:Npn \__codedesc_rulecolor: { \__codedesc_metacolor: }
    \cs_set_eq:NN \__codedesc_typeset:n \relax
    \cs_set_eq:NN \__codedesc_typeset:V \relax
    
    \tl_clear:N \l__codedesc_Lbracket_tl
    \tl_clear:N \l__codedesc_Rbracket_tl
    \tl_set:Nn \l__codedesc_sep_tl {,~}
    \tl_set:Nn \l__codedesc_lastsep_tl {~ \l__codedesc_and_label_tl{} ~}
    \tl_clear:N \l__codedesc_exp_tl 
    \tl_clear:N \l__codedesc_Lbrace_tl
    \tl_clear:N \l__codedesc_Rbrace_tl
    \tl_clear:N \l__codedesc_strut_tl
    
    \bool_set_false:N \l__codedesc_descnotes_bool
    \bool_set_false:N \l__codedesc_descdate_new_bool 
    \bool_set_false:N \l__codedesc_descdate_update_bool 
    \bool_set_false:N \l__codedesc_sidenote_bool 
    
    \bool_set_false:N \l__codedesc_index_bool
    \tl_clear:N \l__codedesc_indexgrp_tl
    \tl_clear:N \l__codedesc_indexprefix_tl
  }
  
\__codedesc_metafmt_clear:


\cs_new_protected:Npn \__codedesc_metafmt:n #1
  {
    \__codedesc_metafmt_set:n {#1}
    \__codedesc_metafmt:
  }
\cs_generate_variant:Nn \__codedesc_metafmt:n {V}
  
\cs_new_protected:Npn \__codedesc_metafmt: 
  {
    \__codedesc_metasize_tl:
    \__codedesc_metafont_tl:
    \__codedesc_metashape:
    \__codedesc_metacolor: {}
  }


\tl_new:N \l__codedesc_metafmt_tmp_tl

\cs_new_protected:Npn \__codedesc_metafmt_get:nnN #1#2#3
  { 
    \keys_precompile:nnN {codedesc / #1}{#2} #3
    \cs_set:Npe  \__codedesc_metafmt: 
      { 
        \exp_not:o \__codedesc_metasize_tl: 
        \exp_not:o \__codedesc_metafont_tl:
        \exp_not:o \__codedesc_metashape:
        \exp_not:o \__codedesc_metacolor: {}
      }        
  }
  
\cs_new_protected:Npn \__codedesc_metafmt_get:nN #1#2
  { 
    \keys_precompile:nnN {codedesc / format}{#1} #2
    \cs_set:Npe  \__codedesc_metafmt: 
      { 
        \exp_not:o \__codedesc_metasize_tl: 
        \exp_not:o \__codedesc_metafont_tl:
        \exp_not:o \__codedesc_metashape:
        \exp_not:o \__codedesc_metacolor: {}
      }        
  }
\cs_generate_variant:Nn \__codedesc_metafmt_get:nN {V}


\cs_new_protected:Npn \__codedesc_metafmt_set:nn #1#2
  { 
    \keys_set:nn {codedesc / #1}{#2} 

    \cs_set:Npe  \__codedesc_metafmt: 
      { 
        \exp_not:o \__codedesc_metasize_tl: 
        \exp_not:o \__codedesc_metafont_tl:
        \exp_not:o \__codedesc_metashape:
        \exp_not:o \__codedesc_metacolor: {}
      }
  }

\cs_new_protected:Npn \__codedesc_metafmt_set:n #1
  { 
    \keys_set:nn {codedesc / format}{#1} 

    \cs_set:Npe  \__codedesc_metafmt: 
      { 
        \exp_not:o \__codedesc_metasize_tl: 
        \exp_not:o \__codedesc_metafont_tl:
        \exp_not:o \__codedesc_metashape:
        \exp_not:o \__codedesc_metacolor: {}
      }
  }
\cs_generate_variant:Nn \__codedesc_metafmt_set:n {V}


    %%%%%%%
    %%% < meta >
    %%%%%%%  
\cs_new_protected:Npn \__codedesc_meta:n #1
  {
%    \ensuremath\langle #1 \ensuremath\rangle
    \mode_if_math:TF 
      {   \langle     #1     \rangle   } %% We shouldn't be here, but...
      { $ \langle $   #1   $ \rangle $ }
  }  
\cs_generate_variant:Nn \__codedesc_meta:n {V}  

    %%%%%%%
    %%% < meta > 'detokenized'
    %%%%%%%
\cs_new_protected:Npn \__codedesc_meta*:n #1
  {
%    \ensuremath\langle \tl_to_str:n {#1} \ensuremath\rangle
    \mode_if_math:TF 
      {   \langle     \tl_to_str:n {#1}     \rangle   } %% We shouldn't be here, but...
      { $ \langle $   \tl_to_str:n {#1}   $ \rangle $ }
  }  
\cs_generate_variant:cn {__codedesc_meta*:n} {V}  

    %%%%%%%
    %%% code 'detokenized'
    %%%%%%%

\regex_const:Nn \c__codedesc_tf_regex {TF$}

\cs_new_protected:Npn \__codedesc_macro_typeset:n #1
  {
    \str_set:Nn \l__codedesc_tmpb_tl {#1}
    \str_remove_all:Nn \l__codedesc_tmpb_tl {~}
    \regex_replace_once:NnNTF \c__codedesc_tf_regex {}\l__codedesc_tmpb_tl
      {
        \l__codedesc_tmpb_tl\textsl{\underline{TF}}
      }
      { \l__codedesc_tmpb_tl }  
  }
\cs_generate_variant:Nn \__codedesc_macro_typeset:n {V}

    %%%%%%%
    %%% just 'detokenized'
    %%%%%%%

\cs_new_protected:Npn \__codedesc_verb_nospc_typeset:n #1
  {
    \str_set:Nn \l__codedesc_tmpb_tl {#1}
    \str_remove_all:Nn \l__codedesc_tmpb_tl {~}
    \l__codedesc_tmpb_tl
  }
\cs_generate_variant:Nn \__codedesc_verb_nospc_typeset:n {V}

    %%%%%%%
    %%% processing as a list
    %%%%%%%

\cs_new_protected:Npn \__codedesc_list_typeset:nnn #1#2#3
  {
    \seq_set_from_clist:Nn \l__codedesc_tmpa_seq {#1}
        
    \l__codedesc_strut_tl
    \l__codedesc_Lbrace_tl 
    
    \seq_pop_left:NNTF \l__codedesc_tmpa_seq \l__codedesc_tmpa_tl
      {
        {
          \__codedesc_metafmt:
          \__codedesc_shape_preadj:
          \__codedesc_typeset:V \l__codedesc_tmpa_tl
          \__codedesc_shape_posadj:
        }
        \seq_pop_right:NNTF \l__codedesc_tmpa_seq \l__codedesc_tmpb_tl   % last one, if any
          {
            \seq_map_inline:Nn \l__codedesc_tmpa_seq
              {
                #2 
                {
                  \__codedesc_metafmt:
                  \__codedesc_shape_preadj:
                  \__codedesc_typeset:n {##1}
                  \__codedesc_shape_posadj:
                } 
              }
            #3 
            {
              \__codedesc_metafmt:
              \__codedesc_shape_preadj:
              \__codedesc_typeset:V \l__codedesc_tmpb_tl
              \__codedesc_shape_posadj:
            } 
          }
          {} %% there was only one
      }
      {}  %% none there

      \l__codedesc_Rbrace_tl
  }
\cs_generate_variant:Nn \__codedesc_list_typeset:nnn {nVV}


\cs_new_protected:Npn \__codedesc_args_typeset:nnnn #1#2#3#4
  {
    \group_begin:
      \seq_set_from_clist:Nn \l__codedesc_tmpa_seq {#3}
      \__codedesc_metafmt_set:n {#1} 
      \l__codedesc_strut_tl
      \__codedesc_metafmt:
      \seq_map_inline:Nn \l__codedesc_tmpa_seq 
        {~\!\!#2 \__codedesc_meta:n {##1} #4 }                                  
    \group_end:    
  }


    %%%%%%%
    %%%  Variables used in the codedescibe environment
    %%%%%%%
  
\bool_new:N   \l__codedesc_longblock_bool

\coffin_new:N \l__codedesc_margin_coffin
\coffin_new:N \l__codedesc_text_coffin
\coffin_new:N \l__codedesc_syntax_coffin
\bool_new:N   \g__codedesc_syntax_bool
\dim_new:N    \l__codedesc_syntax_wd_dim
\dim_new:N    \l__codedesc_margin_wd_dim
  
\seq_new:N    \l__codedesc_descdate_new_seq 
\seq_new:N    \l__codedesc_descdate_update_seq
\seq_new:N    \l__codedesc_sidenote_seq
\seq_new:N    \l__codedesc_newdescnotes_seq


\coffin_new:N \l__codedesc_describe_coffin
\dim_new:N    \l__codedesc_describelabel_wd_dim
\dim_new:N    \l__codedesc_describelist_wd_dim
\tl_new:N     \l__codedesc_ragged_tl

\dim_new:N    \__codedesc_paradvance_dim  

\dim_new:N    \l__codedesc_tmpa_dim
\dim_new:N    \l__codedesc_tmpb_dim
  
\bool_new:N       \l__codedesc_codedescribe_activ_bool
\bool_set_false:N \l__codedesc_codedescribe_activ_bool
\bool_new:N       \l__codedesc_codesyntax_activ_bool
\bool_set_false:N \l__codedesc_codesyntax_activ_bool

  
    %%%%%%%
    %%%  User/Document level commands/environments
    %%%%%%%


\NewDocumentCommand \setcolorscheme {m}
  { \__codedesc_set_color_scheme:n {#1} }

\NewDocumentCommand \newcolorscheme {mm}
  { 
    \keys_precompile:nnN { codedesc / color scheme } {#2}
      \l__codedesc_scheme_tmp_tl
    \keys_define:ne { codedesc / color scheme }
      {
        scheme / #1
          .code:n = { \exp_not:V \l__codedesc_scheme_tmp_tl }
      }
  }

\NewDocumentCommand \defgroupfmt {mm}
  {
    \__codedesc_group_define:nn {#1} {#2}
  }

\NewDocumentCommand \dupgroupfmt {mm}
  {
    \__codedesc_group_dup:nn {#1} {#2}
  }

\NewDocumentCommand \defobjectfmt {mmm}
  {
    \__codedesc_object_define:nnn {#1} {#2} {#3}
  }

\regex_const:Nn \c__codedescribe_slash_regex {^\\}
\regex_const:Nn \c__codedescribe_ast_regex {\*}


\cs_new_protected:Npn \__codedescribe_index:n #1
  {
    \str_set:Nn \l__codedesc_tmpa_tl {#1}
    \regex_replace_all:NnN \c__codedescribe_ast_regex {} \l__codedesc_tmpa_tl
    \tl_set_eq:NN \l__codedesc_tmpb_tl \l__codedesc_tmpa_tl

    \tl_set_eq:NN \l__codedesc_tmpc_tl \l__codedesc_indexprefix_tl

    \regex_replace_once:NnNTF \c__codedescribe_slash_regex {} \l__codedesc_tmpa_tl
      { 
        \regex_replace_once:NnN \c__codedescribe_slash_regex {\\string\\} \l__codedesc_tmpb_tl  
      }
      { }

    \index{\l__codedesc_indexprefix_tl \l__codedesc_tmpa_tl @ \l__codedesc_indexgrp_tl \l__codedesc_tmpb_tl}
  }


\NewDocumentEnvironment {codedescribe}{O{code}m}
  {
    \mode_if_horizontal:TF 
      {\unskip\skip_vertical:n{\l__codecmm_mid_skip}}
      {\skip_vertical:n{\l__codecmm_mid_skip}}
    
    \bool_if:NTF \l__codedesc_codedescribe_activ_bool
      {
        \msg_warning:nnnxx {codedesc} {nested-env}
          {syntax:01}{codedescribe~ env}{codedescribe~ env}      
      }
      {
        \bool_set_true:N \l__codedesc_codedescribe_activ_bool
      }
      
    
    \seq_set_from_clist:Nn \l__codedesc_tmpa_seq {#2}
   
    
    \__codecmm_set_textcolwidth: 
    \hcoffin_set:Nn \l__codedesc_margin_coffin 
      {
        \__codedesc_metafmt_set:nn {desc format}{#1}
        \__codedesc_metafmt:

        %% ARGH !
        %% making a global copy of it (not reentrant friendly)
        %% codedescribe shouldn't be nested... but...
        %%
        \bool_gset_eq:NN \g__codedesc_normal_margin_bool \l__codedesc_normal_margin_bool

       
        \begin{tabular}{@{} l @{} }
          \__codecmm_hline:nnnn {\__codedesc_rulecolor:}{0.5ex}{2}{0.25ex}
          
          \bool_if:NTF \l__codedesc_index_bool
            {
              \seq_map_inline:Nn \l__codedesc_tmpa_seq
                { 
                  \__codedescribe_index:n {##1} 
                   \__codedesc_typeset:n {##1} \l__codedesc_exp_tl \\ 
                }
            }
            {
              \seq_map_inline:Nn \l__codedesc_tmpa_seq 
                { \__codedesc_typeset:n {##1} \l__codedesc_exp_tl \\ } 
            }            
            
          \bool_if:NTF \l__codedesc_descnotes_bool
            {
              \\[-2.5ex]
              \__codecmm_hline:nnnn {\__codecmm_color_select:n{black}}{0.5ex}{0.25}{0.25ex} 
                                                                     
              \bool_if:NTF \l__codedesc_descnotes_inseq_bool
                {
                  \seq_map_inline:Nn \l__codedesc_newdescnotes_seq
                    {\__codedesc_note_fmt:\__codecmm_color_select:n{black} ##1\\[-1ex]}
                }
                {
                  \bool_if:NT \l__codedesc_descdate_new_bool
                    {
                      \seq_map_inline:Nn \l__codedesc_descdate_new_seq
                        {\__codedesc_note_fmt:\__codecmm_color_select:n{black} \l__codedesc_new_label_tl :~ ##1\\[-1ex]}
                    }
                  \bool_if:NT \l__codedesc_descdate_update_bool
                    {
                      \seq_map_inline:Nn \l__codedesc_descdate_update_seq
                        {\__codedesc_note_fmt:\__codecmm_color_select:n{black} \l__codedesc_update_label_tl :~ ##1\\[-1ex]}
                    }
                  \bool_if:NT \l__codedesc_sidenote_bool
                    {
                      \seq_map_inline:Nn \l__codedesc_sidenote_seq
                        {\__codedesc_note_fmt:\__codecmm_color_select:n{black} \l__codedesc_note_label_tl :~ ##1\\[-1ex]}
                    }
                }
              \\[-1.5ex]
            }
            {
              \\[-2.5ex]
            }
          \__codecmm_hline:nnnn {\__codedesc_rulecolor:}{-0.25ex}{2}{1ex}
        \end{tabular}
      }
    \dim_set:Nn \l__codedesc_margin_wd_dim {\coffin_wd:N \l__codedesc_margin_coffin}
%    \coffin_mark_handle:Nnnn  \l__codedesc_margin_coffin {r}{T}{blue}
%    \coffin_mark_handle:Nnnn  \l__codedesc_margin_coffin {r}{B}{green}
%    \coffin_mark_handle:Nnnn  \l__codedesc_margin_coffin {r}{t}{red}

    \dim_compare:nNnTF \l__codedesc_margin_wd_dim > \marginparwidth
      {
        \bool_if:NTF \g__codedesc_normal_margin_bool
          {
            \bool_set_true:N \l__codedesc_longblock_bool
            \dim_set:Nn \l__codedesc_syntax_wd_dim {\l__codecmm_textcolwidth_dim - (\l__codedesc_margin_wd_dim - \marginparwidth) }
          }
          { %% well, user's choice...
            \bool_set_false:N \l__codedesc_longblock_bool
            \dim_set:Nn \l__codedesc_syntax_wd_dim {\l__codecmm_textcolwidth_dim}        
          }
      }
      {
        \bool_set_false:N \l__codedesc_longblock_bool
        \dim_set:Nn \l__codedesc_syntax_wd_dim {\l__codecmm_textcolwidth_dim}        
      }

    \bool_gset_false:N \g__codedesc_syntax_bool
    \vcoffin_set:Nnw \l__codedesc_text_coffin {\l__codecmm_textcolwidth_dim}
    
    \setlength\parindent{0pt}
  }
  {
    \vcoffin_set_end:
    \bool_if:NF \g__codedesc_syntax_bool
      {
        \vcoffin_gset:Nnn \l__codedesc_syntax_coffin {\l__codedesc_syntax_wd_dim}
          {
            \begin{tabular} { @{} l @{} }
              \__codecmm_hline:nnnn {\__codecmm_color_select:n{white}}{0.5ex}{2}{-1.5ex}
              \__codedesc_metacolor:
              \begin{minipage}[t]{\l__codedesc_syntax_wd_dim}
                \obeylines\obeyspaces\setlength\parindent{-2em}
              \end{minipage}\\[-2.5ex]
                  \\                                
                  \__codecmm_hline:nnnn {\__codecmm_color_select:n{white}}{0ex}{2}{1ex}      
            \end{tabular}
          }
      }

%    \coffin_mark_handle:Nnnn  \l__codedesc_syntax_coffin {l}{T}{blue}
%    \coffin_mark_handle:Nnnn  \l__codedesc_syntax_coffin {l}{B}{green}
%    \coffin_mark_handle:Nnnn  \l__codedesc_syntax_coffin {l}{t}{red}

    \bool_if:NTF \l__codedesc_longblock_bool
      { % __describeblock starting at marginpar
        \dim_compare:nNnTF { \marginparwidth + \marginparsep - \l__codedesc_margin_wd_dim } < { \l__codecmm_marginminsep_dim }
          {
            \coffin_join:NnnNnnnn 
              \l__codedesc_syntax_coffin {l}{t} 
              \l__codedesc_margin_coffin {r}{t} 
              {-\marginparsep}{0pt}
            \coffin_join:NnnNnnnn 
              \l__codedesc_syntax_coffin {l}{b} 
              \l__codedesc_text_coffin   {l}{t} 
              {\marginparwidth+\marginparsep}{\l__codecmm_baselineskip_dim}
          }
          {
            \dim_set:Nn \l__codedesc_tmpa_dim {\coffin_ht_plus_dp:N \l__codedesc_syntax_coffin}
            \coffin_join:NnnNnnnn 
              \l__codedesc_syntax_coffin {l}{t} 
              \l__codedesc_margin_coffin {r}{t} 
              {-\marginparsep + \l__codedesc_margin_wd_dim - \marginparwidth}{0pt}
            \dim_set:Nn \l__codedesc_tmpb_dim {\coffin_ht_plus_dp:N \l__codedesc_syntax_coffin}
            \coffin_join:NnnNnnnn 
              \l__codedesc_syntax_coffin {l}{b} 
              \l__codedesc_text_coffin   {l}{t} 
              {\marginparwidth+\marginparsep}{\l__codecmm_baselineskip_dim  + \l__codedesc_tmpb_dim - \l__codedesc_tmpa_dim}
          }
        \par\noindent        
%\coffin_mark_handle:Nnnn  \l__codedesc_syntax_coffin {r}{T}{blue}
        \coffin_typeset:Nnnnn \l__codedesc_syntax_coffin {l}{t} {-\marginparwidth-\marginparsep}{0pt}              
      }
      { % __describeblock at marginpar
        \bool_if:NTF \g__codedesc_syntax_bool
          {
            \coffin_join:NnnNnnnn 
              \l__codedesc_syntax_coffin {l}{b} 
              \l__codedesc_text_coffin   {l}{t} 
              {0pt}{\l__codecmm_baselineskip_dim}
          }
          {
            \coffin_join:NnnNnnnn 
              \l__codedesc_syntax_coffin {l}{B} 
              \l__codedesc_text_coffin   {l}{T} 
              {0pt}{0pt}
          }
        \coffin_attach:NnnNnnnn 
          \l__codedesc_syntax_coffin {l}{t} 
          \l__codedesc_margin_coffin {r}{t} 
          {-\marginparsep}{0pt}
%\coffin_mark_handle:Nnnn  \l__codedesc_syntax_coffin {r}{T}{red}
        \par\noindent
        \coffin_typeset:Nnnnn \l__codedesc_syntax_coffin {l}{t} {0pt}{0pt}      
      }
      
    \skip_vertical:n{\l__codecmm_large_skip}\par
  }
  
 
  
\NewDocumentEnvironment{codesyntax}{O{syntax}}
  {
    \bool_if:NTF \l__codedesc_codedescribe_activ_bool
      {
        \bool_if:NT \g__codedesc_syntax_bool
          {
            \msg_warning:nnn {codedesc} {syntax dup}
                  {syntax:02}
          }
      }
      {
        \msg_warning:nnnxx {codedesc} {out of scope}
              {syntax:03}{codesyntax~ env}{codedescribe~ env}
      }
      
    \bool_set_true:N \l__codedesc_codesyntax_activ_bool
    
    \vcoffin_gset:Nnw \l__codedesc_syntax_coffin {\l__codedesc_syntax_wd_dim}
    \__codedesc_metafmt:n {#1}
    \hspace*{2em}     %% !!! together with \parindent{-2em}
    \begin{tabular} { @{} l @{} }
      \__codecmm_hline:nnnn {\__codecmm_color_select:n{white}}{0.5ex}{2}{-1.5ex}
      \__codedesc_metacolor:
      \begin{minipage}[t]{\l__codedesc_syntax_wd_dim}
        \obeylines\obeyspaces\setlength\parindent{-2em}
  }
  {
      \end{minipage}\\[-2.5ex]
          \\                                
          \__codecmm_hline:nnnn {\__codecmm_color_select:n{white}}{0ex}{2}{1ex}      
    \end{tabular}
    \vcoffin_gset_end:
    \bool_gset_true:N \g__codedesc_syntax_bool

    \bool_set_false:N \l__codedesc_codesyntax_activ_bool    
  }


    %%%%%%%
    %%%  Variables used in the describelist/tsremark environments
    %%%%%%%

\coffin_new:N     \l__codedesc_tsremark_coffin

\bool_new:N       \l__codedesc_tsremark_peek_bool
\bool_set_false:N \l__codedesc_tsremark_peek_bool

\bool_new:N       \l__codedesc_describe_peek_bool
\bool_set_false:N \l__codedesc_describe_peek_bool

\regex_const:Nn \c__codedesc_describe_regex { \c{describe} }
\regex_const:Nn \c__codedesc_remark_regex   { \c{begin} \cB{tsremark} }


\tl_new:N \l__codedesc_metafmt_describe_set_tl
  
\NewDocumentEnvironment{describelist}{O{20mm}m}
  {
     \skip_vertical:n{\l__codecmm_neg_skip}
  
    \__codecmm_set_textcolwidth: 
    \dim_set:Nn \l__codedesc_describelabel_wd_dim {#1}
    \dim_set:Nn \l__codedesc_describelist_wd_dim {\l__codecmm_textcolwidth_dim}
    \cs_set_eq:NN \__codedesc_join:NnnNnnnn \coffin_attach:NnnNnnnn
    \tl_set:Nn \l__codedesc_ragged_tl {\raggedleft}

    \__codedesc_metafmt_get:nN {#2} \l__codedesc_metafmt_describe_set_tl
    
    \cs_set_eq:NN \describe \__codedesc_describe:nn
  }
  {
  }
  
\NewDocumentEnvironment{describelist*}{O{20mm}m}
  {
    \mode_if_horizontal:TF 
      {\skip_vertical:n{\l__codecmm_neg_skip}}
      {\skip_vertical:n{\l__codecmm_null_skip}}        

    \__codecmm_set_textcolwidth: 
    \dim_set:Nn \l__codedesc_describelabel_wd_dim {#1}
    \dim_set:Nn \l__codedesc_describelist_wd_dim {\l__codecmm_textcolwidth_dim - \l__codedesc_describelabel_wd_dim -\marginparsep}
    \cs_set_eq:NN \__codedesc_join:NnnNnnnn \coffin_join:NnnNnnnn
    \tl_clear:N \l__codedesc_ragged_tl

    \__codedesc_metafmt_get:nN {#2} \l__codedesc_metafmt_describe_set_tl
    
    \cs_set_eq:NN \describe \__codedesc_describe:nn
  }
  {
  }


\cs_new_protected:Npn \__codedesc_describe:nn #1#2
  {    
    \hcoffin_set:Nn \l__codedesc_tmpb_coffin 
      { 
        \l__codedesc_metafmt_describe_set_tl
        \bool_if:NTF \l__codedesc_index_bool
          { \__codedescribe_index:n {#1} }
          {}
        \__codedesc_metafmt: %V \l__codedesc_listkind_tl 
        \l__codedesc_ragged_tl 
        \__codedesc_typeset:n {#1}
      }      
    \dim_compare:nNnTF {\coffin_wd:N \l__codedesc_tmpb_coffin} > {\l__codedesc_describelabel_wd_dim}
      {
        \vcoffin_set:Nnn \l__codedesc_tmpa_coffin 
          { \l__codedesc_describelabel_wd_dim } 
          {  ~\ ~ }
        \coffin_attach:NnnNnnnn
          \l__codedesc_tmpa_coffin {r}{t}
          \l__codedesc_tmpb_coffin {r}{t}
          {0pt}{0pt}   
      }
      {
        \vcoffin_set:Nnn \l__codedesc_tmpa_coffin 
          { \l__codedesc_describelabel_wd_dim } 
          { 
            \l__codedesc_metafmt_describe_set_tl
            \bool_if:NTF \l__codedesc_index_bool
              { \__codedescribe_index:n {#1} }
              {}
            \__codedesc_metafmt: %V \l__codedesc_listkind_tl
            \noindent\l__codedesc_ragged_tl \__codedesc_typeset:n {#1}
          }          
      }
    
    \vcoffin_set:Nnn \l__codedesc_tmpb_coffin 
      { \l__codedesc_describelist_wd_dim } 
      { \noindent  #2 \skip_vertical:N \l__codecmm_coffinskip_dim }   
      
    \__codedesc_join:NnnNnnnn 
      \l__codedesc_tmpb_coffin {l}{T} 
      \l__codedesc_tmpa_coffin {r}{B} 
      {-\marginparsep}{0pt}

    \bool_if:NTF \l__codedesc_describe_peek_bool
      { \par }
      {
        \mode_if_horizontal:T { \unskip\par}
        \skip_vertical:N \l__codecmm_small_skip
      }
     
    \noindent
    \coffin_typeset:Nnnnn 
      \l__codedesc_tmpb_coffin {l}{t} {0pt}{-1.5pt}
    
    \xpeekahead_cmd_peek:NTF
      \c__codedesc_describe_regex
      { 
        \bool_set_true:N  \l__codedesc_describe_peek_bool 
      }
      { 
        \bool_set_false:N \l__codedesc_describe_peek_bool 
        \par
        \skip_vertical:N \l__codecmm_mid_skip
      }
  }

  
\NewDocumentCommand \tsmeta {m} 
  {
    \__codedesc_meta:n {#1}
  }

\cs_new_eq:NN \typesetmeta  \tsmeta 


\NewDocumentCommand \tsargs {O{meta}m}
  { 
    \__codedesc_args_typeset:nnnn {#1} {\l__codedesc_Lbracket_tl} {#2} {\l__codedesc_Rbracket_tl}
  }
  
\cs_new_eq:NN \typesetargs  \tsargs 


\NewDocumentCommand \tsmacro {O{code}mO{}m} 
  {
    \group_begin:
      \__codedesc_metafmt_set:n {#1} 
      \__codedesc_list_typeset:nnn{#2}{,~}{,~}
      \,\__codedesc_args_typeset:nnnn {oarg} [ {#3} ]
      \__codedesc_args_typeset:nnnn {marg} \{ {#4} \}
    \group_end:
  }
\cs_new_eq:NN \typesetmacro \tsmacro 


\NewDocumentCommand \tsverb {O{code}m} 
  {
    \group_begin:
      \__codedesc_metafmt_set:n {#1} 
      \l__codedesc_strut_tl
      \__codedesc_metafmt:      
      \tl_to_str:n {#2}
    \group_end:
  }
\cs_new_eq:NN \typesetverb \tsverb 

\NewDocumentCommand \tsobj {O{code}m} 
  {
    \group_begin:
      \__codedesc_metafmt_set:nn {list format}{#1}
      \__codedesc_list_typeset:nVV{#2} \l__codedesc_sep_tl \l__codedesc_lastsep_tl
      
      \bool_if:NTF \l__codedesc_index_bool
        {
          \seq_set_from_clist:Nn \l__codedesc_tmpa_seq {#2}
          \seq_map_inline:Nn \l__codedesc_tmpa_seq
            { \__codedescribe_index:n {##1} }
        }
        {}      
    \group_end:
  }
\cs_new_eq:NN \typesetobj \tsobj


\NewDocumentCommand \tsmarginnote {m}
  {
    \marginpar
      {
        { \__codedesc_note_fmt:\raggedleft #1 \par }
      }
  }
\cs_new_eq:NN \typesetmarginnote \tsmarginnote 



% TODO: issue #18
% Test if already defined...maybe not...
%
\NewDocumentEnvironment {tsremark} {O{ \l__codedesc_remark_label_tl :}}
  {
    \xpeekahead_env_set:nNTF {tsremark}
      \c__codedesc_remark_regex
      { 
        \bool_set_true:N  \l__codedesc_tsremark_peek_bool
      }
      { 
        \bool_set_false:N \l__codedesc_tsremark_peek_bool 
        \par
        \skip_vertical:N \l__codecmm_mid_skip
      }

    \__codecmm_set_textcolwidth:
    \group_begin:
      \vcoffin_gset:Nnw \l__codedesc_tsremark_coffin {0.8\l__codecmm_textcolwidth_dim}
        \setlength\parindent{0pt}\small
        \textsl{\textbf{#1}} 
  }
  {
      \skip_vertical:N \l__codecmm_coffinskip_dim
      \vcoffin_gset_end:
      \bool_if:NTF \l__codedesc_tsremark_peek_bool
        {
          \par
        }
        {
          \mode_if_horizontal:T
            { \par }
          \skip_vertical:n{\l__codecmm_tiny_skip}
        }

      \noindent\hspace{0.2\l__codecmm_textcolwidth_dim}
      \coffin_typeset:Nnnnn 
        \l__codedesc_tsremark_coffin 
        {l}{T}  {0pt}{0pt}
    \group_end:
  }
\cs_new_eq:NN \typesetremark \tsremark
\cs_new_eq:NN \endtypesetremark \endtsremark

\NewDocumentEnvironment {tsremark*} {O{Note:}}
  {
    \msg_warning:nnnnn {codedesc} {deprecated env} {remark*:01}{tsremark*}{tsremark}
    \begin{tsremark}[#1]
  }
  {
    \end{tsremark}
  }


%%%% ARGH !!!!

\keys_define:nn { codedesc / title }
  {
    title    .usage:n = general ,
    title    .value_required:n = true ,
  	title    .tl_set:N = \l__codedesc_title_tl ,

    author   .usage:n = general ,
    author   .value_required:n = true ,
  	author   .tl_set:N = \l__codedesc_author_tl ,

    date     .usage:n = general ,
    date     .value_required:n = true ,
  	date     .tl_set:N = \l__codedesc_descdate_tl ,
  }


\cs_new_protected:Npn \__codedesc_make_title: {%
	\newpage
	\null
	\vskip 2em%
	\begin{center}%
		{\LARGE \l__codedesc_title_tl \par}%
		\vskip 1.5em%
		{\large
			\lineskip .5em%
			\begin{tabular}[t]{c}%
				\l__codedesc_author_tl
			\end{tabular}\par}%
		\vskip 1em%
		{\large \l__codedesc_descdate_tl}%
	\end{center}%
	\par
	\vskip 1.5em
}


\NewDocumentCommand \tsdate {}
  {
      \seq_item:NV \l__codedesc_months_label_seq \c_sys_month_int
      \use:n {~} \int_to_arabic:n {\c_sys_year_int}
  }
  
\cs_new_eq:NN \typesetdate \tsdate 

%%%ARGH !!!!!
%%% 'adapted' from 'abstract.cls'
%%%
%%%

\makeatletter

\tl_new:N \g__codedesc_footnote_tl
\int_new:N \g__codedesc_footnote_int

\cs_new_protected:Npn \__codedesc_footnote:nn #1#2
  {
    \footnotemark[#1]
    \tl_gput_right:Nn \g__codedesc_footnote_tl {\footnotetext[#1]{#2}}
  }

\cs_new_protected:Npn \__codedesc_footnote:n #1
  {
    \int_gincr:N \g__codedesc_footnote_int
    \exp_args:NV \__codedesc_footnote:nn \g__codedesc_footnote_int {#1}
  }
  
\NewDocumentCommand{\__codedesc_footnote:w}{O{}m}
  {
    \tl_if_empty:nTF {#1}
      { \__codedesc_footnote:n  {#2} }
      { \__codedesc_footnote:nn {#1}{#2} }
  }
  
\NewDocumentCommand \tstitle {m}
  {
    \keys_set:nn {codedesc / title}{#1}
  	\group_begin:
          \cs_set_eq:NN \footnote \__codedesc_footnote:w
          \tl_gclear:N \g__codedesc_footnote_tl
          \int_gzero:N \g__codedesc_footnote_int
        	\def\thefootnote{\@fnsymbol\c@footnote}%
        	\def\@makefnmark{\rlap{\@textsuperscript{\normalfont\@thefnmark}}}%
        	\long\def\@makefntext##1{\parindent 1em\noindent
        		\hb@xt@1.8em{%
        			\hss\@textsuperscript{\normalfont\@thefnmark}}##1}%
    	\if@twocolumn
      	\ifnum \col@number=\@ne
        	\__codedesc_make_title:
    	  \else
        	\twocolumn[\__codedesc_make_title:]%
    	  \fi
    	\else
      	\newpage
      	\global\@topnum\z@   % Prevents figures from going at top of page.
      	\__codedesc_make_title:
    	\fi
    	\thispagestyle{plain}
      \g__codedesc_footnote_tl
  	\group_end:
  }
\cs_new_eq:NN \typesettitle \tstitle 


\NewDocumentEnvironment{tsabstract}{}
  {
   	\if@twocolumn
     	\section*{\abstractname}%
   	\else
     	\small
     	\begin{center}%
     		{\bfseries \abstractname\vspace{-.5em}\vspace{\z@}}%
     	\end{center}%
     	\quotation
   	\fi
  }
  {
    \if@twocolumn\else\endquotation\fi
  }
\cs_new_eq:NN \typesetabstract \tsabstract
\cs_new_eq:NN \endtypesetabstract \endtsabstract

\makeatother



