summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/latex/xsim/xsim.exercises.code.tex
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/latex/xsim/xsim.exercises.code.tex')
-rw-r--r--Master/texmf-dist/tex/latex/xsim/xsim.exercises.code.tex515
1 files changed, 515 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/latex/xsim/xsim.exercises.code.tex b/Master/texmf-dist/tex/latex/xsim/xsim.exercises.code.tex
new file mode 100644
index 00000000000..59434ec3071
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/xsim/xsim.exercises.code.tex
@@ -0,0 +1,515 @@
+% ----------------------------------------------------------------------------
+% the XSIM package - exercises 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{exercises}{main exercises definitions}
+
+\xsim_load_modules:n
+ {
+ base, properties, environments, templates, solutions, tags, goals,
+ collections
+ }
+
+\seq_new:N \l__xsim_parameters_seq
+\seq_new:N \l__xsim_fixed_parameters_seq
+\seq_new:N \l__xsim_mandatory_parameters_seq
+\prop_new:N \g__xsim_exercises_prop
+\int_gzero_new:N \g_xsim_id_int
+\int_gzero_new:N \g_xsim_max_id_int
+\tl_new:N \l_xsim_current_id_tl
+\tl_new:N \g_xsim_exercise_id_tl
+\tl_new:N \ExerciseID
+\bool_new:N \l____xsim_print_bool
+
+% ----------------------------------------------------------------------------
+
+\msg_new:nnn {xsim} {parameter-fixed}
+ {
+ You~ tried~ to~ set~ parameter~ `#2'~ for~ type~ `#1'~ \msg_line_context:
+ . ~ However,~ parameter~ `#2'~ is~ a~ fixed~ parameter~ that~ already~
+ has~ been~ set~ for~ type~ `#1'.~ Its~ value~ can't~ be~ changed!
+ }
+
+\msg_new:nnn {xsim} {type-exists}
+ {
+ You~ try~ to~ define~ exercise~ type~ `#1'~ \msg_line_context: .~
+ However,~ the~ exercise~ type~ `#1'~ already~ exists.
+ }
+
+\msg_new:nnn {xsim} {mandatory-parameter}
+ {
+ You~ forget~ to~ set~ the~ mandatory~ parameter~ `#1'~ when~ defining~
+ exercise~ type~ `#2'.
+ }
+
+% ----------------------------------------------------------------------------
+
+\xsim_new_list:n {types}
+
+% #1: true|false (fixed parameter)
+% #2: true|false (mandatory parameter)
+% #3: parameter name
+\cs_new_protected:Npn \xsim_declare_parameter:nnn #1#2#3
+ {
+ \xsim_verbose:n { Declaring~ parameter~ `#3'. }
+ \xsim_if_parameter_exist:nF {#3}
+ {
+ \seq_put_right:Nn \l__xsim_parameters_seq {#3}
+ \bool_if:cT {c_#1_bool}
+ { \seq_put_right:Nn \l__xsim_fixed_parameters_seq {#3} }
+ \bool_if:cT {c_#2_bool}
+ { \seq_put_right:Nn \l__xsim_mandatory_parameters_seq {#3} }
+ }
+ }
+
+\cs_new_protected:Npn \xsim_remove_parameter:n #1
+ {
+ \xsim_verbose:n { Removing~ parameter~ `#1'. }
+ \xsim_if_parameter_exist:nT {#1}
+ { \seq_remove_all:Nn \l__xsim_parameters_seq {#1} }
+ }
+
+\prg_new_conditional:Npnn \xsim_if_parameter_exist:n #1 {p,T,F,TF}
+ {
+ \seq_if_in:NnTF \l__xsim_parameters_seq {#1}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+\cs_generate_variant:Nn \xsim_if_parameter_exist:nT {x}
+
+\prg_new_conditional:Npnn \xsim_if_parameter_fixed:n #1 {p,T,F,TF}
+ {
+ \seq_if_in:NnTF \l__xsim_fixed_parameters_seq {#1}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+
+% #1: type
+% #2: csv list of parameters
+\cs_new_protected:Npn \xsim_set_parameters:nn #1#2
+ {
+ \clist_map_inline:nn {#2}
+ {
+ \seq_set_split:Nnx \l__xsim_tmpa_seq {=} { \tl_trim_spaces:n {##1} }
+ \xsim_set_parameter:nxx {#1}
+ { \seq_item:Nn \l__xsim_tmpa_seq {1} }
+ { \seq_item:Nn \l__xsim_tmpa_seq {2} }
+ }
+ }
+\cs_generate_variant:Nn \xsim_set_parameters:nn {nx}
+
+% #1: type
+\cs_new_protected:Npn \xsim_check_mandatory_parameters:n #1
+ {
+ \seq_map_inline:Nn \l__xsim_mandatory_parameters_seq
+ {
+ \xsim_if_parameter:nnF {#1} {##1}
+ { \msg_error:nnnn {xsim} {mandatory-parameter} {##1} {#1} }
+ }
+ }
+
+% #1: type
+\prg_new_conditional:Npnn \xsim_if_type:n #1 {p,T,F,TF}
+ {
+ \prop_if_exist:cTF {l__xsim_#1_type_parameters_prop}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+
+% #1: type
+% #2: parameter
+% #3: value
+\cs_new_protected:Npn \xsim_set_parameter:nnn #1#2#3
+ {
+ \xsim_if_parameter_exist:nT {#2}
+ {
+ \xsim_if_parameter_fixed:nTF {#1}
+ {
+ \xsim_if_parameter:nnTF {#1} {#2}
+ {
+ \msg_warning:nnnn {xsim} {parameter-fixed} {#1} {#2}
+ \xsim_verbose:n
+ {
+ Not~ setting~ already~ set~ and~ fixed~ parameter~ `#2'~
+ for~ type~ `#1'.
+ }
+ }
+ {
+ \xsim_verbose:n
+ { Setting~ parameter~ `#2'~ for~ type~ `#1'~ to~ `#3'. }
+ \prop_put:cnn {l__xsim_#1_type_parameters_prop} {#2} {#3}
+ }
+ }
+ {
+ \xsim_verbose:n
+ { Setting~ parameter~ `#2'~ for~ type~ `#1'~ to~ `#3'. }
+ \prop_put:cnn {l__xsim_#1_type_parameters_prop} {#2} {#3}
+ }
+ }
+ }
+\cs_generate_variant:Nn \xsim_set_parameter:nnn {nnx,nxx}
+
+% #1: type
+% #2: parameter
+\cs_new:Npn \xsim_get_parameter:nn #1#2
+ { \prop_item:cn {l__xsim_#1_type_parameters_prop} {#2} }
+\cs_generate_variant:Nn \xsim_get_parameter:nn {o}
+
+\prg_new_conditional:Npnn \xsim_if_parameter:nn #1#2 {p,T,F,TF}
+ {
+ \prop_if_in:cnTF {l__xsim_#1_type_parameters_prop} {#2}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+
+% ----------------------------------------------------------------------------
+% inside the argument `#1' refers to the type
+\cs_new_protected:Npn \xsim_foreach_exercise_type:n #1
+ { \xsim_foreach_new_list_entry:nn {types} {#1} }
+
+\cs_new_protected:Npn \xsim_foreach_exercise_id:n #1
+ { \int_step_inline:nnnn {1} {1} { \g_xsim_max_id_int } {#1} }
+
+\cs_new:Npn \__xsim_loop_item:nnnnnn #1#2#3#4#5#6 {}
+\cs_generate_variant:Nn \__xsim_loop_item:nnnnnn {VVxxxx}
+
+% #1: type
+% #2: id
+% #3: boolean property
+\cs_new:Npn \__xsim_deliver_exercise_details:nnn #1#2#3
+ {
+ \xsim_if_in_list:nnT {#3} {#1-#2=={true}}
+ {
+ \tl_set_rescan:Nnx \l__xsim_tmpa_tl {} {#1}
+ \tl_set_rescan:Nnx \l__xsim_tmpb_tl {} {#2}
+ \__xsim_loop_item:VVxxxx
+ \l__xsim_tmpa_tl % #1
+ \l__xsim_tmpb_tl % #2
+ { \xsim_get_property:nnn {#1} {#2} {counter} } % #3
+ { \xsim_get_property:nnn {#1} {#2} {subtitle} } % #4
+ { \xsim_get_property:nnn {#1} {#2} {points} } % #5
+ { \xsim_get_property:nnn {#1} {#2} {bonus-points} } % #6
+ }
+ }
+
+% #1: boolean property
+% #2: loop code
+\xsim_define_loop_macro:Nnn \xsim_foreach_exercise_type_id:nn
+ {nnnnnn}
+ {
+ \xsim_foreach_exercise_type:n
+ {
+ \xsim_foreach_exercise_id:n
+ { \__xsim_deliver_exercise_details:nnn {##1} {####1} {#1} }
+ }
+ }
+
+\xsim_define_loop_macro:Nnn \xsim_foreach_exercise_id_type:nn
+ {nnnnnn}
+ {
+ \xsim_foreach_exercise_id:n
+ {
+ \xsim_foreach_exercise_type:n
+ { \__xsim_deliver_exercise_details:nnn {####1} {##1} {#1} }
+ }
+ }
+
+\cs_new_protected:Npn \xsim_define_exercise_type_variables:n #1
+ {
+ \prop_new:c {l__xsim_#1_type_parameters_prop}
+ \bool_new:c {l__xsim_#1_solution_print_bool}
+ \bool_new:c {l__xsim_#1_exercise_print_bool}
+ \bool_new:c {l__xsim_#1_exercise_use_bool}
+ }
+
+\cs_new_protected:Npn \xsim_define_counters:n #1
+ {
+ \xsim_verbose:n { Defining~ counters~ for~ new~ exercise~ type~ `#1' }
+ \cs_if_exist:cF { c@ \xsim_get_parameter:nn {#1} {counter} }
+ { \newcounter { \xsim_get_parameter:nn {#1} {counter} } }
+ \cs_if_exist:cF { c@ \xsim_get_parameter:nn {#1} {solution-counter} }
+ { \newcounter { \xsim_get_parameter:nn {#1} {solution-counter} } }
+ \cs_if_exist:cF { c@ number of \xsim_get_parameter:nn {#1} {exercise-env} s }
+ { \newcounter { number of \xsim_get_parameter:nn {#1} {exercise-env} s } }
+ }
+
+% #1: type
+% #2: id
+\cs_new_protected:Npn \xsim_step_exercise_counter:nn #1#2
+ {
+ \refstepcounter { \xsim_get_parameter:nn {#1} {counter} }
+ \xsim_set_properties:nnx {#1} {#2}
+ {
+ counter = \use:c { the \xsim_get_parameter:nn {#1} {counter} } ,
+ counter-value = \arabic { \xsim_get_parameter:nn {#1} {counter} }
+ }
+ }
+\cs_generate_variant:Nn \xsim_step_exercise_counter:nn {nV}
+
+% #1: type
+\cs_new_protected:Npn \xsim_declare_exercise_type:nn #1#2
+ {
+ \xsim_if_type:nTF {#1}
+ { \msg_error:nnn {xsim} {type-exists} {#1} }
+ {
+ \xsim_verbose:n { Declaring~ new~ exercise~ type~ `#1'. }
+ \xsim_define_exercise_type_variables:n {#1}
+ \xsim_add_to_list:nn {types} {#1}
+ \xsim_set_parameters:nn {#1} {#2}
+ \xsim_set_parameter:nnx {#1} {number}
+ { number of \xsim_get_parameter:nn {#1} {exercise-env} s }
+ \xsim_check_mandatory_parameters:n {#1}
+ \xsim_if_parameter:nnF {#1} {counter}
+ {
+ \xsim_set_parameters:nx {#1}
+ { counter = \xsim_get_parameter:nn {#1} {exercise-env} }
+ }
+ \xsim_if_parameter:nnF {#1} {solution-counter}
+ {
+ \xsim_set_parameters:nx {#1}
+ { solution-counter = \xsim_get_parameter:nn {#1} {solution-env} }
+ }
+ \xsim_define_counters:n {#1}
+ \xsim_verbose:n { Defining~ options~ for~ new~ exercise~ type~ `#1' }
+ \keys_define:nx {xsim}
+ {
+ \xsim_get_parameter:nn {#1} {solution-env} / print
+ .bool_set:N = \exp_not:c {l__xsim_#1_solution_print_bool} ,
+ \xsim_get_parameter:nn {#1} {solution-env} / print
+ .initial:n = false ,
+ \xsim_get_parameter:nn {#1} {exercise-env} / print
+ .bool_set:N = \exp_not:c {l__xsim_#1_exercise_print_bool} ,
+ \xsim_get_parameter:nn {#1} {exercise-env} / print
+ .initial:n = true ,
+ \xsim_get_parameter:nn {#1} {exercise-env} / use
+ .bool_set:N = \exp_not:c {l__xsim_#1_exercise_use_bool} ,
+ \xsim_get_parameter:nn {#1} {exercise-env} / use
+ .initial:n = true ,
+ \xsim_get_parameter:nn {#1} {exercise-env} / within .code:n =
+ \exp_not:N \@addtoreset { \xsim_get_parameter:nn {#1} {counter} } {####1},
+ \xsim_get_parameter:nn {#1} {exercise-env} / the-counter .code:n =
+ \cs_set:cpn {the \xsim_get_parameter:nn {#1} {counter} } {####1} ,
+ \xsim_get_parameter:nn {#1} {exercise-env} / template
+ .code:n = \xsim_set_parameter:nnn {#1} {exercise-template} {####1} ,
+ \xsim_get_parameter:nn {#1} {solution-env} / template
+ .code:n = \xsim_set_parameter:nnn {#1} {solution-template} {####1} ,
+ \xsim_get_parameter:nn {#1} {exercise-env} / name
+ .code:n = \xsim_set_parameter:nnn {#1} {exercise-name} {####1} ,
+ \xsim_get_parameter:nn {#1} {solution-env} / name
+ .code:n = \xsim_set_parameter:nnn {#1} {solution-name} {####1}
+ }
+ \xsim_new_environment:nn {#1} {exercise}
+ \xsim_new_environment:nn {#1} {solution}
+ }
+ }
+
+% #1: type
+% #2: id
+\prg_new_conditional:Npnn \xsim_if_exercise_exists:nn #1#2 {T,F,TF}
+ {
+ \__xsim_set_file_signature:nnn {#1} {#2} {exercise}
+ \file_if_exist:VTF \l__xsim_file_path_and_name_tl
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+\cs_generate_variant:Nn \xsim_if_exercise_exists:nnT {VV}
+
+% #1: type
+% #2: options
+\cs_new_protected:Npn \xsim_start_exercise:nn #1#2
+ {
+ \xsim_if_insert_mode:F
+ {
+ \int_gincr:N \g_xsim_id_int
+ \int_compare:nF { \g_xsim_max_id_int > \g_xsim_id_int }
+ { \int_gset_eq:NN \g_xsim_max_id_int \g_xsim_id_int }
+ \xsim_set_properties:nxx {#1} { \int_use:N \g_xsim_id_int }
+ {
+ print = true ,
+ use = true ,
+ \exp_not:n {#2} ,
+ id = \int_use:N \g_xsim_id_int ,
+ section-value = \arabic{section} ,
+ section = \thesection ,
+ page-value = \arabic{page} ,
+ page = \thepage ,
+ used = false
+ }
+ \xsim_if_property_exist:nT {chapter}
+ {
+ \xsim_set_properties:nxx {#1} { \int_use:N \g_xsim_id_int }
+ {
+ chapter-value = \arabic{chapter} ,
+ chapter = \thechapter
+ }
+ }
+ \tl_gclear:N \g_xsim_exercise_id_tl
+ \xsim_gsave_property:nxnN {#1} { \int_use:N \g_xsim_id_int } {id}
+ \g_xsim_exercise_id_tl
+ \tl_gset_eq:NN \ExerciseID \g_xsim_exercise_id_tl
+ \tl_gset:Nn \ExerciseType {#1}
+ \xsim_verbose:x
+ {
+ Starting~ exercise~ type~ `#1' with~ id~
+ ` \g_xsim_exercise_id_tl '.
+ }
+ \xsim_exercise_if_use:nVTF {#1} \g_xsim_exercise_id_tl
+ {
+ \stepcounter { \xsim_get_parameter:nn {#1} {number} }
+ % don't step if in active collection:
+ \xsim_if_collections_active:TF
+ {
+ \xsim_set_property:nVnn {#1} \g_xsim_exercise_id_tl
+ {print}
+ {false}
+ }
+ {
+ \xsim_step_exercise_counter:nV {#1} \g_xsim_exercise_id_tl
+ \xsim_set_property:nVnn {#1} \g_xsim_exercise_id_tl
+ {used}
+ {true}
+ }
+ \xsim_set_property:nVnn {#1} \g_xsim_exercise_id_tl
+ {use}
+ {true}
+ \xsim_update_goals:nV {#1} \g_xsim_exercise_id_tl
+ }
+ {
+ \xsim_set_properties:nVn {#1} \g_xsim_exercise_id_tl
+ { use = false , print = false }
+ }
+ \xsim_update_collections:nV {#1} \g_xsim_exercise_id_tl
+ }
+ }
+
+\cs_new_protected:Npn \xsim_stop_exercise:n #1 {}
+
+% ----------------------------------------------------------------------------
+% #1: type
+% #2: id
+\prg_new_protected_conditional:Npnn \xsim_exercise_if_print:nn #1#2 {T,F,TF}
+ {
+ \xsim_if_boolean_property:nnnTF {#1} {#2} {print!}
+ { \prg_return_true: }
+ {
+ \bool_set_true:N \l____xsim_print_bool
+ \bool_if:cF {l__xsim_#1_exercise_print_bool}
+ { \bool_set_false:N \l____xsim_print_bool }
+ \xsim_if_tagged:nnF {#1} {#2}
+ { \bool_set_false:N \l____xsim_print_bool }
+ \xsim_if_boolean_property:nnnF {#1} {#2} {print}
+ { \bool_set_false:N \l____xsim_print_bool }
+ \bool_if:NTF \l____xsim_print_bool
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+ }
+\cs_generate_variant:Nn \xsim_exercise_if_print:nnT {nV}
+\cs_generate_variant:Nn \xsim_exercise_if_print:nnTF {nV}
+
+% #1: type
+% #2: id
+\prg_new_protected_conditional:Npnn \xsim_exercise_if_use:nn #1#2 {T,F,TF}
+ {
+ \xsim_if_boolean_property:nnnTF {#1} {#2} {use!}
+ { \prg_return_true: }
+ {
+ \xsim_exercise_if_print:nnTF {#1} {#2}
+ { \prg_return_true: }
+ {
+ \bool_if:cTF {l__xsim_#1_exercise_use_bool}
+ {
+ \xsim_if_boolean_property:nnnTF {#1} {#2} {use}
+ {
+ \xsim_if_tagged:nnTF {#1} {#2}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+ { \prg_return_false: }
+ }
+ { \prg_return_false: }
+ }
+
+ }
+ }
+\cs_generate_variant:Nn \xsim_exercise_if_use:nnT {nV}
+\cs_generate_variant:Nn \xsim_exercise_if_use:nnTF {nV}
+
+% #1: type
+% #2: id
+% #3: exercise|solution
+\prg_new_protected_conditional:Npnn \xsim_if_print:nnn #1#2#3 {T,F,TF}
+ {
+ \use:c {xsim_#3_if_print:nnTF} {#1} {#2}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+
+% ----------------------------------------------------------------------------
+
+\xsim_new_aux_cs:cpn {total-number} #1
+ { \int_gset:Nn \g_xsim_max_id_int {#1} }
+
+\RequirePackage {etoolbox}
+
+\AtEndPreamble
+ {
+ \xsim_foreach_exercise_type:n
+ {
+ \tl_new:c { number of #1 s }
+ \tl_set:cn { number of #1 s } {0}
+ \xsim_new_aux_cs:cpn {#1} ##1
+ { \tl_gset:cn { number of #1 s } {##1} }
+ }
+ }
+
+\AtBeginDocument
+ {
+ \xsim_foreach_exercise_type:n
+ {
+ \xsim_write_to_aux:x
+ { \token_to_str:N \providecommand \token_to_str:N \numberof #1 s {} }
+ }
+ }
+
+\AtEndDocument
+ {
+ \xsim_if_clear_aux:T
+ {
+ \int_compare:nNnF { \g_xsim_max_id_int } = { \g_xsim_id_int }
+ { \xsim_empty_lists: }
+ }
+ \xsim_add_cs_to_aux:nn {total-number} { { \int_use:N \g_xsim_id_int } }
+ \xsim_foreach_exercise_type:n
+ {
+ \xsim_add_cs_to_aux:nn {#1}
+ { { \arabic { \xsim_get_parameter:nn {#1} {number} } } }
+ }
+ \xsim_update_list:n {types}
+ }
+
+% ----------------------------------------------------------------------------
+\tex_endinput:D