summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/xsim
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2021-02-01 03:00:47 +0000
committerNorbert Preining <norbert@preining.info>2021-02-01 03:00:47 +0000
commit87c74b3292e1c3efc4427ae0536a1d30a0dc8e4b (patch)
tree219447f0cb875a4889a8cac2bea6deb012b7ca7b /macros/latex/contrib/xsim
parent8eab566745f1c61319c17e6a1aeea0f18bcfc34c (diff)
CTAN sync 202102010300
Diffstat (limited to 'macros/latex/contrib/xsim')
-rw-r--r--macros/latex/contrib/xsim/HISTORY (renamed from macros/latex/contrib/xsim/doc/xsim.history)22
-rw-r--r--macros/latex/contrib/xsim/README46
-rw-r--r--macros/latex/contrib/xsim/code/xsim.auxfile.code.tex221
-rw-r--r--macros/latex/contrib/xsim/code/xsim.base.code.tex287
-rw-r--r--macros/latex/contrib/xsim/code/xsim.blanks.code.tex162
-rw-r--r--macros/latex/contrib/xsim/code/xsim.collections.code.tex397
-rw-r--r--macros/latex/contrib/xsim/code/xsim.definitions.code.tex482
-rw-r--r--macros/latex/contrib/xsim/code/xsim.environments.code.tex529
-rw-r--r--macros/latex/contrib/xsim/code/xsim.exercises.code.tex637
-rw-r--r--macros/latex/contrib/xsim/code/xsim.goals.code.tex385
-rw-r--r--macros/latex/contrib/xsim/code/xsim.grades.code.tex153
-rw-r--r--macros/latex/contrib/xsim/code/xsim.interface.code.tex696
-rw-r--r--macros/latex/contrib/xsim/code/xsim.modules.code.tex220
-rw-r--r--macros/latex/contrib/xsim/code/xsim.properties.code.tex540
-rw-r--r--macros/latex/contrib/xsim/code/xsim.random.code.tex315
-rw-r--r--macros/latex/contrib/xsim/code/xsim.solutions.code.tex414
-rw-r--r--macros/latex/contrib/xsim/code/xsim.sty136
-rw-r--r--macros/latex/contrib/xsim/code/xsim.style.layouts.code.tex121
-rw-r--r--macros/latex/contrib/xsim/code/xsim.tags.code.tex211
-rw-r--r--macros/latex/contrib/xsim/code/xsim.templates.code.tex182
-rw-r--r--macros/latex/contrib/xsim/code/xsim.translations.code.tex147
-rw-r--r--macros/latex/contrib/xsim/code/xsimverb.sty97
-rw-r--r--macros/latex/contrib/xsim/doc/examples/xsim.collections.pdfbin33206 -> 0 bytes
-rw-r--r--macros/latex/contrib/xsim/doc/examples/xsim.collections.tex62
-rw-r--r--macros/latex/contrib/xsim/doc/examples/xsim.difficulties.pdfbin31555 -> 0 bytes
-rw-r--r--macros/latex/contrib/xsim/doc/examples/xsim.randomexercises.pdfbin23102 -> 0 bytes
-rw-r--r--macros/latex/contrib/xsim/doc/examples/xsim.texsx-369636.pdfbin46504 -> 0 bytes
-rw-r--r--macros/latex/contrib/xsim/doc/examples/xsim.texsx-391530.pdfbin25040 -> 0 bytes
-rw-r--r--macros/latex/contrib/xsim/doc/xsim.ideas29
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.blanks.pdf (renamed from macros/latex/contrib/xsim/doc/examples/xsim.blanks.pdf)bin29952 -> 38256 bytes
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.blanks.tex (renamed from macros/latex/contrib/xsim/doc/examples/xsim.blanks.tex)1
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.boxed-headings.pdf (renamed from macros/latex/contrib/xsim/doc/examples/xsim.boxed-headings.pdf)bin38376 -> 38372 bytes
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.boxed-headings.tex (renamed from macros/latex/contrib/xsim/doc/examples/xsim.boxed-headings.tex)0
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.code-and-output.pdf (renamed from macros/latex/contrib/xsim/doc/examples/xsim.code-and-output.pdf)bin30938 -> 30939 bytes
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.code-and-output.tex (renamed from macros/latex/contrib/xsim/doc/examples/xsim.code-and-output.tex)2
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.collections.pdfbin0 -> 30259 bytes
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.collections.tex44
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.crossref.pdf (renamed from macros/latex/contrib/xsim/doc/examples/xsim.crossref.pdf)bin38749 -> 38748 bytes
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.crossref.tex (renamed from macros/latex/contrib/xsim/doc/examples/xsim.crossref.tex)2
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.description-list.pdf (renamed from macros/latex/contrib/xsim/doc/examples/xsim.description-list.pdf)bin41167 -> 41171 bytes
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.description-list.tex (renamed from macros/latex/contrib/xsim/doc/examples/xsim.description-list.tex)0
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.different-point-types.pdf (renamed from macros/latex/contrib/xsim/doc/examples/xsim.different-point-types.pdf)bin42153 -> 42156 bytes
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.different-point-types.tex (renamed from macros/latex/contrib/xsim/doc/examples/xsim.different-point-types.tex)0
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.difficulties.pdfbin0 -> 31763 bytes
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.difficulties.tex (renamed from macros/latex/contrib/xsim/doc/examples/xsim.difficulties.tex)0
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.floating.pdf (renamed from macros/latex/contrib/xsim/doc/examples/xsim.floating.pdf)bin37708 -> 37717 bytes
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.floating.tex (renamed from macros/latex/contrib/xsim/doc/examples/xsim.floating.tex)0
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.golatex-80640.pdf (renamed from macros/latex/contrib/xsim/doc/examples/xsim.golatex-80640.pdf)bin46308 -> 46317 bytes
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.golatex-80640.tex (renamed from macros/latex/contrib/xsim/doc/examples/xsim.golatex-80640.tex)1
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.golatex-91339.pdf (renamed from macros/latex/contrib/xsim/doc/examples/xsim.golatex-91339.pdf)bin65379 -> 64956 bytes
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.golatex-91339.tex (renamed from macros/latex/contrib/xsim/doc/examples/xsim.golatex-91339.tex)3
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.grade-distribution.pdf (renamed from macros/latex/contrib/xsim/doc/examples/xsim.grade-distribution.pdf)bin23204 -> 23204 bytes
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.grade-distribution.tex (renamed from macros/latex/contrib/xsim/doc/examples/xsim.grade-distribution.tex)0
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.hints.pdf (renamed from macros/latex/contrib/xsim/doc/examples/xsim.hints.pdf)bin45719 -> 45722 bytes
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.hints.tex (renamed from macros/latex/contrib/xsim/doc/examples/xsim.hints.tex)7
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.issues-49.pdfbin0 -> 95608 bytes
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.issues-49.tex122
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.listings.pdf (renamed from macros/latex/contrib/xsim/doc/examples/xsim.listings.pdf)bin45738 -> 45747 bytes
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.listings.tex (renamed from macros/latex/contrib/xsim/doc/examples/xsim.listings.tex)2
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.listofexercises.pdf (renamed from macros/latex/contrib/xsim/doc/examples/xsim.listofexercises.pdf)bin57220 -> 57220 bytes
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.listofexercises.tex (renamed from macros/latex/contrib/xsim/doc/examples/xsim.listofexercises.tex)0
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.multiplechoice.pdf (renamed from macros/latex/contrib/xsim/doc/examples/xsim.multiplechoice.pdf)bin31016 -> 31019 bytes
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.multiplechoice.tex (renamed from macros/latex/contrib/xsim/doc/examples/xsim.multiplechoice.tex)0
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.pointsums.pdf (renamed from macros/latex/contrib/xsim/doc/examples/xsim.pointsums.pdf)bin28127 -> 28126 bytes
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.pointsums.tex (renamed from macros/latex/contrib/xsim/doc/examples/xsim.pointsums.tex)0
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.randomexercises.pdfbin0 -> 23048 bytes
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.randomexercises.tex (renamed from macros/latex/contrib/xsim/doc/examples/xsim.randomexercises.tex)18
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.texsx-13635.pdf (renamed from macros/latex/contrib/xsim/doc/examples/xsim.texsx-13635.pdf)bin86047 -> 86049 bytes
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.texsx-13635.tex (renamed from macros/latex/contrib/xsim/doc/examples/xsim.texsx-13635.tex)2
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.texsx-155630.pdf (renamed from macros/latex/contrib/xsim/doc/examples/xsim.texsx-155630.pdf)bin20045 -> 20048 bytes
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.texsx-155630.tex (renamed from macros/latex/contrib/xsim/doc/examples/xsim.texsx-155630.tex)3
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.texsx-199360.pdf (renamed from macros/latex/contrib/xsim/doc/examples/xsim.texsx-199360.pdf)bin56153 -> 56106 bytes
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.texsx-199360.tex (renamed from macros/latex/contrib/xsim/doc/examples/xsim.texsx-199360.tex)0
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.texsx-299534.pdf (renamed from macros/latex/contrib/xsim/doc/examples/xsim.texsx-299534.pdf)bin48094 -> 48095 bytes
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.texsx-299534.tex (renamed from macros/latex/contrib/xsim/doc/examples/xsim.texsx-299534.tex)2
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.texsx-305110.pdf (renamed from macros/latex/contrib/xsim/doc/examples/xsim.texsx-305110.pdf)bin36968 -> 36974 bytes
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.texsx-305110.tex (renamed from macros/latex/contrib/xsim/doc/examples/xsim.texsx-305110.tex)0
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.texsx-308883.pdf (renamed from macros/latex/contrib/xsim/doc/examples/xsim.texsx-308883.pdf)bin27155 -> 27157 bytes
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.texsx-308883.tex (renamed from macros/latex/contrib/xsim/doc/examples/xsim.texsx-308883.tex)0
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.texsx-338165.pdf (renamed from macros/latex/contrib/xsim/doc/examples/xsim.texsx-338165.pdf)bin57235 -> 56911 bytes
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.texsx-338165.tex (renamed from macros/latex/contrib/xsim/doc/examples/xsim.texsx-338165.tex)38
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.texsx-350028.pdf (renamed from macros/latex/contrib/xsim/doc/examples/xsim.texsx-350028.pdf)bin130569 -> 130588 bytes
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.texsx-350028.tex (renamed from macros/latex/contrib/xsim/doc/examples/xsim.texsx-350028.tex)80
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.texsx-369065.pdf (renamed from macros/latex/contrib/xsim/doc/examples/xsim.texsx-369065.pdf)bin65721 -> 65714 bytes
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.texsx-369065.tex (renamed from macros/latex/contrib/xsim/doc/examples/xsim.texsx-369065.tex)36
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.texsx-369636.pdfbin0 -> 91296 bytes
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.texsx-369636.tex (renamed from macros/latex/contrib/xsim/doc/examples/xsim.texsx-369636.tex)27
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.texsx-369803.pdf (renamed from macros/latex/contrib/xsim/doc/examples/xsim.texsx-369803.pdf)bin55079 -> 55077 bytes
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.texsx-369803.tex (renamed from macros/latex/contrib/xsim/doc/examples/xsim.texsx-369803.tex)24
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.texsx-370642.pdf (renamed from macros/latex/contrib/xsim/doc/examples/xsim.texsx-370642.pdf)bin28426 -> 28428 bytes
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.texsx-370642.tex (renamed from macros/latex/contrib/xsim/doc/examples/xsim.texsx-370642.tex)0
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.texsx-391530-exercises.tex12
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.texsx-391530.pdfbin0 -> 26102 bytes
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.texsx-391530.tex (renamed from macros/latex/contrib/xsim/doc/examples/xsim.texsx-391530.tex)35
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.texsx-395273.pdf (renamed from macros/latex/contrib/xsim/doc/examples/xsim.texsx-395273.pdf)bin50580 -> 50575 bytes
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.texsx-395273.tex (renamed from macros/latex/contrib/xsim/doc/examples/xsim.texsx-395273.tex)0
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.texsx-466584.pdfbin0 -> 60453 bytes
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.texsx-466584.tex56
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.texsx-498299.pdf (renamed from macros/latex/contrib/xsim/doc/examples/xsim.texsx-498299.pdf)bin42513 -> 42514 bytes
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.texsx-498299.tex (renamed from macros/latex/contrib/xsim/doc/examples/xsim.texsx-498299.tex)1
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.texsx-576998.pdfbin0 -> 49333 bytes
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.texsx-576998.tex135
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.texsx-580636.pdfbin0 -> 51800 bytes
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.texsx-580636.tex92
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.texwelt-15093.pdf (renamed from macros/latex/contrib/xsim/doc/examples/xsim.texwelt-15093.pdf)bin36256 -> 36259 bytes
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.texwelt-15093.tex (renamed from macros/latex/contrib/xsim/doc/examples/xsim.texwelt-15093.tex)1
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.texwelt-23968.pdf (renamed from macros/latex/contrib/xsim/doc/examples/xsim.texwelt-23968.pdf)bin46008 -> 46009 bytes
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.texwelt-23968.tex (renamed from macros/latex/contrib/xsim/doc/examples/xsim.texwelt-23968.tex)7
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.texwelt-6698.pdf (renamed from macros/latex/contrib/xsim/doc/examples/xsim.texwelt-6698.pdf)bin43899 -> 43907 bytes
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.texwelt-6698.tex (renamed from macros/latex/contrib/xsim/doc/examples/xsim.texwelt-6698.tex)1
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.various.pdf (renamed from macros/latex/contrib/xsim/doc/examples/xsim.various.pdf)bin86646 -> 86588 bytes
-rw-r--r--macros/latex/contrib/xsim/examples/xsim.various.tex (renamed from macros/latex/contrib/xsim/doc/examples/xsim.various.tex)3
-rw-r--r--macros/latex/contrib/xsim/xsim-manual.cls (renamed from macros/latex/contrib/xsim/doc/xsim-manual.cls)42
-rw-r--r--macros/latex/contrib/xsim/xsim-manual.pdf (renamed from macros/latex/contrib/xsim/doc/xsim_manual.pdf)bin1269638 -> 1308757 bytes
-rw-r--r--macros/latex/contrib/xsim/xsim-manual.tex (renamed from macros/latex/contrib/xsim/doc/xsim_manual.tex)314
-rw-r--r--macros/latex/contrib/xsim/xsim.sty5629
-rw-r--r--macros/latex/contrib/xsim/xsimverb.sty (renamed from macros/latex/contrib/xsim/code/xsim.verbwrite.code.tex)162
117 files changed, 6570 insertions, 6825 deletions
diff --git a/macros/latex/contrib/xsim/doc/xsim.history b/macros/latex/contrib/xsim/HISTORY
index f1b0f860f7..0d3f7d417a 100644
--- a/macros/latex/contrib/xsim/doc/xsim.history
+++ b/macros/latex/contrib/xsim/HISTORY
@@ -155,4 +155,24 @@ HISTORY:
- new load-time option `debug' - only for development
v0.19a 2020/03/19 - fix missing-variant-bug introduced with the last update
v0.19b 2020/04/04 - fix bug in new attribute mechanism which was a problem
- when `no-files` has been used
+ when `no-files` has been used
+ v0.20 2021/01/31 - switch to one sty file per package
+ - use LaTeX's new hooks
+ - declare undeclared variables
+ - new exercise setup mechanism which clearly determines the
+ difference between definition, usage, and printing of an
+ exercise; this also solves the problem with added goals
+ in the exercise body in a collection
+ - re-write collection mechanism:
+ * changes the behaviour of \collectexercises but doesn't
+ require external files any more and more importantly
+ doesn't require inputting files several times for
+ multiple collections
+ * drop \collectexercisestype
+ * new \(de)activatecollection
+ * new options `collect' and `<type>/collect'
+ - small improvements in performance
+ - new parameters `within' and `the-counter'
+ - make `no-files' the default
+ - new examples
+ - various small fixes
diff --git a/macros/latex/contrib/xsim/README b/macros/latex/contrib/xsim/README
index 5923c8045b..3407220a29 100644
--- a/macros/latex/contrib/xsim/README
+++ b/macros/latex/contrib/xsim/README
@@ -1,6 +1,6 @@
--------------------------------------------------------------------------
-XSIM 2020/04/04 v0.19b
-XSIMVERB 2019/12/29 v0.1a
+XSIM 2021/01/31 v0.20
+XSIMVERB 2021/01/31 v0.3
eXercise Sheets IMproved
@@ -9,15 +9,15 @@ Clemens Niederberger
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'.
@@ -26,30 +26,10 @@ The Current Maintainer of this work is Clemens Niederberger.
The xsim package consists of the code files:
xsim.sty
xsimverb.sty
- xsim.auxfile.code.tex
- xsim.base.code.tex
- xsim.blanks.code.tex
- xsim.collections.code.tex
- xsim.definitions.code.tex
- xsim.environments.code.tex
- xsim.exercises.code.tex
- xsim.goals.code.tex
- xsim.grades.code.tex
- xsim.interface.code.tex
- xsim.modules.code.tex
- xsim.properties.code.tex
- xsim.random.code.tex
- xsim.solutions.code.tex
- xsim.style.layouts.code.tex
- xsim.tags.code.tex
- xsim.templates.code.tex
- xsim.translations.code.tex
- xsim.verbwrite.code.tex
--------------------------------------------------------------------------
The xsim package consists of the documentation files:
- README
- xsim.history, xsim.ideas
- xsim_manual.tex, xsim_manual.pdf
+ README HISTORY
+ xsim-manual.tex, xsim-manual.pdf
xsim-manual.cls
--------------------------------------------------------------------------
The xsim package consists of the example files:
@@ -84,12 +64,16 @@ The xsim package consists of the example files:
xsim.texsx-370642.tex, xsim.texsx-370642.pdf
xsim.texsx-391530.tex, xsim.texsx-391530.pdf
xsim.texsx-395273.tex, xsim.texsx-395273.pdf
- xsim.texsx-498299.tex, xsim.texsx-498299.pdf,
+ xsim.texsx-466584.tex, xsim.texsx-466584.pdf
+ xsim.texsx-498299.tex, xsim.texsx-498299.pdf
+ xsim.texsx-576998.tex, xsim.texsx-576998.pdf
+ xsim.texsx-580636.tex, xsim.texsx-580636.pdf
xsim.texwelt-6698.tex, xsim.texwelt-6698.pdf
xsim.texwelt-15093.tex, xsim.texwelt-15093.pdf
xsim.texwelt-23968.tex, xsim.texwelt-23968.pdf
- xsim.golatex-16824.tex, xsim.golatex-16824.pdf
- xsim.golatex-18844.tex, xsim.golatex-18844.pdf
+ xsim.golatex-80640.tex, xsim.golatex-80640.pdf
+ xsim.golatex-91339.tex, xsim.golatex-91339.pdf
+ xsim.issues-49.tex, xsim.issues-49.pdf
--------------------------------------------------------------------------
If you have any ideas, questions, suggestions or bugs to report, please
feel free to contact me.
diff --git a/macros/latex/contrib/xsim/code/xsim.auxfile.code.tex b/macros/latex/contrib/xsim/code/xsim.auxfile.code.tex
deleted file mode 100644
index 2f31f2009f..0000000000
--- a/macros/latex/contrib/xsim/code/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/macros/latex/contrib/xsim/code/xsim.base.code.tex b/macros/latex/contrib/xsim/code/xsim.base.code.tex
deleted file mode 100644
index fd478455f6..0000000000
--- a/macros/latex/contrib/xsim/code/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/macros/latex/contrib/xsim/code/xsim.blanks.code.tex b/macros/latex/contrib/xsim/code/xsim.blanks.code.tex
deleted file mode 100644
index 6cb2f3b252..0000000000
--- a/macros/latex/contrib/xsim/code/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/macros/latex/contrib/xsim/code/xsim.collections.code.tex b/macros/latex/contrib/xsim/code/xsim.collections.code.tex
deleted file mode 100644
index 5aeb6e2d77..0000000000
--- a/macros/latex/contrib/xsim/code/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/macros/latex/contrib/xsim/code/xsim.definitions.code.tex b/macros/latex/contrib/xsim/code/xsim.definitions.code.tex
deleted file mode 100644
index 5b87fb0f4f..0000000000
--- a/macros/latex/contrib/xsim/code/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/macros/latex/contrib/xsim/code/xsim.environments.code.tex b/macros/latex/contrib/xsim/code/xsim.environments.code.tex
deleted file mode 100644
index ca5f76f80a..0000000000
--- a/macros/latex/contrib/xsim/code/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/macros/latex/contrib/xsim/code/xsim.exercises.code.tex b/macros/latex/contrib/xsim/code/xsim.exercises.code.tex
deleted file mode 100644
index 5314369ffa..0000000000
--- a/macros/latex/contrib/xsim/code/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/macros/latex/contrib/xsim/code/xsim.goals.code.tex b/macros/latex/contrib/xsim/code/xsim.goals.code.tex
deleted file mode 100644
index 67019eb6f3..0000000000
--- a/macros/latex/contrib/xsim/code/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/macros/latex/contrib/xsim/code/xsim.grades.code.tex b/macros/latex/contrib/xsim/code/xsim.grades.code.tex
deleted file mode 100644
index 678011c610..0000000000
--- a/macros/latex/contrib/xsim/code/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/macros/latex/contrib/xsim/code/xsim.interface.code.tex b/macros/latex/contrib/xsim/code/xsim.interface.code.tex
deleted file mode 100644
index b96e5a47b5..0000000000
--- a/macros/latex/contrib/xsim/code/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/macros/latex/contrib/xsim/code/xsim.modules.code.tex b/macros/latex/contrib/xsim/code/xsim.modules.code.tex
deleted file mode 100644
index c487c73036..0000000000
--- a/macros/latex/contrib/xsim/code/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/macros/latex/contrib/xsim/code/xsim.properties.code.tex b/macros/latex/contrib/xsim/code/xsim.properties.code.tex
deleted file mode 100644
index 12a6fdf220..0000000000
--- a/macros/latex/contrib/xsim/code/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/macros/latex/contrib/xsim/code/xsim.random.code.tex b/macros/latex/contrib/xsim/code/xsim.random.code.tex
deleted file mode 100644
index cdd23e3a20..0000000000
--- a/macros/latex/contrib/xsim/code/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/macros/latex/contrib/xsim/code/xsim.solutions.code.tex b/macros/latex/contrib/xsim/code/xsim.solutions.code.tex
deleted file mode 100644
index 0a69194508..0000000000
--- a/macros/latex/contrib/xsim/code/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/macros/latex/contrib/xsim/code/xsim.sty b/macros/latex/contrib/xsim/code/xsim.sty
deleted file mode 100644
index cc30ae9052..0000000000
--- a/macros/latex/contrib/xsim/code/xsim.sty
+++ /dev/null
@@ -1,136 +0,0 @@
-% ----------------------------------------------------------------------------
-% the XSIM package
-%
-% 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.
-% ----------------------------------------------------------------------------
-\RequirePackage {expl3,xparse,l3keys2e}
-
-\ExplSyntaxOn
-
-\tl_const:Nn \c_xsim_date_tl {2020/04/04}
-\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:Nx \c_xsim_version_number_tl
- {
- \c_xsim_version_major_number_tl .
- \c_xsim_version_minor_number_tl
- }
-\tl_const:Nx \c_xsim_version_tl
- {
- \c_xsim_version_number_tl
- \c_xsim_version_subrelease_tl
- }
-\tl_const:Nn \c_xsim_info_tl {eXercise ~ Sheets ~ IMproved}
-
-\ProvidesExplPackage
- {xsim}
- {\c_xsim_date_tl}
- {\c_xsim_version_tl}
- {\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
-
-\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
- }
-
-\ProcessKeysPackageOptions {xsim/package}
-
-\keys_define:nn {xsim/package}
- {
- final .code:n = \msg_error:nnn {xsim} {load-time-option} {final} ,
- verbose .code:n = \msg_error:nnn {xsim} {load-time-option} {verbose} ,
- debug .code:n = \msg_error:nnn {xsim} {load-time-option} {debug} ,
- clear-aux .code:n = \msg_error:nnn {xsim} {load-time-option} {clear-aux} ,
- no-files .code:n = \msg_error:nnn {xsim} {load-time-option} {no-files} ,
- use-aux .code:n = \msg_error:nnn {xsim} {load-time-option} {use-aux} ,
- blank .code:n = \msg_error:nnn {xsim} {load-time-option} {blank}
- }
-
-% --------------------------------------------------------------------------
-
-% messages:
-\msg_new:nnn {xsim} {load-time-option}
- {
- `#1'~ is~ a~ load-time~ option! \\
- You~ cannot~ set~ it~ with~ \token_to_str:N \xsimsetup ! \\
- You~ need~ to~ use~ \token_to_str:N \usepackage [#1] {xsim} .
- }
-
-\msg_new:nnn {xsim} {rerun}
- {
- Exercise~ properties~ may~ have~ changed.~ Rerun~ to~ get~ them~
- synchronized.
- }
-
-\msg_new:nnn {xsim} {verbose} { #1 ~( \msg_line_context: ) }
-
-% --------------------------------------------------------------------------
-
-\cs_new_protected:Npn \xsim_do_rerun:
- { \xsim_if_rerun:T { \msg_warning:nn {xsim} {rerun} } }
-
-% --------------------------------------------------------------------------
-
-% load module mechanism:
-\tl_set:Nn \l_tmpa_tl {code.tex}
-\@onefilewithoptions {xsim.modules} [][] \l_tmpa_tl
-
-% --------------------------------------------------------------------------
-\xsim_load_modules:n {definitions}
-
-\AtEndDocument
- {
- \xsim_do_rerun:
- \xsim_close_aux:
- }
-
-% --------------------------------------------------------------------------
-\file_input_stop:
-
-2020/02/20 - implement issue #31 (blank package option)
-2020/02/21 - don't allow package options to be set with \xsimsetup
diff --git a/macros/latex/contrib/xsim/code/xsim.style.layouts.code.tex b/macros/latex/contrib/xsim/code/xsim.style.layouts.code.tex
deleted file mode 100644
index 31f5810bce..0000000000
--- a/macros/latex/contrib/xsim/code/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/macros/latex/contrib/xsim/code/xsim.tags.code.tex b/macros/latex/contrib/xsim/code/xsim.tags.code.tex
deleted file mode 100644
index f97c1af889..0000000000
--- a/macros/latex/contrib/xsim/code/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/macros/latex/contrib/xsim/code/xsim.templates.code.tex b/macros/latex/contrib/xsim/code/xsim.templates.code.tex
deleted file mode 100644
index f14d7fc87e..0000000000
--- a/macros/latex/contrib/xsim/code/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/macros/latex/contrib/xsim/code/xsim.translations.code.tex b/macros/latex/contrib/xsim/code/xsim.translations.code.tex
deleted file mode 100644
index b9f0712b4b..0000000000
--- a/macros/latex/contrib/xsim/code/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/macros/latex/contrib/xsim/code/xsimverb.sty b/macros/latex/contrib/xsim/code/xsimverb.sty
deleted file mode 100644
index 90373e9021..0000000000
--- a/macros/latex/contrib/xsim/code/xsimverb.sty
+++ /dev/null
@@ -1,97 +0,0 @@
-% ----------------------------------------------------------------------------
-% the XSIMVERB package
-%
-% write environments verbatim to files
-%
-% ----------------------------------------------------------------------------
-% 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.
-% ----------------------------------------------------------------------------
-
-\RequirePackage {expl3}
-\ExplSyntaxOn
-
-\tl_const:Nn \c_xsimverb_date_tl {2019/12/29}
-\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:Nx \c_xsimverb_version_number_tl
- {
- \c_xsimverb_version_major_number_tl .
- \c_xsimverb_version_minor_number_tl
- }
-\tl_const:Nx \c_xsimverb_version_tl
- {
- \c_xsimverb_version_number_tl
- \c_xsimverb_version_subrelease_tl
- }
-\tl_const:Nn \c_xsimverb_info_tl {write~ environments~ verbatim~ to~ files}
-
-\ProvidesExplPackage
- {xsimverb}
- {\c_xsimverb_date_tl}
- {\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
- { \bool_if_exist:NF #1 { \bool_new:N #1 } }
-
-\xsimverb_bool_provide:N \g__xsim_final_bool
-\xsimverb_bool_provide:N \g__xsim_verbose_bool
-\xsimverb_bool_provide:N \g_xsim_clear_aux_bool
-\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
-
-\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
- }
-
-\ProcessKeysPackageOptions {xsimverb}
-
-% --------------------------------------------------------------------------
-
-% load module mechanism:
-\tl_set:Nn \l_tmpa_tl {code.tex}
-\@onefilewithoptions {xsim.modules} [][] \l_tmpa_tl
-
-% --------------------------------------------------------------------------
-
-\xsim_load_module:n {verbwrite}
-
-% --------------------------------------------------------------------------
-\file_input_stop:
-
-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
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.collections.pdf b/macros/latex/contrib/xsim/doc/examples/xsim.collections.pdf
deleted file mode 100644
index fd785cc057..0000000000
--- a/macros/latex/contrib/xsim/doc/examples/xsim.collections.pdf
+++ /dev/null
Binary files differ
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.collections.tex b/macros/latex/contrib/xsim/doc/examples/xsim.collections.tex
deleted file mode 100644
index 990391e091..0000000000
--- a/macros/latex/contrib/xsim/doc/examples/xsim.collections.tex
+++ /dev/null
@@ -1,62 +0,0 @@
-\documentclass{article}
-\usepackage{xsim}
-
-\DeclareExerciseCollection{foo-easy}
-\DeclareExerciseCollection{foo-medium}
-\DeclareExerciseTagging{difficulty}
-
-\usepackage{lipsum}
-\begin{filecontents*}{foo.tex}
-\begin{exercise}[difficulty=easy,points=1]
- foo one \lipsum[4]
-\end{exercise}
-\begin{solution}
- foo one \lipsum[4]
-\end{solution}
-\begin{exercise}[difficulty=medium,points=1]
- foo two \lipsum[4]
-\end{exercise}
-\begin{solution}
- foo two \lipsum[4]
-\end{solution}
-\begin{exercise}[difficulty=easy,points=1]
- foo three \lipsum[4]
-\end{exercise}
-\begin{solution}
- foo three \lipsum[4]
-\end{solution}
-\end{filecontents*}
-
-\begin{document}
-
-\begin{exercise}
- outside before
-\end{exercise}
-
-\collectexercises{foo-easy}
-\xsimsetup{difficulty=easy}
-\input{foo.tex}
-\collectexercisesstop{foo-easy}
-% collection `foo-easy' now contains all exercises of file `foo.tex' tagged
-% with `difficulty=easy'
-
-\collectexercises{foo-medium}
-\xsimsetup{difficulty=medium}
-\input{foo.tex}
-\collectexercisesstop{foo-medium}
-% collection `foo-medium' now contains all exercises of file `foo.tex'
-% tagged with `difficulty=medium'
-
-\section{Easy}
-\printcollection{foo-easy}
-
-\section{Medium}
-\printcollection{foo-medium}
-
-\printsolutions[difficulty=medium]
-
-\section{All Exercises and Their Solutions Again, in Order of Appearance}
-
-\printcollection[print=both]{all exercises}
-
-\end{document}
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.difficulties.pdf b/macros/latex/contrib/xsim/doc/examples/xsim.difficulties.pdf
deleted file mode 100644
index 846f19e201..0000000000
--- a/macros/latex/contrib/xsim/doc/examples/xsim.difficulties.pdf
+++ /dev/null
Binary files differ
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.randomexercises.pdf b/macros/latex/contrib/xsim/doc/examples/xsim.randomexercises.pdf
deleted file mode 100644
index 773d34f495..0000000000
--- a/macros/latex/contrib/xsim/doc/examples/xsim.randomexercises.pdf
+++ /dev/null
Binary files differ
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-369636.pdf b/macros/latex/contrib/xsim/doc/examples/xsim.texsx-369636.pdf
deleted file mode 100644
index 2bc106f303..0000000000
--- a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-369636.pdf
+++ /dev/null
Binary files differ
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-391530.pdf b/macros/latex/contrib/xsim/doc/examples/xsim.texsx-391530.pdf
deleted file mode 100644
index 137c858769..0000000000
--- a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-391530.pdf
+++ /dev/null
Binary files differ
diff --git a/macros/latex/contrib/xsim/doc/xsim.ideas b/macros/latex/contrib/xsim/doc/xsim.ideas
deleted file mode 100644
index b23ebec899..0000000000
--- a/macros/latex/contrib/xsim/doc/xsim.ideas
+++ /dev/null
@@ -1,29 +0,0 @@
---------------------------------------------------------------------------
-
-XSIM -- 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.
---------------------------------------------------------------------------
-
-IDEAS:
-
-- a document class `xsim-exam' for creating exams
-- a mechanism for providing variants of an exam
-
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.blanks.pdf b/macros/latex/contrib/xsim/examples/xsim.blanks.pdf
index dd26d67157..84a8e09b33 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.blanks.pdf
+++ b/macros/latex/contrib/xsim/examples/xsim.blanks.pdf
Binary files differ
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.blanks.tex b/macros/latex/contrib/xsim/examples/xsim.blanks.tex
index b479e961c2..f32b81a129 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.blanks.tex
+++ b/macros/latex/contrib/xsim/examples/xsim.blanks.tex
@@ -1,5 +1,4 @@
\documentclass{article}
-\usepackage[utf8]{inputenc}
\usepackage[ngerman]{babel}
\usepackage{xsim,lipsum,xcolor}
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.boxed-headings.pdf b/macros/latex/contrib/xsim/examples/xsim.boxed-headings.pdf
index 99ba5bbc2a..fb9ff49f98 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.boxed-headings.pdf
+++ b/macros/latex/contrib/xsim/examples/xsim.boxed-headings.pdf
Binary files differ
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.boxed-headings.tex b/macros/latex/contrib/xsim/examples/xsim.boxed-headings.tex
index 9ff47d9d99..9ff47d9d99 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.boxed-headings.tex
+++ b/macros/latex/contrib/xsim/examples/xsim.boxed-headings.tex
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.code-and-output.pdf b/macros/latex/contrib/xsim/examples/xsim.code-and-output.pdf
index 72894ac9a6..4626e8c982 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.code-and-output.pdf
+++ b/macros/latex/contrib/xsim/examples/xsim.code-and-output.pdf
Binary files differ
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.code-and-output.tex b/macros/latex/contrib/xsim/examples/xsim.code-and-output.tex
index 66afaf9b8a..15b1a7dea0 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.code-and-output.tex
+++ b/macros/latex/contrib/xsim/examples/xsim.code-and-output.tex
@@ -46,7 +46,7 @@
\bigskip
-\begin{code}[]
+\begin{code}
blubber \LaTeX
\end{code}
diff --git a/macros/latex/contrib/xsim/examples/xsim.collections.pdf b/macros/latex/contrib/xsim/examples/xsim.collections.pdf
new file mode 100644
index 0000000000..e7ccda79cf
--- /dev/null
+++ b/macros/latex/contrib/xsim/examples/xsim.collections.pdf
Binary files differ
diff --git a/macros/latex/contrib/xsim/examples/xsim.collections.tex b/macros/latex/contrib/xsim/examples/xsim.collections.tex
new file mode 100644
index 0000000000..5f75082a42
--- /dev/null
+++ b/macros/latex/contrib/xsim/examples/xsim.collections.tex
@@ -0,0 +1,44 @@
+\documentclass{article}
+\usepackage{xsim}
+\usepackage{lipsum}
+
+\DeclareExerciseCollection[difficulty=easy]{easy}
+\DeclareExerciseCollection[difficulty=medium]{medium}
+\DeclareExerciseTagging{difficulty}
+
+\xsimsetup{collect}
+
+\begin{document}
+
+\begin{exercise}[use,print]
+ outside before
+\end{exercise}
+
+\begin{exercise}[difficulty=easy,points=1]
+ foo one \lipsum[4]
+\end{exercise}
+\begin{solution}
+ foo one \lipsum[4]
+\end{solution}
+\begin{exercise}[difficulty=medium,points=1]
+ foo two \lipsum[4]
+\end{exercise}
+\begin{solution}
+ foo two \lipsum[4]
+\end{solution}
+\begin{exercise}[difficulty=easy,points=1]
+ foo three \lipsum[4]
+\end{exercise}
+\begin{solution}
+ foo three \lipsum[4]
+\end{solution}
+
+\section{Easy}
+\printcollection{easy}
+
+\section{Medium}
+\printcollection{medium}
+
+\printsolutions[difficulty=medium]
+
+\end{document}
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.crossref.pdf b/macros/latex/contrib/xsim/examples/xsim.crossref.pdf
index 8151a0cef3..19843c4185 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.crossref.pdf
+++ b/macros/latex/contrib/xsim/examples/xsim.crossref.pdf
Binary files differ
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.crossref.tex b/macros/latex/contrib/xsim/examples/xsim.crossref.tex
index fa2fbbb509..0a6c8f4eab 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.crossref.tex
+++ b/macros/latex/contrib/xsim/examples/xsim.crossref.tex
@@ -2,7 +2,7 @@
\usepackage{xsim,lipsum,hyperref}
\DeclareExerciseHeadingTemplate{custom}
- {\section{\XSIMtranslate{default-heading}}}
+ {\section{\XSIMexpandcode{\XSIMtranslate{default-heading}}}}
\DeclareExerciseEnvironmentTemplate{custom}
{%
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.description-list.pdf b/macros/latex/contrib/xsim/examples/xsim.description-list.pdf
index d506ad960b..b05b3276c9 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.description-list.pdf
+++ b/macros/latex/contrib/xsim/examples/xsim.description-list.pdf
Binary files differ
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.description-list.tex b/macros/latex/contrib/xsim/examples/xsim.description-list.tex
index f3c9ed6d74..f3c9ed6d74 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.description-list.tex
+++ b/macros/latex/contrib/xsim/examples/xsim.description-list.tex
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.different-point-types.pdf b/macros/latex/contrib/xsim/examples/xsim.different-point-types.pdf
index b1de5d6325..781831ddf8 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.different-point-types.pdf
+++ b/macros/latex/contrib/xsim/examples/xsim.different-point-types.pdf
Binary files differ
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.different-point-types.tex b/macros/latex/contrib/xsim/examples/xsim.different-point-types.tex
index 0ac3536776..0ac3536776 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.different-point-types.tex
+++ b/macros/latex/contrib/xsim/examples/xsim.different-point-types.tex
diff --git a/macros/latex/contrib/xsim/examples/xsim.difficulties.pdf b/macros/latex/contrib/xsim/examples/xsim.difficulties.pdf
new file mode 100644
index 0000000000..4963fb4836
--- /dev/null
+++ b/macros/latex/contrib/xsim/examples/xsim.difficulties.pdf
Binary files differ
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.difficulties.tex b/macros/latex/contrib/xsim/examples/xsim.difficulties.tex
index 02712f15d6..02712f15d6 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.difficulties.tex
+++ b/macros/latex/contrib/xsim/examples/xsim.difficulties.tex
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.floating.pdf b/macros/latex/contrib/xsim/examples/xsim.floating.pdf
index e2e96537ef..c1352837eb 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.floating.pdf
+++ b/macros/latex/contrib/xsim/examples/xsim.floating.pdf
Binary files differ
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.floating.tex b/macros/latex/contrib/xsim/examples/xsim.floating.tex
index 08448df35a..08448df35a 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.floating.tex
+++ b/macros/latex/contrib/xsim/examples/xsim.floating.tex
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.golatex-80640.pdf b/macros/latex/contrib/xsim/examples/xsim.golatex-80640.pdf
index 76cf1617cb..068dc15fef 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.golatex-80640.pdf
+++ b/macros/latex/contrib/xsim/examples/xsim.golatex-80640.pdf
Binary files differ
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.golatex-80640.tex b/macros/latex/contrib/xsim/examples/xsim.golatex-80640.tex
index 5ccdff63a4..7ac1f15800 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.golatex-80640.tex
+++ b/macros/latex/contrib/xsim/examples/xsim.golatex-80640.tex
@@ -1,6 +1,5 @@
% http://golatex.de/viewtopic,p,80640.html
\documentclass[fontsize=12pt,parskip=half]{scrartcl}
-\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[ngerman]{babel}
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.golatex-91339.pdf b/macros/latex/contrib/xsim/examples/xsim.golatex-91339.pdf
index 97cb4659e0..189210a8a3 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.golatex-91339.pdf
+++ b/macros/latex/contrib/xsim/examples/xsim.golatex-91339.pdf
Binary files differ
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.golatex-91339.tex b/macros/latex/contrib/xsim/examples/xsim.golatex-91339.tex
index 8ae03971c5..ae02ca0344 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.golatex-91339.tex
+++ b/macros/latex/contrib/xsim/examples/xsim.golatex-91339.tex
@@ -1,6 +1,5 @@
% http://golatex.de/viewtopic,p,91339.html
-\documentclass[18pt,a4paper]{article}
-\usepackage[utf8]{inputenc}
+\documentclass[a4paper]{article}
\usepackage[ngerman]{babel}
\usepackage{xsim,tcolorbox}
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.grade-distribution.pdf b/macros/latex/contrib/xsim/examples/xsim.grade-distribution.pdf
index 248358c4a1..2de9ff1358 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.grade-distribution.pdf
+++ b/macros/latex/contrib/xsim/examples/xsim.grade-distribution.pdf
Binary files differ
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.grade-distribution.tex b/macros/latex/contrib/xsim/examples/xsim.grade-distribution.tex
index 8e9731de24..8e9731de24 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.grade-distribution.tex
+++ b/macros/latex/contrib/xsim/examples/xsim.grade-distribution.tex
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.hints.pdf b/macros/latex/contrib/xsim/examples/xsim.hints.pdf
index a34fbd8f79..4b13a435d6 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.hints.pdf
+++ b/macros/latex/contrib/xsim/examples/xsim.hints.pdf
Binary files differ
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.hints.tex b/macros/latex/contrib/xsim/examples/xsim.hints.tex
index 10a0bffed9..82d89f6944 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.hints.tex
+++ b/macros/latex/contrib/xsim/examples/xsim.hints.tex
@@ -10,13 +10,8 @@
\newcommand\printhints{%
\begin{description}
\ForEachUsedExerciseByType{%
- \def\ExerciseType{##1}%
- \def\ExerciseID{##2}%
\GetExercisePropertyT{hint}
- {%
- \item[\XSIMmixedcase{\GetExerciseName}~##3]
- ####1%
- }%
+ {\item[\XSIMmixedcase{\GetExerciseName}~##3]####1}%
}%
\end{description}
}
diff --git a/macros/latex/contrib/xsim/examples/xsim.issues-49.pdf b/macros/latex/contrib/xsim/examples/xsim.issues-49.pdf
new file mode 100644
index 0000000000..3ea1c70ace
--- /dev/null
+++ b/macros/latex/contrib/xsim/examples/xsim.issues-49.pdf
Binary files differ
diff --git a/macros/latex/contrib/xsim/examples/xsim.issues-49.tex b/macros/latex/contrib/xsim/examples/xsim.issues-49.tex
new file mode 100644
index 0000000000..f9baf0a601
--- /dev/null
+++ b/macros/latex/contrib/xsim/examples/xsim.issues-49.tex
@@ -0,0 +1,122 @@
+\documentclass{article}
+\usepackage{xsim}
+
+\xsimsetup{
+ load-style = layouts ,
+ exercise/template = runin ,
+ solution/template = runin
+}
+
+\usepackage{tasks,fontawesome,fmtcount,multicol}
+\NewTasksEnvironment[label=\Alph*),label-width=12pt]{choices}[\choice]
+\newcommand*\correct{\thetask\expanded{\SetExerciseProperty{choice}{\thetask}}}
+
+\NewTasksEnvironment[label=\Roman*,label-width=12pt]{options}[\option]
+
+\DeclareExerciseProperty{choice}
+
+\newcommand*\pkg[1]{\texttt{#1}}
+\newcommand*\cls[1]{\texttt{#1}}
+
+\newcommand\EA[2]{\IfInsideSolutionTF{#2}{#1}}
+\newcommand\answer[1]{\IfInsideSolutionT{#1}}
+
+\begin{document}
+
+\section{List of exercises}
+Solve and answer the following exercises.
+
+\begin{exercise}
+ Factor $x^{2}-2x+1$
+\end{exercise}
+\begin{solution}
+ $\left(x-1\right)^{2}$
+\end{solution}
+\begin{exercise}
+ Factor $3x+3y+3z$
+\end{exercise}
+\begin{solution}
+ $3(x+y+z)$
+\end{solution}
+
+\begin{exercise}[solution]
+ \EA{True or false?}{}
+ \begin{tasks}(2)
+ \task \EA{$\alpha > \delta$}{False}
+ \task \EA{\LaTeX2e\ is cool?}{Very True!}
+ \end{tasks}
+\end{exercise}
+
+\begin{exercise}[subtitle=Talking Linux,solution]
+ \begin{tasks}(2)
+ \task \EA{You use linux?}{Yes}
+ \task \EA{Usually uses the package manager?}{Yes}
+ \end{tasks}
+\end{exercise}
+
+\begin{exercise}[solution]
+ \EA{Rate the following \LaTeX\ packages and classes.}{}
+ \begin{tasks}(\EA{3}{1})
+ \task \EA{\cls{xsim-exam}}{doesn't exist for now}
+ \task \EA{\pkg{xsim}}{very good}
+ \task \EA{\pkg{exsheets}}{obsolete}
+ \end{tasks}
+\end{exercise}
+
+\begin{exercise}
+ \begin{choices}(5)
+ \choice value
+ \choice value
+ \choice value
+ \choice[\correct] correct
+ \choice value
+ \end{choices}
+\end{exercise}
+\begin{solution}
+ \GetExerciseProperty{choice}
+\end{solution}
+
+\begin{exercise}
+ \begin{options}(3)
+ \option $2\alpha+2\delta=90^{\circ}$
+ \option $\alpha=\delta$
+ \option $\angle EDF=45^{\circ}$
+ \end{options}
+ \begin{choices}(4)
+ \choice I only
+ \choice[\correct] II only
+ \choice I and II only
+ \choice I and III only
+ \choice I, II, and III
+ \end{choices}
+\end{exercise}
+\begin{solution}
+ \GetExerciseProperty{choice}
+\end{solution}
+
+\begin{exercise}
+ \begin{tasks}[label=(\arabic*),label-width=13pt](2)
+ \task $2\alpha+2\delta=90^{\circ}$
+ \task $\angle EDF=45^{\circ}$
+ \end{tasks}
+ \begin{choices}(3)
+ \choice Alternative A
+ \choice Alternative B
+ \choice[\correct] Alternative C
+ \choice Alternative D
+ \choice Alternative E
+ \end{choices}
+\end{exercise}
+\begin{solution}
+ \GetExerciseProperty{choice}
+\end{solution}
+
+\clearpage
+
+\section{Solutions}
+\raggedcolumns
+\begin{multicols}{2}
+ \printsolutions[headings=false]
+\end{multicols}
+
+\end{document}
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.listings.pdf b/macros/latex/contrib/xsim/examples/xsim.listings.pdf
index 0d388f2c70..8383fd8b0c 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.listings.pdf
+++ b/macros/latex/contrib/xsim/examples/xsim.listings.pdf
Binary files differ
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.listings.tex b/macros/latex/contrib/xsim/examples/xsim.listings.tex
index 6dd302feb0..a5fe951beb 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.listings.tex
+++ b/macros/latex/contrib/xsim/examples/xsim.listings.tex
@@ -3,7 +3,7 @@
\usepackage{xcolor}
\usepackage{listings}
-\usepackage{xsim}
+\usepackage[use-files]{xsim}
\lstset{
frame=single,
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.listofexercises.pdf b/macros/latex/contrib/xsim/examples/xsim.listofexercises.pdf
index 8050ee8f90..46bf9b89e4 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.listofexercises.pdf
+++ b/macros/latex/contrib/xsim/examples/xsim.listofexercises.pdf
Binary files differ
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.listofexercises.tex b/macros/latex/contrib/xsim/examples/xsim.listofexercises.tex
index c2a9a3fe36..c2a9a3fe36 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.listofexercises.tex
+++ b/macros/latex/contrib/xsim/examples/xsim.listofexercises.tex
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.multiplechoice.pdf b/macros/latex/contrib/xsim/examples/xsim.multiplechoice.pdf
index 02dac6c4df..0e49066a70 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.multiplechoice.pdf
+++ b/macros/latex/contrib/xsim/examples/xsim.multiplechoice.pdf
Binary files differ
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.multiplechoice.tex b/macros/latex/contrib/xsim/examples/xsim.multiplechoice.tex
index e0db3eb0c5..e0db3eb0c5 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.multiplechoice.tex
+++ b/macros/latex/contrib/xsim/examples/xsim.multiplechoice.tex
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.pointsums.pdf b/macros/latex/contrib/xsim/examples/xsim.pointsums.pdf
index aa822a1bd7..225595afe3 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.pointsums.pdf
+++ b/macros/latex/contrib/xsim/examples/xsim.pointsums.pdf
Binary files differ
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.pointsums.tex b/macros/latex/contrib/xsim/examples/xsim.pointsums.tex
index 29d7ac0cdc..29d7ac0cdc 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.pointsums.tex
+++ b/macros/latex/contrib/xsim/examples/xsim.pointsums.tex
diff --git a/macros/latex/contrib/xsim/examples/xsim.randomexercises.pdf b/macros/latex/contrib/xsim/examples/xsim.randomexercises.pdf
new file mode 100644
index 0000000000..670825d54a
--- /dev/null
+++ b/macros/latex/contrib/xsim/examples/xsim.randomexercises.pdf
Binary files differ
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.randomexercises.tex b/macros/latex/contrib/xsim/examples/xsim.randomexercises.tex
index 60877b1a4a..aafb3ddae1 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.randomexercises.tex
+++ b/macros/latex/contrib/xsim/examples/xsim.randomexercises.tex
@@ -1,10 +1,10 @@
\documentclass{article}
\usepackage{xsim}
-\DeclareExerciseCollection{foo}
+\xsimsetup{collect}
+
+\begin{document}
-\usepackage{filecontents}
-\begin{filecontents*}{random.tex}
\begin{exercise}[ID=A]
exercise A
\end{exercise}
@@ -41,18 +41,10 @@
\begin{solution}
solution F
\end{solution}
-\end{filecontents*}
-
-\begin{document}
-
-\collectexercises{foo}
-\input{random.tex}
-\collectexercisesstop{foo}
\section*{Exercises}
-\printrandomexercises[collection=foo,exclude=D]{3}
+\printrandomexercises[collection=all exercises,exclude=D]{3}
-\section*{Solutions}
-\printsolutions*
+\printsolutions
\end{document}
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-13635.pdf b/macros/latex/contrib/xsim/examples/xsim.texsx-13635.pdf
index af889a6709..ff493e3591 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-13635.pdf
+++ b/macros/latex/contrib/xsim/examples/xsim.texsx-13635.pdf
Binary files differ
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-13635.tex b/macros/latex/contrib/xsim/examples/xsim.texsx-13635.tex
index 3b52ce46b2..c0d08a567f 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-13635.tex
+++ b/macros/latex/contrib/xsim/examples/xsim.texsx-13635.tex
@@ -27,6 +27,8 @@
\DeclareExerciseCollection{prime numbers}
\DeclareExerciseCollection{Zeta function}
+\xsimsetup{collect}
+
\begin{document}
\collectexercises{prime numbers}
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-155630.pdf b/macros/latex/contrib/xsim/examples/xsim.texsx-155630.pdf
index 6c9fc4482a..40bacabc8e 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-155630.pdf
+++ b/macros/latex/contrib/xsim/examples/xsim.texsx-155630.pdf
Binary files differ
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-155630.tex b/macros/latex/contrib/xsim/examples/xsim.texsx-155630.tex
index 2edb7bfdad..015f52db0f 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-155630.tex
+++ b/macros/latex/contrib/xsim/examples/xsim.texsx-155630.tex
@@ -3,10 +3,10 @@
\usepackage{xsim}
\DeclareExerciseCollection{foo}
+\xsimsetup{collect}
\begin{document}
-\collectexercises{foo}
\begin{exercise}
foo
\end{exercise}
@@ -16,7 +16,6 @@
\begin{exercise}
baz
\end{exercise}
-\collectexercisesstop{foo}
% shuffle around for a different version:
\printexercise{exercise}{1}
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-199360.pdf b/macros/latex/contrib/xsim/examples/xsim.texsx-199360.pdf
index 9492549598..8c1d7cc9d5 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-199360.pdf
+++ b/macros/latex/contrib/xsim/examples/xsim.texsx-199360.pdf
Binary files differ
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-199360.tex b/macros/latex/contrib/xsim/examples/xsim.texsx-199360.tex
index 334275140a..334275140a 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-199360.tex
+++ b/macros/latex/contrib/xsim/examples/xsim.texsx-199360.tex
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-299534.pdf b/macros/latex/contrib/xsim/examples/xsim.texsx-299534.pdf
index c006aeb34c..c9500e089f 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-299534.pdf
+++ b/macros/latex/contrib/xsim/examples/xsim.texsx-299534.pdf
Binary files differ
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-299534.tex b/macros/latex/contrib/xsim/examples/xsim.texsx-299534.tex
index 1c2be46df3..e330f3d256 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-299534.tex
+++ b/macros/latex/contrib/xsim/examples/xsim.texsx-299534.tex
@@ -1,7 +1,7 @@
% http://tex.stackexchange.com/q/299534/
\documentclass{article}
\usepackage{pythontex}
-\usepackage{xsim}
+\usepackage[use-files]{xsim}
\begin{document}
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-305110.pdf b/macros/latex/contrib/xsim/examples/xsim.texsx-305110.pdf
index fb92e875a9..4b9558d90f 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-305110.pdf
+++ b/macros/latex/contrib/xsim/examples/xsim.texsx-305110.pdf
Binary files differ
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-305110.tex b/macros/latex/contrib/xsim/examples/xsim.texsx-305110.tex
index c10928da0c..c10928da0c 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-305110.tex
+++ b/macros/latex/contrib/xsim/examples/xsim.texsx-305110.tex
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-308883.pdf b/macros/latex/contrib/xsim/examples/xsim.texsx-308883.pdf
index eb27dce140..02039dbc68 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-308883.pdf
+++ b/macros/latex/contrib/xsim/examples/xsim.texsx-308883.pdf
Binary files differ
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-308883.tex b/macros/latex/contrib/xsim/examples/xsim.texsx-308883.tex
index 74e762fa08..74e762fa08 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-308883.tex
+++ b/macros/latex/contrib/xsim/examples/xsim.texsx-308883.tex
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-338165.pdf b/macros/latex/contrib/xsim/examples/xsim.texsx-338165.pdf
index 4b5a09474d..9e8168af2f 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-338165.pdf
+++ b/macros/latex/contrib/xsim/examples/xsim.texsx-338165.pdf
Binary files differ
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-338165.tex b/macros/latex/contrib/xsim/examples/xsim.texsx-338165.tex
index a0b204f914..72ee108668 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-338165.tex
+++ b/macros/latex/contrib/xsim/examples/xsim.texsx-338165.tex
@@ -10,26 +10,24 @@
\tcbuselibrary{breakable, skins}
\settasks{ label = \arabic*. }
-\DeclareExerciseEnvironmentTemplate{boxed}
- {%
- \tcolorbox[
- enhanced ,
- attach boxed title to top center = {yshift=-7.5pt} ,
- colback = white , colbacktitle = white ,
- coltitle = black , colframe = black ,
- boxed title style = { colframe = white } ,
- fonttitle=\bfseries,
- sharp corners=all,
- breakable,
- title=
- \XSIMmixedcase{\GetExerciseName}%
- \IfInsideSolutionF{%
- ~\GetExerciseProperty{counter}%
- \IfExercisePropertySetT{subtitle}{: \GetExerciseProperty{subtitle}}%
- }%
- ]
- }
- {\endtcolorbox}
+\DeclareExerciseEnvironmentTemplate{boxed}{%
+ \tcolorbox[
+ enhanced ,
+ attach boxed title to top center = {yshift=-7.5pt} ,
+ colback = white , colbacktitle = white ,
+ coltitle = black , colframe = black ,
+ boxed title style = { colframe = white } ,
+ fonttitle=\bfseries,
+ sharp corners=all,
+ breakable,
+ title=
+ \XSIMmixedcase{\GetExerciseName}%
+ \IfInsideSolutionF{%
+ ~\GetExerciseProperty{counter}%
+ \IfExercisePropertySetT{subtitle}{: \GetExerciseProperty{subtitle}}%
+ }%
+ ]
+}{\endtcolorbox}
\xsimsetup{
exercise/template = boxed ,
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-350028.pdf b/macros/latex/contrib/xsim/examples/xsim.texsx-350028.pdf
index 36645464fc..2f58a0fde7 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-350028.pdf
+++ b/macros/latex/contrib/xsim/examples/xsim.texsx-350028.pdf
Binary files differ
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-350028.tex b/macros/latex/contrib/xsim/examples/xsim.texsx-350028.tex
index 8f49a92f60..f0d977a131 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-350028.tex
+++ b/macros/latex/contrib/xsim/examples/xsim.texsx-350028.tex
@@ -5,48 +5,44 @@
\usepackage[most]{tcolorbox}
\tcbuselibrary{skins,breakable}
-\DeclareExerciseEnvironmentTemplate{tcolorbox}
- {%
- \tcolorbox[
- enhanced,
- colframe=green!20!black,
- colback=yellow!10!white,
- coltitle=green!40!black,
- fonttitle=\bfseries,
- underlay={%
- \begin{tcbclipinterior}
- \shade[
- inner color=\IfInsideSolutionTF{red!50!yellow}{green!80!yellow},
- outer color=yellow!10!white]
- (interior.north west) circle (2cm);
- \draw[help lines,step=5mm,yellow!80!black,shift={(interior.north west)}]
- (interior.south west) grid (interior.north east);
- \end{tcbclipinterior}%
- },
- attach title to upper=\quad,
- title = \XSIMmixedcase{\GetExerciseName}~\GetExerciseProperty{counter}
- \IfExercisePropertySetT{points}{%
- (\GetExerciseProperty{points}
- \IfExerciseGoalSingularTF{points}
- {\XSIMtranslate{point}}
- {\XSIMtranslate{points}})%
- }]%
- \IfInsideSolutionT{\label{solution:\ExerciseID}}%
- }
- {%
- \endtcolorbox
- \vspace*{\baselineskip}
- \IfInsideSolutionTF
- {%
- \noindent Exercise~\GetExerciseProperty{counter} is on
- page~\GetExerciseProperty{page}.%
- }
- {%
- \noindent The solution of this exercise is on
- page~\pageref{solution:\ExerciseID}.%
- }%
- \vspace{\baselineskip}
- }
+\DeclareExerciseEnvironmentTemplate{tcolorbox}{%
+ \tcolorbox[
+ enhanced,
+ colframe=green!20!black,
+ colback=yellow!10!white,
+ coltitle=green!40!black,
+ fonttitle=\bfseries,
+ underlay={%
+ \begin{tcbclipinterior}
+ \shade[
+ inner color=\IfInsideSolutionTF{red!50!yellow}{green!80!yellow},
+ outer color=yellow!10!white]
+ (interior.north west) circle (2cm);
+ \draw[help lines,step=5mm,yellow!80!black,shift={(interior.north west)}]
+ (interior.south west) grid (interior.north east);
+ \end{tcbclipinterior}%
+ },
+ attach title to upper=\quad,
+ title = \XSIMmixedcase{\GetExerciseName}~\GetExerciseProperty{counter}
+ \IfExercisePropertySetT{points}{%
+ (\GetExerciseProperty{points}
+ \IfExerciseGoalSingularTF{points}
+ {\XSIMtranslate{point}}
+ {\XSIMtranslate{points}})%
+ }]%
+ \IfInsideSolutionT{\label{solution:\ExerciseID}}%
+}{%
+ \endtcolorbox
+ \vspace*{\baselineskip}
+ \IfInsideSolutionTF{%
+ \noindent Exercise~\GetExerciseProperty{counter} is on
+ page~\GetExerciseProperty{page}.%
+ }{%
+ \noindent The solution of this exercise is on
+ page~\pageref{solution:\ExerciseID}.%
+ }%
+ \vspace{\baselineskip}
+}
\xsimsetup{
exercise/template = tcolorbox ,
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-369065.pdf b/macros/latex/contrib/xsim/examples/xsim.texsx-369065.pdf
index 6aa9ab572b..fea54f626b 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-369065.pdf
+++ b/macros/latex/contrib/xsim/examples/xsim.texsx-369065.pdf
Binary files differ
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-369065.tex b/macros/latex/contrib/xsim/examples/xsim.texsx-369065.tex
index b62b85127a..f35149c8ea 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-369065.tex
+++ b/macros/latex/contrib/xsim/examples/xsim.texsx-369065.tex
@@ -11,28 +11,24 @@
solution/print=true
}
-\DeclareExerciseEnvironmentTemplate{cyan-box}
- {%
- \begin{tcolorbox}[arc=0mm,boxrule=1pt,colback=white,colframe=cyan,leftrule=3mm]
- \textsf{%
- \MakeUppercase{%
- \XSIMmixedcase{\GetExerciseName}~\GetExerciseProperty{counter}%
- }%
+\DeclareExerciseEnvironmentTemplate{cyan-box}{%
+ \begin{tcolorbox}[arc=0mm,boxrule=1pt,colback=white,colframe=cyan,leftrule=3mm]
+ \textsf{%
+ \MakeUppercase{%
+ \XSIMmixedcase{\GetExerciseName}~\GetExerciseProperty{counter}%
}%
- \GetExercisePropertyT{subtitle}{ \textit{#1}}%
- \quad
- }
- {\end{tcolorbox}}
-
-\DeclareExerciseEnvironmentTemplate{red}
- {%
- \par
- \Needspace*{2\baselineskip}
- \noindent
- \textsf{\textcolor{red}{\MakeUppercase{\XSIMmixedcase{\GetExerciseName}}}}%
+ }%
+ \GetExercisePropertyT{subtitle}{ \textit{#1}}%
\quad
- }
- {\par\bigskip}
+}{\end{tcolorbox}}
+
+\DeclareExerciseEnvironmentTemplate{red}{%
+ \par
+ \Needspace*{2\baselineskip}
+ \noindent
+ \textsf{\textcolor{red}{\MakeUppercase{\XSIMmixedcase{\GetExerciseName}}}}%
+ \quad
+}{\par\bigskip}
\begin{document}
diff --git a/macros/latex/contrib/xsim/examples/xsim.texsx-369636.pdf b/macros/latex/contrib/xsim/examples/xsim.texsx-369636.pdf
new file mode 100644
index 0000000000..96bd157b68
--- /dev/null
+++ b/macros/latex/contrib/xsim/examples/xsim.texsx-369636.pdf
Binary files differ
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-369636.tex b/macros/latex/contrib/xsim/examples/xsim.texsx-369636.tex
index e13b8653f4..73ab7868f6 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-369636.tex
+++ b/macros/latex/contrib/xsim/examples/xsim.texsx-369636.tex
@@ -5,7 +5,6 @@
\usepackage[T1]{fontenc}
\usepackage{fourier}
\usepackage{tgpagella}
-\usepackage[utf8]{inputenc}
\usepackage{xsim,needspace,adjustbox,scrextend}
@@ -14,20 +13,18 @@
exercise/template = square
}
-\DeclareExerciseEnvironmentTemplate{square}
- {%
- \Needspace*{2\baselineskip}%
- \addmargin[0pt]{.15\textwidth}%
- \par\noindent
- \adjustbox{
- fbox = 1pt 0pt,
- lap = {\textwidth},
- valign = t,
- set vsize = {0pt}{0pt}
- }{\rule{0pt}{20pt}\hspace{20pt}}%
- \textbf{\GetExerciseProperty{counter}} %
- }
- {\endaddmargin\vspace{\baselineskip}}
+\DeclareExerciseEnvironmentTemplate{square}{%
+ \Needspace*{2\baselineskip}%
+ \addmargin[0pt]{.15\textwidth}%
+ \par\noindent
+ \adjustbox{
+ fbox = 1pt 0pt,
+ lap = {\textwidth},
+ valign = t,
+ set vsize = {0pt}{0pt}
+ }{\rule{0pt}{20pt}\hspace{20pt}}%
+ \textbf{\GetExerciseProperty{counter}} %
+}{\endaddmargin\vspace{\baselineskip}}
\usepackage{lipsum}
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-369803.pdf b/macros/latex/contrib/xsim/examples/xsim.texsx-369803.pdf
index 73eab39f10..3e5f8d663b 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-369803.pdf
+++ b/macros/latex/contrib/xsim/examples/xsim.texsx-369803.pdf
Binary files differ
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-369803.tex b/macros/latex/contrib/xsim/examples/xsim.texsx-369803.tex
index 58b6800f93..e91e795353 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-369803.tex
+++ b/macros/latex/contrib/xsim/examples/xsim.texsx-369803.tex
@@ -1,6 +1,5 @@
% https://tex.stackexchange.com/q/369803
\documentclass[a4paper,parskip=half]{scrartcl}
-\usepackage[utf8]{inputenc}
\usepackage[ngerman]{babel}
\usepackage{amsmath}
@@ -12,19 +11,16 @@
\usepackage{xsim,siunitx}
\DeclareExerciseTagging{difficulty}
-\DeclareExerciseEnvironmentTemplate{custom}
- {%
- \subsection*
- {%
- \XSIMmixedcase{\GetExerciseName}\nobreakspace
- \GetExerciseProperty{counter}%
- \IfInsideSolutionF
- {%
- \IfExercisePropertySetT{subtitle}
- { {\normalfont(\GetExerciseProperty{subtitle})}}%
- }%
- }%
- }{}
+\DeclareExerciseEnvironmentTemplate{custom}{%
+ \subsection*{%
+ \XSIMmixedcase{\GetExerciseName}\nobreakspace
+ \GetExerciseProperty{counter}%
+ \IfInsideSolutionF{%
+ \IfExercisePropertySetT{subtitle}
+ { {\normalfont(\GetExerciseProperty{subtitle})}}%
+ }%
+ }%
+}{}
\xsimsetup{
exercise/name = \XSIMtranslate{question} ,
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-370642.pdf b/macros/latex/contrib/xsim/examples/xsim.texsx-370642.pdf
index 13933e80c3..7d70b52d3a 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-370642.pdf
+++ b/macros/latex/contrib/xsim/examples/xsim.texsx-370642.pdf
Binary files differ
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-370642.tex b/macros/latex/contrib/xsim/examples/xsim.texsx-370642.tex
index 99b300c4a0..99b300c4a0 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-370642.tex
+++ b/macros/latex/contrib/xsim/examples/xsim.texsx-370642.tex
diff --git a/macros/latex/contrib/xsim/examples/xsim.texsx-391530-exercises.tex b/macros/latex/contrib/xsim/examples/xsim.texsx-391530-exercises.tex
new file mode 100644
index 0000000000..716921adc0
--- /dev/null
+++ b/macros/latex/contrib/xsim/examples/xsim.texsx-391530-exercises.tex
@@ -0,0 +1,12 @@
+\begin{question}
+ Who is the Defence Minister?
+\end{question}
+\begin{question}
+ Who is the Home Minister?
+\end{question}
+\begin{question}
+ Who is the Finance Minister?
+\end{question}
+\begin{question}
+ Who is the External Affairs Minister?
+\end{question}
diff --git a/macros/latex/contrib/xsim/examples/xsim.texsx-391530.pdf b/macros/latex/contrib/xsim/examples/xsim.texsx-391530.pdf
new file mode 100644
index 0000000000..1446d0345e
--- /dev/null
+++ b/macros/latex/contrib/xsim/examples/xsim.texsx-391530.pdf
Binary files differ
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-391530.tex b/macros/latex/contrib/xsim/examples/xsim.texsx-391530.tex
index 1deafe5fb0..2d76cae57e 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-391530.tex
+++ b/macros/latex/contrib/xsim/examples/xsim.texsx-391530.tex
@@ -14,28 +14,23 @@
\DeclareExerciseProperty{title}
\makeatletter
-\DeclareExerciseEnvironmentTemplate{named}
- {%
- \subsection*{%
- \GetExercisePropertyTF{title}
- {#1}
- {??\@latex@warning{Please give an exercise title}}%
- }%
- }
- {}
+\DeclareExerciseEnvironmentTemplate{named}{%
+ \subsection*{%
+ \GetExercisePropertyTF{title}
+ {#1}
+ {??\@latex@warning{Please give an exercise title}}%
+ }%
+}{}
\makeatother
-\DeclareExerciseEnvironmentTemplate{item}
- {\item}
- {}
-
+\DeclareExerciseEnvironmentTemplate{item}{\item}{}
\DeclareExerciseCollection{exercise-pool}
-\xsimsetup{
- exercise/template = named
-}
+\xsimsetup{ exercise/template = named }
-\begin{filecontents*}{\jobname-exercises.tex}
+\begin{document}
+
+\collectexercises{exercise-pool}
\begin{question}
Who is the Defence Minister?
\end{question}
@@ -48,12 +43,6 @@
\begin{question}
Who is the External Affairs Minister?
\end{question}
-\end{filecontents*}
-
-\begin{document}
-
-\collectexercises{exercise-pool}
-\input{\jobname-exercises.tex}
\collectexercisesstop{exercise-pool}
\begin{exercise}[title=Answer the following in one sentence:]
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-395273.pdf b/macros/latex/contrib/xsim/examples/xsim.texsx-395273.pdf
index c3796c8ee0..056b14e833 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-395273.pdf
+++ b/macros/latex/contrib/xsim/examples/xsim.texsx-395273.pdf
Binary files differ
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-395273.tex b/macros/latex/contrib/xsim/examples/xsim.texsx-395273.tex
index fe6152ed96..fe6152ed96 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-395273.tex
+++ b/macros/latex/contrib/xsim/examples/xsim.texsx-395273.tex
diff --git a/macros/latex/contrib/xsim/examples/xsim.texsx-466584.pdf b/macros/latex/contrib/xsim/examples/xsim.texsx-466584.pdf
new file mode 100644
index 0000000000..83c20f646b
--- /dev/null
+++ b/macros/latex/contrib/xsim/examples/xsim.texsx-466584.pdf
Binary files differ
diff --git a/macros/latex/contrib/xsim/examples/xsim.texsx-466584.tex b/macros/latex/contrib/xsim/examples/xsim.texsx-466584.tex
new file mode 100644
index 0000000000..1f30d3c1b8
--- /dev/null
+++ b/macros/latex/contrib/xsim/examples/xsim.texsx-466584.tex
@@ -0,0 +1,56 @@
+% https://tex.stackexchange.com/q/466584
+\documentclass{article}
+\usepackage{xsim}
+\usepackage{needspace}
+\usepackage{tasks}
+
+\DeclareExerciseEnvironmentTemplate{exandsol}{%
+ \par\vspace{\baselineskip}
+ \Needspace*{2\baselineskip}
+ \noindent\sffamily
+ \textbf{\XSIMmixedcase{\GetExerciseName}~\GetExerciseProperty{counter}}%
+ \GetExercisePropertyT{subtitle}{\hspace{3em}{\small#1}}\par
+ \normalfont
+}{}
+
+\DeclareExerciseEnvironmentTemplate{flushright}{%
+ \begin{flushright}
+ \begin{minipage}{.4\linewidth}
+ \textsf{Solutions:}\par\normalfont
+}{%
+ \end{minipage}%
+ \end{flushright}%
+}
+
+\xsimsetup{
+ exercise/within = section ,
+ exercise/template = exandsol ,
+ solution/template = flushright ,
+ solution/print = true
+}
+
+\renewcommand*\theexercise{\thesection-\arabic{exercise}}
+\newcommand\QA[2]{\IfInsideSolutionTF{#2}{#1}}
+
+\newcommand*\answer[1]{%
+ \begingroup
+ \def\ExerciseType{exercise}%
+ \IfSolutionPrintT{\printsolution{exercise}{#1}}%
+ \endgroup
+}
+
+\begin{document}
+
+\setcounter{section}{1}
+\setcounter{exercise}{30}
+
+\begin{exercise}[ID=one,solution,subtitle=Factorize as much as possible the following expressions.]
+ \begin{tasks}
+ \task \QA{$(2x-3)^2 - (3x-2)^2 =$}{$-(x+5)(5x-1)$}
+ \task \QA{$(x^2-25) - 2(5-x)(x+6) =$}{$(x+5)(3x-17)$}
+ \task \QA{$2x(x+2) + (x+1)^2 + 2 =$}{$3(x+1)^2$}
+ \end{tasks}
+\end{exercise}
+\answer{one}
+
+\end{document}
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-498299.pdf b/macros/latex/contrib/xsim/examples/xsim.texsx-498299.pdf
index 99e8314406..41c97e7254 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-498299.pdf
+++ b/macros/latex/contrib/xsim/examples/xsim.texsx-498299.pdf
Binary files differ
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-498299.tex b/macros/latex/contrib/xsim/examples/xsim.texsx-498299.tex
index 6716d52e7e..6b37b4c518 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.texsx-498299.tex
+++ b/macros/latex/contrib/xsim/examples/xsim.texsx-498299.tex
@@ -1,3 +1,4 @@
+% https://tex.stackexchange.com/q/498299
\documentclass{article}
\usepackage[no-files]{xsim}
\usepackage{tasks}
diff --git a/macros/latex/contrib/xsim/examples/xsim.texsx-576998.pdf b/macros/latex/contrib/xsim/examples/xsim.texsx-576998.pdf
new file mode 100644
index 0000000000..b3aa836926
--- /dev/null
+++ b/macros/latex/contrib/xsim/examples/xsim.texsx-576998.pdf
Binary files differ
diff --git a/macros/latex/contrib/xsim/examples/xsim.texsx-576998.tex b/macros/latex/contrib/xsim/examples/xsim.texsx-576998.tex
new file mode 100644
index 0000000000..ee2947bbb5
--- /dev/null
+++ b/macros/latex/contrib/xsim/examples/xsim.texsx-576998.tex
@@ -0,0 +1,135 @@
+% https://tex.stackexchange.com/q/576998
+\documentclass[twocolumn]{book}
+\usepackage{xsim}
+
+\DeclareExerciseEnvironmentTemplate{number-only}{%
+ \par\noindent
+ \textbf{\GetExerciseProperty{counter}}%
+ \GetExercisePropertyT{subtitle}{ \textit{#1}} %
+}{\par}
+
+\newcommand\printsectionexercises{%
+ \ForEachUsedExerciseByType{%
+ \ifnum\ExercisePropertyGet{##1}{##2}{chapter-value}=\value{chapter}
+ \ifnum\ExercisePropertyGet{##1}{##2}{section-value}=\value{section}
+ \XSIMprint{exercise}{##1}{##2}%
+ \fi
+ \fi
+ }%
+}
+
+\renewcommand\printsolutions{%
+ \def\currentchapter{}%
+ \def\currentsection{}%
+ \def\lastchapter{}%
+ \def\lastsection{}%
+ \ForEachUsedExerciseByType{%
+ \let\lastchapter\currentchapter
+ \let\lastsection\currentsection
+ \edef\currentchapter{\ExercisePropertyGet{##1}{##2}{chapter-value}}%
+ \edef\currentsection{\ExercisePropertyGet{##1}{##2}{section-value}}%
+ \ifx\lastchapter\currentchapter\else
+ \section*{Chapter \ExercisePropertyGet{##1}{##2}{chapter}}
+ \fi
+ \ifx\lastsection\currentsection\else
+ \subsection*{Exercises \ExercisePropertyGet{##1}{##2}{section}}
+ \fi
+ \XSIMprint{solution}{##1}{##2}%
+ }%
+}
+
+\xsimsetup{
+ exercise/template = number-only ,
+ solution/template = number-only ,
+ exercise/within = section ,
+ exercise/the-counter = \arabic{exercise}. ,
+ exercise/print = false
+}
+
+\begin{document}
+
+\setcounter{chapter}{13}
+\chapter{}
+\section{Cats as pets}
+Text text text\dots
+\begin{exercise}
+ Draw a cat.
+\end{exercise}
+\begin{solution}
+ Drawing a cat.
+\end{solution}
+
+Text text text\dots
+\begin{exercise}
+ Bathe a cat.
+\end{exercise}
+\begin{solution}
+ Bathing a cat.
+\end{solution}
+
+Text text text\dots
+\begin{exercise}
+ Trace the history of cats through time.
+\end{exercise}
+\begin{solution}
+ Tracing the history of cats through time.
+\end{solution}
+
+\subsection*{Exercises \thesection}
+\printsectionexercises
+
+\section{Frogs as pets}
+Text text text\dots
+\begin{exercise}
+ Lick a frog.
+\end{exercise}
+\begin{solution}
+ Licking a frog.
+\end{solution}
+
+Text text text\dots
+\begin{exercise}
+ Bathe a frog.
+\end{exercise}
+\begin{solution}
+ Bathing a frog.
+\end{solution}
+
+Text text text\dots
+\begin{exercise}
+ Feed a frog.
+\end{exercise}
+\begin{solution}
+ Feeding a frog.
+\end{solution}
+
+\subsection*{Exercises \thesection}
+\printsectionexercises
+
+\setcounter{chapter}{20}
+\chapter{}
+
+\section{The joys of fish}
+Text text text\dots
+\begin{exercise}
+ Catch a fish.
+\end{exercise}
+\begin{solution}
+ Catching a fish.
+\end{solution}
+
+Text text text\dots
+\begin{exercise}
+ Draw a fish.
+\end{exercise}
+\begin{solution}
+ Drawing a fish.
+\end{solution}
+
+\subsection*{Exercises \thesection}
+\printsectionexercises
+
+\chapter*{Solutions to the exercises}
+\printsolutions
+
+\end{document}
diff --git a/macros/latex/contrib/xsim/examples/xsim.texsx-580636.pdf b/macros/latex/contrib/xsim/examples/xsim.texsx-580636.pdf
new file mode 100644
index 0000000000..d51eb48607
--- /dev/null
+++ b/macros/latex/contrib/xsim/examples/xsim.texsx-580636.pdf
Binary files differ
diff --git a/macros/latex/contrib/xsim/examples/xsim.texsx-580636.tex b/macros/latex/contrib/xsim/examples/xsim.texsx-580636.tex
new file mode 100644
index 0000000000..a6f2be6651
--- /dev/null
+++ b/macros/latex/contrib/xsim/examples/xsim.texsx-580636.tex
@@ -0,0 +1,92 @@
+% https://tex.stackexchange.com/q/580636/
+\documentclass{article}
+\usepackage[use-files]{xsim}
+
+\usepackage[colorlinks,allcolors=blue]{hyperref}
+
+\DeclareExerciseProperty{hints}
+\newcounter{hint}
+\renewcommand\theHhint{\ExerciseID.\arabic{hint}}
+\newcounter{hints}
+\newcounter{step}
+
+\NewDocumentEnvironment{hint}{}{%
+ \stepcounter{hint}%
+ \XSIMsetfilebegin{%
+ \par
+ \refstepcounter{hint}\label{hint:\ExerciseID:\arabic{hint}}%
+ \noindent\textbf{Hint~\thehint\ to exercise \GetExerciseProperty{counter}}%
+ \hfill Back to exercise \ref{ex:\ExerciseID}\par
+ \noindent
+ }%
+ \XSIMsetfileend{\par\addvspace{\bigskipamount}}%
+ \XSIMfilewritestart{\jobname-hint-\ExerciseID-\arabic{hint}.tex}%
+}{%
+ \XSIMfilewritestop
+ \stepcounter{hints}%
+ \SetExpandedExerciseProperty{hints}{\arabic{hints}}%
+}
+
+\DeclareExerciseEnvironmentTemplate{hints}{%
+ \setcounter{hint}{0}%
+ \setcounter{hints}{0}%
+ \par\noindent
+ \textbf{\XSIMmixedcase{\GetExerciseName}\GetExerciseProperty{counter}:}\hfill
+ \IfExercisePropertySetT{hints}{%
+ \setcounter{step}{0}%
+ \def\hintcomma{\def\hintcomma{, }}%
+ Hint\ifnum\GetExerciseProperty{hints}=1\else s\fi:
+ \loop\unless\ifnum\value{step}=\GetExerciseProperty{hints}
+ \stepcounter{step}%
+ \hintcomma\ref{hint:\ExerciseID:\arabic{step}}%
+ \repeat
+ \par\noindent
+ }%
+}{\par\addvspace{\bigskipamount}}
+
+\xsimsetup{
+ exercise/within = section ,
+ exercise/begin-hook = \label{ex:\ExerciseID} ,
+ exercise/template = hints
+}
+
+\newcommand\printhints{%
+ \ForEachUsedExerciseByType{%
+ \setcounter{step}{0}%
+ \setcounter{hint}{0}%
+ \loop\unless\ifnum\value{step}=\GetExerciseProperty{hints}
+ \stepcounter{step}%
+ \input{\jobname-hint-\ExerciseID-\arabic{step}.tex}%
+ \repeat
+ }%
+}
+
+\begin{document}
+
+\section{Exercises}
+\begin{exercise}
+ Description of the exercise. Run the following command
+\begin{verbatim}
+print("Hello world")
+Verbatim &^%$&\content
+\end{verbatim}
+\begin{hint}
+ Run the example from the command line with the python command.
+\end{hint}
+\begin{hint}
+ The solution is 42.
+\end{hint}
+\end{exercise}
+
+\begin{exercise}
+ Another exercise
+\begin{hint}
+ The first ten million years were the worst. Some \verb+&$+.
+\end{hint}
+\end{exercise}
+
+
+\section{Hints}
+\printhints
+
+\end{document}
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.texwelt-15093.pdf b/macros/latex/contrib/xsim/examples/xsim.texwelt-15093.pdf
index 3dc9fb1649..b58d959599 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.texwelt-15093.pdf
+++ b/macros/latex/contrib/xsim/examples/xsim.texwelt-15093.pdf
Binary files differ
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.texwelt-15093.tex b/macros/latex/contrib/xsim/examples/xsim.texwelt-15093.tex
index 1f3fcfefcb..d003cc03af 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.texwelt-15093.tex
+++ b/macros/latex/contrib/xsim/examples/xsim.texwelt-15093.tex
@@ -1,6 +1,5 @@
% http://texwelt.de/wissen/fragen/15093/
\documentclass[paper=a4]{scrartcl}
-\usepackage[utf8]{inputenc}
\usepackage[ngerman]{babel}
\usepackage{xsim,needspace}
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.texwelt-23968.pdf b/macros/latex/contrib/xsim/examples/xsim.texwelt-23968.pdf
index e9816a9793..ac8b2c3d39 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.texwelt-23968.pdf
+++ b/macros/latex/contrib/xsim/examples/xsim.texwelt-23968.pdf
Binary files differ
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.texwelt-23968.tex b/macros/latex/contrib/xsim/examples/xsim.texwelt-23968.tex
index bf205bb7fb..5203bdee8a 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.texwelt-23968.tex
+++ b/macros/latex/contrib/xsim/examples/xsim.texwelt-23968.tex
@@ -18,13 +18,8 @@
\newcommand\printshortsolutions{%
\begin{description}
\ForEachUsedExerciseByType{%
- \def\ExerciseType{##1}%
- \def\ExerciseID{##2}%
\GetExercisePropertyT{shortsolution}
- {%
- \item[Short Solution ##3]
- ####1%
- }%
+ {\item[Short Solution ##3]####1}%
}%
\end{description}
}
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.texwelt-6698.pdf b/macros/latex/contrib/xsim/examples/xsim.texwelt-6698.pdf
index 000663bf44..f8b9609328 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.texwelt-6698.pdf
+++ b/macros/latex/contrib/xsim/examples/xsim.texwelt-6698.pdf
Binary files differ
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.texwelt-6698.tex b/macros/latex/contrib/xsim/examples/xsim.texwelt-6698.tex
index 9e388b9f69..51523e8bcd 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.texwelt-6698.tex
+++ b/macros/latex/contrib/xsim/examples/xsim.texwelt-6698.tex
@@ -1,6 +1,5 @@
% http://texwelt.de/wissen/fragen/6698/
\documentclass{article}
-\usepackage[utf8]{inputenc}
\usepackage[ngerman]{babel}
\usepackage{needspace}
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.various.pdf b/macros/latex/contrib/xsim/examples/xsim.various.pdf
index d0406e830c..aba5075c38 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.various.pdf
+++ b/macros/latex/contrib/xsim/examples/xsim.various.pdf
Binary files differ
diff --git a/macros/latex/contrib/xsim/doc/examples/xsim.various.tex b/macros/latex/contrib/xsim/examples/xsim.various.tex
index 1b7b13f98b..5543010324 100644
--- a/macros/latex/contrib/xsim/doc/examples/xsim.various.tex
+++ b/macros/latex/contrib/xsim/examples/xsim.various.tex
@@ -1,5 +1,6 @@
\documentclass{article}
-\usepackage{xsim,lipsum,tcolorbox}
+\usepackage[use-files]{xsim}
+\usepackage{lipsum,tcolorbox}
\DeclareExerciseType{question}{
exercise-env = question ,
diff --git a/macros/latex/contrib/xsim/doc/xsim-manual.cls b/macros/latex/contrib/xsim/xsim-manual.cls
index c1d198ab04..ed32a87fb3 100644
--- a/macros/latex/contrib/xsim/doc/xsim-manual.cls
+++ b/macros/latex/contrib/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/macros/latex/contrib/xsim/doc/xsim_manual.pdf b/macros/latex/contrib/xsim/xsim-manual.pdf
index dad403c26a..93245d124d 100644
--- a/macros/latex/contrib/xsim/doc/xsim_manual.pdf
+++ b/macros/latex/contrib/xsim/xsim-manual.pdf
Binary files differ
diff --git a/macros/latex/contrib/xsim/doc/xsim_manual.tex b/macros/latex/contrib/xsim/xsim-manual.tex
index 7b1df9ed5d..329f602acf 100644
--- a/macros/latex/contrib/xsim/doc/xsim_manual.tex
+++ b/macros/latex/contrib/xsim/xsim-manual.tex
@@ -2,7 +2,7 @@
% !arara: biber
% arara: pdflatex: { interaction: nonstopmode }
% arara: pdflatex: { interaction: nonstopmode }
-% arara: pdflatex: { interaction: nonstopmode }
+% !arara: pdflatex: { interaction: nonstopmode }
% ----------------------------------------------------------------------------
% the XSIM package
%
@@ -13,15 +13,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'.
%
@@ -33,12 +33,6 @@
\documentclass{xsim-manual}
\begin{filecontents*}[overwrite]{\jobname.bib}
-@online{texsx:romannumeral,
- author = {Bruno Le Floch} ,
- title = {Cunning (La)TeX tricks} ,
- urldate = {2017-03-02} ,
- url = {http://tex.stackexchange.com/a/19769/}
-}
@online{texsx:tagged/exsheets,
title = {Questions tagged `exsheets'} ,
author = {various} ,
@@ -54,33 +48,25 @@
\license
\xsim\ loads the packages \pkg{expl3}~\cite{bnd:l3kernel},
-\pkg{xparse}~\cite{bnd:l3packages}, \pkg{etoolbox}~\cite{pkg:etoolbox},
-\pkg{array}~\cite{pkg:array} \pkg{booktabs}~\cite{pkg:booktabs} and
+\pkg{xparse}~\cite{bnd:l3packages}, \pkg{array}~\cite{pkg:array}
+\pkg{booktabs}~\cite{pkg:booktabs} and
\pkg{translations}~\cite{pkg:translations}. All of these packages are present
on a modern and up to date \TeX\ distribution such as \TeX~Live or MiK\TeX\ so
no further action should be needed. When you are using \xsim\ you should be
using an up to date \TeX\ distribution, anyway.
\begin{bewareofthedog}
+ Please be aware that \xsim\ is in an experimental state and actively
+ developed. Many aspects may change from one update to another until a
+ stable version~1 will be reached. However, I will try my best to keep the
+ interface stable.
+
Newer versions of \xsim\ may depend on newer versions of the support
packages. Remember: it is always dangerous to update single packages.
Always update your \TeX\ distribution if you want an up to date version of a
package. Be careful: if you're in the middle of an important project it
might be better to wait with the update until you've finished the project.
Every update might be breaking some things.
-
- Please also be aware that \xsim\ is actively developed and many things may
- still change. However, I will try my best to keep the interface stable.
-\end{bewareofthedog}
-
-I'm currently thinking to make the option \option{no-files} the default
-behavior of \xsim. There is a poll and discussion regarding this question on
-\xsim's github page if you like to give your opinion on this.
-
-\begin{bewareofthedog}
- The whole collection mechanism is likely to change completely in the
- not-so-far future (let's say sometime in the six months from April~2020 or
- so).
\end{bewareofthedog}
\section{Motivation, Background}
@@ -88,7 +74,7 @@ behavior of \xsim. There is a poll and discussion regarding this question on
It has been quite a while since I first published
\pkg{exsheets}~\cite{pkg:exsheets} in June 2012. Since then it has gained a
user base and a little bit of popularity as the number of questions on tex.sx
-shows (143~at the time of writing)~\cite{texsx:tagged/exsheets}. User
+shows (151~at the time of writing)~\cite{texsx:tagged/exsheets}. User
questions, bug reports and feature requests improved it over the time. It
still has a version number starting with a zero, though, which in my
versioning system means I still consider it experimental.
@@ -140,12 +126,13 @@ meaning in this manual.
probability of possibly faulty exercises after changes to the document.}
The \option{final} option automatically disables this option. See also
sections~\vref{sec:how-exerc-envir} and~\vref{sec:resolve-getting}.
- \opt{no-files}
+ \opt{no-files}\Default{true}
\sinceversion{0.13}This option prevents \xsim\ from writing the exercises
and solutions to external files. This will keep your working folder
``clean'' but will also prevent using verbatim material in exercises and
- solutions and will possibly slow processing further down. \emph{This
- option is considered experimental. Feedback is very welcome.}
+ solutions.
+ \opt{use-files}\Default{false}
+ \sinceversion{0.20}This is the opposite of the option \option{no-files}.
\opt{use-aux}
\sinceversion{0.15}With this option enabled \xsim\ will use the regular
auxiliary file \cs*{jobname}\code{.aux} instead of its own auxiliary file
@@ -158,7 +145,7 @@ meaning in this manual.
Those options are load-time options and are used the usual way as package
options:
\begin{sourcecode}
- \usepackage[verbose]{xsim}
+ \usepackage[use-files]{xsim}
\end{sourcecode}
\begin{bewareofthedog}
Although those options technically belong to the \module{package} module
@@ -271,19 +258,31 @@ More details on those two environments can be found in
section~\vref{sec:using-printing}.
\section{How the Exercise Environments Work}\label{sec:how-exerc-envir}
-Both the exercise and the solution environments write the contents of their
-bodies verbatim to external files following a certain naming structure:
+\sinceversion{0.13}Depending on the options
+\option{no-files}/\option{use-files} the bodies of exercises and solutions is
+either just another property (see section~\vref{sec:exercise-properties}) --
+this is the default behavior -- or is written to an external file.
+
+If the option \keyis{no-files}{true} is set the exercise and solution bodies
+are saved as properties \property{exercise-body} and
+\property{solution-body}. This is the default behavior of \xsim\ since
+version~0.20 and should work fine in most cases. One obvious downsise is that
+verbatim material cannot be used in exercises and solutions.
+
+If the option \keyis{use-files}{true} is set both the exercise and the
+solution environments write the contents of their bodies verbatim to external
+files following a certain naming structure:
\begin{itemize}
\item
- \code{\meta{jobname}-\meta{type}-\meta{id}-exercise|solution-body.tex}
+ \code{\meta{jobname}-\meta{type}-\meta{id}-exercise|solution-body.tex}
\end{itemize}
The name starts with the name of the job (which is the name of the document
itself) followed by type and id of the corresponding exercise and then
followed by the environment type. For example both environments from the first
example have been written to files named
\begin{itemize}
- \item \verbcode+xsim_manual-exercise-1-exercise-body.tex+ and
- \item \verbcode+xsim_manual-exercise-1-solution-body.tex+, respectively.
+ \item \verbcode+xsim-manual-exercise-1-exercise-body.tex+ and
+ \item \verbcode+xsim-manual-exercise-1-solution-body.tex+, respectively.
\end{itemize}
These external files are input when the respective exercise or solution is
printed. An advantage of using external files is that \emph{verbatim material
@@ -298,7 +297,7 @@ it was generated\footnote{In this example the sourcecode line number is
external file where the \env{exercise} environment indeed \emph{was} on
line~1.}:
-\inputsourcecode{exercises/xsim_manual-exercise-1-exercise-body.tex}
+\inputsourcecode{exercises/xsim-manual-exercise-1-exercise-body.tex}
Arguably one downside of the approach using external files for each exercise
and its solution is that your project folder will be cluttered with files. In
@@ -326,19 +325,6 @@ order to deal with this somehow \xsim\ offers the following option:
\end{exercise}
\end{sourcecode}
-If\sinceversion{0.13} you don't like all the external files and the problems
-which come with them \emph{and} if you don't need any verbatim or similar
-material inside the exercises and solutions then you can use the following
-package option:
-\begin{options}
- \opt{no-files}
- This package option prevents \xsim\ from writing the exercises and
- solutions to external files. This will keep your working folder ``clean''
- but will also prevent using verbatim material in exercises and solutions
- and will possibly slow processing further down. \emph{This option is
- considered experimental. Feedback is very welcome.}
-\end{options}
-
\begin{bewareofthedog}
\xsimauxfileinfo
\end{bewareofthedog}
@@ -436,6 +422,12 @@ must) be set. Here is the complete list:
types of exercises sharing a common counter. \emph{This parameter can't
be changed afterwards.} If the explicit or implicit counter does not
exist, yet, it will be defined.
+ \paraval{within}{counter name}
+ \sinceversion{0.20}Adds \parameter{counter} to the reset list of
+ \meta{counter name} by applying \cs*{counterwithin}.
+ \paraval{the-counter}{code}
+ \sinceversion{0.20}Redefines the corresponding representation command
+ \cs*{the...} of \parameter{counter} to \meta{code}.
\paraval{solution-counter}{counter name}
The counter used for the solutions of type \meta{type}. If not explicitly
set the counter with the same name as \parameter{solution-env} is used.
@@ -809,25 +801,32 @@ an exercise:\label{property:print!}
\subsection{What the Environments do}
When an exercise is started with \environ{exercise} (or other environments
-defined through \cs{DeclareExerciseType}) then different things happen
-depending on different settings:
-\begin{itemize}
- \item If the \emph{insert mode} is active nothing happens, see
- section~\vref{sec:collecting-exercises} for details on this.
- \item Else the id integer is incremented.
- \item If the exercise is \emph{used} the corresponding counter is stepped
- and the exercise is added to the \enquote{use list}. The properties
- \property{counter} and \property{use} are updated accordingly.
- \item If an exercise is \emph{printed} then it is also \emph{used}. An
- exercise that isn't used cannot be printed. Being printed means two
- things: being added to the \enquote{print list} and being typeset at the
- position where the exercise is placed in the source file. If an exercise
- is \emph{not printed but used} it means that the counter will be stepped.
- This can be useful for creating an exercise sheet only containing the
- solutions for some exercises.
- \item If an exercise is printed certain hooks and template code is inserted
- around the environment body.
-\end{itemize}
+defined through \cs{DeclareExerciseType}) then three things happen depending
+on the setup:
+\begin{enumerate}
+ \item where the environment is placed in the document the \textbf{base
+ setup} happens: this sets the \property{id} of the exercise and sets the
+ properties chosen in the optional argument.
+ \item in the default setting also the \textbf{usage setup} happens: this
+ increments the counter and sets the counter related properties like
+ \property{counter}. Also the properties related to section numbers and the
+ \property{page} are set.
+ \item in the default setting also the \textbf{print setup} happens: this
+ mostly does nothing. It initiates recording goals that are set inside of
+ the exercise body.
+\end{enumerate}
+
+Depending on wether the option \module{exercise}\code{/}\option{use} has been
+set to \code{false} or wether the property \property{use} has been set to
+\code{false} the \emph{usage setup} can be delayed. The usage the happens
+when the exercise is \emph{inserted} the first time elsewhere in the document,
+for example as part of a collection, see
+section~\vref{sec:collecting-exercises}.
+
+Depending on wether the option \module{exercise}\code{/}\option{print} has
+been set to \code{false} or if the property \property{print} has been set to
+\code{false} the \emph{print setup} can be suppressed. It happens each time
+an exercise is inserted.
\begin{example}
\begin{exercise}[print=false,ID=invisible]
@@ -867,10 +866,14 @@ the environments' names are the module names for the options (here using the
Determines if exercises of type \enquote{exercise} are printed.
\keybool{use}\Module{exercise}\Default{true}
Determines if exercises of type \enquote{exercise} are used.
+ \keybool{collect}\Module{exercise}\Default{false}
+ \sinceversion{0.20}Sets both \option{print} and \option{use} to
+ \code{false} when \keyis{collect}{true} is set and vice versa.
\keyval{within}{counter}\Module{exercise}\Default
- Adds the exercise counter to the reset list of the counter
- \meta{counter}. \emph{Beware that if the counter is a shared counter
- this will affect \emph{all objects} using this counter!}
+ \changedversion{0.20}Adds the exercise counter to the reset list of the
+ counter \meta{counter} using \cs*{counterwithin}. \emph{Beware that if
+ the counter is a shared counter this will affect \emph{all objects}
+ using this counter!}
\keyval{the-counter}{code}\Module{exercise}
An interface for redefining the counter representation command
\cs*{the\meta{counter}}.
@@ -940,55 +943,82 @@ existing exercise, \ie, every exercise whose external file exists.
\section{Collecting Exercises}\label{sec:collecting-exercises}
\begin{bewareofthedog}
- The whole collection mechanism is likely to change completely in the
- not-so-far future (let's say sometime in the six months from April~2020 or
- so).
+ The whole collection mechanism has been changed completely with
+ version~0.20. Please check this section carefully and update and adapt your
+ collections.
\end{bewareofthedog}
\subsection{Background}
-\xsim\ knows the concept of \enquote{exercise collections}. A collection of
-exercises can be useful when you want to print a certain group of exercises
-several times. Each collection must have a unique name with which you can
-refer to the corresponding collection. A collection is realized by declaring
-the collection and by surrounding the exercises belonging to the collection
-with a certain pair of commands (this is explained in the next section).
-
-Let's say you have several files of math exercises where one only contains
-geometry exercises and another only calculus exercises and so on. Surrounding
-the \cs*{input} of each file with said pair of commands for a certain
-collection all exercises of the corresponding file now are a collection which
-then can be printed at once whereever you want the collection of exercises to
-be printed. By choosing certain tags (see section~\vref{sec:tags}) inside
-each collection you could even cherry-pick exercises from the external file.
+\xsim\ knows the concept of \emph{exercise collections}. A collection of
+exercises can be used in two cases, basically:
+\begin{enumerate}
+ \item When you want to print a certain group of exercises several times. In
+ this case you add the exercise to a collection while also using it in the
+ running text. Somewhere later (or earlier actually) in the document you
+ can the reprint the collection\footnote{There is another way to do that,
+ but\dots}.
+ \item If you only want to print exercises which have certain tags. Maybe
+ you have some kind of exercise library in an external which you include
+ into you document and want to print only those exercises which fit
+ certain conditions.
+\end{enumerate}
+Each collection must have a unique name with which you can refer to the
+corresponding collection. A collection is realized by declaring the
+collection in the preamble and by activating the collection.
\subsection{Usage}
+\subsubsection{Declaring collections}
\emph{A collection must be declared in the preamble.} Using a pair of
commands explained below exercises between those commands are added to the
corresponding collection but not printed. After a collection is completed the
collection can be printed as often as needed.
\begin{commands}
- \command{DeclareExerciseCollection}[\marg{collection name}]
+ \command{DeclareExerciseCollection}[\oarg{tag values}\marg{collection name}]
Define a new collection \meta{collection name} in the document preamble.
- \command{collectexercisestype}[\marg{collection name}\marg{exercise type}]
- Opens the collection \meta{collection name} which now collects all
- exercises of type \meta{exercise type} until the collection is closed with
- \cs{collectexercisesstop}. Collections of other types are not
- collected\footnote{This command starts a group with
- \cs*{begingroup}!}.
+ An example could look like this:
+ \cs{DeclareExerciseCollection}\Oarg{topics=algebra,level=1}\Marg{easy-algebra}.
+ Choosing tags automatically activates the collection which means that all
+ exercises which fit the tags are automatically added to the new
+ collection.
+\end{commands}
+
+\subsubsection{Activating collections}
+If a collection is not activated per default in can be activated (or
+deactivated in the opposite case) with these commands:
+\begin{commands}
+ \command{activatecollection}[\marg{collection name}]
+ \sinceversion{0.20}Activates the collection \meta{collection name} which
+ now collects all exercises until the collection is
+ deactivated. \meta{collection name} can be a csv list of collection
+ names.
+ \command{deactivatecollection}[\marg{collection name}]
+ \sinceversion{0.20}Deactivates the collection \meta{collection name}.
+ \meta{collection name} can be a csv list of collection names.
+\end{commands}
+These commands do not influence exercises in other ways other than adding them
+to collections.
+\begin{commands}
\command{collectexercises}[\marg{collection name}]
- Opens the collection \meta{collection name} which now collects all
- exercises until the collection is closed with
- \cs{collectexercisesstop}\footnote{This command starts a group with
- \cs*{begingroup}!}.
+ Activates the collection \meta{collection name} which now collects all
+ exercises until the collection is deactivated, starts a group with
+ \cs*{begingroup} and sets the option \option{collect}, see below.
\command{collectexercisesstop}[\marg{collection name}]
- Closes the collection \meta{collection name}\footnote{This command ends
- a group with \cs*{endgroup}!}.
+ Deactivates the collection \meta{collection name} and ends a group with
+ \cs*{endgroup}.
+\end{commands}
+\begin{options}
+ \keybool{collect}\Default{false}
+ A shortcut option which sets the options
+ \module{\meta{type}}\code{/}\module{collect} for each exercise type.
+\end{options}
+
+\subsubsection{Printing collections}
+\begin{commands}
\command{printcollection}[\oarg{options}\marg{collection name}]
Prints the collection \meta{collection name}, \ie, all exercises collected
earlier. This command cannot be used before the corresponding collection
has been closed correctly.
\end{commands}
-
Valid options are the following:
\begin{options}
\keybool{headings}\Module{print-collection}\Default{false}
@@ -1042,11 +1072,11 @@ You can open several collections at the same time:
\begin{sourcecode}
\collectexercises{foo}
...
- \collectexercisestype{bar}{exercises}
+ \activatecollection{bar}
...
- \collectexercisesstop{bar}
+ \deactivatecollection{foo}
...
- \collectexercisesstop{foo}
+ \collectexercisesstop{bar}
\end{sourcecode}
Exercises will be added to each open collection.
@@ -1589,9 +1619,7 @@ yourself in order to achieve certain layouts\footnote{I plan to incorporate
Returns \meta{true} if both a macro \cs*{chapter} and a counter
\code{chapter} are defined and \meta{false} otherwise.
\command{XSIMmixedcase}[\marg{code}]
- Converts the full expansion\footnote{This is a \cs*{romannumeral}
- expansion~\cite{texsx:romannumeral}.\label{fn:romannumeral}} of
- \meta{code} to mixed case: \\
+ Converts the full expansion of \meta{code} to mixed case: \\
\verbcode+\XSIMmixedcase{this is some text}+ \XSIMmixedcase{this is some
text} \\
\emph{This command expands \meta{code} before converting it}.
@@ -1601,16 +1629,16 @@ yourself in order to achieve certain layouts\footnote{I plan to incorporate
macro \cs*{g@addto@macro}.
\expandable\command{XSIMifeq\TF}[\marg{code 1}\marg{code
2}\marg{true}\marg{false}]
- Checks if the full expansion\footref{fn:romannumeral} of \meta{code 1} and
- \meta{code 2} is the same tokenlist.
+ Checks if the full expansion of \meta{code 1} and \meta{code 2} is the
+ same tokenlist.
\expandable\command{XSIMifblank\TF}[\marg{code}\marg{true}\marg{false}]
- Checks if the full expansion\footref{fn:romannumeral} of \meta{code} is
- blank (\ie, if it is empty or only consists of spaces).
+ Checks if the full expansion of \meta{code} is blank (\ie, if it is empty
+ or only consists of spaces).
\command{XSIMatbegindocument}[\marg{code}]
- \sinceversion{0.15a}Adds \meta{code} to \xsim's begin document hook.
+ \sinceversion{0.16}Adds \meta{code} to \xsim's begin document hook.
Should be used inside style files instead of \cs*{AtBeginDocument}.
\command{XSIMatenddocument}[\marg{code}]
- \sinceversion{0.15a}Adds \meta{code} to \xsim's end document hook.
+ \sinceversion{0.16}Adds \meta{code} to \xsim's end document hook.
Should be used inside style files instead of \cs*{AtEndDocument}.
\end{commands}
@@ -1918,8 +1946,7 @@ vertical layout.
\DeclareExerciseTableTemplate{default}{%
\XSIMputright\ExerciseTableCode{%
\toprule
- \XSIMifblankTF{\ExerciseType}
- {}
+ \XSIMifblankF{\ExerciseType}
{\XSIMmixedcase{\GetExerciseParameter{exercise-name}}}
&
\XSIMmixedcase{\XSIMtranslate{points}} &
@@ -1927,19 +1954,17 @@ vertical layout.
\midrule
}%
\ForEachUsedExerciseByType{%
- \XSIMifeqTF{#1}{\ExerciseTableType{#1}}
+ \XSIMifeqT{#1}{\ExerciseTableType{#1}}
{%
- \XSIMifblankTF{\ExerciseType}
+ \XSIMifblankT{\ExerciseTableType{}}
{%
\XSIMputright\ExerciseTableCode{%
\XSIMmixedcase{\ExerciseParameterGet{#1}{exercise-name} }%
}%
- }
- {}%
+ }%
\XSIMputright\ExerciseTableCode
{#3 & \XSIMifblankTF{#5}{\printgoal{0}}{\printgoal{#5}} & \\ }%
- }
- {}%
+ }%
}
\XSIMputright\ExerciseTableCode{%
\midrule
@@ -1979,24 +2004,21 @@ layout.
\DeclareExerciseTableTemplate{default*}{%
\XSIMputright\ExerciseTableCode{%
\toprule
- \XSIMifblankTF{\ExerciseType}
- {}
+ \XSIMifblankF{\ExerciseType}
{\XSIMmixedcase{\GetExerciseParameter{exercise-name}}}
&%
}%
\ForEachUsedExerciseByType{%
- \XSIMifeqTF {#1} { \ExerciseTableType {#1} }
+ \XSIMifeqT{#1}{\ExerciseTableType{#1}}
{
- \XSIMifblankTF{\ExerciseType}
+ \XSIMifblankT{\ExerciseTableType{}}
{%
\XSIMputright\ExerciseTableCode{%
\XSIMmixedcase{\ExerciseParameterGet{#1}{exercise-name} }%
}%
- }
- {}%
+ }%
\XSIMputright\ExerciseTableCode{#3 &}
- }
- {}%
+ }%
}%
\XSIMputright\ExerciseTableCode{%
\XSIMtranslate{total} \\
@@ -2004,12 +2026,11 @@ layout.
\XSIMmixedcase{\XSIMtranslate{points}} &
}%
\ForEachUsedExerciseByType{%
- \XSIMifeqTF{#1}{\ExerciseTableType{#1}}
+ \XSIMifeqT{#1}{\ExerciseTableType{#1}}
{%
\XSIMputright\ExerciseTableCode{%
\XSIMifblankTF{#5}{\printgoal{0}}{\printgoal{#5}} &}%
- }
- {}%
+ }%
}%
\XSIMputright\ExerciseTableCode{%
\XSIMifblankTF{\ExerciseType}
@@ -2019,12 +2040,11 @@ layout.
\XSIMtranslate{reached} &%
}%
\ForEachUsedExerciseByType{%
- \XSIMifeqTF{#1}{\ExerciseTableType{#1}}
- {\XSIMputright\ExerciseTableCode{&}}
- {}%
+ \XSIMifeqT{#1}{\ExerciseTableType{#1}}
+ {\XSIMputright\ExerciseTableCode{&}}%
}%
\XSIMputright\ExerciseTableCode{ \\ \bottomrule }%
- \def\numberofcolumns{%
+ \edef\numberofcolumns{%
\XSIMifblankTF{\ExerciseType}
{\numberofusedexercises}
{\csname numberof \ExerciseType s\endcsname}%
@@ -2192,14 +2212,11 @@ especially regarding other layouts are also shown in example files added to
this package.
\subsection{\dots Know if \xsim\ Needs Another Compilation?}
-If \xsim\ wants you to recompile your document it writes the following to the
-logfile:
+If \xsim\ wants you to recompile your document it issues a warning and writes
+the following to the logfile:
\begin{sourcecode}
- *************************************************
- * xsim warning: "rerun"
- *
- * Exercise properties may have changed. Rerun to get them synchronized.
- *************************************************
+ Package xsim Warning: Exercise properties may have changed. Rerun to get them
+ (xsim) synchronized.
\end{sourcecode}
So just check the logfile regularly (which you should be doing anyway) and
keep your eyes open.
@@ -2216,14 +2233,15 @@ compilations may resolve your problems.
\subsection{\code{! TeX capacity exceeded, sorry [text input levels=15].}
Why?}
Did you try to use an exercise or solution in a macro of some sort? This
-generally will fail\footnote{The reasons are similar to the ones given here:
+generally will fail if you also use the option \option{use-files}\footnote{The
+ reasons are similar to the ones given here:
\url{https://tex.stackexchange.com/a/295422/}.}. But there should never be
the need to hide the environments inside of a macro, anyway.
\subsection{\code{Runaway argument? !File ended while scanning use of \^{}\^{}M.} Why?}
Did you try to use an exercise or solution in a macro of some sort? This
-generally will fail. But there should never be the need to hide the
-environments inside of a macro, anyway.
+generally will fail if you also use the option \option{use-files}. But there
+should never be the need to hide the environments inside of a macro, anyway.
\subsection{\dots Put a Star (or Another Symbol) in Headings of Exercises That
Are Special?}
diff --git a/macros/latex/contrib/xsim/xsim.sty b/macros/latex/contrib/xsim/xsim.sty
new file mode 100644
index 0000000000..94866005c4
--- /dev/null
+++ b/macros/latex/contrib/xsim/xsim.sty
@@ -0,0 +1,5629 @@
+% ----------------------------------------------------------------------------
+% the XSIM package
+%
+% eXercise Sheets IMproved
+%
+% ----------------------------------------------------------------------------
+% Clemens Niederberger
+% Web: https://github.com/cgnieder/xsim
+% E-Mail: contact@mychemistry.eu
+% ----------------------------------------------------------------------------
+% 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.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.3c or later is part of all distributions of LaTeX
+% version 2008/05/04 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.
+% ----------------------------------------------------------------------------
+\RequirePackage {l3keys2e,xsimverb}
+
+\ExplSyntaxOn
+
+\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 {20}
+\tl_const:Nn \c_xsim_version_subrelease_tl {}
+\tl_const:Nx \c_xsim_version_number_tl
+ {
+ \c_xsim_version_major_number_tl .
+ \c_xsim_version_minor_number_tl
+ }
+\tl_const:Nx \c_xsim_version_tl
+ {
+ \c_xsim_version_number_tl
+ \c_xsim_version_subrelease_tl
+ }
+\tl_const:Nn \c_xsim_info_tl {eXercise ~ Sheets ~ IMproved}
+
+\ProvidesExplPackage
+ {xsim}
+ {\c_xsim_date_tl}
+ {\c_xsim_version_tl}
+ {\c_xsim_info_tl}
+
+% --------------------------------------------------------------------------
+% options, information
+
+\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 ,
+ 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}
+
+\keys_define:nn {xsim/package}
+ {
+ final .code:n = \msg_error:nnn {xsim} {load-time-option} {final} ,
+ verbose .code:n = \msg_error:nnn {xsim} {load-time-option} {verbose} ,
+ debug .code:n = \msg_error:nnn {xsim} {load-time-option} {debug} ,
+ clear-aux .code:n = \msg_error:nnn {xsim} {load-time-option} {clear-aux} ,
+ 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}
+ }
+
+% --------------------------------------------------------------------------
+
+% messages:
+\msg_new:nnn {xsim} {load-time-option}
+ {
+ `#1'~ is~ a~ load-time~ option! \\
+ You~ cannot~ set~ it~ with~ \token_to_str:N \xsimsetup ! \\
+ You~ need~ to~ use~ \token_to_str:N \usepackage [#1] {xsim} .
+ }
+
+\msg_new:nnn {xsim} {rerun}
+ {
+ Exercise~ properties~ may~ have~ changed.~ Rerun~ to~ get~ them~
+ synchronized.
+ }
+
+\msg_new:nnn {xsim} {verbose} { #1 ~( \msg_line_context: ) }
+
+% --------------------------------------------------------------------------
+
+\cs_new_protected:Npn \xsim_do_rerun:
+ { \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.
+ }
+
+% ----------------------------------------------------------------------------
+
+\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: }
+ }
+
+% --------------------------------------------------------------------------
+% 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}
+ }
+ }
+
+% #1: module
+% #2: hook name
+\cs_new_protected:Npn \__xsim_module_hook_use:nn #1#2
+ {
+ \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}
+
+% --------------------------------------------------------------------------
+
+\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} }
+
+\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/macros/latex/contrib/xsim/code/xsim.verbwrite.code.tex b/macros/latex/contrib/xsim/xsimverb.sty
index e43c30d34d..712440d423 100644
--- a/macros/latex/contrib/xsim/code/xsim.verbwrite.code.tex
+++ b/macros/latex/contrib/xsim/xsimverb.sty
@@ -1,22 +1,22 @@
% ----------------------------------------------------------------------------
-% the XSIM package - verbwrite module
+% the XSIMVERB package
%
-% eXercise Sheets IMproved
+% write environments verbatim to files
%
% ----------------------------------------------------------------------------
% Clemens Niederberger
% 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,9 +25,100 @@
% If you have any ideas, questions, suggestions or bugs to report, please
% feel free to contact me.
% ----------------------------------------------------------------------------
+\RequirePackage {l3keys2e}
+\ExplSyntaxOn
+
+\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 {3}
+\tl_const:Nn \c_xsimverb_version_subrelease_tl {}
+\tl_const:Nx \c_xsimverb_version_number_tl
+ {
+ \c_xsimverb_version_major_number_tl .
+ \c_xsimverb_version_minor_number_tl
+ }
+\tl_const:Nx \c_xsimverb_version_tl
+ {
+ \c_xsimverb_version_number_tl
+ \c_xsimverb_version_subrelease_tl
+ }
+\tl_const:Nn \c_xsimverb_info_tl {write~ environments~ verbatim~ to~ files}
+
+\ProvidesExplPackage
+ {xsimverb}
+ {\c_xsimverb_date_tl}
+ {\c_xsimverb_version_tl}
+ {\c_xsimverb_info_tl}
+
+% options, information
+
+\cs_new_protected:Npn \xsimverb_bool_provide:N #1
+ { \bool_if_exist:NF #1 { \bool_new:N #1 } }
+
+\xsimverb_bool_provide:N \g__xsim_final_bool
+\xsimverb_bool_provide:N \g__xsim_verbose_bool
+\xsimverb_bool_provide:N \g_xsim_clear_aux_bool
+\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 ,
+ 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: }
+ }
+
+ \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}
+ }
+
+% --------------------------------------------------------------------------
+% #1: name
+% #2: description
+\cs_set_protected:Npn \XSIMmodule #1#2 {}
+\cs_set_protected:Npn \XSIMmoduleend {}
+
+% --------------------------------------------------------------------------
\XSIMmodule{verbwrite}{write contents of environments verbatim to files}
-\xsim_load_modules:n {base}
+\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
@@ -43,27 +134,29 @@
\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 { \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
+ \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
- { \xsim_if_final:F { \iow_close:N #1 } }
+ { \bool_if:NT \l__xsim_stream_open_bool { \iow_close:N #1 } }
% #1: write stream
% #2: contents
@@ -73,21 +166,22 @@
{
% 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 }
+ \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__xsim_tmpa_int
- \tl_set:Nx \l__xsim_tmpa_tl { \tl_tail:N \l__xsim_tmpa_tl }
+ \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__xsim_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 }
@@ -106,6 +200,7 @@
{ \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:
{
@@ -135,17 +230,17 @@
\xsim_if_final:F %
{ %
\iow_now:Nx \l__xsim_file_contents_iow %
- { \l_xsim_file_begin_tl } %
+ { \exp_not:V \l_xsim_file_begin_tl } %
} %
} %
\__xsim_set_verb_catcodes: %
- \tl_set:Nx \l__xsim_tmpa_tl %
+ \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__xsim_tmpa_tl %
- ####2 \l__xsim_tmpa_tl %
+ ####1 \l__xsimverb_tmpa_tl %
+ ####2 \l__xsimverb_tmpa_tl %
####3 \exp_not:N \q_stop: %
} %
{ %
@@ -168,8 +263,8 @@
\cs_set:Npx \__xsim_M:w ##1 ^^M %
{ %
\exp_not:N \__xsim_tmpa:www ##1 %
- \l__xsim_tmpa_tl %
- \l__xsim_tmpa_tl %
+ \l__xsimverb_tmpa_tl %
+ \l__xsimverb_tmpa_tl %
\exp_not:N \q_stop: %
} %
\char_set_active_eq:nN {13} \__xsim_M:w %
@@ -185,7 +280,7 @@
\xsim_if_final:F
{
\iow_now:Nx \l__xsim_file_contents_iow
- { \l_xsim_file_end_tl }
+ { \exp_not:V \l_xsim_file_end_tl }
}
}
\__xsim_close_stream:N \l__xsim_file_contents_iow
@@ -213,5 +308,4 @@
\NewDocumentCommand \XSIMgobblechars {m}
{ \int_set:Nn \l_xsim_line_gobble_int {#1} }
-% ----------------------------------------------------------------------------
-\file_input_stop:
+\XSIMmoduleend