%%%============================================================================== %% 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 {} { props} sets package info %%% %%% \pkginfograbProvidesExplPackage {} { 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