% ---------------------------------------------------------------------------- % the XSIM package - base module % % eXercise Sheets IMproved % % ---------------------------------------------------------------------------- % Clemens Niederberger % Web: https://github.com/cgnieder/xsim % E-Mail: contact@mychemistry.eu % ---------------------------------------------------------------------------- % Copyright 2017--2020 Clemens Niederberger % % This work may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.3 % of this license or (at your option) any later version. % The latest version of this license is in % http://www.latex-project.org/lppl.txt % and version 1.3 or later is part of all distributions of LaTeX % version 2005/12/01 or later. % % This work has the LPPL maintenance status `maintained'. % % The Current Maintainer of this work is Clemens Niederberger. % ---------------------------------------------------------------------------- % If you have any ideas, questions, suggestions or bugs to report, please % feel free to contact me. % ---------------------------------------------------------------------------- \XSIMmodule{base}{basic functionality of the package} \tl_new:N \g_xsim_end_document_hook_tl \tl_new:N \g_xsim_begin_document_hook_tl \AtBeginDocument { \tl_use:N \g_xsim_begin_document_hook_tl } \AtEndDocument { \tl_use:N \g_xsim_end_document_hook_tl } \cs_new_protected:Npn \xsim_at_begin_document:n #1 { \tl_gput_right:Nn \g_xsim_begin_document_hook_tl {#1} } \cs_new_protected:Npn \xsim_at_end_document:n #1 { \tl_gput_right:Nn \g_xsim_end_document_hook_tl {#1} } % ---------------------------------------------------------------------------- \xsim_load_modules:n {auxfile} % ---------------------------------------------------------------------------- % variants of kernel functions: \cs_generate_variant:Nn \seq_set_split:Nnn {Nnx,NV} \cs_generate_variant:Nn \seq_gset_split:Nnn {c,cVx,cnx} \cs_generate_variant:Nn \seq_use:Nn {cV} \cs_generate_variant:Nn \seq_count:N {c} \cs_generate_variant:Nn \seq_if_empty:NT {c} \cs_generate_variant:Nn \seq_if_in:NnT {cV} \cs_generate_variant:Nn \seq_gremove_all:Nn {cV} \cs_generate_variant:Nn \seq_gput_right:Nn {cV} \cs_generate_variant:Nn \prop_put:Nnn {Nnx,cxx} \cs_generate_variant:Nn \prop_gput:Nnn {Nx,Nnx,cxx} \cs_generate_variant:Nn \prop_item:Nn {c} \cs_generate_variant:Nn \prop_if_in:NnTF {Nx} \cs_generate_variant:Nn \use:nn {nx} \cs_generate_variant:Nn \file_input:n {V,x} \cs_generate_variant:Nn \file_if_exist:nT {V,x} \cs_generate_variant:Nn \file_if_exist:nTF {V} \cs_generate_variant:Nn \msg_error:nnnnn {nnnxx} \cs_generate_variant:Nn \keys_define:nn {nx} \cs_generate_variant:Nn \keys_set:nn {xn} \cs_generate_variant:Nn \tl_mixed_case:n {x,f} \cs_generate_variant:Nn \tl_if_eq:nnTF {ff,V} \cs_generate_variant:Nn \tl_if_eq:nnT {x} \cs_generate_variant:Nn \tl_if_blank:nTF {f} \cs_generate_variant:Nn \tl_set_rescan:Nnn {Nnx} \cs_generate_variant:Nn \iow_now:Nn {NV} \cs_generate_variant:Nn \str_if_eq:nnT {x} \cs_generate_variant:Nn \str_if_eq:nnF {xx} \cs_generate_variant:Nn \str_if_eq_p:nn {e} \cs_generate_variant:Nn \prg_new_protected_conditional:Npnn {c} % ---------------------------------------------------------------------------- % temporary variables: \tl_new:N \l__xsim_tmpa_tl \tl_new:N \l__xsim_tmpb_tl \tl_new:N \l__xsim_tmpc_tl \tl_new:N \l__xsim_tmpd_tl \str_new:N \l__xsim_tmpa_str \str_new:N \l__xsim_tmpb_str \str_new:N \l__xsim_tmpc_str \bool_new:N \l__xsim_tmpa_bool \bool_new:N \l__xsim_tmpb_bool \bool_new:N \l__xsim_tmpc_bool \dim_new:N \l__xsim_tmpa_dim \dim_new:N \l__xsim_tmpb_dim \dim_new:N \l__xsim_tmpc_dim \seq_new:N \l__xsim_tmpa_seq \seq_new:N \l__xsim_tmpb_seq \seq_new:N \l__xsim_tmpc_seq \int_new:N \l__xsim_tmpa_int \int_new:N \l__xsim_tmpb_int \int_new:N \l__xsim_tmpc_int \box_new:N \l__xsim_tmpa_box \box_new:N \l__xsim_tmpb_box \box_new:N \l__xsim_tmpc_box \clist_new:N \l__xsim_tmpa_clist \clist_new:N \l__xsim_tmpb_clist \clist_new:N \l__xsim_tmpc_clist % ---------------------------------------------------------------------------- \prg_new_conditional:Npnn \xsim_if_komascript: {T,F,TF} { \cs_if_exist:cTF {KOMAClassName} { \prg_return_true: } { \prg_return_false: } } % ---------------------------------------------------------------------------- \prg_new_conditional:Npnn \xsim_if_final: {p,T,F,TF} { \bool_if:NTF \g__xsim_final_bool { \prg_return_true: } { \prg_return_false: } } \prg_new_conditional:Npnn \xsim_if_verbose: {p,T,F,TF} { \bool_if:NTF \g__xsim_verbose_bool { \prg_return_true: } { \prg_return_false: } } \prg_new_conditional:Npnn \xsim_if_debug: {p,T,F,TF} { \bool_if:NTF \g__xsim_debug_bool { \prg_return_true: } { \prg_return_false: } } \prg_new_conditional:Npnn \xsim_if_package_blank: {p,T,F,TF} { \bool_if:NTF \g__xsim_blank_bool { \prg_return_true: } { \prg_return_false: } } \prg_new_conditional:Npnn \xsim_if_rerun: {p,T,F,TF} { \bool_if:NTF \g__xsim_rerun_bool { \prg_return_true: } { \prg_return_false: } } \prg_new_conditional:Npnn \xsim_if_write_to_files: {p,T,F,TF} { \bool_if:NTF \g__xsim_write_to_file_bool { \prg_return_true: } { \prg_return_false: } } \prg_new_conditional:Npnn \xsim_if_clear_aux: {p,T,F,TF} { \xsim_if_final:TF { \prg_return_false: } { \bool_if:NTF \g_xsim_clear_aux_bool { \prg_return_true: } { \prg_return_false: } } } \cs_new_protected:Npn \xsim_verbose:n #1 { \xsim_if_verbose:T { \msg_info:nnn {xsim} {verbose} {#1} } } \cs_generate_variant:Nn \xsim_verbose:n {x} \cs_new_protected:Npn \xsim_rerun: { \bool_gset_true:N \g__xsim_rerun_bool } \prg_new_conditional:Npnn \xsim_if_chapter: {p,T,F,TF} { \bool_lazy_and:nnTF { \cs_if_exist_p:N \chapter } { \cs_if_exist_p:N \c@chapter } { \prg_return_true: } { \prg_return_false: } } % ---------------------------------------------------------------------------- % #1: macro name % #2: 0 to 9 times `n' (= number of arguments of internal item) % #3: code; may contain a suiting \__xsim_loop_item: \cs_new_protected:Npn \xsim_define_loop_macro:Nnn #1#2#3 { \xsim_verbose:n { Defining~ loop~ macro~ #1 } \cs_new_protected:Npn #1 ##1##2 { \cs_set:cn {__xsim_loop_item:#2} {##2} #3 } } % ---------------------------------------------------------------------------- \msg_new:nnn {xsim} {attribute-not-set} { The~ attribute~ `#1'~ is~ not~ set~ \msg_line_context: } % #1: attribute % #2: item \cs_new_protected:Npn \xsim_attribute_new:nn #1#2 { \cs_new:cpn {____xsim_attribute_ \tl_to_str:n {#1::#2} :} {} } % #1: attribute % #2: item % #3: value \cs_new_protected:Npn \xsim_attribute_set:nnn #1#2#3 { \cs_gset:cpx {____xsim_attribute_ \tl_to_str:n {#1::#2} :} { \exp_not:n { \exp_not:n {#3} } } } \cs_generate_variant:Nn \xsim_attribute_set:nnn {nnx} % #1: attribute % #2: item \cs_new_protected:Npn \xsim_attribute_unset:nn #1#2 { \cs_undefine:c {____xsim_attribute_ \tl_to_str:n {#1::#2} :} } % #1: attribute % #2: item \cs_new:Npn \xsim_attribute_get:nn #1#2 { \cs_if_exist:cTF {____xsim_attribute_ \tl_to_str:n {#1::#2} :} { \use:c {____xsim_attribute_ \tl_to_str:n {#1::#2} :} } { \xsim_if_debug:T { \msg_expandable_error:nnn {xsim} {attribute-not-set} {#1::#2} } } } % #1: attribute % #2: item \prg_new_conditional:Npnn \xsim_attribute_if_set:nn #1#2 {p,T,F,TF} { \cs_if_exist:cTF {____xsim_attribute_ \tl_to_str:n {#1::#2} :} { \prg_return_true: } { \prg_return_false: } } % #1: attribute % #2: item \prg_new_conditional:Npnn \__xsim_if_attribute_eq:nnn #1#2#3 {p,T,F,TF} { \tl_if_eq:enTF { \use:c {____xsim_attribute_ \tl_to_str:n {#1::#2} :} } {#3} { \prg_return_true: } { \prg_return_false: } } % #1: attribute % #2: item \cs_new_protected:Npn \xsim_attribute_show:nn #1#2 { \iow_term:n {} \iow_term:x { \c_space_tl \c_space_tl \tl_to_str:n {#1::#2} \c_space_tl \c_space_tl == \c_space_tl \c_space_tl {\use:c {____xsim_attribute_ \tl_to_str:n {#1::#2} :}} } \iow_term:n {} } % ---------------------------------------------------------------------------- \cs_new_protected:Npn \xsim_setup:n #1 { \keys_set:nn {xsim} {#1} } % ---------------------------------------------------------------------------- \file_input_stop: 2020/03/15 - alternative to property lists for performance optimizations 2020/03/22 - fix bug in new attribute mechanism which was a problem when `no-files` has been used