summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/xsim
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2020-03-18 03:01:18 +0000
committerNorbert Preining <norbert@preining.info>2020-03-18 03:01:18 +0000
commit701be49cc7a592cc192c0f28e45a763a4c745282 (patch)
tree4e86cf1011b55faeddf0e8da471c2e55324b37fa /macros/latex/contrib/xsim
parent35730d4ce115914408c09833060f86cc84fc0d14 (diff)
CTAN sync 202003180301
Diffstat (limited to 'macros/latex/contrib/xsim')
-rw-r--r--macros/latex/contrib/xsim/README2
-rw-r--r--macros/latex/contrib/xsim/code/xsim.auxfile.code.tex16
-rw-r--r--macros/latex/contrib/xsim/code/xsim.base.code.tex82
-rw-r--r--macros/latex/contrib/xsim/code/xsim.collections.code.tex29
-rw-r--r--macros/latex/contrib/xsim/code/xsim.environments.code.tex9
-rw-r--r--macros/latex/contrib/xsim/code/xsim.exercises.code.tex75
-rw-r--r--macros/latex/contrib/xsim/code/xsim.goals.code.tex2
-rw-r--r--macros/latex/contrib/xsim/code/xsim.interface.code.tex4
-rw-r--r--macros/latex/contrib/xsim/code/xsim.modules.code.tex4
-rw-r--r--macros/latex/contrib/xsim/code/xsim.properties.code.tex116
-rw-r--r--macros/latex/contrib/xsim/code/xsim.random.code.tex5
-rw-r--r--macros/latex/contrib/xsim/code/xsim.solutions.code.tex11
-rw-r--r--macros/latex/contrib/xsim/code/xsim.sty7
-rw-r--r--macros/latex/contrib/xsim/code/xsim.templates.code.tex20
-rw-r--r--macros/latex/contrib/xsim/doc/examples/xsim.collections.tex2
-rw-r--r--macros/latex/contrib/xsim/doc/xsim-manual.cls73
-rw-r--r--macros/latex/contrib/xsim/doc/xsim.history5
-rw-r--r--macros/latex/contrib/xsim/doc/xsim_manual.pdfbin1233169 -> 1233899 bytes
-rw-r--r--macros/latex/contrib/xsim/doc/xsim_manual.tex7
19 files changed, 338 insertions, 131 deletions
diff --git a/macros/latex/contrib/xsim/README b/macros/latex/contrib/xsim/README
index d8f72533c5..e99d361202 100644
--- a/macros/latex/contrib/xsim/README
+++ b/macros/latex/contrib/xsim/README
@@ -1,5 +1,5 @@
--------------------------------------------------------------------------
-XSIM 2020/02/23 v0.18
+XSIM 2020/03/16 v0.19
XSIMVERB 2019/12/29 v0.1a
eXercise Sheets IMproved
diff --git a/macros/latex/contrib/xsim/code/xsim.auxfile.code.tex b/macros/latex/contrib/xsim/code/xsim.auxfile.code.tex
index 4fa95620a3..2f31f2009f 100644
--- a/macros/latex/contrib/xsim/code/xsim.auxfile.code.tex
+++ b/macros/latex/contrib/xsim/code/xsim.auxfile.code.tex
@@ -105,19 +105,17 @@
\cs_new_protected:Npn \xsim_new_list:n #1
{
\xsim_verbose:n { Defining~ new~ auxfile~ list~ `#1'. }
- \prop_new:c {g__xsim_list_#1_prop}
\seq_new:c {g__xsim_list_#1_seq}
\seq_new:c {g__xsim_list_recorded_#1_seq}
\xsim_new_aux_property:cpn {#1} ##1
{
- \prop_gclear:c {g__xsim_list_#1_prop}
\tl_if_blank:nF {##1}
{
\seq_gset_split:cVx {g__xsim_list_#1_seq}
\l__xsim_split_aux_lists_str
{ \tl_to_str:n {##1} }
\seq_map_inline:cn {g__xsim_list_#1_seq}
- { \prop_gput:cnn {g__xsim_list_#1_prop} {####1} {} }
+ { \xsim_attribute_set:nnn {#1} {####1} {} }
}
}
\xsim_at_begin_document:n
@@ -140,7 +138,7 @@
{
\xsim_verbose:n { Adding~ `#2'~ to~ list~ `#1'. }
\str_set:Nn \l__xsim_tmpa_str {#2}
- \prop_gput:cnn {g__xsim_list_#1_prop} {#2} {}
+ \xsim_attribute_set:nnn {#1} {#2} {}
\seq_if_in:cVT {g__xsim_list_#1_seq} \l__xsim_tmpa_str
{ \seq_gremove_all:cV {g__xsim_list_#1_seq} \l__xsim_tmpa_str }
\seq_gput_right:cV {g__xsim_list_#1_seq} \l__xsim_tmpa_str
@@ -153,8 +151,8 @@
{
\xsim_verbose:n { Removing~ `#2'~ to~ list~ `#1'. }
\str_set:Nn \l__xsim_tmpa_str {#2}
- \prop_if_in:cnT {g__xsim_list_#1_prop} {#2}
- { \prop_gremove:cn {g__xsim_list_#1_prop} {#2} }
+ \xsim_attribute_if_set:nnT {#1} {#2}
+ { \xsim_attribute_unset:nn {#1} {#2} }
\seq_if_in:cVT {g__xsim_list_#1_seq} \l__xsim_tmpa_str
{ \seq_gremove_all:cV {g__xsim_list_#1_seq} \l__xsim_tmpa_str }
\seq_if_in:cVT {g__xsim_list_recorded#1_seq} \l__xsim_tmpa_str
@@ -167,16 +165,13 @@
% #2: entry
\prg_new_conditional:Npnn \xsim_if_in_list:nn #1#2 {p,T,F,TF}
{
- \prop_if_in:cnTF {g__xsim_list_#1_prop} {#2}
+ \xsim_attribute_if_set:nnTF {#1} {#2}
{ \prg_return_true: }
{ \prg_return_false: }
}
\cs_generate_variant:Nn \xsim_if_in_list:nnTF {nx}
\cs_generate_variant:Nn \xsim_if_in_list:nnT {nx}
-\cs_new:Npn \xsim_list_show:n #1
- { \prop_show:c {g__xsim_list_#1_prop} }
-
\bool_new:N \l__xsim_empty_lists_bool
\cs_new_protected:Npn \xsim_empty_lists:
{ \bool_set_true:N \l__xsim_empty_lists_bool }
@@ -223,3 +218,4 @@
% ----------------------------------------------------------------------------
\file_input_stop:
+2020/03/16 - performance optimizations
diff --git a/macros/latex/contrib/xsim/code/xsim.base.code.tex b/macros/latex/contrib/xsim/code/xsim.base.code.tex
index fbaf246c0f..3bcfb21d36 100644
--- a/macros/latex/contrib/xsim/code/xsim.base.code.tex
+++ b/macros/latex/contrib/xsim/code/xsim.base.code.tex
@@ -53,7 +53,7 @@
\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 {cxx}
+\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}
@@ -68,12 +68,11 @@
\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 {Nnn}
+\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 \iow_now:Nn {NV}
\cs_generate_variant:Nn \prg_new_protected_conditional:Npnn {c}
% ----------------------------------------------------------------------------
@@ -136,6 +135,13 @@
{ \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
@@ -198,8 +204,78 @@
% ----------------------------------------------------------------------------
+\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 {#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
diff --git a/macros/latex/contrib/xsim/code/xsim.collections.code.tex b/macros/latex/contrib/xsim/code/xsim.collections.code.tex
index b85ffa2a15..5aeb6e2d77 100644
--- a/macros/latex/contrib/xsim/code/xsim.collections.code.tex
+++ b/macros/latex/contrib/xsim/code/xsim.collections.code.tex
@@ -29,7 +29,7 @@
\xsim_load_modules:n {base}
-\prop_new:N \g__xsim_collections_prop
+\seq_new:N \g__xsim_collections_seq
\bool_new:N \l____xsim_active_bool
\msg_new:nnn {xsim} {collection-exists}
@@ -66,7 +66,8 @@
{ \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_attribute_set:nnn {collection} {#1} { \c_false_bool }
+ \seq_gput_right:Nn \g__xsim_collections_seq {#1}
\xsim_new_list:n {collection:#1}
\seq_new:c {g__xsim_collection_#1_seq}
}
@@ -75,7 +76,7 @@
% #1: collection name
\prg_new_conditional:Npnn \xsim_if_collection_exist:n #1 {T,F,TF}
{
- \prop_if_in:NnTF \g__xsim_collections_prop {#1}
+ \seq_if_in:NnTF \g__xsim_collections_seq {#1}
{ \prg_return_true: }
{ \prg_return_false: }
}
@@ -83,7 +84,9 @@
\xsim_new_collection:n {all~ exercises}
\cs_new_protected:Npn \xsim_foreach_collection:n #1
- { \prop_map_inline:Nn \g__xsim_collections_prop {#1} }
+ { \seq_map_inline:Nn \g__xsim_collections_seq {#1} }
+
+\cs_new:Npn \xsim_collection_map_break: { \seq_map_break: }
% ----------------------------------------------------------------------------
@@ -96,7 +99,7 @@
}
{
\xsim_verbose:n { Activating~ collection~ `#1'. }
- \prop_gput:Nnn \g__xsim_collections_prop {#1} { \c_true_bool }
+ \xsim_attribute_set:nnn {collection} {#1} { \c_true_bool }
\tl_if_blank:nF {#2}
{ \seq_gput_right:cn {g__xsim_collection_#1_seq} {#2} }
}
@@ -111,8 +114,8 @@
\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}
+ \xsim_attribute_set:nnn {collection} {#1} { \c_false_bool }
+ % \seq_gclear:c {g__xsim_collection_#1_seq}
}
{ % TODO: warning
}
@@ -161,7 +164,7 @@
\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}
+ \seq_if_in:cnF {g__xsim_collection_#1_seq} {#2}
{ \__xsim_add_to_collection:nnn {#1} {#2} {#3} }
}
}
@@ -349,11 +352,11 @@
% #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}
+ \xsim_attribute_if_set:nnTF {collection} {#1}
{
\bool_lazy_and:nnTF
{ !\str_if_eq_p:en {#1} {all~ exercises} }
- { \prop_item:Nn \g__xsim_collections_prop {#1} }
+ { \xsim_attribute_get:nn {collection} {#1} }
{ \prg_return_true: }
{ \prg_return_false: }
}
@@ -363,12 +366,12 @@
\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_foreach_collection:n
{
\xsim_if_collection_active:nT {##1}
{
\bool_set_true:N \l____xsim_active_bool
- \prop_map_break:
+ \xsim_collection_map_break:
}
}
\bool_if:NTF \l____xsim_active_bool
@@ -381,7 +384,7 @@
\xsim_at_begin_document:n
{
\xsim_get_collections:
- \xsim_activate_collection:n {all~ exercises}
+ \xsim_activate_collection:n {all~ exercises}
}
\xsim_at_end_document:n
diff --git a/macros/latex/contrib/xsim/code/xsim.environments.code.tex b/macros/latex/contrib/xsim/code/xsim.environments.code.tex
index ce4b281ba0..ca5f76f80a 100644
--- a/macros/latex/contrib/xsim/code/xsim.environments.code.tex
+++ b/macros/latex/contrib/xsim/code/xsim.environments.code.tex
@@ -55,9 +55,6 @@
\tl_new:N \ExerciseText
\tl_set:Nn \ExerciseText { \msg_error:nn {xsim} {only-in-solution} }
-\cs_generate_variant:Nn \tl_set_rescan:Nnn {Nnx}
-\cs_generate_variant:Nn \prop_put:Nnn {Nnx}
-
% ----------------------------------------------------------------------------
\msg_new:nnn {xsim} {only-in-solution}
@@ -277,6 +274,8 @@
% #3: exercise|solution
\cs_new_protected:Npn \xsim_typeset_environment:nnn #1#2#3
{
+ \tl_set:Nn \ExerciseType {#1}
+ \tl_set:Nn \ExerciseID {#2}
\xsim_if_exchange:nnnT {#1} {#2} {#3}
{ \__xsim_set_file_signature:nnn {#1} {#2} {exercise} }
\xsim_verbose:n
@@ -507,7 +506,7 @@
\bool_set_true:N \l__xsim_options_given_bool
\use:c {xsim_start_#2:nn} {#1} {##1}
}
- \xsim_start_environment:nVnn {#1} \g_xsim_exercise_id_tl {#2} {##2}
+ \xsim_start_environment:nVnn {#1} \g_xsim_exercise_id_tl {#2} {##2}
}
{
\xsim_stop_environment:nVn {#1} \g_xsim_exercise_id_tl {#2}
@@ -526,3 +525,5 @@
2020/02/19 - implement issue #33 (solution property)
2020/02/20 - fix issue #27
- implement issue #2
+2020/03/08 - correctly re-set \ExerciseType and \ExerciseID for typesetting
+ (they're no longer local)
diff --git a/macros/latex/contrib/xsim/code/xsim.exercises.code.tex b/macros/latex/contrib/xsim/code/xsim.exercises.code.tex
index 2fc9e4d142..9ba49c6803 100644
--- a/macros/latex/contrib/xsim/code/xsim.exercises.code.tex
+++ b/macros/latex/contrib/xsim/code/xsim.exercises.code.tex
@@ -33,15 +33,16 @@
collections
}
+\seq_new:N \l__xsim_exercise_types_seq
\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
+\tl_new:N \ExerciseType
\bool_new:N \l____xsim_print_bool
% ----------------------------------------------------------------------------
@@ -73,6 +74,28 @@
}
% ----------------------------------------------------------------------------
+% #1: type
+% #2: parameter
+% #3: value
+\cs_new_protected:Npn \__xsim_set_parameter_type:nnn #1#2#3
+ { \xsim_attribute_set:nnn {#1} {#2} {#3} }
+
+% #1: type
+% #2: parameter
+\cs_new:Npn \xsim_get_parameter:nn #1#2
+ { \xsim_attribute_get:nn {#1} {#2} }
+\cs_generate_variant:Nn \xsim_get_parameter:nn {o}
+
+% #1: type
+% #2: parameter
+\prg_new_conditional:Npnn \xsim_if_parameter_set:nn #1#2 {p,T,F,TF}
+ {
+ \xsim_attribute_if_set:nnTF {#1} {#2}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+
+% ----------------------------------------------------------------------------
\xsim_new_list:n {types}
@@ -141,7 +164,7 @@
% #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}
+ \seq_if_in:NnTF \l__xsim_exercise_types_seq {#1}
{ \prg_return_true: }
{ \prg_return_false: }
}
@@ -167,31 +190,18 @@
{
\xsim_verbose:n
{ Setting~ parameter~ `#2'~ for~ type~ `#1'~ to~ `#3'. }
- \prop_put:cnn {l__xsim_#1_type_parameters_prop} {#2} {#3}
+ \__xsim_set_parameter_type:nnn {#1} {#2} {#3}
}
}
{
\xsim_verbose:n
{ Setting~ parameter~ `#2'~ for~ type~ `#1'~ to~ `#3'. }
- \prop_put:cnn {l__xsim_#1_type_parameters_prop} {#2} {#3}
+ \__xsim_set_parameter_type:nnn {#1} {#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_set:nn #1#2 {p,T,F,TF}
- {
- \prop_if_in:cnTF {l__xsim_#1_type_parameters_prop} {#2}
- { \prg_return_true: }
- { \prg_return_false: }
- }
-
\cs_new:Npn \__xsim_get_parameter_tmp:n #1 {}
\cs_generate_variant:Nn \__xsim_get_parameter_tmp:n {V}
@@ -274,7 +284,7 @@
\cs_new_protected:Npn \xsim_define_exercise_type_variables:n #1
{
- \prop_new:c {l__xsim_#1_type_parameters_prop}
+ \seq_put_right:Nn \l__xsim_exercise_types_seq {#1}
\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}
@@ -320,22 +330,22 @@
\xsim_if_parameter_set:nnF {#1} {exercises-name}
{
\xsim_set_parameters:nn {#1}
- { exercises-name = \xsim_get_parameter:nn {#1} {exercise-name} s }
+ { exercises-name = \xsim_get_parameter:nn {#1} {exercise-name} s }
}
\xsim_if_parameter_set:nnF {#1} {solutions-name}
{
\xsim_set_parameters:nn {#1}
- { solutions-name = \xsim_get_parameter:nn {#1} {solution-name} s }
+ { solutions-name = \xsim_get_parameter:nn {#1} {solution-name} s }
}
\xsim_if_parameter_set:nnF {#1} {counter}
{
\xsim_set_parameters:nx {#1}
- { counter = \xsim_get_parameter:nn {#1} {exercise-env} }
+ { counter = \xsim_get_parameter:nn {#1} {exercise-env} }
}
\xsim_if_parameter_set:nnF {#1} {solution-counter}
{
\xsim_set_parameters:nx {#1}
- { solution-counter = \xsim_get_parameter:nn {#1} {solution-env} }
+ { solution-counter = \xsim_get_parameter:nn {#1} {solution-env} }
}
\xsim_define_counters:n {#1}
\xsim_verbose:n { Defining~ options~ for~ new~ exercise~ type~ `#1' }
@@ -363,8 +373,12 @@
.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} {exercise-env} s / name
+ .code:n = \xsim_set_parameter:nnn {#1} {exercises-name} {####1} ,
\xsim_get_parameter:nn {#1} {solution-env} / name
.code:n = \xsim_set_parameter:nnn {#1} {solution-name} {####1} ,
+ \xsim_get_parameter:nn {#1} {solution-env} s / name
+ .code:n = \xsim_set_parameter:nnn {#1} {solutions-name} {####1} ,
\xsim_get_parameter:nn {#1} {exercise-env} / heading
.code:n = \xsim_set_parameter:nnn {#1} {exercise-heading} {####1} ,
\xsim_get_parameter:nn {#1} {solution-env} / heading
@@ -395,6 +409,7 @@
\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 }
\tl_gset:Nx \g_xsim_exercise_id_tl { \int_use:N \g_xsim_id_int }
+ \tl_gset:Nn \g_xsim_exercise_type_tl {#1}
% save the goal values from the auxiliary files:
\xsim_foreach_goal:n
{
@@ -467,11 +482,8 @@
chapter = \thechapter
}
}
- % \tl_gclear:N \g_xsim_exercise_id_tl
- % \xsim_gsave_property:nVnN {#1} \l__xsim_tmpa_tl {id}
- % \g_xsim_exercise_id_tl
- \tl_gset_eq:NN \ExerciseID \g_xsim_exercise_id_tl
- \tl_gset:Nn \ExerciseType {#1}
+ \tl_set_eq:NN \ExerciseID \g_xsim_exercise_id_tl
+ \tl_set:Nn \ExerciseType {#1}
\xsim_verbose:x
{
Starting~ exercise~ type~ `#1' with~ id~
@@ -505,7 +517,11 @@
}
}
-\cs_new_protected:Npn \xsim_stop_exercise:n #1 {}
+\cs_new_protected:Npn \xsim_stop_exercise:n #1
+ {
+ \xsim_if_insert_mode:F
+ { \tl_gset_eq:NN \g_xsim_exercise_id_tl \ExerciseID }
+ }
% ----------------------------------------------------------------------------
% #1: type
@@ -615,3 +631,6 @@
\file_input_stop:
2020/02/21 - implement issue #2
+2020/03/01 - add options `<ex-env>s/name` and `<sol-env>/name`
+2020/03/07 - set \ExerciseID and \ExerciseType only locally
+2020/03/14 - performance optimizations
diff --git a/macros/latex/contrib/xsim/code/xsim.goals.code.tex b/macros/latex/contrib/xsim/code/xsim.goals.code.tex
index 6b17d2bc3f..67019eb6f3 100644
--- a/macros/latex/contrib/xsim/code/xsim.goals.code.tex
+++ b/macros/latex/contrib/xsim/code/xsim.goals.code.tex
@@ -156,7 +156,7 @@
\prg_new_conditional:Npnn \xsim_if_goal_value:nnnn #1#2#3#4 {p,T,F,TF}
{
\fp_compare:nTF
- { (0 \xsim_get_property:nnn {#1} {#2} {#3}) #4 }
+ { (0 + \xsim_get_property:nnn {#1} {#2} {#3}) #4 }
{ \prg_return_true: }
{ \prg_return_false: }
}
diff --git a/macros/latex/contrib/xsim/code/xsim.interface.code.tex b/macros/latex/contrib/xsim/code/xsim.interface.code.tex
index b0ca92a1c4..b96e5a47b5 100644
--- a/macros/latex/contrib/xsim/code/xsim.interface.code.tex
+++ b/macros/latex/contrib/xsim/code/xsim.interface.code.tex
@@ -332,8 +332,8 @@
\NewExpandableDocumentCommand \XSIMtranslate {m}
{ \xsim_translate:n {#1} }
-\NewDocumentCommand \XSIMexpandcode {+m}
- { \use:x {#1} }
+\NewExpandableDocumentCommand \XSIMexpandcode {+m}
+ { \use:e {#1} }
\NewExpandableDocumentCommand \XSIMmixedcase {m}
{ \tl_mixed_case:f {#1} }
diff --git a/macros/latex/contrib/xsim/code/xsim.modules.code.tex b/macros/latex/contrib/xsim/code/xsim.modules.code.tex
index bc82dcbafc..51b595fdd3 100644
--- a/macros/latex/contrib/xsim/code/xsim.modules.code.tex
+++ b/macros/latex/contrib/xsim/code/xsim.modules.code.tex
@@ -87,7 +87,7 @@
{ \msg_error:nnn {xsim} {module-missing} {#1} }
}
}
-\cs_generate_variant:Nn \__xsim_load_module:n { V }
+\cs_generate_variant:Nn \__xsim_load_module:n {V}
\prg_new_conditional:Npnn \xsim_if_module_loaded:n #1 {p,T,F,TF}
{
@@ -163,8 +163,6 @@
\tl_set:Nx \l__xsim_module_version_tl {\c_xsim_version_tl}
}
-\cs_generate_variant:Nn \str_if_eq:nnF {xx}
-
\cs_new_protected:Npn \__xsim_module:nn #1#2
{
\seq_gput_right:Nn \g__xsim_loaded_modules_seq {#1}
diff --git a/macros/latex/contrib/xsim/code/xsim.properties.code.tex b/macros/latex/contrib/xsim/code/xsim.properties.code.tex
index 0bbc972f21..12a6fdf220 100644
--- a/macros/latex/contrib/xsim/code/xsim.properties.code.tex
+++ b/macros/latex/contrib/xsim/code/xsim.properties.code.tex
@@ -49,13 +49,39 @@
\msg_line_context: . \\
However,~ property~ `#1'~ is~ not~ a~ boolean~ property!
}
-
+
+\msg_new:nnn {xsim} {unbalanced-property-list}
+ {
+ There~ is~ a~ mis-match~ in~ the~ property~ list: \\
+ `#1' \\
+ \msg_line_context:
+ }
+
\seq_new:N \l__xsim_properties_seq
\seq_new:N \l__xsim_boolean_properties_seq
\seq_new:N \l__xsim_unique_properties_seq
\seq_new:N \l__xsim_noupdate_properties_seq
\seq_new:N \l__xsim_given_properties_seq
-\prop_new:N \g__xsim_properties_prop
+
+% #1: type
+% #2: id
+% #3: property
+\cs_new_protected:Npn \__xsim_define_property:nnn #1#2#3
+ { \xsim_attribute_new:nn {#1!#2} {#3} }
+
+% check if property is set:
+% #1: type
+% #2: id
+% #3: property
+\prg_new_conditional:Npnn \xsim_if_property_set:nnn #1#2#3 {p,T,F,TF}
+ {
+ \xsim_attribute_if_set:nnTF {#1!#2} {#3}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+\prg_generate_conditional_variant:Nnn \xsim_if_property_set:nnn
+ {nx,nnx,xx,nV}
+ {T,F,TF}
% new property:
% #1: boolean if unique
@@ -88,8 +114,6 @@
\seq_if_in:NnF \l__xsim_unique_properties_seq {#4}
{ \seq_put_right:Nn \l__xsim_unique_properties_seq {#4} }
\seq_new:c {l__xsim_unique_property_#4_values_seq}
- \prop_new:c {g__xsim_property_#4_type_prop}
- \prop_new:c {g__xsim_property_#4_id_prop}
}
{ \xsim_verbose:n { Declaring~ new~ exercise~ property~ `#4'. } }
}
@@ -160,27 +184,27 @@
% #4: value
\cs_new_protected:Npn \xsim_set_property:nnnn #1#2#3#4
{
- \xsim_if_property_exist:nTF {#3}
+ \xsim_if_property_exist:nTF {#3} % _p
{
- \xsim_if_property_set:nnnTF {#1} {#2} {#3}
+ \xsim_if_property_set:nnnTF {#1} {#2} {#3} % _p
{
- \xsim_if_property_unique_value:nnTF {#3} {#4}
+ \xsim_if_property_unique_value:nnTF {#3} {#4} %_p
{ \msg_warning:nnnn {xsim} {property-unique} {#3} {#4} }
{
- \xsim_if_property_boolean:nTF {#3}
+ \xsim_if_property_boolean:nTF {#3} % _p
{ \__xsim_set_boolean_property:nnnn {#1} {#2} {#3} {#4} }
{
- \xsim_if_property_unique:nTF {#3}
+ \xsim_if_property_unique:nTF {#3} % _p
{ \__xsim_set_unique_property:nnnn {#1} {#2} {#3} {#4} }
{ \__xsim_set_property:nnnn {#1} {#2} {#3} {#4} }
}
}
}
{
- \xsim_if_property_boolean:nTF {#3}
+ \xsim_if_property_boolean:nTF {#3} % _p
{ \__xsim_set_boolean_property:nnnn {#1} {#2} {#3} {#4} }
{
- \xsim_if_property_unique:nTF {#3}
+ \xsim_if_property_unique:nTF {#3} % _p
{ \__xsim_set_unique_property:nnnn {#1} {#2} {#3} {#4} }
{ \__xsim_set_property:nnnn {#1} {#2} {#3} {#4} }
}
@@ -218,6 +242,17 @@
% #1: type
% #2: id
% #3: property
+\cs_new_protected:Npn \__xsim_unset_property:nnn #1#2#3
+ {
+ \xsim_verbose:n
+ { Un-setting~ property~ `#3'~ of~ exercise~ type~ `#1'~ id~ `#2'. }
+ \__xsim_remove_property_from_list:nnn {#1} {#2} {#3}
+ \xsim_attribute_unset:nn {#1!#2} {#3}
+ }
+
+% #1: type
+% #2: id
+% #3: property
\cs_new_protected:Npn \xsim_unset_property:nnn #1#2#3
{
\xsim_if_property_exist:nTF {#3}
@@ -237,10 +272,10 @@
Setting~ property~ `#3'~ of~ exercise~ type~ `#1'~ id~ `#2'~ to~
value~ `#4'.
}
- \__xsim_remove_property_from_list:nnn {#1} {#2} {#3}
+ \__xsim_remove_property_from_list:nnn {#1} {#2} {#3}
% now we can safely add the property to the list:
\xsim_add_to_list:nn {#3} {#1-#2=={#4}}
- \prop_gput:Nnn \g__xsim_properties_prop {#2!#1!#3} {#4}
+ \xsim_attribute_set:nnn {#1!#2} {#3} {#4}
}
\cs_generate_variant:Nn \__xsim_set_property:nnnn {VVnV}
@@ -250,19 +285,8 @@
% #4: value
\cs_new_protected:Npn \__xsim_set_property_reverse:nnnn #1#2#3#4
{
- \prop_gput:cnn {g__xsim_property_#3_type_prop} {#4} {#1}
- \prop_gput:cnn {g__xsim_property_#3_id_prop} {#4} {#2}
- }
-
-% #1: type
-% #2: id
-% #3: property
-\cs_new_protected:Npn \__xsim_unset_property:nnn #1#2#3
- {
- \xsim_verbose:n
- { Un-setting~ property~ `#3'~ of~ exercise~ type~ `#1'~ id~ `#2'. }
- \__xsim_remove_property_from_list:nnn {#1} {#2} {#3}
- \prop_gremove:Nn \g__xsim_properties_prop {#2!#1!#3}
+ \xsim_attribute_set:nnn {type:#3} {#4} {#1}
+ \xsim_attribute_set:nnn {id:#3} {#4} {#2}
}
\tl_set:Nx \l__xsim_tmpa_tl { \cs_to_str:N \{ }
@@ -280,6 +304,9 @@
\str_set:Nn #3 {#6}
}
+% #1: type
+% #2: id
+% #3: property
\cs_new_protected:Npn \__xsim_remove_property_from_list:nnn #1#2#3
{
% make sure we change the entry if it has been recorded previously:
@@ -331,6 +358,8 @@
\clist_map_inline:nn {#3}
{
\seq_set_split:Nnx \l__xsim_tmpa_seq {=} { \tl_trim_spaces:n {##1} }
+ \int_compare:nNnT { \seq_count:N \l__xsim_tmpa_seq } > {2}
+ { \msg_error:nnn {xsim} {unbalanced-property-list} {##1} }
\xsim_set_property:nnxx
{#1}
{#2}
@@ -343,36 +372,21 @@
}
\cs_generate_variant:Nn \xsim_set_properties:nnn {nnx,nxx,nV,nVx}
-% check if property is set:
-% #1: type
-% #2: id
-% #3: property
-\prg_new_conditional:Npnn \xsim_if_property_set:nnn #1#2#3 {T,F,TF}
- {
- \prop_if_in:NnTF \g__xsim_properties_prop {#2!#1!#3}
- { \prg_return_true: }
- { \prg_return_false: }
- }
-\prg_generate_conditional_variant:Nnn \xsim_if_property_set:nnn
- {nx,nnx,xx,nV}
- {T,F,TF}
-
% ----------------------------------------------------------------------------
-\prop_new:N \g__xsim_property_aliases_prop
\seq_new:N \g__xsim_property_aliases_seq
% #1: property
\prg_new_conditional:Npnn \xsim_if_property_alias:n #1 {p,T,F,TF}
{
- \prop_if_in:NnTF \g__xsim_property_aliases_prop {#1}
+ \seq_if_in:NnTF \g__xsim_property_aliases_seq {#1}
{ \prg_return_true: }
{ \prg_return_false: }
}
% #1: property
\cs_new:Npn \xsim_property_alias:n #1
- { \prop_item:Nn \g__xsim_property_aliases_prop {#1} }
+ { \xsim_attribute_get:nn {#1} {alias} }
% #1: property
% #2: alias of
@@ -382,8 +396,7 @@
{
\xsim_verbose:n
{ Making~ property~ `#1'~ an~ alias~ of~ property~ `#2'. }
- \prop_new:c {g__xsim_property_#1_alias_prop}
- \prop_gput:Nnn \g__xsim_property_aliases_prop {#1} {#2}
+ \xsim_attribute_set:nnn {#1} {alias} {#2}
\seq_gput_right:Nn \g__xsim_property_aliases_seq {#1}
}
}
@@ -408,8 +421,7 @@
\xsim_if_property_set:nnxT {#1} {#2}
{ \xsim_property_alias:n {#3} }
{
- \prop_gput:cxx {g__xsim_property_#3_alias_prop}
- { \xsim_get_property:nnn {#1} {#2} {#3} }
+ \xsim_attribute_set:nnx {alias:#1!#2} {#3}
{
\xsim_get_property:nnf {#1} {#2}
{ \xsim_property_alias:n {#3} }
@@ -433,18 +445,18 @@
% #2: id
% #3: property
\cs_new:Npn \xsim_get_property:nnn #1#2#3
- { \prop_item:Nn \g__xsim_properties_prop { #2 ! #1 ! #3 } }
+ { \xsim_attribute_get:nn {#1!#2} {#3} }
\cs_generate_variant:Nn \xsim_get_property:nnn {nx,ne,xx,oo,no,nnf,nf,oof,nV}
% #1: property
% #2: value
\cs_new:Npn \xsim_get_id_for_property:nn #1#2
- { \prop_item:cn {g__xsim_property_#1_id_prop} {#2} }
+ { \xsim_attribute_get:nn {id:#1} {#2} }
% #1: property
% #2: value
\cs_new:Npn \xsim_get_type_for_property:nn #1#2
- { \prop_item:cn {g__xsim_property_#1_type_prop} {#2} }
+ { \xsim_attribute_get:nn {type:#1} {#2} }
\cs_generate_variant:Nn \xsim_get_type_for_property:nn {nV}
% #1: id or ID
@@ -512,7 +524,7 @@
\cs_generate_variant:Nn \xsim_if_boolean_property:nnnF {nV}
\cs_new_protected:Npn \xsim_save_property:nnnN #1#2#3#4
- { \prop_get:NnN \g__xsim_properties_prop {#2!#1!#3} #4 }
+ { \tl_set:No #4 { \cs:w __xsim_property_#2!#1!#3: \cs_end: } }
\cs_generate_variant:Nn \xsim_save_property:nnnN {nx,xx}
\cs_new_protected:Npn \xsim_gsave_property:nnnN #1#2#3#4
@@ -524,3 +536,5 @@
% ----------------------------------------------------------------------------
\file_input_stop:
+2020/03/09 - add meaningful error if a comma is missing in the property list
+2020/03/14 - performance optimizations
diff --git a/macros/latex/contrib/xsim/code/xsim.random.code.tex b/macros/latex/contrib/xsim/code/xsim.random.code.tex
index 422963792f..cdd23e3a20 100644
--- a/macros/latex/contrib/xsim/code/xsim.random.code.tex
+++ b/macros/latex/contrib/xsim/code/xsim.random.code.tex
@@ -94,7 +94,7 @@
% #1: random list id
% #2: sequence variable to set list from
\cs_new_protected:Npn \xsim_save_random_list:nN #1#2
- {
+ { % TODO: check if #2 is empty
\xsim_random_list_if_exist:nF {#1}
{ \xsim_new_random_list:n {#1} }
\xsim_random_list_if_empty:nT {#1}
@@ -103,6 +103,7 @@
\xsim_add_property_to_aux:nn {random}
{ {#1} { \xsim_use_random_list:nn {#1} {,} } }
}
+\cs_generate_variant:Nn \xsim_save_random_list:nN {x}
% #1: collection
% #2: number of items
@@ -142,7 +143,7 @@
{ \l__xsim_tmpa_int }
\g__xsim_random_list_seq
}
- \xsim_save_random_list:nN
+ \xsim_save_random_list:xN
{ \int_to_alph:n { \g__xsim_random_list_id_int } }
\g__xsim_random_list_seq
\xsim_verbose:x
diff --git a/macros/latex/contrib/xsim/code/xsim.solutions.code.tex b/macros/latex/contrib/xsim/code/xsim.solutions.code.tex
index 2666d1aa86..0a69194508 100644
--- a/macros/latex/contrib/xsim/code/xsim.solutions.code.tex
+++ b/macros/latex/contrib/xsim/code/xsim.solutions.code.tex
@@ -35,7 +35,7 @@
\bool_new:N \l__xsim_printsolutions_conditions_bool
\bool_new:N \l____xsim_this_condition_bool
-\prop_new:N \l__xsim_printsolutions_conditions_prop
+\seq_new:N \l__xsim_printsolutions_conditions_seq
\int_new:N \l_xsim_printsolutions_section_int
\int_new:N \l_xsim_printsolutions_chapter_int
@@ -194,7 +194,8 @@
\cs_new_protected:Npn \xsim_declare_printsolutions_condition:nn #1#2
{
\bool_new:c {l__xsim_printsolutions_#1_condition_bool}
- \prop_put:Nnn \l__xsim_printsolutions_conditions_prop {#1} {#2}
+ \seq_put_right:Nn \l__xsim_printsolutions_conditions_seq {#1}
+ \xsim_attribute_set:nnn {printsolutions} {#1} {#2}
}
\prg_new_conditional:Npnn \__xsim_printsolutions_if_condition:n #1 {T,F,TF}
@@ -218,11 +219,12 @@
{
\__xsim_printsolutions_condition_false:
\bool_set_true:N \l____xsim_this_condition_bool
- \prop_map_inline:Nn \l__xsim_printsolutions_conditions_prop
+ \seq_map_inline:Nn \l__xsim_printsolutions_conditions_seq
{
\bool_if:cT {l__xsim_printsolutions_##1_condition_bool}
{
- ##2 {#1} {#2} {#3}
+ \xsim_attribute_get:nn {printsolutions} {##1}
+ {#1} {#2} {#3}
{ }
{ \bool_set_false:N \l____xsim_this_condition_bool }
}
@@ -409,3 +411,4 @@
\file_input_stop:
2020/02/23 - resolve bug #56
+2020/03/16 - performance optimizations
diff --git a/macros/latex/contrib/xsim/code/xsim.sty b/macros/latex/contrib/xsim/code/xsim.sty
index 8cd0f23796..79ab9b4b80 100644
--- a/macros/latex/contrib/xsim/code/xsim.sty
+++ b/macros/latex/contrib/xsim/code/xsim.sty
@@ -29,9 +29,9 @@
\ExplSyntaxOn
-\tl_const:Nn \c_xsim_date_tl {2020/02/23}
+\tl_const:Nn \c_xsim_date_tl {2020/03/16}
\tl_const:Nn \c_xsim_version_major_number_tl {0}
-\tl_const:Nn \c_xsim_version_minor_number_tl {18}
+\tl_const:Nn \c_xsim_version_minor_number_tl {19}
\tl_const:Nn \c_xsim_version_subrelease_tl {}
\tl_const:Nx \c_xsim_version_number_tl
{
@@ -57,6 +57,7 @@
\bool_new:N \g__xsim_final_bool
\bool_new:N \g__xsim_verbose_bool
+\bool_new:N \g__xsim_debug_bool
\bool_new:N \g_xsim_clear_aux_bool
\bool_new:N \g__xsim_write_to_file_bool
\bool_new:N \g_xsim_use_aux_bool
@@ -67,6 +68,7 @@
{
final .bool_gset:N = \g__xsim_final_bool ,
verbose .bool_gset:N = \g__xsim_verbose_bool ,
+ debug .bool_gset:N = \g__xsim_debug_bool ,
clear-aux .bool_gset:N = \g_xsim_clear_aux_bool ,
no-files .bool_gset_inverse:N = \g__xsim_write_to_file_bool ,
no-files .initial:n = false ,
@@ -82,6 +84,7 @@
{
final .code:n = \msg_error:nnn {xsim} {load-time-option} {final} ,
verbose .code:n = \msg_error:nnn {xsim} {load-time-option} {verbose} ,
+ debug .code:n = \msg_error:nnn {xsim} {load-time-option} {debug} ,
clear-aux .code:n = \msg_error:nnn {xsim} {load-time-option} {clear-aux} ,
no-files .code:n = \msg_error:nnn {xsim} {load-time-option} {no-files} ,
use-aux .code:n = \msg_error:nnn {xsim} {load-time-option} {use-aux} ,
diff --git a/macros/latex/contrib/xsim/code/xsim.templates.code.tex b/macros/latex/contrib/xsim/code/xsim.templates.code.tex
index 7644074be7..35bd173bba 100644
--- a/macros/latex/contrib/xsim/code/xsim.templates.code.tex
+++ b/macros/latex/contrib/xsim/code/xsim.templates.code.tex
@@ -36,11 +36,21 @@
I~ am~ using~ the~ template~ `#3'~ (template~ type~ `#1')~ instead.
}
+\msg_new:nnn {xsim} {template-type-exists}
+ { The~ template~ type~ `#1'~ already~ exists~ \msg_line_context: }
+
+% ----------------------------------------------------------------------------
+\seq_new:N \l__xsim_template_types_seq
+
% #1: template type
\cs_new_protected:Npn \xsim_new_template_type:n #1
{
- \xsim_verbose:n { Declaring~ new~ template~ type~ `#1'. }
- \prop_new:c {l__xsim_#1_template_prop}
+ \seq_if_in:NnTF \l__xsim_template_types_seq {#1}
+ { \msg_error:nnn {xsim} {template-type-exists} {#1} }
+ {
+ \xsim_verbose:n { Declaring~ new~ template~ type~ `#1'. }
+ \seq_put_right:Nn \l__xsim_template_types_seq {#1}
+ }
}
% #1: template type
@@ -50,12 +60,12 @@
{
\xsim_verbose:n { Defining~ new~ template~ `#2'~ of~ type~ `#1'. }
\tl_new:c {l__xsim_template_#1_#2_setup_tl}
- \prop_put:cnn {l__xsim_#1_template_prop} {#2} {#3}
+ \xsim_attribute_set:nnn {template::#1} {#2} {#3}
}
\prg_new_conditional:Npnn \xsim_if_template_exist:nn #1#2 {T,F,TF}
{
- \prop_if_in:cnTF {l__xsim_#1_template_prop} {#2}
+ \xsim_attribute_if_set:nnTF {template::#1} {#2}
{ \prg_return_true: }
{ \prg_return_false: }
}
@@ -63,7 +73,7 @@
% #1: template type
% #2: template name
\cs_new_protected:Npn \__xsim_get_template:nn #1#2
- { \prop_item:cn {l__xsim_#1_template_prop} {#2} }
+ { \xsim_attribute_get:nn {template::#1} {#2} }
% ----------------------------------------------------------------------------
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.collections.tex b/macros/latex/contrib/xsim/doc/examples/xsim.collections.tex
index beca191005..990391e091 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.collections.tex
+++ b/macros/latex/contrib/xsim/doc/examples/xsim.collections.tex
@@ -5,7 +5,7 @@
\DeclareExerciseCollection{foo-medium}
\DeclareExerciseTagging{difficulty}
-\usepackage{filecontents,lipsum}
+\usepackage{lipsum}
\begin{filecontents*}{foo.tex}
\begin{exercise}[difficulty=easy,points=1]
foo one \lipsum[4]
diff --git a/macros/latex/contrib/xsim/doc/xsim-manual.cls b/macros/latex/contrib/xsim/doc/xsim-manual.cls
index 1171fe9dd2..e40029df10 100644
--- a/macros/latex/contrib/xsim/doc/xsim-manual.cls
+++ b/macros/latex/contrib/xsim/doc/xsim-manual.cls
@@ -492,7 +492,7 @@
\tcbset{enhanced,enhanced jigsaw}
\newtcolorbox{bewareofthedog}{
- colback = white ,
+ colback = red!2!white!98 ,
colframe = red ,
underlay={%
\path[draw=none]
@@ -597,6 +597,76 @@
\endcnltxcode
}
+\RenewDocumentEnvironment{sourcecode}{}
+ {%
+ \xsimman@readoptions{%
+ \setlength\cnltx@sidebysidewidth
+ {\dimexpr .45\columnwidth -\lst@xleftmargin -\lst@xrightmargin\relax}%
+ \XSIMexpandcode{%
+ \noexpand\lstset{
+ style=cnltx,
+ \ifboolexpe{ bool {cnltx@sidebyside} and not bool {cnltx@codeonly} }
+ {linewidth=\cnltx@sidebysidewidth,}{}%
+ \expandonce\cnltx@local@listings@options
+ }%
+ }%
+ \XSIMgobblechars{2}%
+ }%
+ }
+ {%
+ \XSIMfilewritestop
+ \cnltxcode[breakable]%
+ \lstinputlisting[style=cnltx]{\jobname.tmp}%
+ \endcnltxcode
+ }
+
+\RenewDocumentEnvironment{example}{}
+ {%
+ \xsimman@readoptions{%
+ \setlength\cnltx@sidebysidewidth
+ {\dimexpr .45\columnwidth -\lst@xleftmargin -\lst@xrightmargin\relax}%
+ \XSIMexpandcode{%
+ \noexpand\lstset{
+ style=cnltx,
+ \ifboolexpe{ bool {cnltx@sidebyside} and not bool {cnltx@codeonly} }
+ {linewidth=\cnltx@sidebysidewidth,}{}%
+ \expandonce\cnltx@local@listings@options
+ }%
+ }%
+ \XSIMgobblechars{2}%
+ }%
+ }
+ {%
+ \XSIMfilewritestop
+ \catcode`\^^M=5
+ \ifbool{cnltx@sidebyside}
+ {%
+ \cnltxcode
+ \noindent
+ \minipage[c]{\cnltx@sidebysidewidth}%
+ \cnltx@pre@source@hook
+ \lstinputlisting[style=cnltx] {\jobname.tmp}%
+ \cnltx@after@source@hook
+ \endminipage\hfill
+ \minipage[c]{\cnltx@sidebysidewidth}%
+ \cnltx@pre@example@hook
+ \input {\jobname.tmp}%
+ \cnltx@after@example@hook
+ \endminipage
+ }
+ {%
+ \cnltxcode[breakable]%
+ \cnltx@pre@source@hook
+ \lstinputlisting{\jobname.tmp}%
+ \cnltx@after@source@hook
+ \tcblower
+ \cnltx@pre@example@hook
+ \input {\jobname.tmp}%
+ \cnltx@after@example@hook
+ }%
+ \endcnltxcode
+ }
+
\renewrobustcmd*\inputsourcecode[2][]{%
\begingroup
\pgfqkeys{/cnltx}{#1}%
@@ -899,6 +969,7 @@
\xsim@add@version{0.16a} {2020-01-16}
\xsim@add@version{0.17} {2020-02-21}
\xsim@add@version{0.18} {2020-02-23}
+\xsim@add@version{0.19} {2020-03-16}
% ----------------------------------------------------------------------------
\newrobustcmd*\xsimauxfileinfo{%
diff --git a/macros/latex/contrib/xsim/doc/xsim.history b/macros/latex/contrib/xsim/doc/xsim.history
index 20415de1bf..b957f1e1da 100644
--- a/macros/latex/contrib/xsim/doc/xsim.history
+++ b/macros/latex/contrib/xsim/doc/xsim.history
@@ -148,3 +148,8 @@ HISTORY:
- change \printexercise and \printsolution to accept a
clist of either ids or IDs (or mixed)
- new templates in the `layouts' style
+ v0.19 2020/03/16 - improve performance
+ - only set \ExerciseID and \ExerciseType locally to ensure
+ correct values when exercises (of different types) are
+ nested
+ - new load-time option `debug' - only for development
diff --git a/macros/latex/contrib/xsim/doc/xsim_manual.pdf b/macros/latex/contrib/xsim/doc/xsim_manual.pdf
index 03d1892dac..f3d4e64233 100644
--- a/macros/latex/contrib/xsim/doc/xsim_manual.pdf
+++ b/macros/latex/contrib/xsim/doc/xsim_manual.pdf
Binary files differ
diff --git a/macros/latex/contrib/xsim/doc/xsim_manual.tex b/macros/latex/contrib/xsim/doc/xsim_manual.tex
index e301758b60..d3adf284d9 100644
--- a/macros/latex/contrib/xsim/doc/xsim_manual.tex
+++ b/macros/latex/contrib/xsim/doc/xsim_manual.tex
@@ -68,6 +68,9 @@ using an up to date \TeX\ distribution, anyway.
package. Be careful: if you're in the middle of an important project it
might be better to wait with the update until you've finished the project.
Every update might be breaking some things.
+
+ Please also be aware that \xsim\ is actively developed and many things may
+ still change. However, I will try my best to keep the interface stable.
\end{bewareofthedog}
\section{Motivation and Background}
@@ -1483,6 +1486,10 @@ yourself in order to achieve certain layouts\footnote{I plan to incorporate
Can be used to refer to the current exercise type.
\expandable\command{ExerciseID}
Can be used to refer to the current exercise id.
+ \expandable\command{ExerciseText}
+ Can be used inside solutions to retrieve the text of the corresponding
+ solution. This is propably seldom useful as in most use cases the
+ exercise property \property{solution} is the easier alternative.
\expandable\command{ExerciseCollection}
Can be used in certain templates to refer to the collection that is
currently inserted.