%%%============================================================================== %% 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.4} {2024/02/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] \ProvidesExplPackage {codedescribe} {2024/02/17} {1.4} {LaTeX Code Description/Documentation} %%%%%%% %%% %%% Just an attempt of having my packages info in a regular way %%% Idea being: { / pkg info } for each and all. %%% %%%%%%% \keys_define:nn { codedescribe / pkg info} { name .code:n = {codedescribe} , prefix .code:n = {codedesc} , date .code:n = {2024/02/17} , version .code:n = {1.4} , description .code:n = {\LaTeX~Code~Description/Documentation} } \cs_if_exist:NF \PkgInfo { \NewDocumentCommand \PkgInfo {mm} { \keys_set:nn {#1 / pkg info}{#2} } \NewDocumentCommand \PkgDescription {m} { \noindent Package~ \textbf{\PkgInfo{#1}{name}}~Version:~\PkgInfo{#1}{version}~ -~ \PkgInfo{#1}{date}\par \emph{\PkgInfo{#1}{description}}~\par } } %%%%%%% %%% End of cut-n-paste %%%%%%% \use:c {@reversemargintrue} \bool_new:N \l__codedesc_loadlisting_bool \bool_set_true:N \l__codedesc_loadlisting_bool \keys_define:nn { codedescribe } { nolisting.usage:n = load, nolisting.bool_set_inverse:N = \l__codedesc_loadlisting_bool, nolisting.default:n = {true}, } \ProcessKeyOptions [codedescribe ] %% bbding is need for those hollow stars... \RequirePackage{xcolor} \RequirePackage{pifont} \bool_if:nT {\l__codedesc_loadlisting_bool} { \RequirePackage{codelisting} } \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 \tl_to_str:n {o , e} \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>. } %%%%%%% %%% %%% 'simplified' bold versions of \hline and \rule %%% those don't peek ahead (to see if they are followed by another line) %%% %%%%%%% \cs_new:Npn \__codedesc_hline:nnnn #1#2#3#4 {\noalign{#1\vskip #2\vskip 0pt\hrule height #3\arrayrulewidth\vskip #4\vskip 0pt}} \cs_new:Npn \__codedesc_hline:nn #1#2 {\__codedesc_hline:nnnn {#1}{-0.5ex}{#2}{0.25ex}} \cs_new:Npn \__codedesc_hline:n #1 {\__codedesc_hline:nnnn {#1}{-0.5ex}{2}{0.25ex}} \cs_new:Npn \__codedesc_rule:n #1 {\hrule height #1\arrayrulewidth} \cs_new:Npn \__codedesc_rule: {\hrule height 2\arrayrulewidth} %%%%%%% %%% %%% To get the 'real' columnwidth (multicolumn case) %%% given the current \linewidth and \textwidth %%% %%%%%%% \dim_new:N \l__codedesc_linewidth_dim \dim_new:N \l__codedesc_textcolwidth_dim \cs_new_protected:Npn \__codedesc_set_textcolwidth: { \dim_compare:nNnTF {\linewidth} = {\l__codedesc_linewidth_dim} {} { % \dim_set:Nn \l__codedesc_linewidth_dim {\linewidth} % \fp_set:Nn \l_tmpa_fp {(\textwidth - \linewidth) / \textwidth} % \dim_set:Nn \l__codedesc_textcolwidth_dim {\linewidth - \fp_use:N \l_tmpa_fp \columnsep} \dim_set:Nn \l__codedesc_textcolwidth_dim {\linewidth} } } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \keys_define:nn { codedesc / scratch_def } { 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 } , 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 } , color.usage:n = general , color .value_required:n = true , color.code:n = { \tl_set:Nn \l__codedesc_tmpcolor_tl { #1 } } , lbracket .usage:n = general , lbracket .value_required:n = true , lbracket .code:n = { \tl_set:Nn \l__codedesc_tmplbracket_tl { #1 } } , rbracket .usage:n = general , rbracket .value_required:n = true , rbracket .code:n = { \tl_set:Nn \l__codedesc_tmprbracket_tl { #1 } } , unknown.code:n = { \msg_error:nnxx { codedesc } {format-err} {format}{\l_keys_key_str} }, } \keys_define:nn { codedesc / grp_scratch } { unknown .code:n = {} } \cs_new_protected:Npn \__codedesc_group_define:nn #1#2 { \tl_clear:N \l__codedesc_tmpfmt_tl \tl_clear:N \l__codedesc_tmpshape_tl \tl_clear:N \l__codedesc_tmpcolor_tl \tl_clear:N \l__codedesc_tmplbracket_tl \tl_clear:N \l__codedesc_tmprbracket_tl \keys_set:nn { codedesc / grp_scratch } {#1} \keys_set:nn { codedesc / scratch_def } {#2} \tl_clear:N \l_tmpa_tl \tl_clear:N \l_tmpb_tl \tl_if_empty:NF \l__codedesc_tmpfmt_tl { \tl_put_right:No \l_tmpa_tl{\l__codedesc_tmpfmt_tl} \tl_set:Nn \l_tmpb_tl { , } } \tl_if_empty:NF \l__codedesc_tmpshape_tl { \tl_put_right:No \l_tmpa_tl{ \l_tmpb_tl } \tl_put_right:No \l_tmpa_tl{\l__codedesc_tmpshape_tl} \tl_set:Nn \l_tmpb_tl { , } } \tl_if_empty:NF \l__codedesc_tmpcolor_tl { \tl_put_right:No \l_tmpa_tl{ \l_tmpb_tl } \tl_put_right:Nn \l_tmpa_tl{ color = } \tl_put_right:No \l_tmpa_tl{ \l__codedesc_tmpcolor_tl} \tl_set:Nn \l_tmpb_tl { , } } \tl_if_empty:NF \l__codedesc_tmplbracket_tl { \tl_put_right:No \l_tmpa_tl{ \l_tmpb_tl } \tl_put_right:Nn \l_tmpa_tl{ lbracket = } \tl_put_right:No \l_tmpa_tl{ \l__codedesc_tmplbracket_tl} \tl_set:Nn \l_tmpb_tl { , } } \tl_if_empty:NF \l__codedesc_tmprbracket_tl { \tl_put_right:No \l_tmpa_tl{ \l_tmpb_tl } \tl_put_right:Nn \l_tmpa_tl{ rbracket = } \tl_put_right:No \l_tmpa_tl{ \l__codedesc_tmprbracket_tl} % \tl_set:Nn \l_tmpb_tl { , } } \keys_define:ne { codedesc / grp_scratch } { #1 .meta:nn = { codedesc / scratch_def } { \l_tmpa_tl} } \keys_define:ne { codedesc / grp_fmt } { #1 .meta:nn = { codedesc / base_fmt } { \l_tmpa_tl} } } \keys_define:nn { codedesc / grp_fmt } { unknown .code:n = \msg_error:nnxx { codedesc } {group-err} {grpfmt}{\l_keys_key_str} } \cs_new_protected:Npn \__codedesc_object_define:nnn #1#2#3 { \tl_if_blank:nTF {#3} { \keys_define:nn { codedesc / format } { #1 .meta:nn = { codedesc / grp_fmt } { #2 } } } { \__codedesc_group_define:nn { #1_objfmt } {#3} \keys_define:nn { codedesc / format } { #1 .meta:nn = { codedesc / grp_fmt } { #2 , #1_objfmt} } } } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \tl_set:Nn \__codedesc_metasize_tl: {\small} \tl_set:Nn \__codedesc_metafont_tl: {\ttfamily} \colorlet{c__codedesc_none_color}{red!70!black} \colorlet{c__codedesc_verb_color}{ black } \__codedesc_group_define:nn {verb} {color=c__codedesc_verb_color} \__codedesc_object_define:nnn {verb}{verb}{verb} \__codedesc_object_define:nnn {xverb}{verb}{xverb} \colorlet{c__codedesc_marg_color}{ gray!60!black } \__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={\}}} \colorlet{c__codedesc_oarg_color}{ gray!90!black } \__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={>}} \colorlet{c__codedesc_code_color}{ blue!40!black } \__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 {code} {xverb,color=red} \colorlet{c__codedesc_syntax_color}{ blue!60!black } \__codedesc_group_define:nn {syntax} {color=c__codedesc_syntax_color} \__codedesc_object_define:nnn {syntax}{syntax}{} \colorlet{c__codedesc_keyval_color}{ teal!40!black } \__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}{} \colorlet{c__codedesc_options_color}{ green!30!black } \__codedesc_group_define:nn {option} {color=c__codedesc_options_color} \__codedesc_object_define:nnn {option}{option}{} \colorlet{c__codedesc_defaultval_color}{ blue!60!black } \__codedesc_group_define:nn {defaultval} {color=c__codedesc_defaultval_color} \__codedesc_object_define:nnn {defaultval}{defaultval}{} \colorlet{c__codedesc_env_color}{ green!30!black } \__codedesc_group_define:nn {env} {slshape,color=c__codedesc_env_color} \__codedesc_object_define:nnn {env}{env}{} \colorlet{c__codedesc_pkg_color}{ green!30!black } \__codedesc_group_define:nn {pkg} {slshape,color=c__codedesc_pkg_color} \__codedesc_object_define:nnn {pkg}{pkg}{} \__codedesc_object_define:nnn {pack}{pkg}{} \keys_define:nn { codedesc / base_fmt } { meta .usage:n = general , meta .value_forbidden:n = true , meta .code:n = { \tl_set:Nn \__codedesc_typeset_tl:n { \__codedesc_meta:n } \tl_set:Nn \__codedesc_typeset_tl:o { \__codedesc_meta:o } } , xmeta .usage:n = general , xmeta .value_forbidden:n = true , xmeta .code:n = { \tl_set:Nn \__codedesc_typeset_tl:n { \__codedesc_meta*:n } \tl_set:Nn \__codedesc_typeset_tl:o { \__codedesc_meta*:o } } , verb .usage:n = general , verb .value_forbidden:n = true , verb .code:n = { \tl_set:Nn \__codedesc_typeset_tl:n { \tl_to_str:n } \tl_set:Nn \__codedesc_typeset_tl:o { \tl_to_str:o } } , xverb .usage:n = general , xverb .value_forbidden:n = true , xverb .code:n = { \tl_set:Nn \__codedesc_typeset_tl:n { \__codedesc_verb_nospc_typeset:n } \tl_set:Nn \__codedesc_typeset_tl:o { \__codedesc_verb_nospc_typeset:o } } , code .usage:n = general , code .value_forbidden:n = true , code .code:n = { \tl_set:Nn \__codedesc_typeset_tl:n { \__codedesc_macro_typeset:n } \tl_set:Nn \__codedesc_typeset_tl:o { \__codedesc_macro_typeset:o } } , slshape .usage:n = general , slshape .value_forbidden:n = true , slshape .code:n = { \tl_set:Nn \__codedesc_metashape_tl: { \slshape} } , itshape .usage:n = general , itshape .value_forbidden:n = true , itshape .code:n = { \tl_set:Nn \__codedesc_metashape_tl: { \itshape } } , lbracket .usage:n = general , lbracket .value_required:n = true , lbracket .code:n = { \tl_set:Nn \__codedesc_Lbracket_tl { #1 } } , rbracket .usage:n = general , rbracket .value_required:n = true , rbracket .code:n = { \tl_set:Nn \__codedesc_Rbracket_tl { #1 } } , color .usage:n = general , color .value_required:n = true , color .code:n = { \tl_set:Nn \__codedesc_metacolor_tl: { \color{#1} } } , } \keys_define:nn { codedesc / format } { EXP.usage:n = general, EXP.code:n = { \tl_set:Nn \__codedesc_exp_tl { ~\hfill{\scriptsize\ding{72}} } }, % rEXP.usage:n = general, rEXP.code:n = { \tl_set:Nn \__codedesc_exp_tl { ~\hfill{\scriptsize\ding{73}} } }, % sep.usage:n = general, sep.code:n = { \tl_set:Nn \__codedesc_lastsep_tl { ~#1~ } }, % comma.usage:n = general, comma.code:n = { \tl_set:Nn \__codedesc_lastsep_tl { ,~ } }, % rulecolor.usage:n = general, rulecolor.code:n = { \tl_set:Nn \__codedesc_rulecolor_tl: { \color{#1} } }, % new.usage:n = general, new.code:n = { \bool_set_true:N \l__codedesc_descnotes_bool \bool_set_true:N \l__codedesc_descdate_new_bool % \tl_set:Nn \l__codedesc_descdate_new_tl {#1} \seq_put_right:Nn \l__codedesc_descdate_new_seq {#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 %\tl_set:Nn \l__codedesc_descdate_update_tl {#1} \seq_put_right:Nn \l__codedesc_descdate_update_seq {#1} }, note.usage:n = general, note.code:n = { \bool_set_true:N \l__codedesc_descnotes_bool \bool_set_true:N \l__codedesc_sidenote_bool % \tl_set:Nn \l__codedesc_sidenote_tl {#1} \seq_put_right:Nn \l__codedesc_sidenote_seq {#1} }, unknown.usage:n = general, unknown.code:n = { \tl_set:Nn \__codedesc_metacolor_tl: { \color{c__codedesc_none_color} } \msg_error:nnxx { codedesc } {object-err} {format}{\l_keys_key_str} }, } \cs_new_protected:Npn \__codedesc_metafmt_set:n #1 { \tl_set:Nn \__codedesc_rulecolor_tl: { \__codedesc_metacolor_tl: } \tl_set:Nn \__codedesc_metashape_tl: { } \tl_set:Nn \__codedesc_typeset_tl:n { } \tl_set:Nn \__codedesc_typeset_tl:o { } \tl_set:Nn \__codedesc_Lbracket_tl { } \tl_set:Nn \__codedesc_Rbracket_tl { } \tl_set:Nn \__codedesc_sep_tl {,\ } \tl_set:Nn \__codedesc_lastsep_tl {\ and\ } \tl_set:Nn \__codedesc_exp_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 \keys_set:nn {codedesc / format}{#1} } \cs_generate_variant:Nn \__codedesc_metafmt_set:n {o} \cs_new_protected:Npn \__codedesc_metafmt:n #1 { \__codedesc_metafmt_set:n {#1} \__codedesc_metafmt: } \cs_generate_variant:Nn \__codedesc_metafmt:n {o} \cs_new_protected:Npn \__codedesc_metafmt: { \__codedesc_metacolor_tl: \__codedesc_metasize_tl: \__codedesc_metafont_tl: \__codedesc_metashape_tl: } %%%%%%% %%% %%% < meta > %%% %%%%%%% \cs_new_protected:Npn \__codedesc_meta:n #1 { \ensuremath\langle #1 \ensuremath\rangle } \cs_generate_variant:Nn \__codedesc_meta:n {o} %%%%%%% %%% %%% < meta > 'detokenized' %%% %%%%%%% \cs_new_protected:Npn \__codedesc_meta*:n #1 { \ensuremath\langle \tl_to_str:n {#1} \ensuremath\rangle } \cs_generate_variant:cn {__codedesc_meta*:n} {o} \cs_new_protected:Npn \__codedesc_macro_typeset:n #1 { \tl_set:Ne \l_tmpb_tl {\tl_to_str:n{#1}} \regex_replace_all:nnN {\ }{} \l_tmpb_tl \regex_replace_once:nnNTF {TF}{}\l_tmpb_tl { \l_tmpb_tl\textsl{\underline{TF}} } { \l_tmpb_tl } } \cs_generate_variant:Nn \__codedesc_macro_typeset:n {o} \cs_new_protected:Npn \__codedesc_verb_nospc_typeset:n #1 { \tl_set:Ne \l_tmpb_tl {\tl_to_str:n{#1}} \regex_replace_all:nnN {\ }{} \l_tmpb_tl \l_tmpb_tl } \cs_generate_variant:Nn \__codedesc_verb_nospc_typeset:n {o} \cs_new_protected:Npn \__codedesc_list_typeset:nnn #1#2#3 { \seq_set_from_clist:Nn \l_tmpa_seq {#1} \bool_set:Nn \l__codedesc_bool {\seq_if_empty_p:N \l_tmpa_seq} \tl_set:Nn \l__codedesc_middle_tl {} \tl_set:Nn \l__codedesc_lastone_tl {} \bool_until_do:Nn \l__codedesc_bool { \seq_pop_left:NNTF \l_tmpa_seq \l_tmpa_tl { \seq_if_empty:NTF \l_tmpa_seq { \l__codedesc_lastone_tl { \__codedesc_metafmt: \__codedesc_typeset_tl:o \l_tmpa_tl } \bool_set_true:N \l__codedesc_bool } { \l__codedesc_middle_tl { \__codedesc_metafmt: \__codedesc_typeset_tl:o \l_tmpa_tl } \tl_set:Nn \l__codedesc_middle_tl {#2} \tl_set:Nn \l__codedesc_lastone_tl {#3} } } {} } } \cs_generate_variant:Nn \__codedesc_list_typeset:nnn {noo} \cs_new_protected:Npn \__codedesc_args_typeset:nnnn #1#2#3#4 { \seq_set_from_clist:Nn \l_tmpa_seq {#3} \group_begin: \__codedesc_metafmt:n {#1} \seq_map_inline:Nn \l_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 \l__codedesc_syntax_bool \dim_new:N \l__codedesc_syntax_wd_dim \dim_new:N \l__codedesc_margin_wd_dim \bool_new:N \l__codedesc_descnotes_bool \bool_new:N \l__codedesc_descdate_new_bool %\tl_new:N \l__codedesc_descdate_new_tl \seq_new:N \l__codedesc_descdate_new_seq \bool_new:N \l__codedesc_descdate_update_bool %\tl_new:N \l__codedesc_descdate_update_tl \seq_new:N \l__codedesc_descdate_update_seq \bool_new:N \l__codedesc_sidenote_bool %\tl_new:N \l__codedesc_sidenote_tl \seq_new:N \l__codedesc_sidenote_seq \coffin_new:N \__codedesc_describe_coffin \dim_new:N \__codedesc_describelabel_wd_dim \dim_new:N \__codedesc_describelist_wd_dim \tl_new:N \__codedesc_join_tl: \tl_new:N \__codedesc_ragged_tl: \dim_new:N \__codedesc_paradvance_dim %%%%%%%%%%%%%%%%%%% %%%% %%%% User/Document level commands %%%% %%%%%%%%%%%%%%%%%%% \NewDocumentCommand \defgroupfmt {mm} { \__codedesc_group_define:nn {#1} {#2} } \NewDocumentCommand \defobjectfmt {mmm} { \__codedesc_object_define:nn {#1} {#2} {#3} } \NewDocumentEnvironment {codedescribe}{O{code}m} { \mode_if_horizontal:TF { \dim_set:Nn \__codedesc_paradvance_dim {\baselineskip} } { \dim_set:Nn \__codedesc_paradvance_dim {0pt} } \seq_set_from_clist:Nn \l_tmpa_seq {#2} \__codedesc_set_textcolwidth: \hcoffin_set:Nn \l__codedesc_margin_coffin { \__codedesc_metafmt:n {#1} \begin{tabular}{@{} l @{} } \__codedesc_hline:nnnn {\__codedesc_rulecolor_tl:}{0.5ex}{2}{0.25ex} \seq_map_inline:Nn \l_tmpa_seq { \__codedesc_typeset_tl:n {##1} \__codedesc_exp_tl \\ } \bool_if:nTF {\l__codedesc_descnotes_bool} { \\[-2.5ex] \__codedesc_hline:nnnn {\color{black}}{0.5ex}{0.25}{0.25ex} %%% \bool_if:nT {\l__codedesc_descdate_new_bool} %%% {\scriptsize\color{black}new:~ \l__codedesc_descdate_new_tl\\[-1ex]} \bool_if:nT {\l__codedesc_descdate_new_bool} { \seq_map_inline:Nn \l__codedesc_descdate_new_seq {\scriptsize\color{black}new:~ ##1\\[-1ex]} } %%% \bool_if:nT {\l__codedesc_descdate_update_bool} %%% {\scriptsize\color{black}update:~ \l__codedesc_descdate_update_tl\\[-1ex]} \bool_if:nT {\l__codedesc_descdate_update_bool} { \seq_map_inline:Nn \l__codedesc_descdate_update_seq {\scriptsize\color{black}update:~ ##1\\[-1ex]} } %%% \bool_if:nT {\l__codedesc_sidenote_bool} %%% {\scriptsize\color{black}NB:~ \l__codedesc_sidenote_tl\\[-1ex]} \bool_if:nT {\l__codedesc_sidenote_bool} { \seq_map_inline:Nn \l__codedesc_sidenote_seq {\scriptsize\color{black}NB:~ ##1\\[-1ex]} } \\[-1.5ex] } { \\[-2.5ex] } \__codedesc_hline:nnnn {\__codedesc_rulecolor_tl:}{-0.25ex}{2}{1ex} \end{tabular} } \dim_set:Nn \l__codedesc_margin_wd_dim {\coffin_wd:N \l__codedesc_margin_coffin} \bool_if:nTF { \dim_compare_p:nNn \l__codedesc_margin_wd_dim > \marginparwidth} { \bool_set_true:N \l__codedesc_longblock_bool \dim_set:Nn \l__codedesc_syntax_wd_dim {\l__codedesc_textcolwidth_dim - (\l__codedesc_margin_wd_dim - \marginparwidth) } } { \bool_set_false:N \l__codedesc_longblock_bool \dim_set:Nn \l__codedesc_syntax_wd_dim {\l__codedesc_textcolwidth_dim} } \coffin_clear:N \l__codedesc_syntax_coffin \bool_set_false:N \l__codedesc_syntax_bool \vcoffin_set:Nnw \l__codedesc_text_coffin {\l__codedesc_textcolwidth_dim} \setlength\parindent{0pt} \begin{minipage}[t]{\l__codedesc_textcolwidth_dim} } { \end{minipage} \vcoffin_set_end: \bool_if:NTF \l__codedesc_longblock_bool { % __describeblock starting at marginpar \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}{\baselineskip} \par\noindent \coffin_typeset:Nnnnn \l__codedesc_syntax_coffin {l}{t} {-\marginparwidth-\marginparsep}{\__codedesc_paradvance_dim} } { % __describeblock at marginpar \coffin_attach: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} {0pt}{\baselineskip} \par\noindent \coffin_typeset:Nnnnn \l__codedesc_syntax_coffin {l}{t} {0pt}{\__codedesc_paradvance_dim} } \\[0.5\baselineskip] %\\[\__codedesc_paradvance_dim]%[-0.5\baselineskip] } \NewDocumentEnvironment{codesyntax}{} { \vcoffin_gset:Nnw \l__codedesc_syntax_coffin {\l__codedesc_syntax_wd_dim} \__codedesc_metafmt:n {syntax} \hspace*{2em} %% !!! together with \parindent{-2em} \begin{tabular} { @{} l @{} } \__codedesc_hline:nnnn {\color{white}}{0.5ex}{2}{-1.5ex} \__codedesc_metacolor_tl: \begin{minipage}[t]{\l__codedesc_syntax_wd_dim} \obeylines\obeyspaces\setlength\parindent{-2em} } { \end{minipage}\\[-2.5ex] \\ \__codedesc_hline:nnnn {\color{white}}{0ex}{2}{1ex} \end{tabular} %\color{black} \vcoffin_gset_end: } \NewDocumentEnvironment{describelist}{O{20mm}m} { %\vspace*{-1.5ex} \mode_if_horizontal:TF {\\[-0.5\baselineskip]} {} \__codedesc_set_textcolwidth: \coffin_clear:N \__codedesc_describe_coffin \dim_set:Nn \__codedesc_describelabel_wd_dim {#1} \dim_set:Nn \__codedesc_describelist_wd_dim {\l__codedesc_textcolwidth_dim} \tl_set:Nn \__codedesc_join_tl: {\coffin_attach:NnnNnnnn} \tl_set:Nn \__codedesc_ragged_tl: {\raggedleft} \tl_set:Nn \__codedesc_listkind_tl {#2} } { % \par\noindent\coffin_typeset:Nnnnn \__codedesc_describe_coffin {l}{t}{0pt}{10pt} } \NewDocumentEnvironment{describelist*}{O{20mm}m} { %\vspace*{-1.5ex} \mode_if_horizontal:TF {\\[-0.5\baselineskip]}%{\vspace*{-1ex}} {} \__codedesc_set_textcolwidth: \coffin_clear:N \__codedesc_describe_coffin \dim_set:Nn \__codedesc_describelabel_wd_dim {#1} \dim_set:Nn \__codedesc_describelist_wd_dim {\l__codedesc_textcolwidth_dim - \__codedesc_describelabel_wd_dim -\marginparsep} \tl_set:Nn \__codedesc_join_tl: {\coffin_join:NnnNnnnn} \tl_set:Nn \__codedesc_ragged_tl: {} \tl_set:Nn \__codedesc_listkind_tl {#2} } { % \par\noindent\coffin_typeset:Nnnnn \__codedesc_describe_coffin {l}{t}{0pt}{10pt} } \NewDocumentCommand \describe {mm} { \hcoffin_set:Nn \l_tmpb_coffin { \__codedesc_metafmt:o { \__codedesc_listkind_tl } \__codedesc_ragged_tl: \__codedesc_typeset_tl:n {#1} } \dim_compare:nNnTF {\coffin_wd:N \l_tmpb_coffin} > {\__codedesc_describelabel_wd_dim} { \vcoffin_set:Nnn \l_tmpa_coffin { \__codedesc_describelabel_wd_dim } { ~\ ~ } \coffin_attach:NnnNnnnn \l_tmpa_coffin {r}{t} \l_tmpb_coffin {r}{t} {0pt}{0pt} } { \vcoffin_set:Nnn \l_tmpa_coffin { \__codedesc_describelabel_wd_dim } { \__codedesc_metafmt:o { \__codedesc_listkind_tl } \noindent\__codedesc_ragged_tl: \__codedesc_typeset_tl:n {#1} } } \vcoffin_set:Nnn \l_tmpb_coffin { \__codedesc_describelist_wd_dim } { \noindent \begin{minipage}[t]{ \__codedesc_describelist_wd_dim } #2 \end{minipage} } \__codedesc_join_tl: \l_tmpb_coffin {l}{t} \l_tmpa_coffin {r}{t} {-\marginparsep}{0pt} \mode_if_horizontal:TF { \\[-\baselineskip] } { } \noindent \coffin_typeset:Nnnnn \l_tmpb_coffin {l}{t} {0pt}{0pt} \\ } \NewDocumentCommand \typesetmeta {m} {\__codedesc_meta:n {#1}} \cs_new_eq:NN \tsmeta \typesetmeta \NewDocumentCommand \typesetargs {O{meta}m} { % \keys_set:nn {codedesc / delimiters}{#1} \group_begin: \__codedesc_metafmt:n {#1} \__codedesc_args_typeset:nnnn {#1} {\__codedesc_Lbracket_tl} {#2} {\__codedesc_Rbracket_tl} \group_end: } \cs_new_eq:NN \tsargs \typesetargs \NewDocumentCommand \typesetmacro {mO{}m} { \__codedesc_metafmt_set:n {code} %.... argh! \__codedesc_list_typeset:nnn{#1}{,~}{,~} % \__codedesc_macro_typeset:n{#1} \,\__codedesc_args_typeset:nnnn {oarg} [ {#2} ] \__codedesc_args_typeset:nnnn {marg} \{ {#3} \} } \cs_new_eq:NN \tsmacro \typesetmacro \NewDocumentCommand \typesetverb {O{code}m} { \group_begin: \__codedesc_metafmt:n {#1} \tl_to_str:n {#2} \group_end: } \cs_new_eq:NN \tsverb \typesetverb \NewDocumentCommand \typesetobj {O{code}m} { \__codedesc_metafmt_set:n {#1} \__codedesc_list_typeset:noo{#2}{\__codedesc_sep_tl}{\__codedesc_lastsep_tl} } \cs_new_eq:NN \tsobj \typesetobj \NewDocumentCommand \typesetmarginnote {m}{\marginpar{{\scriptsize\raggedleft #1 \par}}} \cs_new_eq:NN \tsmarginnote \typesetmarginnote \NewDocumentEnvironment {tsremark} {O{Note:}} { \mode_if_horizontal:TF {\par\vspace*{0.25\baselineskip}}%\vspace*{-1.5ex}} {\vspace*{0.75\baselineskip}} \__codedesc_set_textcolwidth: \group_begin: \noindent\hspace{0.2\l__codedesc_textcolwidth_dim} \begin{minipage}{0.8\l__codedesc_textcolwidth_dim} \setlength\parindent{0pt}\small \textsl{\textbf{#1}} %\dim_to_decimal:n {\linewidth} } { \end{minipage} \group_end: \\[0.5\baselineskip] } %%%% 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}% \let \footnote \thanks {\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 \typesetdate {} { \int_case:nn {\month} { {1}{January} {2}{February} {3}{March} {4}{April} {5}{May} {6}{June} {7}{July} {8}{August} {9}{September} {10}{October} {11}{November} {12}{December} } \use:n {~} \int_to_arabic:n {\year} } \cs_new_eq:NN \tsdate \typesetdate %%%ARGH !!!!! %%% 'adapted' from 'abstract.cls' %%% %%% \makeatletter \NewDocumentCommand \typesettitle {m} { \keys_set:nn {codedesc / title}{#1} \group_begin: \renewcommand\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}\@thanks \group_end: } \cs_new_eq:NN \tstitle \typesettitle \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 \endtypesetabstractend \endtsabstract \makeatother