%% %% This is file `ccool.sty', %% generated with the docstrip utility. %% %% The original source files were: %% %% ccool.dtx (with options: `package') %% ---------------------------------------------------------------------------- %% ccool --- A key-value document command parser %% Released under the LaTeX Project Public License v1.3c or later %% See http://www.latex-project.org/lppl.txt %% ---------------------------------------------------------------------------- %% \NeedsTeXFormat{LaTeX2e}[2020/02/02] \RequirePackage{erw-l3}[2020/06/04] \RequirePackage{etoolbox}[2019/09/21] \RequirePackage{l3keys2e}[2020/03/06] \RequirePackage{xparse}[2020/03/06] \ProvidesExplPackage {ccool} % Package name {2020/10/10} % Release date {3.1} % Release version {cool --- A key-value document command parser} % Description \ExplSyntaxOn \cs_new_protected:Nn \__ccool_aux_inner_set:n { \cs_gset:Npn \__ccool_aux_inner:n ##1 {#1} \cs_generate_variant:Nn \__ccool_aux_inner:n { e } } \cs_new_protected:Npn \__ccool_aux_key:w #1 = #2 \q_stop { \seq_gput_right:Nx \g__ccool_aux_key_seq { \tl_trim_spaces:n{#1} } } \cs_new_protected:Nn \__ccool_aux_key:n { \__ccool_aux_key:w #1 \q_stop } \cs_new_protected:Nn \__ccool_aux_key:N { \seq_gclear_new:N \g__ccool_aux_key_seq \seq_map_function:NN #1 \__ccool_aux_key:n } \cs_new_protected:Nn \__ccool_aux_outer_set:n { \cs_gset:Npn \__ccool_aux_outer:n ##1 {#1} } \prop_new:N \g__ccool_aux_prop \cs_new_protected:Nn \__ccool_aux_prop:nn { \prop_gput:Nnn \g__ccool_aux_prop{#1}{#2} } \cs_generate_variant:Nn \__ccool_aux_prop:nn { eo, ee, ex, xo, xe, xx } \tl_new:N \g__ccool_option_expans_tl \cs_new_protected:Npn \__ccool_aux_prop:w #1 = #2 \q_stop { \exp_args:Nx \use:c{__ccool_aux_prop:\g__ccool_option_expans_tl} { \tl_trim_spaces:n{#1} } { \__ccool_aux_inner:n{ \tl_trim_spaces:n{#2} } } } \cs_new_protected:Nn \__ccool_aux_prop:n { \__ccool_aux_prop:w #1 \q_stop } \cs_new_protected:Nn \__ccool_aux_prop:N { \prop_gclear_new:N \g__ccool_aux_prop \seq_if_empty:NTF #1 { \c_empty_tl } { \seq_map_function:NN #1 \__ccool_aux_prop:n } } \cs_new_protected:Nn \__ccool_aux_val:Nn { \seq_gclear_new:N \g__ccool_aux_val_seq \__ccool_seq_from_prop:NNn \g__ccool_aux_val_seq #1 { \__ccool_prop_name:n{#2} } } \prop_new:N \g__ccool_lang_and_prop \cs_new_protected:Nn \__ccool_lang_and_update:n { \erw_prop_keyval_parse:NNNn \g__ccool_lang_and_prop \erw_keyval_error:Nn \prop_gput:Nnn { #1 } } \cs_generate_variant:Nn \__ccool_lang_and_update:n { e } \cs_new:Nn \__ccool_lang_and:n { \prop_if_in:NnTF \g__ccool_lang_and_prop {#1} {\prop_item:Nn\g__ccool_lang_and_prop{#1}} { \msg_warning:nnn{__ccool}{lang_and}{#1} \__ccool_lang_and:n{english} } } \ifcsdef{languagename} { \cs_new:Nn \__ccool_lang_and:{\exp_args:No\__ccool_lang_and:n{\languagename}} } { \cs_new:Nn \__ccool_lang_and:{english} } \tl_const:Nn \c__ccool_lang_and_tl { afrikaans=en, basque=eta, catalan=i, croatian=i, czech=a, danish=og, dutch=en, english=and, esperanto=kaj, estonian=ja, finnish=ja, french=et, galician=e, german=und, hungarian=\'es, icelandic=og, indonesian=dan, irish=agus, italian=e, kurmanji=\^u, latin=et, latvian=un, lithuanian=ir, ngerman=und, polish=i, portuguese=e, romanian=\c{s}i, slovak=a, spanish=y, swedish=och, swissgerman=und, turkish=ve, turkmen=we, welsh=a } \iow_new:N \g__ccool_log_iow \AtEndDocument{\iow_close:N \g__ccool_log_iow} \bool_set_false:N \g__ccool_log_open_bool \cs_new_protected:Nn \__ccool_log_close: { \iow_close:N \g__ccool_log_iow \bool_gset_false:N \g__ccool_log_open_bool } \tl_new:N \g__ccool_log_file_tl \cs_new_protected:Nn \__ccool_log_open: { \tl_gset:Nx \g__ccool_log_to_tl{\g__ccool_log_file_tl} \iow_open:Nn \g__ccool_log_iow {\g__ccool_log_to_tl} \bool_gset_true:N \g__ccool_log_open_bool } \cs_new_protected:Nn \__ccool_log_read:n { \file_input:n{#1} \tl_log:n{read~from~#1} } \cs_generate_variant:Nn \__ccool_log_read:n { e } \cs_new_protected:Nn \__ccool_log_read: { \__ccool_log_read:e{\g__ccool_log_to_tl} } \tl_new:N \g__ccool_log_to_tl \cs_new_protected:Nn \__ccool_log_write:n { \bool_if:nTF{ \g__ccool_log_open_bool } { \iow_now:Nn \g__ccool_log_iow {#1} \tl_log:n{ write~to~#1 } } { \msg_error:nnn{ __ccool }{ iow }{ \g__ccool_log_iow } } } \cs_generate_variant:Nn \__ccool_log_write:n { e } \cs_new_protected:Nn \__ccool_make_key:Nn { \exp_args:NNx \DeclareDocumentCommand{#1} { D<>{\g__ccool_option_param_tl} } { \__ccool_prop_item:nn{##1}{#2} } } \cs_generate_variant:Nn \__ccool_make_key:Nn {c} \cs_new_protected:Nn \__ccool_make_key:n { \__ccool_make_key:cn{#1}{#1} } \cs_generate_variant:Nn \__ccool_make_key:n { e } \cs_new_protected:Nn \__ccool_make_key:N { \seq_map_function:NN #1 \__ccool_make_key:e } \cs_new_protected:Nn \__ccool_make_ccool_exp:nnn { \__ccool_aux_val:Nn \g__ccool_aux_key_seq {#1} \__ccool_aux_outer_set:n{#3} \__ccool_aux_outer:n { \exp_args:NNf \erw_seq_use:Nn \g__ccool_aux_val_seq {#2} } } \cs_new_protected:Nn \__ccool_make_ccool_key:nnn { \__ccool_prop_if_exist:nTF{#1} { \c_empty_tl } { \__ccool_prop_new:n{#1} } \exp_args:No \__ccool_aux_inner_set:n{#2} \seq_set_from_clist:Nn \g__ccool_aux_keyval_seq {#3} \__ccool_aux_prop:N \g__ccool_aux_keyval_seq \__ccool_prop_append:Nn \g__ccool_aux_prop {#1} \__ccool_aux_key:N \g__ccool_aux_keyval_seq \__ccool_make_key:N \g__ccool_aux_key_seq } \cs_new_protected:Nn \__ccool_make_ccool_sideeffect:nnn { \__ccool_make_ccool_key:nnn{#1}{#2}{#3} \bool_if:nTF{ \g__ccool_log_open_bool } { \__ccool_log_write:n { \begingroup \def \__ccool_log_entry { \Ccool<#1>c{#2}{#3} } \expandafter \endgroup \__ccool_log_entry } }{\c_empty_tl} } \cs_new_protected:Npn \__ccool_make_ccool:nnnn #1 #2 #3 #4 { \exp_args:NNx \DeclareDocumentCommand \Ccool {%^^A 2 3 4 5 6 7 8 9 +o D<>{#1} E{ c }{{#2}} m t+ s E{ s c }{{#3}{#4}} +o } { \IfValueT{##1}{##1} \__ccool_make_ccool_sideeffect:nnn{##2}{##3}{##4} \IfBooleanT{##6} { \__ccool_make_ccool_exp:nnn{##2}{##7}{##8} } \bool_if:nTF{##5} { \gappto{\CcoolHook} { \__ccool_make_ccool_sideeffect:nnn{##2}{##3}{##4} } } {\c_empty_tl} \IfValueT{##9} { \exp_not:n{ \Ccool[##9] } } } } \msg_new:nnn {__ccool} { iow } {#1~is~closed~can't~write} \msg_new:nnn {__ccool} {lang_and} {~key~#1~missing~for~global~option~'And';~falling~back~on~'english'} \tl_new:N \g__ccool_option_inner_tl \cs_new_protected:Nn \__ccool_option_inner:n { \tl_gset:Nn \g__ccool_option_inner_tl {#1} } \tl_new:N \g__ccool_option_param_tl \cs_new_protected:Nn \__ccool_option_param:n { \tl_gset:Nn \g__ccool_option_param_tl{#1} } \tl_new:N \g__ccool_option_outer_tl \cs_new_protected:Nn \__ccool_option_outer:n { \tl_gset:Nn \g__ccool_option_outer_tl {#1} } \tl_new:N \g__ccool_option_separ_tl \cs_new_protected:Nn \__ccool_option_separ:n { \cs_gset:Npn \g__ccool_option_separ_tl {#1} } \ifcsdef{text} { \tl_const:Nn \c__ccool_option_separ_default_tl { { \text{{\ }\__ccool_lang_and:{\ }} } { \text{,{\ }} } { \text{,{\ }\__ccool_lang_and:{\ }} } } } { \tl_const:Nn \c__ccool_option_separ_default_tl { { {\ }\__ccool_lang_and:{\ } } { ,{\ } } { ,{\ }\__ccool_lang_and:{\ } } } } \cs_new_protected:Npn \__ccool_prop_append:NN #1 #2 { \cs_set:Nn \__ccool_prop_append:nn { \prop_gput:Nnx #1 {##1}{ \prop_item:Nn #2{##1} } } \prop_map_function:NN #2 \__ccool_prop_append:nn } \cs_generate_variant:Nn \__ccool_prop_append:NN { cN } \cs_new_protected:Nn \__ccool_prop_append:Nn { \__ccool_prop_append:cN{ \__ccool_prop_name:n {#2} } #1 } \cs_new_protected:Nn \__ccool_prop_clear_new:n { \exp_args:No \prop_clear_new:c{ \__ccool_prop_name:n {#1} } } \cs_new_protected:Nn \__ccool_prop_clear_new_map:n { \seq_set_from_clist:Nn \g__ccool_aux_key_seq {#1} \seq_map_function:NN \g__ccool_aux_key_seq \__ccool_prop_clear_new:n } \cs_new:Nn \__ccool_prop_if_exist:nTF { \prop_if_exist:cTF{ \__ccool_prop_name:n {#1} }{#2}{#3} } \cs_new:Nn \__ccool_prop_item:nn { \prop_item:cn { \__ccool_prop_name:n {#1} } {#2} } \cs_new:Npn \__ccool_prop_name:n #1{ __ccool_#1 } \cs_new_protected:Nn \__ccool_prop_new:n { \prop_new:c{ \__ccool_prop_name:n {#1} } } \cs_new_protected:Nn \__ccool_seq_from_prop:NNn { \cs_set_protected:Nn \__ccool_seq_from_prop:n { \seq_gput_right:No #1 { \prop_item:cn{#3}{##1} } } \seq_map_function:NN #2 \__ccool_seq_from_prop:n } \NewDocumentCommand{ \CcoolClear } { D<>{\g__ccool_option_param_tl} } { \__ccool_prop_clear_new_map:n{#1} } \NewDocumentCommand{\CcoolHook}{}{\c_empty_tl} \ProvideDocumentCommand \CcoolLambda { O{m} m } { \erw_lambda:nnn \DeclareDocumentCommand { #1 } { #2 } } \NewDocumentCommand{ \CcoolOption } { O{ And, Expans, File, Inner, Param, Outer, Separ, Write } } { \keys_set:nn{ __ccool }{#1} } \keys_define:nn { __ccool } { And .code:n = { \__ccool_lang_and_update:e{ #1 } }, And .default:n = { \c__ccool_lang_and_tl }, And .initial:n = { \c__ccool_lang_and_tl }, Expans .multichoices:nn = { eo, ee, ex, xo, xe, xx } { \tl_gset_eq:NN \g__ccool_option_expans_tl \l_keys_choice_tl }, Expans .default:n = { xo }, Expans .initial:n = { xo }, File .code:n = { \tl_gset:Nx \g__ccool_log_file_tl{#1} }, File .default:n = { \erw_sys_jobnametimestamp: }, File .initial:n = { \erw_sys_jobnametimestamp: }, Inner .code:n={ \__ccool_option_inner:n{#1} \exp_last_unbraced:Nf \__ccool_make_ccool:nnnn { { \g__ccool_option_param_tl } { \g__ccool_option_inner_tl } { \g__ccool_option_separ_tl } { \g__ccool_option_outer_tl } } }, Inner .value_required:n = false, Inner .default:n = {####1}, Inner .initial:n = {####1}, Param .code:n={ \__ccool_option_param:n{#1} \exp_last_unbraced:Nf \__ccool_make_ccool:nnnn { { \g__ccool_option_param_tl } { \g__ccool_option_inner_tl } { \g__ccool_option_separ_tl } { \g__ccool_option_outer_tl } } }, Param .value_required:n = false, Param .default:n = { Default }, Param .initial:n = { Default }, Outer .code:n={ \__ccool_option_outer:n{#1} \exp_last_unbraced:Nf \__ccool_make_ccool:nnnn { { \g__ccool_option_param_tl } { \g__ccool_option_inner_tl } { \g__ccool_option_separ_tl } { \g__ccool_option_outer_tl } } }, Outer .value_required:n = false, Outer .default:n = { \ensuremath{####1} }, Outer .initial:n = { \ensuremath{####1} }, Separ .code:n={ \__ccool_option_separ:n{#1} \exp_last_unbraced:Nf \__ccool_make_ccool:nnnn { { \g__ccool_option_param_tl } { \g__ccool_option_inner_tl } { \g__ccool_option_separ_tl } { \g__ccool_option_outer_tl } } }, Separ .value_required:n = false, Separ .default:n = { \c__ccool_option_separ_default_tl }, Separ .initial:n = { \c__ccool_option_separ_default_tl }, Write .code:n = { \bool_if:nTF{#1} {\__ccool_log_open:} {\__ccool_log_close:} }, Write .value_required:n = false, Write .default:n = \BooleanFalse, Write .initial:n = \BooleanFalse } \NewDocumentCommand{\CcoolRead} {o} { \IfValueTF{#1} {\__ccool_log_read:e{#1}} {\__ccool_log_read:} } \NewDocumentCommand{\CcoolVers} {} {\use:c{ver@ccool.sty}} \ExplSyntaxOff %% %% Copyright (C) 2020 by Erwann Rogard %% %% This work may be distributed and/or modified under the %% conditions of the LaTeX Project Public License (LPPL), either %% version 1.3c of this license or (at your option) any later %% version. The latest version of this license is in the file: %% %% http://www.latex-project.org/lppl.txt %% %% This work is "maintained" (as per LPPL maintenance status) by %% Erwann Rogard. %% %% This work consists of the file ccool.dtx and the derived files: %% ccool.sty, and ccool.pdf. %% %% %% End of file `ccool.sty'.