summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex')
-rw-r--r--Master/texmf-dist/tex/latex/xsim/xsim-manual.cls42
-rw-r--r--Master/texmf-dist/tex/latex/xsim/xsim.auxfile.code.tex221
-rw-r--r--Master/texmf-dist/tex/latex/xsim/xsim.base.code.tex287
-rw-r--r--Master/texmf-dist/tex/latex/xsim/xsim.blanks.code.tex162
-rw-r--r--Master/texmf-dist/tex/latex/xsim/xsim.collections.code.tex397
-rw-r--r--Master/texmf-dist/tex/latex/xsim/xsim.definitions.code.tex482
-rw-r--r--Master/texmf-dist/tex/latex/xsim/xsim.environments.code.tex529
-rw-r--r--Master/texmf-dist/tex/latex/xsim/xsim.exercises.code.tex637
-rw-r--r--Master/texmf-dist/tex/latex/xsim/xsim.goals.code.tex385
-rw-r--r--Master/texmf-dist/tex/latex/xsim/xsim.grades.code.tex153
-rw-r--r--Master/texmf-dist/tex/latex/xsim/xsim.interface.code.tex696
-rw-r--r--Master/texmf-dist/tex/latex/xsim/xsim.modules.code.tex220
-rw-r--r--Master/texmf-dist/tex/latex/xsim/xsim.properties.code.tex540
-rw-r--r--Master/texmf-dist/tex/latex/xsim/xsim.random.code.tex315
-rw-r--r--Master/texmf-dist/tex/latex/xsim/xsim.solutions.code.tex414
-rw-r--r--Master/texmf-dist/tex/latex/xsim/xsim.sty5567
-rw-r--r--Master/texmf-dist/tex/latex/xsim/xsim.style.layouts.code.tex121
-rw-r--r--Master/texmf-dist/tex/latex/xsim/xsim.tags.code.tex211
-rw-r--r--Master/texmf-dist/tex/latex/xsim/xsim.templates.code.tex182
-rw-r--r--Master/texmf-dist/tex/latex/xsim/xsim.translations.code.tex147
-rw-r--r--Master/texmf-dist/tex/latex/xsim/xsim.verbwrite.code.tex217
-rw-r--r--Master/texmf-dist/tex/latex/xsim/xsimverb.sty272
22 files changed, 5799 insertions, 6398 deletions
diff --git a/Master/texmf-dist/tex/latex/xsim/xsim-manual.cls b/Master/texmf-dist/tex/latex/xsim/xsim-manual.cls
index c1d198ab04d..ed32a87fb3a 100644
--- a/Master/texmf-dist/tex/latex/xsim/xsim-manual.cls
+++ b/Master/texmf-dist/tex/latex/xsim/xsim-manual.cls
@@ -8,15 +8,15 @@
% Web: https://github.com/cgnieder/xsim
% E-Mail: contact@mychemistry.eu
% ----------------------------------------------------------------------------
-% Copyright 2017--2020 Clemens Niederberger
+% Copyright 2017--2021 Clemens Niederberger
%
% This work may be distributed and/or modified under the
-% conditions of the LaTeX Project Public License, either version 1.3
+% conditions of the LaTeX Project Public License, either version 1.3c
% 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.
+% and version 1.3c or later is part of all distributions of LaTeX
+% version 2008/05/04 or later.
%
% This work has the LPPL maintenance status `maintained'.
%
@@ -29,19 +29,18 @@
% please ignore the contents of this file -- it is not a good example for
% coding...
%
-\ProvidesClass{xsim-manual}[2020/04/04]
+\ProvidesClass{xsim-manual}[2021/01/31]
\LoadClass[load-preamble,add-index]{cnltx-doc}
\RequirePackage{imakeidx}
-\RequirePackage[utf8]{inputenc}
-\RequirePackage{xsim,xsimverb}
+\RequirePackage[use-files]{xsim}
\RequirePackage{geometry}
\geometry{
- left = 3.5cm ,
- right = 3cm ,
- marginparwidth = 3cm ,
- marginparsep = 2mm
+ left = 4cm ,
+ right = 2.5cm ,
+ marginparwidth = 3.3cm ,
+ marginparsep = 5mm
}
\setcnltx{
@@ -56,6 +55,7 @@
quote-format = \small\biolinumLF ,
add-cmds = {
blank ,
+ activatecollection ,
addbonus ,
addpoints ,
AddtoExerciseGoal ,
@@ -66,6 +66,7 @@
collectexercises ,
collectexercisestype ,
collectexercisesstop ,
+ deactivatecollection ,
DeclareExerciseCollection ,
DeclareExerciseEnvironmentTemplate ,
DeclareExerciseGoal ,
@@ -204,11 +205,14 @@
@percentchar ,
bottomrule ,
breite ,
+ captionsetup ,
choice ,
+ correct ,
cs ,
DeclareFloatingEnvironment ,
enddescription ,
endtcolorbox ,
+ ex ,
hint ,
hoehe ,
iflist ,
@@ -221,9 +225,11 @@
Needspace ,
NewDocumentCommand ,
NewDocumentEnvironment ,
+ NewTasksEnvironment ,
newlist ,
numberofcolumns ,
numberofproblems ,
+ option ,
pkg ,
pointsandbonus ,
printA, printC, printE ,
@@ -236,6 +242,7 @@
tcolorbox ,
thechapter ,
thesection ,
+ thetask ,
toprule ,
whileboolexpr ,
xsim
@@ -691,14 +698,13 @@
\RequirePackage{varioref}
\RequirePackage{bookmark}
+\DeclareExerciseCollection{foo}
+\DeclareExerciseCollection{layouts}
\xsimsetup{
% clear-aux ,
path = exercises
}
-\DeclareExerciseCollection{foo}
-\DeclareExerciseCollection{layouts}
-
\newrobustcmd*\TF{%
\colorlet{outside}{.}%
\textcolor{red}{\underline{\textcolor{outside}{TF}}}%
@@ -934,7 +940,10 @@
\xsim@add@example{texsx-370642}{Minimalistic layout}
\xsim@add@example{texsx-391530}{Exercises and sub-exercises}
\xsim@add@example{texsx-395273}{Different aspects of exercises, highlighted solutions}
+\xsim@add@example{texsx-466584}{Flushright Solutions}
\xsim@add@example{texsx-498299}{Multiple choice questions with automated solutions}
+\xsim@add@example{texsx-576998}{Exercises at the end of section and sectionwise solutions}
+\xsim@add@example{texsx-580636}{Multiple hints per exercise with backlinks}
\xsim@add@example{texwelt-6698}{Custom list of exercises}
\xsim@add@example{texwelt-15093}{Indicate difficulty level}
\xsim@add@example{texwelt-23968}{Long and short solutions}
@@ -985,12 +994,13 @@
\xsim@add@version{0.19} {2020-03-16}
\xsim@add@version{0.19a} {2020-03-19}
\xsim@add@version{0.19b} {2020-04-04}
+\xsim@add@version{0.20} {2021-01-31}
% ----------------------------------------------------------------------------
\newrobustcmd*\xsimauxfileinfo{%
\xsim\ writes a lot of stuff to an auxiliary file called
- \cs*{jobname}\code{.xsim} (or the common \cs*{jobname}\code{.aux} if you use
- option \option{use-aux}) for re-using information on subsequent
+ \meta{file name}\code{.xsim} (or the common \meta{file name}\code{.aux} if
+ you use option \option{use-aux}) for re-using information on subsequent
compilations. If you add exercises, change properties \etc\ it might happen
that wrong information is staying in the auxiliary file and is wrongly used
by \xsim. In such cases deleting the auxiliary file and doing a few fresh
diff --git a/Master/texmf-dist/tex/latex/xsim/xsim.auxfile.code.tex b/Master/texmf-dist/tex/latex/xsim/xsim.auxfile.code.tex
deleted file mode 100644
index 2f31f2009f5..00000000000
--- a/Master/texmf-dist/tex/latex/xsim/xsim.auxfile.code.tex
+++ /dev/null
@@ -1,221 +0,0 @@
-% ----------------------------------------------------------------------------
-% the XSIM package - auxfile 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{auxfile}{writing stuff to an auxiliary file}
-
-\prg_new_conditional:Npnn \xsim_if_use_aux: {p,T,F,TF}
- {
- \bool_if:NTF \g_xsim_use_aux_bool
- { \prg_return_true: }
- { \prg_return_false: }
- }
-
-\cs_new_protected:Npn \xsim_write_to_aux:n #1
- {
- \legacy_if:nT {@filesw}
- {
- \xsim_if_use_aux:TF
- { \iow_now:Nn \@auxout {#1} }
- { \iow_now:Nn \l__xsim_aux_file_iow {#1} }
- }
- }
-\cs_generate_variant:Nn \xsim_write_to_aux:n {x}
-
-% --------------------------------------------------------------------------
-
-\cs_new_protected:Npn \XSIM #1 { \use:c {XSIMaux#1} }
-
-\cs_new_protected:Npn \xsim_new_aux_property:cpn #1
- { \cs_new_protected:cpn {XSIMaux#1} }
-
-\cs_new_protected:Npn \xsim_add_property_to_aux:nn #1#2
- {
- \xsim_verbose:n { Writing~ command~ \XSIM {#1}~ to~ aux~ file }
- \xsim_write_to_aux:x { \token_to_str:N \XSIM {#1} #2 }
- }
-
-\xsim_at_begin_document:n
- {
- \iow_now:Nx \@auxout
- { \token_to_str:N \providecommand \token_to_str:N \XSIM [1] {} }
- }
-
-% ----------------------------------------------------------------------------
-
-\xsim_if_use_aux:F
- {
- \iow_new:N \l__xsim_aux_file_iow
- \xsim_at_begin_document:n
- { \iow_open:Nn \l__xsim_aux_file_iow { \c_sys_jobname_str .xsim } }
- }
-
-\cs_new_protected:Npn \xsim_close_aux:
- {
- \xsim_if_use_aux:F
- {
- \iow_close:N \l__xsim_aux_file_iow
- \legacy_if:nT {@filesw}
- { \iow_now:Nx \@auxout { \token_to_str:N \XSIM {readaux} } }
- }
- }
-
-\xsim_new_aux_property:cpn {readaux}
- {
- \file_if_exist:nT { \c_sys_jobname_str .xsim }
- { \file_input:n { \c_sys_jobname_str .xsim } }
- }
-
-% ----------------------------------------------------------------------------
-% list for recording values that need to be written to the aux file and
-% updated at begin document
-
-\str_new:N \l__xsim_split_aux_lists_str
-\keys_define:nn {xsim}
- {
- split-aux-lists .code:n = \str_set:Nn \l__xsim_split_aux_lists_str {#1} ,
- split-aux-lists .initial:n = ||
- }
-
-% define list:
-% #1: name
-\cs_new_protected:Npn \xsim_new_list:n #1
- {
- \xsim_verbose:n { Defining~ new~ auxfile~ list~ `#1'. }
- \seq_new:c {g__xsim_list_#1_seq}
- \seq_new:c {g__xsim_list_recorded_#1_seq}
- \xsim_new_aux_property:cpn {#1} ##1
- {
- \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}
- { \xsim_attribute_set:nnn {#1} {####1} {} }
- }
- }
- \xsim_at_begin_document:n
- {
- \seq_gclear:c {g__xsim_list_recorded_#1_seq}
- \seq_set_eq:Nc \l__xsim_tmpa_seq {g__xsim_list_#1_seq}
- \seq_map_inline:Nn \l__xsim_tmpa_seq
- {
- \str_set:Nn \l__xsim_tmpa_str {##1}
- \seq_gput_right:cV {g__xsim_list_recorded_#1_seq} \l__xsim_tmpa_str
- }
- \seq_gremove_duplicates:c {g__xsim_list_recorded_#1_seq}
- }
- }
-
-% add to or remove from list:
-% #1: name
-% #2: entry
-\cs_new_protected:Npn \xsim_add_to_list:nn #1#2
- {
- \xsim_verbose:n { Adding~ `#2'~ to~ list~ `#1'. }
- \str_set:Nn \l__xsim_tmpa_str {#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
- }
-\cs_generate_variant:Nn \xsim_add_to_list:nn {nx}
-
-% #1: name
-% #2: entry
-\cs_new_protected:Npn \xsim_remove_from_list:nn #1#2
- {
- \xsim_verbose:n { Removing~ `#2'~ to~ list~ `#1'. }
- \str_set:Nn \l__xsim_tmpa_str {#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
- { \seq_gremove_all:cV {g__xsim_list_recorded_#1_seq} \l__xsim_tmpa_str }
- }
-\cs_generate_variant:Nn \xsim_remove_from_list:nn {nx}
-
-% check if in list:
-% #1: name
-% #2: entry
-\prg_new_conditional:Npnn \xsim_if_in_list:nn #1#2 {p,T,F,TF}
- {
- \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}
-
-\bool_new:N \l__xsim_empty_lists_bool
-\cs_new_protected:Npn \xsim_empty_lists:
- { \bool_set_true:N \l__xsim_empty_lists_bool }
-
-% update list (should be used inside \xsim_at_end_document:n):
-% #1: name
-\cs_new_protected:Npn \xsim_update_list:n #1
- {
- \xsim_verbose:n { Updating~ list~ `#1'. }
- \seq_remove_duplicates:c {g__xsim_list_#1_seq}
- \seq_remove_duplicates:c {g__xsim_list_recorded_#1_seq}
- \str_set:Nx \l__xsim_tmpa_str
- { \seq_use:cn {g__xsim_list_#1_seq} {} }
- \str_set:Nx \l__xsim_tmpb_str
- { \seq_use:cn {g__xsim_list_recorded_#1_seq} {} }
- \str_if_eq:NNF \l__xsim_tmpa_str \l__xsim_tmpb_str
- { \xsim_rerun: }
- \bool_if:NF \l__xsim_empty_lists_bool
- {
- \xsim_add_property_to_aux:nn {#1}
- { { \seq_use:cV {g__xsim_list_#1_seq} \l__xsim_split_aux_lists_str } }
- }
- }
-
-% loop over list:
-% #1: name
-% #2: code
-\cs_new_protected:Npn \xsim_foreach_list_entry:nn #1#2
- { \seq_map_inline:cn {g__xsim_list_recorded_#1_seq} {#2} }
-
-\cs_new_protected:Npn \xsim_foreach_new_list_entry:nn #1#2
- { \seq_map_inline:cn {g__xsim_list_#1_seq} {#2} }
-
-% length of a list:
-% #1: name
-\cs_new:Npn \xsim_list_count:n #1
- { \seq_count:c {g__xsim_list_recorded_#1_seq} }
-
-% item of a list:
-% #1: name
-% #2: integer
-\cs_new:Npn \xsim_list_item:nn #1#2
- { \seq_item:cn {g__xsim_list_recorded_#1_seq} {#2} }
-
-% ----------------------------------------------------------------------------
-\file_input_stop:
-2020/03/16 - performance optimizations
diff --git a/Master/texmf-dist/tex/latex/xsim/xsim.base.code.tex b/Master/texmf-dist/tex/latex/xsim/xsim.base.code.tex
deleted file mode 100644
index fd478455f6a..00000000000
--- a/Master/texmf-dist/tex/latex/xsim/xsim.base.code.tex
+++ /dev/null
@@ -1,287 +0,0 @@
-% ----------------------------------------------------------------------------
-% 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:<nnn>
-\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
diff --git a/Master/texmf-dist/tex/latex/xsim/xsim.blanks.code.tex b/Master/texmf-dist/tex/latex/xsim/xsim.blanks.code.tex
deleted file mode 100644
index 6cb2f3b252f..00000000000
--- a/Master/texmf-dist/tex/latex/xsim/xsim.blanks.code.tex
+++ /dev/null
@@ -1,162 +0,0 @@
-% ----------------------------------------------------------------------------
-% the XSIM package - blanks 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{blanks}{add blanks, cloze}
-
-\bool_new:N \l__xsim_blank_width_bool
-\bool_new:N \l__xsim_blank_linespread_bool
-\bool_new:N \l__xsim_fill_blank_bool
-\tl_new:N \l__xsim_blank_linespread_tl
-\tl_new:N \l__xsim_blank_scale_tl
-\dim_new:N \l__xsim_blank_dim
-\dim_new:N \l__xsim_blank_line_increment_dim
-\dim_new:N \l__xsim_blank_line_minimum_length_dim
-\box_new:N \l__xsim_blank_box
-
-\cs_new_protected:Npn \xsim_write_cloze_blank:n #1 {#1}
-\cs_new_protected:Npn \xsim_write_cloze_filled:n #1 {#1}
-
-\keys_define:nn {xsim/blank}
- {
- blank-style .code:n =
- \cs_set_protected:Npn \xsim_write_cloze_blank:n ##1 {#1} ,
- blank-style .initial:n = \underline {#1} ,
- filled-style .code:n =
- \cs_set_protected:Npn \xsim_write_cloze_filled:n ##1 {#1} ,
- filled-style .initial:n = \underline {#1} ,
- style .meta:n =
- {
- blank-style = #1 ,
- filled-style = #1
- } ,
- fill .bool_set:N = \l__xsim_fill_blank_bool ,
- fill .initial:n = false ,
- scale .tl_set:N = \l__xsim_blank_scale_tl ,
- scale .initial:n = 1 ,
- width .code:n =
- {
- \bool_set_true:N \l__xsim_blank_width_bool
- \dim_set:Nn \l__xsim_blank_dim {#1}
- } ,
- linespread .code:n =
- \bool_set_true:N \l__xsim_blank_linespread_bool
- \tl_set:Nn \l__xsim_blank_linespread_tl {#1} ,
- linespread .initial:n = 1 ,
- line-increment .dim_set:N = \l__xsim_blank_line_increment_dim ,
- line-increment .initial:n = 0.001\linewidth ,
- line-minimum-length .dim_set:N = \l__xsim_blank_line_minimum_length_dim ,
- line-minimum-length .initial:n = 2em
- }
-
-\cs_new_protected:Npn \xsim_blank:n #1
- {
- \box_clear:N \l__xsim_blank_box
- \mode_if_math:TF
- { \hbox_set:Nn \l__xsim_blank_box { $ \m@th \mathpalette{}{#1} $ } }
- { \hbox_set:Nn \l__xsim_blank_box {#1} }
- \bool_lazy_or:nnTF
- { \xsim_if_inside_solution_p: }
- { \l__xsim_fill_blank_bool }
- { \xsim_write_cloze_filled:n {#1} }
- {
- \bool_if:NTF \l__xsim_blank_width_bool
- { \__xsim_blank_skip:V \l__xsim_blank_dim }
- { \__xsim_blank_skip:n { \box_wd:N \l__xsim_blank_box } }
- }
- }
-
-\cs_new_protected:Npn \__xsim_blank_skip:n #1
- {
- \bool_if:NTF \l__xsim_blank_width_bool
- { \dim_set:Nn \l__xsim_tmpa_dim {#1} }
- {
- \fp_set:Nn \l__xsim_tmpa_fp
- { \dim_to_fp:n {#1} * \l__xsim_blank_scale_tl }
- \dim_set:Nn \l__xsim_tmpa_dim { \fp_to_dim:N \l__xsim_tmpa_fp }
- }
- \dim_compare:nTF
- { \l__xsim_tmpa_dim > \l__xsim_blank_line_minimum_length_dim }
- {
- \mode_if_math:TF
- { \xsim_write_cloze_blank:n { \skip_horizontal:N \l__xsim_tmpa_dim } }
- {
- \dim_do_while:nn { \l__xsim_tmpa_dim > \c_zero_dim }
- {
- % I wonder what the correct l3 way would be -- if there is
- % one, yet:
- % \tex_hfil:D
- \tex_penalty:D \hyphenpenalty
- % \tex_hfilneg:D
- \dim_compare:nTF
- { \l__xsim_tmpa_dim < \l__xsim_blank_line_increment_dim }
- { \xsim_write_cloze_blank:n { \skip_horizontal:N \l__xsim_tmpa_dim } }
- {
- \xsim_write_cloze_blank:n
- { \skip_horizontal:N \l__xsim_blank_line_increment_dim }
- }
- \dim_sub:Nn \l__xsim_tmpa_dim { \l__xsim_blank_line_increment_dim }
- }
- }
- }
- {
- \xsim_write_cloze_blank:n
- { \skip_horizontal:N \l__xsim_blank_line_minimum_length_dim }
- }
- }
-\cs_generate_variant:Nn \__xsim_blank_skip:n {V}
-
-% ----------------------------------------------------------------------------
-\file_input_stop:
-
-the following code from Heiko Oberdieck in d.c.t.t served as inspiration
-and basis for the \blank command:
-https://groups.google.com/d/msg/de.comp.text.tex/fZLwraH04jE/o1RSdFXjGuIJ
-
-\makeatletter
-\newcommand*{\luecke}{%
- \begingroup
- \setlength{\dimen@}{6cm}%
- \ifdim\dimen@>2em %
- \underline{\hspace{1em}}%
- \advance\dimen@ by -2em\relax
- \@whiledim\dimen@>0pt\do{%
- \penalty\hyphenpenalty
- \ifdim\dimen@<1pt %
- \underline{\hspace{\dimen@}}%
- \else
- \underline{\hspace{1pt}}%
- \fi
- \advance\dimen@ by -1pt %
- }%
- \underline{\hspace{1em}}%
- \else
- \underline{\hspace{\dimen@}}%
- \fi
- \endgroup
- \xspace
-}
-\makeatother
diff --git a/Master/texmf-dist/tex/latex/xsim/xsim.collections.code.tex b/Master/texmf-dist/tex/latex/xsim/xsim.collections.code.tex
deleted file mode 100644
index 5aeb6e2d77e..00000000000
--- a/Master/texmf-dist/tex/latex/xsim/xsim.collections.code.tex
+++ /dev/null
@@ -1,397 +0,0 @@
-% ----------------------------------------------------------------------------
-% the XSIM package - collections 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{collections}{collect exercises and print collected exercises}
-
-\xsim_load_modules:n {base}
-
-\seq_new:N \g__xsim_collections_seq
-\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_exist:nTF {#1}
- { \msg_error:nnn {xsim} {collection-exists} {#1} }
- {
- \xsim_verbose:n { Declaring~ new~ collection~ `#1'. }
- \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}
- }
- }
-
-% #1: collection name
-\prg_new_conditional:Npnn \xsim_if_collection_exist:n #1 {T,F,TF}
- {
- \seq_if_in:NnTF \g__xsim_collections_seq {#1}
- { \prg_return_true: }
- { \prg_return_false: }
- }
-
-\xsim_new_collection:n {all~ exercises}
-
-\cs_new_protected:Npn \xsim_foreach_collection:n #1
- { \seq_map_inline:Nn \g__xsim_collections_seq {#1} }
-
-\cs_new:Npn \xsim_collection_map_break: { \seq_map_break: }
-
-% ----------------------------------------------------------------------------
-
-% #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'. }
- \xsim_attribute_set:nnn {collection} {#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'. }
- \xsim_attribute_set:nnn {collection} {#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_exist:nF {#1}
- { \msg_error:nnn {xsim} {unknown-collection} {#1} }
- \xsim_activate_collection:nn {#1} {#2}
- \xsim_setup:x { \xsim_get_parameter:nn {#2} {exercise-env} /print = false }
- }
-\cs_generate_variant:Nn \xsim_setup:n {x}
-
-% start collection for all exercise types:
-% #1: collection name
-\cs_new_protected:Npn \xsim_start_collection:n #1
- {
- \group_begin:
- \xsim_if_collection_exist:nF {#1}
- { \msg_error:nnn {xsim} {unknown-collection} {#1} }
- \xsim_activate_collection:n {#1}
- \xsim_foreach_exercise_type:n
- { \xsim_setup:x { \xsim_get_parameter:nn {##1} {exercise-env} /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:cnF {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_exist:nnT {##1} {####1}
- { \bool_set_true:N \l__xsim_tmpa_bool }
- }
- {
- \use:c
- {
- xsim_if_
- \l__xsim_print_collection_choice_tl
- _exist: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_exist:nnT {##1} {####1}
- { \xsim_insert:nnnn {##1} {####1} {} {exercise} }
- \xsim_if_solution_exist:nnT {##1} {####1}
- { \xsim_insert:nnnn {##1} {####1} {} {solution} }
- }
- {
- \use:c
- {
- xsim_if_
- \l__xsim_print_collection_choice_tl
- _exist: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}
- {
- \xsim_attribute_if_set:nnTF {collection} {#1}
- {
- \bool_lazy_and:nnTF
- { !\str_if_eq_p:en {#1} {all~ exercises} }
- { \xsim_attribute_get:nn {collection} {#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
- \xsim_foreach_collection:n
- {
- \xsim_if_collection_active:nT {##1}
- {
- \bool_set_true:N \l____xsim_active_bool
- \xsim_collection_map_break:
- }
- }
- \bool_if:NTF \l____xsim_active_bool
- { \prg_return_true: }
- { \prg_return_false: }
- }
-
-% ----------------------------------------------------------------------------
-
-\xsim_at_begin_document:n
- {
- \xsim_get_collections:
- \xsim_activate_collection:n {all~ exercises}
- }
-
-\xsim_at_end_document:n
- {
- \xsim_deactivate_collection:n {all~ exercises}
- \xsim_foreach_collection:n { \xsim_update_list:n {collection:#1} }
- }
-
-% ----------------------------------------------------------------------------
-\file_input_stop:
diff --git a/Master/texmf-dist/tex/latex/xsim/xsim.definitions.code.tex b/Master/texmf-dist/tex/latex/xsim/xsim.definitions.code.tex
deleted file mode 100644
index 5b87fb0f4f8..00000000000
--- a/Master/texmf-dist/tex/latex/xsim/xsim.definitions.code.tex
+++ /dev/null
@@ -1,482 +0,0 @@
-% ----------------------------------------------------------------------------
-% the XSIM package - definitions 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{definitions}{definition of user commands}
-
-\xsim_load_modules:n {base,exercises,blanks,translations,interface,grades,random}
-
-% not exactly a user choice: the `exercises' environments rely on them:
-\DeclareExerciseParameter*!{exercise-env}
-\DeclareExerciseParameter*!{solution-env}
-\DeclareExerciseParameter !{exercise-name}
-\DeclareExerciseParameter !{solution-name}
-\DeclareExerciseParameter {exercises-name}
-\DeclareExerciseParameter {solutions-name}
-\DeclareExerciseParameter !{exercise-template}
-\DeclareExerciseParameter !{solution-template}
-\DeclareExerciseParameter* {counter}
-\DeclareExerciseParameter* {solution-counter}
-\DeclareExerciseParameter* {number}
-
-% these are additional - but are used in the `default' environment
-% template:
-\DeclareExerciseParameter {exercise-heading}
-\DeclareExerciseParameter {solution-heading}
-
-% ----------------------------------------------------------------------------
-
-% not exactly a user choice, must be present at various places:
-\DeclareExerciseProperty! {id}
-\DeclareExerciseProperty! {ID}
-\DeclareExerciseProperty {counter}
-\DeclareExerciseProperty {counter-value}
-\DeclareExerciseProperty * {print}
-\DeclareExerciseProperty *-{print!}
-\DeclareExerciseProperty * {use}
-\DeclareExerciseProperty * {used}
-\DeclareExerciseProperty *-{use!}
-\DeclareExerciseProperty * {solution}
-\XSIMifchapterT{
- \DeclareExerciseProperty {chapter-value}
- \DeclareExerciseProperty {chapter}
-}
-\DeclareExerciseProperty {section-value}
-\DeclareExerciseProperty {section}
-\DeclareExerciseProperty {sectioning}
-
-% those are additional and wouldn't *need* to be present except for
-% pre-defined templates which make use of them (the page and page-value
-% property actually needs to be defined for xsim to be able to save the
-% corresponding values):
-\DeclareExerciseProperty {subtitle}
-\DeclareExerciseProperty {points}
-\DeclareExerciseProperty {bonus-points}
-\DeclareExerciseProperty {page-value}
-\DeclareExerciseProperty {page}
-
-\DeclareExercisePropertyAlias {ID} {id}
-
-% ----------------------------------------------------------------------------
-
-\DeclareExerciseTagging {tags}
-\DeclareExerciseTagging {topics}
-
-\xsimsetup{tags/ignore-untagged=false}
-
-% ----------------------------------------------------------------------------
-
-\DeclareExerciseGoal {points}
-\DeclareExerciseGoal {bonus-points}
-
-\NewDocumentCommand \printgoal {m}
- { \ExerciseGoalValuePrint {#1} {} {} }
-
-\NewDocumentCommand \points {m}
- {
- \ExerciseGoalValuePrint {#1}
- { \, \XSIMtranslate {point} }
- { \, \XSIMtranslate {points} }
- }
-
-\NewDocumentCommand \addpoints {sm}
- {
- \AddtoExerciseGoal {points} {#2}
- \IfBooleanF {#1} { \points {#2} }
- }
-
-\NewDocumentCommand \printpoints {m}
- {
- \TotalExerciseTypeGoal {#1} {points}
- { \, \XSIMtranslate {point} }
- { \, \XSIMtranslate {points} }
- }
-
-\NewDocumentCommand \printtotalpoints {}
- {
- \TotalExerciseGoal {points}
- { \, \XSIMtranslate {point} }
- { \, \XSIMtranslate {points} }
- }
-
-\NewDocumentCommand \addbonus {sm}
- {
- \AddtoExerciseGoal {bonus-points} {#2}
- \IfBooleanF {#1} { \points {#2} }
- }
-
-\NewDocumentCommand \printbonus {m}
- {
- \TotalExerciseTypeGoal {#1} {bonus-points}
- { \, \XSIMtranslate {point} }
- { \, \XSIMtranslate {points} }
- }
-
-\NewDocumentCommand \printtotalbonus {}
- {
- \TotalExerciseGoal {bonus-points}
- { \, \XSIMtranslate {point} }
- { \, \XSIMtranslate {points} }
- }
-
-% ----------------------------------------------------------------------------
-\NewDocumentCommand \pointsforgrade {m}
- {
- \GetGradeRequirementForGoal {#1} {points}
- { \, \XSIMtranslate {point} }
- { \, \XSIMtranslate {points} }
- }
-
-\NewDocumentCommand \goalsforgrade {mm}
- {
- \GetGradeRequirementForGoals {#2} {#1}
- { \, \XSIMtranslate {point} }
- { \, \XSIMtranslate {points} }
- }
-
-\NewDocumentCommand \totalgoalforgrade {m}
- {
- \GetGradeRequirement {#1}
- { \, \XSIMtranslate {point} }
- { \, \XSIMtranslate {points} }
- }
-
-% ----------------------------------------------------------------------------
-
-\xsim_if_package_blank:F
- {
- \DeclareExerciseType {exercise} {
- exercise-env = exercise ,
- solution-env = solution ,
- exercise-name = \XSIMtranslate {exercise} ,
- exercises-name = \XSIMtranslate {exercises} ,
- solution-name = \XSIMtranslate {solution} ,
- solutions-name = \XSIMtranslate {solutions} ,
- exercise-template = default ,
- solution-template = default ,
- exercise-heading = \subsection* ,
- solution-heading = \subsection*
- }
- }
-
-% ----------------------------------------------------------------------------
-
-\DeclareExerciseEnvironmentTemplate {default}
- {
- \GetExerciseHeadingF { \subsection* }
- {
- \XSIMmixedcase { \GetExerciseName } \nobreakspace
- \GetExerciseProperty {counter}
- \IfInsideSolutionF
- {
- \IfExercisePropertySetT {subtitle}
- { ~ { \normalfont \itshape \GetExerciseProperty {subtitle} } }
- }
- }
- \GetExercisePropertyT {points}
- {
- \marginpar
- {
- \IfInsideSolutionF { \rule {1.2cm} {1pt} \slash }
- \printgoal {\PropertyValue}
- \GetExercisePropertyT {bonus-points}
- { \nobreakspace ( + \printgoal {\PropertyValue} ) }
- \nobreakspace\XSIMtranslate {point-abbr}
- }
- }
- }
- { \par }
-
-% ----------------------------------------------------------------------------
-
-\DeclareExerciseHeadingTemplate {none} {}
-
-\DeclareExerciseHeadingTemplate {default}
- { \section* { \XSIMtranslate {default-heading} } }
-
-\DeclareExerciseHeadingTemplate {collection}
- { \section* { \XSIMtranslate {collection-heading} } }
-
-\DeclareExerciseHeadingTemplate {per-section}
- { \section* { \XSIMtranslate {per-section-heading} } }
-
-\DeclareExerciseHeadingTemplate {per-chapter}
- { \section* { \XSIMtranslate {per-chapter-heading} } }
-
-% ----------------------------------------------------------------------------
-
-\RequirePackage{array,booktabs}
-
-\DeclareExerciseTableTemplate {default*}
- {
- \XSIMputright \ExerciseTableCode
- {
- \toprule
- \XSIMifblankTF {\ExerciseType}
- {}
- { \XSIMmixedcase { \GetExerciseParameter {exercise-name} } }
- &
- }
- \ForEachUsedExerciseByType
- {
- \XSIMifeqTF {#1} { \ExerciseTableType {#1} }
- {
- \XSIMifblankTF { \ExerciseType }
- {
- \XSIMputright \ExerciseTableCode
- {
- \XSIMmixedcase
- { \ExerciseParameterGet {#1} {exercise-name} ~ }
- }
- }
- {}
- \XSIMputright \ExerciseTableCode { #3 & }
- }
- {}
- }
- \XSIMputright \ExerciseTableCode
- {
- \XSIMtranslate {total} \\
- \midrule \XSIMmixedcase { \XSIMtranslate {points} } &
- }
- \ForEachUsedExerciseByType
- {
- \XSIMifeqTF {#1} { \ExerciseTableType {#1} }
- {
- \XSIMputright \ExerciseTableCode
- { \XSIMifblankTF {#5} {\printgoal{0}} {\printgoal{#5}} & }
- }
- {}
- }
- \XSIMputright \ExerciseTableCode
- {
- \XSIMifblankTF {\ExerciseType}
- { \TotalExerciseGoal {points} {} {} }
- { \TotalExerciseTypeGoal {\ExerciseType} {points} {} {} }
- \\ \midrule
- \XSIMtranslate {reached} &
- }
- \ForEachUsedExerciseByType
- {
- \XSIMifeqTF {#1} { \ExerciseTableType {#1} }
- { \XSIMputright \ExerciseTableCode {&} }
- {}
- }
- \XSIMputright \ExerciseTableCode { \\ \bottomrule }
- \def\numberofcolumns{
- \XSIMifblankTF {\ExerciseType}
- {\numberofusedexercises}
- {\csname numberof \ExerciseType s\endcsname}
- }
- \XSIMifeqF{\numberofcolumns}{0}
- {
- \begin {tabular} {l*{\numberofcolumns}{c}c}
- \ExerciseTableCode
- \end {tabular}
- }
- }
-
-\DeclareExerciseTableTemplate {default}
- {
- \XSIMputright \ExerciseTableCode
- {
- \toprule
- \XSIMifblankTF {\ExerciseType}
- {}
- { \XSIMmixedcase { \GetExerciseParameter {exercise-name} } }
- &
- \XSIMmixedcase { \XSIMtranslate {points} } &
- \XSIMtranslate {reached} \\
- \midrule
- }
- \ForEachUsedExerciseByType
- {
- \XSIMifeqTF {#1} { \ExerciseTableType {#1} }
- {
- \XSIMifblankTF { \ExerciseType }
- {
- \XSIMputright \ExerciseTableCode
- {
- \XSIMmixedcase
- { \ExerciseParameterGet {#1} {exercise-name} ~ }
- }
- }
- {}
- \XSIMputright \ExerciseTableCode
- { #3 & \XSIMifblankTF {#5} {\printgoal{0}} {\printgoal{#5}} & \\ }
- }
- {}
- }
- \XSIMputright \ExerciseTableCode
- {
- \midrule
- \XSIMtranslate {total} &
- \XSIMifblankTF {\ExerciseType}
- { \TotalExerciseGoal {points} {} {} }
- { \TotalExerciseTypeGoal {\ExerciseType} {points} {} {} } &
- \\ \bottomrule
- }
- \XSIMexpandcode
- {
- \noexpand \begin {tabular} {\XSIMifblankTF{\ExerciseType}{l}{c}cc}
- \noexpand \ExerciseTableCode
- \noexpand \end {tabular}
- }
- }
-
-% ----------------------------------------------------------------------------
-
-\DeclareExerciseTranslations {exercise} {
- Fallback = exercise ,
- English = exercise ,
- French = exercice ,
- German = \"Ubung
-}
-
-\DeclareExerciseTranslations {exercises} {
- Fallback = exercises ,
- English = exercises ,
- French = exercices ,
- German = \"Ubungen
-}
-
-\DeclareExerciseTranslations {question} {
- Fallback = question ,
- English = question ,
- French = question ,
- German = Aufgabe
-}
-
-\DeclareExerciseTranslations {questions} {
- Fallback = questions ,
- English = questions ,
- French = questions ,
- German = Aufgaben
-}
-
-\DeclareExerciseTranslations {solution} {
- Fallback = solution ,
- English = solution ,
- French = solution ,
- German = L\"osung
-}
-
-\DeclareExerciseTranslations {solutions} {
- Fallback = solutions ,
- English = solutions ,
- French = solutions ,
- German = L\"osungen
-}
-
-\DeclareExerciseTranslations {point-abbr} {
- Fallback = p. ,
- English = p. ,
- French = p. ,
- German = P.
-}
-
-\DeclareExerciseTranslations {point} {
- Fallback = point ,
- English = point ,
- French = point ,
- German = Punkt
-}
-
-\DeclareExerciseTranslations {points} {
- Fallback = points ,
- English = points ,
- French = points ,
- German = Punkte
-}
-
-\DeclareExerciseTranslations {reached} {
- Fallback = reached ,
- English = reached ,
- French = obtenus ,
- German = erreicht
-}
-
-\DeclareExerciseTranslations {total} {
- Fallback = total ,
- English = total ,
- French = total ,
- German = insgesamt
-}
-
-\DeclareExerciseTranslations {default-heading} {
- Fallback = \XSIMmixedcase { \GetExerciseParameter {solutions-name} }~
- to~ the~ \XSIMmixedcase { \GetExerciseParameter {exercises-name} } ,
- English = \XSIMmixedcase { \GetExerciseParameter {solutions-name} }~
- to~ the~ \XSIMmixedcase { \GetExerciseParameter {exercises-name} } ,
- French = \XSIMmixedcase { \GetExerciseParameter {solutions-name} ~
- des~ \GetExerciseParameter {exercises-name} } ,
- German = \XSIMmixedcase { \GetExerciseParameter {solutions-name} }~
- zu~ den~ \XSIMmixedcase { \GetExerciseParameter {exercises-name} }
-}
-
-\DeclareExerciseTranslations {collection-heading} {
- Fallback = \XSIMmixedcase { \GetExerciseParameter {exercises-name} } ,
- English = \XSIMmixedcase { \GetExerciseParameter {exercises-name} } ,
- French = \XSIMmixedcase { \GetExerciseParameter {exercises-name} } ,
- German = \XSIMmixedcase { \GetExerciseParameter {exercises-name} }
-}
-
-\DeclareExerciseTranslations {per-section-heading} {
- Fallback = \XSIMmixedcase { \GetExerciseParameter {solutions-name} } ~
- to~ the~ \XSIMmixedcase { \GetExerciseParameter {exercises-name} } ~
- of~ Section \nobreakspace \ExerciseSection ,
- English = \XSIMmixedcase { \GetExerciseParameter {solutions-name} } ~
- to~ the~ \XSIMmixedcase { \GetExerciseParameter {exercises-name} } ~
- of~ Section \nobreakspace \ExerciseSection ,
- French = \XSIMmixedcase { \GetExerciseParameter {solutions-name} ~
- des~ \GetExerciseParameter {exercises-name} ~ de~ la~
- section \nobreakspace \ExerciseSection } ,
- German = \XSIMmixedcase { \GetExerciseParameter {solutions-name} } ~
- zu~ den~ \XSIMmixedcase { \GetExerciseParameter {exercises-name} }~
- in~ Abschnitt \nobreakspace \ExerciseSection
-}
-
-\DeclareExerciseTranslations {per-chapter-heading} {
- Fallback = \XSIMmixedcase { \GetExerciseParameter {solutions-name} } ~
- to~ the~ \XSIMmixedcase { \GetExerciseParameter {exercises-name} } ~
- of~ Chapter \nobreakspace \ExerciseChapter ,
- English = \XSIMmixedcase { \GetExerciseParameter {solutions-name} } ~
- to~ the~ \XSIMmixedcase { \GetExerciseParameter {exercises-name} } ~
- of~ Chapter \nobreakspace \ExerciseChapter ,
- French = \XSIMmixedcase { \GetExerciseParameter {solutions-name} ~
- des~ \GetExerciseParameter {exercises-name} ~
- du~ chapitre \nobreakspace \ExerciseChapter } ,
- German = \XSIMmixedcase { \GetExerciseParameter {solutions-name} } ~
- zu~ den~ \XSIMmixedcase { \GetExerciseParameter {exercises-name} } ~
- in~ Kapitel \nobreakspace \ExerciseChapter
-}
-
-% ----------------------------------------------------------------------------
-\file_input_stop:
-
-2019/02/17 - fix issue #39 (error in German translations)
-2020/02/19 - implement issue #33 (solution property)
-2020/02/20 - implement issue #31 (blank package option)
diff --git a/Master/texmf-dist/tex/latex/xsim/xsim.environments.code.tex b/Master/texmf-dist/tex/latex/xsim/xsim.environments.code.tex
deleted file mode 100644
index ca5f76f80a7..00000000000
--- a/Master/texmf-dist/tex/latex/xsim/xsim.environments.code.tex
+++ /dev/null
@@ -1,529 +0,0 @@
-% ----------------------------------------------------------------------------
-% the XSIM package - environments 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{environments}{generic code for exercise and solution environments}
-
-\xsim_load_modules:n {templates,verbwrite}
-
-\xsim_if_write_to_files:F
- {
- \xsim_declare_property:nnnn
- { \c_false_bool }
- { \c_false_bool }
- { \c_false_bool }
- {solution-body}
- \xsim_declare_property:nnnn
- { \c_false_bool }
- { \c_false_bool }
- { \c_false_bool }
- {exercise-body}
- }
-
-\tl_new:N \l__xsim_file_name_signature_tl
-\tl_new:N \l__xsim_file_path_tl
-\tl_new:N \l__xsim_file_path_and_name_tl
-\tl_new:N \l__xsim_file_name_tl
-\tl_new:N \l__xsim_file_extension_tl
-\tl_new:N \l__xsim_solution_tl
-\bool_new:N \l__xsim_options_given_bool
-\bool_new:N \l__xsim_insert_mode_bool
-
-\tl_new:N \ExerciseText
-\tl_set:Nn \ExerciseText { \msg_error:nn {xsim} {only-in-solution} }
-
-% ----------------------------------------------------------------------------
-
-\msg_new:nnn {xsim} {only-in-solution}
- {
- You~ can't~ use~ \token_to_str:N \ExerciseText \c_space_tl inside~ an~
- exercise.~ It~ is~ only~ allowed~ inside~ solution~ environments!
- }
-
-% ----------------------------------------------------------------------------
-
-\keys_define:nn {xsim}
- {
- path .tl_set:N = \l__xsim_file_path_tl ,
- file-extension .tl_set:N = \l__xsim_file_extension_tl ,
- file-extension .initial:n = tex
- }
-
-% ----------------------------------------------------------------------------
-
-\tl_const:Nn \c__xsim_comment_line_tl { \c__xsim_percent_char_tl }
-\tl_const:Nn \c__xsim_comment_line_fill_tl { \prg_replicate:nn {72} {-} }
-\tl_const:Nn \c__xsim_comment_line_indent_tl { \c_space_tl \c_space_tl }
-
-\cs_new:Npn \__xsim_comment_line_and_feed:n #1
- { \__xsim_comment_line:n {#1} ^^J }
-
-\cs_new:Npn \__xsim_comment_line:n #1
- {
- \c__xsim_comment_line_tl
- \tl_if_blank:nF {#1} { \c_space_tl }
- #1
- }
-
-\cs_new:Npn \__xsim_two_digits:n #1
- { \int_compare:nT { #1 < 10 } {0} \int_eval:n {#1} }
-
-% #1: type
-% #2: id
-% #3: exercise|solution
-\cs_new_protected:Npn \__xsim_set_file_signature:nnn #1#2#3
- { \tl_set:Nn \l__xsim_file_name_signature_tl {#1-#2-#3} }
-\cs_generate_variant:Nn \__xsim_set_file_signature:nnn {nx,nV}
-
-\tl_set:Nn \l__xsim_file_name_tl
- { \c_sys_jobname_str - \l__xsim_file_name_signature_tl -body . \l__xsim_file_extension_tl }
-
-\tl_set:Nn \l__xsim_file_path_and_name_tl
- {
- \tl_if_blank:VF \l__xsim_file_path_tl
- { \l__xsim_file_path_tl / }
- \l__xsim_file_name_tl
- }
-
-% #1: type
-% #2: id
-% #3: exercise|solution
-% #4: file name
-% #5: path
-\cs_new_protected:Npn \__xsim_file_info:nnnnn #1#2#3#4#5
- {
- \tl_set:Nn \l_xsim_file_begin_tl
- {
- \__xsim_comment_line_and_feed:n { \c__xsim_comment_line_fill_tl }
- \__xsim_comment_line_and_feed:n {file~ `#4'}
- \tl_if_blank:nF {#5}
- {
- \__xsim_comment_line_and_feed:n
- { \c__xsim_comment_line_indent_tl in~ folder~ `#5/'}
- }
- \__xsim_comment_line_and_feed:n {}
- \__xsim_comment_line_and_feed:n
- {
- \c__xsim_comment_line_indent_tl
- \c__xsim_comment_line_indent_tl
- #3~ of~ type~ `#1'~ with~ id~ `#2'
- }
- \__xsim_comment_line_and_feed:n {}
- \__xsim_comment_line_and_feed:n
- {generated~ by~ the~ `\@currenvir'~ environment~ of~ the}
- \__xsim_comment_line_and_feed:n
- {
- \c__xsim_comment_line_indent_tl
- `xsim'~ package~ v \c_xsim_version_tl
- \c_space_tl (\c_xsim_date_tl)
- }
- \__xsim_comment_line_and_feed:n
- {
- from~ source~ `\c_sys_jobname_str'~ on~
- \int_use:N \c_sys_year_int /
- \__xsim_two_digits:n { \c_sys_month_int } /
- \__xsim_two_digits:n { \c_sys_day_int } ~
- \msg_line_context:
- }
- \__xsim_comment_line:n { \c__xsim_comment_line_fill_tl }
- }
- }
-\cs_generate_variant:Nn \__xsim_file_info:nnnnn {nnnVV}
-
-% ----------------------------------------------------------------------------
-% #1: type
-% #2: id
-% #3: exercise|solution
-% #4: potential environment body
-\cs_new_protected:Npn \xsim_save_environment_body:nnnn #1#2#3#4
- {
- \xsim_if_write_to_files:TF
- { \__xsim_write_environment_body:nnn {#1} {#2} {#3} }
- { \__xsim_save_environment_body:nnnn {#1} {#2} {#3} {#4} }
- }
-
-\cs_new_protected:Npn \xsim_save_environment_body_end:
- {
- \xsim_if_write_to_files:TF
- { \__xsim_write_environment_body_end: }
- { \__xsim_save_environment_body_end: }
- }
-
-% writing to files:
-% #1: type
-% #2: id
-% #3: exercise|solution
-\cs_new_protected:Npn \__xsim_write_environment_body:nnn #1#2#3
- {
- \xsim_verbose:n
- { Starting~ to~ write~ #3~ environment~ type~ `#1'~ id~ `#2' }
- \__xsim_set_file_signature:nnn {#1} {#2} {#3}
- \__xsim_file_info:nnnVV {#1} {#2} {#3}
- \l__xsim_file_name_tl
- \l__xsim_file_path_tl
- \int_zero:N \l_xsim_line_gobble_int
- \xsim_file_write_start:nV
- { \l__xsim_options_given_bool }
- \l__xsim_file_path_and_name_tl
- }
-
-\cs_new_protected:Npn \__xsim_write_environment_body_end:
- { \xsim_file_write_stop: }
-
-% saving to property lists:
-% #1: type
-% #2: id
-% #3: exercise|solution
-% #4: environment body
-\cs_new_protected:Npn \__xsim_save_environment_body:nnnn #1#2#3#4
- {
- \xsim_verbose:n { Saving~ #3~ environment~ type~ `#1'~ id~ `#2' }
- \xsim_set_property:nnnn {#1} {#2} {#3-body} {#4}
- }
-
-\cs_new:Npn \__xsim_save_environment_body_end: { }
-
-% ----------------------------------------------------------------------------
-% #1: type
-% #2: exercise|solution
-% #3: hook
-\cs_new_protected:Npn \xsim_new_hook:nnn #1#2#3
- {
- \xsim_verbose:n { Defining~ new~ #1~ (#2)~ hook~ `#3' }
- \tl_new:c {l__xsim_#1_#2_#3_hook_tl}
- \keys_define:nx {xsim}
- {
- \xsim_get_parameter:nn {#1} {#2-env}/#3-hook .tl_set:N =
- \exp_not:c {l__xsim_#1_#2_#3_hook_tl}
- }
- }
-
-% #1: type
-% #2: exercise|solution
-% #3: hook
-\cs_new:Npn \xsim_use_hook:nnn #1#2#3
- { \exp_not:v {l__xsim_#1_#2_#3_hook_tl} }
-
-% #1: type
-% #2: exercise|solution
-% #3: hook
-% #4: code
-\cs_new_protected:Npn \xsim_set_hook:nnnn #1#2#3#4
- {
- \xsim_verbose:n { Setting~ #1~ (#2)~ hook~ `#3' }
- \tl_set:cn {l__xsim_#1_#2_#3_hook_tl} {#4}
- }
-
-% #1: type
-% #2: exercise|solution
-% #3: hook
-% #4: code
-\cs_new_protected:Npn \xsim_addto_hook:nnnn #1#2#3#4
- {
- \xsim_verbose:n { Adding~ to~ #1~ (#2)~ hook~ `#3' }
- \tl_put_right:cn {l__xsim_#1_#2_#3_hook_tl} {#4}
- }
-
-% ----------------------------------------------------------------------------
-
-% #1: type
-% #2: id
-% #3: exercise|solution
-% #4: potential enironment body
-\cs_new_protected:Npn \xsim_start_environment:nnnn #1#2#3#4
- { \xsim_save_environment_body:nnnn {#1} {#2} {#3} {#4} }
-\cs_generate_variant:Nn \xsim_start_environment:nnnn {nV}
-
-% #1: type
-% #2: id
-% #3: exercise|solution
-\cs_new_protected:Npn \xsim_stop_environment:nnn #1#2#3
- {
- \xsim_save_environment_body_end:
- \xsim_if_print:nnnTF {#1} {#2} {#3}
- { \xsim_typeset_environment:nnn {#1} {#2} {#3} }
- { \xsim_use_hook:nnn {#1} {#3} {print-false} }
- }
-\cs_generate_variant:Nn \xsim_stop_environment:nnn {nV}
-
-% #1: type
-% #2: id
-% #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
- { Typesetting~ #3~ environment~ type~ `#1'~ id~ `#2' }
- \xsim_use_hook:nnn {#1} {#3} {pre}
- \xsim_use_template:nx
- {begin}
- { \xsim_get_parameter:nn {#1} {#3-template} }
- \xsim_use_hook:nnn {#1} {#3} {begin}
- \xsim_if_write_to_files:TF
- {
- \file_if_exist:nTF { \exp_not:V \l__xsim_file_path_and_name_tl }
- { \file_input:n { \exp_not:V \l__xsim_file_path_and_name_tl } }
- {
- \xsim_verbose:n
- { File~ `\l__xsim_file_path_and_name_tl'~ doesn't~ exist. }
- }
- }
- {
- \xsim_if_exchange:nnnTF {#1} {#2} {#3}
- { \xsim_get_property:nnn {#1} {#2} {exercise-body} }
- { \xsim_get_property:nnn {#1} {#2} {#3-body} }
- }
- \xsim_synchronize_goals:nn {#1} {#2}
- \str_if_eq:nnT {#3} {exercise}
- { \xsim_update_goals:nn {#1} {#2} }
- \xsim_use_hook:nnn {#1} {#3} {end}
- \xsim_use_template:nx
- {end}
- { \xsim_get_parameter:nn {#1} {#3-template} }
- \xsim_use_hook:nnn {#1} {#3} {post}
- }
-
-% #1: type
-% #2: id
-% #3: exercise|solution
-\prg_new_conditional:Npnn \xsim_if_exchange:nnn #1#2#3 {T,F,TF}
- {
- \str_if_eq:nnTF {#3} {solution}
- {
- \xsim_if_boolean_property:nnnTF {#1} {#2} {solution}
- { \prg_return_true: }
- { \prg_return_false: }
- }
- { \prg_return_false: }
- }
-
-% #1: type
-% #2: id
-% #3: exercise|solution
-\prg_new_protected_conditional:Npnn \xsim_if_exist:nnn #1#2#3 {T,F,TF}
- {
- \xsim_if_write_to_files:TF
- {
- \__xsim_set_file_signature:nnn {#1} {#2} {#3}
- \file_if_exist:VTF \l__xsim_file_path_and_name_tl
- { \prg_return_true: }
- { \prg_return_false: }
- }
- {
- \xsim_if_property_exist:nTF {#3-body}
- {
- \xsim_if_property_set:nnnTF {#1} {#2} {#3-body}
- { \prg_return_true: }
- { \prg_return_false: }
- }
- { \prg_return_false: }
- }
- }
-
-% #1: type
-% #2: id
-% #3: options
-% #4: exercise|solution
-\cs_new_protected:Npn \xsim_insert:nnnn #1#2#3#4
- {
- \xsim_if_exchange:nnnTF {#1} {#2} {#4}
- { \xsim_if_exist:nnnTF {#1} {#2} {exercise} }
- { \xsim_if_exist:nnnTF {#1} {#2} {#4} }
- {
- \xsim_verbose:n
- { Inserting~ #4~ type~ `#1'~ id~ `#2'. }
- \group_begin:
- \xsim_insert_mode:
- \use:c {xsim_start_#4:nn} {#1} {#3}
- \tl_set:Nn \ExerciseType {#1}
- \tl_set:Nn \ExerciseID {#2}
- \str_if_eq:nnT {#4} {exercise}
- {
- \xsim_if_boolean_property:nnnF {#1} {#2} {used}
- {
- \xsim_step_exercise_counter:nn {#1} {#2}
- \xsim_set_properties:nnx {#1} {#2}
- {
- page-value = \the\value{page} ,
- page = \thepage ,
- section-value = \the\value{section} ,
- section = \thesection
- }
- \xsim_synchronize_goals:nn {#1} {#2}
- \xsim_update_goals:nn {#1} {#2}
- }
- \xsim_if_property_exist:nT {chapter}
- {
- \xsim_set_properties:nnx {#1} {#2}
- {
- chapter-value = \the\value{chapter} ,
- chapter = \thechapter
- }
- }
- \xsim_set_properties:nnn {#1} {#2}
- { print=true , used=true }
- }
- \str_if_eq:nnT {#4} {solution}
- {
- \xsim_if_write_to_files:TF
- {
- \__xsim_set_file_signature:nnn {#1} {#2} {exercise}
- \file_get:nnN {\l__xsim_file_path_and_name_tl} {} \ExerciseText
- \tl_trim_spaces:N \ExerciseText
- }
- {
- \tl_set:Nx \ExerciseText
- { \xsim_get_property:nnn {#1} {#2} {exercise-body} }
- }
- }
- \use:x
- {
- \xsim_use_hook:nnn {#1} {#4} {pre}
- \xsim_use_template:nn
- {begin}
- { \xsim_get_parameter:nn {#1} {#4-template} }
- \xsim_use_hook:nnn {#1} {#4} {begin}
- \xsim_input:nnn {#1} {#2} {#4}
- \xsim_use_hook:nnn {#1} {#4} {end}
- \xsim_use_template:nn
- {end}
- { \xsim_get_parameter:nn {#1} {#4-template} }
- \xsim_use_hook:nnn {#1} {#4} {post}
- }
- \group_end:
- }
- {
- \xsim_if_write_to_files:T
- {
- \xsim_verbose:x
- { File~ `\l__xsim_file_path_and_name_tl'~ doesn't~ exist. }
- }
- }
- }
-\cs_generate_variant:Nn \xsim_insert:nnnn {nV,VV,nnnV,xx,ne}
-
-% #1: type
-% #2: id
-% #3: exercise|solution
-\cs_new_protected:Npn \xsim_input:nnn #1#2#3
- {
- \group_begin:
- \xsim_if_write_to_files:TF
- {
- \xsim_if_exchange:nnnTF {#1} {#2} {#3}
- { \__xsim_set_file_signature:nnn {#1} {#2} {exercise} }
- { \__xsim_set_file_signature:nnn {#1} {#2} {#3} }
- \file_input:n { \l__xsim_file_path_and_name_tl }
- }
- {
- \xsim_if_exchange:nnnTF {#1} {#2} {#3}
- { \xsim_get_property:nnn {#1} {#2} {exercise-body} }
- { \xsim_get_property:nnn {#1} {#2} {#3-body} }
- }
- \group_end:
- }
-\cs_generate_variant:Nn \xsim_input:nnn {oo}
-
-\prg_new_conditional:Npnn \xsim_if_insert_mode: {T,F,TF}
- {
- \bool_if:NTF \l__xsim_insert_mode_bool
- { \prg_return_true: }
- { \prg_return_false: }
- }
-
-\cs_new_protected:Npn \xsim_insert_mode:
- { \bool_set_true:N \l__xsim_insert_mode_bool }
-
-% ----------------------------------------------------------------------------
-
-% #1: type
-% #2: exercise|solution
-\cs_new_protected:Npn \xsim_new_environment:nn #1#2
- {
- \xsim_verbose:n { Defining~ #2~ environment~ type~ `#1'. }
- \xsim_new_hook:nnn {#1} {#2} {pre}
- \xsim_new_hook:nnn {#1} {#2} {begin}
- \xsim_new_hook:nnn {#1} {#2} {end}
- \xsim_new_hook:nnn {#1} {#2} {post}
- \xsim_new_hook:nnn {#1} {#2} {print-false}
- \xsim_if_write_to_files:TF
- {
- \NewDocumentEnvironment
- { \xsim_get_parameter:nn {#1} {#2-env} } {!o}
- {
- \IfNoValueTF {##1}
- {
- \bool_set_false:N \l__xsim_options_given_bool
- \use:c {xsim_start_#2:nn} {#1} {}
- }
- {
- \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} { }
- }
- {
- \xsim_stop_environment:nVn {#1} \g_xsim_exercise_id_tl {#2}
- \use:c {xsim_stop_#2:n} {#1}
- }
- }
- {
- \NewDocumentEnvironment
- { \xsim_get_parameter:nn {#1} {#2-env} } {o+b}
- {
- \IfNoValueTF {##1}
- {
- \bool_set_false:N \l__xsim_options_given_bool
- \use:c {xsim_start_#2:nn} {#1} {}
- }
- {
- \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_stop_environment:nVn {#1} \g_xsim_exercise_id_tl {#2}
- \use:c {xsim_stop_#2:n} {#1}
- }
- }
- }
-
-% ----------------------------------------------------------------------------
-\file_input_stop:
-
-2019/02/17 - fix issue #43
-2019/10/03 - add possibility to save environment bodies to property list
-2020/02/15 - remove spurious \par at the beginning and end of typeset
- exercises and solutions
-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/Master/texmf-dist/tex/latex/xsim/xsim.exercises.code.tex b/Master/texmf-dist/tex/latex/xsim/xsim.exercises.code.tex
deleted file mode 100644
index 5314369ffad..00000000000
--- a/Master/texmf-dist/tex/latex/xsim/xsim.exercises.code.tex
+++ /dev/null
@@ -1,637 +0,0 @@
-% ----------------------------------------------------------------------------
-% the XSIM package - exercises 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{exercises}{main exercises definitions}
-
-\xsim_load_modules:n
- {
- base, properties, environments, templates, solutions, tags, goals,
- 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
-\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 \g_xsim_exercise_type_tl
-\tl_new:N \ExerciseID
-\tl_new:N \ExerciseType
-\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'.
- }
-
-\msg_new:nnn {xsim} {unknown-parameter}
- {
- You~ tried~ to~ retrieve~ the~ parameter~ `#1'~ \msg_line_context: . \\
- This~ parameter~ does~ not~ exist.~ Check~ for~ a~ typo~ or~ \\
- define~ the~ parameter~ yourself.
- }
-
-% ----------------------------------------------------------------------------
-% #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}
-
-% #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_set: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}
- {
- \seq_if_in:NnTF \l__xsim_exercise_types_seq {#1}
- { \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_set: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'. }
- \__xsim_set_parameter_type:nnn {#1} {#2} {#3}
- }
- }
- {
- \xsim_verbose:n
- { Setting~ parameter~ `#2'~ for~ type~ `#1'~ to~ `#3'. }
- \__xsim_set_parameter_type:nnn {#1} {#2} {#3}
- }
- }
- }
-\cs_generate_variant:Nn \xsim_set_parameter:nnn {nnx,nxx}
-
-\cs_new:Npn \__xsim_get_parameter_tmp:n #1 {}
-\cs_generate_variant:Nn \__xsim_get_parameter_tmp:n {V}
-
-% #1: type
-% #2: parameter
-\cs_new_protected:Npn \xsim_get_parameter_if_set:nnTF #1#2#3#4
- {
- \group_begin:
- \xsim_if_parameter_exist:nTF {#2}
- {
- \xsim_if_parameter_set:nnTF {#1} {#2}
- {
- \tl_set:Nx \ParameterValue
- { \xsim_get_parameter:nn {#1} {#2} }
- \cs_set:Npn \__xsim_get_parameter_tmp:n ##1 {#3}
- \__xsim_get_parameter_tmp:V \ParameterValue
- }
- {#4}
- }
- { \msg_error:nnn {xsim} {unknown-parameter} {#2} }
- \group_end:
- }
-\cs_new_protected:Npn \xsim_get_parameter_if_set:nnT #1#2#3
- { \xsim_get_parameter_if_set:nnTF {#1} {#2} {#3} {} }
-\cs_new_protected:Npn \xsim_get_parameter_if_set:nnF #1#2#3
- { \xsim_get_parameter_if_set:nnTF {#1} {#2} {} {#3} }
-\cs_generate_variant:Nn \xsim_get_parameter_if_set:nnTF {o}
-
-% ----------------------------------------------------------------------------
-% 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
- {
- \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}
- }
-
-\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_set:nnF {#1} {exercises-name}
- {
- \xsim_set_parameters:nn {#1}
- { 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 }
- }
- \xsim_if_parameter_set:nnF {#1} {counter}
- {
- \xsim_set_parameters:nx {#1}
- { 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} }
- }
- \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} {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
- .code:n = \xsim_set_parameter:nnn {#1} {solution-heading} {####1}
- }
- \xsim_new_environment:nn {#1} {exercise}
- \xsim_new_environment:nn {#1} {solution}
- }
- }
-
-% #1: type
-% #2: id
-\prg_new_conditional:Npnn \xsim_if_exercise_exist:nn #1#2 {T,F,TF}
- {
- \xsim_if_exist:nnnTF {#1} {#2} {exercise}
- { \prg_return_true: }
- { \prg_return_false: }
- }
-\cs_generate_variant:Nn \xsim_if_exercise_exist: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 }
- \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
- {
- \xsim_temporary_goal_new:nVn {#1} \g_xsim_exercise_id_tl {##1}
- \xsim_if_property_set:nVnT {#1} \g_xsim_exercise_id_tl {##1}
- {
- \xsim_temporary_goal_set:nVnn
- {#1}
- \g_xsim_exercise_id_tl
- {##1}
- { \xsim_get_property:nVn {#1} \g_xsim_exercise_id_tl {##1} }
- }
- }
- \xsim_set_properties:nVx {#1} \g_xsim_exercise_id_tl
- {
- % preset options so the user doesn't has to:
- print = true ,
- use = true ,
- % options set by the user:
- \exp_not:n {#2} ,
- % options which need to have certain values:
- id = \g_xsim_exercise_id_tl ,
- section-value = \arabic{section} ,
- section = \thesection ,
- page-value = \arabic{page} ,
- sectioning =
- { \cs_if_exist:NTF \thechapter { \arabic {chapter} } {0} }
- { \arabic {section} }
- { \arabic {subsection} }
- { \arabic {subsubsection} }
- { \arabic {paragraph} } ,
- page = \thepage ,
- % this cannot yet be set (see below):
- used = false
- }
- % temporary goal now: either 0 or equal the complete property
- % property: equal to the given value
- \xsim_foreach_goal:n
- {
- \fp_set:Nn \l__xsim_tmpa_fp
- { \xsim_temporary_goal_get:nVn {#1} \g_xsim_exercise_id_tl {##1} }
- % set temporary goal to given property:
- \xsim_if_property_given:nTF {##1}
- {
- \xsim_temporary_goal_set:nVnn
- {#1}
- \g_xsim_exercise_id_tl
- {##1}
- { \xsim_get_property:nVn {#1} \g_xsim_exercise_id_tl {##1} }
- }
- {
- \xsim_temporary_goal_set:nVnn
- {#1}
- \g_xsim_exercise_id_tl
- {##1}
- {0}
- }
- % update to property to complete value:
- \xsim_if_property_set:nVnT {#1} \g_xsim_exercise_id_tl {##1}
- {
- \xsim_set_property:nVnx {#1} \g_xsim_exercise_id_tl {##1}
- { \fp_to_decimal:N \l__xsim_tmpa_fp }
- }
- }
- \xsim_if_property_exist:nT {chapter}
- {
- \xsim_set_properties:nVx {#1} \g_xsim_exercise_id_tl
- {
- chapter-value = \arabic{chapter} ,
- chapter = \thechapter
- }
- }
- \tl_set_eq:NN \ExerciseID \g_xsim_exercise_id_tl
- \tl_set: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_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
- {
- \xsim_if_insert_mode:F
- { \tl_gset_eq:NN \g_xsim_exercise_id_tl \ExerciseID }
- }
-
-% ----------------------------------------------------------------------------
-% #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_property: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_property:cpn {#1} ##1
- { \tl_gset:cn { number of #1 s } {##1} }
- }
- }
-
-\xsim_at_begin_document:n
- {
- \xsim_foreach_exercise_type:n
- {
- \xsim_write_to_aux:x
- { \token_to_str:N \providecommand \token_to_str:N \numberof #1 s {} }
- }
- }
-
-\xsim_at_end_document:n
- {
- \xsim_if_clear_aux:T
- {
- \int_compare:nNnF { \g_xsim_max_id_int } = { \g_xsim_id_int }
- { \xsim_empty_lists: }
- }
- \xsim_add_property_to_aux:nn {total-number} { { \int_use:N \g_xsim_id_int } }
- \xsim_foreach_exercise_type:n
- {
- \xsim_add_property_to_aux:nn {#1}
- { { \arabic { \xsim_get_parameter:nn {#1} {number} } } }
- }
- \xsim_update_list:n {types}
- }
-
-% ----------------------------------------------------------------------------
-\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/Master/texmf-dist/tex/latex/xsim/xsim.goals.code.tex b/Master/texmf-dist/tex/latex/xsim/xsim.goals.code.tex
deleted file mode 100644
index 67019eb6f36..00000000000
--- a/Master/texmf-dist/tex/latex/xsim/xsim.goals.code.tex
+++ /dev/null
@@ -1,385 +0,0 @@
-% ----------------------------------------------------------------------------
-% the XSIM package - goals 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{goals}{counting of points and bonus points}
-
-\xsim_load_modules:n {properties,exercises}
-
-\msg_new:nnn {xsim} {goal-unknown}
- { The~ goal~ `#1'~ has~ never~ been~ declared~ \msg_line_context: }
-
-\seq_new:N \l__xsim_goals_seq
-\tl_new:N \l_xism_grading_table_template_tl
-\tl_new:N \l_xism_grading_table_exercise_type_tl
-
-% #1: name
-\cs_new_protected:Npn \xsim_declare_exercise_goal:n #1
- {
- \xsim_if_goal_exist:nF {#1}
- {
- \xsim_verbose:n { Declaring~ new~ goal~ `#1'. }
- \xsim_declare_property:nnnn
- { \c_false_bool }
- { \c_false_bool }
- { \c_false_bool }
- {#1}
- \seq_put_right:Nn \l__xsim_goals_seq {#1}
- \fp_gzero_new:c {g__xsim_goal_#1_fp}
- \bool_new:c {l__xsim_goal_#1_given_bool}
- \fp_gzero_new:c {l__xsim_current_goal_#1_fp}
- \fp_if_exist:cF {g__xsim_total_goal_#1_fp}
- { \fp_new:c {g__xsim_total_goal_#1_fp} }
- \fp_if_exist:cF {g__xsim_total_goal_recorded_#1_fp}
- { \fp_new:c {g__xsim_total_goal_recorded_#1_fp} }
- \xsim_at_begin_document:n
- {
- \xsim_foreach_exercise_type:n
- {
- \fp_gzero_new:c {g__xsim_##1_goal_#1_fp}
- \fp_if_exist:cF {g__xsim_total_##1_goal_#1_fp}
- { \fp_new:c {g__xsim_total_##1_goal_#1_fp} }
- }
- }
- }
- }
-
-\prg_new_conditional:Npnn \xsim_if_goal_exist:n #1 {p,T,F,TF}
- {
- \seq_if_in:NnTF \l__xsim_goals_seq {#1}
- { \prg_return_true: }
- { \prg_return_false: }
- }
-
-\prg_new_conditional:Npnn \xsim_if_goal_given:n #1 {p,T,F,TF}
- {
- \bool_if:cTF {l__xsim_goal_#1_given_bool}
- { \prg_return_true: }
- { \prg_return_false: }
- }
-
-\cs_new_protected:Npn \xsim_goal_given:n #1
- { \bool_set_true:c {l__xsim_goal_#1_given_bool} }
-
-% #1: exercise type
-% #2: id
-% #3: goal
-\cs_new_protected:Npn \xsim_update_goal:nnn #1#2#3
- {
- \xsim_if_goal_exist:nT {#3}
- {
- \fp_gadd:cn {g__xsim_goal_#3_fp}
- { \xsim_get_property:nnn {#1} {#2} {#3} + 0 }
- \fp_gadd:cn {g__xsim_#1_goal_#3_fp}
- { \xsim_get_property:nnn {#1} {#2} {#3} + 0 }
- }
- }
-
-% #1: exercise type
-% #2: id
-\cs_new_protected:Npn \xsim_update_goals:nn #1#2
- {
- \xsim_foreach_goal:n
- { \xsim_update_goal:nnn {#1} {#2} {##1} }
- }
-\cs_generate_variant:Nn \xsim_update_goals:nn {nV}
-
-\cs_new_protected:Npn \xsim_foreach_goal:n #1
- { \seq_map_inline:Nn \l__xsim_goals_seq {#1} }
-
-% #1: type
-% #2: id
-\cs_new_protected:Npn \xsim_synchronize_goals:nn #1#2
- {
- \xsim_foreach_goal:n
- {
- \xsim_if_property_set:nnnTF {#1} {#2} {##1}
- {
- \xsim_set_property:nnnx {#1} {#2} {##1}
- { \xsim_temporary_goal_get:nnn {#1} {#2} {##1} }
- }
- {
- \fp_compare:nNnT
- { \xsim_temporary_goal_get:nnn {#1} {#2} {##1} } > {0}
- {
- \xsim_set_property:nnnx {#1} {#2} {##1}
- { \xsim_temporary_goal_get:nnn {#1} {#2} {##1} }
- }
- }
- }
- }
-
-% #1: exercise type
-% #2: id
-% #3: goal
-% #4: value
-\cs_new_protected:Npn \xsim_addto_goal:nnnn #1#2#3#4
- {
- \xsim_if_goal_exist:nT {#3}
- {
- \xsim_verbose:n { Adding~ `#4'~ to~ `#3'~ goal~ of~ #1~ #2 }
- % \fp_gadd:cn {g__xsim_goal_#3_fp} {#4}
- % \fp_gadd:cn {g__xsim_#1_goal_#3_fp} {#4}
- % \fp_add:cn {l__xsim_current_goal_#3_fp} {#4}
- \xsim_temporary_goal_add:nnnn {#1} {#2} {#3} {#4}
- }
- }
-\cs_generate_variant:Nn \xsim_addto_goal:nnnn {xx,nVnx}
-
-% #1: exercise type
-% #2: id
-% #3: goal
-% #4: relation and value
-\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 }
- { \prg_return_true: }
- { \prg_return_false: }
- }
-\cs_generate_variant:Nn \xsim_if_goal_value:nnnnTF {xx}
-
-% ----------------------------------------------------------------------------
-% we need some kind of temporary variable to be able to set goals both as
-% option to exercises and within the exercise body
-
-% #1: type
-% #2: id
-% #3: goal
-\cs_new_protected:Npn \xsim_temporary_goal_new:nnn #1#2#3
- { \fp_new:c {g__xsim_goal_#3_#1_#2_fp} }
-\cs_generate_variant:Nn \xsim_temporary_goal_new:nnn {nV}
-
-% #1: type
-% #2: id
-% #3: goal
-% #4: value
-\cs_new_protected:Npn \xsim_temporary_goal_set:nnnn #1#2#3#4
- { \fp_gset:cn {g__xsim_goal_#3_#1_#2_fp} {#4} }
-\cs_generate_variant:Nn \xsim_temporary_goal_set:nnnn {nV}
-
-% #1: type
-% #2: id
-% #3: goal
-% #4: value
-\cs_new_protected:Npn \xsim_temporary_goal_add:nnnn #1#2#3#4
- { \fp_gadd:cn {g__xsim_goal_#3_#1_#2_fp} {#4} }
-\cs_generate_variant:Nn \xsim_temporary_goal_add:nnnn {nV}
-
-% #1: type
-% #2: id
-% #3: goal
-\cs_new:Npn \xsim_temporary_goal_get:nnn #1#2#3
- { \fp_to_decimal:c {g__xsim_goal_#3_#1_#2_fp} }
-\cs_generate_variant:Nn \xsim_temporary_goal_get:nnn {nV}
-
-% #1: type
-% #2: id
-% #3: goal
-\cs_new_protected:Npn \__xsim_temporary_goal_show:nnn #1#2#3
- { \fp_show:c {g__xsim_goal_#3_#1_#2_fp} }
-
-% ----------------------------------------------------------------------------
-% a function which can be used to modify how the numbers of a goal are
-% printed:
-\cs_new_protected:Npn \__xsim_print_goal:n #1 {#1}
-\cs_generate_variant:Nn \__xsim_print_goal:n {x}
-
-% #1: value
-% #2: value == 1
-% #3: value != 1
-\cs_new_protected:Npn \xsim_print_goal:nnn #1#2#3
- {
- \__xsim_print_goal:x { \fp_to_decimal:n {#1} }
- \fp_compare:nTF { (#1) = 1 } {#2} {#3}
- }
-
-% #1: exercise type
-% #2: goal
-% #3: sum == 1
-% #4: sum != 1
-\cs_new_protected:Npn \xsim_print_goal_sum:nnnn #1#2#3#4
- { \xsim_print_goal:nnn { \use:c {g__xsim_total_#1_goal_#2_fp} } {#3} {#4} }
-
-% #1: goal
-% #2: sum == 1
-% #3: sum != 1
-\cs_new_protected:Npn \xsim_print_total_goal_sum:nnn #1#2#3
- { \xsim_print_goal:nnn { \use:c {g__xsim_total_goal_#1_fp} } {#2} {#3} }
-
-% ----------------------------------------------------------------------------
-% the same as the last to functions but for a list of goals:
-
-% #1: fp variable to be set
-% #2: list of goals (separated with +)
-% #3: function to be applied to goal names
-\cs_new_protected:Npn \__xsim_exercise_goals_sum_aux:Nnn #1#2#3
- {
- \seq_set_split:Nnn \l__xsim_tmpa_seq {+} {#2}
- \seq_set_map:NNn \l__xsim_tmpb_seq \l__xsim_tmpa_seq {#3}
- \fp_set:Nn #1 { \seq_use:Nn \l__xsim_tmpb_seq {+} }
- }
-
-% #1: fp variable
-% #2: exercise type
-% #3: list of goals (separated with +)
-\cs_new_protected:Npn \__xsim_exercise_goals_sum:Nnn #1#2#3
- {
- \__xsim_exercise_goals_sum_aux:Nnn #1 {#3}
- { \exp_not:c {g__xsim_total_#2_goal_ \tl_trim_spaces:n {##1} _fp} }
- }
-
-% #1: fp variable
-% #2: list of goals (separated with +)
-\cs_new_protected:Npn \__xsim_exercise_goals_sum:Nn #1#2
- {
- \__xsim_exercise_goals_sum_aux:Nnn #1 {#2}
- { \exp_not:c {g__xsim_total_goal_ \tl_trim_spaces:n {##1} _fp} }
- }
-
-% #1: exercise type
-% #2: list of goals (separated with +)
-% #3: sum == 1
-% #4: sum != 1
-\cs_new_protected:Npn \xsim_print_goals_sum:nnnn #1#2#3#4
- {
- \__xsim_exercise_goals_sum:Nnn \l__xsim_tmpa_fp {#1} {#2}
- \xsim_print_goal:nnn { \l__xsim_tmpa_fp } {#3} {#4}
- }
-
-% #1: list of goals (separated with +)
-% #2: sum == 1
-% #3: sum != 1
-\cs_new_protected:Npn \xsim_print_total_goals_sum:nnn #1#2#3
- {
- \__xsim_exercise_goals_sum:Nn \l__xsim_tmpa_fp {#1}
- \xsim_print_goal:nnn { \l__xsim_tmpa_fp } {#2} {#3}
- }
-
-% ----------------------------------------------------------------------------
-% #1: exercise type
-% #2: goal
-% #3: relation and value
-\prg_new_conditional:Npnn \xsim_if_goal_sum:nnn #1#2#3 {p,T,F,TF}
- {
- \fp_compare:nTF
- { ( \use:c {g__xsim_total_#1_goal_#2_fp} ) #3 }
- { \prg_return_true: }
- { \prg_return_false: }
- }
-
-% #1: exercise type
-% #2: list of goals (separated with +)
-% #3: relation and value
-\prg_new_protected_conditional:Npnn \xsim_if_goals_sum:nnn #1#2#3 {T,F,TF}
- {
- \__xsim_exercise_goals_sum:Nnn \l__xsim_tmpa_fp {#1} {#2}
- \fp_compare:nTF
- { ( \l__xsim_tmpa_fp ) #3 }
- { \prg_return_true: }
- { \prg_return_false: }
- }
-
-% #1: goal
-% #2: relation and value
-\prg_new_conditional:Npnn \xsim_if_total_goal_sum:nn #1#2 {p,T,F,TF}
- {
- \fp_compare:nTF
- { ( \use:c {g__xsim_total_goal_#1_fp} ) #2 }
- { \prg_return_true: }
- { \prg_return_false: }
- }
-
-% #1: list of goals (separated with +)
-% #2: relation and value
-\prg_new_protected_conditional:Npnn \xsim_if_total_goals_sum:nn #1#2 {T,F,TF}
- {
- \__xsim_exercise_goals_sum:Nn \l__xsim_tmpa_fp {#1}
- \fp_compare:nTF
- { ( \l__xsim_tmpa_fp ) #2 }
- { \prg_return_true: }
- { \prg_return_false: }
- }
-
-% ----------------------------------------------------------------------------
-% #1: exercise type
-% #2: goal
-% #3: value
-\xsim_new_aux_property:cpn {goal} #1#2#3
- { \fp_gset:cn {g__xsim_total_#1_goal_#2_fp} {#3} }
-
-% #1: goal
-% #2: value
-\xsim_new_aux_property:cpn {totalgoal} #1#2
- { \fp_gset:cn {g__xsim_total_goal_#1_fp} {#2} }
-
-\xsim_at_begin_document:n
- {
- \seq_map_inline:Nn \l__xsim_goals_seq
- {
- \fp_gset_eq:cc
- {g__xsim_total_goal_recorded_#1_fp}
- {g__xsim_total_goal_#1_fp}
- }
- }
-
-\xsim_at_end_document:n
- {
- \seq_map_inline:Nn \l__xsim_goals_seq
- {
- \xsim_foreach_exercise_type:n
- {
- \xsim_add_property_to_aux:nn {goal}
- { {##1} {#1} { \fp_to_decimal:c {g__xsim_##1_goal_#1_fp} } }
- }
- \tl_set:Nx \l__xsim_tmpa_tl
- { \fp_to_decimal:c {g__xsim_total_goal_#1_fp} }
- \tl_set:Nx \l__xsim_tmpb_tl
- { \fp_to_decimal:c {g__xsim_total_goal_recorded_#1_fp} }
- \tl_if_eq:NNF \l__xsim_tmpa_tl \l__xsim_tmpb_tl { \xsim_rerun: }
- \xsim_add_property_to_aux:nn {totalgoal}
- { {#1} { \fp_to_decimal:c {g__xsim_goal_#1_fp} } }
- }
- }
-
-% ----------------------------------------------------------------------------
-
-\keys_define:nn {xsim}
- {
- goal-print .code:n =
- \cs_set_protected:Npn \__xsim_print_goal:n ##1 {#1} ,
- grading-table/template .tl_set:N = \l_xism_grading_table_template_tl ,
- grading-table/template .initial:n = default ,
- grading-table/type .tl_set:N = \l_xism_grading_table_exercise_type_tl ,
- grading-table/type .initial:n =
- }
-
-% ----------------------------------------------------------------------------
-\file_input_stop:
-
-2019/01/30 - bug fix (cf. https://texwelt.de/wissen/fragen/24101/)
-2020/02/20 - add temporary variables for the whole subpoint thing
- (cf. issue #2)
diff --git a/Master/texmf-dist/tex/latex/xsim/xsim.grades.code.tex b/Master/texmf-dist/tex/latex/xsim/xsim.grades.code.tex
deleted file mode 100644
index 678011c6100..00000000000
--- a/Master/texmf-dist/tex/latex/xsim/xsim.grades.code.tex
+++ /dev/null
@@ -1,153 +0,0 @@
-% ----------------------------------------------------------------------------
-% the XSIM package - grades 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{grades}{distribute goal sums to grades}
-
-\xsim_load_modules:n {goals}
-
-\msg_new:nnn {xsim} {grade-unknown}
- { The~ grade~ `#1'~ has~ never~ been~ declared~ \msg_line_context: }
-
-\bool_new:N \l__xsim_grades_half_bool
-\fp_new:N \l__xsim_grade_round_fp
-\fp_zero:N \l__xsim_grade_round_fp
-\prop_new:N \l__xsim_relative_grades_prop
-\tl_new:N \l__xsim_grade_split_tl
-
-\cs_new:Npn \__xsim_fp_round_to_half:n #1
- { round( 2*(#1),0)/2 }
-
-\cs_new:Npn \__xsim_grades_round:n #1
- { round ( #1 , \l__xsim_grade_round_fp ) }
-
-% #1: factor
-% #2: goal sum
-\cs_new:Npn \__xsim_grade_rounded:nn #1#2
- {
- \bool_if:NTF \l__xsim_grades_half_bool
- { \__xsim_fp_round_to_half:n }
- { \__xsim_grades_round:n }
- { (#1) * (#2) }
- }
-
-\cs_new_protected:Npn \xsim_declare_relative_grades:n #1
- {
- \seq_set_split:NVn \l__xsim_tmpa_seq \l__xsim_grade_split_tl {#1}
- \seq_map_inline:Nn \l__xsim_tmpa_seq
- { \__xsim_declare_relative_grade:w ##1 \q_stop }
- \xsim_verbose:n {Declaring~ relative~ grade~ distribution}
- }
-
-\cs_new_protected:Npn \__xsim_declare_relative_grade:w #1 = #2 \q_stop
- {
- \tl_set:Nx \l__xsim_tmpa_tl { \tl_trim_spaces:n {#1} }
- \tl_set:Nx \l__xsim_tmpb_tl { \tl_trim_spaces:n {#2} }
- \prop_put:NVV \l__xsim_relative_grades_prop
- \l__xsim_tmpa_tl
- \l__xsim_tmpb_tl
- }
-
-% #1: grade
-% #2: sum of points
-% #3: code after grade requirement if == 1
-% #4: code after grade requirement if != 1
-\cs_new_protected:Npn \xsim_get_grade:nnnn #1#2#3#4
- {
- \prop_get:NnNTF \l__xsim_relative_grades_prop {#1} \l__xsim_tmpa_tl
- {
- \xsim_print_goal:nnn
- {
- min(
- \__xsim_grade_rounded:nn
- { \l__xsim_tmpa_tl }
- {#2} ,
- #2
- )
- }
- {#3}
- {#4}
- }
- { \msg_error:nnn {xsim} {grade-unknown} {#1} }
- }
-
-% #1: grade
-% #2: goal
-% #3: code after grade requirement if == 1
-% #4: code after grade requirement if != 1
-\cs_new_protected:Npn \xsim_get_grade_goal:nnnn #1#2#3#4
- {
- \xsim_if_goal_exist:nTF {#2}
- {
- \xsim_get_grade:nnnn
- {#1}
- { \use:c {g__xsim_total_goal_#2_fp} }
- {#3}
- {#4}
- }
- { \msg_error:nnn {xsim} {goal-unknown} {#2} }
- }
-
-% #1: grade
-% #2: goal list (separated with +)
-% #3: code after grade requirement if == 1
-% #4: code after grade requirement if != 1
-\cs_new_protected:Npn \xsim_get_grade_requirement:nnnn #1#2#3#4
- {
- \seq_set_split:Nnn \l__xsim_tmpa_seq {+} {#2}
- \fp_zero:N \l__xsim_tmpa_fp
- \seq_map_inline:Nn \l__xsim_tmpa_seq
- {
- \fp_add:Nn \l__xsim_tmpa_fp
- { \use:c {g__xsim_total_goal_\tl_trim_spaces:n {##1} _fp} }
- }
- \xsim_get_grade:nnnn {#1} { \l__xsim_tmpa_fp } {#3} {#4}
- }
-
-% #1: grade
-% #2: code after grade requirement if == 1
-% #3: code after grade requirement if != 1
-\cs_new_protected:Npn \xsim_get_absolute_grade_requirement:nnn #1#2#3
- {
- \fp_zero:N \l__xsim_tmpa_fp
- \xsim_foreach_goal:n
- {
- \fp_add:Nn \l__xsim_tmpa_fp
- { \use:c {g__xsim_total_goal_##1_fp} }
- }
- \xsim_get_grade:nnnn {#1} { \l__xsim_tmpa_fp } {#2} {#3}
- }
-
-\keys_define:nn {xsim/grades}
- {
- round .fp_set:N = \l__xsim_grade_round_fp ,
- half .bool_set:N = \l__xsim_grades_half_bool ,
- split .tl_set:N = \l__xsim_grade_split_tl ,
- split .initial:n = {,}
- }
-
-% ----------------------------------------------------------------------------
-\file_input_stop:
diff --git a/Master/texmf-dist/tex/latex/xsim/xsim.interface.code.tex b/Master/texmf-dist/tex/latex/xsim/xsim.interface.code.tex
deleted file mode 100644
index b96e5a47b5d..00000000000
--- a/Master/texmf-dist/tex/latex/xsim/xsim.interface.code.tex
+++ /dev/null
@@ -1,696 +0,0 @@
-% ----------------------------------------------------------------------------
-% the XSIM package - interface 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{interface}{user interface}
-
-\NewDocumentCommand \DeclareExerciseEnvironmentTemplate {m+m+m}
- { \xsim_declare_environment_template:nnn {#1} {#2} {#3} }
-\@onlypreamble \DeclareExerciseEnvironmentTemplate
-
-\NewDocumentCommand \DeclareExerciseHeadingTemplate {m+m}
- { \xsim_declare_heading_template:nn {#1} {#2} }
-\@onlypreamble \DeclareExerciseHeadingTemplate
-
-\NewDocumentCommand \DeclareExerciseTableTemplate {m+m}
- { \xsim_declare_table_template:nn {#1} {#2} }
-\@onlypreamble \DeclareExerciseTableTemplate
-
-\NewDocumentCommand \UseExerciseTemplate {mm}
- { \xsim_use_template:nn {#1} {#2} }
-
-% ----------------------------------------------------------------------------
-
-\NewDocumentCommand \DeclareExerciseType {mm}
- { \xsim_declare_exercise_type:nn {#1} {#2} }
-\@onlypreamble \DeclareExerciseType
-
-\NewExpandableDocumentCommand \numberofusedexercises {}
- { \int_use:N \g_xsim_max_id_int }
-
-% ----------------------------------------------------------------------------
-
-\ProvideDocumentCommand \IfExistSolutionTF {+m+m}
- { \xsim_if_solution_exist:ooTF {\ExerciseType} {\ExerciseID} {#1} {#2} }
-
-\NewDocumentCommand \IfExistSolutionT {+m}
- { \IfExistSolutionTF {#1} {} }
-
-\NewDocumentCommand \IfExistSolutionF {+m}
- { \IfExistSolutionTF {} {#1} }
-
-\NewExpandableDocumentCommand \IfInsideSolutionTF {+m+m}
- { \xsim_if_inside_solution:TF {#1} {#2} }
-
-\NewExpandableDocumentCommand \IfInsideSolutionT {+m}
- { \IfInsideSolutionTF {#1} {} }
-
-\NewExpandableDocumentCommand \IfInsideSolutionF {+m}
- { \IfInsideSolutionTF {} {#1} }
-
-\NewExpandableDocumentCommand \IfSolutionPrintTF {+m+m}
- { \xsim_if_solution_print:nTF {\ExerciseType} {#1} {#2} }
-
-\NewExpandableDocumentCommand \IfSolutionPrintT {+m}
- { \IfSolutionPrintTF {#1} {} }
-
-\NewExpandableDocumentCommand \IfSolutionPrintF {+m}
- { \IfSolutionPrintTF {} {#1} }
-
-% ----------------------------------------------------------------------------
-
-\NewDocumentCommand \DeclareExerciseProperty {t!st-m}
- {
- \IfBooleanTF {#2}
- {
- \IfBooleanTF {#3}
- {
- \xsim_declare_property:nnnn
- { \c_false_bool }
- { \c_true_bool }
- { \c_true_bool }
- {#4}
- }
- {
- \xsim_declare_property:nnnn
- { \c_false_bool }
- { \c_true_bool }
- { \c_false_bool }
- {#4}
- }
- }
- {
- \IfBooleanTF {#1}
- {
- \IfBooleanTF {#3}
- {
- \xsim_declare_property:nnnn
- { \c_true_bool }
- { \c_false_bool }
- { \c_true_bool }
- {#4}
- }
- {
- \xsim_declare_property:nnnn
- { \c_true_bool }
- { \c_false_bool }
- { \c_false_bool }
- {#4}
- }
- }
- {
- \IfBooleanTF {#3}
- {
- \xsim_declare_property:nnnn
- { \c_false_bool }
- { \c_false_bool }
- { \c_true_bool }
- {#4}
- }
- {
- \xsim_declare_property:nnnn
- { \c_false_bool }
- { \c_false_bool }
- { \c_false_bool }
- {#4}
- }
- }
- }
- }
-\@onlypreamble \DeclareExerciseProperty
-
-\NewDocumentCommand \DeclareExercisePropertyAlias {mm}
- { \xsim_make_property_alias:nn {#1} {#2} }
-\@onlypreamble \DeclareExercisePropertyAlias
-
-\NewDocumentCommand \SetExerciseProperty {m+m}
- { \xsim_set_property:xxnn {\ExerciseType} {\ExerciseID} {#1} {#2} }
-
-\NewDocumentCommand \SetExpandedExerciseProperty {m+m}
- { \xsim_set_property:xxnx {\ExerciseType} {\ExerciseID} {#1} {#2} }
-
-\NewDocumentCommand \ExerciseSetProperty {mmm+m}
- { \xsim_set_property:nnnn {#1} {#2} {#3} {#4} }
-
-\NewDocumentCommand \ExerciseSetExpandedProperty {mmm+m}
- { \xsim_set_property:nnnx {#1} {#2} {#3} {#4} }
-
-\NewExpandableDocumentCommand \IfExercisePropertyExistTF {+m+m+m}
- { \xsim_if_property_exist:nTF {#1} {#2} {#3} }
-
-\NewExpandableDocumentCommand \IfExercisePropertyExistT {+m+m}
- { \IfExercisePropertyExistTF {#1} {#2} {} }
-
-\NewExpandableDocumentCommand \IfExercisePropertyExistF {+m+m}
- { \IfExercisePropertyExistTF {#1} {} {#2} }
-
-\NewDocumentCommand \IfExercisePropertySetTF {m+m+m}
- { \xsim_if_property_set:xxnTF {\ExerciseType} {\ExerciseID} {#1} {#2} {#3} }
-
-\NewDocumentCommand \IfExercisePropertySetT {m+m}
- { \IfExercisePropertySetTF {#1} {#2} {} }
-
-\NewDocumentCommand \IfExercisePropertySetF {m+m}
- { \IfExercisePropertySetTF {#1} {} {#2} }
-
-\NewExpandableDocumentCommand \GetExerciseProperty {m}
- { \xsim_get_property:oon {\ExerciseType} {\ExerciseID} {#1} }
-
-\NewExpandableDocumentCommand \GetExerciseAliasProperty {m}
- {
- \xsim_get_property:oof
- {\ExerciseType}
- {\ExerciseID}
- { \xsim_property_alias:n {#1} }
- }
-
-\NewDocumentCommand \GetExercisePropertyTF {m+m+m}
- {
- \xsim_get_property_if_set:oonTF {\ExerciseType} {\ExerciseID} {#1}
- {#2}
- {#3}
- }
-
-\NewDocumentCommand \GetExercisePropertyT {m+m}
- { \GetExercisePropertyTF {#1} {#2} {} }
-\NewDocumentCommand \GetExercisePropertyF {m+m+m}
- { \GetExercisePropertyTF {#1} {} {#2} }
-
-\NewExpandableDocumentCommand \GetExerciseIdForProperty {mm}
- { \xsim_get_id_for_property:nn {#1} {#2} }
-
-\NewExpandableDocumentCommand \GetExerciseTypeForProperty {mm}
- { \xsim_get_type_for_property:nn {#1} {#2} }
-
-\NewExpandableDocumentCommand \IfExerciseBooleanPropertyTF {+m+m+m}
- {
- \xsim_if_boolean_property:oonTF {\ExerciseType} {\ExerciseID} {#1}
- {#2}
- {#3}
- }
-
-\NewExpandableDocumentCommand \IfExerciseBooleanPropertyT {+m+m}
- { \IfExerciseBooleanPropertyTF {#1} {#2} {} }
-\NewExpandableDocumentCommand \IfExerciseBooleanPropertyF {+m+m}
- { \IfExerciseBooleanPropertyTF {#1} {} {#2} }
-
-\NewDocumentCommand \SaveExerciseProperty {mm}
- { \xsim_save_property:xxnN {\ExerciseType} {\ExerciseID} {#1} #2 }
-
-\NewDocumentCommand \GlobalSaveExerciseProperty {mm}
- { \xsim_gsave_property:xxnN {\ExerciseType} {\ExerciseID} {#1} #2 }
-
-% ----------------------------------------------------------------------------
-
-\NewDocumentCommand \DeclareExerciseParameter {st!m}
- {
- \IfBooleanTF {#1} % fixed
- {
- \IfBooleanTF {#2} % mandatory
- { \xsim_declare_parameter:nnn {true} {true} {#3} }
- { \xsim_declare_parameter:nnn {true} {false} {#3} }
- }
- {
- \IfBooleanTF {#2} % mandatory
- { \xsim_declare_parameter:nnn {false} {true} {#3} }
- { \xsim_declare_parameter:nnn {false} {false} {#3} }
- }
- }
-
-\NewExpandableDocumentCommand \GetExerciseParameter {m}
- { \xsim_get_parameter:on {\ExerciseType} {#1} }
-
-\NewDocumentCommand \SetExerciseParameter {mmm}
- { \xsim_set_parameter:nnn {#1} {#2} {#3} }
-
-\NewDocumentCommand \SetExerciseParameters {mm}
- { \xsim_set_parameters:nn {#1} {#2} }
-
-\NewExpandableDocumentCommand \GetExerciseName {}
- {
- \IfInsideSolutionTF
- { \GetExerciseParameter {solution-name} }
- { \GetExerciseParameter {exercise-name} }
- }
-
-\NewExpandableDocumentCommand \GetExerciseHeadingF {m}
- {
- \IfInsideSolutionTF
- {
- \IfExerciseParameterSetTF {solution-heading}
- { \GetExerciseParameter {solution-heading} }
- {#1}
- }
- {
- \IfExerciseParameterSetTF {exercise-heading}
- { \GetExerciseParameter {exercise-heading} }
- {#1}
- }
- }
-
-\NewDocumentCommand \GetExerciseBody {m}
- { \xsim_input:oon { \ExerciseType } { \ExerciseID } {#1} }
-
-\NewExpandableDocumentCommand \IfExerciseParameterSetTF {+m+m+m}
- { \xsim_if_parameter_set:nnTF {\ExerciseType} {#1} {#2} {#3} }
-
-\NewExpandableDocumentCommand \IfExerciseParameterSetT {+m+m}
- { \IfExerciseParameterSetTF {#1} {#2} {} }
-
-\NewExpandableDocumentCommand \IfExerciseParameterSetF {+m+m}
- { \IfExerciseParameterSetTF {#1} {} {#2} }
-
-\NewExpandableDocumentCommand \ExerciseParameterIfSetTF {+m+m+m+m}
- { \xsim_if_parameter_set:nnTF {#1} {#2} {#3} {#4} }
-
-\NewExpandableDocumentCommand \ExerciseParameterIfSetT {+m+m+m}
- { \ExerciseParameterIfSetTF {#1} {#2} {#3} {} }
-
-\NewExpandableDocumentCommand \ExerciseParameterIfSetF {+m+m+m}
- { \ExerciseParameterIfSetTF {#1} {#2} {} {#3} }
-
-\NewDocumentCommand \GetExerciseParameterTF {m+m+m}
- { \xsim_get_parameter_if_set:onTF {\ExerciseType} {#1} {#2} {#3} }
-
-\NewDocumentCommand \GetExerciseParameterT {m+m}
- { \GetExerciseParameterTF {#1} {#2} {} }
-
-\NewDocumentCommand \GetExerciseParameterF {m+m+m}
- { \GetExerciseParameterTF {#1} {} {#2} }
-
-% ----------------------------------------------------------------------------
-
-\NewDocumentCommand \ExercisePropertyIfSetTF {mmm+m+m}
- { \xsim_if_property_set:nnnTF {#1} {#2} {#3} {#4} {#5} }
-
-\NewDocumentCommand \ExercisePropertyIfSetT {mmm+m}
- { \ExercisePropertyIfSetTF {#1} {#2} {#3} {#4} {} }
-
-\NewDocumentCommand \ExercisePropertyIfSetF {mmm+m}
- { \ExercisePropertyIfSetTF {#1} {#2} {#3} {} {#4} }
-
-\NewExpandableDocumentCommand \ExercisePropertyGet {mmm}
- { \xsim_get_property:nnn {#1} {#2} {#3} }
-
-\NewExpandableDocumentCommand \ExercisePropertyGetAlias {mm}
- { \xsim_get_property:nnf {#1} {#2} { \xsim_property_alias:n {#1} } }
-
-\NewDocumentCommand \ExercisePropertySave {mmmm}
- { \xsim_save_property:nnnN {#1} {#2} {#3} #4 }
-
-\NewDocumentCommand \ExercisePropertyGlobalSave {mmmm}
- { \xsim_gsave_property:nnnN {#1} {#2} {#3} #4 }
-
-\NewExpandableDocumentCommand \ExerciseParameterGet {mm}
- { \xsim_get_parameter:nn {#1} {#2} }
-
-% ----------------------------------------------------------------------------
-
-\NewExpandableDocumentCommand \XSIMtranslate {m}
- { \xsim_translate:n {#1} }
-
-\NewExpandableDocumentCommand \XSIMexpandcode {+m}
- { \use:e {#1} }
-
-\NewExpandableDocumentCommand \XSIMmixedcase {m}
- { \tl_mixed_case:f {#1} }
-
-\NewDocumentCommand \XSIMputright {mm}
- { \tl_put_right:Nn #1 {#2} }
-
-\NewExpandableDocumentCommand \XSIMifeqTF {+m+m+m+m}
- { \tl_if_eq:ffTF {#1} {#2} {#3} {#4} }
-
-\NewExpandableDocumentCommand \XSIMifeqT {+m+m+m}
- { \XSIMifeqTF {#1} {#2} {#3} {} }
-
-\NewExpandableDocumentCommand \XSIMifeqF {+m+m+m}
- { \XSIMifeqTF {#1} {#2} {} {#3} }
-
-\NewExpandableDocumentCommand \XSIMifblankTF {+m+m+m}
- { \tl_if_blank:fTF {#1} {#2} {#3} }
-
-\NewExpandableDocumentCommand \XSIMifblankT {+m+m}
- { \XSIMifblankTF {#1} {#2} {} }
-
-\NewExpandableDocumentCommand \XSIMifblankF {+m+m}
- { \XSIMifblankTF {#1} {} {#2} {} }
-
-% ----------------------------------------------------------------------------
-
-\NewDocumentCommand \DeclareExerciseGoal {m}
- { \xsim_declare_exercise_goal:n {#1} }
-\@onlypreamble \DeclareExerciseGoal
-
-\NewDocumentCommand \IfExerciseGoalTF {mm+m+m}
- {
- \xsim_if_goal_value:xxnnTF
- {\ExerciseType} {\ExerciseID} {#1}
- {#2}
- {#3} {#4}
- }
-
-\NewDocumentCommand \IfExerciseGoalT {mm+m}
- { \IfExerciseGoalTF {#1} {#2} {#3} {} }
-
-\NewDocumentCommand \IfExerciseGoalF {mm+m}
- { \IfExerciseGoalTF {#1} {#2} {} {#3} }
-
-\NewDocumentCommand \IfExerciseGoalSingularTF {mmm}
- { \IfExerciseGoalTF {#1} {=1} {#2} {#3} }
-
-\NewDocumentCommand \IfExerciseGoalSingularT {mm}
- { \IfExerciseGoalT {#1} {=1} {#2} }
-
-\NewDocumentCommand \IfExerciseGoalSingularF {mm}
- { \IfExerciseGoalF {#1} {=1} {#2} }
-
-\NewDocumentCommand \IfExerciseTypeGoalsSumTF {mmm+m+m}
- { \xsim_if_goals_sum:nnnTF {#1} {#2} {#3} {#4} {#5} }
-
-\NewDocumentCommand \IfExerciseTypeGoalsSumT {mmm+m}
- { \IfExerciseTypeGoalsSumTF {#1} {#2} {#3} {#4} {} }
-
-\NewDocumentCommand \IfExerciseTypeGoalsSumF {mmm+m}
- { \IfExerciseTypeGoalsSumTF {#1} {#2} {#3} {} {#4} }
-
-\NewDocumentCommand \IfExerciseGoalsSumTF {mm+m+m}
- { \xsim_if_total_goals_sum:nnTF {#1} {#2} {#3} {#4} }
-
-\NewDocumentCommand \IfExerciseGoalsSumT {mm+m}
- { \IfExerciseGoalsSumTF {#1} {#2} {#3} {} }
-
-\NewDocumentCommand \IfExerciseGoalsSumF {mm+m}
- { \IfExerciseGoalsSumTF {#1} {#2} {} {#3} }
-
-\NewDocumentCommand \TotalExerciseTypeGoal {mmmm}
- { \xsim_print_goal_sum:nnnn {#1} {#2} {#3} {#4} }
-
-\NewDocumentCommand \TotalExerciseTypeGoals {mmmm}
- { \xsim_print_goals_sum:nnnn {#1} {#2} {#3} {#4} }
-
-\NewDocumentCommand \TotalExerciseGoal {mmm}
- { \xsim_print_total_goal_sum:nnn {#1} {#2} {#3} }
-
-\NewDocumentCommand \TotalExerciseGoals {mmm}
- { \xsim_print_total_goals_sum:nnn {#1} {#2} {#3} }
-
-\NewDocumentCommand \AddtoExerciseTypeGoal {mmmm}
- { \xsim_addto_goal:nnnn {#1} {#2} {#3} {#4} }
-
-\NewDocumentCommand \AddtoExerciseGoal {mm}
- { \xsim_addto_goal:xxnn {\ExerciseType} {\ExerciseID} {#1} {#2} }
-
-\NewDocumentCommand \ExerciseGoalValuePrint {mmm}
- { \xsim_print_goal:nnn {#1} {#2} {#3} }
-
-\NewDocumentCommand \AddtoExerciseTypeGoalPrint {mmmmmm}
- {
- \xsim_addto_goal:nnnn {#1} {#2} {#3} {#4}
- \xsim_print_goal:nnn {#4} {#5} {#6}
- }
-
-\NewDocumentCommand \AddtoExerciseGoalPrint {mmmm}
- {
- \xsim_addto_goal:xxnn {\ExerciseType} {\ExerciseID} {#1} {#2}
- \xsim_print_goal:nnn {#2} {#3} {#4}
- }
-
-% ----------------------------------------------------------------------------
-\NewDocumentCommand \DeclareGradeDistribution {m}
- { \xsim_declare_relative_grades:n {#1} }
-
-\NewDocumentCommand \GetGradeRequirementForGoal {mmmm}
- { \xsim_get_grade_goal:nnnn {#1} {#2} {#3} {#4} }
-
-\NewDocumentCommand \GetGradeRequirementForGoals {mmmm}
- { \xsim_get_grade_requirement:nnnn {#1} {#2} {#3} {#4} }
-
-\NewDocumentCommand \GetGradeRequirement {mmm}
- { \xsim_get_absolute_grade_requirement:nnn {#1} {#2} {#3} }
-
-% ----------------------------------------------------------------------------
-
-\NewDocumentCommand \DeclareExerciseTagging {m}
- { \xsim_new_tag_type:n {#1} }
-\@onlypreamble \DeclareExerciseTagging
-
-\NewDocumentCommand \ProvideExerciseTagging {m}
- {
- \xsim_if_tag_type_exist:nTF {#1}
- { \msg_warning:nnn {xsim} {tag-exists} {#1} }
- { \xsim_new_tag_type:n {#1} }
- }
-
-\NewDocumentCommand \ForEachExerciseTag {m+m}
- { \xsim_foreach_exercise_tag:oonn {\ExerciseType} {\ExerciseID} {#1} {#2} }
-
-\NewDocumentCommand \ListExerciseTags {mm}
- { \xsim_exercise_tags_use:oonn {\ExerciseType} {\ExerciseID} {#1} {#2} }
-
-\NewDocumentCommand \UseExerciseTags {mmmm}
- {
- \xsim_exercise_tags_use:oonnnn
- {\ExerciseType}
- {\ExerciseID}
- {#1}
- {#2}
- {#3}
- {#4}
- }
-
-\NewDocumentCommand \IfExerciseTagSetTF {m+m+m}
- { \xsim_if_tags_value:nTF {#1} {#2} {#3} }
-\NewDocumentCommand \IfExerciseTagSetT {m+m}
- { \xsim_if_tags_value:nT {#1} {#2} }
-\NewDocumentCommand \IfExerciseTagSetF {m+m}
- { \xsim_if_tags_value:nF {#1} {#2} }
-
-\NewDocumentCommand \IfExerciseTopicSetTF {m+m+m}
- { \xsim_if_topic_value:nTF {#1} {#2} {#3} }
-\NewDocumentCommand \IfExerciseTopicSetT {m+m}
- { \xsim_if_topic_value:nT {#1} {#2} }
-\NewDocumentCommand \IfExerciseTopicSetF {m+m}
- { \xsim_if_topic_value:nF {#1} {#2} }
-
-% ----------------------------------------------------------------------------
-
-\NewDocumentCommand \XSIMatbegindocument {+m}
- { \xsim_at_begin_document:n {#1} }
-
-\NewDocumentCommand \XSIMatenddocument {+m}
- { \xsim_at_end_document:n {#1} }
-
-% ----------------------------------------------------------------------------
-
-\NewDocumentCommand \ForEachPrintedExerciseByType {+m}
- { \xsim_foreach_exercise_type_id:nn {print} {#1} }
-
-\NewDocumentCommand \ForEachPrintedExerciseByID {+m}
- { \xsim_foreach_exercise_id_type:nn {print} {#1} }
-
-\NewDocumentCommand \ForEachUsedExerciseByType {+m}
- { \xsim_foreach_exercise_type_id:nn {used} {#1} }
-
-\NewDocumentCommand \ForEachUsedExerciseByID {+m}
- { \xsim_foreach_exercise_id_type:nn {used} {#1} }
-
-% ----------------------------------------------------------------------------
-
-\NewDocumentCommand \DeclareExerciseTranslations {mm}
- { \xsim_declare_translations:nn {#1} {#2} }
-\@onlypreamble \DeclareExerciseTranslations
-
-\NewDocumentCommand \DeclareExerciseTranslation {mmm}
- { \xsim_declare_translation:nnn {#1} {#2} {#3} }
-\@onlypreamble \DeclareExerciseTranslation
-
-\NewDocumentCommand \ForEachExerciseTranslation {+m}
- { \xsim_for_all_translations_do:n {#1} }
-
-% ----------------------------------------------------------------------------
-
-\NewDocumentCommand \DeclareExerciseCollection {m}
- { \xsim_new_collection:n {#1} }
-\@onlypreamble \DeclareExerciseCollection
-
-\NewDocumentCommand \collectexercisestype {mm}
- { \xsim_start_collection:nn {#1} {#2} }
-
-\NewDocumentCommand \collectexercises {m}
- { \xsim_start_collection:n {#1} }
-
-\NewDocumentCommand \collectexercisesstop {m}
- { \xsim_stop_collection:n {#1} }
-
-\NewDocumentCommand \printcollection {O{}m}
- { \xsim_print_collection:nn {#1} {#2} }
-
-\NewDocumentCommand \printrandomexercises {O{}m}
- {
- \group_begin:
- \keys_set:nn {xsim/random} {#1}
- \xsim_print_random_list:VnN
- \l_xsim_random_collection_tl
- {#2}
- \l_xsim_random_exclude_list_clist
- \group_end:
- }
-
-% ----------------------------------------------------------------------------
-
-\NewDocumentCommand \blank {som}
- {
- \group_begin:
- \IfNoValueF {#2} { \keys_set:nn {xsim/blank} {#2} }
- \mode_if_vertical:TF
- {
- \IfBooleanTF {#1}
- { \xsim_blank:n {#3} }
- {
- \bool_if:NT \l__xsim_blank_linespread_bool
- { \linespread { \l__xsim_blank_linespread_tl } \selectfont }
- \noindent \null \xsim_blank:n {#3} \par
- }
- }
- { \xsim_blank:n {#3} }
- \group_end:
- }
-
-\NewDocumentCommand \examspace { sm }
- {
- \IfBooleanTF {#1}
- { \xsim_examspace:nn { \c_true_bool } {#2} }
- { \xsim_examspace:nn { \c_false_bool } {#2} }
- }
-
-% ----------------------------------------------------------------------------
-
-\NewDocumentCommand \gradingtable {O{}}
- {
- \group_begin:
- \keys_set:nn {xsim/grading-table} {#1}
- \xsim_setup_template:nVn {table} \l_xism_grading_table_template_tl
- {
- \providecommand* \ExerciseTableCode {}
- \providecommand* \ExerciseTableType [1] {}
- \providecommand* \ExerciseType {}
- \tl_set_eq:NN \ExerciseType \l_xism_grading_table_exercise_type_tl
- \renewcommand* \ExerciseTableCode {}
- \renewcommand* \ExerciseTableType [1]
- { \XSIMifblankTF { \ExerciseType } {##1} { \ExerciseType } }
- }
- \xsim_use_template:nV {table} \l_xism_grading_table_template_tl
- \group_end:
- }
-
-% ----------------------------------------------------------------------------
-
-\NewDocumentCommand \XSIMprint {mO{}mm}
- { \xsim_insert:nenn {#3} { \xsim_normalize_id:n {#4} } {#2} {#1} }
-
-\NewDocumentCommand \XSIMxprint {mO{}mm}
- { \xsim_insert:xxnn {#3} { \xsim_normalize_id:e {#4} } {#2} {#1} }
-
-\NewDocumentCommand \printexercise {O{}mm}
- {
- \clist_map_inline:nn {#3}
- { \xsim_insert:nenn {#2} { \xsim_normalize_id:n {##1} } {#1} {exercise} }
- }
-
-\NewDocumentCommand \xprintexercise {O{}mm}
- {
- \clist_map_inline:nn {#3}
- { \xsim_insert:xxnn {#2} { \xsim_normalize_id:e {##1} } {#1} {exercise} }
- }
-
-\NewDocumentCommand \printsolution {O{}mm}
- {
- \clist_map_inline:nn {#3}
- { \xsim_insert:nenn {#2} { \xsim_normalize_id:n {##1} } {#1} {solution} }
- }
-
-\NewDocumentCommand \xprintsolution {O{}mm}
- {
- \clist_map_inline:nn {#3}
- { \xsim_insert:xxnn {#2} { \xsim_normalize_id:e {##1} } {#1} {solution} }
- }
-
-% ----------------------------------------------------------------------------
-
-\NewDocumentCommand \printsolutionstype {sO{}m}
- {
- \IfBooleanTF {#1}
- { \xsim_print_type_solutions:nnn { \c_true_bool } {#2} {#3} }
- { \xsim_print_type_solutions:nnn { \c_false_bool } {#2} {#3} }
- }
-
-\NewDocumentCommand \printsolutions {sO{}}
- {
- \IfBooleanTF {#1}
- { \xsim_print_all_solutions_per_type:nn { \c_true_bool } {#2} }
- { \xsim_print_all_solutions_per_type:nn { \c_false_bool } {#2} }
- }
-
-\NewDocumentCommand \printallsolutions {sO{}}
- {
- \IfBooleanTF {#1}
- { \xsim_print_all_solutions_per_id:nn { \c_true_bool } {#2} }
- { \xsim_print_all_solutions_per_id:nn { \c_false_bool } {#2} }
- }
-
-% ----------------------------------------------------------------------------
-
-\NewDocumentCommand \printforexercises {sO{}+mO{}}
- {
- \IfBooleanTF {#1}
- {
- \xsim_foreach_exercise_type:n
- { \xsim_print_type_code:nnnnn { \c_true_bool } {#2} {#4} {##1} {#3} }
- }
- {
- \xsim_foreach_exercise_type:n
- { \xsim_print_type_code:nnnnn { \c_false_bool } {#2} {#4} {##1} {#3} }
- }
- }
-
-% ----------------------------------------------------------------------------
-
-\NewDocumentCommand \xsimsetup {+m}
- { \xsim_setup:n {#1} }
-
-% ----------------------------------------------------------------------------
-\NewExpandableDocumentCommand \XSIMifchapterTF {+m+m}
- { \xsim_if_chapter:TF {#1} {#2} }
-
-\NewExpandableDocumentCommand \XSIMifchapterT {+m}
- { \xsim_if_chapter:T {#1} }
-
-\NewExpandableDocumentCommand \XSIMifchapterF {+m}
- { \xsim_if_chapter:F {#1} }
-
-% ----------------------------------------------------------------------------
-\file_input_stop:
diff --git a/Master/texmf-dist/tex/latex/xsim/xsim.modules.code.tex b/Master/texmf-dist/tex/latex/xsim/xsim.modules.code.tex
deleted file mode 100644
index c487c730366..00000000000
--- a/Master/texmf-dist/tex/latex/xsim/xsim.modules.code.tex
+++ /dev/null
@@ -1,220 +0,0 @@
-% ----------------------------------------------------------------------------
-% the XSIM package - modules 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.
-% ----------------------------------------------------------------------------
-%
-% this is a pseudo module as it does the actual definitions for the whole
-% module loading stuff; we do this so both packages `xsimverb' and `xsim' can
-% use the `verbwrite' module
-\RequirePackage{scrlfile}
-\ExplSyntaxOn
-
-\msg_new:nnn {xsim} {module-missing}
- {
- You've~ requested~ the~ xsim~ module~ `#1'~ but~ it~ appears~ to~
- be~ missing~ on~ your~ system.~ Maybe~ you've~ misspelled~ the~ name?~
- Loading~ the~ module~ will~ abort~ \msg_line_context:
- }
-
-\msg_new:nnn {xsim} {loading-module}
- { Loading~ module~ `#1'~ ... }
-
-\msg_new:nnn {xsim} {wrong-module-name}
- { The~ module~ file~ name~ is~ `#2'~ but~ it~ provides~ module~ `#1'. }
-
-\msg_new:nnn {xsim} {forbidden-module}
- {
- You've~ requested~ the~ xsim~ module~ `modules'~ \msg_line_context: .~
- This~ module~ is~ a~ pseudo~ module~ which~ may~ not~ be~ loaded~ through~
- the~ module~ loading~ mechansim.
- }
-
-% ----------------------------------------------------------------------------
-
-\cs_generate_variant:Nn \str_if_eq:nnF {xx}
-
-\tl_const:Nn \c__xsim_module_extension_tl {code.tex}
-\tl_const:Nn \c__xsim_module_prefix_tl {xsim}
-
-\seq_new:N \g__xsim_loaded_modules_seq
-\prop_new:N \g__xsim_loaded_modules_prop
-
-\cs_new_protected:Npn \xsim_load_modules:n #1
- { \clist_map_inline:nn {#1} { \xsim_load_module:n {##1} } }
-
-\cs_new_protected:Npn \xsim_load_module:n #1
- {
- \tl_set:Nx \l_tmpa_tl { \tl_trim_spaces:n {#1} }
- \str_if_eq:VnTF \l_tmpa_tl {modules}
- { \msg_error:nn {xsim} {forbidden-module} }
- { \__xsim_load_module:V \l_tmpa_tl }
- }
-
-\cs_new_protected:Npn \__xsim_load_module:n #1
- {
- \xsim_if_module_loaded:nF {#1}
- {
- \xsim_if_module_exist:nTF {#1}
- {
- \__xsim_use_module_hook:nn {#1} {before}
- \msg_info:nnn {xsim} {loading-module} {#1}
- \@onefilewithoptions
- {\c__xsim_module_prefix_tl.#1}[][]
- \c__xsim_module_extension_tl
- \__xsim_use_module_hook:nn {#1} {after}
- }
- { \msg_error:nnn {xsim} {module-missing} {#1} }
- }
- }
-\cs_generate_variant:Nn \__xsim_load_module:n {V}
-
-\prg_new_conditional:Npnn \xsim_if_module_loaded:n #1 {p,T,F,TF}
- {
- \seq_if_in:NnTF \g__xsim_loaded_modules_seq {#1}
- { \prg_return_true: }
- { \prg_return_false: }
- }
-
-\prg_new_conditional:Npnn \xsim_if_module_exist:n #1 {p,T,F,TF}
- {
- \file_if_exist:nTF
- {\c__xsim_module_prefix_tl.#1.\c__xsim_module_extension_tl}
- { \prg_return_true: }
- { \prg_return_false: }
- }
-
-% --------------------------------------------------------------------------
-% module hooks:
-% #1: module
-% #2: code
-\cs_new_protected:Npn \xsim_after_module:nn #1#2
- {
- \xsim_if_module_loaded:nTF {#1}
- {#2}
- { \__xsim_add_to_module_hook:nnn {#1} {after} {#2} }
- }
-
-% #1: module
-% #2: code
-\cs_new_protected:Npn \xsim_before_module:nn #1#2
- {
- \xsim_if_module_loaded:nF {#1}
- { \__xsim_add_to_module_hook:nnn {#1} {before} {#2} }
- }
-
-% #1: module
-% #2: hook name
-% #3: code
-\cs_new_protected:Npn \__xsim_add_to_module_hook:nnn #1#2#3
- {
- \xsim_if_module_loaded:nF {#1}
- {
- \tl_if_exist:cF {g__xsim_module_#1_#2_hook_tl}
- { \tl_new:c {g__xsim_module_#1_#2_hook_tl} }
- \tl_gput_right:cn {g__xsim_module_#1_#2_hook_tl} {#3}
- }
- }
-
-% #1: module
-% #2: hook name
-\cs_new_protected:Npn \__xsim_use_module_hook:nn #1#2
- {
- \tl_if_exist:cT {g__xsim_module_#1_#2_hook_tl}
- {
- \tl_use:c {g__xsim_module_#1_#2_hook_tl}
- \tl_gclear:c {g__xsim_module_#1_#2_hook_tl}
- }
- }
-
-% --------------------------------------------------------------------------
-
-\tl_new:N \l__xsim_module_date_tl
-\tl_new:N \l__xsim_module_version_tl
-
-\tl_if_exist:NF \c_xsim_date_tl
- { \tl_set:Nx \l__xsim_module_date_tl {\c_xsimverb_date_tl} }
-\tl_if_exist:NF \c_xsim_version_tl
- { \tl_set:Nx \l__xsim_module_version_tl {\c_xsimverb_version_tl} }
-
-\AfterPackage*{xsim}
- {
- \tl_set:Nx \l__xsim_module_date_tl {\c_xsim_date_tl}
- \tl_set:Nx \l__xsim_module_version_tl {\c_xsim_version_tl}
- }
-
-\cs_new_protected:Npn \__xsim_module:nn #1#2
- {
- \seq_gput_right:Nn \g__xsim_loaded_modules_seq {#1}
- \prop_gput:Nnn \g__xsim_loaded_modules_prop {#1} {#2}
- \str_if_eq:xxF
- {\c__xsim_module_prefix_tl.#1.\c__xsim_module_extension_tl}
- {\@currname.\@currext}
- {
- \msg_error:nnnxx {xsim} {wrong-module-name}
- {#1}
- {\@currname.\@currext}
- }
- \ProvidesFile
- {\c__xsim_module_prefix_tl.#1.\c__xsim_module_extension_tl}
- [
- \l__xsim_module_date_tl
- \c_space_tl
- v \l__xsim_module_version_tl
- \c_space_tl
- xsim~ module~ `#1'~ (#2)
- ]
- }
-\cs_generate_variant:Nn \msg_error:nnnn {nnnx}
-
-% --------------------------------------------------------------------------
-% define a xsim module:
-% #1: name
-% #2: description
-\NewDocumentCommand \XSIMmodule {mm}
- { \__xsim_module:nn {#1} {#2} \ExplSyntaxOn }
-
-% --------------------------------------------------------------------------
-% style files
-\NewDocumentCommand \xsimstyle {smO{}}
- {
- \__xsim_module:nn {style.#2} {#3}
- \IfBooleanT {#1} { \ExplSyntaxOn }
- }
-
-% \cs_new_protected:Npn \xsim_style_options:nn #1#2
-% { \keys_define:nn {xsim/#1} {#2} }
-
-\cs_new_protected:Npn \xsim_load_style:n #1
- { \clist_map_inline:nn {#1} { \xsim_load_module:n {style.##1} } }
-
-\keys_define:nn {xsim}
- { load-style .code:n = \xsim_load_style:n {#1} }
-
-\NewDocumentCommand \loadxsimstyle {m}
- { \xsim_load_style:n {#1} }
-
-% --------------------------------------------------------------------------
-\file_input_stop:
diff --git a/Master/texmf-dist/tex/latex/xsim/xsim.properties.code.tex b/Master/texmf-dist/tex/latex/xsim/xsim.properties.code.tex
deleted file mode 100644
index 12a6fdf220b..00000000000
--- a/Master/texmf-dist/tex/latex/xsim/xsim.properties.code.tex
+++ /dev/null
@@ -1,540 +0,0 @@
-% ----------------------------------------------------------------------------
-% the XSIM package - properties 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{properties}{properties of exercises}
-
-\xsim_load_modules:n {base,auxfile}
-
-\msg_new:nnn {xsim} {unknown-property}
- {
- You~ tried~ to~ set~ the~ property~ `#1'~ \msg_line_context: . \\
- This~ property~ does~ not~ exist.~ Check~ for~ a~ typo~ or~ \\
- define~ the~ property~ yourself.
- }
-
-\msg_new:nnn {xsim} {property-unique}
- {
- You~ tried~ to~ set~ the~ property~ `#1'~ \msg_line_context: . \\
- This~ property~ has~ to~ have~ a~ unique~ value~ and~ thus~ \\
- cannot~ be~ set~ to~ `#2'~ since~ this~ value~ is~ already~ talen.
- }
-
-\msg_new:nnn {xsim} {no-boolean-property}
- {
- You~ tried~ to~ check~ the~ boolean~ value~ of~ property~ `#1'~
- \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
-
-% #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
-% #2: boolean if boolean
-% #3: boolean if noupdate
-% #4: property name
-\cs_new_protected:Npn \xsim_declare_property:nnnn #1#2#3#4
- {
- \xsim_if_property_exist:nF {#4}
- {
- \seq_put_right:Nn \l__xsim_properties_seq {#4}
- \bool_if:nTF {#3}
- {
- \seq_if_in:NnF \l__xsim_noupdate_properties_seq {#4}
- { \seq_put_right:Nn \l__xsim_noupdate_properties_seq {#4} }
- }
- { \xsim_new_list:n {#4} }
- \bool_if:nTF {#2}
- {
- \xsim_verbose:n
- { Declaring~ new~ boolean~ exercise~ property~ `#4'. }
- \seq_if_in:NnF \l__xsim_boolean_properties_seq {#4}
- { \seq_put_right:Nn \l__xsim_boolean_properties_seq {#4} }
- }
- {
- \bool_if:nTF {#1}
- {
- \xsim_verbose:n
- { Declaring~ new~ unique~ exercise~ property~ `#4'. }
- \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}
- }
- { \xsim_verbose:n { Declaring~ new~ exercise~ property~ `#4'. } }
- }
- \bool_if:nF {#3}
- {
- \xsim_at_end_document:n { \xsim_update_list:n {#4} }
- \xsim_at_begin_document:n { \__xsim_set_property_from_list:n {#4} }
- }
- }
- }
-
-% check if property exists:
-\prg_new_conditional:Npnn \xsim_if_property_exist:n #1 {p,T,F,TF}
- {
- \seq_if_in:NnTF \l__xsim_properties_seq {#1}
- { \prg_return_true: }
- { \prg_return_false: }
- }
-\cs_generate_variant:Nn \xsim_if_property_exist:nTF {x}
-
-\prg_new_conditional:Npnn \xsim_if_property_noupdate:n #1 {p,T,F,TF}
- {
- \seq_if_in:NnTF \l__xsim_noupdate_properties_seq {#1}
- { \prg_return_true: }
- { \prg_return_false: }
- }
-\cs_generate_variant:Nn \xsim_if_property_noupdate:nF {V}
-
-\prg_new_conditional:Npnn \xsim_if_property_boolean:n #1 {p,T,F,TF}
- {
- \seq_if_in:NnTF \l__xsim_boolean_properties_seq {#1}
- { \prg_return_true: }
- { \prg_return_false: }
- }
-
-\prg_new_conditional:Npnn \xsim_if_property_unique:n #1 {p,T,F,TF}
- {
- \seq_if_in:NnTF \l__xsim_unique_properties_seq {#1}
- { \prg_return_true: }
- { \prg_return_false: }
- }
-
-% true if property #1 has been set in the /last/ call of
-% \xsim_set_properties:nnn
-\prg_new_conditional:Npnn \xsim_if_property_given:n #1 {p,T,F,TF}
- {
- \seq_if_in:NnTF \l__xsim_given_properties_seq {#1}
- { \prg_return_true: }
- { \prg_return_false: }
- }
-
-% #1: property
-% #2: value
-\prg_new_conditional:Npnn \xsim_if_property_unique_value:nn #1#2 {p,T,F,TF}
- {
- \xsim_if_property_unique:nTF {#1}
- {
- \seq_if_in:cnTF {l__xsim_unique_property_#1_values_seq} {#2}
- { \prg_return_true: }
- { \prg_return_false: }
- }
- { \prg_return_false: }
- }
-
-% #1: type
-% #2: id
-% #3: property
-% #4: value
-\cs_new_protected:Npn \xsim_set_property:nnnn #1#2#3#4
- {
- \xsim_if_property_exist:nTF {#3} % _p
- {
- \xsim_if_property_set:nnnTF {#1} {#2} {#3} % _p
- {
- \xsim_if_property_unique_value:nnTF {#3} {#4} %_p
- { \msg_warning:nnnn {xsim} {property-unique} {#3} {#4} }
- {
- \xsim_if_property_boolean:nTF {#3} % _p
- { \__xsim_set_boolean_property:nnnn {#1} {#2} {#3} {#4} }
- {
- \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} % _p
- { \__xsim_set_boolean_property:nnnn {#1} {#2} {#3} {#4} }
- {
- \xsim_if_property_unique:nTF {#3} % _p
- { \__xsim_set_unique_property:nnnn {#1} {#2} {#3} {#4} }
- { \__xsim_set_property:nnnn {#1} {#2} {#3} {#4} }
- }
- }
- }
- { \msg_error:nnn {xsim} {unknown-property} {#3} }
- }
-\cs_generate_variant:Nn \xsim_set_property:nnnn {nnxx,nnnV,nV,nVnx,nnnx,xx,xxnx,nxnx}
-
-% #1: type
-% #2: id
-% #3: property
-% #4: value
-\cs_new_protected:Npn \__xsim_set_boolean_property:nnnn #1#2#3#4
- {
- \str_case_e:nnTF { \str_lowercase:n {#4} }
- {
- {} {}
- {true} {}
- }
- { \__xsim_set_property:nnnn {#1} {#2} {#3} {true} }
- { \__xsim_set_property:nnnn {#1} {#2} {#3} {false} }
- }
-
-% #1: type
-% #2: id
-% #3: property
-% #4: value
-\cs_new_protected:Npn \__xsim_set_unique_property:nnnn #1#2#3#4
- {
- \__xsim_set_property:nnnn {#1} {#2} {#3} {#4}
- \__xsim_set_property_reverse:nnnn {#1} {#2} {#3} {#4}
- }
-
-% #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}
- { \__xsim_unset_property:nnn {#1} {#2} {#3} }
- { \msg_error:nnn {xsim} {unknown-property} {#3} }
- }
-\cs_generate_variant:Nn \xsim_unset_property:nnn {nx,nnx,nV}
-
-% #1: type
-% #2: id
-% #3: property
-% #4: value
-\cs_new_protected:Npn \__xsim_set_property:nnnn #1#2#3#4
- {
- \xsim_verbose:n
- {
- Setting~ property~ `#3'~ of~ exercise~ type~ `#1'~ id~ `#2'~ to~
- value~ `#4'.
- }
- \__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}}
- \xsim_attribute_set:nnn {#1!#2} {#3} {#4}
- }
-\cs_generate_variant:Nn \__xsim_set_property:nnnn {VVnV}
-
-% #1: type
-% #2: id
-% #3: property
-% #4: value
-\cs_new_protected:Npn \__xsim_set_property_reverse:nnnn #1#2#3#4
- {
- \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 \{ }
-\tl_set:Nx \l__xsim_tmpb_tl { \cs_to_str:N \} }
-\use:x
- {
- \cs_new_protected:Npn
- \exp_not:N \__xsim_extract_property_list_entry:NNNwww
- ##1##2##3##4-##5== \l__xsim_tmpa_tl ##6 \l__xsim_tmpb_tl
- \exp_not:N \q_stop
- }
- {
- \str_set:Nn #1 {#4}
- \str_set:Nn #2 {#5}
- \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:
- \xsim_foreach_list_entry:nn {#3}
- {
- \__xsim_extract_property_list_entry:NNNwww
- \l__xsim_tmpa_str \l__xsim_tmpb_str \l__xsim_tmpc_str ##1 \q_stop
- \str_if_eq:xnT { \l__xsim_tmpa_str - \l__xsim_tmpb_str } {#1-#2}
- {
- \xsim_remove_from_list:nx {#3}
- { #1-#2 == {\l__xsim_tmpc_str} }
- }
- }
- % make sure we change the entry if it has been set during the current run:
- \xsim_foreach_new_list_entry:nn {#3}
- {
- \__xsim_extract_property_list_entry:NNNwww
- \l__xsim_tmpa_str \l__xsim_tmpb_str \l__xsim_tmpc_str ##1 \q_stop
- \str_if_eq:xnT { \l__xsim_tmpa_str - \l__xsim_tmpb_str } {#1-#2}
- {
- \xsim_remove_from_list:nx {#3}
- { #1-#2 == {\l__xsim_tmpc_str} }
- }
- }
- }
-
-\cs_new_protected:Npn \__xsim_set_property_from_list:n #1
- {
- \xsim_foreach_list_entry:nn {#1}
- {
- \__xsim_extract_property_list_entry:NNNwww
- \l__xsim_tmpa_str \l__xsim_tmpb_str \l__xsim_tmpc_str ##1 \q_stop
- \tl_set_rescan:Nnx \l__xsim_tmpc_tl {} { \l__xsim_tmpc_str }
- \__xsim_set_property:VVnV
- \l__xsim_tmpa_str
- \l__xsim_tmpb_str
- {#1}
- \l__xsim_tmpc_tl
- }
- }
-
-% set properties:
-% #1: type
-% #2: id
-% #3: csv list of properties
-\cs_new_protected:Npn \xsim_set_properties:nnn #1#2#3
- {
- \seq_clear:N \l__xsim_given_properties_seq
- \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}
- { \seq_item:Nn \l__xsim_tmpa_seq {1} }
- { \seq_item:Nn \l__xsim_tmpa_seq {2} }
- \seq_put_right:Nx \l__xsim_given_properties_seq
- { \seq_item:Nn \l__xsim_tmpa_seq {1} }
- }
- \xsim_property_set_aliases:nn {#1} {#2}
- }
-\cs_generate_variant:Nn \xsim_set_properties:nnn {nnx,nxx,nV,nVx}
-
-% ----------------------------------------------------------------------------
-
-\seq_new:N \g__xsim_property_aliases_seq
-
-% #1: property
-\prg_new_conditional:Npnn \xsim_if_property_alias:n #1 {p,T,F,TF}
- {
- \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
- { \xsim_attribute_get:nn {#1} {alias} }
-
-% #1: property
-% #2: alias of
-\cs_new_protected:Npn \xsim_make_property_alias:nn #1#2
- {
- \xsim_if_property_alias:nF {#1}
- {
- \xsim_verbose:n
- { Making~ property~ `#1'~ an~ alias~ of~ property~ `#2'. }
- \xsim_attribute_set:nnn {#1} {alias} {#2}
- \seq_gput_right:Nn \g__xsim_property_aliases_seq {#1}
- }
- }
-
-% #1: type
-% #2: id
-% #3: property
-\cs_new_protected:Npn \xsim_property_set_alias:nnn #1#2#3
- {
- \xsim_if_property_set:nnnF {#1} {#2} {#3}
- {
- \xsim_if_property_set:nnxT {#1} {#2}
- { \xsim_property_alias:n {#3} }
- {
- \xsim_set_property:nnnx {#1} {#2} {#3}
- {
- \xsim_get_property:nnf {#1} {#2}
- { \xsim_property_alias:n {#3} }
- }
- }
- }
- \xsim_if_property_set:nnxT {#1} {#2}
- { \xsim_property_alias:n {#3} }
- {
- \xsim_attribute_set:nnx {alias:#1!#2} {#3}
- {
- \xsim_get_property:nnf {#1} {#2}
- { \xsim_property_alias:n {#3} }
- }
- }
- }
-\cs_generate_variant:Nn \xsim_property_set_alias:nnn {nV}
-
-% #1: type
-% #2: id
-\cs_new_protected:Npn \xsim_property_set_aliases:nn #1#2
- {
- \seq_map_inline:Nn \g__xsim_property_aliases_seq
- { \xsim_property_set_alias:nnn {#1} {#2} {##1} }
- }
-
-% ----------------------------------------------------------------------------
-
-% retrieve properties:
-% #1: type
-% #2: id
-% #3: property
-\cs_new:Npn \xsim_get_property:nnn #1#2#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
- { \xsim_attribute_get:nn {id:#1} {#2} }
-
-% #1: property
-% #2: value
-\cs_new:Npn \xsim_get_type_for_property:nn #1#2
- { \xsim_attribute_get:nn {type:#1} {#2} }
-\cs_generate_variant:Nn \xsim_get_type_for_property:nn {nV}
-
-% #1: id or ID
-\cs_new:Npn \xsim_normalize_id:n #1
- {
- \tl_if_blank:eTF
- { \xsim_get_id_for_property:nn {ID} {#1} }
- {#1}
- { \xsim_get_id_for_property:nn {ID} {#1} }
- }
-\cs_generate_variant:Nn \xsim_normalize_id:n {e}
-
-\cs_new:Npn \__xsim_get_property_tmp:n #1 {}
-\cs_generate_variant:Nn \__xsim_get_property_tmp:n {V}
-
-% #1: type
-% #2: id
-% #3: property
-\cs_new_protected:Npn \xsim_get_property_if_set:nnnTF #1#2#3#4#5
- {
- \group_begin:
- \xsim_if_property_exist:nTF {#3}
- {
- \xsim_if_property_set:nnnTF {#1} {#2} {#3}
- {
- \tl_set:Nx \PropertyValue
- { \xsim_get_property:nnn {#1} {#2} {#3} }
- \cs_set:Npn \__xsim_get_property_tmp:n ##1 {#4}
- \__xsim_get_property_tmp:V \PropertyValue
- }
- {#5}
- }
- { \msg_error:nnn {xsim} {unknown-property} {#3} }
- \group_end:
- }
-\cs_new_protected:Npn \xsim_get_property_if_set:nnnT #1#2#3#4
- { \xsim_get_property_if_set:nnnTF {#1} {#2} {#3} {#4} {} }
-\cs_new_protected:Npn \xsim_get_property_if_set:nnnF #1#2#3#4
- { \xsim_get_property_if_set:nnnTF {#1} {#2} {#3} {} {#4} }
-\cs_generate_variant:Nn \xsim_get_property_if_set:nnnTF {oo}
-
-% #1: type
-% #2: id
-% #3: property
-\prg_new_conditional:Npnn \xsim_if_boolean_property:nnn #1#2#3 {T,F,TF}
- {
- \xsim_if_property_exist:nTF {#3}
- {
- \xsim_if_property_boolean:nTF {#3}
- {
- \xsim_if_property_set:nnnTF {#1} {#2} {#3}
- {
- \bool_if:cTF
- {c_ \xsim_get_property:nnn {#1} {#2} {#3} _bool}
- { \prg_return_true: }
- { \prg_return_false: }
- }
- { \prg_return_false: }
- }
- { \msg_error:nnn {xsim} {no-boolean-property} {#3} }
- }
- { \msg_error:nnn {xsim} {unknown-property} {#3} }
- }
-\cs_generate_variant:Nn \xsim_if_boolean_property:nnnTF {oo}
-\cs_generate_variant:Nn \xsim_if_boolean_property:nnnF {nV}
-
-\cs_new_protected:Npn \xsim_save_property:nnnN #1#2#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
- {
- \xsim_save_property:nnnN {#1} {#2} {#3} #4
- \tl_gset:NV #4 #4
- }
-\cs_generate_variant:Nn \xsim_gsave_property:nnnN {nx,xx,nV}
-
-% ----------------------------------------------------------------------------
-\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/Master/texmf-dist/tex/latex/xsim/xsim.random.code.tex b/Master/texmf-dist/tex/latex/xsim/xsim.random.code.tex
deleted file mode 100644
index cdd23e3a209..00000000000
--- a/Master/texmf-dist/tex/latex/xsim/xsim.random.code.tex
+++ /dev/null
@@ -1,315 +0,0 @@
-% ----------------------------------------------------------------------------
-% the XSIM package - random 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{random}{randomly select exercises from collections}
-
-\msg_new:nnn {xsim} {random-numbers-unavailable}
- {
- You~ are~ compiling~ your~ document~ using ~XeLaTeX.~ Please~ be~ aware~
- that~ random~ selection~ of~ exercises~ is~ unavailable~ in~ XeLaTeX.~ If~
- you~ use~ this~ feature~ you~ can~ safely~ ignore~ this~ message.
- }
-
-\sys_if_engine_xetex:T
- { \msg_warning:nn {xsim} {random-numbers-unavailable} }
-
-\xsim_load_modules:n {collections}
-
-\tl_new:N \l_xsim_random_collection_tl
-\tl_new:N \l__xsim_print_random_choice_tl
-\tl_const:Nn \c__xsim_print_random_both_tl {both}
-\tl_const:Nn \c__xsim_print_random_exercise_tl {exercise}
-\tl_const:Nn \c__xsim_print_random_solution_tl {solution}
-\seq_new:N \g__xsim_random_list_seq
-\seq_new:N \l__xsim_allowed_exercise_ids_seq
-\int_new:N \g__xsim_random_list_id_int
-\bool_new:N \l__xsim_sort_random_bool
-\clist_new:N \l_xsim_random_exclude_list_clist
-
-% #1: random list id
-% #2: csv list of integers
-\xsim_new_aux_property:cpn {random} #1#2
- {
- \xsim_random_list_if_exist:nF {#1}
- { \xsim_new_random_list:n {#1} }
- \xsim_set_random_list:nn {#1} {#2}
- }
-
-\cs_new_protected:Npn \xsim_new_random_list:n #1
- {
- \xsim_verbose:n {Defining~ new~ random~ list~ `#1'}
- \seq_new:c {g__xsim_random_#1 _seq}
- }
-
-\cs_new_protected:Npn \xsim_set_random_list:nn #1#2
- { \seq_gset_from_clist:cn {g__xsim_random_#1_seq} {#2} }
-
-\cs_new_protected:Npn \xsim_set_random_list_from_seq:nN #1#2
- { \seq_gset_eq:cN {g__xsim_random_#1_seq} #2 }
-
-\cs_new:Npn \xsim_use_random_list:nn #1#2
- { \seq_use:cn {g__xsim_random_#1_seq} {#2} }
-
-\cs_new_protected:Npn \xsim_map_random_list:nn #1#2
- { \seq_map_inline:cn {g__xsim_random_#1_seq} {#2} }
-
-\prg_new_conditional:Npnn \xsim_random_list_if_exist:n #1 {p,T,F,TF}
- {
- \seq_if_exist:cTF {g__xsim_random_#1_seq}
- { \prg_return_true: }
- { \prg_return_false: }
- }
-
-\prg_new_conditional:Npnn \xsim_random_list_if_empty:n #1 {p,T,F,TF}
- {
- \seq_if_empty:cTF {g__xsim_random_#1_seq}
- { \prg_return_true: }
- { \prg_return_false: }
- }
-
-% #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}
- { \xsim_set_random_list_from_seq:nN {#1} #2 }
- \xsim_verbose:n {Saving~ random~ list~ `#1'}
- \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
-% #3: clist variable of excluded ids
-\cs_new_protected:Npn \xsim_print_random_list:nnN #1#2#3
- {
- \xsim_if_collection_exist:nTF {#1}
- {
- \int_gincr:N \g__xsim_random_list_id_int
- \int_compare:nNnTF { \xsim_collection_count:n {#1} } = {0}
- { \xsim_rerun: }
- {
- % generate seq of allowed ids from collection:
- \xsim_foreach_exercise_id:n
- {
- \tl_set:Nx \l__xsim_tmpa_tl
- { \xsim_get_type_for_property:nn {id} {##1} }
- \xsim_if_in_collection:nVnT {#1} \l__xsim_tmpa_tl {##1}
- {
- \clist_if_in:NnF #3 {##1}
- { \seq_put_right:Nn \l__xsim_allowed_exercise_ids_seq {##1} }
- }
- }
- \int_compare:nNnTF
- {#2}
- >
- { \seq_count:N \l__xsim_allowed_exercise_ids_seq }
- {
- \int_set:Nn \l__xsim_tmpa_int
- { \seq_count:N \l__xsim_allowed_exercise_ids_seq }
- }
- { \int_set:Nn \l__xsim_tmpa_int {#2} }
- % generate random list:
- \xsim_generate_random_list:nnnN
- { \int_to_alph:n { \g__xsim_random_list_id_int } }
- { \seq_count:N \l__xsim_allowed_exercise_ids_seq }
- { \l__xsim_tmpa_int }
- \g__xsim_random_list_seq
- }
- \xsim_save_random_list:xN
- { \int_to_alph:n { \g__xsim_random_list_id_int } }
- \g__xsim_random_list_seq
- \xsim_verbose:x
- {
- Printing~ exercises~ of~ random~ list~
- `\int_to_alph:n { \g__xsim_random_list_id_int }'~ of~
- collection~ `#1'
- }
- \xsim_print_random_exercises:Nn
- \l__xsim_allowed_exercise_ids_seq
- { \int_to_alph:n { \g__xsim_random_list_id_int } }
- }
- { \msg_error:nnn {xsim} {unknown-collection} {#1} }
- }
-\cs_generate_variant:Nn \xsim_print_random_list:nnN {V}
-
-% #1: random list id
-% #2: max number to choose from
-% #3: number of items
-% #4: seq variable
-\cs_new_protected:Npn \xsim_generate_random_list:nnnN #1#2#3#4
- {
- \bool_lazy_or:nnT
- { !\xsim_random_list_if_exist_p:n {#1} }
- { \xsim_random_list_if_empty_p:n {#1} }
- {
- \xsim_verbose:n
- {Generating~ random~ list~ `#1'~ with~ #3~ out~ of~ #2~ items}
- \seq_gclear:N #4
- \int_do_until:nNnn { \seq_count:N #4 } = {#3}
- {
- \tl_set:Nx \l__xsim_tmpa_tl
- { \fp_eval:n { randint(#2) } }
- \seq_if_in:NVF #4
- \l__xsim_tmpa_tl
- { \seq_gput_right:NV #4 \l__xsim_tmpa_tl }
- }
- \bool_if:NT \l__xsim_sort_random_bool
- {
- \seq_sort:Nn #4
- {
- \int_compare:nNnTF {##1} > {##2}
- { \sort_return_swapped: }
- { \sort_return_same: }
- }
- }
- }
- }
-
-% #1: seq variable of ids
-% #2: random list id
-\cs_new_protected:Npn \xsim_print_random_exercises:Nn #1#2
- {
- \bool_lazy_and:nnT
- { \xsim_random_list_if_exist_p:n {#2} }
- { !\xsim_random_list_if_empty_p:n {#2} }
- {
- \xsim_verbose:x
- {
- Printing~
- \l__xsim_print_random_choice_tl \c_space_tl
- \str_if_eq:onT { \l__xsim_print_random_choice_tl } {both}
- { exercises~ and~ solutions~ }
- of~ random~ list~ `#2'
- }
- \xsim_map_random_list:nn {#2}
- {
- \tl_set:Nx \l__xsim_tmpa_tl
- { \seq_item:Nn #1 {##1} }
- \tl_set:Nx \l__xsim_tmpb_tl
- { \xsim_get_type_for_property:nV {id} \l__xsim_tmpa_tl }
- \bool_lazy_or:nnT
- {
- \tl_if_eq_p:NN
- \l__xsim_print_random_choice_tl
- \c__xsim_print_random_both_tl
- }
- {
- \tl_if_eq_p:NN
- \l__xsim_print_random_choice_tl
- \c__xsim_print_random_exercise_tl
- }
- {
- \xsim_if_exercise_exist:VVT
- \l__xsim_tmpb_tl
- \l__xsim_tmpa_tl
- {
- \xsim_insert:VVnn
- \l__xsim_tmpb_tl
- \l__xsim_tmpa_tl
- {}
- {exercise}
- }
- }
- \bool_lazy_or:nnT
- {
- \tl_if_eq_p:NN
- \l__xsim_print_random_choice_tl
- \c__xsim_print_random_both_tl
- }
- {
- \tl_if_eq_p:NN
- \l__xsim_print_random_choice_tl
- \c__xsim_print_random_solution_tl
- }
- {
- \xsim_if_solution_exist:VVT
- \l__xsim_tmpb_tl
- \l__xsim_tmpa_tl
- {
- \xsim_insert:VVnn
- \l__xsim_tmpb_tl
- \l__xsim_tmpa_tl
- {}
- {solution}
- }
- }
- }
- }
- }
-
-\keys_define:nn {xsim/random}
- {
- sort .bool_set:N = \l__xsim_sort_random_bool ,
- sort .initial:n = true ,
- collection .tl_set:N = \l_xsim_random_collection_tl ,
- collection .initial:n = all~exercises ,
- exclude .code:n = \__xsim_exclude_ids:n {#1} ,
- print .choice: ,
- print/exercises .code:n =
- \tl_set:Nn \l__xsim_print_random_choice_tl {exercise} ,
- print/solutions .code:n =
- \tl_set:Nn \l__xsim_print_random_choice_tl {solution} ,
- print/both .code:n =
- \tl_set:Nn \l__xsim_print_random_choice_tl {both} ,
- print/unknown .code:n =
- \msg_warning:nnn {xsim} {print-collection-choice} {#1}
- \tl_set:Nn \l__xsim_print_random_choice_tl {exercise} ,
- print .initial:n = exercises
- }
-
-\cs_new_protected:Npn \__xsim_exclude_ids:n #1
- {
- \seq_clear:N \l__xsim_tmpa_seq
- \clist_map_inline:nn {#1}
- {
- \tl_set:Nx \l__xsim_tmpa_tl
- { \xsim_get_id_for_property:nn {ID} {##1} }
- \tl_if_blank:VTF \l__xsim_tmpa_tl
- { \seq_put_right:Nn \l__xsim_tmpa_seq {##1} }
- {
- \seq_put_right:Nx \l__xsim_tmpa_seq
- { \xsim_get_id_for_property:nn {ID} {##1} }
- }
- }
- \seq_remove_duplicates:N \l__xsim_tmpa_seq
- \clist_set_from_seq:NN
- \l_xsim_random_exclude_list_clist
- \l__xsim_tmpa_seq
- }
-
-% use this in the exclude list:
-% \xsim_get_type_for_property:nn {id} {}
-% or a combination of:
-% \xsim_get_type_for_property:nn {ID} {}
-% \xsim_get_id_for_property:nn {ID} {}
-
-% ----------------------------------------------------------------------------
-\file_input_stop:
diff --git a/Master/texmf-dist/tex/latex/xsim/xsim.solutions.code.tex b/Master/texmf-dist/tex/latex/xsim/xsim.solutions.code.tex
deleted file mode 100644
index 0a691945085..00000000000
--- a/Master/texmf-dist/tex/latex/xsim/xsim.solutions.code.tex
+++ /dev/null
@@ -1,414 +0,0 @@
-% ----------------------------------------------------------------------------
-% the XSIM package - solutions 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{solutions}{managing solutions}
-
-\xsim_load_modules:n {tags,properties}
-
-\bool_new:N \l_xsim_inside_solution_bool
-\bool_new:N \l__xsim_include_question_bool
-\bool_new:N \l__xsim_printsolutions_headings_bool
-\bool_new:N \l__xsim_printsolutions_conditions_bool
-\bool_new:N \l____xsim_this_condition_bool
-
-\seq_new:N \l__xsim_printsolutions_conditions_seq
-
-\int_new:N \l_xsim_printsolutions_section_int
-\int_new:N \l_xsim_printsolutions_chapter_int
-
-\tl_new:N \l__xsim_printsolutions_headings_template_tl
-\tl_new:N \ExerciseSection
-\tl_new:N \ExerciseChapter
-\tl_new:N \l__xsim_printsolutions_collection_tl
-
-% ----------------------------------------------------------------------------
-
-\prg_new_conditional:Npnn \xsim_if_inside_solution: {p,T,F,TF}
- {
- \bool_if:NTF \l_xsim_inside_solution_bool
- { \prg_return_true: }
- { \prg_return_false: }
- }
-
-\prg_new_conditional:Npnn \xsim_if_solution_print:n #1 {p,T,F,TF}
- {
- \bool_if:cTF {l__xsim_#1_solution_print_bool}
- { \prg_return_true: }
- { \prg_return_false: }
- }
-
-% #1: type
-% #2: id
-\prg_new_protected_conditional:Npnn \xsim_solution_if_print:nn #1#2 {T,F,TF}
- {
- \bool_set_true: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:cF {l__xsim_#1_solution_print_bool}
- { \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_solution_if_print:nnT {nV,oo}
-
-% #1: type
-% #2: id
-\prg_new_protected_conditional:Npnn \xsim_if_solution_exist:nn #1#2 {T,F,TF}
- {
- \xsim_if_boolean_property:nnnTF {#1} {#2} {solution}
- { \xsim_if_exist:nnnTF {#1} {#2} {exercise} }
- { \xsim_if_exist:nnnTF {#1} {#2} {solution} }
- { \prg_return_true: }
- { \prg_return_false: }
- }
-\cs_generate_variant:Nn \xsim_if_solution_exist:nnT {VV,oo}
-\cs_generate_variant:Nn \xsim_if_solution_exist:nnTF {oo}
-
-% #1: type
-% #2: options
-\cs_new_protected:Npn \xsim_start_solution:nn #1#2
- {
- \keys_set:xn { xsim/\xsim_get_parameter:nn {#1} {solution-env} } {#2}
- \bool_set_true:N \l_xsim_inside_solution_bool
- \refstepcounter { \xsim_get_parameter:nn {#1} {solution-counter} }
- }
-
-\cs_new_protected:Npn \xsim_stop_solution:n #1 {}
-
-% ----------------------------------------------------------------------------
-
-% #1: conditional base function (three n args)
-% #2: name
-% #3: code (refer to type and id with `#1' and `#2'), #3 refers to the boolean
-% properties use/print
-\cs_new_protected:Npn \xsim_new_solutions_condition:Nnn #1#2#3
- {
- \prg_new_protected_conditional:Npnn #1 ##1##2##3 {T,F,TF}
- {
- \xsim_if_in_list:nnTF {##3} {##1-##2=={true}}
- {
- \__xsim_printsolutions_if_condition:nTF {#2}
- { \__xsim_printsolutions_condition_true: #3 }
- { \prg_return_false: }
- }
- { \prg_return_false: }
- }
- }
-
-% per section condition:
-\xsim_new_solutions_condition:Nnn \__xsim_if_solutions_per_section:nnn
- {per-section}
- {
- \xsim_if_in_list:nxTF {section-value}
- { #1-#2 == { \int_use:N \l_xsim_printsolutions_section_int } }
- {
- \tl_set:Nx \ExerciseSection
- { \xsim_get_property:nnn {#1} {#2} {section} }
- \prg_return_true:
- }
- { \prg_return_false: }
- }
-
-% per chapter condition:
-\xsim_new_solutions_condition:Nnn \__xsim_if_solutions_per_chapter:nnn
- {per-chapter}
- {
- \xsim_if_in_list:nxTF {chapter-value}
- { #1-#2 == { \int_use:N \l_xsim_printsolutions_chapter_int } }
- {
- \tl_set:Nx \ExerciseChapter
- { \xsim_get_property:nnn {#1} {#2} {chapter} }
- \prg_return_true:
- }
- { \prg_return_false: }
- }
-
-% per collection condition:
-\xsim_new_solutions_condition:Nnn \__xsim_if_solutions_in_collection:nnn
- {per-collection}
- {
- \tl_if_blank:VTF \l__xsim_printsolutions_collection_tl
- { \prg_return_false: }
- {
- \xsim_if_in_collection:VnnTF
- \l__xsim_printsolutions_collection_tl
- {#1}
- {#2}
- { \prg_return_true: }
- { \prg_return_false: }
- }
- }
-
-% ----------------------------------------------------------------------------
-% conditions mechanism
-\cs_new_protected:Npn \__xsim_printsolutions_condition_false:
- { \bool_set_false:N \l__xsim_printsolutions_conditions_bool }
-
-\cs_new_protected:Npn \__xsim_printsolutions_condition_true:
- { \bool_set_true:N \l__xsim_printsolutions_conditions_bool }
-
-% #1: type
-% #2: id
-% #3: boolean property
-\prg_new_conditional:Npnn
- \__xsim_printsolutions_if_conditions:nnn #1#2#3 {T,F,TF}
- {
- \bool_if:NTF \l__xsim_printsolutions_conditions_bool
- { \prg_return_true: }
- {
- \xsim_if_in_list:nnTF {#3} {#1-#2=={true}}
- { \prg_return_false: }
- { \prg_return_true: }
- }
- }
-
-% #1: name
-% #2: condition
-\cs_new_protected:Npn \xsim_declare_printsolutions_condition:nn #1#2
- {
- \bool_new:c {l__xsim_printsolutions_#1_condition_bool}
- \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}
- {
- \bool_if:cTF {l__xsim_printsolutions_#1_condition_bool}
- { \prg_return_true: }
- { \prg_return_false: }
- }
-
-% #1: name
-% #2: true|false
-\cs_new_protected:Npn \__xsim_printsolutions_condition:nn #1#2
- { \bool_set_eq:cc {l__xsim_printsolutions_#1_condition_bool} {c_#2_bool} }
-
-% false if any condition is false for this solution:
-% #1: type
-% #2: id
-% #3: boolean property
-\prg_new_protected_conditional:Npnn
- \__xsim_printsolutions_check_conditions:nnn #1#2#3 {T,F,TF}
- {
- \__xsim_printsolutions_condition_false:
- \bool_set_true:N \l____xsim_this_condition_bool
- \seq_map_inline:Nn \l__xsim_printsolutions_conditions_seq
- {
- \bool_if:cT {l__xsim_printsolutions_##1_condition_bool}
- {
- \xsim_attribute_get:nn {printsolutions} {##1}
- {#1} {#2} {#3}
- { }
- { \bool_set_false:N \l____xsim_this_condition_bool }
- }
- }
- \bool_if:NTF \l____xsim_this_condition_bool
- { \prg_return_true: }
- { \prg_return_false: }
- }
-
-
-% #1: type
-% #2: id
-% #3: boolean property
-% #4: code
-\cs_new_protected:Npn \xsim_if_this_solution_do:nnnn #1#2#3#4
- {
- \xsim_if_solution_exist:nnT {#1} {#2}
- { \__xsim_printsolutions_check_conditions:nnnT {#1} {#2} {#3} {#4} }
- }
-
-% #1: type
-% #2: boolean property
-% #3: code
-\cs_new_protected:Npn \xsim_if_solutions_do:nnn #1#2#3
- {
- \xsim_foreach_exercise_type_id:nn {#2}
- { \xsim_if_this_solution_do:nnnn {#1} {##2} {#2} {#3} }
- }
-
-% ----------------------------------------------------------------------------
-% #1: boolean -- if true only the solutions of printed exercises will be
-% output
-% #2: pre
-% #3: post
-% #4: type
-% #5: code (refer to type with #1 and id with #2)
-\cs_new_protected:Npn \xsim_print_type_code:nnnnn #1#2#3#4#5
- {
- \group_begin:
- \cs_set_protected:Npn \__xsim_print_entry:nn ##1##2 {#5}
- #2
- \bool_set_false:N \l__xsim_tmpa_bool
- \bool_if:nTF {#1}
- {
- \xsim_if_solutions_do:nnn {#4} {print}
- { \bool_set_true:N \l__xsim_tmpa_bool }
- }
- {
- \xsim_if_solutions_do:nnn {#4} {used}
- { \bool_set_true:N \l__xsim_tmpa_bool }
- }
- \tl_set:Nn \ExerciseType {#4}
- \bool_if:NT \l__xsim_tmpa_bool
- {
- \bool_if:NT \l__xsim_printsolutions_headings_bool
- {
- \xsim_use_template:nV
- {heading}
- \l__xsim_printsolutions_headings_template_tl
- }
- }
- \bool_if:nTF {#1}
- {
- \xsim_if_solutions_do:nnn {#4} {print}
- { \__xsim_print_entry:nn {#4} {##2} }
- }
- {
- \xsim_if_solutions_do:nnn {#4} {used}
- { \__xsim_print_entry:nn {#4} {##2} }
- }
- #3
- \group_end:
- }
-
-% #1: boolean -- if true only the solutions of printed exercises will be
-% output
-% #2: options
-% #3: type
-\cs_new_protected:Npn \xsim_print_type_solutions:nnn #1#2#3
- {
- \xsim_print_type_code:nnnnn
- {#1}
- {
- \xsim_verbose:n
- { Printing~ solutions~ for~ exercise~ type~ `#3'. }
- \keys_set:nn {xsim/print-solutions} {#2}
- }
- {}
- {#3}
- { \xsim_insert:nnnn {##1} {##2} {} {solution} }
- }
-
-% #1: boolean -- if true only the solutions of printed exercises will be
-% output
-% #2: options
-\cs_new_protected:Npn \xsim_print_all_solutions_per_type:nn #1#2
- {
- \xsim_foreach_exercise_type:n
- { \xsim_print_type_solutions:nnn {#1} {#2} {##1} }
- }
-
-% #1: boolean -- if true only the solutions of printed exercises will be
-% output
-% #2: options
-\cs_new_protected:Npn \xsim_print_all_solutions_per_id:nn #1#2
- {
- \xsim_verbose:n { Printing~ solutions. }
- \group_begin:
- \keys_set:nn {xsim/print-solutions} {#2}
- \bool_set_false:N \l__xsim_tmpa_bool
- \bool_if:nTF {#1}
- {
- \xsim_foreach_exercise_id_type:nn {print}
- {
- \xsim_if_this_solution_do:nnnn {##1} {##2} {print}
- { \xsim_insert:nnnn {##1} {##2} {} {solution} }
- }
- }
- {
- \xsim_foreach_exercise_id_type:nn {used}
- {
- \xsim_if_this_solution_do:nnnn {##1} {##2} {used}
- { \xsim_insert:nnnn {##1} {##2} {} {solution} }
- }
- }
- \group_end:
- }
-
-% ----------------------------------------------------------------------------
-
-\xsim_declare_printsolutions_condition:nn {per-section}
- { \__xsim_if_solutions_per_section:nnnTF }
-\xsim_declare_printsolutions_condition:nn {per-chapter}
- { \__xsim_if_solutions_per_chapter:nnnTF }
-\xsim_declare_printsolutions_condition:nn {per-collection}
- { \__xsim_if_solutions_in_collection:nnnTF }
-
-% ----------------------------------------------------------------------------
-
-\keys_define:nn {xsim/print-solutions}
- {
- headings .bool_set:N = \l__xsim_printsolutions_headings_bool ,
- headings .initial:n = true ,
- headings-template .tl_set:N = \l__xsim_printsolutions_headings_template_tl ,
- headings-template .initial:n = default ,
- include-exercise .bool_set:N = \l__xsim_include_question_bool ,
- include-exercise .initial:n = false ,
- section .choice: ,
- section/true .code:n =
- \__xsim_printsolutions_condition:nn {per-section} {true}
- \int_set:Nn \l_xsim_printsolutions_section_int { \value {section} } ,
- section/false .code:n =
- \__xsim_printsolutions_condition:nn {per-section} {false} ,
- section/unknown .code:n =
- \__xsim_printsolutions_condition:nn {per-section} {true}
- \int_set:Nn \l_xsim_printsolutions_section_int {#1} ,
- section .default:n = true ,
- section .initial:n = false ,
- chapter .choice: ,
- chapter/true .code:n =
- \__xsim_printsolutions_condition:nn {per-chapter} {true}
- \int_set:Nn \l_xsim_printsolutions_chapter_int { \value {chapter} } ,
- chapter/false .code:n =
- \__xsim_printsolutions_condition:nn {per-chapter} {false} ,
- chapter/unknown .code:n =
- \__xsim_printsolutions_condition:nn {per-chapter} {true}
- \int_set:Nn \l_xsim_printsolutions_chapter_int {#1} ,
- chapter .default:n = true ,
- chapter .initial:n = false ,
- collection .choice: ,
- collection/false .code:n =
- \__xsim_printsolutions_condition:nn {per-collection} {false} ,
- collection/unknown .code:n =
- \xsim_if_collection_exist:nT {#1}
- {
- \__xsim_printsolutions_condition:nn {per-collection} {true}
- \tl_set:Nn \l__xsim_printsolutions_collection_tl {#1}
- } ,
- collection .initial:n = false
- }
-
-% ----------------------------------------------------------------------------
-
-\file_input_stop:
-
-2020/02/23 - resolve bug #56
-2020/03/16 - performance optimizations
diff --git a/Master/texmf-dist/tex/latex/xsim/xsim.sty b/Master/texmf-dist/tex/latex/xsim/xsim.sty
index cc30ae90528..94866005c48 100644
--- a/Master/texmf-dist/tex/latex/xsim/xsim.sty
+++ b/Master/texmf-dist/tex/latex/xsim/xsim.sty
@@ -8,15 +8,15 @@
% Web: https://github.com/cgnieder/xsim
% E-Mail: contact@mychemistry.eu
% ----------------------------------------------------------------------------
-% Copyright 2017--2020 Clemens Niederberger
+% Copyright 2017--2021 Clemens Niederberger
%
% This work may be distributed and/or modified under the
-% conditions of the LaTeX Project Public License, either version 1.3
+% conditions of the LaTeX Project Public License, either version 1.3c
% 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.
+% and version 1.3c or later is part of all distributions of LaTeX
+% version 2008/05/04 or later.
%
% This work has the LPPL maintenance status `maintained'.
%
@@ -25,14 +25,14 @@
% If you have any ideas, questions, suggestions or bugs to report, please
% feel free to contact me.
% ----------------------------------------------------------------------------
-\RequirePackage {expl3,xparse,l3keys2e}
+\RequirePackage {l3keys2e,xsimverb}
\ExplSyntaxOn
-\tl_const:Nn \c_xsim_date_tl {2020/04/04}
+\tl_const:Nn \c_xsim_date_tl {2021/01/31}
\tl_const:Nn \c_xsim_version_major_number_tl {0}
-\tl_const:Nn \c_xsim_version_minor_number_tl {19}
-\tl_const:Nn \c_xsim_version_subrelease_tl {b}
+\tl_const:Nn \c_xsim_version_minor_number_tl {20}
+\tl_const:Nn \c_xsim_version_subrelease_tl {}
\tl_const:Nx \c_xsim_version_number_tl
{
\c_xsim_version_major_number_tl .
@@ -52,30 +52,36 @@
{\c_xsim_info_tl}
% --------------------------------------------------------------------------
-
% options, information
-\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
-\bool_new:N \g__xsim_rerun_bool
-\bool_new:N \g__xsim_blank_bool
+\cs_new_protected:Npn \xsim_bool_provide:N #1
+ { \bool_if_exist:NF #1 { \bool_new:N #1 } }
+
+\xsim_bool_provide:N \g__xsim_final_bool
+\xsim_bool_provide:N \g__xsim_verbose_bool
+\xsim_bool_provide:N \g_xsim_clear_aux_bool
+\xsim_bool_provide:N \g__xsim_write_to_file_bool
+\xsim_bool_provide:N \g_xsim_use_aux_bool
+\xsim_bool_provide:N \g__xsim_rerun_bool
+\xsim_bool_provide:N \g__xsim_debug_bool
+\xsim_bool_provide:N \g__xsim_blank_bool
\keys_define:nn {xsim/package}
{
- 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 ,
- use-aux .bool_gset:N = \g_xsim_use_aux_bool ,
- use-aux .initial:n = false ,
- blank .bool_gset:N = \g__xsim_blank_bool ,
- blank .initial:n = false
+ 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 ,
+ use-files .bool_gset:N = \g__xsim_write_to_file_bool ,
+ use-files .initial:n = false ,
+ no-files .choice: ,
+ no-files / true .meta:n = { use-files = false } ,
+ no-files / false .meta:n = { use-files = true } ,
+ no-files .default:n = true ,
+ use-aux .bool_gset:N = \g_xsim_use_aux_bool ,
+ use-aux .initial:n = false ,
+ blank .bool_gset:N = \g__xsim_blank_bool ,
+ blank .initial:n = false
}
\ProcessKeysPackageOptions {xsim/package}
@@ -86,6 +92,7 @@
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} ,
+ use-files .code:n = \msg_error:nnn {xsim} {load-time-option} {use-files} ,
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} ,
blank .code:n = \msg_error:nnn {xsim} {load-time-option} {blank}
@@ -115,22 +122,5508 @@
{ \xsim_if_rerun:T { \msg_warning:nn {xsim} {rerun} } }
% --------------------------------------------------------------------------
+% MODULE mechanism
+\msg_new:nnn {xsim} {module-missing}
+ {
+ You've~ requested~ the~ xsim~ module~ `#1'~ but~ it~ appears~ to~
+ be~ missing~ on~ your~ system.~ Maybe~ you've~ misspelled~ the~ name?~
+ Loading~ the~ module~ will~ abort~ \msg_line_context:
+ }
+
+\msg_new:nnn {xsim} {loading-module}
+ { Loading~ module~ `#1'~ ... }
+
+\msg_new:nnn {xsim} {wrong-module-name}
+ { The~ module~ file~ name~ is~ `#2'~ but~ it~ provides~ module~ `#1'. }
+
+\msg_new:nnn {xsim} {forbidden-module}
+ {
+ You've~ requested~ the~ xsim~ module~ `modules'~ \msg_line_context: .~
+ This~ module~ is~ a~ pseudo~ module~ which~ may~ not~ be~ loaded~ through~
+ the~ module~ loading~ mechansim.
+ }
+
+% ----------------------------------------------------------------------------
-% load module mechanism:
-\tl_set:Nn \l_tmpa_tl {code.tex}
-\@onefilewithoptions {xsim.modules} [][] \l_tmpa_tl
+\cs_generate_variant:Nn \str_if_eq:nnF {xx}
+
+\tl_const:Nn \c__xsim_module_extension_tl {code.tex}
+\tl_const:Nn \c__xsim_module_prefix_tl {xsim}
+
+\cs_new_protected:Npn \xsim_load_module:n #1
+ {
+ \tl_set:Nx \l_tmpa_tl { \tl_trim_spaces:n {#1} }
+ \str_if_eq:VnTF \l_tmpa_tl {modules}
+ { \msg_error:nn {xsim} {forbidden-module} }
+ { \__xsim_load_module:V \l_tmpa_tl }
+ }
+
+\cs_new_protected:Npn \__xsim_load_module:n #1
+ {
+ \xsim_if_module_loaded:nF {#1}
+ {
+ \xsim_if_module_exist:nTF {#1}
+ {
+ \__xsim_module_hook_use:nn {#1} {before}
+ \msg_info:nnn {xsim} {loading-module} {#1}
+ \@onefilewithoptions
+ {\c__xsim_module_prefix_tl.#1}[][]
+ \c__xsim_module_extension_tl
+ \__xsim_module_hook_use:nn {#1} {after}
+ }
+ { \msg_error:nnn {xsim} {module-missing} {#1} }
+ }
+ }
+\cs_generate_variant:Nn \__xsim_load_module:n {V}
+
+\tl_new:N \g__xsim_modules_loaded_tl
+
+\prg_new_conditional:Npnn \xsim_if_module_loaded:n #1 {p,T,F,TF}
+ {
+ \tl_if_in:NnTF \g__xsim_modules_loaded_tl {#1}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+
+\prg_new_conditional:Npnn \xsim_if_module_exist:n #1 {p,T,F,TF}
+ {
+ \file_if_exist:nTF
+ {\c__xsim_module_prefix_tl.#1.\c__xsim_module_extension_tl}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
% --------------------------------------------------------------------------
-\xsim_load_modules:n {definitions}
+% module hooks:
+% #1: module
+% #2: code
+\cs_new_protected:Npn \xsim_module_after:nn #1#2
+ {
+ \xsim_if_module_loaded:nTF {#1}
+ {#2}
+ { \__xsim_add_to_module_hook:nnn {#1} {after} {#2} }
+ }
+
+% #1: module
+% #2: code
+\cs_new_protected:Npn \xsim_module_before:nn #1#2
+ {
+ % TODO: error in T case?
+ \xsim_if_module_loaded:nF {#1}
+ { \__xsim_add_to_module_hook:nnn {#1} {before} {#2} }
+ }
+
+% #1: module
+% #2: hook name
+% #3: code
+\cs_new_protected:Npn \__xsim_add_to_module_hook:nnn #1#2#3
+ {
+ \xsim_if_module_loaded:nF {#1}
+ {
+ \tl_if_exist:cF {g__xsim_module_hook_#1_#2_tl}
+ { \tl_new:c {g__xsim_module_hook_#1_#2_tl} }
+ \tl_gput_right:cn {g__xsim_module_hook_#1_#2_tl} {#3}
+ }
+ }
-\AtEndDocument
+% #1: module
+% #2: hook name
+\cs_new_protected:Npn \__xsim_module_hook_use:nn #1#2
{
- \xsim_do_rerun:
- \xsim_close_aux:
+ \tl_if_exist:cT {g__xsim_module_hook_#1_#2_tl}
+ {
+ \tl_use:c {g__xsim_module_hook_#1_#2_tl}
+ \tl_gclear:c {g__xsim_module_hook_#1_#2_tl}
+ }
}
+\cs_generate_variant:Nn \__xsim_module_hook_use:nn {V}
% --------------------------------------------------------------------------
-\file_input_stop:
+
+\tl_new:N \l__xsim_module_date_tl
+\tl_new:N \l__xsim_module_version_tl
+
+\tl_if_exist:NF \c_xsim_date_tl
+ { \tl_set:Nx \l__xsim_module_date_tl {\c_xsimverb_date_tl} }
+\tl_if_exist:NF \c_xsim_version_tl
+ { \tl_set:Nx \l__xsim_module_version_tl {\c_xsimverb_version_tl} }
+
+\hook_gput_code:nnn {package/after/xsim} {xsim}
+ {
+ \tl_set:NV \l__xsim_module_date_tl \c_xsim_date_tl
+ \tl_set:NV \l__xsim_module_version_tl \c_xsim_version_tl
+ }
+
+\cs_new_protected:Npn \__xsim_module:nn #1#2
+ {
+ \str_if_eq:xxF
+ {\c__xsim_module_prefix_tl.#1.\c__xsim_module_extension_tl}
+ {\@currname.\@currext}
+ {
+ \msg_error:nnnxx {xsim} {wrong-module-name}
+ {#1}
+ {\@currname.\@currext}
+ }
+ \ProvidesFile
+ {\c__xsim_module_prefix_tl.#1.\c__xsim_module_extension_tl}
+ [
+ \l__xsim_module_date_tl
+ \c_space_tl
+ v \l__xsim_module_version_tl
+ \c_space_tl
+ xsim~ module~ `#1'~ (#2)
+ ]
+ }
+\cs_generate_variant:Nn \msg_error:nnnn {nnnx}
+
+% --------------------------------------------------------------------------
+% define a xsim module:
+% #1: if star: expl3 mode
+% #2: name
+% #3: description
+\NewDocumentCommand \xsimstyle {smO{}}
+ {
+ \__xsim_module:nn {style.#2} {#3}
+ \IfBooleanT {#1} { \ExplSyntaxOn }
+ }
+
+% \cs_new_protected:Npn \xsim_style_options:nn #1#2
+% { \keys_define:nn {xsim/#1} {#2} }
+
+\cs_new_protected:Npn \xsim_load_style:n #1
+ { \clist_map_inline:nn {#1} { \xsim_load_module:n {style.##1} } }
+
+\keys_define:nn {xsim}
+ { load-style .code:n = \xsim_load_style:n {#1} }
+
+\NewDocumentCommand \loadxsimstyle {m}
+ { \xsim_load_style:n {#1} }
+
+% --------------------------------------------------------------------------
+% define internal xsim modules:
+\tl_new:N \g_xsim_module_tl
+\tl_new:N \g__xsim_module_stop_tl
+
+\cs_new_protected:Npn \xsim_stop_module:n #1
+ { \tl_gput_right:Nn \g__xsim_module_stop_tl {{#1}} }
+
+% #1: name
+% #2: description
+\cs_set_protected:Npn \XSIMmodule #1#2
+ {
+ \msg_log:nnnn {xsim} {loading-module} {#1} {#2}
+ \tl_gput_right:Nn \g__xsim_modules_loaded_tl {{#1}}
+ \tl_gset:Nn \g_xsim_module_tl {#1}
+ \__xsim_module_hook_use:nn {#1} {before}
+ \tl_map_inline:Nn \g__xsim_module_stop_tl
+ {
+ \str_if_eq:nnT {##1} {#1}
+ { \tl_map_break:n { \__xsim_gobble_module:w } }
+ }
+ }
+
+\cs_set_protected:Npn \XSIMmoduleend
+ { \__xsim_module_hook_use:Vn \g_xsim_module_tl {after} }
+
+\cs_new_protected:Npn \__xsim_gobble_module:w #1 \XSIMmoduleend {}
+
+% --------------------------------------------------------------------------
+\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
+
+% \hook_gput_code:nnn {begindocument} {xsim}
+% { \tl_use:N \g_xsim_begin_document_hook_tl }
+% \hook_gput_code:nnn {enddocument} {xsim}
+% { \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} }
+
+\cs_new_protected:Npn \xsim_at_begin_document:n #1
+ { \hook_gput_code:nnn {begindocument} {xsim} {#1} }
+
+\cs_new_protected:Npn \xsim_before_begin_document:n #1
+ { \hook_gput_code:nnn {begindocument/before} {xsim} {#1} }
+
+\cs_new_protected:Npn \xsim_at_end_document:n #1
+ { \hook_gput_code:nnn {enddocument} {xsim} {#1} }
+
+\cs_new_protected:Npn \xsim_before_end_document:n #1
+ { \hook_gput_code:nnn {enddocument/before} {xsim} {#1} }
+
+% ----------------------------------------------------------------------------
+
+% 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 \seq_set_from_clist:Nn {c,Nx}
+\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 \msg_warning:nnn {nnV}
+\cs_generate_variant:Nn \keys_define:nn {nx}
+\cs_generate_variant:Nn \keys_set:nn {xn,nx}
+\cs_generate_variant:Nn \text_titlecase:n {e}
+\cs_generate_variant:Nn \tl_if_eq:nnTF {ee,ff,V}
+\cs_generate_variant:Nn \tl_if_eq:nnT {x}
+\cs_generate_variant:Nn \tl_if_blank:nTF {f,e}
+\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}
+\cs_generate_variant:Nn \clist_map_inline:nn {V}
+
+% ----------------------------------------------------------------------------
+% 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
+
+\fp_new:N \l__xsim_tmpa_fp
+\fp_new:N \l__xsim_tmpb_fp
+\fp_new:N \l__xsim_tmpc_fp
+
+\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: }
+ }
+
+% ----------------------------------------------------------------------------
+
+\cs_if_exist:NF \xsim_if_final:T
+ {
+ \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_if_exist:NF \xsim_verbose:n
+ {
+ \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: }
+ }
+
+% ----------------------------------------------------------------------------
+
+\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} }
+
+\XSIMmoduleend
+\XSIMmodule{auxfile}{writing stuff to an auxiliary file}
+
+\prg_new_conditional:Npnn \xsim_if_use_aux: {p,T,F,TF}
+ {
+ \bool_if:NTF \g_xsim_use_aux_bool
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+
+\cs_new_protected:Npn \xsim_write_to_aux:n #1
+ {
+ \legacy_if:nT {@filesw}
+ {
+ \xsim_if_use_aux:TF
+ { \iow_now:Nn \@auxout {#1} }
+ { \iow_now:Nn \l__xsim_aux_file_iow {#1} }
+ }
+ }
+\cs_generate_variant:Nn \xsim_write_to_aux:n {x}
+
+% --------------------------------------------------------------------------
+
+\cs_new_protected:Npn \XSIM #1 { \use:c {XSIMaux#1} }
+
+\cs_new_protected:Npn \xsim_new_aux_property:cpn #1
+ { \cs_new_protected:cpn {XSIMaux#1} }
+
+\cs_new_protected:Npn \xsim_add_property_to_aux:nn #1#2
+ {
+ \xsim_verbose:n { Writing~ command~ \XSIM {#1}~ to~ aux~ file }
+ \xsim_write_to_aux:x { \token_to_str:N \XSIM {#1} #2 }
+ }
+
+\xsim_at_begin_document:n
+ {
+ \iow_now:Nx \@auxout
+ { \token_to_str:N \providecommand \token_to_str:N \XSIM [1] {} }
+ }
+
+% ----------------------------------------------------------------------------
+
+\xsim_if_use_aux:F
+ {
+ \iow_new:N \l__xsim_aux_file_iow
+ \hook_gput_code:nnn {begindocument} {xsim}
+ { \iow_open:Nn \l__xsim_aux_file_iow { \c_sys_jobname_str .xsim } }
+ }
+
+\cs_new_protected:Npn \xsim_close_aux:
+ {
+ \xsim_if_use_aux:F
+ {
+ \iow_close:N \l__xsim_aux_file_iow
+ \legacy_if:nT {@filesw}
+ { \iow_now:Nx \@auxout { \token_to_str:N \XSIM {readaux} } }
+ }
+ }
+
+\xsim_new_aux_property:cpn {readaux}
+ {
+ \file_if_exist:nT { \c_sys_jobname_str .xsim }
+ { \file_input:n { \c_sys_jobname_str .xsim } }
+ }
+
+% ----------------------------------------------------------------------------
+% list for recording values that need to be written to the aux file and
+% updated at begin document
+
+\str_new:N \l__xsim_split_aux_lists_str
+\keys_define:nn {xsim}
+ {
+ split-aux-lists .code:n = \str_set:Nn \l__xsim_split_aux_lists_str {#1} ,
+ split-aux-lists .initial:n = ||
+ }
+
+% define list:
+% #1: name
+\cs_new_protected:Npn \xsim_new_list:n #1
+ {
+ \xsim_verbose:n { Defining~ new~ auxfile~ list~ `#1'. }
+ \seq_new:c {g__xsim_list_#1_seq}
+ \seq_new:c {g__xsim_list_recorded_#1_seq}
+ \xsim_new_aux_property:cpn {#1} ##1
+ {
+ \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}
+ { \xsim_attribute_set:nnn {#1} {####1} {} }
+ }
+ }
+ \xsim_at_begin_document:n { \xsim_set_list:n {#1} }
+ }
+
+% #1: name
+\cs_new_protected:Npn \xsim_set_list:n #1
+ {
+ \seq_gclear:c {g__xsim_list_recorded_#1_seq}
+ \seq_set_eq:Nc \l__xsim_tmpa_seq {g__xsim_list_#1_seq}
+ \seq_map_inline:Nn \l__xsim_tmpa_seq
+ {
+ \str_set:Nn \l__xsim_tmpa_str {##1}
+ \seq_gput_right:cV {g__xsim_list_recorded_#1_seq} \l__xsim_tmpa_str
+ }
+ \seq_gremove_duplicates:c {g__xsim_list_recorded_#1_seq}
+ }
+
+% add to or remove from list:
+% #1: name
+% #2: entry
+\cs_new_protected:Npn \xsim_add_to_list:nn #1#2
+ {
+ \xsim_verbose:n { Adding~ `#2'~ to~ list~ `#1'. }
+ \str_set:Nn \l__xsim_tmpa_str {#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
+ }
+\cs_generate_variant:Nn \xsim_add_to_list:nn {nx}
+
+% #1: name
+% #2: entry
+\cs_new_protected:Npn \xsim_remove_from_list:nn #1#2
+ {
+ \xsim_verbose:n { Removing~ `#2'~ to~ list~ `#1'. }
+ \str_set:Nn \l__xsim_tmpa_str {#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
+ { \seq_gremove_all:cV {g__xsim_list_recorded_#1_seq} \l__xsim_tmpa_str }
+ }
+\cs_generate_variant:Nn \xsim_remove_from_list:nn {nx}
+
+% check if in list:
+% #1: name
+% #2: entry
+\prg_new_conditional:Npnn \xsim_if_in_list:nn #1#2 {p,T,F,TF}
+ {
+ \xsim_attribute_if_set:nnTF {#1} {#2}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+\prg_generate_conditional_variant:Nnn \xsim_if_in_list:nn {nx} {T,TF}
+
+\bool_new:N \l__xsim_empty_lists_bool
+\cs_new_protected:Npn \xsim_empty_lists:
+ { \bool_set_true:N \l__xsim_empty_lists_bool }
+
+% update list (should be used inside \xsim_at_end_document:n):
+% #1: name
+\cs_new_protected:Npn \xsim_update_list:n #1
+ {
+ \xsim_verbose:n { Updating~ list~ `#1'. }
+ \seq_gremove_duplicates:c {g__xsim_list_#1_seq}
+ \seq_gremove_duplicates:c {g__xsim_list_recorded_#1_seq}
+ \str_set:Nx \l__xsim_tmpa_str
+ { \seq_use:cn {g__xsim_list_#1_seq} {} }
+ \str_set:Nx \l__xsim_tmpb_str
+ { \seq_use:cn {g__xsim_list_recorded_#1_seq} {} }
+ \str_if_eq:NNF \l__xsim_tmpa_str \l__xsim_tmpb_str
+ { \xsim_rerun: }
+ \bool_if:NF \l__xsim_empty_lists_bool
+ {
+ \xsim_add_property_to_aux:nn {#1}
+ { { \seq_use:cV {g__xsim_list_#1_seq} \l__xsim_split_aux_lists_str } }
+ }
+ }
+
+% loop over list:
+% #1: name
+% #2: code
+\cs_new_protected:Npn \xsim_foreach_list_entry:nn #1#2
+ { \seq_map_inline:cn {g__xsim_list_recorded_#1_seq} {#2} }
+
+\cs_new_protected:Npn \xsim_foreach_new_list_entry:nn #1#2
+ { \seq_map_inline:cn {g__xsim_list_#1_seq} {#2} }
+
+% length of a list:
+% #1: name
+\cs_new:Npn \xsim_list_count:n #1
+ { \seq_count:c {g__xsim_list_recorded_#1_seq} }
+
+% item of a list:
+% #1: name
+% #2: integer
+\cs_new:Npn \xsim_list_item:nn #1#2
+ { \seq_item:cn {g__xsim_list_recorded_#1_seq} {#2} }
+
+\XSIMmoduleend
+\XSIMmodule{properties}{properties of exercises}
+
+\msg_new:nnn {xsim} {unknown-property}
+ {
+ You~ tried~ to~ set~ the~ property~ `#1'~ \msg_line_context: . \\
+ This~ property~ does~ not~ exist.~ Check~ for~ a~ typo~ or~ \\
+ define~ the~ property~ yourself.
+ }
+
+\msg_new:nnn {xsim} {property-unique}
+ {
+ You~ tried~ to~ set~ the~ property~ `#1'~ \msg_line_context: . \\
+ This~ property~ has~ to~ have~ a~ unique~ value~ and~ thus~ \\
+ cannot~ be~ set~ to~ `#2'~ since~ this~ value~ is~ already~ taken.
+ }
+
+\msg_new:nnn {xsim} {no-boolean-property}
+ {
+ You~ tried~ to~ check~ the~ boolean~ value~ of~ property~ `#1'~
+ \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
+
+% #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
+ {ne,nne,ee,nV}
+ {p,T,F,TF}
+
+% new property:
+% #1: boolean if unique
+% #2: boolean if boolean
+% #3: boolean if noupdate
+% #4: property name
+\cs_new_protected:Npn \xsim_declare_property:nnnn #1#2#3#4
+ {
+ \xsim_if_property_exist:nF {#4}
+ {
+ \seq_put_right:Nn \l__xsim_properties_seq {#4}
+ \bool_if:nTF {#3}
+ {
+ \seq_if_in:NnF \l__xsim_noupdate_properties_seq {#4}
+ { \seq_put_right:Nn \l__xsim_noupdate_properties_seq {#4} }
+ }
+ { \xsim_new_list:n {#4} }
+ \bool_if:nTF {#2}
+ {
+ \xsim_verbose:n
+ { Declaring~ new~ boolean~ exercise~ property~ `#4'. }
+ \seq_if_in:NnF \l__xsim_boolean_properties_seq {#4}
+ { \seq_put_right:Nn \l__xsim_boolean_properties_seq {#4} }
+ }
+ {
+ \bool_if:nTF {#1}
+ {
+ \xsim_verbose:n
+ { Declaring~ new~ unique~ exercise~ property~ `#4'. }
+ \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}
+ }
+ { \xsim_verbose:n { Declaring~ new~ exercise~ property~ `#4'. } }
+ }
+ \bool_if:nF {#3}
+ {
+ \xsim_at_end_document:n { \xsim_update_list:n {#4} }
+ \xsim_at_begin_document:n { \__xsim_set_property_from_list:n {#4} }
+ }
+ }
+ }
+
+% ----------------------------------------------------------------------------
+% check if property exists:
+\prg_new_conditional:Npnn \xsim_if_property_exist:n #1 {p,T,F,TF}
+ {
+ \seq_if_in:NnTF \l__xsim_properties_seq {#1}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+\cs_generate_variant:Nn \xsim_if_property_exist:nTF {x}
+
+\prg_new_conditional:Npnn \xsim_if_property_noupdate:n #1 {p,T,F,TF}
+ {
+ \seq_if_in:NnTF \l__xsim_noupdate_properties_seq {#1}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+\cs_generate_variant:Nn \xsim_if_property_noupdate:nF {V}
+
+\prg_new_conditional:Npnn \xsim_if_property_boolean:n #1 {p,T,F,TF}
+ {
+ \seq_if_in:NnTF \l__xsim_boolean_properties_seq {#1}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+
+\prg_new_conditional:Npnn \xsim_if_property_unique:n #1 {p,T,F,TF}
+ {
+ \seq_if_in:NnTF \l__xsim_unique_properties_seq {#1}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+
+% true if property #1 has been set in the /last/ call of
+% \xsim_set_properties:nnn
+\prg_new_conditional:Npnn \xsim_if_property_given:n #1 {p,T,F,TF}
+ {
+ \seq_if_in:NnTF \l__xsim_given_properties_seq {#1}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+
+% #1: property
+% #2: value
+\prg_new_conditional:Npnn \xsim_if_property_unique_value:nn #1#2 {p,T,F,TF}
+ {
+ \xsim_if_property_unique:nTF {#1}
+ {
+ \seq_if_in:cnTF {l__xsim_unique_property_#1_values_seq} {#2}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+ { \prg_return_false: }
+ }
+
+% #1: code
+\cs_new_protected:Npn \xsim_foreach_property:n #1
+ { \seq_map_inline:Nn \l__xsim_properties_seq {#1} }
+
+% ----------------------------------------------------------------------------
+% #1: type
+% #2: id
+% #3: property
+% #4: value
+\cs_new_protected:Npn \xsim_set_property:nnnn #1#2#3#4
+ {
+ \xsim_if_property_unique:nTF {#3}
+ {
+ \xsim_if_property_unique_value:nnTF {#3} {#4}
+ { \msg_warning:nnnn {xsim} {property-unique} {#3} {#4} }
+ { \__xsim_set_unique_property:nnnn {#1} {#2} {#3} {#4} }
+ }
+ {
+ \xsim_if_property_boolean:nTF {#3}
+ { \__xsim_set_boolean_property:nnnn {#1} {#2} {#3} {#4} }
+ { \__xsim_set_property:nnnn {#1} {#2} {#3} {#4} }
+ }
+ }
+\cs_generate_variant:Nn \xsim_set_property:nnnn {nnee,nnnV,nV,nVne,nnne,ee,eene,nene}
+
+% #1: type
+% #2: id
+% #3: property
+% #4: value
+\cs_new_protected:Npn \__xsim_set_boolean_property:nnnn #1#2#3#4
+ {
+ \str_case_e:nnTF { \str_lowercase:n {#4} }
+ {
+ {} {}
+ {true} {}
+ }
+ { \__xsim_set_property:nnnn {#1} {#2} {#3} {true} }
+ { \__xsim_set_property:nnnn {#1} {#2} {#3} {false} }
+ }
+
+% #1: type
+% #2: id
+% #3: property
+% #4: value
+\cs_new_protected:Npn \__xsim_set_unique_property:nnnn #1#2#3#4
+ {
+ \__xsim_set_property:nnnn {#1} {#2} {#3} {#4}
+ \__xsim_set_property_reverse:nnnn {#1} {#2} {#3} {#4}
+ }
+
+% #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_if_property_noupdate:nF {#3}
+ { \__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}
+ { \__xsim_unset_property:nnn {#1} {#2} {#3} }
+ { \msg_error:nnn {xsim} {unknown-property} {#3} }
+ }
+\cs_generate_variant:Nn \xsim_unset_property:nnn {nx,nnx,nV}
+
+% #1: type
+% #2: id
+% #3: property
+% #4: value
+\cs_new_protected:Npn \__xsim_set_property:nnnn #1#2#3#4
+ {
+ \xsim_verbose:n
+ {
+ Setting~ property~ `#3'~ of~ exercise~ type~ `#1'~ id~ `#2'~ to~
+ value~ `#4'.
+ }
+ \xsim_if_property_noupdate:nF {#3}
+ {
+ \__xsim_remove_property_from_list:nnn {#1} {#2} {#3}
+ \xsim_add_to_list:nn {#3} {#1-#2=={#4}}
+ }
+ \xsim_attribute_set:nnn {#1!#2} {#3} {#4}
+ }
+\cs_generate_variant:Nn \__xsim_set_property:nnnn {VVnV}
+
+% #1: type
+% #2: id
+% #3: property
+% #4: value
+\cs_new_protected:Npn \__xsim_set_property_reverse:nnnn #1#2#3#4
+ {
+ \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 \{ }
+\tl_set:Nx \l__xsim_tmpb_tl { \cs_to_str:N \} }
+\use:x
+ {
+ \cs_new_protected:Npn
+ \exp_not:N \__xsim_extract_property_list_entry:NNNwww
+ ##1##2##3##4-##5== \l__xsim_tmpa_tl ##6 \l__xsim_tmpb_tl
+ \exp_not:N \q_stop
+ }
+ {
+ \str_set:Nn #1 {#4}
+ \str_set:Nn #2 {#5}
+ \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:
+ \xsim_foreach_list_entry:nn {#3}
+ {
+ \__xsim_extract_property_list_entry:NNNwww
+ \l__xsim_tmpa_str \l__xsim_tmpb_str \l__xsim_tmpc_str ##1 \q_stop
+ \str_if_eq:xnT { \l__xsim_tmpa_str - \l__xsim_tmpb_str } {#1-#2}
+ {
+ \xsim_remove_from_list:nx {#3}
+ { #1-#2 == {\l__xsim_tmpc_str} }
+ }
+ }
+ % make sure we change the entry if it has been set during the current run:
+ \xsim_foreach_new_list_entry:nn {#3}
+ {
+ \__xsim_extract_property_list_entry:NNNwww
+ \l__xsim_tmpa_str \l__xsim_tmpb_str \l__xsim_tmpc_str ##1 \q_stop
+ \str_if_eq:xnT { \l__xsim_tmpa_str - \l__xsim_tmpb_str } {#1-#2}
+ {
+ \xsim_remove_from_list:nx {#3}
+ { #1-#2 == {\l__xsim_tmpc_str} }
+ }
+ }
+ }
+
+\seq_new:N \g_xsim_used_order_seq
+\seq_new:N \g_xsim_printed_order_seq
+
+\cs_new_protected:Npn \__xsim_set_property_from_list:n #1
+ {
+ \xsim_foreach_list_entry:nn {#1}
+ {
+ \__xsim_extract_property_list_entry:NNNwww
+ \l__xsim_tmpa_str \l__xsim_tmpb_str \l__xsim_tmpc_str ##1 \q_stop
+ \tl_set_rescan:Nnx \l__xsim_tmpa_tl {} { \l__xsim_tmpa_str }
+ \tl_set_rescan:Nnx \l__xsim_tmpb_tl {} { \l__xsim_tmpb_str }
+ \tl_set_rescan:Nnx \l__xsim_tmpc_tl {} { \l__xsim_tmpc_str }
+ \str_if_eq:nnT {#1} {used}
+ {
+ \str_if_eq:VnT \l__xsim_tmpc_str {true}
+ {
+ \seq_gput_right:Nx \g_xsim_used_order_seq
+ { \l__xsim_tmpa_tl - \l__xsim_tmpb_tl }
+ }
+ }
+ \str_if_eq:nnT {#1} {printed}
+ {
+ \str_if_eq:VnT \l__xsim_tmpc_str {true}
+ {
+ \seq_gput_right:Nx \g_xsim_printed_order_seq
+ { \l__xsim_tmpa_tl - \l__xsim_tmpb_tl }
+ }
+ }
+ \__xsim_set_property:VVnV
+ \l__xsim_tmpa_str
+ \l__xsim_tmpb_str
+ {#1}
+ \l__xsim_tmpc_tl
+ }
+ }
+
+% set properties:
+% #1: type
+% #2: id
+% #3: csv list of properties
+\cs_new_protected:Npn \xsim_set_properties:nnn #1#2#3
+ {
+ \cs_set_protected:Npn \__xsim_tmp:n ##1
+ { \xsim_set_property:nnnn {#1} {#2} {##1} {} }
+ \cs_set_protected:Npn \__xsim_tmp:nn ##1##2
+ { \xsim_set_property:nnnn {#1} {#2} {##1} {##2} }
+ \keyval_parse:NNn
+ \__xsim_tmp:n
+ \__xsim_tmp:nn
+ {#3}
+ \xsim_property_set_aliases:nn {#1} {#2}
+ }
+\cs_generate_variant:Nn \xsim_set_properties:nnn {nne,nee,nV,nVe}
+
+% ----------------------------------------------------------------------------
+
+\seq_new:N \g__xsim_property_aliases_seq
+
+% #1: property
+\prg_new_conditional:Npnn \xsim_if_property_alias:n #1 {p,T,F,TF}
+ {
+ \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
+ { \xsim_attribute_get:nn {#1} {alias} }
+
+% #1: property
+% #2: alias of
+\cs_new_protected:Npn \xsim_make_property_alias:nn #1#2
+ {
+ \xsim_if_property_alias:nF {#1}
+ {
+ \xsim_verbose:n
+ { Making~ property~ `#1'~ an~ alias~ of~ property~ `#2'. }
+ \xsim_attribute_set:nnn {#1} {alias} {#2}
+ \seq_gput_right:Nn \g__xsim_property_aliases_seq {#1}
+ }
+ }
+
+% #1: type
+% #2: id
+% #3: property
+\cs_new_protected:Npn \xsim_property_set_alias:nnn #1#2#3
+ {
+ \xsim_if_property_set:nneT {#1} {#2}
+ { \xsim_property_alias:n {#3} }
+ {
+ \xsim_attribute_set:nnx {alias:#1!#2} {#3}
+ {
+ \xsim_get_property:nnf {#1} {#2}
+ { \xsim_property_alias:n {#3} }
+ }
+ \xsim_if_property_set:nnnF {#1} {#2} {#3}
+ {
+ \xsim_set_property:nnne {#1} {#2} {#3}
+ {
+ \xsim_get_property:nnf {#1} {#2}
+ { \xsim_property_alias:n {#3} }
+ }
+ }
+ }
+ }
+\cs_generate_variant:Nn \xsim_property_set_alias:nnn {nV}
+
+% #1: type
+% #2: id
+\cs_new_protected:Npn \xsim_property_set_aliases:nn #1#2
+ {
+ \seq_map_inline:Nn \g__xsim_property_aliases_seq
+ { \xsim_property_set_alias:nnn {#1} {#2} {##1} }
+ }
+
+% ----------------------------------------------------------------------------
+% retrieve properties:
+% #1: type
+% #2: id
+% #3: property
+\cs_new:Npn \xsim_get_property:nnn #1#2#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
+ { \xsim_attribute_get:nn {id:#1} {#2} }
+
+% #1: ID
+% #2: variable
+\cs_new_protected:Npn \xsim_get_type_for_id:nN #1#2
+ {
+ \xsim_foreach_list_entry:nn {idtypes}
+ {
+ \__xsim_extract_property_list_entry:NNNwww
+ \l__xsim_tmpa_str \l__xsim_tmpb_str \l__xsim_tmpc_str -##1 \q_stop
+ \str_if_eq:VnT \l__xsim_tmpb_str {#1}
+ {
+ \str_set_eq:NN #2 \l__xsim_tmpc_str
+ \seq_map_break:
+ }
+ }
+ }
+
+% #1: property
+% #2: value
+\cs_new:Npn \xsim_get_type_for_property:nn #1#2
+ { \xsim_attribute_get:nn {type:#1} {#2} }
+\cs_generate_variant:Nn \xsim_get_type_for_property:nn {nV}
+
+% #1: id or ID
+\cs_new:Npn \xsim_normalize_id:n #1
+ {
+ \tl_if_blank:eTF
+ { \xsim_get_id_for_property:nn {ID} {#1} }
+ {#1}
+ { \xsim_get_id_for_property:nn {ID} {#1} }
+ }
+\cs_generate_variant:Nn \xsim_normalize_id:n {e}
+
+\tl_new:N \l_xsim_property_value_tl
+\tl_new:N \PropertyValue
+
+\cs_new:Npn \__xsim_tmp:n #1 {#1}
+\cs_generate_variant:Nn \__xsim_tmp:n {V}
+
+% #1: type
+% #2: id
+% #3: property
+\cs_new_protected:Npn \xsim_get_property_if_set:nnnTF #1#2#3#4#5
+ {
+ \xsim_if_property_exist:nTF {#3}
+ {
+ \xsim_if_property_set:nnnTF {#1} {#2} {#3}
+ {
+ \tl_set:Nx \l_xsim_property_value_tl
+ { \xsim_get_property:nnn {#1} {#2} {#3} }
+ \tl_set_eq:NN \PropertyValue \l_xsim_property_value_tl
+ \cs_set:Npn \__xsim_tmp:n ##1 {#4}
+ \__xsim_tmp:V \l_xsim_property_value_tl
+ }
+ {#5}
+ }
+ { \msg_error:nnn {xsim} {unknown-property} {#3} }
+ }
+\cs_generate_variant:Nn \xsim_get_property_if_set:nnnTF {oo}
+
+\cs_new_protected:Npn \xsim_get_property_if_set:nnnT #1#2#3#4
+ { \xsim_get_property_if_set:nnnTF {#1} {#2} {#3} {#4} {} }
+
+\cs_new_protected:Npn \xsim_get_property_if_set:nnnF #1#2#3#4
+ { \xsim_get_property_if_set:nnnTF {#1} {#2} {#3} {} {#4} }
+
+% #1: type
+% #2: id
+% #3: property
+\prg_new_conditional:Npnn \xsim_if_boolean_property:nnn #1#2#3 {T,F,TF}
+ {
+ \xsim_if_property_exist:nTF {#3}
+ {
+ \xsim_if_property_boolean:nTF {#3}
+ {
+ \xsim_if_property_set:nnnTF {#1} {#2} {#3}
+ {
+ \bool_if:cTF
+ {c_ \xsim_get_property:nnn {#1} {#2} {#3} _bool}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+ { \prg_return_false: }
+ }
+ { \msg_error:nnn {xsim} {no-boolean-property} {#3} }
+ }
+ { \msg_error:nnn {xsim} {unknown-property} {#3} }
+ }
+\prg_generate_conditional_variant:Nnn \xsim_if_boolean_property:nnn {oo,nV} {T,F,TF}
+
+\cs_new_protected:Npn \xsim_save_property:nnnN #1#2#3#4
+ { \tl_set:Nx #4 { \xsim_get_property:nnn {#1} {#2} {#3} } }
+\cs_generate_variant:Nn \xsim_save_property:nnnN {nx,xx}
+
+\cs_new_protected:Npn \xsim_gsave_property:nnnN #1#2#3#4
+ {
+ \xsim_save_property:nnnN {#1} {#2} {#3} #4
+ \tl_gset:NV #4 #4
+ }
+\cs_generate_variant:Nn \xsim_gsave_property:nnnN {nx,xx,nV}
+
+\XSIMmoduleend
+\XSIMmodule{environments}{generic code for exercise and solution environments}
+
+\xsim_if_write_to_files:F
+ {
+ \xsim_declare_property:nnnn
+ { \c_false_bool }
+ { \c_false_bool }
+ { \c_false_bool }
+ {solution-body}
+ \xsim_declare_property:nnnn
+ { \c_false_bool }
+ { \c_false_bool }
+ { \c_false_bool }
+ {exercise-body}
+ }
+
+\tl_new:N \l__xsim_file_name_signature_tl
+\tl_new:N \l__xsim_file_path_tl
+\tl_new:N \l__xsim_file_path_and_name_tl
+\tl_new:N \l__xsim_file_name_tl
+\tl_new:N \l__xsim_file_extension_tl
+\tl_new:N \l__xsim_solution_tl
+\bool_new:N \l__xsim_options_given_bool
+\bool_new:N \l__xsim_insert_mode_bool
+
+\tl_new:N \ExerciseText
+\tl_set:Nn \ExerciseText { \msg_error:nn {xsim} {only-in-solution} }
+
+% ----------------------------------------------------------------------------
+
+\msg_new:nnn {xsim} {only-in-solution}
+ {
+ You~ can't~ use~ \token_to_str:N \ExerciseText \c_space_tl inside~ an~
+ exercise.~ It~ is~ only~ allowed~ inside~ solution~ environments!
+ }
+
+% ----------------------------------------------------------------------------
+
+\keys_define:nn {xsim}
+ {
+ path .tl_set:N = \l__xsim_file_path_tl ,
+ file-extension .tl_set:N = \l__xsim_file_extension_tl ,
+ file-extension .initial:n = tex
+ }
+
+% ----------------------------------------------------------------------------
+
+\tl_const:Nn \c__xsim_comment_line_tl { \c__xsim_percent_char_tl }
+\tl_const:Nn \c__xsim_comment_line_fill_tl { \prg_replicate:nn {72} {-} }
+\tl_const:Nn \c__xsim_comment_line_indent_tl { \c_space_tl \c_space_tl }
+
+\cs_new:Npn \__xsim_comment_line_and_feed:n #1
+ { \__xsim_comment_line:n {#1} ^^J }
+
+\cs_new:Npn \__xsim_comment_line:n #1
+ {
+ \c__xsim_comment_line_tl
+ \tl_if_blank:nF {#1} { \c_space_tl }
+ #1
+ }
+
+\cs_new:Npn \__xsim_two_digits:n #1
+ { \int_compare:nT { #1 < 10 } {0} \int_eval:n {#1} }
+
+% #1: type
+% #2: id
+% #3: exercise|solution
+\cs_new_protected:Npn \__xsim_set_file_signature:nnn #1#2#3
+ { \tl_set:Nn \l__xsim_file_name_signature_tl {#1-#2-#3} }
+\cs_generate_variant:Nn \__xsim_set_file_signature:nnn {nx,nV}
+
+\tl_set:Nn \l__xsim_file_name_tl
+ { \c_sys_jobname_str - \l__xsim_file_name_signature_tl -body . \l__xsim_file_extension_tl }
+
+\tl_set:Nn \l__xsim_file_path_and_name_tl
+ {
+ \tl_if_blank:VF \l__xsim_file_path_tl
+ { \l__xsim_file_path_tl / }
+ \l__xsim_file_name_tl
+ }
+
+% #1: type
+% #2: id
+% #3: exercise|solution
+% #4: file name
+% #5: path
+\cs_new_protected:Npn \__xsim_file_info:nnnnn #1#2#3#4#5
+ {
+ \tl_set:Nx \l_xsim_file_begin_tl
+ {
+ \__xsim_comment_line_and_feed:n { \c__xsim_comment_line_fill_tl }
+ \__xsim_comment_line_and_feed:n {file~ `#4'}
+ \tl_if_blank:nF {#5}
+ {
+ \__xsim_comment_line_and_feed:n
+ { \c__xsim_comment_line_indent_tl in~ folder~ `#5/'}
+ }
+ \__xsim_comment_line_and_feed:n {}
+ \__xsim_comment_line_and_feed:n
+ {
+ \c__xsim_comment_line_indent_tl
+ \c__xsim_comment_line_indent_tl
+ #3~ of~ type~ `#1'~ with~ id~ `#2'
+ }
+ \__xsim_comment_line_and_feed:n {}
+ \__xsim_comment_line_and_feed:n
+ {generated~ by~ the~ `\@currenvir'~ environment~ of~ the}
+ \__xsim_comment_line_and_feed:n
+ {
+ \c__xsim_comment_line_indent_tl
+ `xsim'~ package~ v \c_xsim_version_tl
+ \c_space_tl (\c_xsim_date_tl)
+ }
+ \__xsim_comment_line_and_feed:n
+ {
+ from~ source~ `\c_sys_jobname_str'~ on~
+ \int_use:N \c_sys_year_int /
+ \__xsim_two_digits:n { \c_sys_month_int } /
+ \__xsim_two_digits:n { \c_sys_day_int } ~
+ \msg_line_context:
+ }
+ \__xsim_comment_line:n { \c__xsim_comment_line_fill_tl }
+ }
+ }
+\cs_generate_variant:Nn \__xsim_file_info:nnnnn {nnnVV}
+
+% ----------------------------------------------------------------------------
+% #1: type
+% #2: id
+% #3: exercise|solution
+% #4: potential environment body
+\cs_new_protected:Npn \xsim_save_environment_body:nnnn #1#2#3#4
+ {
+ \xsim_if_write_to_files:TF
+ { \__xsim_write_environment_body:nnn {#1} {#2} {#3} }
+ { \__xsim_save_environment_body:nnnn {#1} {#2} {#3} {#4} }
+ }
+
+\cs_new_protected:Npn \xsim_save_environment_body_end:
+ {
+ \xsim_if_write_to_files:TF
+ { \__xsim_write_environment_body_end: }
+ { \__xsim_save_environment_body_end: }
+ }
+
+% writing to files:
+% #1: type
+% #2: id
+% #3: exercise|solution
+\cs_new_protected:Npn \__xsim_write_environment_body:nnn #1#2#3
+ {
+ \xsim_verbose:n
+ { Starting~ to~ write~ #3~ environment~ type~ `#1'~ id~ `#2' }
+ \__xsim_set_file_signature:nnn {#1} {#2} {#3}
+ \__xsim_file_info:nnnVV {#1} {#2} {#3}
+ \l__xsim_file_name_tl
+ \l__xsim_file_path_tl
+ \int_zero:N \l_xsim_line_gobble_int
+ \xsim_file_write_start:nV
+ { \l__xsim_options_given_bool }
+ \l__xsim_file_path_and_name_tl
+ }
+
+\cs_new_protected:Npn \__xsim_write_environment_body_end:
+ { \xsim_file_write_stop: }
+
+% saving to property lists:
+% #1: type
+% #2: id
+% #3: exercise|solution
+% #4: environment body
+\cs_new_protected:Npn \__xsim_save_environment_body:nnnn #1#2#3#4
+ {
+ \xsim_verbose:n { Saving~ #3~ environment~ type~ `#1'~ id~ `#2' }
+ \xsim_set_property:nnnn {#1} {#2} {#3-body} {#4}
+ \xsim_if_exchange:nnnF {#1} {#2} {#3}
+ { \xsim_set_property:nnnn {#1} {#2} {solution-body} {#3} }
+ }
+
+\cs_new:Npn \__xsim_save_environment_body_end: { }
+
+% ----------------------------------------------------------------------------
+% #1: type
+% #2: exercise|solution
+% #3: hook
+\cs_new_protected:Npn \xsim_new_hook:nnn #1#2#3
+ {
+ \xsim_verbose:n { Defining~ new~ #1~ (#2)~ hook~ `#3' }
+ \tl_new:c {l__xsim_#1_#2_#3_hook_tl}
+ \keys_define:nx {xsim}
+ {
+ \xsim_get_parameter:nn {#1} {#2-env}/#3-hook .tl_set:N =
+ \exp_not:c {l__xsim_#1_#2_#3_hook_tl}
+ }
+ }
+
+% #1: type
+% #2: exercise|solution
+% #3: hook
+\cs_new:Npn \xsim_use_hook:nnn #1#2#3
+ { \exp_not:v {l__xsim_#1_#2_#3_hook_tl} }
+
+% #1: type
+% #2: exercise|solution
+% #3: hook
+% #4: code
+\cs_new_protected:Npn \xsim_set_hook:nnnn #1#2#3#4
+ {
+ \xsim_verbose:n { Setting~ #1~ (#2)~ hook~ `#3' }
+ \tl_set:cn {l__xsim_#1_#2_#3_hook_tl} {#4}
+ }
+
+% #1: type
+% #2: exercise|solution
+% #3: hook
+% #4: code
+\cs_new_protected:Npn \xsim_addto_hook:nnnn #1#2#3#4
+ {
+ \xsim_verbose:n { Adding~ to~ #1~ (#2)~ hook~ `#3' }
+ \tl_put_right:cn {l__xsim_#1_#2_#3_hook_tl} {#4}
+ }
+
+% ----------------------------------------------------------------------------
+
+% #1: type
+% #2: id
+% #3: exercise|solution
+% #4: potential enironment body
+\cs_new_protected:Npn \xsim_start_environment:nnnn #1#2#3#4
+ { \xsim_save_environment_body:nnnn {#1} {#2} {#3} {#4} }
+\cs_generate_variant:Nn \xsim_start_environment:nnnn {nV}
+
+% #1: type
+% #2: id
+% #3: exercise|solution
+\cs_new_protected:Npn \xsim_stop_environment:nnn #1#2#3
+ {
+ \xsim_save_environment_body_end:
+ \xsim_if_print:nnnTF {#1} {#2} {#3}
+ { \xsim_typeset_environment:nnn {#1} {#2} {#3} }
+ { \xsim_use_hook:nnn {#1} {#3} {print-false} }
+ }
+\cs_generate_variant:Nn \xsim_stop_environment:nnn {nV}
+
+% #1: type
+% #2: id
+% #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_verbose:n
+ { Typesetting~ #3~ environment~ type~ `#1'~ id~ `#2' }
+ \xsim_use_hook:nnn {#1} {#3} {pre}
+ \xsim_use_template:nx
+ {begin}
+ { \xsim_get_parameter:nn {#1} {#3-template} }
+ \xsim_use_hook:nnn {#1} {#3} {begin}
+ \xsim_input:nnn {#1} {#2} {#3}
+ \xsim_use_hook:nnn {#1} {#3} {end}
+ \xsim_use_template:nx
+ {end}
+ { \xsim_get_parameter:nn {#1} {#3-template} }
+ \xsim_use_hook:nnn {#1} {#3} {post}
+ }
+
+% #1: type
+% #2: id
+% #3: exercise|solution
+\prg_new_conditional:Npnn \xsim_if_exchange:nnn #1#2#3 {T,F,TF}
+ {
+ \str_if_eq:nnTF {#3} {solution}
+ {
+ \xsim_if_boolean_property:nnnTF {#1} {#2} {solution}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+ { \prg_return_false: }
+ }
+
+% #1: type
+% #2: id
+% #3: exercise|solution
+\prg_new_protected_conditional:Npnn \xsim_if_exist:nnn #1#2#3 {T,F,TF}
+ {
+ \xsim_if_write_to_files:TF
+ {
+ \__xsim_set_file_signature:nnn {#1} {#2} {#3}
+ \file_if_exist:VTF \l__xsim_file_path_and_name_tl
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+ {
+ \xsim_if_property_exist:nTF {#3-body}
+ {
+ \xsim_if_property_set:nnnTF {#1} {#2} {#3-body}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+ { \prg_return_false: }
+ }
+ }
+
+% #1: type
+% #2: id
+% #3: options
+% #4: exercise|solution
+\cs_new_protected:Npn \xsim_insert:nnnn #1#2#3#4
+ {
+ \xsim_if_exist:nnnT {#1} {#2} {#4}
+ {
+ \xsim_verbose:n
+ { Inserting~ #4~ type~ `#1'~ id~ `#2'. }
+ \group_begin:
+ \xsim_insert_mode:
+ \tl_gset:Nx \g_xsim_exercise_id_tl {#2}
+ \tl_gset:Nn \g_xsim_exercise_type_tl {#1}
+ \use:c {xsim_start_#4:nn} {#1} {#3}
+ \xsim_typeset_environment:nnn {#1} {#2} {#4}
+ \use:c {xsim_stop_#4:n} {#1} {}
+ \group_end:
+ }
+ }
+\cs_generate_variant:Nn \xsim_insert:nnnn {nV,VV,nnnV,xx,ne}
+
+% #1: type
+% #2: id
+% #3: exercise|solution
+\cs_new_protected:Npn \xsim_input:nnn #1#2#3
+ {
+ \xsim_if_exchange:nnnTF {#1} {#2} {#3}
+ { \__xsim_set_file_signature:nnn {#1} {#2} {exercise} }
+ { \__xsim_set_file_signature:nnn {#1} {#2} {#3} }
+ \xsim_if_write_to_files:TF
+ {
+ \file_if_exist:nTF { \exp_not:V \l__xsim_file_path_and_name_tl }
+ { \file_input:n { \exp_not:V \l__xsim_file_path_and_name_tl } }
+ {
+ \xsim_verbose:n
+ { File~ `\l__xsim_file_path_and_name_tl'~ doesn't~ exist. }
+ }
+ }
+ {
+ \xsim_if_exchange:nnnTF {#1} {#2} {#3}
+ { \xsim_get_property:nnn {#1} {#2} {exercise-body} }
+ { \xsim_get_property:nnn {#1} {#2} {#3-body} }
+ }
+ }
+\cs_generate_variant:Nn \xsim_input:nnn {oo}
+
+\prg_new_conditional:Npnn \xsim_if_insert_mode: {T,F,TF}
+ {
+ \bool_if:NTF \l__xsim_insert_mode_bool
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+
+\cs_new_protected:Npn \xsim_insert_mode:
+ { \bool_set_true:N \l__xsim_insert_mode_bool }
+
+% ----------------------------------------------------------------------------
+
+% #1: type
+% #2: exercise|solution
+\cs_new_protected:Npn \xsim_new_environment:nn #1#2
+ {
+ \xsim_verbose:n { Defining~ #2~ environment~ type~ `#1'. }
+ \xsim_new_hook:nnn {#1} {#2} {pre}
+ \xsim_new_hook:nnn {#1} {#2} {begin}
+ \xsim_new_hook:nnn {#1} {#2} {end}
+ \xsim_new_hook:nnn {#1} {#2} {post}
+ \xsim_new_hook:nnn {#1} {#2} {print-false}
+ \xsim_if_write_to_files:TF
+ {
+ \NewDocumentEnvironment
+ { \xsim_get_parameter:nn {#1} {#2-env} } {!o}
+ {
+ \IfNoValueTF {##1}
+ {
+ \bool_set_false:N \l__xsim_options_given_bool
+ \use:c {xsim_start_#2:nn} {#1} {}
+ }
+ {
+ \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} { }
+ }
+ {
+ \xsim_stop_environment:nVn {#1} \g_xsim_exercise_id_tl {#2}
+ \use:c {xsim_stop_#2:n} {#1}
+ }
+ }
+ {
+ \NewDocumentEnvironment
+ { \xsim_get_parameter:nn {#1} {#2-env} } {o+b}
+ {
+ \IfNoValueTF {##1}
+ {
+ \bool_set_false:N \l__xsim_options_given_bool
+ \use:c {xsim_start_#2:nn} {#1} {}
+ }
+ {
+ \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_stop_environment:nVn {#1} \g_xsim_exercise_id_tl {#2}
+ \use:c {xsim_stop_#2:n} {#1}
+ }
+ }
+ }
+
+\XSIMmoduleend
+\XSIMmodule{templates}{templates for typesetting exercises}
+
+\msg_new:nnn {xsim} {unknown-template}
+ {
+ You~ are~ trying~ to~ load~ the~ template~ `#2'~ (template~ type~ `#1')~
+ \msg_line_context: .~ This~ template~ does~ not~ seem~ to~ be~ defined.~
+ 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
+ {
+ \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
+% #2: template name
+% #3: code
+\cs_new_protected:Npn \__xsim_add_template:nnn #1#2#3
+ {
+ \xsim_verbose:n { Defining~ new~ template~ `#2'~ of~ type~ `#1'. }
+ \tl_new:c {l__xsim_template_#1_#2_setup_tl}
+ \xsim_attribute_set:nnn {template::#1} {#2} {#3}
+ }
+
+\prg_new_conditional:Npnn \xsim_if_template_exist:nn #1#2 {T,F,TF}
+ {
+ \xsim_attribute_if_set:nnTF {template::#1} {#2}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+
+% #1: template type
+% #2: template name
+\cs_new_protected:Npn \__xsim_get_template:nn #1#2
+ { \xsim_attribute_get:nn {template::#1} {#2} }
+
+% ----------------------------------------------------------------------------
+
+% environment templates (types `begin' and `end'):
+\xsim_new_template_type:n {begin}
+\xsim_new_template_type:n {end}
+
+% #1: template name
+% #2: begin code
+% #3: end code
+\cs_new_protected:Npn \xsim_declare_environment_template:nnn #1#2#3
+ {
+ \__xsim_add_template:nnn {begin} {#1}
+ {
+ \__xsim_start_template:nn {begin} {#1}
+ \__xsim_start_template:nn {end} {#1}
+ #2
+ }
+ \__xsim_add_template:nnn {end} {#1}
+ {
+ #3
+ \__xsim_stop_template:nn {end} {#1}
+ \__xsim_stop_template:nn {begin} {#1}
+ }
+ }
+
+% ----------------------------------------------------------------------------
+
+% heading templates for the solution list (type `heading'):
+\xsim_new_template_type:n {heading}
+
+% #1: template name
+% #2: code
+\cs_new_protected:Npn \xsim_declare_heading_template:nn #1#2
+ {
+ \__xsim_add_template:nnn {heading} {#1}
+ {
+ \__xsim_start_template:nn {heading} {#1}
+ #2
+ \__xsim_stop_template:nn {heading} {#1}
+ }
+ }
+
+% ----------------------------------------------------------------------------
+
+% grading table templates (type `table'):
+\xsim_new_template_type:n {table}
+
+% #1: template name
+% #2: code
+\cs_new_protected:Npn \xsim_declare_table_template:nn #1#2
+ {
+ \__xsim_add_template:nnn {table} {#1}
+ {
+ \__xsim_start_template:nn {table} {#1}
+ #2
+ \__xsim_stop_template:nn {table} {#1}
+ }
+ }
+
+% ----------------------------------------------------------------------------
+
+% using templates:
+% setup up the next usage of `template name':
+% #1: template type
+% #2: template name
+% #3: setup code
+\cs_new_protected:Npn \xsim_setup_template:nnn #1#2#3
+ { \tl_set:cn {l__xsim_template_#1_#2_setup_tl} {#3} }
+\cs_generate_variant:Nn \xsim_setup_template:nnn {nnV,nVn}
+
+% #1: template type
+% #2: template name
+\cs_new_protected:Npn \__xsim_setup_template:nn #1#2
+ { \tl_use:c {l__xsim_template_#1_#2_setup_tl} }
+
+% #1: template type
+% #2: template name
+\cs_new_protected:Npn \__xsim_clear_template_setup:nn #1#2
+ { \tl_clear:c {l__xsim_template_#1_#2_setup_tl} }
+
+% #1: template type
+% #2: template name
+\cs_new_protected:Npn \__xsim_start_template:nn #1#2
+ { \group_begin: \__xsim_setup_template:nn {#1} {#2} }
+
+% #1: template type
+% #2: template name
+\cs_new_protected:Npn \__xsim_stop_template:nn #1#2
+ { \group_end: \__xsim_clear_template_setup:nn {#1} {#2} }
+
+% #1: template type
+% #2: template name
+\cs_new_protected:Npn \xsim_use_template:nn #1#2
+ {
+ \xsim_if_template_exist:nnTF {#1} {#2}
+ { \__xsim_get_template:nn {#1} {#2} }
+ {
+ \msg_warning:nnnnn {xsim} {unknown-template} {#1} {#2} {default}
+ \__xsim_get_template:nn {#1} {default}
+ }
+ }
+\cs_generate_variant:Nn \xsim_use_template:nn {nx,nV}
+
+\XSIMmoduleend
+\XSIMmodule{tags}{tagging of exercises}
+
+\seq_new:N \l__xsim_tag_types_seq
+\bool_new:N \l____xsim_tagged_bool
+
+\msg_new:nnn {xsim} {tag-exists}
+ { The~ tag~ type~ `#1'~ already~ exists.~ I~ am~ doing~ nothing. }
+
+\msg_new:nnn {xsim} {tag-unknown}
+ { The~ tag~ type~ `#1'~ is~ not~ defined.~ Check~ for~ a~ typo. }
+
+% #1: name
+\cs_new_protected:Npn \xsim_new_tag_type:n #1
+ {
+ \xsim_verbose:n { Declaring~ new~ tag~ type~ `#1'. }
+ \seq_put_right:Nn \l__xsim_tag_types_seq {#1}
+ \seq_remove_duplicates:N \l__xsim_tag_types_seq
+ \seq_new:c {l__xsim_chosen_tags_#1_seq}
+ \bool_new:c {l__xsim_ignore_untagged_#1_bool}
+ \bool_new:c {l____xsim_tagged_#1_bool}
+ \keys_define:nn {xsim}
+ {
+ #1/ignore-untagged .bool_set:c = {l__xsim_ignore_untagged_#1_bool} ,
+ #1/ignore-untagged .initial:n = true ,
+ #1 .code:n =
+ \seq_set_from_clist:cn {l__xsim_chosen_tags_#1_seq} {##1}
+ }
+ \prg_new_protected_conditional:cpnn {xsim_if_#1_value:n} ##1 {T,F,TF}
+ {
+ \seq_if_in:cnTF {l__xsim_chosen_tags_#1_seq} {##1}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+ \xsim_declare_property:nnnn
+ { \c_false_bool }
+ { \c_false_bool }
+ { \c_false_bool }
+ {#1}
+ \xsim_declare_printsolutions_condition:nn {#1}
+ { \__xsim_printsolutions_if_tagged:nnnnTF {#1} }
+ \keys_define:nn {xsim/print-solutions}
+ {
+ #1 .choice: ,
+ #1/false .code:n =
+ \__xsim_printsolutions_condition:nn {#1} {false} ,
+ #1/true .code:n =
+ \__xsim_printsolutions_condition:nn {#1} {true} ,
+ #1/unknown .code:n =
+ \keys_set:nn {xsim} { #1 = ##1 }
+ \__xsim_printsolutions_condition:nn {#1} {true} ,
+ #1 .initial:n = false
+ }
+ }
+
+% #1: tag type
+\prg_new_protected_conditional:Npnn \xsim_if_tag_type_exist:n #1 {T,F,TF}
+ {
+ \seq_if_in:NnTF \l__xsim_tag_types_seq {#1}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+\prg_generate_conditional_variant:Nnn \xsim_if_tag_type_exist:n {V} {TF}
+
+% #1: tag type
+% #2: exercise type
+% #3: id
+% #4: print|use
+\prg_new_protected_conditional:Npnn
+ \__xsim_printsolutions_if_tagged:nnnn #1#2#3#4 {T,F,TF}
+ {
+ \xsim_if_in_list:nnTF {#4} {#2-#3=={true}}
+ {
+ \__xsim_printsolutions_if_condition:nTF {#1}
+ {
+ \__xsim_printsolutions_condition_true:
+ \xsim_if_tagged:nnnTF {#2} {#3} {#1}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+ { \prg_return_false: }
+ }
+ { \prg_return_false: }
+ }
+
+% #1: exercise type
+% #2: id
+% #3: tag type
+\prg_new_protected_conditional:Npnn \xsim_if_tagged:nnn #1#2#3 {T,F,TF}
+ {
+ \bool_set_false:c {l____xsim_tagged_#3_bool}
+ \seq_if_empty:cTF {l__xsim_chosen_tags_#3_seq}
+ { \bool_set_true:c {l____xsim_tagged_#3_bool} }
+ {
+ \seq_set_from_clist:Nx
+ \l__xsim_tmpa_seq
+ { \xsim_get_property:nnn {#1} {#2} {#3} }
+ \seq_if_empty:NTF \l__xsim_tmpa_seq
+ {
+ \bool_set_eq:cc
+ {l____xsim_tagged_#3_bool}
+ {l__xsim_ignore_untagged_#3_bool}
+ }
+ {
+ \seq_map_inline:Nn \l__xsim_tmpa_seq
+ {
+ \seq_if_in:cnT {l__xsim_chosen_tags_#3_seq} {##1}
+ {
+ \bool_set_true:c {l____xsim_tagged_#3_bool}
+ \seq_map_break:
+ }
+ }
+ }
+ }
+ \bool_if:cTF {l____xsim_tagged_#3_bool}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+
+% #1: exercise type
+% #2: id
+% #3: tag type
+% #4: tag values
+\prg_new_protected_conditional:Npnn \xsim_has_tags:nnnn #1#2#3#4 {T,F,TF}
+ {
+ \bool_set_false:c {l____xsim_tagged_#3_bool}
+ \seq_set_from_clist:Nn \l__xsim_tmpa_seq {#4}
+ \seq_if_empty:NTF \l__xsim_tmpa_seq
+ {% no tag values given:
+ \bool_set_true:c {l____xsim_tagged_#3_bool}
+ }
+ {
+ \seq_set_from_clist:Nx
+ \l__xsim_tmpb_seq
+ { \xsim_get_property:nnn {#1} {#2} {#3} }
+ \seq_if_empty:NTF \l__xsim_tmpb_seq
+ {% exercise has no tag values given
+ % \bool_set_eq:cc
+ % {l____xsim_tagged_#3_bool}
+ % {l__xsim_ignore_untagged_#3_bool}
+ \bool_set_false:c {l____xsim_tagged_#3_bool}
+ }
+ {
+ \seq_map_inline:Nn \l__xsim_tmpb_seq
+ {
+ \seq_if_in:NnT \l__xsim_tmpa_seq {##1}
+ {
+ \bool_set_true:c {l____xsim_tagged_#3_bool}
+ \seq_map_break:
+ }
+ }
+ }
+ }
+ \bool_if:cTF {l____xsim_tagged_#3_bool}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+\prg_generate_conditional_variant:Nnn \xsim_has_tags:nnnn {nnVV} {T}
+
+% #1: exercise type
+% #2: id
+\prg_new_protected_conditional:Npnn \xsim_if_tagged:nn #1#2 {T,F,TF}
+ {
+ \bool_set_true:N \l____xsim_tagged_bool
+ \seq_map_inline:Nn \l__xsim_tag_types_seq
+ {
+ \xsim_if_tagged:nnnF {#1} {#2} {##1}
+ {
+ \bool_set_false:N \l____xsim_tagged_bool
+ \seq_map_break:
+ }
+ }
+ \bool_if:NTF \l____xsim_tagged_bool
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+
+
+% #1: exercise type
+% #2: id
+% #3: tag type
+% #4: code
+\cs_new_protected:Npn \xsim_foreach_exercise_tag:nnnn #1#2#3#4
+ {
+ \seq_set_from_clist:Nx \l__xsim_tmpa_seq
+ { \xsim_get_property:nnn {#1} {#2} {#3} }
+ \seq_map_inline:Nn \l__xsim_tmpa_seq {#4}
+ }
+\cs_generate_variant:Nn \xsim_foreach_exercise_tag:nnnn {oo}
+
+% #1: exercise type
+% #2: id
+% #3: tag type
+% #4: sep
+\cs_new_protected:Npn \xsim_exercise_tags_use:nnnn #1#2#3#4
+ {
+ \seq_set_from_clist:Nx \l__xsim_tmpa_seq
+ { \xsim_get_property:nnn {#1} {#2} {#3} }
+ \seq_use:Nn \l__xsim_tmpa_seq {#4}
+ }
+\cs_generate_variant:Nn \xsim_exercise_tags_use:nnnn {oo}
+
+% #1: exercise type
+% #2: id
+% #3: tag type
+% #4: sep between two
+% #5: sep between more than two
+% #6: sep between last two
+\cs_new_protected:Npn \xsim_exercise_tags_use:nnnnnn #1#2#3#4#5#6
+ {
+ \seq_set_from_clist:Nx \l__xsim_tmpa_seq
+ { \xsim_get_property:nnn {#1} {#2} {#3} }
+ \seq_use:Nnnn \l__xsim_tmpa_seq {#4} {#5} {#6}
+ }
+\cs_generate_variant:Nn \xsim_exercise_tags_use:nnnn {oo}
+\cs_generate_variant:Nn \xsim_exercise_tags_use:nnnnnn {oo}
+
+\XSIMmoduleend
+\XSIMmodule{goals}{counting of points and bonus points}
+
+\msg_new:nnn {xsim} {goal-unknown}
+ { The~ goal~ `#1'~ has~ never~ been~ declared~ \msg_line_context: }
+
+\seq_new:N \l__xsim_goals_seq
+\tl_new:N \l_xism_grading_table_template_tl
+\tl_new:N \l_xism_grading_table_exercise_type_tl
+
+% #1: name
+\cs_new_protected:Npn \xsim_declare_exercise_goal:n #1
+ {
+ \xsim_if_goal_exist:nF {#1}
+ {
+ \xsim_verbose:n { Declaring~ new~ goal~ `#1'. }
+ \xsim_declare_property:nnnn
+ { \c_false_bool } { \c_false_bool } { \c_false_bool } {#1}
+ \xsim_declare_property:nnnn
+ { \c_false_bool } { \c_false_bool } { \c_false_bool } {user#1}
+ \xsim_declare_property:nnnn
+ { \c_false_bool } { \c_false_bool } { \c_false_bool } {body#1}
+ \seq_put_right:Nn \l__xsim_goals_seq {#1}
+ \fp_gzero_new:c {g__xsim_goal_#1_fp}
+ \fp_new:c {l__xsim_temporary_#1_fp}
+ \bool_new:c {l__xsim_temporary_#1_bool}
+ \bool_new:c {l__xsim_goal_#1_given_bool}
+ \fp_gzero_new:c {l__xsim_current_goal_#1_fp}
+ \fp_if_exist:cF {g__xsim_total_goal_#1_fp}
+ { \fp_new:c {g__xsim_total_goal_#1_fp} }
+ \fp_if_exist:cF {g__xsim_total_goal_recorded_#1_fp}
+ { \fp_new:c {g__xsim_total_goal_recorded_#1_fp} }
+ \xsim_before_begin_document:n
+ {
+ \xsim_foreach_exercise_type:n
+ { \xsim_goal_init:nn {##1} {#1} }
+ }
+ }
+ }
+
+% #1: type
+% #2: goal
+\cs_new_protected:Npn \xsim_goal_init:nn #1#2
+ {
+ \fp_gzero_new:c {g__xsim_#1_goal_#2_fp}
+ \fp_if_exist:cF {g__xsim_total_#1_goal_#2_fp}
+ { \fp_new:c {g__xsim_total_#1_goal_#2_fp} }
+ }
+
+\prg_new_conditional:Npnn \xsim_if_goal_exist:n #1 {p,T,F,TF}
+ {
+ \seq_if_in:NnTF \l__xsim_goals_seq {#1}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+
+\prg_new_conditional:Npnn \xsim_if_goal_given:n #1 {p,T,F,TF}
+ {
+ \bool_if:cTF {l__xsim_goal_#1_given_bool}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+
+\cs_new_protected:Npn \xsim_goal_given:n #1
+ { \bool_set_true:c {l__xsim_goal_#1_given_bool} }
+
+% #1: exercise type
+% #2: id
+% #3: goal
+\cs_new_protected:Npn \xsim_update_goal:nnn #1#2#3
+ {
+ \xsim_if_goal_exist:nT {#3}
+ {
+ \fp_gadd:cn {g__xsim_goal_#3_fp}
+ { \xsim_get_property:nnn {#1} {#2} {#3} + 0 }
+ \fp_gadd:cn {g__xsim_#1_goal_#3_fp}
+ { \xsim_get_property:nnn {#1} {#2} {#3} + 0 }
+ }
+ }
+
+% #1: exercise type
+% #2: id
+\cs_new_protected:Npn \xsim_update_goals:nn #1#2
+ {
+ \xsim_foreach_goal:n
+ { \xsim_update_goal:nnn {#1} {#2} {##1} }
+ }
+\cs_generate_variant:Nn \xsim_update_goals:nn {nV}
+
+\cs_new_protected:Npn \xsim_foreach_goal:n #1
+ { \seq_map_inline:Nn \l__xsim_goals_seq {#1} }
+
+
+% #1: exercise type
+% #2: id
+% #3: goal
+% #4: value
+\cs_new_protected:Npn \xsim_addto_goal:nnnn #1#2#3#4
+ {
+ \xsim_if_goal_exist:nT {#3}
+ {
+ \xsim_verbose:n { Adding~ `#4'~ to~ `#3'~ goal~ of~ #1~ #2 }
+ \fp_set:Nn \l__xsim_tmpa_fp
+ { \xsim_get_property:nnn {#1} {#2} {body#3} + 0 + #4 }
+ \xsim_set_property:nnne {#1} {#2} {body#3}
+ { \fp_to_decimal:N \l__xsim_tmpa_fp }
+ }
+ }
+\cs_generate_variant:Nn \xsim_addto_goal:nnnn {xx,nVnx}
+
+% #1: exercise type
+% #2: id
+% #3: goal
+% #4: relation and value
+\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 }
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+\cs_generate_variant:Nn \xsim_if_goal_value:nnnnTF {xx}
+
+% ----------------------------------------------------------------------------
+% a function which can be used to modify how the numbers of a goal are
+% printed:
+\cs_new_protected:Npn \__xsim_print_goal:n #1 {#1}
+\cs_generate_variant:Nn \__xsim_print_goal:n {x}
+
+% #1: value
+% #2: value == 1
+% #3: value != 1
+\cs_new_protected:Npn \xsim_print_goal:nnn #1#2#3
+ {
+ \__xsim_print_goal:x { \fp_to_decimal:n {#1} }
+ \fp_compare:nTF { (#1) = 1 } {#2} {#3}
+ }
+
+% #1: exercise type
+% #2: goal
+% #3: sum == 1
+% #4: sum != 1
+\cs_new_protected:Npn \xsim_print_goal_sum:nnnn #1#2#3#4
+ { \xsim_print_goal:nnn { \use:c {g__xsim_total_#1_goal_#2_fp} } {#3} {#4} }
+
+% #1: goal
+% #2: sum == 1
+% #3: sum != 1
+\cs_new_protected:Npn \xsim_print_total_goal_sum:nnn #1#2#3
+ { \xsim_print_goal:nnn { \use:c {g__xsim_total_goal_#1_fp} } {#2} {#3} }
+
+% ----------------------------------------------------------------------------
+% the same as the last to functions but for a list of goals:
+
+% #1: fp variable to be set
+% #2: list of goals (separated with +)
+% #3: function to be applied to goal names
+\cs_new_protected:Npn \__xsim_exercise_goals_sum_aux:Nnn #1#2#3
+ {
+ \seq_set_split:Nnn \l__xsim_tmpa_seq {+} {#2}
+ \seq_set_map:NNn \l__xsim_tmpb_seq \l__xsim_tmpa_seq {#3}
+ \fp_set:Nn #1 { \seq_use:Nn \l__xsim_tmpb_seq {+} }
+ }
+
+% #1: fp variable
+% #2: exercise type
+% #3: list of goals (separated with +)
+\cs_new_protected:Npn \__xsim_exercise_goals_sum:Nnn #1#2#3
+ {
+ \__xsim_exercise_goals_sum_aux:Nnn #1 {#3}
+ { \use:c {g__xsim_total_#2_goal_ \tl_trim_spaces:n {##1} _fp} }
+ }
+
+% #1: fp variable
+% #2: list of goals (separated with +)
+\cs_new_protected:Npn \__xsim_exercise_goals_sum:Nn #1#2
+ {
+ \__xsim_exercise_goals_sum_aux:Nnn #1 {#2}
+ { \use:c {g__xsim_total_goal_ \tl_trim_spaces:n {##1} _fp} }
+ }
+
+% #1: exercise type
+% #2: list of goals (separated with +)
+% #3: sum == 1
+% #4: sum != 1
+\cs_new_protected:Npn \xsim_print_goals_sum:nnnn #1#2#3#4
+ {
+ \__xsim_exercise_goals_sum:Nnn \l__xsim_tmpa_fp {#1} {#2}
+ \xsim_print_goal:nnn { \l__xsim_tmpa_fp } {#3} {#4}
+ }
+
+% #1: list of goals (separated with +)
+% #2: sum == 1
+% #3: sum != 1
+\cs_new_protected:Npn \xsim_print_total_goals_sum:nnn #1#2#3
+ {
+ \__xsim_exercise_goals_sum:Nn \l__xsim_tmpa_fp {#1}
+ \xsim_print_goal:nnn { \l__xsim_tmpa_fp } {#2} {#3}
+ }
+
+% ----------------------------------------------------------------------------
+% #1: exercise type
+% #2: goal
+% #3: relation and value
+\prg_new_conditional:Npnn \xsim_if_goal_sum:nnn #1#2#3 {p,T,F,TF}
+ {
+ \fp_compare:nTF
+ { ( \use:c {g__xsim_total_#1_goal_#2_fp} ) #3 }
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+
+% #1: exercise type
+% #2: list of goals (separated with +)
+% #3: relation and value
+\prg_new_protected_conditional:Npnn \xsim_if_goals_sum:nnn #1#2#3 {T,F,TF}
+ {
+ \__xsim_exercise_goals_sum:Nnn \l__xsim_tmpa_fp {#1} {#2}
+ \fp_compare:nTF
+ { ( \l__xsim_tmpa_fp ) #3 }
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+
+% #1: goal
+% #2: relation and value
+\prg_new_conditional:Npnn \xsim_if_total_goal_sum:nn #1#2 {p,T,F,TF}
+ {
+ \fp_compare:nTF
+ { ( \use:c {g__xsim_total_goal_#1_fp} ) #2 }
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+
+% #1: list of goals (separated with +)
+% #2: relation and value
+\prg_new_protected_conditional:Npnn \xsim_if_total_goals_sum:nn #1#2 {T,F,TF}
+ {
+ \__xsim_exercise_goals_sum:Nn \l__xsim_tmpa_fp {#1}
+ \fp_compare:nTF
+ { ( \l__xsim_tmpa_fp ) #2 }
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+
+% ----------------------------------------------------------------------------
+% #1: exercise type
+% #2: goal
+% #3: value
+\xsim_new_aux_property:cpn {goal} #1#2#3
+ { \fp_gset:cn {g__xsim_total_#1_goal_#2_fp} {#3} }
+
+% #1: goal
+% #2: value
+\xsim_new_aux_property:cpn {totalgoal} #1#2
+ { \fp_gset:cn {g__xsim_total_goal_#1_fp} {#2} }
+
+\xsim_at_begin_document:n
+ { \xsim_foreach_goal:n { \xsim_get_total_goal:n {#1} } }
+
+% #1: goal
+\cs_new_protected:Npn \xsim_get_total_goal:n #1
+ {
+ \fp_gset_eq:cc
+ {g__xsim_total_goal_recorded_#1_fp}
+ {g__xsim_total_goal_#1_fp}
+ }
+
+\xsim_at_end_document:n { \xsim_save_goals: }
+
+\cs_new_protected:Npn \xsim_save_goals:
+ {
+ \xsim_foreach_goal:n
+ {
+ \xsim_foreach_exercise_type:n
+ {
+ \xsim_add_property_to_aux:nn {goal}
+ { {####1} {##1} { \fp_to_decimal:c {g__xsim_####1_goal_##1_fp} } }
+ }
+ \tl_set:Nx \l__xsim_tmpa_tl
+ { \fp_to_decimal:c {g__xsim_total_goal_##1_fp} }
+ \tl_set:Nx \l__xsim_tmpb_tl
+ { \fp_to_decimal:c {g__xsim_total_goal_recorded_##1_fp} }
+ \tl_if_eq:NNF \l__xsim_tmpa_tl \l__xsim_tmpb_tl { \xsim_rerun: }
+ \xsim_add_property_to_aux:nn {totalgoal}
+ { {##1} { \fp_to_decimal:c {g__xsim_goal_##1_fp} } }
+ }
+ }
+
+% ----------------------------------------------------------------------------
+
+\keys_define:nn {xsim}
+ {
+ goal-print .code:n =
+ \cs_set_protected:Npn \__xsim_print_goal:n ##1 {#1} ,
+ grading-table/template .tl_set:N = \l_xism_grading_table_template_tl ,
+ grading-table/template .initial:n = default ,
+ grading-table/type .tl_set:N = \l_xism_grading_table_exercise_type_tl ,
+ grading-table/type .initial:n =
+ }
+
+\XSIMmoduleend
+\XSIMmodule{exercises}{main exercises definitions}
+
+\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
+\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 \g_xsim_exercise_type_tl
+\tl_new:N \ExerciseID
+\tl_new:N \ExerciseType
+
+% ----------------------------------------------------------------------------
+
+\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'.
+ }
+
+\msg_new:nnn {xsim} {unknown-parameter}
+ {
+ You~ tried~ to~ retrieve~ the~ parameter~ `#1'~ \msg_line_context: . \\
+ This~ parameter~ does~ not~ exist.~ Check~ for~ a~ typo~ or~ \\
+ define~ the~ parameter~ yourself.
+ }
+
+\msg_new:nnn {xsim} {parameter-undefined}
+ {
+ You~ tried~ to~ set~ the~ parameter~ `#2'~ for~ exercise~ type~ `#1'~
+ \msg_line_context: . \\
+ This~ parameter~ does~ not~ exist.~ Check~ for~ a~ typo~ or~ \\
+ define~ the~ parameter~ yourself.
+ }
+
+\msg_new:nnn {xsim} {parameter-value}
+ {
+ A~ parameter~ needs~ to~ be~ set~ to~ a~ (possibly~ empty)~ value! \\
+ Not~ setting~ parameter~ `#2'~ for~ exercise~ type~ `#1'~
+ \msg_line_context: .
+ }
+
+% ----------------------------------------------------------------------------
+% #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}
+\xsim_new_list:n {idtypes}
+
+% #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
+ {
+ \cs_set_protected:Npn \__xsim_set_parameter:n ##1
+ { \msg_warning:nnnn {xsim} {parameter-value} {#1} {##1} }
+ \cs_set_protected:Npn \__xsim_set_parameter:nn ##1##2
+ { \xsim_set_parameter:nnn {#1} {##1} {##2} }
+ \keyval_parse:NNn
+ \__xsim_set_parameter:n
+ \__xsim_set_parameter:nn
+ {#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_set: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}
+ {
+ \seq_if_in:NnTF \l__xsim_exercise_types_seq {#1}
+ { \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:nTF {#2}
+ {
+ \xsim_if_parameter_fixed:nTF {#1}
+ {
+ \xsim_if_parameter_set: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'. }
+ \__xsim_set_parameter_type:nnn {#1} {#2} {#3}
+ }
+ }
+ {
+ \xsim_verbose:n
+ { Setting~ parameter~ `#2'~ for~ type~ `#1'~ to~ `#3'. }
+ \__xsim_set_parameter_type:nnn {#1} {#2} {#3}
+ }
+ }
+ { \msg_error:nnnn {xsim} {parameter-undefined} {#1} {#2} }
+ }
+\cs_generate_variant:Nn \xsim_set_parameter:nnn {nnx,nxx}
+
+\cs_new:Npn \__xsim_get_parameter_tmp:n #1 {}
+\cs_generate_variant:Nn \__xsim_get_parameter_tmp:n {V}
+
+% #1: type
+% #2: parameter
+\cs_new_protected:Npn \xsim_get_parameter_if_set:nnTF #1#2#3#4
+ {
+ \group_begin:
+ \xsim_if_parameter_exist:nTF {#2}
+ {
+ \xsim_if_parameter_set:nnTF {#1} {#2}
+ {
+ \tl_set:Nx \ParameterValue
+ { \xsim_get_parameter:nn {#1} {#2} }
+ \cs_set:Npn \__xsim_get_parameter_tmp:n ##1 {#3}
+ \__xsim_get_parameter_tmp:V \ParameterValue
+ }
+ {#4}
+ }
+ { \msg_error:nnn {xsim} {unknown-parameter} {#2} }
+ \group_end:
+ }
+\cs_new_protected:Npn \xsim_get_parameter_if_set:nnT #1#2#3
+ { \xsim_get_parameter_if_set:nnTF {#1} {#2} {#3} {} }
+\cs_new_protected:Npn \xsim_get_parameter_if_set:nnF #1#2#3
+ { \xsim_get_parameter_if_set:nnTF {#1} {#2} {} {#3} }
+\cs_generate_variant:Nn \xsim_get_parameter_if_set:nnTF {o}
+
+% ----------------------------------------------------------------------------
+% 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} }
+
+% #1: macro name
+% #2: 0 to 9 times `n' (= number of arguments of internal item)
+% #3: code; may contain a suiting \__xsim_loop_item:<nnn>
+\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 }
+ }
+
+\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_protected:Npn \__xsim_deliver_exercise_details:nnn #1#2#3
+ {
+ \tl_if_blank:nTF {#3}
+ { \use:n }
+ { \xsim_if_in_list:nnT {#3} {#1-#2=={true}} }
+ {
+ \tl_set_rescan:Nnx \ExerciseType {} {#1}
+ \tl_set_rescan:Nnx \ExerciseID {} {#2}
+ \__xsim_loop_item:VVxxxx
+ \ExerciseType % #1
+ \ExerciseID % #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:Npn \__xsim_loop_item:nn #1#2 {}
+\cs_generate_variant:Nn \__xsim_loop_item:nn {VV}
+
+\xsim_define_loop_macro:Nnn \xsim_foreach_exercise:nn
+ {nn}
+ {
+ \cs_set:Npn \__xsim_tmpa:w ##1-##2 \q_stop {##1}
+ \cs_set:Npn \__xsim_tmpb:w ##1-##2 \q_stop {##2}
+ \seq_map_inline:cn {g_xsim_#1_order_seq}
+ {
+ \tl_set:Nx \l__xsim_tmpa_tl { \__xsim_tmpa:w ##1 \q_stop }
+ \tl_set:Nx \l__xsim_tmpb_tl { \__xsim_tmpb:w ##1 \q_stop }
+ \__xsim_loop_item:VV \l__xsim_tmpa_tl \l__xsim_tmpb_tl
+ }
+ }
+
+% ----------------------------------------------------------------------------
+\cs_new_protected:Npn \xsim_define_exercise_type_variables:n #1
+ {
+ \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}
+ }
+
+\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 } }
+ \xsim_if_parameter_set:nnT {#1} {within}
+ {
+ \counterwithin
+ { \xsim_get_parameter:nn {#1} {counter} }
+ { \xsim_get_parameter:nn {#1} {within} }
+ }
+ \xsim_if_parameter_set:nnT {#1} {the-counter}
+ {
+ \cs_set:cpx { the \xsim_get_parameter:nn {#1} {counter} }
+ { \xsim_get_parameter:nn {#1} {the-counter} }
+ }
+ }
+
+% #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:nne {#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_set:nnF {#1} {exercises-name}
+ {
+ \xsim_set_parameters:nn {#1}
+ { 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 }
+ }
+ \xsim_if_parameter_set:nnF {#1} {counter}
+ {
+ \xsim_set_parameters:nx {#1}
+ { 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} }
+ }
+ \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} / collect .choice: ,
+ \xsim_get_parameter:nn {#1} {exercise-env} / collect / true .code:n =
+ \keys_set:nn
+ { xsim / \xsim_get_parameter:nn {#1} {exercise-env} }
+ { use = false , print = false } ,
+ \xsim_get_parameter:nn {#1} {exercise-env} / collect / false .code:n =
+ \keys_set:nn
+ { xsim / \xsim_get_parameter:nn {#1} {exercise-env} }
+ { use = true , print = true } ,
+ \xsim_get_parameter:nn {#1} {exercise-env} / collect .default:n = true ,
+ \xsim_get_parameter:nn {#1} {exercise-env} / collect .initial:n = false ,
+ \xsim_get_parameter:nn {#1} {exercise-env} / within .code:n =
+ \exp_not:N \counterwithin { \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} {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
+ .code:n = \xsim_set_parameter:nnn {#1} {solution-heading} {####1}
+ }
+ \xsim_new_environment:nn {#1} {exercise}
+ \xsim_new_environment:nn {#1} {solution}
+ }
+ }
+
+% #1: type
+% #2: id
+\prg_new_conditional:Npnn \xsim_if_exercise_exist:nn #1#2 {T,F,TF}
+ {
+ \xsim_if_exist:nnnTF {#1} {#2} {exercise}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+\cs_generate_variant:Nn \xsim_if_exercise_exist:nnT {VV}
+
+% ----------------------------------------------------------------------------
+% define boolean properties <do> and <done> (<done> is a noupdate property)
+% and the conditional:
+% \xsim_if_<do>:nnTF
+%
+% #1: <do>
+% #2: <done>
+\cs_new_protected:Npn \__xsim_new_exercise_mode:nn #1#2
+ {
+ % boolean:
+ \xsim_declare_property:nnnn
+ { \c_false_bool } { \c_true_bool } { \c_false_bool } {#1}
+ % boolean, noupdate:
+ \xsim_declare_property:nnnn
+ { \c_false_bool } { \c_true_bool } { \c_true_bool } {(#2)}
+ % boolean:
+ \xsim_declare_property:nnnn
+ { \c_false_bool } { \c_true_bool } { \c_false_bool } {#2}
+ % ##1: type
+ % ##2: id
+ % ##3: exercise|solution
+ \prg_new_protected_conditional:cpnn {xsim_if_#1:nnn} ##1##2##3 {T,F,TF}
+ {
+ \use:c {xsim_##3_if_#1:nnTF} {##1} {##2}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+ }
+\cs_generate_variant:Nn \prg_new_protected_conditional:Npnn {c}
+\cs_generate_variant:Nn \prg_generate_conditional_variant:Nnn {c}
+
+\__xsim_new_exercise_mode:nn {use} {used}
+\__xsim_new_exercise_mode:nn {print} {printed}
+
+% #1: type
+% #2: options
+\cs_new_protected:Npn \xsim_exercise_setup:nn #1#2
+ {
+ \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 }
+ \tl_gset:Nx \g_xsim_exercise_id_tl { \int_use:N \g_xsim_id_int }
+ \tl_gset:Nn \g_xsim_exercise_type_tl {#1}
+ \xsim_add_to_list:nx {idtypes} { \g_xsim_exercise_id_tl == {#1} }
+ \xsim_foreach_goal:n
+ {
+ \xsim_if_property_set:nVnT {#1} \g_xsim_exercise_id_tl {##1}
+ {
+ \bool_set_true:c {l__xsim_temporary_##1_bool}
+ \fp_set:cn {l__xsim_temporary_##1_fp}
+ { \xsim_get_property:nVn {#1} \g_xsim_exercise_id_tl {##1} }
+ \xsim_unset_property:nVn {#1} \g_xsim_exercise_id_tl {##1}
+ }
+ }
+ \xsim_set_properties:nVe {#1} \g_xsim_exercise_id_tl
+ {
+ % properties set by the user:
+ \exp_not:n {#2} ,
+ % properties which need to have certain values:
+ id = \g_xsim_exercise_id_tl ,
+ printed = false ,
+ used = false
+ }
+ \xsim_foreach_goal:n
+ {
+ \xsim_if_property_set:nVnT {#1} \g_xsim_exercise_id_tl {##1}
+ {
+ \xsim_set_property:nVne {#1} \g_xsim_exercise_id_tl {user##1}
+ { \xsim_get_property:nVn {#1} \g_xsim_exercise_id_tl {##1} }
+ }
+ \bool_if:cT {l__xsim_temporary_##1_bool}
+ {
+ \xsim_set_property:nVne {#1} \g_xsim_exercise_id_tl {##1}
+ { \fp_to_decimal:c {l__xsim_temporary_##1_fp} }
+ }
+ }
+ }
+
+\prg_new_conditional:Npnn \xsim_exercise_if_use:nn #1#2 {T,F,TF}
+ {
+ \xsim_if_boolean_property:nnnTF {#1} {#2} {(used)}
+ { \prg_return_false: }
+ {
+ \xsim_if_insert_mode:TF
+ {
+ \xsim_if_property_set:nnnTF {#1} {#2} {use}
+ {
+ \xsim_if_boolean_property:nnnTF {#1} {#2} {use}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+ {
+ \bool_if:cTF {l__xsim_#1_exercise_use_bool}
+ { \prg_return_false: }
+ { \prg_return_true: }
+ }
+ }
+ {
+ \xsim_if_property_set:nnnTF {#1} {#2} {use}
+ {
+ \xsim_if_boolean_property:nnnTF {#1} {#2} {use}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+ {
+ \bool_if:cTF {l__xsim_#1_exercise_use_bool}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+ }
+ }
+ }
+\prg_generate_conditional_variant:Nnn \xsim_exercise_if_use:nn {nV} {T,TF}
+
+% #1: type
+% #2: ID
+\cs_new_protected:Npn \xsim_exercise_use_setup:nn #1#2
+ {
+ \stepcounter { \xsim_get_parameter:nn {#1} {number} }
+ \xsim_step_exercise_counter:nn {#1} {#2}
+ \xsim_set_properties:nne {#1} {#2}
+ {
+ section-value = \arabic{section} ,
+ section = \thesection ,
+ page-value = \arabic{page} ,
+ sectioning =
+ { \cs_if_exist:NTF \thechapter { \arabic {chapter} } {0} }
+ { \arabic {section} }
+ { \arabic {subsection} }
+ { \arabic {subsubsection} }
+ { \arabic {paragraph} } ,
+ page = \thepage
+ }
+ \xsim_if_property_exist:nT {chapter}
+ {
+ \xsim_set_properties:nne {#1} {#2}
+ {
+ chapter-value = \arabic{chapter} ,
+ chapter = \thechapter
+ }
+ }
+ }
+\cs_generate_variant:Nn \xsim_exercise_use_setup:nn {nV}
+
+\prg_new_conditional:Npnn \xsim_exercise_if_print:nn #1#2 {T,F,TF}
+ {
+ \xsim_if_tagged:nnTF {#1} {#2}
+ {
+ \xsim_if_insert_mode:TF
+ { \prg_return_true: }
+ {
+ \bool_if:cTF {l__xsim_#1_exercise_print_bool}
+ {
+ \xsim_if_property_set:nnnTF {#1} {#2} {print}
+ {
+ \xsim_if_boolean_property:nnnTF {#1} {#2} {print}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+ { \prg_return_true: }
+ }
+ {
+ \xsim_if_boolean_property:nnnTF {#1} {#2} {print}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+ }
+ }
+ { \prg_return_false: }
+ }
+\prg_generate_conditional_variant:Nnn \xsim_exercise_if_print:nn {nV} {T,TF}
+
+% #1: type
+% #2: ID
+\cs_new_protected:Npn \xsim_exercise_print_setup:nn #1#2
+ {
+ \xsim_foreach_goal:n
+ {
+ \xsim_if_property_set:nnnT {#1} {#2} {body##1}
+ { \xsim_set_property:nnnn {#1} {#2} {body##1} {0} }
+ }
+ }
+\cs_generate_variant:Nn \xsim_exercise_print_setup:nn {nV}
+
+% #1: type
+% #2: options
+\cs_new_protected:Npn \xsim_start_exercise:nn #1#2
+ {
+ \xsim_if_insert_mode:F { \xsim_exercise_setup:nn {#1} {#2} }
+ \xsim_exercise_if_use:nVT {#1} \g_xsim_exercise_id_tl
+ { \xsim_exercise_use_setup:nV {#1} \g_xsim_exercise_id_tl }
+ \xsim_exercise_if_print:nVT {#1} \g_xsim_exercise_id_tl
+ { \xsim_exercise_print_setup:nV {#1} \g_xsim_exercise_id_tl }
+ \tl_set_eq:NN \ExerciseID \g_xsim_exercise_id_tl
+ \tl_set:Nn \ExerciseType {#1}
+ \xsim_verbose:x
+ { Starting~ exercise~ type~ `#1' with~ id~ ` \g_xsim_exercise_id_tl '. }
+ \xsim_if_insert_mode:F { \xsim_collect:nV {#1} \g_xsim_exercise_id_tl }
+ }
+
+% #1: type
+\cs_new_protected:Npn \xsim_stop_exercise:n #1
+ {
+ \tl_set_eq:NN \ExerciseID \g_xsim_exercise_id_tl
+ \tl_set:Nn \ExerciseType {#1}
+ \xsim_if_insert_mode:F
+ {
+ \xsim_foreach_goal:n
+ {
+ \xsim_if_property_set:nVnTF {#1} \g_xsim_exercise_id_tl {##1}
+ {
+ \fp_set:Nn \l__xsim_tmpa_fp
+ { \xsim_get_property:nVn {#1} \g_xsim_exercise_id_tl {body##1} + 0 }
+ \fp_set:Nn \l__xsim_tmpb_fp
+ { \xsim_get_property:nVn {#1} \g_xsim_exercise_id_tl {user##1} + 0 }
+ \fp_set:Nn \l__xsim_tmpa_fp { \l__xsim_tmpa_fp + \l__xsim_tmpb_fp }
+ \xsim_set_property:nVne {#1} \g_xsim_exercise_id_tl {##1}
+ { \fp_to_decimal:N \l__xsim_tmpa_fp }
+ }
+ {
+ \xsim_if_property_set:nVnT {#1} \g_xsim_exercise_id_tl {body##1}
+ { \xsim_set_property:nVnn {#1} \g_xsim_exercise_id_tl {##1} {0} }
+ }
+ }
+ }
+ \xsim_exercise_if_print:nVT {#1} \g_xsim_exercise_id_tl
+ {
+ \xsim_set_property:nVnn {#1} \g_xsim_exercise_id_tl {(printed)} {true}
+ \xsim_set_property:nVnn {#1} \g_xsim_exercise_id_tl {printed} {true}
+ }
+ \xsim_exercise_if_use:nVT {#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 {used} {true}
+ \xsim_update_goals:nV {#1} \g_xsim_exercise_id_tl
+ }
+ }
+
+% ----------------------------------------------------------------------------
+
+\xsim_new_aux_property:cpn {total-number} #1
+ { \int_gset:Nn \g_xsim_max_id_int {#1} }
+
+\hook_gput_code:nnn {begindocument/before} {xsim}
+ {
+ \xsim_foreach_exercise_type:n
+ {
+ \tl_new:c { number of #1 s }
+ \tl_gset:cn { number of #1 s } {0}
+ \xsim_new_aux_property:cpn {#1} ##1
+ { \tl_gset:cn { number of #1 s } {##1} }
+ }
+ }
+
+\xsim_at_begin_document:n
+ {
+ \xsim_foreach_exercise_type:n
+ {
+ \xsim_write_to_aux:x
+ { \token_to_str:N \providecommand \token_to_str:N \numberof #1 s {} }
+ }
+ }
+
+\xsim_at_end_document:n
+ {
+ \xsim_if_clear_aux:T
+ {
+ \int_compare:nNnF { \g_xsim_max_id_int } = { \g_xsim_id_int }
+ { \xsim_empty_lists: }
+ }
+ \xsim_add_property_to_aux:nn {total-number} { { \int_use:N \g_xsim_id_int } }
+ \xsim_foreach_exercise_type:n
+ {
+ \xsim_add_property_to_aux:nn {#1}
+ { { \arabic { \xsim_get_parameter:nn {#1} {number} } } }
+ }
+ \xsim_update_list:n {types}
+ \xsim_update_list:n {idtypes}
+ }
+
+\XSIMmoduleend
+\XSIMmodule{solutions}{managing solutions}
+
+\bool_new:N \l_xsim_inside_solution_bool
+\bool_new:N \l__xsim_include_question_bool
+\bool_new:N \l__xsim_printsolutions_headings_bool
+\bool_new:N \l__xsim_printsolutions_conditions_bool
+\bool_new:N \l____xsim_this_condition_bool
+
+\seq_new:N \l__xsim_printsolutions_conditions_seq
+
+\int_new:N \l_xsim_printsolutions_section_int
+\int_new:N \l_xsim_printsolutions_chapter_int
+
+\tl_new:N \l__xsim_printsolutions_headings_template_tl
+\tl_new:N \ExerciseSection
+\tl_new:N \ExerciseChapter
+\tl_new:N \l__xsim_printsolutions_collection_tl
+
+% ----------------------------------------------------------------------------
+
+\prg_new_conditional:Npnn \xsim_if_inside_solution: {p,T,F,TF}
+ {
+ \bool_if:NTF \l_xsim_inside_solution_bool
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+
+\prg_new_conditional:Npnn \xsim_if_solution_print:n #1 {p,T,F,TF}
+ {
+ \bool_if:cTF {l__xsim_#1_solution_print_bool}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+
+\bool_new:N \l____xsim_print_bool
+
+% #1: type
+% #2: id
+\prg_new_protected_conditional:Npnn \xsim_solution_if_print:nn #1#2 {T,F,TF}
+ {
+ \bool_set_true: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} {(used)}
+ { \bool_set_false:N \l____xsim_print_bool }
+ \bool_if:cF {l__xsim_#1_solution_print_bool}
+ { \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_solution_if_print:nnT {nV,oo}
+
+% #1: type
+% #2: id
+\prg_new_protected_conditional:Npnn \xsim_if_solution_exist:nn #1#2 {T,F,TF}
+ {
+ \xsim_if_boolean_property:nnnTF {#1} {#2} {solution}
+ { \xsim_if_exist:nnnTF {#1} {#2} {exercise} }
+ { \xsim_if_exist:nnnTF {#1} {#2} {solution} }
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+\cs_generate_variant:Nn \xsim_if_solution_exist:nnT {VV,oo}
+\cs_generate_variant:Nn \xsim_if_solution_exist:nnTF {oo}
+
+% #1: type
+% #2: options
+\cs_new_protected:Npn \xsim_start_solution:nn #1#2
+ {
+ \keys_set:xn { xsim/\xsim_get_parameter:nn {#1} {solution-env} } {#2}
+ \bool_set_true:N \l_xsim_inside_solution_bool
+ \refstepcounter { \xsim_get_parameter:nn {#1} {solution-counter} }
+ }
+
+\cs_new_protected:Npn \xsim_stop_solution:n #1 {}
+
+% ----------------------------------------------------------------------------
+
+% #1: conditional base function (three n args)
+% #2: name
+% #3: code (refer to type and id with `#1' and `#2'), #3 refers to the boolean
+% properties use/print
+\cs_new_protected:Npn \xsim_new_solutions_condition:Nnn #1#2#3
+ {
+ \prg_new_protected_conditional:Npnn #1 ##1##2##3 {T,F,TF}
+ {
+ \xsim_if_in_list:nnTF {##3} {##1-##2=={true}}
+ {
+ \__xsim_printsolutions_if_condition:nTF {#2}
+ { \__xsim_printsolutions_condition_true: #3 }
+ { \prg_return_false: }
+ }
+ { \prg_return_false: }
+ }
+ }
+
+% per section condition:
+\xsim_new_solutions_condition:Nnn \__xsim_if_solutions_per_section:nnn
+ {per-section}
+ {
+ \xsim_if_in_list:nxTF {section-value}
+ { #1-#2 == { \int_use:N \l_xsim_printsolutions_section_int } }
+ {
+ \tl_set:Nx \ExerciseSection
+ { \xsim_get_property:nnn {#1} {#2} {section} }
+ \prg_return_true:
+ }
+ { \prg_return_false: }
+ }
+
+% per chapter condition:
+\xsim_new_solutions_condition:Nnn \__xsim_if_solutions_per_chapter:nnn
+ {per-chapter}
+ {
+ \xsim_if_in_list:nxTF {chapter-value}
+ { #1-#2 == { \int_use:N \l_xsim_printsolutions_chapter_int } }
+ {
+ \tl_set:Nx \ExerciseChapter
+ { \xsim_get_property:nnn {#1} {#2} {chapter} }
+ \prg_return_true:
+ }
+ { \prg_return_false: }
+ }
+
+% per collection condition:
+\xsim_new_solutions_condition:Nnn \__xsim_if_solutions_in_collection:nnn
+ {per-collection}
+ {
+ \tl_if_blank:VTF \l__xsim_printsolutions_collection_tl
+ { \prg_return_false: }
+ {
+ \xsim_if_in_collection:VnnTF
+ \l__xsim_printsolutions_collection_tl
+ {#1}
+ {#2}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+ }
+
+% ----------------------------------------------------------------------------
+% conditions mechanism
+\cs_new_protected:Npn \__xsim_printsolutions_condition_false:
+ { \bool_set_false:N \l__xsim_printsolutions_conditions_bool }
+
+\cs_new_protected:Npn \__xsim_printsolutions_condition_true:
+ { \bool_set_true:N \l__xsim_printsolutions_conditions_bool }
+
+% #1: type
+% #2: id
+% #3: boolean property
+\prg_new_conditional:Npnn
+ \__xsim_printsolutions_if_conditions:nnn #1#2#3 {T,F,TF}
+ {
+ \bool_if:NTF \l__xsim_printsolutions_conditions_bool
+ { \prg_return_true: }
+ {
+ \xsim_if_in_list:nnTF {#3} {#1-#2=={true}}
+ { \prg_return_false: }
+ { \prg_return_true: }
+ }
+ }
+
+% #1: name
+% #2: condition
+\cs_new_protected:Npn \xsim_declare_printsolutions_condition:nn #1#2
+ {
+ \bool_new:c {l__xsim_printsolutions_#1_condition_bool}
+ \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}
+ {
+ \bool_if:cTF {l__xsim_printsolutions_#1_condition_bool}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+
+% #1: name
+% #2: true|false
+\cs_new_protected:Npn \__xsim_printsolutions_condition:nn #1#2
+ { \bool_set_eq:cc {l__xsim_printsolutions_#1_condition_bool} {c_#2_bool} }
+
+% false if any condition is false for this solution:
+% #1: type
+% #2: id
+% #3: boolean property
+\prg_new_protected_conditional:Npnn
+ \__xsim_printsolutions_check_conditions:nnn #1#2#3 {T,F,TF}
+ {
+ \__xsim_printsolutions_condition_false:
+ \bool_set_true:N \l____xsim_this_condition_bool
+ \seq_map_inline:Nn \l__xsim_printsolutions_conditions_seq
+ {
+ \bool_if:cT {l__xsim_printsolutions_##1_condition_bool}
+ {
+ \xsim_attribute_get:nn {printsolutions} {##1}
+ {#1} {#2} {#3}
+ { }
+ { \bool_set_false:N \l____xsim_this_condition_bool }
+ }
+ }
+ \bool_if:NTF \l____xsim_this_condition_bool
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+
+
+% #1: type
+% #2: id
+% #3: boolean property
+% #4: code
+\cs_new_protected:Npn \xsim_if_this_solution_do:nnnn #1#2#3#4
+ {
+ \xsim_if_solution_exist:nnT {#1} {#2}
+ { \__xsim_printsolutions_check_conditions:nnnT {#1} {#2} {#3} {#4} }
+ }
+\cs_generate_variant:Nn \xsim_if_this_solution_do:nnnn {nV}
+
+% #1: type
+% #2: boolean property
+% #3: code
+\cs_new_protected:Npn \xsim_if_solutions_do:nnn #1#2#3
+ {
+ \xsim_foreach_exercise:nn {#2}
+ {
+ \str_if_eq:nnT {#1} {##1}
+ {
+ \xsim_if_this_solution_do:nnnn
+ {#1}
+ {##2}
+ {#2}
+ {#3}
+ }
+ }
+ }
+\cs_generate_variant:Nn \str_if_eq:nnT {nV}
+
+% ----------------------------------------------------------------------------
+% #1: boolean -- if true only the solutions of printed exercises will be
+% output
+% #2: pre
+% #3: post
+% #4: type
+% #5: code (refer to type with #1 and id with #2)
+\cs_new_protected:Npn \xsim_print_type_code:nnnnn #1#2#3#4#5
+ {
+ \group_begin:
+ \cs_set_protected:Npn \__xsim_print_entry:nn ##1##2 {#5}
+ #2
+ \bool_set_false:N \l__xsim_tmpa_bool
+ \bool_if:nTF {#1}
+ {
+ \xsim_if_solutions_do:nnn {#4} {printed}
+ { \bool_set_true:N \l__xsim_tmpa_bool }
+ }
+ {
+ \xsim_if_solutions_do:nnn {#4} {used}
+ { \bool_set_true:N \l__xsim_tmpa_bool }
+ }
+ \tl_set:Nn \ExerciseType {#4}
+ \bool_if:NT \l__xsim_tmpa_bool
+ {
+ \bool_if:NT \l__xsim_printsolutions_headings_bool
+ {
+ \xsim_use_template:nV
+ {heading}
+ \l__xsim_printsolutions_headings_template_tl
+ }
+ }
+ \bool_if:nTF {#1}
+ {
+ \xsim_if_solutions_do:nnn {#4} {printed}
+ { \__xsim_print_entry:nn {#4} {##2} }
+ }
+ {
+ \xsim_if_solutions_do:nnn {#4} {used}
+ { \__xsim_print_entry:nn {#4} {##2} }
+ }
+ #3
+ \group_end:
+ }
+
+% #1: boolean -- if true only the solutions of printed exercises will be
+% output
+% #2: options
+% #3: type
+\cs_new_protected:Npn \xsim_print_type_solutions:nnn #1#2#3
+ {
+ \xsim_print_type_code:nnnnn
+ {#1}
+ {
+ \xsim_verbose:n
+ { Printing~ solutions~ for~ exercise~ type~ `#3'. }
+ \keys_set:nn {xsim/print-solutions} {#2}
+ }
+ {}
+ {#3}
+ { \xsim_insert:nnnn {##1} {##2} {} {solution} }
+ }
+
+% #1: boolean -- if true only the solutions of printed exercises will be
+% output
+% #2: options
+\cs_new_protected:Npn \xsim_print_all_solutions_per_type:nn #1#2
+ {
+ \xsim_foreach_exercise_type:n
+ { \xsim_print_type_solutions:nnn {#1} {#2} {##1} }
+ }
+
+% #1: boolean -- if true only the solutions of printed exercises will be
+% output
+% #2: options
+\cs_new_protected:Npn \xsim_print_all_solutions_per_id:nn #1#2
+ {
+ \xsim_verbose:n { Printing~ solutions. }
+ \group_begin:
+ \keys_set:nn {xsim/print-solutions} {#2}
+ \bool_set_false:N \l__xsim_tmpa_bool
+ \bool_if:nTF {#1}
+ {
+ \xsim_foreach_exercise_id_type:nn {print}
+ {
+ \xsim_if_this_solution_do:nnnn {##1} {##2} {print}
+ { \xsim_insert:nnnn {##1} {##2} {} {solution} }
+ }
+ }
+ {
+ \xsim_foreach_exercise_id_type:nn {used}
+ {
+ \xsim_if_this_solution_do:nnnn {##1} {##2} {used}
+ { \xsim_insert:nnnn {##1} {##2} {} {solution} }
+ }
+ }
+ \group_end:
+ }
+
+% ----------------------------------------------------------------------------
+
+\xsim_declare_printsolutions_condition:nn {per-section}
+ { \__xsim_if_solutions_per_section:nnnTF }
+\xsim_declare_printsolutions_condition:nn {per-chapter}
+ { \__xsim_if_solutions_per_chapter:nnnTF }
+\xsim_declare_printsolutions_condition:nn {per-collection}
+ { \__xsim_if_solutions_in_collection:nnnTF }
+
+% ----------------------------------------------------------------------------
+
+\keys_define:nn {xsim/print-solutions}
+ {
+ headings .bool_set:N = \l__xsim_printsolutions_headings_bool ,
+ headings .initial:n = true ,
+ headings-template .tl_set:N = \l__xsim_printsolutions_headings_template_tl ,
+ headings-template .initial:n = default ,
+ include-exercise .bool_set:N = \l__xsim_include_question_bool ,
+ include-exercise .initial:n = false ,
+ section .choice: ,
+ section/true .code:n =
+ \__xsim_printsolutions_condition:nn {per-section} {true}
+ \int_set:Nn \l_xsim_printsolutions_section_int { \value {section} } ,
+ section/false .code:n =
+ \__xsim_printsolutions_condition:nn {per-section} {false} ,
+ section/unknown .code:n =
+ \__xsim_printsolutions_condition:nn {per-section} {true}
+ \int_set:Nn \l_xsim_printsolutions_section_int {#1} ,
+ section .default:n = true ,
+ section .initial:n = false ,
+ chapter .choice: ,
+ chapter/true .code:n =
+ \__xsim_printsolutions_condition:nn {per-chapter} {true}
+ \int_set:Nn \l_xsim_printsolutions_chapter_int { \value {chapter} } ,
+ chapter/false .code:n =
+ \__xsim_printsolutions_condition:nn {per-chapter} {false} ,
+ chapter/unknown .code:n =
+ \__xsim_printsolutions_condition:nn {per-chapter} {true}
+ \int_set:Nn \l_xsim_printsolutions_chapter_int {#1} ,
+ chapter .default:n = true ,
+ chapter .initial:n = false ,
+ collection .choice: ,
+ collection/false .code:n =
+ \__xsim_printsolutions_condition:nn {per-collection} {false} ,
+ collection/unknown .code:n =
+ \xsim_if_collection_exist:nT {#1}
+ {
+ \__xsim_printsolutions_condition:nn {per-collection} {true}
+ \tl_set:Nn \l__xsim_printsolutions_collection_tl {#1}
+ } ,
+ collection .initial:n = false
+ }
+
+\XSIMmoduleend
+\XSIMmodule{collections}{collect exercises and print collected exercises}
+
+\seq_new:N \g__xsim_collections_seq
+\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-unknown}
+ {
+ The~ collection~ `#1'~ does~ not~ seem~ to~ exist~ \msg_line_context: .
+ If~ this~ is~ not¨ a~ typo~ define~ it~ first.
+ }
+
+\msg_new:nnn {xsim} {collection-activate}
+ {
+ The~ collection~ `#1'~ is~ already~ active~ \msg_line_context: .~
+ Not~ activating~ it~ now.
+ }
+
+\msg_new:nnn {xsim} {collection-deactivate}
+ {
+ The~ collection~ `#1'~ is~ not~ active~ \msg_line_context: .~
+ Not~ deactivating~ it~ now.
+ }
+
+\msg_new:nnn {xsim} {print-collection-choice}
+ {
+ The~ choice~ `#1'~ neither~ exists~ for~ `print-collection/print'~ nor~
+ for~ `random/print'.~ I'm~ using~ `exercises'~ instead~ \msg_line_context: .
+ }
+
+% ----------------------------------------------------------------------------
+\xsim_declare_property:nnnn
+ { \c_false_bool }
+ { \c_false_bool }
+ { \c_false_bool }
+ {collections}
+
+% #1: collection name
+% #2: conditions: clist of <tag>=<value>
+\cs_new_protected:Npn \xsim_new_collection:nn #1#2
+ {
+ \xsim_if_collection_exist:nTF {#1}
+ { \msg_error:nnn {xsim} {collection-exists} {#1} }
+ {
+ \xsim_verbose:n { Declaring~ new~ collection~ `#1'. }
+ \xsim_attribute_new:nn {collection} {#1}
+ \xsim_attribute_set:nnn {collection} {#1} { \c_false_bool }
+ \xsim_attribute_new:nn {collection:conditions} {#1}
+ \xsim_attribute_set:nnn {collection:conditions} {#1} {#2}
+ \seq_gput_right:Nn \g__xsim_collections_seq {#1}
+ \xsim_new_list:n {collection:#1}
+ \xsim_at_end_document:n
+ { \xsim_update_list:n {collection:#1} }
+ }
+ }
+
+% #1: collection name
+\prg_new_conditional:Npnn \xsim_if_collection_exist:n #1 {T,F,TF}
+ {
+ \seq_if_in:NnTF \g__xsim_collections_seq {#1}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+
+\cs_new_protected:Npn \xsim_foreach_collection:n #1
+ { \seq_map_inline:Nn \g__xsim_collections_seq {#1} }
+
+\cs_new:Npn \xsim_collection_map_break: { \seq_map_break: }
+
+% ----------------------------------------------------------------------------
+% #1: collection name
+\prg_new_conditional:Npnn \xsim_if_collection_active:n #1 {T,F,TF}
+ {
+ \xsim_attribute_if_set:nnTF {collection} {#1}
+ {
+ \bool_if:nTF
+ { \xsim_attribute_get:nn {collection} {#1} }
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+ { \prg_return_false: }
+ }
+
+% #1: collection name
+\cs_new_protected:Npn \xsim_activate_collection:n #1
+ {
+ \xsim_if_collection_exist:nTF {#1}
+ {
+ \xsim_if_collection_active:nTF {#1}
+ { \msg_warning:nnn {xsim} {collection-activate} {#1} }
+ {
+ \xsim_verbose:n { Activating~ collection~ `#1'. }
+ \xsim_attribute_set:nnn {collection} {#1} { \c_true_bool }
+ }
+ }
+ { \msg_error:nnn {xsim} {collection-unknown} {#1} }
+ }
+
+% #1: collection name
+\cs_new_protected:Npn \xsim_deactivate_collection:n #1
+ {
+ \xsim_if_collection_exist:nTF {#1}
+ {
+ \xsim_if_collection_active:nTF {#1}
+ {
+ \xsim_verbose:n { Deactivating~ collection~ `#1'. }
+ \xsim_attribute_set:nnn {collection} {#1} { \c_false_bool }
+ }
+ { \msg_warning:nnn {xsim} {collection-deactivate} {#1} }
+ }
+ { \msg_error:nnn {xsim} {collection-unknown} {#1} }
+ }
+
+% #1: csv list of collections
+% #2: type
+\cs_new_protected:Npn \xsim_collect_type_start:nn #1#2
+ {
+ \group_begin:
+ \keys_set:nn {xsim} { #2/collect = true }
+ \clist_map_inline:nn {#1}
+ {
+ \xsim_if_collection_active:nF {##1}
+ { \xsim_activate_collection:n {##1} }
+ }
+ }
+
+% #1: csv list of collections
+\cs_new_protected:Npn \xsim_collect_start:n #1
+ {
+ \group_begin:
+ \xsim_foreach_exercise_type:n
+ {
+ \keys_set:nx {xsim}
+ { \xsim_get_parameter:nn {##1} {exercise-env} / collect = true }
+ }
+ \clist_map_inline:nn {#1}
+ {
+ \xsim_if_collection_active:nF {##1}
+ { \xsim_activate_collection:n {##1} }
+ }
+ }
+
+% #1: csv list of collections
+\cs_new_protected:Npn \xsim_collect_stop:n #1
+ {
+ \clist_map_inline:nn {#1} { \xsim_deactivate_collection:n {##1} }
+ \group_end:
+ }
+
+\keys_define:nn {xsim}
+ {
+ collect .code:n =
+ \xsim_foreach_exercise_type:n
+ {
+ \keys_set:nx {xsim}
+ { \xsim_get_parameter:nn {##1} {exercise-env} / collect = #1 }
+ } ,
+ collect .default:n = true ,
+ collect .initial:n = false
+ }
+
+% ----------------------------------------------------------------------------
+% #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}
+
+\cs_new:Npn \xsim_collection_count:n #1
+ { \xsim_list_count:n {collection:#1} }
+
+\bool_new:N \l____xsim_collection_condition_bool
+
+% #1: collection name
+% #2: type
+% #3: ID
+\prg_new_protected_conditional:Npnn \xsim_collection_conditions_if:nnn #1#2#3 {T,F,TF}
+ {
+ \bool_set_false:N \l____xsim_collection_condition_bool
+ \clist_set:Nx \l__xsim_tmpa_clist
+ { \xsim_attribute_get:nn {collection:conditions} {#1} }
+ \clist_if_empty:NTF \l__xsim_tmpa_clist
+ { \bool_set_true:N \l____xsim_collection_condition_bool }
+ {
+ \clist_map_inline:Vn
+ \l__xsim_tmpa_clist
+ {
+ \tl_set:Nx \l__xsim_tmpa_tl
+ { \__xsim_get_condition_tag:w ##1 \q_stop }
+ \tl_set:Nx \l__xsim_tmpb_tl
+ { \__xsim_get_condition_values:w ##1 \q_stop }
+ \xsim_if_tag_type_exist:VTF \l__xsim_tmpa_tl
+ {
+ \xsim_has_tags:nnVVT {#2} {#3} \l__xsim_tmpa_tl \l__xsim_tmpb_tl
+ {
+ \bool_set_true:N \l____xsim_collection_condition_bool
+ \clist_map_break:
+ }
+ }
+ { \msg_warning:nnV {xsim} {tag-unknown} \l__xsim_tmpa_tl }
+ }
+ }
+ \bool_if:NTF \l____xsim_collection_condition_bool
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+
+\cs_new:Npn \__xsim_get_condition_tag:w #1=#2 \q_stop {#1}
+\cs_new:Npn \__xsim_get_condition_values:w #1=#2 \q_stop {#2}
+
+% #1: type
+% #2: ID
+\cs_new_protected:Npn \xsim_collect:nn #1#2
+ {
+ \xsim_foreach_collection:n
+ {
+ \xsim_if_collection_active:nT {##1}
+ {
+ \xsim_collection_conditions_if:nnnT {##1} {#1} {#2}
+ { \xsim_add_to_collection:nnn {##1} {#1} {#2} }
+ }
+ }
+ }
+\cs_generate_variant:Nn \xsim_collect:nn {nV}
+
+% #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'. }
+ \clist_set:Nx \l__xsim_tmpa_clist
+ { \xsim_get_property:nnn {#2} {#3} {collections} }
+ \clist_if_in:NnF \l__xsim_tmpa_clist {#1}
+ { \clist_put_right:Nn \l__xsim_tmpa_clist {#1} }
+ \xsim_set_property:nnnV {#2} {#3} {collections} \l__xsim_tmpa_clist
+ \xsim_add_to_list:nn {collection:#1} {#2-#3}
+ }
+
+% ----------------------------------------------------------------------------
+\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 .tl_set:N = \l__xsim_print_collection_choice_tl ,
+ print .initial:n = exercises
+ }
+
+% #1: options
+% #2: collection name
+\cs_new_protected:Npn \xsim_print_collection:nn #1#2
+ {
+ \group_begin:
+ \keys_set:nn {xsim/print-collection} {#1}
+ \clist_clear:N \l__xsim_tmpa_clist
+ \clist_clear:N \l__xsim_tmpb_clist
+ \xsim_foreach_exercise_type_id:nn {}
+ {
+ \xsim_get_property_if_set:nnnT {##1} {##2} {collections}
+ {
+ \clist_if_in:NnT \l_xsim_property_value_tl {#2}
+ {
+ \str_set:Nn \l__xsim_tmpa_str {##1}
+ \clist_put_right:NV \l__xsim_tmpa_clist \l__xsim_tmpa_str
+ \clist_put_right:Nn \l__xsim_tmpb_clist {##2}
+ }
+ }
+ }
+ \xsim_foreach_exercise_type:n
+ {
+ \bool_if:NT \l__xsim_printcollection_headings_bool
+ {
+ \clist_if_in:NnT \l__xsim_tmpa_clist {##1}
+ {
+ \tl_set:Nn \ExerciseType {##1}
+ \xsim_use_template:nV
+ {heading}
+ \l__xsim_printcollection_headings_template_tl
+ }
+ }
+ \clist_map_inline:Nn \l__xsim_tmpa_clist
+ {
+ \str_if_eq:nnT {##1} {####1}
+ {
+ \clist_pop:NN \l__xsim_tmpa_clist \l__xsim_tmpa_tl
+ \clist_pop:NN \l__xsim_tmpb_clist \l__xsim_tmpb_tl
+ \str_case:Vn \l__xsim_print_collection_choice_tl
+ {
+ {exercises} { \xsim_insert:nVnn {##1} \l__xsim_tmpb_tl {} {exercise} }
+ {solutions} { \xsim_insert:nVnn {##1} \l__xsim_tmpb_tl {} {solution} }
+ {both} {
+ \xsim_insert:nVnn {##1} \l__xsim_tmpb_tl {} {exercise}
+ \xsim_insert:nVnn {##1} \l__xsim_tmpb_tl {} {solution}
+ }
+ }
+ }
+ }
+ }
+ \group_end:
+ }
+
+% ----------------------------------------------------------------------------
+\xsim_new_collection:nn {all~ exercises} {}
+\xsim_activate_collection:n {all~ exercises}
+
+\XSIMmoduleend
+\XSIMmodule{blanks}{add blanks, cloze}
+
+\bool_new:N \l__xsim_blank_width_bool
+\bool_new:N \l__xsim_blank_linespread_bool
+\bool_new:N \l__xsim_fill_blank_bool
+\tl_new:N \l__xsim_blank_linespread_tl
+\tl_new:N \l__xsim_blank_scale_tl
+\dim_new:N \l__xsim_blank_dim
+\dim_new:N \l__xsim_blank_line_increment_dim
+\dim_new:N \l__xsim_blank_line_minimum_length_dim
+\box_new:N \l__xsim_blank_box
+
+\cs_new_protected:Npn \xsim_write_cloze_blank:n #1 {#1}
+\cs_new_protected:Npn \xsim_write_cloze_filled:n #1 {#1}
+
+\keys_define:nn {xsim/blank}
+ {
+ blank-style .code:n =
+ \cs_set_protected:Npn \xsim_write_cloze_blank:n ##1 {#1} ,
+ blank-style .initial:n = \underline {#1} ,
+ filled-style .code:n =
+ \cs_set_protected:Npn \xsim_write_cloze_filled:n ##1 {#1} ,
+ filled-style .initial:n = \underline {#1} ,
+ style .meta:n =
+ {
+ blank-style = #1 ,
+ filled-style = #1
+ } ,
+ fill .bool_set:N = \l__xsim_fill_blank_bool ,
+ fill .initial:n = false ,
+ scale .tl_set:N = \l__xsim_blank_scale_tl ,
+ scale .initial:n = 1 ,
+ width .code:n =
+ {
+ \bool_set_true:N \l__xsim_blank_width_bool
+ \dim_set:Nn \l__xsim_blank_dim {#1}
+ } ,
+ linespread .code:n =
+ \bool_set_true:N \l__xsim_blank_linespread_bool
+ \tl_set:Nn \l__xsim_blank_linespread_tl {#1} ,
+ linespread .initial:n = 1 ,
+ line-increment .dim_set:N = \l__xsim_blank_line_increment_dim ,
+ line-increment .initial:n = 0.001\linewidth ,
+ line-minimum-length .dim_set:N = \l__xsim_blank_line_minimum_length_dim ,
+ line-minimum-length .initial:n = 2em
+ }
+
+\cs_new_protected:Npn \xsim_blank:n #1
+ {
+ \box_clear:N \l__xsim_blank_box
+ \mode_if_math:TF
+ { \hbox_set:Nn \l__xsim_blank_box { $ \m@th \mathpalette{}{#1} $ } }
+ { \hbox_set:Nn \l__xsim_blank_box {#1} }
+ \bool_lazy_or:nnTF
+ { \xsim_if_inside_solution_p: }
+ { \l__xsim_fill_blank_bool }
+ { \xsim_write_cloze_filled:n {#1} }
+ {
+ \bool_if:NTF \l__xsim_blank_width_bool
+ { \__xsim_blank_skip:V \l__xsim_blank_dim }
+ { \__xsim_blank_skip:n { \box_wd:N \l__xsim_blank_box } }
+ }
+ }
+
+\cs_new_protected:Npn \__xsim_blank_skip:n #1
+ {
+ \bool_if:NTF \l__xsim_blank_width_bool
+ { \dim_set:Nn \l__xsim_tmpa_dim {#1} }
+ {
+ \fp_set:Nn \l__xsim_tmpa_fp
+ { \dim_to_fp:n {#1} * \l__xsim_blank_scale_tl }
+ \dim_set:Nn \l__xsim_tmpa_dim { \fp_to_dim:N \l__xsim_tmpa_fp }
+ }
+ \dim_compare:nTF
+ { \l__xsim_tmpa_dim > \l__xsim_blank_line_minimum_length_dim }
+ {
+ \mode_if_math:TF
+ { \xsim_write_cloze_blank:n { \skip_horizontal:N \l__xsim_tmpa_dim } }
+ {
+ \dim_do_while:nn { \l__xsim_tmpa_dim > \c_zero_dim }
+ {
+ % I wonder what the correct l3 way would be -- if there is
+ % one, yet:
+ % \tex_hfil:D
+ \tex_penalty:D \hyphenpenalty
+ % \tex_hfilneg:D
+ \dim_compare:nTF
+ { \l__xsim_tmpa_dim < \l__xsim_blank_line_increment_dim }
+ { \xsim_write_cloze_blank:n { \skip_horizontal:N \l__xsim_tmpa_dim } }
+ {
+ \xsim_write_cloze_blank:n
+ { \skip_horizontal:N \l__xsim_blank_line_increment_dim }
+ }
+ \dim_sub:Nn \l__xsim_tmpa_dim { \l__xsim_blank_line_increment_dim }
+ }
+ }
+ }
+ {
+ \xsim_write_cloze_blank:n
+ { \skip_horizontal:N \l__xsim_blank_line_minimum_length_dim }
+ }
+ }
+\cs_generate_variant:Nn \__xsim_blank_skip:n {V}
+
+\XSIMmoduleend
+\XSIMmodule{grades}{distribute goal sums to grades}
+
+\msg_new:nnn {xsim} {grade-unknown}
+ { The~ grade~ `#1'~ has~ never~ been~ declared~ \msg_line_context: }
+
+\bool_new:N \l__xsim_grades_half_bool
+\fp_new:N \l__xsim_grade_round_fp
+\fp_zero:N \l__xsim_grade_round_fp
+\prop_new:N \l__xsim_relative_grades_prop
+\tl_new:N \l__xsim_grade_split_tl
+
+\cs_new:Npn \__xsim_fp_round_to_half:n #1
+ { round( 2*(#1),0)/2 }
+
+\cs_new:Npn \__xsim_grades_round:n #1
+ { round ( #1 , \l__xsim_grade_round_fp ) }
+
+% #1: factor
+% #2: goal sum
+\cs_new:Npn \__xsim_grade_rounded:nn #1#2
+ {
+ \bool_if:NTF \l__xsim_grades_half_bool
+ { \__xsim_fp_round_to_half:n }
+ { \__xsim_grades_round:n }
+ { (#1) * (#2) }
+ }
+
+\cs_new_protected:Npn \xsim_declare_relative_grades:n #1
+ {
+ \seq_set_split:NVn \l__xsim_tmpa_seq \l__xsim_grade_split_tl {#1}
+ \seq_map_inline:Nn \l__xsim_tmpa_seq
+ { \__xsim_declare_relative_grade:w ##1 \q_stop }
+ \xsim_verbose:n {Declaring~ relative~ grade~ distribution}
+ }
+
+\cs_new_protected:Npn \__xsim_declare_relative_grade:w #1 = #2 \q_stop
+ {
+ \tl_set:Nx \l__xsim_tmpa_tl { \tl_trim_spaces:n {#1} }
+ \tl_set:Nx \l__xsim_tmpb_tl { \tl_trim_spaces:n {#2} }
+ \prop_put:NVV \l__xsim_relative_grades_prop
+ \l__xsim_tmpa_tl
+ \l__xsim_tmpb_tl
+ }
+
+% #1: grade
+% #2: sum of points
+% #3: code after grade requirement if == 1
+% #4: code after grade requirement if != 1
+\cs_new_protected:Npn \xsim_get_grade:nnnn #1#2#3#4
+ {
+ \prop_get:NnNTF \l__xsim_relative_grades_prop {#1} \l__xsim_tmpa_tl
+ {
+ \xsim_print_goal:nnn
+ {
+ min(
+ \__xsim_grade_rounded:nn
+ { \l__xsim_tmpa_tl }
+ {#2} ,
+ #2
+ )
+ }
+ {#3}
+ {#4}
+ }
+ { \msg_error:nnn {xsim} {grade-unknown} {#1} }
+ }
+
+% #1: grade
+% #2: goal
+% #3: code after grade requirement if == 1
+% #4: code after grade requirement if != 1
+\cs_new_protected:Npn \xsim_get_grade_goal:nnnn #1#2#3#4
+ {
+ \xsim_if_goal_exist:nTF {#2}
+ {
+ \xsim_get_grade:nnnn
+ {#1}
+ { \use:c {g__xsim_total_goal_#2_fp} }
+ {#3}
+ {#4}
+ }
+ { \msg_error:nnn {xsim} {goal-unknown} {#2} }
+ }
+
+% #1: grade
+% #2: goal list (separated with +)
+% #3: code after grade requirement if == 1
+% #4: code after grade requirement if != 1
+\cs_new_protected:Npn \xsim_get_grade_requirement:nnnn #1#2#3#4
+ {
+ \seq_set_split:Nnn \l__xsim_tmpa_seq {+} {#2}
+ \fp_zero:N \l__xsim_tmpa_fp
+ \seq_map_inline:Nn \l__xsim_tmpa_seq
+ {
+ \fp_add:Nn \l__xsim_tmpa_fp
+ { \use:c {g__xsim_total_goal_\tl_trim_spaces:n {##1} _fp} }
+ }
+ \xsim_get_grade:nnnn {#1} { \l__xsim_tmpa_fp } {#3} {#4}
+ }
+
+% #1: grade
+% #2: code after grade requirement if == 1
+% #3: code after grade requirement if != 1
+\cs_new_protected:Npn \xsim_get_absolute_grade_requirement:nnn #1#2#3
+ {
+ \fp_zero:N \l__xsim_tmpa_fp
+ \xsim_foreach_goal:n
+ {
+ \fp_add:Nn \l__xsim_tmpa_fp
+ { \use:c {g__xsim_total_goal_##1_fp} }
+ }
+ \xsim_get_grade:nnnn {#1} { \l__xsim_tmpa_fp } {#2} {#3}
+ }
+
+\keys_define:nn {xsim/grades}
+ {
+ round .fp_set:N = \l__xsim_grade_round_fp ,
+ half .bool_set:N = \l__xsim_grades_half_bool ,
+ split .tl_set:N = \l__xsim_grade_split_tl ,
+ split .initial:n = {,}
+ }
+
+\XSIMmoduleend
+\XSIMmodule{random}{randomly select exercises from collections}
+
+\msg_new:nnn {xsim} {random-numbers-unavailable}
+ {
+ You~ are~ compiling~ your~ document~ using ~XeLaTeX.~ Please~ be~ aware~
+ that~ random~ selection~ of~ exercises~ is~ unavailable~ in~ XeLaTeX.~ If~
+ you~ use~ this~ feature~ you~ can~ safely~ ignore~ this~ message.
+ }
+
+\sys_if_engine_xetex:T
+ { \msg_warning:nn {xsim} {random-numbers-unavailable} }
+
+\tl_new:N \l_xsim_random_collection_tl
+\tl_new:N \l__xsim_print_random_choice_tl
+\seq_new:N \g__xsim_random_list_seq
+\seq_new:N \l__xsim_allowed_exercise_ids_seq
+\int_new:N \g__xsim_random_list_id_int
+\bool_new:N \l__xsim_sort_random_bool
+\clist_new:N \l_xsim_random_exclude_list_clist
+
+% #1: random list id
+% #2: csv list of integers
+\xsim_new_aux_property:cpn {random} #1#2
+ {
+ \xsim_random_list_if_exist:nF {#1}
+ { \xsim_new_random_list:n {#1} }
+ \xsim_set_random_list:nn {#1} {#2}
+ }
+
+\cs_new_protected:Npn \xsim_new_random_list:n #1
+ {
+ \xsim_verbose:n {Defining~ new~ random~ list~ `#1'}
+ \seq_new:c {g__xsim_random_#1 _seq}
+ }
+
+\cs_new_protected:Npn \xsim_set_random_list:nn #1#2
+ { \seq_gset_from_clist:cn {g__xsim_random_#1_seq} {#2} }
+
+\cs_new_protected:Npn \xsim_set_random_list_from_seq:nN #1#2
+ { \seq_gset_eq:cN {g__xsim_random_#1_seq} #2 }
+
+\cs_new:Npn \xsim_use_random_list:nn #1#2
+ { \seq_use:cn {g__xsim_random_#1_seq} {#2} }
+
+\cs_new_protected:Npn \xsim_map_random_list:nn #1#2
+ { \seq_map_inline:cn {g__xsim_random_#1_seq} {#2} }
+
+\prg_new_conditional:Npnn \xsim_random_list_if_exist:n #1 {p,T,F,TF}
+ {
+ \seq_if_exist:cTF {g__xsim_random_#1_seq}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+
+\prg_new_conditional:Npnn \xsim_random_list_if_empty:n #1 {p,T,F,TF}
+ {
+ \seq_if_empty:cTF {g__xsim_random_#1_seq}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+
+% #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}
+ { \xsim_set_random_list_from_seq:nN {#1} #2 }
+ \xsim_verbose:n {Saving~ random~ list~ `#1'}
+ \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
+% #3: clist variable of excluded ids
+\cs_new_protected:Npn \xsim_print_random_list:nnN #1#2#3
+ {
+ \xsim_if_collection_exist:nTF {#1}
+ {
+ \int_gincr:N \g__xsim_random_list_id_int
+ \int_compare:nNnTF { \xsim_collection_count:n {#1} } = {0}
+ {
+ % TODO: message
+ \xsim_rerun:
+ }
+ {
+ % generate seq of allowed ids from collection:
+ \xsim_foreach_exercise_id:n
+ {
+ \xsim_get_type_for_id:nN {##1} \l__xsim_tmpa_str
+ \tl_set_rescan:Nnx \l__xsim_tmpa_tl {} { \l__xsim_tmpa_str }
+ \xsim_if_in_collection:nVnT {#1} \l__xsim_tmpa_tl {##1}
+ {
+ \clist_if_in:NnF #3 {##1}
+ { \seq_put_right:Nn \l__xsim_allowed_exercise_ids_seq {##1} }
+ }
+ }
+ \int_compare:nNnTF
+ {#2}
+ >
+ { \seq_count:N \l__xsim_allowed_exercise_ids_seq }
+ {
+ \int_set:Nn \l__xsim_tmpa_int
+ { \seq_count:N \l__xsim_allowed_exercise_ids_seq }
+ }
+ { \int_set:Nn \l__xsim_tmpa_int {#2} }
+ % generate random list:
+ \xsim_generate_random_list:nnnN
+ { \int_to_alph:n { \g__xsim_random_list_id_int } }
+ { \seq_count:N \l__xsim_allowed_exercise_ids_seq }
+ { \l__xsim_tmpa_int }
+ \g__xsim_random_list_seq
+ }
+ \xsim_save_random_list:xN
+ { \int_to_alph:n { \g__xsim_random_list_id_int } }
+ \g__xsim_random_list_seq
+ \xsim_verbose:x
+ {
+ Printing~ exercises~ of~ random~ list~
+ `\int_to_alph:n { \g__xsim_random_list_id_int }'~ of~
+ collection~ `#1'
+ }
+ \xsim_print_random_exercises:Nn
+ \l__xsim_allowed_exercise_ids_seq
+ { \int_to_alph:n { \g__xsim_random_list_id_int } }
+ }
+ { \msg_error:nnn {xsim} {unknown-collection} {#1} }
+ }
+\cs_generate_variant:Nn \xsim_print_random_list:nnN {V}
+
+% #1: random list id
+% #2: max number to choose from
+% #3: number of items
+% #4: seq variable
+\cs_new_protected:Npn \xsim_generate_random_list:nnnN #1#2#3#4
+ {
+ \bool_lazy_or:nnT
+ { !\xsim_random_list_if_exist_p:n {#1} }
+ { \xsim_random_list_if_empty_p:n {#1} }
+ {
+ \xsim_verbose:n
+ {Generating~ random~ list~ `#1'~ with~ #3~ out~ of~ #2~ items}
+ \seq_gclear:N #4
+ \int_compare:nNnF {#2} = 0
+ {
+ \int_do_until:nNnn { \seq_count:N #4 } = {#3}
+ {
+ \tl_set:Nx \l__xsim_tmpa_tl
+ { \fp_eval:n { randint(#2) } }
+ \seq_if_in:NVF #4
+ \l__xsim_tmpa_tl
+ { \seq_gput_right:NV #4 \l__xsim_tmpa_tl }
+ }
+ }
+ \bool_if:NT \l__xsim_sort_random_bool
+ {
+ \seq_gsort:Nn #4
+ {
+ \int_compare:nNnTF {##1} > {##2}
+ { \sort_return_swapped: }
+ { \sort_return_same: }
+ }
+ }
+ }
+ }
+
+% #1: seq variable of ids
+% #2: random list id
+\cs_new_protected:Npn \xsim_print_random_exercises:Nn #1#2
+ {
+ \seq_if_empty:NF #1
+ {
+ \bool_lazy_and:nnT
+ { \xsim_random_list_if_exist_p:n {#2} }
+ { !\xsim_random_list_if_empty_p:n {#2} }
+ {
+ \xsim_verbose:x
+ {
+ Printing~
+ \str_case:Vn \l__xsim_print_random_choice_tl
+ {
+ {exercises} {exercises~}
+ {solutions} {solutions~}
+ {both} { exercises~ and~ solutions~ }
+ }
+ of~ random~ list~ `#2'.
+ }
+ \xsim_map_random_list:nn {#2}
+ {
+ \tl_set:Nx \l__xsim_tmpa_tl
+ { \seq_item:Nn #1 {##1} }
+ \tl_set:Nx \l__xsim_tmpb_tl
+ { \xsim_get_type_for_property:nV {id} \l__xsim_tmpa_tl }
+ \bool_set_false:N \l__xsim_tmpa_bool
+ \bool_set_false:N \l__xsim_tmpb_bool
+ \str_case:VnF \l__xsim_print_random_choice_tl
+ {
+ {exercises} { \bool_set_true:N \l__xsim_tmpa_bool }
+ {solutions} { \bool_set_true:N \l__xsim_tmpb_bool }
+ {both} {
+ \bool_set_true:N \l__xsim_tmpa_bool
+ \bool_set_true:N \l__xsim_tmpb_bool
+ }
+ }
+ {
+ \msg_warning:nnV {xsim}
+ {print-collection-choice}
+ \l__xsim_print_random_choice_tl
+ }
+ \bool_if:NT \l__xsim_tmpa_bool
+ {
+ \xsim_if_exercise_exist:VVT
+ \l__xsim_tmpb_tl
+ \l__xsim_tmpa_tl
+ {
+ \xsim_insert:VVnn
+ \l__xsim_tmpb_tl
+ \l__xsim_tmpa_tl
+ {}
+ {exercise}
+ }
+ }
+ \bool_if:NT \l__xsim_tmpb_bool
+ {
+ \xsim_if_solution_exist:VVT
+ \l__xsim_tmpb_tl
+ \l__xsim_tmpa_tl
+ {
+ \xsim_insert:VVnn
+ \l__xsim_tmpb_tl
+ \l__xsim_tmpa_tl
+ {}
+ {solution}
+ }
+ }
+ }
+ }
+ }
+ }
+
+\keys_define:nn {xsim/random}
+ {
+ sort .bool_set:N = \l__xsim_sort_random_bool ,
+ sort .initial:n = true ,
+ collection .tl_set:N = \l_xsim_random_collection_tl ,
+ collection .initial:n = all~exercises ,
+ exclude .code:n = \__xsim_exclude_ids:n {#1} ,
+ print .tl_set:N = \l__xsim_print_random_choice_tl ,
+ print .initial:n = exercises
+ }
+
+\cs_new_protected:Npn \__xsim_exclude_ids:n #1
+ {
+ \seq_clear:N \l__xsim_tmpa_seq
+ \clist_map_inline:nn {#1}
+ {
+ \tl_set:Nx \l__xsim_tmpa_tl
+ { \xsim_get_id_for_property:nn {ID} {##1} }
+ \tl_if_blank:VTF \l__xsim_tmpa_tl
+ { \seq_put_right:Nn \l__xsim_tmpa_seq {##1} }
+ {
+ \seq_put_right:Nx \l__xsim_tmpa_seq
+ { \xsim_get_id_for_property:nn {ID} {##1} }
+ }
+ }
+ \seq_remove_duplicates:N \l__xsim_tmpa_seq
+ \clist_set_from_seq:NN
+ \l_xsim_random_exclude_list_clist
+ \l__xsim_tmpa_seq
+ }
+
+\XSIMmoduleend
+\XSIMmodule{translations}{language settings for XSIM}
+
+\RequirePackage{translations}
+
+\msg_new:nnn {xsim} {language-not-defined}
+ {
+ You~ chose~ the~ language~ `#1'~ which~ is~ not~ defined~ by~ xsim.~
+ `english'~ is~ used~ instead.~ If~ you~ just~ mistyped~ try~ again!~
+ Otherwise~ contact~ the~ author~ and~ he'll~ probably~ add~ your~
+ language.
+ }
+
+\msg_new:nnn {xsim} {empty-translation}
+ {
+ No~ translation~ provided~ for~ key~ `#1'~ in~ language~ `#2'~
+ \msg_line_context: .
+ }
+
+% --------------------------------------------------------------------------
+
+\bool_new:N \l__xsim_language_auto_bool
+\bool_set_true:N \l__xsim_language_auto_bool
+% this token list will hold the chosen language for xsim; since the
+% language is either chosen automatically or by option it is only available at
+% begin document
+\tl_new:N \l_xsim_language_tl
+\tl_set:Nn \l_xsim_language_tl {english}
+\tl_new:N \l__xsim_current_language_tl
+
+\tl_const:Nn \c__xsim_keyword_prefix_tl {xsim-keyword-}
+
+% ----------------------------------------------------------------------------
+
+\prop_new:N \g_xsim_translations_prop
+
+% translate the key #1
+\cs_new:Npn \xsim_translate:n #1
+ {
+ \bool_if:NTF \l__xsim_language_auto_bool
+ { \GetTranslation { \c__xsim_keyword_prefix_tl #1 } }
+ {
+ \GetTranslationFor
+ { \l_xsim_language_tl }
+ { \c__xsim_keyword_prefix_tl #1 }
+ }
+ }
+
+\xsim_at_begin_document:n
+ {
+ \bool_if:NTF \l__xsim_language_auto_bool
+ {
+ \tl_set:Nx \l_xsim_language_tl
+ { \@trnslt@language{\@trnslt@current@language} }
+ }
+ {
+ \tl_set_eq:NN
+ \l_xsim_language_tl
+ \l__xsim_current_language_tl
+ }
+ }
+
+% ----------------------------------------------------------------------------
+% #1: language
+% #2: keyword
+% #3: translation
+\cs_new_protected:Npn \xsim_declare_translation:nnn #1#2#3
+ {
+ \xsim_verbose:n
+ { Declaring~ `#1'~ tranlation~ of~ `#2':~ `#3'. }
+ \declaretranslation
+ {#1}
+ { \c__xsim_keyword_prefix_tl #2 }
+ {#3}
+ \prop_gput:Nnn \g_xsim_translations_prop {#2(#1)} {#3}
+ }
+\cs_generate_variant:Nn \xsim_declare_translation:nnn {V,VnV}
+
+% #1: key
+% #2: csv list: { <lang1> = <translation1> , <lang2> = <translation2> }
+\cs_new_protected:Npn \xsim_declare_translations:nn #1#2
+ {
+ \cs_set_protected:Npn \__xsim_declare_translation:n ##1
+ { \msg_warning:nnnn {xsim} {empty-translation} {#1} {##1} }
+ \cs_set_protected:Npn \__xsim_declare_translation:nn ##1##2
+ { \xsim_declare_translation:nnn {##1} {#1} {##2} }
+ \keyval_parse:NNn
+ \__xsim_declare_translation:n
+ \__xsim_declare_translation:nn
+ {#2}
+ }
+
+\cs_new:Npn \__xsim_parse_translate_list_entry:nnn #1#2#3 {}
+
+\cs_new_protected:Npn \__xsim_parse_translate_list_entry:www #1(#2)\q_mark#3\q_stop
+ { \__xsim_parse_translate_list_entry:nnn {#1} {#2} {#3} }
+
+\cs_new_protected:Npn \xsim_for_all_translations_do:n #1
+ {
+ \cs_set:Npn \__xsim_parse_translate_list_entry:nnn ##1##2##3 {#1}
+ \prop_map_inline:Nn \g_xsim_translations_prop
+ { \__xsim_parse_translate_list_entry:www ##1 \q_mark ##2 \q_stop }
+ }
+
+% ----------------------------------------------------------------------------
+
+\keys_define:nn {xsim}
+ {
+ language .value_required:n = true ,
+ language .code:n =
+ \tl_if_eq:nnTF {#1} {auto}
+ { \bool_set_true:N \l__xsim_language_auto_bool }
+ {
+ \bool_set_false:N \l__xsim_language_auto_bool
+ \tl_set:Nn \l__xsim_current_language_tl {#1}
+ } ,
+ language .initial:n = auto
+ }
+
+\XSIMmoduleend
+\XSIMmodule{interface}{user interface}
+
+\msg_new:nnn {xsim} {remove}
+ {
+ The~ command~ #2 is~ deprecated.~ As~ of~ version~ #1~ it~ serves~ no~
+ purpose~ and~ does~ nothing.
+ }
+
+\msg_new:nnn {xsim} {deprecate}
+ {
+ The~ command~ #2 is~ deprecated.~ As~ of~ version~ #1~ it~ serves~ no~
+ purpose~ and~ does~ nothing.~ Use~ #3 instead.
+ }
+
+\cs_new_protected:Npn \xsim_remove:nN #1#2
+ { \msg_warning:nnnn {xsim} {remove} {#1} {#2} }
+
+\cs_new_protected:Npn \xsim_deprecate:nNN #1#2#3
+ { \msg_warning:nnnn {xsim} {remove} {#1} {#2} {#3} }
+
+% ----------------------------------------------------------------------------
+\NewDocumentCommand \DeclareExerciseEnvironmentTemplate {m+m+m}
+ { \xsim_declare_environment_template:nnn {#1} {#2} {#3} }
+\@onlypreamble \DeclareExerciseEnvironmentTemplate
+
+\NewDocumentCommand \DeclareExerciseHeadingTemplate {m+m}
+ { \xsim_declare_heading_template:nn {#1} {#2} }
+\@onlypreamble \DeclareExerciseHeadingTemplate
+
+\NewDocumentCommand \DeclareExerciseTableTemplate {m+m}
+ { \xsim_declare_table_template:nn {#1} {#2} }
+\@onlypreamble \DeclareExerciseTableTemplate
+
+\NewDocumentCommand \UseExerciseTemplate {mm}
+ { \xsim_use_template:nn {#1} {#2} }
+
+% ----------------------------------------------------------------------------
+
+\NewDocumentCommand \DeclareExerciseType {mm}
+ { \xsim_declare_exercise_type:nn {#1} {#2} }
+\@onlypreamble \DeclareExerciseType
+
+\NewExpandableDocumentCommand \numberofusedexercises {}
+ { \int_use:N \g_xsim_max_id_int }
+
+% ----------------------------------------------------------------------------
+
+\NewDocumentCommand \IfExistSolutionTF {+m+m}
+ { \xsim_if_solution_exist:ooTF {\ExerciseType} {\ExerciseID} {#1} {#2} }
+
+\NewDocumentCommand \IfExistSolutionT {+m}
+ { \IfExistSolutionTF {#1} {} }
+
+\NewDocumentCommand \IfExistSolutionF {+m}
+ { \IfExistSolutionTF {} {#1} }
+
+\NewExpandableDocumentCommand \IfInsideSolutionTF {+m+m}
+ { \xsim_if_inside_solution:TF {#1} {#2} }
+
+\NewExpandableDocumentCommand \IfInsideSolutionT {+m}
+ { \IfInsideSolutionTF {#1} {} }
+
+\NewExpandableDocumentCommand \IfInsideSolutionF {+m}
+ { \IfInsideSolutionTF {} {#1} }
+
+\NewExpandableDocumentCommand \IfSolutionPrintTF {+m+m}
+ { \xsim_if_solution_print:nTF {\ExerciseType} {#1} {#2} }
+
+\NewExpandableDocumentCommand \IfSolutionPrintT {+m}
+ { \IfSolutionPrintTF {#1} {} }
+
+\NewExpandableDocumentCommand \IfSolutionPrintF {+m}
+ { \IfSolutionPrintTF {} {#1} }
+
+% ----------------------------------------------------------------------------
+
+\NewDocumentCommand \DeclareExerciseProperty {t!st-m}
+ {
+ \IfBooleanTF {#2}
+ {
+ \IfBooleanTF {#3}
+ {
+ \xsim_declare_property:nnnn
+ { \c_false_bool }
+ { \c_true_bool }
+ { \c_true_bool }
+ {#4}
+ }
+ {
+ \xsim_declare_property:nnnn
+ { \c_false_bool }
+ { \c_true_bool }
+ { \c_false_bool }
+ {#4}
+ }
+ }
+ {
+ \IfBooleanTF {#1}
+ {
+ \IfBooleanTF {#3}
+ {
+ \xsim_declare_property:nnnn
+ { \c_true_bool }
+ { \c_false_bool }
+ { \c_true_bool }
+ {#4}
+ }
+ {
+ \xsim_declare_property:nnnn
+ { \c_true_bool }
+ { \c_false_bool }
+ { \c_false_bool }
+ {#4}
+ }
+ }
+ {
+ \IfBooleanTF {#3}
+ {
+ \xsim_declare_property:nnnn
+ { \c_false_bool }
+ { \c_false_bool }
+ { \c_true_bool }
+ {#4}
+ }
+ {
+ \xsim_declare_property:nnnn
+ { \c_false_bool }
+ { \c_false_bool }
+ { \c_false_bool }
+ {#4}
+ }
+ }
+ }
+ }
+\@onlypreamble \DeclareExerciseProperty
+
+\NewDocumentCommand \DeclareExercisePropertyAlias {mm}
+ { \xsim_make_property_alias:nn {#1} {#2} }
+\@onlypreamble \DeclareExercisePropertyAlias
+
+\NewDocumentCommand \SetExerciseProperty {m+m}
+ { \xsim_set_property:eenn {\ExerciseType} {\ExerciseID} {#1} {#2} }
+
+\NewDocumentCommand \SetExpandedExerciseProperty {m+m}
+ { \xsim_set_property:eene {\ExerciseType} {\ExerciseID} {#1} {#2} }
+
+\NewDocumentCommand \ExerciseSetProperty {mmm+m}
+ { \xsim_set_property:nnnn {#1} {#2} {#3} {#4} }
+
+\NewDocumentCommand \ExerciseSetExpandedProperty {mmm+m}
+ { \xsim_set_property:nnne {#1} {#2} {#3} {#4} }
+
+\NewExpandableDocumentCommand \IfExercisePropertyExistTF {+m+m+m}
+ { \xsim_if_property_exist:nTF {#1} {#2} {#3} }
+
+\NewExpandableDocumentCommand \IfExercisePropertyExistT {+m+m}
+ { \IfExercisePropertyExistTF {#1} {#2} {} }
+
+\NewExpandableDocumentCommand \IfExercisePropertyExistF {+m+m}
+ { \IfExercisePropertyExistTF {#1} {} {#2} }
+
+\NewDocumentCommand \IfExercisePropertySetTF {m+m+m}
+ { \xsim_if_property_set:eenTF {\ExerciseType} {\ExerciseID} {#1} {#2} {#3} }
+
+\NewDocumentCommand \IfExercisePropertySetT {m+m}
+ { \IfExercisePropertySetTF {#1} {#2} {} }
+
+\NewDocumentCommand \IfExercisePropertySetF {m+m}
+ { \IfExercisePropertySetTF {#1} {} {#2} }
+
+\NewExpandableDocumentCommand \GetExerciseProperty {m}
+ { \xsim_get_property:oon {\ExerciseType} {\ExerciseID} {#1} }
+
+\NewExpandableDocumentCommand \GetExerciseAliasProperty {m}
+ {
+ \xsim_get_property:oof
+ {\ExerciseType}
+ {\ExerciseID}
+ { \xsim_property_alias:n {#1} }
+ }
+
+\NewDocumentCommand \GetExercisePropertyTF {m+m+m}
+ {
+ \xsim_get_property_if_set:oonTF {\ExerciseType} {\ExerciseID} {#1}
+ {#2}
+ {#3}
+ }
+
+\NewDocumentCommand \GetExercisePropertyT {m+m}
+ { \GetExercisePropertyTF {#1} {#2} {} }
+\NewDocumentCommand \GetExercisePropertyF {m+m+m}
+ { \GetExercisePropertyTF {#1} {} {#2} }
+
+\NewExpandableDocumentCommand \GetExerciseIdForProperty {mm}
+ { \xsim_get_id_for_property:nn {#1} {#2} }
+
+\NewExpandableDocumentCommand \GetExerciseTypeForProperty {mm}
+ { \xsim_get_type_for_property:nn {#1} {#2} }
+
+\NewExpandableDocumentCommand \IfExerciseBooleanPropertyTF {+m+m+m}
+ {
+ \xsim_if_boolean_property:oonTF {\ExerciseType} {\ExerciseID} {#1}
+ {#2}
+ {#3}
+ }
+
+\NewExpandableDocumentCommand \IfExerciseBooleanPropertyT {+m+m}
+ { \IfExerciseBooleanPropertyTF {#1} {#2} {} }
+\NewExpandableDocumentCommand \IfExerciseBooleanPropertyF {+m+m}
+ { \IfExerciseBooleanPropertyTF {#1} {} {#2} }
+
+\NewDocumentCommand \SaveExerciseProperty {mm}
+ { \xsim_save_property:xxnN {\ExerciseType} {\ExerciseID} {#1} #2 }
+
+\NewDocumentCommand \GlobalSaveExerciseProperty {mm}
+ { \xsim_gsave_property:xxnN {\ExerciseType} {\ExerciseID} {#1} #2 }
+
+% ----------------------------------------------------------------------------
+
+\NewDocumentCommand \DeclareExerciseParameter {st!m}
+ {
+ \IfBooleanTF {#1} % fixed
+ {
+ \IfBooleanTF {#2} % mandatory
+ { \xsim_declare_parameter:nnn {true} {true} {#3} }
+ { \xsim_declare_parameter:nnn {true} {false} {#3} }
+ }
+ {
+ \IfBooleanTF {#2} % mandatory
+ { \xsim_declare_parameter:nnn {false} {true} {#3} }
+ { \xsim_declare_parameter:nnn {false} {false} {#3} }
+ }
+ }
+
+\NewExpandableDocumentCommand \GetExerciseParameter {m}
+ { \xsim_get_parameter:on {\ExerciseType} {#1} }
+
+\NewDocumentCommand \SetExerciseParameter {mmm}
+ { \xsim_set_parameter:nnn {#1} {#2} {#3} }
+
+\NewDocumentCommand \SetExerciseParameters {mm}
+ { \xsim_set_parameters:nn {#1} {#2} }
+
+\NewExpandableDocumentCommand \GetExerciseName {}
+ {
+ \IfInsideSolutionTF
+ { \GetExerciseParameter {solution-name} }
+ { \GetExerciseParameter {exercise-name} }
+ }
+
+\NewExpandableDocumentCommand \GetExerciseHeadingF {m}
+ {
+ \IfInsideSolutionTF
+ {
+ \IfExerciseParameterSetTF {solution-heading}
+ { \GetExerciseParameter {solution-heading} }
+ {#1}
+ }
+ {
+ \IfExerciseParameterSetTF {exercise-heading}
+ { \GetExerciseParameter {exercise-heading} }
+ {#1}
+ }
+ }
+
+\NewDocumentCommand \GetExerciseBody {m}
+ { \xsim_input:oon { \ExerciseType } { \ExerciseID } {#1} }
-2020/02/20 - implement issue #31 (blank package option)
-2020/02/21 - don't allow package options to be set with \xsimsetup
+\NewExpandableDocumentCommand \IfExerciseParameterSetTF {+m+m+m}
+ { \xsim_if_parameter_set:nnTF {\ExerciseType} {#1} {#2} {#3} }
+
+\NewExpandableDocumentCommand \IfExerciseParameterSetT {+m+m}
+ { \IfExerciseParameterSetTF {#1} {#2} {} }
+
+\NewExpandableDocumentCommand \IfExerciseParameterSetF {+m+m}
+ { \IfExerciseParameterSetTF {#1} {} {#2} }
+
+\NewExpandableDocumentCommand \ExerciseParameterIfSetTF {+m+m+m+m}
+ { \xsim_if_parameter_set:nnTF {#1} {#2} {#3} {#4} }
+
+\NewExpandableDocumentCommand \ExerciseParameterIfSetT {+m+m+m}
+ { \ExerciseParameterIfSetTF {#1} {#2} {#3} {} }
+
+\NewExpandableDocumentCommand \ExerciseParameterIfSetF {+m+m+m}
+ { \ExerciseParameterIfSetTF {#1} {#2} {} {#3} }
+
+\NewDocumentCommand \GetExerciseParameterTF {m+m+m}
+ { \xsim_get_parameter_if_set:onTF {\ExerciseType} {#1} {#2} {#3} }
+
+\NewDocumentCommand \GetExerciseParameterT {m+m}
+ { \GetExerciseParameterTF {#1} {#2} {} }
+
+\NewDocumentCommand \GetExerciseParameterF {m+m+m}
+ { \GetExerciseParameterTF {#1} {} {#2} }
+
+% ----------------------------------------------------------------------------
+
+\NewDocumentCommand \ExercisePropertyIfSetTF {mmm+m+m}
+ { \xsim_if_property_set:nnnTF {#1} {#2} {#3} {#4} {#5} }
+
+\NewDocumentCommand \ExercisePropertyIfSetT {mmm+m}
+ { \ExercisePropertyIfSetTF {#1} {#2} {#3} {#4} {} }
+
+\NewDocumentCommand \ExercisePropertyIfSetF {mmm+m}
+ { \ExercisePropertyIfSetTF {#1} {#2} {#3} {} {#4} }
+
+\NewExpandableDocumentCommand \ExercisePropertyGet {mmm}
+ { \xsim_get_property:nnn {#1} {#2} {#3} }
+
+\NewExpandableDocumentCommand \ExercisePropertyGetAlias {mm}
+ { \xsim_get_property:nnf {#1} {#2} { \xsim_property_alias:n {#1} } }
+
+\NewDocumentCommand \ExercisePropertySave {mmmm}
+ { \xsim_save_property:nnnN {#1} {#2} {#3} #4 }
+
+\NewDocumentCommand \ExercisePropertyGlobalSave {mmmm}
+ { \xsim_gsave_property:nnnN {#1} {#2} {#3} #4 }
+
+\NewExpandableDocumentCommand \ExerciseParameterGet {mm}
+ { \xsim_get_parameter:nn {#1} {#2} }
+
+% ----------------------------------------------------------------------------
+
+\NewExpandableDocumentCommand \XSIMtranslate {m}
+ { \xsim_translate:n {#1} }
+
+\NewExpandableDocumentCommand \XSIMexpandcode {+m}
+ { \use:e {#1} }
+
+\NewExpandableDocumentCommand \XSIMmixedcase {m}
+ { \text_titlecase:e {#1} }
+
+\NewDocumentCommand \XSIMputright {mm}
+ { \tl_put_right:Nn #1 {#2} }
+
+\NewExpandableDocumentCommand \XSIMifeqTF {+m+m+m+m}
+ { \tl_if_eq:eeTF {#1} {#2} {#3} {#4} }
+
+\NewExpandableDocumentCommand \XSIMifeqT {+m+m+m}
+ { \XSIMifeqTF {#1} {#2} {#3} {} }
+
+\NewExpandableDocumentCommand \XSIMifeqF {+m+m+m}
+ { \XSIMifeqTF {#1} {#2} {} {#3} }
+
+\NewExpandableDocumentCommand \XSIMifblankTF {+m+m+m}
+ { \tl_if_blank:eTF {#1} {#2} {#3} }
+
+\NewExpandableDocumentCommand \XSIMifblankT {+m+m}
+ { \XSIMifblankTF {#1} {#2} {} }
+
+\NewExpandableDocumentCommand \XSIMifblankF {+m+m}
+ { \XSIMifblankTF {#1} {} {#2} {} }
+
+% ----------------------------------------------------------------------------
+
+\NewDocumentCommand \DeclareExerciseGoal {m}
+ { \xsim_declare_exercise_goal:n {#1} }
+\@onlypreamble \DeclareExerciseGoal
+
+\NewDocumentCommand \IfExerciseGoalTF {mm+m+m}
+ {
+ \xsim_if_goal_value:xxnnTF
+ {\ExerciseType} {\ExerciseID} {#1}
+ {#2}
+ {#3} {#4}
+ }
+
+\NewDocumentCommand \IfExerciseGoalT {mm+m}
+ { \IfExerciseGoalTF {#1} {#2} {#3} {} }
+
+\NewDocumentCommand \IfExerciseGoalF {mm+m}
+ { \IfExerciseGoalTF {#1} {#2} {} {#3} }
+
+\NewDocumentCommand \IfExerciseGoalSingularTF {mmm}
+ { \IfExerciseGoalTF {#1} {=1} {#2} {#3} }
+
+\NewDocumentCommand \IfExerciseGoalSingularT {mm}
+ { \IfExerciseGoalT {#1} {=1} {#2} }
+
+\NewDocumentCommand \IfExerciseGoalSingularF {mm}
+ { \IfExerciseGoalF {#1} {=1} {#2} }
+
+\NewDocumentCommand \IfExerciseTypeGoalsSumTF {mmm+m+m}
+ { \xsim_if_goals_sum:nnnTF {#1} {#2} {#3} {#4} {#5} }
+
+\NewDocumentCommand \IfExerciseTypeGoalsSumT {mmm+m}
+ { \IfExerciseTypeGoalsSumTF {#1} {#2} {#3} {#4} {} }
+
+\NewDocumentCommand \IfExerciseTypeGoalsSumF {mmm+m}
+ { \IfExerciseTypeGoalsSumTF {#1} {#2} {#3} {} {#4} }
+
+\NewDocumentCommand \IfExerciseGoalsSumTF {mm+m+m}
+ { \xsim_if_total_goals_sum:nnTF {#1} {#2} {#3} {#4} }
+
+\NewDocumentCommand \IfExerciseGoalsSumT {mm+m}
+ { \IfExerciseGoalsSumTF {#1} {#2} {#3} {} }
+
+\NewDocumentCommand \IfExerciseGoalsSumF {mm+m}
+ { \IfExerciseGoalsSumTF {#1} {#2} {} {#3} }
+
+\NewDocumentCommand \TotalExerciseTypeGoal {mmmm}
+ { \xsim_print_goal_sum:nnnn {#1} {#2} {#3} {#4} }
+
+\NewDocumentCommand \TotalExerciseTypeGoals {mmmm}
+ { \xsim_print_goals_sum:nnnn {#1} {#2} {#3} {#4} }
+
+\NewDocumentCommand \TotalExerciseGoal {mmm}
+ { \xsim_print_total_goal_sum:nnn {#1} {#2} {#3} }
+
+\NewDocumentCommand \TotalExerciseGoals {mmm}
+ { \xsim_print_total_goals_sum:nnn {#1} {#2} {#3} }
+
+\NewDocumentCommand \AddtoExerciseTypeGoal {mmmm}
+ { \xsim_addto_goal:nnnn {#1} {#2} {#3} {#4} }
+
+\NewDocumentCommand \AddtoExerciseGoal {mm}
+ { \xsim_addto_goal:xxnn {\ExerciseType} {\ExerciseID} {#1} {#2} }
+
+\NewDocumentCommand \ExerciseGoalValuePrint {mmm}
+ { \xsim_print_goal:nnn {#1} {#2} {#3} }
+
+\NewDocumentCommand \AddtoExerciseTypeGoalPrint {mmmmmm}
+ {
+ \xsim_addto_goal:nnnn {#1} {#2} {#3} {#4}
+ \xsim_print_goal:nnn {#4} {#5} {#6}
+ }
+
+\NewDocumentCommand \AddtoExerciseGoalPrint {mmmm}
+ {
+ \xsim_addto_goal:xxnn {\ExerciseType} {\ExerciseID} {#1} {#2}
+ \xsim_print_goal:nnn {#2} {#3} {#4}
+ }
+
+% ----------------------------------------------------------------------------
+\NewDocumentCommand \DeclareGradeDistribution {m}
+ { \xsim_declare_relative_grades:n {#1} }
+
+\NewDocumentCommand \GetGradeRequirementForGoal {mmmm}
+ { \xsim_get_grade_goal:nnnn {#1} {#2} {#3} {#4} }
+
+\NewDocumentCommand \GetGradeRequirementForGoals {mmmm}
+ { \xsim_get_grade_requirement:nnnn {#1} {#2} {#3} {#4} }
+
+\NewDocumentCommand \GetGradeRequirement {mmm}
+ { \xsim_get_absolute_grade_requirement:nnn {#1} {#2} {#3} }
+
+% ----------------------------------------------------------------------------
+
+\NewDocumentCommand \DeclareExerciseTagging {m}
+ { \xsim_new_tag_type:n {#1} }
+\@onlypreamble \DeclareExerciseTagging
+
+\NewDocumentCommand \ProvideExerciseTagging {m}
+ {
+ \xsim_if_tag_type_exist:nTF {#1}
+ { \msg_warning:nnn {xsim} {tag-exists} {#1} }
+ { \xsim_new_tag_type:n {#1} }
+ }
+
+\NewDocumentCommand \ForEachExerciseTag {m+m}
+ { \xsim_foreach_exercise_tag:oonn {\ExerciseType} {\ExerciseID} {#1} {#2} }
+
+\NewDocumentCommand \ListExerciseTags {mm}
+ { \xsim_exercise_tags_use:oonn {\ExerciseType} {\ExerciseID} {#1} {#2} }
+
+\NewDocumentCommand \UseExerciseTags {mmmm}
+ {
+ \xsim_exercise_tags_use:oonnnn
+ {\ExerciseType}
+ {\ExerciseID}
+ {#1}
+ {#2}
+ {#3}
+ {#4}
+ }
+
+\NewDocumentCommand \IfExerciseTagSetTF {m+m+m}
+ { \xsim_if_tags_value:nTF {#1} {#2} {#3} }
+\NewDocumentCommand \IfExerciseTagSetT {m+m}
+ { \xsim_if_tags_value:nT {#1} {#2} }
+\NewDocumentCommand \IfExerciseTagSetF {m+m}
+ { \xsim_if_tags_value:nF {#1} {#2} }
+
+\NewDocumentCommand \IfExerciseTopicSetTF {m+m+m}
+ { \xsim_if_topic_value:nTF {#1} {#2} {#3} }
+\NewDocumentCommand \IfExerciseTopicSetT {m+m}
+ { \xsim_if_topic_value:nT {#1} {#2} }
+\NewDocumentCommand \IfExerciseTopicSetF {m+m}
+ { \xsim_if_topic_value:nF {#1} {#2} }
+
+% ----------------------------------------------------------------------------
+
+\NewDocumentCommand \XSIMatbegindocument {+m}
+ { \xsim_at_begin_document:n {#1} }
+
+\NewDocumentCommand \XSIMatenddocument {+m}
+ { \xsim_at_end_document:n {#1} }
+
+% ----------------------------------------------------------------------------
+
+\NewDocumentCommand \ForEachPrintedExerciseByType {+m}
+ { \xsim_foreach_exercise_type_id:nn {printed} {#1} }
+
+\tl_new:N \XSIMtmp
+
+\NewDocumentCommand \ForEachPrintedExerciseByID {+m}
+ {
+ \tl_set_eq:NN \XSIMtmp \ExerciseType
+ \xsim_foreach_exercise_id_type:nn {print} {#1}
+ \tl_set_eq:NN \ExerciseType \XSIMtmp
+ \tl_clear:N \XSIMtmp
+ }
+
+\NewDocumentCommand \ForEachUsedExerciseByType {+m}
+ {
+ \tl_set_eq:NN \XSIMtmp \ExerciseType
+ \xsim_foreach_exercise_type_id:nn {used} {#1}
+ \tl_set_eq:NN \ExerciseType \XSIMtmp
+ \tl_clear:N \XSIMtmp
+ }
+
+\NewDocumentCommand \ForEachUsedExerciseByID {+m}
+ {
+ \tl_set_eq:NN \XSIMtmp \ExerciseType
+ \xsim_foreach_exercise_id_type:nn {used} {#1}
+ \tl_set_eq:NN \ExerciseType \XSIMtmp
+ \tl_clear:N \XSIMtmp
+ }
+
+% ----------------------------------------------------------------------------
+
+\NewDocumentCommand \DeclareExerciseTranslations {mm}
+ { \xsim_declare_translations:nn {#1} {#2} }
+\@onlypreamble \DeclareExerciseTranslations
+
+\NewDocumentCommand \DeclareExerciseTranslation {mmm}
+ { \xsim_declare_translation:nnn {#1} {#2} {#3} }
+\@onlypreamble \DeclareExerciseTranslation
+
+\NewDocumentCommand \ForEachExerciseTranslation {+m}
+ { \xsim_for_all_translations_do:n {#1} }
+
+% ----------------------------------------------------------------------------
+
+\NewDocumentCommand \DeclareExerciseCollection {om}
+ {
+ \IfNoValueTF {#1}
+ { \xsim_new_collection:nn {#2} {} }
+ {
+ \xsim_new_collection:nn {#2} {#1}
+ \xsim_activate_collection:n {#2}
+ }
+ }
+\@onlypreamble \DeclareExerciseCollection
+
+\NewDocumentCommand \activatecollection {m}
+ { \xsim_activate_collection:n {#1} }
+
+\NewDocumentCommand \deactivatecollection {m}
+ { \xsim_deactivate_collection:n {#1} }
+
+% \NewDocumentCommand \collectexercisestype {mm}
+% { \xsim_collect_type_start:nn {#1} {#2} }
+
+\NewDocumentCommand \collectexercises {m}
+ { \xsim_collect_start:n {#1} }
+
+\NewDocumentCommand \collectexercisesstop {m}
+ { \xsim_collect_stop:n {#1} }
+
+\NewDocumentCommand \printcollection {O{}m}
+ { \xsim_print_collection:nn {#1} {#2} }
+
+\NewDocumentCommand \printrandomexercises {O{}m}
+ {
+ \group_begin:
+ \keys_set:nn {xsim/random} {#1}
+ \xsim_print_random_list:VnN
+ \l_xsim_random_collection_tl
+ {#2}
+ \l_xsim_random_exclude_list_clist
+ \group_end:
+ }
+
+% ----------------------------------------------------------------------------
+
+\NewDocumentCommand \blank {som}
+ {
+ \group_begin:
+ \IfNoValueF {#2} { \keys_set:nn {xsim/blank} {#2} }
+ \mode_if_vertical:TF
+ {
+ \IfBooleanTF {#1}
+ { \xsim_blank:n {#3} }
+ {
+ \bool_if:NT \l__xsim_blank_linespread_bool
+ { \linespread { \l__xsim_blank_linespread_tl } \selectfont }
+ \noindent \null \xsim_blank:n {#3} \par
+ }
+ }
+ { \xsim_blank:n {#3} }
+ \group_end:
+ }
+
+\NewDocumentCommand \examspace { sm }
+ {
+ \IfBooleanTF {#1}
+ { \xsim_examspace:nn { \c_true_bool } {#2} }
+ { \xsim_examspace:nn { \c_false_bool } {#2} }
+ }
+
+% ----------------------------------------------------------------------------
+
+\NewDocumentCommand \gradingtable {O{}}
+ {
+ \group_begin:
+ \keys_set:nn {xsim/grading-table} {#1}
+ \xsim_setup_template:nVn {table} \l_xism_grading_table_template_tl
+ {
+ \providecommand* \ExerciseTableCode {}
+ \providecommand* \ExerciseTableType [1] {}
+ \providecommand* \ExerciseType {}
+ \tl_set_eq:NN \ExerciseType \l_xism_grading_table_exercise_type_tl
+ \renewcommand* \ExerciseTableCode {}
+ \renewcommand* \ExerciseTableType [1]
+ {
+ \XSIMifblankTF { \l_xism_grading_table_exercise_type_tl }
+ {##1}
+ { \l_xism_grading_table_exercise_type_tl }
+ }
+ }
+ \xsim_use_template:nV {table} \l_xism_grading_table_template_tl
+ \group_end:
+ }
+
+% ----------------------------------------------------------------------------
+
+\NewDocumentCommand \XSIMprint {mO{}mm}
+ { \xsim_insert:nenn {#3} { \xsim_normalize_id:n {#4} } {#2} {#1} }
+
+\NewDocumentCommand \XSIMxprint {mO{}mm}
+ { \xsim_insert:xxnn {#3} { \xsim_normalize_id:e {#4} } {#2} {#1} }
+
+\NewDocumentCommand \printexercise {O{}mm}
+ {
+ \clist_map_inline:nn {#3}
+ { \xsim_insert:nenn {#2} { \xsim_normalize_id:n {##1} } {#1} {exercise} }
+ }
+
+\NewDocumentCommand \xprintexercise {O{}mm}
+ {
+ \clist_map_inline:nn {#3}
+ { \xsim_insert:xxnn {#2} { \xsim_normalize_id:e {##1} } {#1} {exercise} }
+ }
+
+\NewDocumentCommand \printsolution {O{}mm}
+ {
+ \clist_map_inline:nn {#3}
+ { \xsim_insert:nenn {#2} { \xsim_normalize_id:n {##1} } {#1} {solution} }
+ }
+
+\NewDocumentCommand \xprintsolution {O{}mm}
+ {
+ \clist_map_inline:nn {#3}
+ { \xsim_insert:xxnn {#2} { \xsim_normalize_id:e {##1} } {#1} {solution} }
+ }
+
+% ----------------------------------------------------------------------------
+
+\NewDocumentCommand \printsolutionstype {sO{}m}
+ {
+ \IfBooleanTF {#1}
+ { \xsim_print_type_solutions:nnn { \c_true_bool } {#2} {#3} }
+ { \xsim_print_type_solutions:nnn { \c_false_bool } {#2} {#3} }
+ }
+
+\NewDocumentCommand \printsolutions {sO{}}
+ {
+ \IfBooleanTF {#1}
+ { \xsim_print_all_solutions_per_type:nn { \c_true_bool } {#2} }
+ { \xsim_print_all_solutions_per_type:nn { \c_false_bool } {#2} }
+ }
+
+\NewDocumentCommand \printallsolutions {sO{}}
+ {
+ \IfBooleanTF {#1}
+ { \xsim_print_all_solutions_per_id:nn { \c_true_bool } {#2} }
+ { \xsim_print_all_solutions_per_id:nn { \c_false_bool } {#2} }
+ }
+
+% ----------------------------------------------------------------------------
+
+\NewDocumentCommand \printforexercises {sO{}+mO{}}
+ {
+ \IfBooleanTF {#1}
+ {
+ \xsim_foreach_exercise_type:n
+ { \xsim_print_type_code:nnnnn { \c_true_bool } {#2} {#4} {##1} {#3} }
+ }
+ {
+ \xsim_foreach_exercise_type:n
+ { \xsim_print_type_code:nnnnn { \c_false_bool } {#2} {#4} {##1} {#3} }
+ }
+ }
+
+% ----------------------------------------------------------------------------
+
+\NewDocumentCommand \xsimsetup {+m}
+ { \xsim_setup:n {#1} }
+
+% ----------------------------------------------------------------------------
+\NewExpandableDocumentCommand \XSIMifchapterTF {+m+m}
+ { \xsim_if_chapter:TF {#1} {#2} }
+
+\NewExpandableDocumentCommand \XSIMifchapterT {+m}
+ { \xsim_if_chapter:T {#1} }
+
+\NewExpandableDocumentCommand \XSIMifchapterF {+m}
+ { \xsim_if_chapter:F {#1} }
+
+\XSIMmoduleend
+\XSIMmodule{definitions}{definition of user commands}
+
+% not exactly a user choice: the `exercises' environments rely on them:
+\DeclareExerciseParameter*!{exercise-env}
+\DeclareExerciseParameter*!{solution-env}
+\DeclareExerciseParameter !{exercise-name}
+\DeclareExerciseParameter !{solution-name}
+\DeclareExerciseParameter {exercises-name}
+\DeclareExerciseParameter {solutions-name}
+\DeclareExerciseParameter !{exercise-template}
+\DeclareExerciseParameter !{solution-template}
+\DeclareExerciseParameter* {counter}
+\DeclareExerciseParameter* {solution-counter}
+\DeclareExerciseParameter* {number}
+\DeclareExerciseParameter {within}
+\DeclareExerciseParameter {the-counter}
+
+% these are additional - but are used in the `default' environment
+% template:
+\DeclareExerciseParameter {exercise-heading}
+\DeclareExerciseParameter {solution-heading}
+
+% ----------------------------------------------------------------------------
+
+% not exactly a user choice, must be present at various places:
+\DeclareExerciseProperty! {id}
+\DeclareExerciseProperty! {ID}
+\DeclareExerciseProperty {counter}
+\DeclareExerciseProperty {counter-value}
+\DeclareExerciseProperty * {solution}
+\XSIMifchapterT{
+ \DeclareExerciseProperty {chapter-value}
+ \DeclareExerciseProperty {chapter}
+}
+\DeclareExerciseProperty {section-value}
+\DeclareExerciseProperty {section}
+\DeclareExerciseProperty {sectioning}
+
+% those are additional and wouldn't *need* to be present except for
+% pre-defined templates which make use of them (the page and page-value
+% property actually needs to be defined for xsim to be able to save the
+% corresponding values):
+\DeclareExerciseProperty {subtitle}
+\DeclareExerciseProperty {points}
+\DeclareExerciseProperty {bonus-points}
+\DeclareExerciseProperty {page-value}
+\DeclareExerciseProperty {page}
+
+\DeclareExercisePropertyAlias {ID} {id}
+
+% ----------------------------------------------------------------------------
+
+\DeclareExerciseTagging {tags}
+\DeclareExerciseTagging {topics}
+
+\xsimsetup{tags/ignore-untagged=false}
+
+% ----------------------------------------------------------------------------
+
+\DeclareExerciseGoal {points}
+\DeclareExerciseGoal {bonus-points}
+
+\NewDocumentCommand \printgoal {m}
+ { \ExerciseGoalValuePrint {#1} {} {} }
+
+\NewDocumentCommand \points {m}
+ {
+ \ExerciseGoalValuePrint {#1}
+ { \, \XSIMtranslate {point} }
+ { \, \XSIMtranslate {points} }
+ }
+
+\NewDocumentCommand \addpoints {sm}
+ {
+ \AddtoExerciseGoal {points} {#2}
+ \IfBooleanF {#1} { \points {#2} }
+ }
+
+\NewDocumentCommand \printpoints {m}
+ {
+ \TotalExerciseTypeGoal {#1} {points}
+ { \, \XSIMtranslate {point} }
+ { \, \XSIMtranslate {points} }
+ }
+
+\NewDocumentCommand \printtotalpoints {}
+ {
+ \TotalExerciseGoal {points}
+ { \, \XSIMtranslate {point} }
+ { \, \XSIMtranslate {points} }
+ }
+
+\NewDocumentCommand \addbonus {sm}
+ {
+ \AddtoExerciseGoal {bonus-points} {#2}
+ \IfBooleanF {#1} { \points {#2} }
+ }
+
+\NewDocumentCommand \printbonus {m}
+ {
+ \TotalExerciseTypeGoal {#1} {bonus-points}
+ { \, \XSIMtranslate {point} }
+ { \, \XSIMtranslate {points} }
+ }
+
+\NewDocumentCommand \printtotalbonus {}
+ {
+ \TotalExerciseGoal {bonus-points}
+ { \, \XSIMtranslate {point} }
+ { \, \XSIMtranslate {points} }
+ }
+
+% ----------------------------------------------------------------------------
+\NewDocumentCommand \pointsforgrade {m}
+ {
+ \GetGradeRequirementForGoal {#1} {points}
+ { \, \XSIMtranslate {point} }
+ { \, \XSIMtranslate {points} }
+ }
+
+\NewDocumentCommand \goalsforgrade {mm}
+ {
+ \GetGradeRequirementForGoals {#2} {#1}
+ { \, \XSIMtranslate {point} }
+ { \, \XSIMtranslate {points} }
+ }
+
+\NewDocumentCommand \totalgoalforgrade {m}
+ {
+ \GetGradeRequirement {#1}
+ { \, \XSIMtranslate {point} }
+ { \, \XSIMtranslate {points} }
+ }
+
+% ----------------------------------------------------------------------------
+
+\xsim_if_package_blank:F
+ {
+ \DeclareExerciseType {exercise} {
+ exercise-env = exercise ,
+ solution-env = solution ,
+ exercise-name = \XSIMtranslate {exercise} ,
+ exercises-name = \XSIMtranslate {exercises} ,
+ solution-name = \XSIMtranslate {solution} ,
+ solutions-name = \XSIMtranslate {solutions} ,
+ exercise-template = default ,
+ solution-template = default ,
+ exercise-heading = \subsection* ,
+ solution-heading = \subsection*
+ }
+ }
+
+% ----------------------------------------------------------------------------
+
+\DeclareExerciseEnvironmentTemplate {default}
+ {
+ \GetExerciseHeadingF { \subsection* }
+ {
+ \XSIMmixedcase { \GetExerciseName } \nobreakspace
+ \GetExerciseProperty {counter}
+ \IfInsideSolutionF
+ {
+ \IfExercisePropertySetT {subtitle}
+ { ~ { \normalfont \itshape \GetExerciseProperty {subtitle} } }
+ }
+ }
+ \GetExercisePropertyT {points}
+ {
+ \marginpar
+ {
+ \IfInsideSolutionF { \rule {1.2cm} {1pt} \slash }
+ \printgoal {\PropertyValue}
+ \GetExercisePropertyT {bonus-points}
+ { \nobreakspace ( + \printgoal {\PropertyValue} ) }
+ \nobreakspace\XSIMtranslate {point-abbr}
+ }
+ }
+ }
+ { \par }
+
+% ----------------------------------------------------------------------------
+
+\DeclareExerciseHeadingTemplate {none} {}
+
+\DeclareExerciseHeadingTemplate {default}
+ { \section* { \XSIMtranslate {default-heading} } }
+
+\DeclareExerciseHeadingTemplate {collection}
+ { \section* { \XSIMtranslate {collection-heading} } }
+
+\DeclareExerciseHeadingTemplate {per-section}
+ { \section* { \XSIMtranslate {per-section-heading} } }
+
+\DeclareExerciseHeadingTemplate {per-chapter}
+ { \section* { \XSIMtranslate {per-chapter-heading} } }
+
+% ----------------------------------------------------------------------------
+
+\RequirePackage{array,booktabs}
+
+\DeclareExerciseTableTemplate {default*}
+ {
+ \XSIMputright \ExerciseTableCode
+ {
+ \toprule
+ \XSIMifblankF { \ExerciseType }
+ { \XSIMmixedcase { \GetExerciseParameter {exercise-name} } }
+ &
+ }
+ \ForEachUsedExerciseByType
+ {
+ \XSIMifeqT {#1} { \ExerciseTableType {#1} }
+ {
+ \XSIMifblankT { \ExerciseTableType {} }
+ {
+ \XSIMputright \ExerciseTableCode
+ {
+ \XSIMmixedcase
+ { \ExerciseParameterGet {#1} {exercise-name} ~ }
+ }
+ }
+ \XSIMputright \ExerciseTableCode { #3 & }
+ }
+ }
+ \XSIMputright \ExerciseTableCode
+ {
+ \XSIMtranslate {total} \\
+ \midrule \XSIMmixedcase { \XSIMtranslate {points} } &
+ }
+ \ForEachUsedExerciseByType
+ {
+ \XSIMifeqT {#1} { \ExerciseTableType {#1} }
+ {
+ \XSIMputright \ExerciseTableCode
+ { \XSIMifblankTF {#5} {\printgoal{0}} {\printgoal{#5}} & }
+ }
+ }
+ \XSIMputright \ExerciseTableCode
+ {
+ \XSIMifblankTF { \ExerciseType }
+ { \TotalExerciseGoal {points} {} {} }
+ { \TotalExerciseTypeGoal { \ExerciseType } {points} {} {} }
+ \\ \midrule
+ \XSIMtranslate {reached} &
+ }
+ \ForEachUsedExerciseByType
+ {
+ \XSIMifeqT {#1} { \ExerciseTableType {#1} }
+ { \XSIMputright \ExerciseTableCode {&} }
+ }
+ \XSIMputright \ExerciseTableCode { \\ \bottomrule }
+ \edef \numberofcolumns
+ {
+ \XSIMifblankTF { \ExerciseType }
+ {\numberofusedexercises}
+ {\csname numberof \ExerciseType s\endcsname}
+ }
+ \XSIMifeqF {\numberofcolumns} {0}
+ {
+ \begin {tabular} {l*{\numberofcolumns}{c}c}
+ \ExerciseTableCode
+ \end {tabular}
+ }
+ }
+
+\DeclareExerciseTableTemplate {default}
+ {
+ \XSIMputright \ExerciseTableCode
+ {
+ \toprule
+ \XSIMifblankF { \ExerciseType }
+ { \XSIMmixedcase { \GetExerciseParameter {exercise-name} } }
+ &
+ \XSIMmixedcase { \XSIMtranslate {points} } &
+ \XSIMtranslate {reached} \\
+ \midrule
+ }
+ \ForEachUsedExerciseByType
+ {
+ \XSIMifeqT {#1} { \ExerciseTableType {#1} }
+ {
+ \XSIMifblankT { \ExerciseTableType {} }
+ {
+ \XSIMputright \ExerciseTableCode
+ {
+ \XSIMmixedcase
+ { \ExerciseParameterGet {#1} {exercise-name} ~ }
+ }
+ }
+ \XSIMputright \ExerciseTableCode
+ { #3 & \XSIMifblankTF {#5} {\printgoal{0}} {\printgoal{#5}} & \\ }
+ }
+ }
+ \XSIMputright \ExerciseTableCode
+ {
+ \midrule
+ \XSIMtranslate {total} &
+ \XSIMifblankTF { \ExerciseType }
+ { \TotalExerciseGoal {points} {} {} }
+ { \TotalExerciseTypeGoal { \ExerciseType } {points} {} {} } &
+ \\ \bottomrule
+ }
+ \XSIMexpandcode
+ {
+ \noexpand \begin {tabular} {\XSIMifblankTF{\ExerciseType}{l}{c}cc}
+ \noexpand \ExerciseTableCode
+ \noexpand \end {tabular}
+ }
+ }
+
+% ----------------------------------------------------------------------------
+
+\DeclareExerciseTranslations {exercise} {
+ Fallback = exercise ,
+ English = exercise ,
+ French = exercice ,
+ German = \"Ubung
+}
+
+\DeclareExerciseTranslations {exercises} {
+ Fallback = exercises ,
+ English = exercises ,
+ French = exercices ,
+ German = \"Ubungen
+}
+
+\DeclareExerciseTranslations {question} {
+ Fallback = question ,
+ English = question ,
+ French = question ,
+ German = Aufgabe
+}
+
+\DeclareExerciseTranslations {questions} {
+ Fallback = questions ,
+ English = questions ,
+ French = questions ,
+ German = Aufgaben
+}
+
+\DeclareExerciseTranslations {solution} {
+ Fallback = solution ,
+ English = solution ,
+ French = solution ,
+ German = L\"osung
+}
+
+\DeclareExerciseTranslations {solutions} {
+ Fallback = solutions ,
+ English = solutions ,
+ French = solutions ,
+ German = L\"osungen
+}
+
+\DeclareExerciseTranslations {point-abbr} {
+ Fallback = p. ,
+ English = p. ,
+ French = p. ,
+ German = P.
+}
+
+\DeclareExerciseTranslations {point} {
+ Fallback = point ,
+ English = point ,
+ French = point ,
+ German = Punkt
+}
+
+\DeclareExerciseTranslations {points} {
+ Fallback = points ,
+ English = points ,
+ French = points ,
+ German = Punkte
+}
+
+\DeclareExerciseTranslations {reached} {
+ Fallback = reached ,
+ English = reached ,
+ French = obtenus ,
+ German = erreicht
+}
+
+\DeclareExerciseTranslations {total} {
+ Fallback = total ,
+ English = total ,
+ French = total ,
+ German = insgesamt
+}
+
+\DeclareExerciseTranslations {default-heading} {
+ Fallback = \XSIMmixedcase { \GetExerciseParameter {solutions-name} }~
+ to~ the~ \XSIMmixedcase { \GetExerciseParameter {exercises-name} } ,
+ English = \XSIMmixedcase { \GetExerciseParameter {solutions-name} }~
+ to~ the~ \XSIMmixedcase { \GetExerciseParameter {exercises-name} } ,
+ French = \XSIMmixedcase { \GetExerciseParameter {solutions-name} ~
+ des~ \GetExerciseParameter {exercises-name} } ,
+ German = \XSIMmixedcase { \GetExerciseParameter {solutions-name} }~
+ zu~ den~ \XSIMmixedcase { \GetExerciseParameter {exercises-name} }
+}
+
+\DeclareExerciseTranslations {collection-heading} {
+ Fallback = \XSIMmixedcase { \GetExerciseParameter {exercises-name} } ,
+ English = \XSIMmixedcase { \GetExerciseParameter {exercises-name} } ,
+ French = \XSIMmixedcase { \GetExerciseParameter {exercises-name} } ,
+ German = \XSIMmixedcase { \GetExerciseParameter {exercises-name} }
+}
+
+\DeclareExerciseTranslations {per-section-heading} {
+ Fallback = \XSIMmixedcase { \GetExerciseParameter {solutions-name} } ~
+ to~ the~ \XSIMmixedcase { \GetExerciseParameter {exercises-name} } ~
+ of~ Section \nobreakspace \ExerciseSection ,
+ English = \XSIMmixedcase { \GetExerciseParameter {solutions-name} } ~
+ to~ the~ \XSIMmixedcase { \GetExerciseParameter {exercises-name} } ~
+ of~ Section \nobreakspace \ExerciseSection ,
+ French = \XSIMmixedcase { \GetExerciseParameter {solutions-name} ~
+ des~ \GetExerciseParameter {exercises-name} ~ de~ la~
+ section \nobreakspace \ExerciseSection } ,
+ German = \XSIMmixedcase { \GetExerciseParameter {solutions-name} } ~
+ zu~ den~ \XSIMmixedcase { \GetExerciseParameter {exercises-name} }~
+ in~ Abschnitt \nobreakspace \ExerciseSection
+}
+
+\DeclareExerciseTranslations {per-chapter-heading} {
+ Fallback = \XSIMmixedcase { \GetExerciseParameter {solutions-name} } ~
+ to~ the~ \XSIMmixedcase { \GetExerciseParameter {exercises-name} } ~
+ of~ Chapter \nobreakspace \ExerciseChapter ,
+ English = \XSIMmixedcase { \GetExerciseParameter {solutions-name} } ~
+ to~ the~ \XSIMmixedcase { \GetExerciseParameter {exercises-name} } ~
+ of~ Chapter \nobreakspace \ExerciseChapter ,
+ French = \XSIMmixedcase { \GetExerciseParameter {solutions-name} ~
+ des~ \GetExerciseParameter {exercises-name} ~
+ du~ chapitre \nobreakspace \ExerciseChapter } ,
+ German = \XSIMmixedcase { \GetExerciseParameter {solutions-name} } ~
+ zu~ den~ \XSIMmixedcase { \GetExerciseParameter {exercises-name} } ~
+ in~ Kapitel \nobreakspace \ExerciseChapter
+}
+
+\XSIMmoduleend
+% finish package:
+\hook_gput_code:nnn {enddocument} {toplevel} { \xsim_close_aux:\xsim_do_rerun: }
+%----------------------------------------------------------------------------
+\file_input_stop:
diff --git a/Master/texmf-dist/tex/latex/xsim/xsim.style.layouts.code.tex b/Master/texmf-dist/tex/latex/xsim/xsim.style.layouts.code.tex
deleted file mode 100644
index 31f5810bce5..00000000000
--- a/Master/texmf-dist/tex/latex/xsim/xsim.style.layouts.code.tex
+++ /dev/null
@@ -1,121 +0,0 @@
-% ----------------------------------------------------------------------------
-% the XSIM package - layouts style
-%
-% 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.
-% ----------------------------------------------------------------------------
-\xsimstyle{layouts}[2019/10/12]
-
-\RequirePackage{needspace}
-
-\DeclareExerciseEnvironmentTemplate{runin}
- {%
- \par\vspace{\baselineskip}
- \Needspace*{2\baselineskip}
- \noindent
- \textbf{\XSIMmixedcase{\GetExerciseName}~\GetExerciseProperty{counter}}%
- \GetExercisePropertyT{subtitle}{ \textit{#1}} % <<< notice the space
- \IfInsideSolutionF{%
- \GetExercisePropertyT{points}{%
- \marginpar{%
- \printgoal{\PropertyValue}%
- \GetExercisePropertyT{bonus-points}{+\printgoal{\PropertyValue}}%
- \,\IfExerciseGoalSingularTF{points}
- {\XSIMtranslate{point}}
- {\XSIMtranslate{points}}%
- }%
- }%
- }%
- }
- {}
-
-\RequirePackage{array}
-
-\DeclareExerciseEnvironmentTemplate{margin}
- {%
- \trivlist
- \item[\llap{%
- \smash{%
- \tabular[t]{@{}r@{}}
- \textbf{\XSIMmixedcase{\GetExerciseName}~\GetExerciseProperty{counter}}
- \IfExercisePropertySetT{points}{%
- \tabularnewline
- (%
- \printgoal{\GetExerciseProperty{points}}%
- \GetExercisePropertyT{bonus-points}{+\printgoal{#1}}%
- \,\XSIMtranslate{point-abbr}%
- )%
- }%
- \endtabular
- }%
- }]\relax
- }
- {\endtrivlist}
-
-\DeclareExerciseEnvironmentTemplate{inline}
- {%
- \textbf{\GetExerciseProperty{counter}}%
- \IfInsideSolutionF{%
- \GetExercisePropertyT{points}{ % <<< notice the space
- (\printgoal{\PropertyValue}%
- \GetExercisePropertyT{bonus-points}{+\printgoal{\PropertyValue}}%
- \,\IfExerciseGoalSingularTF{points}
- {\XSIMtranslate{point}}
- {\XSIMtranslate{points}})%
- }%
- } % <<< notice the space
- }
- {}
-
-\DeclareExerciseEnvironmentTemplate{minimal}
- {\par\UseExerciseTemplate{begin}{inline}}
- {\UseExerciseTemplate{end}{inline}\par}
-
-\DeclareExerciseEnvironmentTemplate{centered}
- {%
- \par\vspace{\baselineskip}
- \Needspace*{2\baselineskip}
- \noindent
- \hfil\textbf{\XSIMmixedcase{\GetExerciseName}~\GetExerciseProperty{counter}}%
- \GetExercisePropertyT{subtitle}{ \textit{#1}}\hfil
- \par\noindent
- \IfInsideSolutionF{%
- \GetExercisePropertyT{points}{%
- \marginpar{%
- \printgoal{\PropertyValue}%
- \GetExercisePropertyT{bonus-points}{+\printgoal{\PropertyValue}}%
- \,\IfExerciseGoalSingularTF{points}
- {\XSIMtranslate{point}}
- {\XSIMtranslate{points}}%
- }%
- }%
- }%
- }
- {}
-
-% ----------------------------------------------------------------------------
-\endinput
-
-2020/02/23 - added: inline, centered
- - adapt to removed \par from the generic environments
diff --git a/Master/texmf-dist/tex/latex/xsim/xsim.tags.code.tex b/Master/texmf-dist/tex/latex/xsim/xsim.tags.code.tex
deleted file mode 100644
index f97c1af8892..00000000000
--- a/Master/texmf-dist/tex/latex/xsim/xsim.tags.code.tex
+++ /dev/null
@@ -1,211 +0,0 @@
-% ----------------------------------------------------------------------------
-% the XSIM package - tags 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{tags}{tagging of exercises}
-
-\xsim_load_modules:n {properties}
-
-\seq_new:N \l__xsim_tag_types_seq
-\bool_new:N \l____xsim_tagged_bool
-
-\cs_new_protected:Npn \xsim_set_seq_from_clist:Nn #1#2
- {
- \seq_clear:N #1
- \clist_map_inline:nn {#2}
- { \tl_if_blank:nF {##1} { \seq_put_right:Nn #1 {##1} } }
- }
-\cs_generate_variant:Nn \xsim_set_seq_from_clist:Nn {c,Nx}
-
-\msg_new:nnn {xsim} {tag-exists}
- { The~ tag~ type~ `#1'~ already~ exists.~ I~ am~ doing~ nothing. }
-
-% #1: name
-\cs_new_protected:Npn \xsim_new_tag_type:n #1
- {
- \xsim_verbose:n { Declaring~ new~ tag~ type~ `#1'. }
- \seq_put_right:Nn \l__xsim_tag_types_seq {#1}
- \seq_remove_duplicates:N \l__xsim_tag_types_seq
- \seq_new:c {l__xsim_chosen_tags_#1_seq}
- \bool_new:c {l__xsim_ignore_untagged_#1_bool}
- \bool_new:c {l____xsim_tagged_#1_bool}
- \keys_define:nn {xsim}
- {
- #1/ignore-untagged .bool_set:c = {l__xsim_ignore_untagged_#1_bool} ,
- #1/ignore-untagged .initial:n = true ,
- #1 .code:n =
- \xsim_set_seq_from_clist:cn {l__xsim_chosen_tags_#1_seq} {##1}
- }
- \prg_new_protected_conditional:cpnn {xsim_if_#1_value:n} ##1 {T,F,TF}
- {
- \seq_if_in:cnTF {l__xsim_chosen_tags_#1_seq} {##1}
- { \prg_return_true: }
- { \prg_return_false: }
- }
- \xsim_declare_property:nnnn
- { \c_false_bool }
- { \c_false_bool }
- { \c_false_bool }
- {#1}
- \xsim_declare_printsolutions_condition:nn {#1}
- { \__xsim_printsolutions_if_tagged:nnnnTF {#1} }
- \keys_define:nn {xsim/print-solutions}
- {
- #1 .choice: ,
- #1/false .code:n =
- \__xsim_printsolutions_condition:nn {#1} {false} ,
- #1/true .code:n =
- \__xsim_printsolutions_condition:nn {#1} {true} ,
- #1/unknown .code:n =
- \keys_set:nn {xsim} { #1 = ##1 }
- \__xsim_printsolutions_condition:nn {#1} {true} ,
- #1 .initial:n = false
- }
- }
-
-% #1: tag type
-\prg_new_protected_conditional:Npnn \xsim_if_tag_type_exist:n #1 {T,F,TF}
- {
- \seq_if_in:NnTF \l__xsim_tag_types_seq {#1}
- { \prg_return_true: }
- { \prg_return_false: }
- }
-
-% #1: tag type
-% #2: exercise type
-% #3: id
-% #4: print|use
-\prg_new_protected_conditional:Npnn
- \__xsim_printsolutions_if_tagged:nnnn #1#2#3#4 {T,F,TF}
- {
- \xsim_if_in_list:nnTF {#4} {#2-#3=={true}}
- {
- \__xsim_printsolutions_if_condition:nTF {#1}
- {
- \__xsim_printsolutions_condition_true:
- \xsim_if_tagged:nnnTF {#2} {#3} {#1}
- { \prg_return_true: }
- { \prg_return_false: }
- }
- { \prg_return_false: }
- }
- { \prg_return_false: }
- }
-
-% #1: exercise type
-% #2: id
-% #3: tag type
-\prg_new_protected_conditional:Npnn \xsim_if_tagged:nnn #1#2#3 {T,F,TF}
- {
- \bool_set_false:c {l____xsim_tagged_#3_bool}
- \seq_if_empty:cTF {l__xsim_chosen_tags_#3_seq}
- { \bool_set_true:c {l____xsim_tagged_#3_bool} }
- {
- \xsim_set_seq_from_clist:Nx
- \l__xsim_tmpa_seq
- { \xsim_get_property:nnn {#1} {#2} {#3} }
- \seq_if_empty:NTF \l__xsim_tmpa_seq
- {
- \bool_set_eq:cc
- {l____xsim_tagged_#3_bool}
- {l__xsim_ignore_untagged_#3_bool}
- }
- {
- \seq_map_inline:Nn \l__xsim_tmpa_seq
- {
- \seq_if_in:cnT {l__xsim_chosen_tags_#3_seq} {##1}
- {
- \bool_set_true:c {l____xsim_tagged_#3_bool}
- \seq_map_break:
- }
- }
- }
- }
- \bool_if:cTF {l____xsim_tagged_#3_bool}
- { \prg_return_true: }
- { \prg_return_false: }
- }
-
-% #1: exercise type
-% #2: id
-\prg_new_protected_conditional:Npnn \xsim_if_tagged:nn #1#2 {T,F,TF}
- {
- \bool_set_true:N \l____xsim_tagged_bool
- \seq_map_inline:Nn \l__xsim_tag_types_seq
- {
- \xsim_if_tagged:nnnF {#1} {#2} {##1}
- {
- \bool_set_false:N \l____xsim_tagged_bool
- \seq_map_break:
- }
- }
- \bool_if:NTF \l____xsim_tagged_bool
- { \prg_return_true: }
- { \prg_return_false: }
- }
-
-
-% #1: exercise type
-% #2: id
-% #3: tag type
-% #4: code
-\cs_new_protected:Npn \xsim_foreach_exercise_tag:nnnn #1#2#3#4
- {
- \xsim_set_seq_from_clist:Nx \l__xsim_tmpa_seq
- { \xsim_get_property:nnn {#1} {#2} {#3} }
- \seq_map_inline:Nn \l__xsim_tmpa_seq {#4}
- }
-\cs_generate_variant:Nn \xsim_foreach_exercise_tag:nnnn {oo}
-
-% #1: exercise type
-% #2: id
-% #3: tag type
-% #4: sep
-\cs_new_protected:Npn \xsim_exercise_tags_use:nnnn #1#2#3#4
- {
- \xsim_set_seq_from_clist:Nx \l__xsim_tmpa_seq
- { \xsim_get_property:nnn {#1} {#2} {#3} }
- \seq_use:Nn \l__xsim_tmpa_seq {#4}
- }
-\cs_generate_variant:Nn \xsim_exercise_tags_use:nnnn {oo}
-
-% #1: exercise type
-% #2: id
-% #3: tag type
-% #4: sep between two
-% #5: sep between more than two
-% #6: sep between last two
-\cs_new_protected:Npn \xsim_exercise_tags_use:nnnnnn #1#2#3#4#5#6
- {
- \xsim_set_seq_from_clist:Nx \l__xsim_tmpa_seq
- { \xsim_get_property:nnn {#1} {#2} {#3} }
- \seq_use:Nnnn \l__xsim_tmpa_seq {#4} {#5} {#6}
- }
-\cs_generate_variant:Nn \xsim_exercise_tags_use:nnnn {oo}
-\cs_generate_variant:Nn \xsim_exercise_tags_use:nnnnnn {oo}
-
-% ----------------------------------------------------------------------------
-\file_input_stop:
diff --git a/Master/texmf-dist/tex/latex/xsim/xsim.templates.code.tex b/Master/texmf-dist/tex/latex/xsim/xsim.templates.code.tex
deleted file mode 100644
index f14d7fc87e3..00000000000
--- a/Master/texmf-dist/tex/latex/xsim/xsim.templates.code.tex
+++ /dev/null
@@ -1,182 +0,0 @@
-% ----------------------------------------------------------------------------
-% the XSIM package - templates 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{templates}{templates for typesetting exercises}
-
-\xsim_load_modules:n {base}
-
-\msg_new:nnn {xsim} {unknown-template}
- {
- You~ are~ trying~ to~ load~ the~ template~ `#2'~ (template~ type~ `#1')~
- \msg_line_context: .~ This~ template~ does~ not~ seem~ to~ be~ defined.~
- 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
- {
- \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
-% #2: template name
-% #3: code
-\cs_new_protected:Npn \__xsim_add_template:nnn #1#2#3
- {
- \xsim_verbose:n { Defining~ new~ template~ `#2'~ of~ type~ `#1'. }
- \tl_new:c {l__xsim_template_#1_#2_setup_tl}
- \xsim_attribute_set:nnn {template::#1} {#2} {#3}
- }
-
-\prg_new_conditional:Npnn \xsim_if_template_exist:nn #1#2 {T,F,TF}
- {
- \xsim_attribute_if_set:nnTF {template::#1} {#2}
- { \prg_return_true: }
- { \prg_return_false: }
- }
-
-% #1: template type
-% #2: template name
-\cs_new_protected:Npn \__xsim_get_template:nn #1#2
- { \xsim_attribute_get:nn {template::#1} {#2} }
-
-% ----------------------------------------------------------------------------
-
-% environment templates (types `begin' and `end'):
-\xsim_new_template_type:n {begin}
-\xsim_new_template_type:n {end}
-
-% #1: template name
-% #2: begin code
-% #3: end code
-\cs_new_protected:Npn \xsim_declare_environment_template:nnn #1#2#3
- {
- \__xsim_add_template:nnn {begin} {#1}
- {
- \__xsim_start_template:nn {begin} {#1}
- \__xsim_start_template:nn {end} {#1}
- #2
- }
- \__xsim_add_template:nnn {end} {#1}
- {
- #3
- \__xsim_stop_template:nn {end} {#1}
- \__xsim_stop_template:nn {begin} {#1}
- }
- }
-
-% ----------------------------------------------------------------------------
-
-% heading templates for the solution list (type `heading'):
-\xsim_new_template_type:n {heading}
-
-% #1: template name
-% #2: code
-\cs_new_protected:Npn \xsim_declare_heading_template:nn #1#2
- {
- \__xsim_add_template:nnn {heading} {#1}
- {
- \__xsim_start_template:nn {heading} {#1}
- #2
- \__xsim_stop_template:nn {heading} {#1}
- }
- }
-
-% ----------------------------------------------------------------------------
-
-% grading table templates (type `table'):
-\xsim_new_template_type:n {table}
-
-% #1: template name
-% #2: code
-\cs_new_protected:Npn \xsim_declare_table_template:nn #1#2
- {
- \__xsim_add_template:nnn {table} {#1}
- {
- \__xsim_start_template:nn {table} {#1}
- #2
- \__xsim_stop_template:nn {table} {#1}
- }
- }
-
-% ----------------------------------------------------------------------------
-
-% using templates:
-% setup up the next usage of `template name':
-% #1: template type
-% #2: template name
-% #3: setup code
-\cs_new_protected:Npn \xsim_setup_template:nnn #1#2#3
- { \tl_set:cn {l__xsim_template_#1_#2_setup_tl} {#3} }
-\cs_generate_variant:Nn \xsim_setup_template:nnn {nnV,nVn}
-
-% #1: template type
-% #2: template name
-\cs_new_protected:Npn \__xsim_setup_template:nn #1#2
- { \tl_use:c {l__xsim_template_#1_#2_setup_tl} }
-
-% #1: template type
-% #2: template name
-\cs_new_protected:Npn \__xsim_clear_template_setup:nn #1#2
- { \tl_clear:c {l__xsim_template_#1_#2_setup_tl} }
-
-% #1: template type
-% #2: template name
-\cs_new_protected:Npn \__xsim_start_template:nn #1#2
- { \group_begin: \__xsim_setup_template:nn {#1} {#2} }
-
-% #1: template type
-% #2: template name
-\cs_new_protected:Npn \__xsim_stop_template:nn #1#2
- { \group_end: \__xsim_clear_template_setup:nn {#1} {#2} }
-
-% #1: template type
-% #2: template name
-\cs_new_protected:Npn \xsim_use_template:nn #1#2
- {
- \xsim_if_template_exist:nnTF {#1} {#2}
- { \__xsim_get_template:nn {#1} {#2} }
- {
- \msg_warning:nnnnn {xsim} {unknown-template} {#1} {#2} {default}
- \__xsim_get_template:nn {#1} {default}
- }
- }
-\cs_generate_variant:Nn \xsim_use_template:nn {nx,nV}
-
-% ----------------------------------------------------------------------------
-\file_input_stop:
diff --git a/Master/texmf-dist/tex/latex/xsim/xsim.translations.code.tex b/Master/texmf-dist/tex/latex/xsim/xsim.translations.code.tex
deleted file mode 100644
index b9f0712b4b8..00000000000
--- a/Master/texmf-dist/tex/latex/xsim/xsim.translations.code.tex
+++ /dev/null
@@ -1,147 +0,0 @@
-% ----------------------------------------------------------------------------
-% the XSIM package - translations 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{translations}{language settings for XSIM}
-
-\RequirePackage{translations}
-
-\msg_new:nnn {xsim} {language-not-defined}
- {
- You~ chose~ the~ language~ `#1'~ which~ is~ not~ defined~ by~ xsim.~
- `english'~ is~ used~ instead.~ If~ you~ just~ mistyped~ try~ again!~
- Otherwise~ contact~ the~ author~ and~ he'll~ probably~ add~ your~ language.
- }
-
-% --------------------------------------------------------------------------
-
-\bool_new:N \l__xsim_language_auto_bool
-\bool_set_true:N \l__xsim_language_auto_bool
-% this token list will hold the chosen language for xsim; since the
-% language is either chosen automatically or by option it is only available at
-% begin document
-\tl_new:N \l_xsim_language_tl
-\tl_set:Nn \l_xsim_language_tl {english}
-\tl_new:N \l__xsim_current_language_tl
-
-\tl_const:Nn \c__xsim_keyword_prefix_tl {xsim-keyword-}
-
-% ----------------------------------------------------------------------------
-
-\prop_new:N \g_xsim_translations_prop
-
-% translate the key #1
-\cs_new:Npn \xsim_translate:n #1
- {
- \bool_if:NTF \l__xsim_language_auto_bool
- { \GetTranslation { \c__xsim_keyword_prefix_tl #1 } }
- {
- \GetTranslationFor
- { \l_xsim_language_tl }
- { \c__xsim_keyword_prefix_tl #1 }
- }
- }
-
-\xsim_at_begin_document:n
- {
- \bool_if:NTF \l__xsim_language_auto_bool
- {
- \tl_set:Nx \l_xsim_language_tl
- { \@trnslt@language{\@trnslt@current@language} }
- }
- {
- \tl_set_eq:NN
- \l_xsim_language_tl
- \l__xsim_current_language_tl
- }
- }
-
-% ----------------------------------------------------------------------------
-% #1: keyword
-% #2: language
-% #3: translation
-\cs_new_protected:Npn \__xsim_declare_translation:nw #1#2=#3\q_stop
- {
- \tl_set:Nx \l__xsim_tmpa_tl { \tl_trim_spaces:n {#2} }
- \tl_set:Nx \l__xsim_tmpb_tl { \tl_trim_spaces:n {#3} }
- \xsim_declare_translation:VnV
- \l__xsim_tmpa_tl
- {#1}
- \l__xsim_tmpb_tl
- }
-
-% #1: language
-% #2: keyword
-% #3: translation
-\cs_new_protected:Npn \xsim_declare_translation:nnn #1#2#3
- {
- \xsim_verbose:n
- { Declaring~ `#1'~ tranlation~ of~ `#2':~ `#3'. }
- \declaretranslation
- {#1}
- { \c__xsim_keyword_prefix_tl #2 }
- {#3}
- \prop_gput:Nnn \g_xsim_translations_prop {#2(#1)} {#3}
- }
-\cs_generate_variant:Nn \xsim_declare_translation:nnn {V,VnV}
-
-% #1: key
-% #2: csv list: { <lang1> = <translation1> , <lang2> = <translation2> }
-\cs_new_protected:Npn \xsim_declare_translations:nn #1#2
- {
- \clist_map_inline:nn {#2}
- { \__xsim_declare_translation:nw {#1} ##1 \q_stop }
- }
-
-\cs_new:Npn \__xsim_parse_translate_list_entry:nnn #1#2#3 {}
-
-\cs_new_protected:Npn \__xsim_parse_translate_list_entry:www #1(#2)\q_mark#3\q_stop
- { \__xsim_parse_translate_list_entry:nnn {#1} {#2} {#3} }
-
-\cs_new_protected:Npn \xsim_for_all_translations_do:n #1
- {
- \cs_set:Npn \__xsim_parse_translate_list_entry:nnn ##1##2##3 {#1}
- \prop_map_inline:Nn \g_xsim_translations_prop
- { \__xsim_parse_translate_list_entry:www ##1 \q_mark ##2 \q_stop }
- }
-
-% ----------------------------------------------------------------------------
-
-\keys_define:nn {xsim}
- {
- language .value_required:n = true ,
- language .code:n =
- \tl_if_eq:nnTF {#1} {auto}
- { \bool_set_true:N \l__xsim_language_auto_bool }
- {
- \bool_set_false:N \l__xsim_language_auto_bool
- \tl_set:Nn \l__xsim_current_language_tl {#1}
- } ,
- language .initial:n = auto
- }
-
-% ----------------------------------------------------------------------------
-\file_input_stop:
diff --git a/Master/texmf-dist/tex/latex/xsim/xsim.verbwrite.code.tex b/Master/texmf-dist/tex/latex/xsim/xsim.verbwrite.code.tex
deleted file mode 100644
index e43c30d34d7..00000000000
--- a/Master/texmf-dist/tex/latex/xsim/xsim.verbwrite.code.tex
+++ /dev/null
@@ -1,217 +0,0 @@
-% ----------------------------------------------------------------------------
-% the XSIM package - verbwrite 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{verbwrite}{write contents of environments verbatim to files}
-
-\xsim_load_modules:n {base}
-
-\iow_new:N \l__xsim_file_contents_iow
-\tl_new:N \l_xsim_file_begin_tl
-\tl_new:N \l_xsim_file_end_tl
-\int_new:N \l_xsim_line_gobble_int
-\int_zero:N \l_xsim_line_gobble_int
-
-\tl_const:Nx \c__xsim_backslash_char_tl { \cs_to_str:N \\ }
-
-\group_begin:
- \char_set_catcode_other:n {37}
- \tl_const:Nn \c__xsim_percent_char_tl {%}
-\group_end:
-
-% ----------------------------------------------------------------------------
-
-% the `final' option will prevent writing to files:
-% #1: write stream
-% #2: file name
-\cs_new_protected:Npn \__xsim_open_stream:Nn #1#2
- {
- \file_if_exist:nTF {#2}
- { \xsim_if_final:F { \iow_open:Nn #1 {#2} } }
- {
- % \g__xsim_final_bool is a global variable; however, if it is true and
- % the exercise file doesn't exist, yet, we need to set it locally to
- % false in order to ensure that the file is correctly written and the
- % stream closed afterwards
- \bool_set_false:N \g__xsim_final_bool
- \iow_open:Nn #1 {#2}
- }
- }
-
-% #1: write stream
-\cs_new_protected:Npn \__xsim_close_stream:N #1
- { \xsim_if_final:F { \iow_close:N #1 } }
-
-% #1: write stream
-% #2: contents
-\cs_new_protected:Npn \__xsim_write_to_stream:Nn #1#2
- {
- \xsim_if_final:F
- {
- % remove the /one/ space token with catcode 10 that is inserted if
- % no options are given to the surrounding environment:
- \tl_set:Nn \l__xsim_tmpa_tl {#2}
- \tl_remove_once:Nn \l__xsim_tmpa_tl {~}
- % \tl_show:N \l__xsim_tmpa_tl
- % \int_show:n { \tl_count:N \l__xsim_tmpa_tl }
- % \tl_analysis_show:N \l__xsim_tmpa_tl
- \int_zero:N \l__xsim_tmpa_int
- \int_while_do:nn { \l__xsim_tmpa_int < \l_xsim_line_gobble_int }
- {
- \int_incr:N \l__xsim_tmpa_int
- \tl_set:Nx \l__xsim_tmpa_tl { \tl_tail:N \l__xsim_tmpa_tl }
- }
- \iow_now:NV #1 \l__xsim_tmpa_tl
- }
- }
-\cs_generate_variant:Nn \__xsim_write_to_stream:Nn {Nx}
-
-\cs_new:Npn \__xsim_tab: { \c_space_tl \c_space_tl }
-\cs_new:Npn \__xsim_par: { ^^J ^^J }
-
-% the following is inspired by the definition of the `filecontents'
-% environment:
-% #1: boolean - if true an active eol needs to be inserted before
-% starting to write
-% #2: file name
-\cs_new_protected:Npn \xsim_file_write_start:nn #1#2
- {
- % we need to insert an active ^^M if no options are given
- % see http://tex.stackexchange.com/q/9035/5049 reasons
- \use:nx
- { \__xsim_file_write_start:n {#2} }
- { \bool_if:nF {#1} { \exp_not:V \c__xsim_active_eol_tl } }
- }
-\cs_generate_variant:Nn \xsim_file_write_start:nn {nV}
-
-\cs_new_protected:Npn \__xsim_set_verb_catcodes:
- {
- \seq_map_inline:Nn \l_char_special_seq
- { \char_set_catcode_other:N ##1 }
- \int_step_inline:nnnn {128} {1} {255}
- { \char_set_catcode_letter:n {##1} }
- }
-
-\group_begin:
-\char_set_catcode_active:n {13} % ^^M (carriage return, endlinechar)
-\char_set_catcode_active:n {12} % ^^L (form feed)
-\char_set_catcode_active:n {9} % ^^I (horizontal tab)
-%
-\tl_const:Nn \c__xsim_active_eol_tl {^^M} %
-%
-% #1: file name
-\cs_new_protected:Npn \__xsim_file_write_start:n #1 %
- { %
- \group_begin: %
- \xsim_if_final:TF %
- { \xsim_verbose:x { Not~ (re-)writing~ file~ `#1'. } } %
- { \xsim_verbose:x { (Re-)writing~ file~ `#1'. } } %
- \__xsim_open_stream:Nn \l__xsim_file_contents_iow {#1} %
- \tl_if_blank:VF \l_xsim_file_begin_tl %
- { %
- \xsim_if_final:F %
- { %
- \iow_now:Nx \l__xsim_file_contents_iow %
- { \l_xsim_file_begin_tl } %
- } %
- } %
- \__xsim_set_verb_catcodes: %
- \tl_set:Nx \l__xsim_tmpa_tl %
- { \c__xsim_backslash_char_tl end \cs_to_str:N \{ \@currenvir \cs_to_str:N \} } %
- \use:x %
- { %
- \cs_set:cpn {__xsim_tmpa:www} %
- ####1 \l__xsim_tmpa_tl %
- ####2 \l__xsim_tmpa_tl %
- ####3 \exp_not:N \q_stop: %
- } %
- { %
- \tl_if_blank:nTF {##3} %
- { \__xsim_write_to_stream:Nn \l__xsim_file_contents_iow {##1} } %
- { %
- \cs_set:Npx \__xsim_M:w { \exp_not:N \end {\@currenvir} } %
- \char_set_active_eq:nN {13} \__xsim_M:w %
- % the last line is `##1 \end{\@currenvir} ##2':
- \tl_if_blank:nF {##1} %
- { \__xsim_write_to_stream:Nn \l__xsim_file_contents_iow {##1} }%
- \tl_if_blank:nF {##2} %
- {} %
- } %
- ^^M %
- } %
- \char_set_catcode_active:n {13} %
- \char_set_catcode_active:n {12} %
- \char_set_catcode_active:n {9} %
- \cs_set:Npx \__xsim_M:w ##1 ^^M %
- { %
- \exp_not:N \__xsim_tmpa:www ##1 %
- \l__xsim_tmpa_tl %
- \l__xsim_tmpa_tl %
- \exp_not:N \q_stop: %
- } %
- \char_set_active_eq:nN {13} \__xsim_M:w %
- \char_set_active_eq:nN {12} \__xsim_par: %
- \char_set_active_eq:nN {9} \__xsim_tab: %
- } %
-\group_end:
-
-\cs_new_protected:Npn \xsim_file_write_stop:
- {
- \tl_if_blank:VF \l_xsim_file_end_tl
- {
- \xsim_if_final:F
- {
- \iow_now:Nx \l__xsim_file_contents_iow
- { \l_xsim_file_end_tl }
- }
- }
- \__xsim_close_stream:N \l__xsim_file_contents_iow
- \group_end:
- }
-
-% ----------------------------------------------------------------------------
-
-\NewDocumentCommand \XSIMfilewritestart {sm}
- {
- \IfBooleanTF {#1}
- { \xsim_file_write_start:nn { \c_false_bool } {#2} }
- { \xsim_file_write_start:nn { \c_true_bool } {#2} }
- }
-
-\NewDocumentCommand \XSIMfilewritestop {}
- { \xsim_file_write_stop: }
-
-\NewDocumentCommand \XSIMsetfilebegin {+m}
- { \tl_set:Nn \l_xsim_file_begin_tl {#1} }
-
-\NewDocumentCommand \XSIMsetfileend {+m}
- { \tl_set:Nn \l_xsim_file_end_tl {#1} }
-
-\NewDocumentCommand \XSIMgobblechars {m}
- { \int_set:Nn \l_xsim_line_gobble_int {#1} }
-
-% ----------------------------------------------------------------------------
-\file_input_stop:
diff --git a/Master/texmf-dist/tex/latex/xsim/xsimverb.sty b/Master/texmf-dist/tex/latex/xsim/xsimverb.sty
index 90373e9021d..712440d4231 100644
--- a/Master/texmf-dist/tex/latex/xsim/xsimverb.sty
+++ b/Master/texmf-dist/tex/latex/xsim/xsimverb.sty
@@ -8,15 +8,15 @@
% Web: https://github.com/cgnieder/xsim
% E-Mail: contact@mychemistry.eu
% ----------------------------------------------------------------------------
-% Copyright 2017--2020 Clemens Niederberger
+% Copyright 2017--2021 Clemens Niederberger
%
% This work may be distributed and/or modified under the
-% conditions of the LaTeX Project Public License, either version 1.3
+% conditions of the LaTeX Project Public License, either version 1.3c
% 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.
+% and version 1.3c or later is part of all distributions of LaTeX
+% version 2008/05/04 or later.
%
% This work has the LPPL maintenance status `maintained'.
%
@@ -25,14 +25,13 @@
% If you have any ideas, questions, suggestions or bugs to report, please
% feel free to contact me.
% ----------------------------------------------------------------------------
-
-\RequirePackage {expl3}
+\RequirePackage {l3keys2e}
\ExplSyntaxOn
-\tl_const:Nn \c_xsimverb_date_tl {2019/12/29}
+\tl_const:Nn \c_xsimverb_date_tl {2021/01/31}
\tl_const:Nn \c_xsimverb_version_major_number_tl {0}
-\tl_const:Nn \c_xsimverb_version_minor_number_tl {1}
-\tl_const:Nn \c_xsimverb_version_subrelease_tl {a}
+\tl_const:Nn \c_xsimverb_version_minor_number_tl {3}
+\tl_const:Nn \c_xsimverb_version_subrelease_tl {}
\tl_const:Nx \c_xsimverb_version_number_tl
{
\c_xsimverb_version_major_number_tl .
@@ -51,9 +50,6 @@
{\c_xsimverb_version_tl}
{\c_xsimverb_info_tl}
-\@ifpackageloaded {xsim} { \file_input_stop: } {}
-\RequirePackage {xparse,l3keys2e}
-
% options, information
\cs_new_protected:Npn \xsimverb_bool_provide:N #1
@@ -65,33 +61,251 @@
\xsimverb_bool_provide:N \g__xsim_write_to_file_bool
\xsimverb_bool_provide:N \g_xsim_use_aux_bool
\xsimverb_bool_provide:N \g__xsim_rerun_bool
+\xsimverb_bool_provide:N \g__xsim_debug_bool
+\xsimverb_bool_provide:N \g__xsim_blank_bool
\keys_define:nn {xsimverb}
{
- final .bool_gset:N = \g__xsim_final_bool ,
- verbose .bool_gset:N = \g__xsim_verbose_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 ,
- use-aux .bool_gset:N = \g_xsim_use_aux_bool ,
- use-aux .initial:n = false
+ 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 ,
+ use-files .bool_gset:N = \g__xsim_write_to_file_bool ,
+ use-files .initial:n = false ,
+ no-files .choice: ,
+ no-files / true .meta:n = { use-files = false } ,
+ no-files / false .meta:n = { use-files = true } ,
+ no-files .default:n = true ,
+ use-aux .bool_gset:N = \g_xsim_use_aux_bool ,
+ use-aux .initial:n = false ,
+ blank .bool_gset:N = \g__xsim_blank_bool ,
+ blank .initial:n = false
}
\ProcessKeysPackageOptions {xsimverb}
-% --------------------------------------------------------------------------
+\cs_if_exist:NF \xsim_if_final:T
+ {
+ \prg_new_conditional:Npnn \xsim_if_final: {p,T,F,TF}
+ {
+ \bool_if:NTF \g__xsim_final_bool
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
-% load module mechanism:
-\tl_set:Nn \l_tmpa_tl {code.tex}
-\@onefilewithoptions {xsim.modules} [][] \l_tmpa_tl
+ \prg_new_conditional:Npnn \xsim_if_verbose: {p,T,F,TF}
+ {
+ \bool_if:NTF \g__xsim_verbose_bool
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+ }
+\cs_if_exist:NF \xsim_verbose:n
+ {
+ \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}
+ }
+
% --------------------------------------------------------------------------
-
-\xsim_load_module:n {verbwrite}
+% #1: name
+% #2: description
+\cs_set_protected:Npn \XSIMmodule #1#2 {}
+\cs_set_protected:Npn \XSIMmoduleend {}
% --------------------------------------------------------------------------
-\file_input_stop:
+\XSIMmodule{verbwrite}{write contents of environments verbatim to files}
+
+\int_new:N \l__xsimverb_tmpa_int
+\tl_new:N \l__xsimverb_tmpa_tl
+
+\iow_new:N \l__xsim_file_contents_iow
+\tl_new:N \l_xsim_file_begin_tl
+\tl_new:N \l_xsim_file_end_tl
+\int_new:N \l_xsim_line_gobble_int
+\int_zero:N \l_xsim_line_gobble_int
+
+\tl_const:Nx \c__xsim_backslash_char_tl { \cs_to_str:N \\ }
+
+\group_begin:
+ \char_set_catcode_other:n {37}
+ \tl_const:Nn \c__xsim_percent_char_tl {%}
+\group_end:
+
+% ----------------------------------------------------------------------------
+\bool_new:N \l__xsim_stream_open_bool
+% the `final' option will prevent writing to files:
+% #1: write stream
+% #2: file name
+\cs_new_protected:Npn \__xsim_open_stream:Nn #1#2
+ {
+ \file_if_exist:nTF {#2}
+ {
+ \xsim_if_final:F
+ {
+ \bool_set_true:N \l__xsim_stream_open_bool
+ \iow_open:Nn #1 {#2}
+ }
+ }
+ {
+ \bool_set_true:N \l__xsim_stream_open_bool
+ \iow_open:Nn #1 {#2}
+ }
+ }
+
+% #1: write stream
+\cs_new_protected:Npn \__xsim_close_stream:N #1
+ { \bool_if:NT \l__xsim_stream_open_bool { \iow_close:N #1 } }
+
+% #1: write stream
+% #2: contents
+\cs_new_protected:Npn \__xsim_write_to_stream:Nn #1#2
+ {
+ \xsim_if_final:F
+ {
+ % remove the /one/ space token with catcode 10 that is inserted if
+ % no options are given to the surrounding environment:
+ \tl_set:Nn \l__xsimverb_tmpa_tl {#2}
+ \tl_remove_once:Nn \l__xsimverb_tmpa_tl {~}
+ % \tl_show:N \l__xsimverb_tmpa_tl
+ % \int_show:n { \tl_count:N \l__xsimverb_tmpa_tl }
+ % \tl_analysis_show:N \l__xsimverb_tmpa_tl
+ \int_zero:N \l__xsimverb_tmpa_int
+ \int_while_do:nn { \l__xsimverb_tmpa_int < \l_xsim_line_gobble_int }
+ {
+ \int_incr:N \l__xsimverb_tmpa_int
+ \tl_set:Nx \l__xsimverb_tmpa_tl { \tl_tail:N \l__xsimverb_tmpa_tl }
+ }
+ \iow_now:NV #1 \l__xsimverb_tmpa_tl
+ }
+ }
+\cs_generate_variant:Nn \__xsim_write_to_stream:Nn {Nx}
+\cs_generate_variant:Nn \iow_now:Nn {NV}
+
+\cs_new:Npn \__xsim_tab: { \c_space_tl \c_space_tl }
+\cs_new:Npn \__xsim_par: { ^^J ^^J }
+
+% the following is inspired by the definition of the `filecontents'
+% environment:
+% #1: boolean - if true an active eol needs to be inserted before
+% starting to write
+% #2: file name
+\cs_new_protected:Npn \xsim_file_write_start:nn #1#2
+ {
+ % we need to insert an active ^^M if no options are given
+ % see http://tex.stackexchange.com/q/9035/5049 reasons
+ \use:nx
+ { \__xsim_file_write_start:n {#2} }
+ { \bool_if:nF {#1} { \exp_not:V \c__xsim_active_eol_tl } }
+ }
+\cs_generate_variant:Nn \xsim_file_write_start:nn {nV}
+\cs_generate_variant:Nn \use:nn {nx}
+
+\cs_new_protected:Npn \__xsim_set_verb_catcodes:
+ {
+ \seq_map_inline:Nn \l_char_special_seq
+ { \char_set_catcode_other:N ##1 }
+ \int_step_inline:nnnn {128} {1} {255}
+ { \char_set_catcode_letter:n {##1} }
+ }
+
+\group_begin:
+\char_set_catcode_active:n {13} % ^^M (carriage return, endlinechar)
+\char_set_catcode_active:n {12} % ^^L (form feed)
+\char_set_catcode_active:n {9} % ^^I (horizontal tab)
+%
+\tl_const:Nn \c__xsim_active_eol_tl {^^M} %
+%
+% #1: file name
+\cs_new_protected:Npn \__xsim_file_write_start:n #1 %
+ { %
+ \group_begin: %
+ \xsim_if_final:TF %
+ { \xsim_verbose:x { Not~ (re-)writing~ file~ `#1'. } } %
+ { \xsim_verbose:x { (Re-)writing~ file~ `#1'. } } %
+ \__xsim_open_stream:Nn \l__xsim_file_contents_iow {#1} %
+ \tl_if_blank:VF \l_xsim_file_begin_tl %
+ { %
+ \xsim_if_final:F %
+ { %
+ \iow_now:Nx \l__xsim_file_contents_iow %
+ { \exp_not:V \l_xsim_file_begin_tl } %
+ } %
+ } %
+ \__xsim_set_verb_catcodes: %
+ \tl_set:Nx \l__xsimverb_tmpa_tl %
+ { \c__xsim_backslash_char_tl end \cs_to_str:N \{ \@currenvir \cs_to_str:N \} } %
+ \use:x %
+ { %
+ \cs_set:cpn {__xsim_tmpa:www} %
+ ####1 \l__xsimverb_tmpa_tl %
+ ####2 \l__xsimverb_tmpa_tl %
+ ####3 \exp_not:N \q_stop: %
+ } %
+ { %
+ \tl_if_blank:nTF {##3} %
+ { \__xsim_write_to_stream:Nn \l__xsim_file_contents_iow {##1} } %
+ { %
+ \cs_set:Npx \__xsim_M:w { \exp_not:N \end {\@currenvir} } %
+ \char_set_active_eq:nN {13} \__xsim_M:w %
+ % the last line is `##1 \end{\@currenvir} ##2':
+ \tl_if_blank:nF {##1} %
+ { \__xsim_write_to_stream:Nn \l__xsim_file_contents_iow {##1} }%
+ \tl_if_blank:nF {##2} %
+ {} %
+ } %
+ ^^M %
+ } %
+ \char_set_catcode_active:n {13} %
+ \char_set_catcode_active:n {12} %
+ \char_set_catcode_active:n {9} %
+ \cs_set:Npx \__xsim_M:w ##1 ^^M %
+ { %
+ \exp_not:N \__xsim_tmpa:www ##1 %
+ \l__xsimverb_tmpa_tl %
+ \l__xsimverb_tmpa_tl %
+ \exp_not:N \q_stop: %
+ } %
+ \char_set_active_eq:nN {13} \__xsim_M:w %
+ \char_set_active_eq:nN {12} \__xsim_par: %
+ \char_set_active_eq:nN {9} \__xsim_tab: %
+ } %
+\group_end:
+
+\cs_new_protected:Npn \xsim_file_write_stop:
+ {
+ \tl_if_blank:VF \l_xsim_file_end_tl
+ {
+ \xsim_if_final:F
+ {
+ \iow_now:Nx \l__xsim_file_contents_iow
+ { \exp_not:V \l_xsim_file_end_tl }
+ }
+ }
+ \__xsim_close_stream:N \l__xsim_file_contents_iow
+ \group_end:
+ }
+
+% ----------------------------------------------------------------------------
+
+\NewDocumentCommand \XSIMfilewritestart {sm}
+ {
+ \IfBooleanTF {#1}
+ { \xsim_file_write_start:nn { \c_false_bool } {#2} }
+ { \xsim_file_write_start:nn { \c_true_bool } {#2} }
+ }
+
+\NewDocumentCommand \XSIMfilewritestop {}
+ { \xsim_file_write_stop: }
+
+\NewDocumentCommand \XSIMsetfilebegin {+m}
+ { \tl_set:Nn \l_xsim_file_begin_tl {#1} }
+
+\NewDocumentCommand \XSIMsetfileend {+m}
+ { \tl_set:Nn \l_xsim_file_end_tl {#1} }
+
+\NewDocumentCommand \XSIMgobblechars {m}
+ { \int_set:Nn \l_xsim_line_gobble_int {#1} }
-2018/01/31 - define xsim's options as dummy options to prevent possible errors
- caused by undefined booleans
-2019/12/29 - adapt to update of xsim
+\XSIMmoduleend