summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/latex/xsim/xsim.collections.code.tex
diff options
context:
space:
mode:
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.tex395
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