diff options
Diffstat (limited to 'Master/texmf-dist/tex/latex/xsim/xsim.collections.code.tex')
-rw-r--r-- | Master/texmf-dist/tex/latex/xsim/xsim.collections.code.tex | 395 |
1 files changed, 395 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/latex/xsim/xsim.collections.code.tex b/Master/texmf-dist/tex/latex/xsim/xsim.collections.code.tex new file mode 100644 index 00000000000..8bf0c0bc705 --- /dev/null +++ b/Master/texmf-dist/tex/latex/xsim/xsim.collections.code.tex @@ -0,0 +1,395 @@ +% ---------------------------------------------------------------------------- +% the XSIM package - collections module +% +% eXercise Sheets IMproved +% +% ---------------------------------------------------------------------------- +% Clemens Niederberger +% Web: https://github.com/cgnieder/xsim +% E-Mail: contact@mychemistry.eu +% ---------------------------------------------------------------------------- +% Copyright 2017 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{collections}{collect exercises and print collected exercises} + +\xsim_load_modules:n {base} + +\prop_new:N \g__xsim_collections_prop +\bool_new:N \l____xsim_active_bool + +\msg_new:nnn {xsim} {collection-exists} + { + The~ collection~ `#1'~ you're~ trying~ to~ define~ \msg_line_context: + \c_space_tl already~ exists. + } + +\msg_new:nnn {xsim} {collection-active} + { + You~ can't~ print~ collection~ `#1'~ while~ it~ is~ still~ active~ + \msg_line_context: + } + +\msg_new:nnn {xsim} {unknown-collection} + { + You're~ trying~ to~ use~ the~ collection~ `#1'~ \msg_line_context: + \c_space_tl but~ no~ collection~ with~ that~ name~ exists.~ You~ need~ to~ + define~ it~ first! + } + +\msg_new:nnn {xsim} {print-collection-choice} + { + The~ choice~ `#1'~ for~ the~ option~ `print-collection/print'~ does~ not~ + exist.~ I'm~ using~ `exercises'~ instead~ \msg_line_context: + } + +% ---------------------------------------------------------------------------- + +% #1: collection name +\cs_new_protected:Npn \xsim_new_collection:n #1 + { + \xsim_if_collection_exists:nTF {#1} + { \msg_error:nnn {xsim} {collection-exists} {#1} } + { + \xsim_verbose:n { Declaring~ new~ collection~ `#1'. } + \prop_gput:Nnn \g__xsim_collections_prop {#1} { \c_false_bool } + \xsim_new_list:n {collection:#1} + \seq_new:c {g__xsim_collection_#1_seq} + } + } + +% #1: collection name +\prg_new_conditional:Npnn \xsim_if_collection_exists:n #1 {T,F,TF} + { + \prop_if_in:NnTF \g__xsim_collections_prop {#1} + { \prg_return_true: } + { \prg_return_false: } + } + +\xsim_new_collection:n {all~ exercises} + +\cs_new_protected:Npn \xsim_foreach_collection:n #1 + { \prop_map_inline:Nn \g__xsim_collections_prop {#1} } + +% ---------------------------------------------------------------------------- + +% #1: collection name +% #2: type +\cs_new_protected:Npn \xsim_activate_collection:nn #1#2 + { + \xsim_if_collection_active:nTF {#1} + { % TODO: error + } + { + \xsim_verbose:n { Activating~ collection~ `#1'. } + \prop_gput:Nnn \g__xsim_collections_prop {#1} { \c_true_bool } + \tl_if_blank:nF {#2} + { \seq_gput_right:cn {g__xsim_collection_#1_seq} {#2} } + } + } + +\cs_new_protected:Npn \xsim_activate_collection:n #1 + { \xsim_activate_collection:nn {#1} {} } + +% #1: collection name +\cs_new_protected:Npn \xsim_deactivate_collection:n #1 + { + \xsim_if_collection_active:nTF {#1} + { + \xsim_verbose:n { Deactivating~ collection~ `#1'. } + \prop_gput:Nnn \g__xsim_collections_prop {#1} { \c_false_bool } + \seq_gclear:c {g__xsim_collection_#1_seq} + } + { % TODO: warning + } + } + +% start collection for an exercise type: +% #1: collection name +% #2: type +\cs_new_protected:Npn \xsim_start_collection:nn #1#2 + { + \group_begin: + \xsim_if_collection_exists:nF {#1} + { \msg_error:nnn {xsim} {unknown-collection} {#1} } + \xsim_activate_collection:nn {#1} {#2} + \xsim_setup:n { #2/print = false } + } + +% start collection for all exercise types: +% #1: collection name +\cs_new_protected:Npn \xsim_start_collection:n #1 + { + \group_begin: + \xsim_if_collection_exists:nF {#1} + { \msg_error:nnn {xsim} {unknown-collection} {#1} } + \xsim_activate_collection:n {#1} + \xsim_foreach_exercise_type:n + { \xsim_setup:n { ##1/print = false } } + } + +% stop collection: +% #1: collection name +\cs_new_protected:Npn \xsim_stop_collection:n #1 + { + \xsim_deactivate_collection:n {#1} + \group_end: + } + +% ---------------------------------------------------------------------------- + +% #1: collection name +% #2: type +% #3: id +\cs_new_protected:Npn \xsim_add_to_collection:nnn #1#2#3 + { + \seq_if_empty:cTF {g__xsim_collection_#1_seq} + { \__xsim_add_to_collection:nnn {#1} {#2} {#3} } + { + \seq_if_in:cnT {g__xsim_collection_#1_seq} {#2} + { \__xsim_add_to_collection:nnn {#1} {#2} {#3} } + } + } + +% #1: collection name +% #2: type +% #3: id +\cs_new_protected:Npn \__xsim_add_to_collection:nnn #1#2#3 + { + \xsim_verbose:n + { Adding~ exercise~ type~ `#2'~ id~ `#3'~ to~ collection~ `#1'. } + \xsim_add_to_list:nn {collection:#1} {#2-#3} + } + +\cs_new:Npn \xsim_collection_count:n #1 + { \xsim_list_count:n {collection:#1} } + +% #1: type +% #2: id +\cs_new_protected:Npn \xsim_update_collections:nn #1#2 + { + \xsim_if_insert_mode:F + { + \xsim_exercise_if_use:nnT {#1} {#2} + { \xsim_add_to_collection:nnn {all~ exercises} {#1} {#2} } + \xsim_foreach_collection:n + { + \xsim_exercise_if_use:nnTF {#1} {#2} + { + \xsim_if_collection_active:nT {##1} + { \xsim_add_to_collection:nnn {##1} {#1} {#2} } + } + { \xsim_remove_from_list:nn {collection:##1} {#1-#2} } + } + } + } +\cs_generate_variant:Nn \xsim_update_collections:nn {nV} + +% #1: collection name +\cs_new_protected:Npn \xsim_get_collections: + { + \xsim_foreach_collection:n + { + \xsim_foreach_list_entry:nn {collection:##1} + { \__xsim_list_to_collection:nww {##1} ####1 \q_stop } + } + } + +\cs_new_protected:Npn \__xsim_list_to_collection:nww #1#2-#3 \q_stop + { \xsim_add_to_collection:nnn {#1} {#2} {#3} } + +% ---------------------------------------------------------------------------- + +% #1: collection name +% #2: type +% #3: id +\prg_new_conditional:Npnn \xsim_if_in_collection:nnn #1#2#3 {T,F,TF} + { + \xsim_if_in_list:nnTF {collection:#1} {#2-#3} + { \prg_return_true: } + { \prg_return_false: } + } +\cs_generate_variant:Nn \xsim_if_in_collection:nnnTF {V} +\cs_generate_variant:Nn \xsim_if_in_collection:nnnT {x,nV} + +% ---------------------------------------------------------------------------- + +\bool_new:N \l__xsim_printcollection_headings_bool +\tl_new:N \l__xsim_printcollection_headings_template_tl +\tl_new:N \l__xsim_print_collection_choice_tl + +\keys_define:nn {xsim/print-collection} + { + headings .bool_set:N = \l__xsim_printcollection_headings_bool , + headings .initial:n = false , + headings-template .tl_set:N = \l__xsim_printcollection_headings_template_tl , + headings-template .initial:n = collection , + print .choice: , + print/exercises .code:n = + \tl_set:Nn \l__xsim_print_collection_choice_tl {exercise} , + print/solutions .code:n = + \tl_set:Nn \l__xsim_print_collection_choice_tl {solution} , + print/both .code:n = + \tl_set:Nn \l__xsim_print_collection_choice_tl {both} , + print/unknown .code:n = + \msg_warning:nnn {xsim} {print-collection-choice} {#1} + \tl_set:Nn \l__xsim_print_collection_choice_tl {exercise} , + print .initial:n = exercises + } + +% #1: options +% #2: collection name +\cs_new_protected:Npn \xsim_print_collection:nn #1#2 + { + \xsim_if_collection_active:nTF {#2} + { \msg_error:nnn {xsim} {collection-active} {#2} } + { + \xsim_verbose:x + { + Printing~ + \l__xsim_print_collection_choice_tl \c_space_tl + \str_if_eq:onT { \l__xsim_print_collection_choice_tl } {both} + { exercises~ and~ solutions~ } + of~ collection~ `#2' + } + \group_begin: + \keys_set:nn {xsim/print-collection} {#1} + \tl_set:Nn \ExerciseCollection {#2} + \xsim_foreach_exercise_type:n + { + \tl_set:Nn \ExerciseType {##1} + \bool_if:NT \l__xsim_printcollection_headings_bool + { + \bool_set_false:N \l__xsim_tmpa_bool + \xsim_foreach_exercise_id:n + { + \xsim_if_in_collection:nnnT {#2} {##1} {####1} + { + \tl_if_eq:VnTF + \l__xsim_print_collection_choice_tl + {both} + { + \xsim_if_exercise_exists:nnT {##1} {####1} + { \bool_set_true:N \l__xsim_tmpa_bool } + } + { + \use:c + { + xsim_if_ + \l__xsim_print_collection_choice_tl + _exists:nnT + } + {##1} + {####1} + { \bool_set_true:N \l__xsim_tmpa_bool } + } + } + } + \bool_if:NT \l__xsim_tmpa_bool + { + \xsim_use_template:nV + {heading} + \l__xsim_printcollection_headings_template_tl + } + } + \xsim_foreach_exercise_id:n + { + \xsim_if_in_collection:nnnT {#2} {##1} {####1} + { + \tl_if_eq:VnTF + \l__xsim_print_collection_choice_tl + {both} + { + \xsim_if_exercise_exists:nnT {##1} {####1} + { \xsim_insert:nnnn {##1} {####1} {} {exercise} } + \xsim_if_solution_exists:nnT {##1} {####1} + { \xsim_insert:nnnn {##1} {####1} {} {solution} } + } + { + \use:c + { + xsim_if_ + \l__xsim_print_collection_choice_tl + _exists:nnT + } + {##1} + {####1} + { + \xsim_insert:nnnV + {##1} + {####1} + {} + \l__xsim_print_collection_choice_tl + } + } + } + } + } + \group_end: + } + } + +% ---------------------------------------------------------------------------- + +% #1: collection name +\prg_new_conditional:Npnn \xsim_if_collection_active:n #1 {T,F,TF} + { + \prop_if_in:NnTF \g__xsim_collections_prop {#1} + { + \bool_if:nTF + { + !\str_if_eq_x_p:nn {#1} {all~ exercises} && + \prop_item:Nn \g__xsim_collections_prop {#1} + } + { \prg_return_true: } + { \prg_return_false: } + } + { \prg_return_false: } + } + +\prg_new_protected_conditional:Npnn \xsim_if_collections_active: {T,F,TF} + { + \bool_set_false:N \l____xsim_active_bool + \prop_map_inline:Nn \g__xsim_collections_prop + { + \xsim_if_collection_active:nT {##1} + { + \bool_set_true:N \l____xsim_active_bool + \prop_map_break: + } + } + \bool_if:NTF \l____xsim_active_bool + { \prg_return_true: } + { \prg_return_false: } + } + +% ---------------------------------------------------------------------------- + +\AtBeginDocument + { + \xsim_get_collections: + \xsim_activate_collection:n {all~ exercises} + } + +\AtEndDocument + { + \xsim_deactivate_collection:n {all~ exercises} + \xsim_foreach_collection:n { \xsim_update_list:n {collection:#1} } + } + +% ---------------------------------------------------------------------------- +\tex_endinput:D |