├── HISTORY ├── IDEAS ├── README ├── TODO ├── code ├── 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.properties.code.tex ├── xsim.random.code.tex ├── xsim.solutions.code.tex ├── xsim.start.code.tex ├── xsim.sty ├── xsim.style.layouts.code.tex ├── xsim.tags.code.tex ├── xsim.templates.code.tex ├── xsim.translations.code.tex ├── xsim.verbwrite.code.tex ├── xsimverb.start.code.tex └── xsimverb.sty ├── doc ├── examples │ ├── xsim.blanks.pdf │ ├── xsim.blanks.tex │ ├── xsim.boxed-headings.pdf │ ├── xsim.boxed-headings.tex │ ├── xsim.code-and-output.pdf │ ├── xsim.code-and-output.tex │ ├── xsim.collections.pdf │ ├── xsim.collections.tex │ ├── xsim.crossref.pdf │ ├── xsim.crossref.tex │ ├── xsim.description-list.pdf │ ├── xsim.description-list.tex │ ├── xsim.different-point-types.pdf │ ├── xsim.different-point-types.tex │ ├── xsim.difficulties.pdf │ ├── xsim.difficulties.tex │ ├── xsim.floating.pdf │ ├── xsim.floating.tex │ ├── xsim.golatex-80640.pdf │ ├── xsim.golatex-80640.tex │ ├── xsim.golatex-91339.pdf │ ├── xsim.golatex-91339.tex │ ├── xsim.grade-distribution.pdf │ ├── xsim.grade-distribution.tex │ ├── xsim.hints.pdf │ ├── xsim.hints.tex │ ├── xsim.issues-49.pdf │ ├── xsim.issues-49.tex │ ├── xsim.listings.pdf │ ├── xsim.listings.tex │ ├── xsim.listofexercises.pdf │ ├── xsim.listofexercises.tex │ ├── xsim.multiplechoice.pdf │ ├── xsim.multiplechoice.tex │ ├── xsim.pointsums.pdf │ ├── xsim.pointsums.tex │ ├── xsim.randomexercises.pdf │ ├── xsim.randomexercises.tex │ ├── xsim.texsx-13635.pdf │ ├── xsim.texsx-13635.tex │ ├── xsim.texsx-155630.pdf │ ├── xsim.texsx-155630.tex │ ├── xsim.texsx-199360.pdf │ ├── xsim.texsx-199360.tex │ ├── xsim.texsx-299534.pdf │ ├── xsim.texsx-299534.tex │ ├── xsim.texsx-305110.pdf │ ├── xsim.texsx-305110.tex │ ├── xsim.texsx-308883.pdf │ ├── xsim.texsx-308883.tex │ ├── xsim.texsx-338165.pdf │ ├── xsim.texsx-338165.tex │ ├── xsim.texsx-350028.pdf │ ├── xsim.texsx-350028.tex │ ├── xsim.texsx-369065.pdf │ ├── xsim.texsx-369065.tex │ ├── xsim.texsx-369636.pdf │ ├── xsim.texsx-369636.tex │ ├── xsim.texsx-369803.pdf │ ├── xsim.texsx-369803.tex │ ├── xsim.texsx-370642.pdf │ ├── xsim.texsx-370642.tex │ ├── xsim.texsx-391530.pdf │ ├── xsim.texsx-391530.tex │ ├── xsim.texsx-395273.pdf │ ├── xsim.texsx-395273.tex │ ├── xsim.texsx-466584.pdf │ ├── xsim.texsx-466584.tex │ ├── xsim.texsx-498299.pdf │ ├── xsim.texsx-498299.tex │ ├── xsim.texsx-549540.pdf │ ├── xsim.texsx-549540.tex │ ├── xsim.texsx-576998.pdf │ ├── xsim.texsx-576998.tex │ ├── xsim.texsx-580636.pdf │ ├── xsim.texsx-580636.tex │ ├── xsim.texwelt-15093.pdf │ ├── xsim.texwelt-15093.tex │ ├── xsim.texwelt-23968.pdf │ ├── xsim.texwelt-23968.tex │ ├── xsim.texwelt-6698.pdf │ ├── xsim.texwelt-6698.tex │ ├── xsim.various.pdf │ └── xsim.various.tex ├── xsim-manual.cls ├── xsim-manual.pdf └── xsim-manual.tex └── xsim.build /HISTORY: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------- 2 | 3 | XSIM -- eXercise Sheets IMproved 4 | 5 | -------------------------------------------------------------------------- 6 | Clemens Niederberger 7 | Web: https://github.com/cgnieder/xsim 8 | E-Mail: clemens@cnltx.de 9 | -------------------------------------------------------------------------- 10 | Copyright 2017--2022 Clemens Niederberger 11 | 12 | This work may be distributed and/or modified under the 13 | conditions of the LaTeX Project Public License, either version 1.3c 14 | of this license or (at your option) any later version. 15 | The latest version of this license is in 16 | http://www.latex-project.org/lppl.txt 17 | and version 1.3c or later is part of all distributions of LaTeX 18 | version 2008/05/04 or later. 19 | 20 | This work has the LPPL maintenance status `maintained'. 21 | 22 | The Current Maintainer of this work is Clemens Niederberger. 23 | -------------------------------------------------------------------------- 24 | 25 | HISTORY: 26 | 27 | v0.0 2017/02/09 - start with coding the first ideas 28 | v0.1 2017/03/19 - first draft which actually seems to do everything as 29 | planned 30 | v0.2 2017/03/21 - bugfix in the verbwrite module 31 | - add `use!' and `print!' properties 32 | - add the concepts of `noupdate' and `boolean' properties 33 | v0.4 2017/03/24 - \IfExerciseBooleanPropertyTF 34 | - \GetExercisePropertyTF, \PropertyValue 35 | - \printallsolutions 36 | - \UseExerciseTemplate 37 | - bug fix in solution environments: now get printed again 38 | when option `print=true' is used 39 | - bug fix to the translations of the solution list headings: 40 | exercise name instead of exercise type is now printed 41 | - \AddtoExerciseTypeGoal, \AddtoExerciseGoal 42 | \AddtoExerciseTypeGoalPrint, \AddtoExerciseGoalPrint, 43 | \ExerciseGoalValuePrint 44 | - \addpoints, \addbonus, \points, \printgoal 45 | v0.5 2017/03/30 - add style file mechanism 46 | - make solution print conditions `section' and `chapter' 47 | combinable 48 | v0.5a 2017/04/15 - fix wrong translation of the `default-heading' 49 | v0.5b 2017/04/16 - add \SetExerciseProperty 50 | v0.6 2017/04/27 - official interface for grade distributions 51 | - refine hook management (environment module) 52 | v0.6a 2017/04/28 - refine \blank command, add documentation for said command 53 | v0.7 2017/05/09 - \xsim_list_length:n 54 | - new boolean property `used' 55 | - when an exercise is collected the counter isn't stepped 56 | but only when the exercise is inserted for the first 57 | time; when this happens the new property `used' is set to 58 | `true' 59 | - make setting boolean properties case insensitive 60 | - add missing pieces to manual (eg `page' property...) 61 | - \TotalExerciseGoals and \TotalExerciseTypeGoals 62 | - \XSIMifchapterTF 63 | - \xsim_if_goal_sum:nnnTF and friends, 64 | \IfExerciseTypeGoalsSumTF and \IfExerciseGoalsSumTF 65 | - some more hints in the manual regarding collections 66 | v0.8 2017/05/18 - bug fix in \xsim_set_property:nnnn 67 | - random exercise lists from collections 68 | - \xsim_collection_count:n 69 | - \GetExerciseIdForProperty and \GetExerciseTypeForProperty 70 | for unique properties 71 | - set property `print=false' during collection and only to 72 | true when the corresponding exercises actually are 73 | printed 74 | - do not insert \par at the beginning and end of exercises 75 | and solutions; this should be left to the templates! 76 | - new option `print-collection/print' which allows to 77 | choose between exercises, solutions, and both to be 78 | printed 79 | - new parameter `solution-counter' in order to avoid 80 | possible conflicts with existing counters 81 | v0.8a 2017/05/19 - \IfPrintSolutionTF 82 | v0.8b 2017/05/23 - use \printgoal in default environment template 83 | - \xsim_print_goal:nnn now expands input to a number 84 | v0.9 2017/06/20 - \xsimstyle's behaviour now matches the description in 85 | the manual 86 | - add style file `layouts' which at the moment provides the 87 | two exercise templates `runin' and `margin' 88 | - \printforexercises , \xsim_print_type_code:nnnnn 89 | - \IfExerciseParameterSetTF 90 | - \GetExerciseParameterTF 91 | - change syntax of \SetExerciseProperty 92 | - \SetExpandedExerciseProperty 93 | - \ExerciseSetProperty, \ExerciseSetExpandedProperty 94 | - property `sectioning' 95 | - \IfExistSolutionTF 96 | v0.10 2017/09/19 - \xsim_input:nnn 97 | - \GetExerciseBody 98 | - option `blank/fill' 99 | - bug fix in \xsim_start_collection:nn 100 | - added further examples to package 101 | - new option `file-extension' 102 | v0.10a 2017/10/01 - bug fix: grading table options can now be set with 103 | \xsimsetup (issue 15) 104 | v0.11 2018/02/12 - change name requirement for style files in order to 105 | prevent possible name clashes with module files 106 | - fix bug in \SetExerciseProperty and 107 | \SetExpandedExerciseProperty 108 | - fix bug when xsimverb is used standalone (issue 21) 109 | - add option `split-aux-lists' (issue 18) 110 | - \IfExerciseTagSetTF and \IfExerciseTopicSetTF 111 | - introduce a \xsim_if__value:nTF for each tag 112 | kind 113 | - \ProvideExerciseTagging 114 | v0.12 2019/09/30 - add parameter versions for the plural forms of exercise 115 | and solution names 116 | - bug fixes (issues 37, 39, 43, 47) 117 | v0.13 2019/10/06 - experimental package option `no-files' 118 | v0.14 2019/10/13 - new exercise parameters `exercise-heading' and 119 | `solution-heading' 120 | - new options `exercise/heading' and `solution/heading' as 121 | interface for setting the new parameters 122 | - new command \GetExerciseHeadingF for using the new 123 | parameters in environment templates 124 | - change the environment template `default' to use the new 125 | \GetExerciseHeadingF and output a \par at the end 126 | - make argument of \xsimsetup long 127 | - new template `minimal' 128 | - new option `load-style' 129 | - new example `texwelt-23968' (long and short solutions) 130 | v0.14a 2019/10/19 - fix \xsim_if_exercise_exist:nnTF to obey the `no-files' 131 | option 132 | v0.15 2019/11/02 - use own auxiliary file per default and add option 133 | `use-aux' 134 | v0.16 2019/11/10 - fix issue due to usage of own auxiliary file 135 | - \XSIMatbegindocument and \XSIMatenddocument 136 | - \xprintexercise, \xprintsolution, \xsimprint, \xsimxprint 137 | 2019/12/29 - bugfix in `xsimverb' 138 | v0.16a 2020/01/16 - adapt to renaming of string case changing functions 139 | v0.17 2020/02/21 - prefer lazy boolean evaluation if possible 140 | - remove spurious \par at the beginning of typeset 141 | exercises 142 | - add `blank' option, implements issue #31 143 | - add `solution' property, implements issue #33 144 | - fix issue #27 145 | - implement issue #2 146 | - don't allow package options to be set with \xsimsetup 147 | v0.18 2020/02/23 - fix issue #56 148 | - change \printexercise and \printsolution to accept a 149 | clist of either ids or IDs (or mixed) 150 | - new templates in the `layouts' style 151 | v0.19 2020/03/16 - improve performance 152 | - only set \ExerciseID and \ExerciseType locally to ensure 153 | correct values when exercises (of different types) are 154 | nested 155 | - new load-time option `debug' - only for development 156 | v0.19a 2020/03/19 - fix missing-variant-bug introduced with the last update 157 | v0.19b 2020/04/04 - fix bug in new attribute mechanism which was a problem 158 | when `no-files` has been used 159 | v0.20 2021/01/31 - switch to one sty file per package 160 | - use LaTeX's new hooks 161 | - declare undeclared variables 162 | - new exercise setup mechanism which clearly determines the 163 | difference between definition, usage, and printing of an 164 | exercise; this also solves the problem with added goals 165 | in the exercise body in a collection 166 | - re-write collection mechanism: 167 | * changes the behaviour of \collectexercises but doesn't 168 | require external files any more and more importantly 169 | doesn't require inputting files several times for 170 | multiple collections 171 | * drop \collectexercisestype 172 | * new \(de)activatecollection 173 | * new options `collect' and `/collect' 174 | - small improvements in performance 175 | - new parameters `within' and `the-counter' 176 | - make `no-files' the default 177 | - new examples 178 | - various small fixes 179 | v0.20a 2021/02/01 - re-add missing `layouts' style 180 | - add example texsx-549540 181 | v0.20b 2021/02/02 - fix issue #78 182 | v0.20c 2021/02/03 - fix issue #80 183 | - add missing test in \xsim_if_exist:nnnTF 184 | v0.21 2022/02/12 - make \__xsim_set_file_signature:nnn public 185 | - make \l__xsim_file_path_and_name_tl, \l__xsim_file_name_tl 186 | and \l__xsim_file_path_tl public 187 | - introduce \XSIMsetfilebeginX and \XSIMsetfileendX (xsimverb) 188 | - reduce comment line in automated comments in exercise and 189 | solution files 190 | - add option /use-unmatched 191 | - document option `blank/fill' 192 | - add counter foreach type and collection that holds the 193 | number of exercises of a type in a collection 194 | - fix issue #90 195 | - correct file hooks 196 | - implement issue #88 197 | - fix issue #96 198 | - `use!' and `print!' had gone lost. Add them back in. 199 | - add new options `match-all'/`match-any' for the collection 200 | conditions. Resolves issue #94. 201 | - new \ForEachUsedExerciseByOrder, used in the table 202 | templates which resolves issue #85 203 | v0.?? 2022/??/?? - add warning if an exercise tries to set a non-existing 204 | property 205 | - new \ForEachPrintedExerciseByOrder 206 | - fix bug in \ForEachPrintedExerciseByID 207 | -------------------------------------------------------------------------------- /IDEAS: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------- 2 | 3 | XSIM -- eXercise Sheets IMproved 4 | 5 | -------------------------------------------------------------------------- 6 | Clemens Niederberger 7 | Web: https://github.com/cgnieder/xsim 8 | E-Mail: contact@mychemistry.eu 9 | -------------------------------------------------------------------------- 10 | Copyright 2017--2022 Clemens Niederberger 11 | 12 | This work may be distributed and/or modified under the 13 | conditions of the LaTeX Project Public License, either version 1.3 14 | of this license or (at your option) any later version. 15 | The latest version of this license is in 16 | http://www.latex-project.org/lppl.txt 17 | and version 1.3 or later is part of all distributions of LaTeX 18 | version 2005/12/01 or later. 19 | 20 | This work has the LPPL maintenance status `maintained'. 21 | 22 | The Current Maintainer of this work is Clemens Niederberger. 23 | -------------------------------------------------------------------------- 24 | 25 | IDEAS: 26 | 27 | - a document class `xsim-exam' for creating exams 28 | - a mechanism for providing variants of an exam 29 | 30 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------- 2 | XSIM 2022/02/12 v0.21a 3 | XSIMVERB 2022/02/12 v0.4 4 | 5 | eXercise Sheets IMproved 6 | 7 | -------------------------------------------------------------------------- 8 | Clemens Niederberger 9 | Web: https://github.com/cgnieder/xsim 10 | E-Mail: clemens@cnltx.de 11 | -------------------------------------------------------------------------- 12 | Copyright 2017--2022 Clemens Niederberger 13 | 14 | This work may be distributed and/or modified under the 15 | conditions of the LaTeX Project Public License, either version 1.3c 16 | of this license or (at your option) any later version. 17 | The latest version of this license is in 18 | http://www.latex-project.org/lppl.txt 19 | and version 1.3c or later is part of all distributions of LaTeX 20 | version 2008/05/04 or later. 21 | 22 | This work has the LPPL maintenance status `maintained'. 23 | 24 | The Current Maintainer of this work is Clemens Niederberger. 25 | -------------------------------------------------------------------------- 26 | The xsim package consists of the code files: 27 | xsim.sty 28 | xsimverb.sty 29 | xsim.style.layouts.code.tex 30 | -------------------------------------------------------------------------- 31 | The xsim package consists of the documentation files: 32 | README, HISTORY 33 | xsim-manual.tex, xsim-manual.pdf 34 | xsim-manual.cls 35 | -------------------------------------------------------------------------- 36 | The xsim package consists of the example files: 37 | xsim.blanks.tex, xsim.blanks.pdf 38 | xsim.boxed-headings.tex, xsim.boxed-headings.pdf 39 | xsim.code-and-output.tex, xsim.code-and-output.pdf 40 | xsim.collections.tex, xsim.collections.pdf 41 | xsim.crossref.tex, xsim.crossref.pdf 42 | xsim.description-list.tex, xsim.description-list.pdf 43 | xsim.different-point-types.tex, xsim.different-point-types.pdf 44 | xsim.difficulties.tex, xsim.difficulties.pdf 45 | xsim.floating.tex, xsim.floating.pdf 46 | xsim.grade-distribution.tex, xsim.grade-distribution.pdf 47 | xsim.hints.tex, xsim.hints.pdf 48 | xsim.listings.tex, xsim.listings.pdf 49 | xsim.listofexercises.tex, xsim.listofexercises.pdf 50 | xsim.multiplechoice.tex, xsim.multiplechoice.pdf 51 | xsim.pointsums.tex, xsim.pointsums.pdf 52 | xsim.randomexercises.tex, xsim.randomexercises.pdf 53 | xsim.various.tex, xsim.various.pdf 54 | xsim.texsx-13635.tex, xsim.texsx-13635.pdf 55 | xsim.texsx-155630.tex, xsim.texsx-155630.pdf 56 | xsim.texsx-199360.tex, xsim.texsx-199360.pdf 57 | xsim.texsx-299534.tex, xsim.texsx-299534.pdf 58 | xsim.texsx-305110.tex, xsim.texsx-305110.pdf 59 | xsim.texsx-308883.tex, xsim.texsx-308883.pdf 60 | xsim.texsx-338165.tex, xsim.texsx-338165.pdf 61 | xsim.texsx-350028.tex, xsim.texsx-350028.pdf 62 | xsim.texsx-369065.tex, xsim.texsx-369065.pdf 63 | xsim.texsx-369803.tex, xsim.texsx-369803.pdf 64 | xsim.texsx-369686.tex, xsim.texsx-369686.pdf 65 | xsim.texsx-370642.tex, xsim.texsx-370642.pdf 66 | xsim.texsx-391530.tex, xsim.texsx-391530.pdf 67 | xsim.texsx-395273.tex, xsim.texsx-395273.pdf 68 | xsim.texsx-466584.tex, xsim.texsx-466584.pdf 69 | xsim.texsx-498299.tex, xsim.texsx-498299.pdf 70 | xsim.texsx-549540.tex, xsim.texsx-549540.pdf 71 | xsim.texsx-576998.tex, xsim.texsx-576998.pdf 72 | xsim.texsx-580636.tex, xsim.texsx-580636.pdf 73 | xsim.texwelt-6698.tex, xsim.texwelt-6698.pdf 74 | xsim.texwelt-15093.tex, xsim.texwelt-15093.pdf 75 | xsim.texwelt-23968.tex, xsim.texwelt-23968.pdf 76 | xsim.golatex-80640.tex, xsim.golatex-80640.pdf 77 | xsim.golatex-91339.tex, xsim.golatex-91339.pdf 78 | xsim.issues-49.tex, xsim.issues-49.pdf 79 | -------------------------------------------------------------------------- 80 | If you have any ideas, questions, suggestions or bugs to report, please 81 | feel free to contact me. 82 | -------------------------------------------------------------------------- 83 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | - reimplement headings options for \printcollection and \printrandomexercises ? 2 | 3 | -------------------------------------------------------------------------------- /code/xsim.auxfile.code.tex: -------------------------------------------------------------------------------- 1 | \XSIMmodule{auxfile}{writing stuff to an auxiliary file} 2 | 3 | \prg_new_conditional:Npnn \xsim_if_use_aux: {p,T,F,TF} 4 | { 5 | \bool_if:NTF \g_xsim_use_aux_bool 6 | { \prg_return_true: } 7 | { \prg_return_false: } 8 | } 9 | 10 | \cs_new_protected:Npn \xsim_write_to_aux:n #1 11 | { 12 | \legacy_if:nT {@filesw} 13 | { 14 | \xsim_if_use_aux:TF 15 | { \iow_now:Nn \@auxout {#1} } 16 | { \iow_now:Nn \l__xsim_aux_file_iow {#1} } 17 | } 18 | } 19 | \cs_generate_variant:Nn \xsim_write_to_aux:n {x} 20 | 21 | % -------------------------------------------------------------------------- 22 | 23 | \cs_new_protected:Npn \XSIM #1 { \use:c {XSIMaux#1} } 24 | 25 | \cs_new_protected:Npn \xsim_new_aux_property:cpn #1 26 | { \cs_new_protected:cpn {XSIMaux#1} } 27 | 28 | \cs_new_protected:Npn \xsim_add_property_to_aux:nn #1#2 29 | { 30 | \xsim_verbose:n { Writing~ command~ \XSIM {#1}~ to~ aux~ file } 31 | \xsim_write_to_aux:x { \token_to_str:N \XSIM {#1} #2 } 32 | } 33 | 34 | \xsim_at_begin_document:n 35 | { 36 | \iow_now:Nx \@auxout 37 | { \token_to_str:N \providecommand \token_to_str:N \XSIM [1] {} } 38 | } 39 | 40 | % ---------------------------------------------------------------------------- 41 | 42 | \xsim_if_use_aux:F 43 | { 44 | \iow_new:N \l__xsim_aux_file_iow 45 | \tl_new:N \l__xsim_mdfive_hash_tl 46 | \tl_const:Nx \c_xsim_auxfile_tl { \c_sys_jobname_str .xsim } 47 | \hook_gput_code:nnn {begindocument} {xsim} 48 | { 49 | \file_get_mdfive_hash:VN 50 | \c_xsim_auxfile_tl 51 | \l__xsim_mdfive_hash_tl 52 | \iow_open:NV \l__xsim_aux_file_iow \c_xsim_auxfile_tl 53 | } 54 | } 55 | 56 | \cs_new_protected:Npn \xsim_close_aux: 57 | { 58 | \xsim_if_use_aux:F 59 | { 60 | \iow_close:N \l__xsim_aux_file_iow 61 | \file_get_mdfive_hash:VN 62 | \c_xsim_auxfile_tl 63 | \l__xsim_tmpa_tl 64 | \tl_if_eq:NNF \l__xsim_mdfive_hash_tl \l__xsim_tmpa_tl { \xsim_rerun: } 65 | \legacy_if:nT {@filesw} 66 | { \iow_now:Nx \@auxout { \token_to_str:N \XSIM {readaux} } } 67 | } 68 | } 69 | 70 | \xsim_new_aux_property:cpn {readaux} 71 | { 72 | \file_if_exist:VT \c_xsim_auxfile_tl 73 | { \file_input:V \c_xsim_auxfile_tl } 74 | } 75 | 76 | % ---------------------------------------------------------------------------- 77 | % list for recording values that need to be written to the aux file and 78 | % updated at begin document 79 | 80 | \str_new:N \l__xsim_split_aux_lists_str 81 | \keys_define:nn {xsim} 82 | { 83 | split-aux-lists .code:n = \str_set:Nn \l__xsim_split_aux_lists_str {#1} , 84 | split-aux-lists .initial:n = || 85 | } 86 | 87 | % define list: 88 | % #1: name 89 | \cs_new_protected:Npn \xsim_new_list:n #1 90 | { 91 | \xsim_verbose:n { Defining~ new~ auxfile~ list~ `#1'. } 92 | \seq_new:c {g__xsim_list_#1_seq} 93 | \seq_new:c {g__xsim_list_recorded_#1_seq} 94 | \xsim_new_aux_property:cpn {#1} ##1 95 | { 96 | \tl_if_blank:nF {##1} 97 | { 98 | \seq_gset_split:cVx {g__xsim_list_#1_seq} 99 | \l__xsim_split_aux_lists_str 100 | { \tl_to_str:n {##1} } 101 | \seq_map_inline:cn {g__xsim_list_#1_seq} 102 | { \xsim_attribute_set:nnn {#1} {####1} {} } 103 | } 104 | } 105 | \xsim_at_begin_document:n { \xsim_set_list:n {#1} } 106 | } 107 | 108 | % #1: name 109 | \cs_new_protected:Npn \xsim_set_list:n #1 110 | { 111 | \seq_gclear:c {g__xsim_list_recorded_#1_seq} 112 | \seq_set_eq:Nc \l__xsim_tmpa_seq {g__xsim_list_#1_seq} 113 | \seq_map_inline:Nn \l__xsim_tmpa_seq 114 | { 115 | \str_set:Nn \l__xsim_tmpa_str {##1} 116 | \seq_gput_right:cV {g__xsim_list_recorded_#1_seq} \l__xsim_tmpa_str 117 | } 118 | \seq_gremove_duplicates:c {g__xsim_list_recorded_#1_seq} 119 | } 120 | 121 | % add to or remove from list: 122 | % #1: name 123 | % #2: entry 124 | \cs_new_protected:Npn \xsim_add_to_list:nn #1#2 125 | { 126 | \xsim_verbose:n { Adding~ `#2'~ to~ list~ `#1'. } 127 | \str_set:Nn \l__xsim_tmpa_str {#2} 128 | \xsim_attribute_set:nnn {#1} {#2} {} 129 | \seq_if_in:cVT {g__xsim_list_#1_seq} \l__xsim_tmpa_str 130 | { \seq_gremove_all:cV {g__xsim_list_#1_seq} \l__xsim_tmpa_str } 131 | \seq_gput_right:cV {g__xsim_list_#1_seq} \l__xsim_tmpa_str 132 | } 133 | \cs_generate_variant:Nn \xsim_add_to_list:nn {nx,nV} 134 | 135 | % #1: name 136 | % #2: entry 137 | \cs_new_protected:Npn \xsim_remove_from_list:nn #1#2 138 | { 139 | \xsim_verbose:n { Removing~ `#2'~ to~ list~ `#1'. } 140 | \str_set:Nn \l__xsim_tmpa_str {#2} 141 | \xsim_attribute_if_set:nnT {#1} {#2} 142 | { \xsim_attribute_unset:nn {#1} {#2} } 143 | \seq_if_in:cVT {g__xsim_list_#1_seq} \l__xsim_tmpa_str 144 | { \seq_gremove_all:cV {g__xsim_list_#1_seq} \l__xsim_tmpa_str } 145 | \seq_if_in:cVT {g__xsim_list_recorded#1_seq} \l__xsim_tmpa_str 146 | { \seq_gremove_all:cV {g__xsim_list_recorded_#1_seq} \l__xsim_tmpa_str } 147 | } 148 | \cs_generate_variant:Nn \xsim_remove_from_list:nn {nx} 149 | 150 | % check if in list: 151 | % #1: name 152 | % #2: entry 153 | \prg_new_conditional:Npnn \xsim_if_in_list:nn #1#2 {p,T,F,TF} 154 | { 155 | \xsim_attribute_if_set:nnTF {#1} {#2} 156 | { \prg_return_true: } 157 | { \prg_return_false: } 158 | } 159 | \prg_generate_conditional_variant:Nnn \xsim_if_in_list:nn {nx} {T,TF} 160 | 161 | \bool_new:N \l__xsim_empty_lists_bool 162 | \cs_new_protected:Npn \xsim_empty_lists: 163 | { \bool_set_true:N \l__xsim_empty_lists_bool } 164 | 165 | % update list (should be used inside \xsim_at_end_document:n): 166 | % #1: name 167 | \cs_new_protected:Npn \xsim_update_list:n #1 168 | { 169 | \xsim_verbose:n { Updating~ list~ `#1'. } 170 | \seq_gremove_duplicates:c {g__xsim_list_#1_seq} 171 | \seq_gremove_duplicates:c {g__xsim_list_recorded_#1_seq} 172 | \str_set:Nx \l__xsim_tmpa_str 173 | { \seq_use:cn {g__xsim_list_#1_seq} {} } 174 | \str_set:Nx \l__xsim_tmpb_str 175 | { \seq_use:cn {g__xsim_list_recorded_#1_seq} {} } 176 | \str_if_eq:NNF \l__xsim_tmpa_str \l__xsim_tmpb_str 177 | { \xsim_rerun: } 178 | \bool_if:NF \l__xsim_empty_lists_bool 179 | { 180 | \xsim_add_property_to_aux:nn {#1} 181 | { { \seq_use:cV {g__xsim_list_#1_seq} \l__xsim_split_aux_lists_str } } 182 | } 183 | } 184 | 185 | % loop over list: 186 | % #1: name 187 | % #2: code 188 | \cs_new_protected:Npn \xsim_foreach_list_entry:nn #1#2 189 | { \seq_map_inline:cn {g__xsim_list_recorded_#1_seq} {#2} } 190 | 191 | \cs_new_protected:Npn \xsim_foreach_new_list_entry:nn #1#2 192 | { \seq_map_inline:cn {g__xsim_list_#1_seq} {#2} } 193 | 194 | % length of a list: 195 | % #1: name 196 | \cs_new:Npn \xsim_list_count:n #1 197 | { \seq_count:c {g__xsim_list_recorded_#1_seq} } 198 | 199 | % item of a list: 200 | % #1: name 201 | % #2: integer 202 | \cs_new:Npn \xsim_list_item:nn #1#2 203 | { \seq_item:cn {g__xsim_list_recorded_#1_seq} {#2} } 204 | 205 | \XSIMmoduleend 206 | -------------------------------------------------------------------------------- /code/xsim.base.code.tex: -------------------------------------------------------------------------------- 1 | \XSIMmodule{base}{basic functionality of the package} 2 | 3 | % \tl_new:N \g_xsim_end_document_hook_tl 4 | % \tl_new:N \g_xsim_begin_document_hook_tl 5 | 6 | % \hook_gput_code:nnn {begindocument} {xsim} 7 | % { \tl_use:N \g_xsim_begin_document_hook_tl } 8 | % \hook_gput_code:nnn {enddocument} {xsim} 9 | % { \tl_use:N \g_xsim_end_document_hook_tl } 10 | 11 | % \cs_new_protected:Npn \xsim_at_begin_document:n #1 12 | % { \tl_gput_right:Nn \g_xsim_begin_document_hook_tl {#1} } 13 | 14 | % \cs_new_protected:Npn \xsim_at_end_document:n #1 15 | % { \tl_gput_right:Nn \g_xsim_end_document_hook_tl {#1} } 16 | 17 | \cs_new_protected:Npn \xsim_at_begin_document:n #1 18 | { \hook_gput_code:nnn {begindocument} {xsim} {#1} } 19 | 20 | \cs_new_protected:Npn \xsim_before_begin_document:n #1 21 | { \hook_gput_code:nnn {begindocument/before} {xsim} {#1} } 22 | 23 | \cs_new_protected:Npn \xsim_at_end_document:n #1 24 | { \hook_gput_code:nnn {enddocument} {xsim} {#1} } 25 | 26 | \cs_new_protected:Npn \xsim_before_end_document:n #1 27 | { \hook_gput_code:nnn {enddocument/before} {xsim} {#1} } 28 | 29 | % ---------------------------------------------------------------------------- 30 | 31 | % variants of kernel functions: 32 | \cs_generate_variant:Nn \seq_set_split:Nnn {Nnx,NV} 33 | \cs_generate_variant:Nn \seq_gset_split:Nnn {c,cVx,cnx} 34 | \cs_generate_variant:Nn \seq_use:Nn {cV} 35 | \cs_generate_variant:Nn \seq_count:N {c} 36 | \cs_generate_variant:Nn \seq_if_empty:NT {c} 37 | \cs_generate_variant:Nn \seq_if_in:NnT {cV} 38 | \cs_generate_variant:Nn \seq_gremove_all:Nn {cV} 39 | \cs_generate_variant:Nn \seq_gput_right:Nn {cV} 40 | \cs_generate_variant:Nn \seq_set_from_clist:Nn {c,Nx} 41 | \cs_generate_variant:Nn \prop_put:Nnn {Nnx,cxx} 42 | \cs_generate_variant:Nn \prop_gput:Nnn {Nx,Nnx,cxx} 43 | \cs_generate_variant:Nn \prop_item:Nn {c} 44 | \cs_generate_variant:Nn \prop_if_in:NnTF {Nx} 45 | \cs_generate_variant:Nn \use:nn {nx} 46 | \cs_generate_variant:Nn \file_input:n {V,x} 47 | \cs_generate_variant:Nn \file_if_exist:nT {V,x} 48 | \cs_generate_variant:Nn \file_if_exist:nTF {V} 49 | \cs_generate_variant:Nn \file_get_mdfive_hash:nN {V} 50 | \cs_generate_variant:Nn \msg_error:nnnnn {nnnxx} 51 | \cs_generate_variant:Nn \msg_warning:nnn {nnV} 52 | \cs_generate_variant:Nn \keys_define:nn {nx} 53 | \cs_generate_variant:Nn \keys_set:nn {xn,nx} 54 | \cs_generate_variant:Nn \text_titlecase:n {e} 55 | \cs_generate_variant:Nn \tl_if_eq:nnTF {ee,ff,V} 56 | \cs_generate_variant:Nn \tl_if_eq:nnT {x} 57 | \cs_generate_variant:Nn \tl_if_blank:nTF {f,e} 58 | \cs_generate_variant:Nn \tl_set_rescan:Nnn {Nnx} 59 | \cs_generate_variant:Nn \iow_now:Nn {NV} 60 | \cs_generate_variant:Nn \iow_open:Nn {NV} 61 | \cs_generate_variant:Nn \str_if_eq:nnT {x} 62 | \cs_generate_variant:Nn \str_if_eq:nnF {xx} 63 | \cs_generate_variant:Nn \str_if_eq_p:nn {e} 64 | \cs_generate_variant:Nn \prg_new_protected_conditional:Npnn {c} 65 | \cs_generate_variant:Nn \clist_map_inline:nn {V} 66 | 67 | % ---------------------------------------------------------------------------- 68 | % temporary variables: 69 | \tl_new:N \l__xsim_tmpa_tl 70 | \tl_new:N \l__xsim_tmpb_tl 71 | \tl_new:N \l__xsim_tmpc_tl 72 | \tl_new:N \l__xsim_tmpd_tl 73 | 74 | \str_new:N \l__xsim_tmpa_str 75 | \str_new:N \l__xsim_tmpb_str 76 | \str_new:N \l__xsim_tmpc_str 77 | 78 | \bool_new:N \l__xsim_tmpa_bool 79 | \bool_new:N \l__xsim_tmpb_bool 80 | \bool_new:N \l__xsim_tmpc_bool 81 | 82 | \dim_new:N \l__xsim_tmpa_dim 83 | \dim_new:N \l__xsim_tmpb_dim 84 | \dim_new:N \l__xsim_tmpc_dim 85 | 86 | \seq_new:N \l__xsim_tmpa_seq 87 | \seq_new:N \l__xsim_tmpb_seq 88 | \seq_new:N \l__xsim_tmpc_seq 89 | 90 | \int_new:N \l__xsim_tmpa_int 91 | \int_new:N \l__xsim_tmpb_int 92 | \int_new:N \l__xsim_tmpc_int 93 | 94 | \fp_new:N \l__xsim_tmpa_fp 95 | \fp_new:N \l__xsim_tmpb_fp 96 | \fp_new:N \l__xsim_tmpc_fp 97 | 98 | \box_new:N \l__xsim_tmpa_box 99 | \box_new:N \l__xsim_tmpb_box 100 | \box_new:N \l__xsim_tmpc_box 101 | 102 | \clist_new:N \l__xsim_tmpa_clist 103 | \clist_new:N \l__xsim_tmpb_clist 104 | \clist_new:N \l__xsim_tmpc_clist 105 | 106 | % ---------------------------------------------------------------------------- 107 | 108 | \prg_new_conditional:Npnn \xsim_if_komascript: {T,F,TF} 109 | { 110 | \cs_if_exist:cTF {KOMAClassName} 111 | { \prg_return_true: } 112 | { \prg_return_false: } 113 | } 114 | 115 | % ---------------------------------------------------------------------------- 116 | 117 | \cs_if_exist:NF \xsim_if_final:T 118 | { 119 | \prg_new_conditional:Npnn \xsim_if_final: {p,T,F,TF} 120 | { 121 | \bool_if:NTF \g__xsim_final_bool 122 | { \prg_return_true: } 123 | { \prg_return_false: } 124 | } 125 | 126 | \prg_new_conditional:Npnn \xsim_if_verbose: {p,T,F,TF} 127 | { 128 | \bool_if:NTF \g__xsim_verbose_bool 129 | { \prg_return_true: } 130 | { \prg_return_false: } 131 | } 132 | } 133 | 134 | \prg_new_conditional:Npnn \xsim_if_debug: {p,T,F,TF} 135 | { 136 | \bool_if:NTF \g__xsim_debug_bool 137 | { \prg_return_true: } 138 | { \prg_return_false: } 139 | } 140 | 141 | \prg_new_conditional:Npnn \xsim_if_package_blank: {p,T,F,TF} 142 | { 143 | \bool_if:NTF \g__xsim_blank_bool 144 | { \prg_return_true: } 145 | { \prg_return_false: } 146 | } 147 | 148 | \prg_new_conditional:Npnn \xsim_if_rerun: {p,T,F,TF} 149 | { 150 | \bool_if:NTF \g__xsim_rerun_bool 151 | { \prg_return_true: } 152 | { \prg_return_false: } 153 | } 154 | 155 | \prg_new_conditional:Npnn \xsim_if_write_to_files: {p,T,F,TF} 156 | { 157 | \bool_if:NTF \g__xsim_write_to_file_bool 158 | { \prg_return_true: } 159 | { \prg_return_false: } 160 | } 161 | 162 | \prg_new_conditional:Npnn \xsim_if_clear_aux: {p,T,F,TF} 163 | { 164 | \xsim_if_final:TF 165 | { \prg_return_false: } 166 | { 167 | \bool_if:NTF \g_xsim_clear_aux_bool 168 | { \prg_return_true: } 169 | { \prg_return_false: } 170 | } 171 | } 172 | 173 | \cs_if_exist:NF \xsim_verbose:n 174 | { 175 | \cs_new_protected:Npn \xsim_verbose:n #1 176 | { \xsim_if_verbose:T { \msg_info:nnn {xsim} {verbose} {#1} } } 177 | \cs_generate_variant:Nn \xsim_verbose:n {x} 178 | } 179 | 180 | \cs_new_protected:Npn \xsim_rerun: 181 | { \bool_gset_true:N \g__xsim_rerun_bool } 182 | 183 | \prg_new_conditional:Npnn \xsim_if_chapter: {p,T,F,TF} 184 | { 185 | \bool_lazy_and:nnTF 186 | { \cs_if_exist_p:N \chapter } 187 | { \cs_if_exist_p:N \c@chapter } 188 | { \prg_return_true: } 189 | { \prg_return_false: } 190 | } 191 | 192 | % ---------------------------------------------------------------------------- 193 | 194 | \msg_new:nnn {xsim} {attribute-not-set} 195 | { The~ attribute~ `#1'~ is~ not~ set~ \msg_line_context: } 196 | 197 | % #1: attribute 198 | % #2: item 199 | \cs_new_protected:Npn \xsim_attribute_new:nn #1#2 200 | { \cs_new:cpn {____xsim_attribute_ \tl_to_str:n {#1::#2} :} {} } 201 | 202 | % #1: attribute 203 | % #2: item 204 | % #3: value 205 | \cs_new_protected:Npn \xsim_attribute_set:nnn #1#2#3 206 | { 207 | \cs_gset:cpx 208 | {____xsim_attribute_ \tl_to_str:n {#1::#2} :} 209 | { \exp_not:n { \exp_not:n {#3} } } 210 | } 211 | \cs_generate_variant:Nn \xsim_attribute_set:nnn {nnx} 212 | 213 | % #1: attribute 214 | % #2: item 215 | \cs_new_protected:Npn \xsim_attribute_unset:nn #1#2 216 | { \cs_undefine:c {____xsim_attribute_ \tl_to_str:n {#1::#2} :} } 217 | 218 | % #1: attribute 219 | % #2: item 220 | \cs_new:Npn \xsim_attribute_get:nn #1#2 221 | { 222 | \cs_if_exist:cTF {____xsim_attribute_ \tl_to_str:n {#1::#2} :} 223 | { \use:c {____xsim_attribute_ \tl_to_str:n {#1::#2} :} } 224 | { 225 | \xsim_if_debug:T 226 | { \msg_expandable_error:nnn {xsim} {attribute-not-set} {#1::#2} } 227 | } 228 | } 229 | 230 | % #1: attribute 231 | % #2: item 232 | \prg_new_conditional:Npnn \xsim_attribute_if_set:nn #1#2 {p,T,F,TF} 233 | { 234 | \cs_if_exist:cTF {____xsim_attribute_ \tl_to_str:n {#1::#2} :} 235 | { \prg_return_true: } 236 | { \prg_return_false: } 237 | } 238 | 239 | % #1: attribute 240 | % #2: item 241 | \prg_new_conditional:Npnn \__xsim_if_attribute_eq:nnn #1#2#3 {p,T,F,TF} 242 | { 243 | \tl_if_eq:enTF 244 | { \use:c {____xsim_attribute_ \tl_to_str:n {#1::#2} :} } 245 | {#3} 246 | { \prg_return_true: } 247 | { \prg_return_false: } 248 | } 249 | 250 | % #1: attribute 251 | % #2: item 252 | \cs_new_protected:Npn \xsim_attribute_show:nn #1#2 253 | { 254 | \iow_term:n {} 255 | \iow_term:x 256 | { 257 | \c_space_tl \c_space_tl 258 | \tl_to_str:n {#1::#2} 259 | \c_space_tl \c_space_tl == \c_space_tl \c_space_tl 260 | {\use:c {____xsim_attribute_ \tl_to_str:n {#1::#2} :}} 261 | } 262 | \iow_term:n {} 263 | } 264 | 265 | % ---------------------------------------------------------------------------- 266 | 267 | \cs_new_protected:Npn \xsim_setup:n #1 268 | { \keys_set:nn {xsim} {#1} } 269 | 270 | \XSIMmoduleend 271 | -------------------------------------------------------------------------------- /code/xsim.blanks.code.tex: -------------------------------------------------------------------------------- 1 | \XSIMmodule{blanks}{add blanks, cloze} 2 | 3 | \bool_new:N \l__xsim_blank_width_bool 4 | \bool_new:N \l__xsim_blank_linespread_bool 5 | \bool_new:N \l__xsim_fill_blank_bool 6 | \tl_new:N \l__xsim_blank_linespread_tl 7 | \tl_new:N \l__xsim_blank_scale_tl 8 | \dim_new:N \l__xsim_blank_dim 9 | \dim_new:N \l__xsim_blank_line_increment_dim 10 | \dim_new:N \l__xsim_blank_line_minimum_length_dim 11 | \box_new:N \l__xsim_blank_box 12 | 13 | \cs_new_protected:Npn \xsim_write_cloze_blank:n #1 {#1} 14 | \cs_new_protected:Npn \xsim_write_cloze_filled:n #1 {#1} 15 | 16 | \keys_define:nn {xsim/blank} 17 | { 18 | blank-style .code:n = 19 | \cs_set_protected:Npn \xsim_write_cloze_blank:n ##1 {#1} , 20 | blank-style .initial:n = \underline {#1} , 21 | filled-style .code:n = 22 | \cs_set_protected:Npn \xsim_write_cloze_filled:n ##1 {#1} , 23 | filled-style .initial:n = \underline {#1} , 24 | style .meta:n = 25 | { blank-style = #1 , filled-style = #1 } , 26 | fill .bool_set:N = \l__xsim_fill_blank_bool , 27 | fill .initial:n = false , 28 | scale .tl_set:N = \l__xsim_blank_scale_tl , 29 | scale .initial:n = 1 , 30 | width .code:n = 31 | { 32 | \bool_set_true:N \l__xsim_blank_width_bool 33 | \dim_set:Nn \l__xsim_blank_dim {#1} 34 | } , 35 | linespread .code:n = 36 | \bool_set_true:N \l__xsim_blank_linespread_bool 37 | \tl_set:Nn \l__xsim_blank_linespread_tl {#1} , 38 | linespread .initial:n = 1 , 39 | line-increment .dim_set:N = \l__xsim_blank_line_increment_dim , 40 | line-increment .initial:n = 0.001\linewidth , 41 | line-minimum-length .dim_set:N = \l__xsim_blank_line_minimum_length_dim , 42 | line-minimum-length .initial:n = 2em 43 | } 44 | 45 | \cs_new_protected:Npn \xsim_blank:n #1 46 | { 47 | \box_clear:N \l__xsim_blank_box 48 | \mode_if_math:TF 49 | { \hbox_set:Nn \l__xsim_blank_box { $ \m@th \mathpalette{}{#1} $ } } 50 | { \hbox_set:Nn \l__xsim_blank_box {#1} } 51 | \bool_lazy_or:nnTF 52 | { \xsim_if_inside_solution_p: } 53 | { \l__xsim_fill_blank_bool } 54 | { \xsim_write_cloze_filled:n {#1} } 55 | { 56 | \bool_if:NTF \l__xsim_blank_width_bool 57 | { \__xsim_blank_skip:V \l__xsim_blank_dim } 58 | { \__xsim_blank_skip:n { \box_wd:N \l__xsim_blank_box } } 59 | } 60 | } 61 | 62 | \cs_new_protected:Npn \__xsim_blank_skip:n #1 63 | { 64 | \bool_if:NTF \l__xsim_blank_width_bool 65 | { \dim_set:Nn \l__xsim_tmpa_dim {#1} } 66 | { 67 | \fp_set:Nn \l__xsim_tmpa_fp 68 | { \dim_to_fp:n {#1} * \l__xsim_blank_scale_tl } 69 | \dim_set:Nn \l__xsim_tmpa_dim { \fp_to_dim:N \l__xsim_tmpa_fp } 70 | } 71 | \dim_compare:nTF 72 | { \l__xsim_tmpa_dim > \l__xsim_blank_line_minimum_length_dim } 73 | { 74 | \mode_if_math:TF 75 | { \xsim_write_cloze_blank:n { \skip_horizontal:N \l__xsim_tmpa_dim } } 76 | { 77 | \dim_do_while:nn { \l__xsim_tmpa_dim > \c_zero_dim } 78 | { 79 | % I wonder what the correct l3 way would be -- if there is 80 | % one, yet: 81 | % \tex_hfil:D 82 | \tex_penalty:D \hyphenpenalty 83 | % \tex_hfilneg:D 84 | \dim_compare:nTF 85 | { \l__xsim_tmpa_dim < \l__xsim_blank_line_increment_dim } 86 | { \xsim_write_cloze_blank:n { \skip_horizontal:N \l__xsim_tmpa_dim } } 87 | { 88 | \xsim_write_cloze_blank:n 89 | { \skip_horizontal:N \l__xsim_blank_line_increment_dim } 90 | } 91 | \dim_sub:Nn \l__xsim_tmpa_dim { \l__xsim_blank_line_increment_dim } 92 | } 93 | } 94 | } 95 | { 96 | \xsim_write_cloze_blank:n 97 | { \skip_horizontal:N \l__xsim_blank_line_minimum_length_dim } 98 | } 99 | } 100 | \cs_generate_variant:Nn \__xsim_blank_skip:n {V} 101 | 102 | \XSIMmoduleend 103 | -------------------------------------------------------------------------------- /code/xsim.goals.code.tex: -------------------------------------------------------------------------------- 1 | \XSIMmodule{goals}{counting of points and bonus points} 2 | 3 | \msg_new:nnn {xsim} {goal-unknown} 4 | { The~ goal~ `#1'~ has~ never~ been~ declared~ \msg_line_context: } 5 | 6 | \seq_new:N \l__xsim_goals_seq 7 | \tl_new:N \l_xsim_grading_table_template_tl 8 | \tl_new:N \l_xsim_grading_table_exercise_type_tl 9 | 10 | % #1: name 11 | \cs_new_protected:Npn \xsim_declare_exercise_goal:n #1 12 | { 13 | \xsim_if_goal_exist:nF {#1} 14 | { 15 | \xsim_verbose:n { Declaring~ new~ goal~ `#1'. } 16 | \xsim_declare_property:nnnn 17 | { \c_false_bool } { \c_false_bool } { \c_false_bool } {#1} 18 | \xsim_declare_property:nnnn 19 | { \c_false_bool } { \c_false_bool } { \c_false_bool } {user#1} 20 | \xsim_declare_property:nnnn 21 | { \c_false_bool } { \c_false_bool } { \c_false_bool } {body#1} 22 | \seq_put_right:Nn \l__xsim_goals_seq {#1} 23 | \fp_gzero_new:c {g__xsim_goal_#1_fp} 24 | \fp_new:c {l__xsim_temporary_#1_fp} 25 | \bool_new:c {l__xsim_temporary_#1_bool} 26 | \bool_new:c {l__xsim_goal_#1_given_bool} 27 | \fp_gzero_new:c {l__xsim_current_goal_#1_fp} 28 | \fp_if_exist:cF {g__xsim_total_goal_#1_fp} 29 | { \fp_new:c {g__xsim_total_goal_#1_fp} } 30 | \fp_if_exist:cF {g__xsim_total_goal_recorded_#1_fp} 31 | { \fp_new:c {g__xsim_total_goal_recorded_#1_fp} } 32 | \xsim_before_begin_document:n 33 | { 34 | \xsim_foreach_exercise_type:n 35 | { \xsim_goal_init:nn {##1} {#1} } 36 | } 37 | } 38 | } 39 | 40 | % #1: type 41 | % #2: goal 42 | \cs_new_protected:Npn \xsim_goal_init:nn #1#2 43 | { 44 | \fp_gzero_new:c {g__xsim_#1_goal_#2_fp} 45 | \fp_if_exist:cF {g__xsim_total_#1_goal_#2_fp} 46 | { \fp_new:c {g__xsim_total_#1_goal_#2_fp} } 47 | } 48 | 49 | \prg_new_conditional:Npnn \xsim_if_goal_exist:n #1 {p,T,F,TF} 50 | { 51 | \seq_if_in:NnTF \l__xsim_goals_seq {#1} 52 | { \prg_return_true: } 53 | { \prg_return_false: } 54 | } 55 | 56 | \prg_new_conditional:Npnn \xsim_if_goal_given:n #1 {p,T,F,TF} 57 | { 58 | \bool_if:cTF {l__xsim_goal_#1_given_bool} 59 | { \prg_return_true: } 60 | { \prg_return_false: } 61 | } 62 | 63 | \cs_new_protected:Npn \xsim_goal_given:n #1 64 | { \bool_set_true:c {l__xsim_goal_#1_given_bool} } 65 | 66 | % #1: exercise type 67 | % #2: id 68 | % #3: goal 69 | \cs_new_protected:Npn \xsim_update_goal:nnn #1#2#3 70 | { 71 | \xsim_if_goal_exist:nT {#3} 72 | { 73 | \fp_gadd:cn {g__xsim_goal_#3_fp} 74 | { \xsim_get_property:nnn {#1} {#2} {#3} + 0 } 75 | \fp_gadd:cn {g__xsim_#1_goal_#3_fp} 76 | { \xsim_get_property:nnn {#1} {#2} {#3} + 0 } 77 | } 78 | } 79 | 80 | % #1: exercise type 81 | % #2: id 82 | \cs_new_protected:Npn \xsim_update_goals:nn #1#2 83 | { 84 | \xsim_foreach_goal:n 85 | { \xsim_update_goal:nnn {#1} {#2} {##1} } 86 | } 87 | \cs_generate_variant:Nn \xsim_update_goals:nn {nV} 88 | 89 | \cs_new_protected:Npn \xsim_foreach_goal:n #1 90 | { \seq_map_inline:Nn \l__xsim_goals_seq {#1} } 91 | 92 | 93 | % #1: exercise type 94 | % #2: id 95 | % #3: goal 96 | % #4: value 97 | \cs_new_protected:Npn \xsim_addto_goal:nnnn #1#2#3#4 98 | { 99 | \xsim_if_goal_exist:nT {#3} 100 | { 101 | \xsim_verbose:n { Adding~ `#4'~ to~ `#3'~ goal~ of~ #1~ #2 } 102 | \fp_set:Nn \l__xsim_tmpa_fp 103 | { \xsim_get_property:nnn {#1} {#2} {body#3} + 0 + #4 } 104 | \xsim_set_property:nnne {#1} {#2} {body#3} 105 | { \fp_to_decimal:N \l__xsim_tmpa_fp } 106 | } 107 | } 108 | \cs_generate_variant:Nn \xsim_addto_goal:nnnn {xx,nVnx} 109 | 110 | % #1: exercise type 111 | % #2: id 112 | % #3: goal 113 | % #4: relation and value 114 | \prg_new_conditional:Npnn \xsim_if_goal_value:nnnn #1#2#3#4 {p,T,F,TF} 115 | { 116 | \fp_compare:nTF 117 | { (0 + \xsim_get_property:nnn {#1} {#2} {#3}) #4 } 118 | { \prg_return_true: } 119 | { \prg_return_false: } 120 | } 121 | \cs_generate_variant:Nn \xsim_if_goal_value:nnnnTF {xx} 122 | 123 | % ---------------------------------------------------------------------------- 124 | % a function which can be used to modify how the numbers of a goal are 125 | % printed: 126 | \cs_new_protected:Npn \__xsim_print_goal:n #1 {#1} 127 | \cs_generate_variant:Nn \__xsim_print_goal:n {x} 128 | 129 | % #1: value 130 | % #2: value == 1 131 | % #3: value != 1 132 | \cs_new_protected:Npn \xsim_print_goal:nnn #1#2#3 133 | { 134 | \__xsim_print_goal:x { \fp_to_decimal:n {#1} } 135 | \fp_compare:nTF { (#1) = 1 } {#2} {#3} 136 | } 137 | 138 | % #1: exercise type 139 | % #2: goal 140 | % #3: sum == 1 141 | % #4: sum != 1 142 | \cs_new_protected:Npn \xsim_print_goal_sum:nnnn #1#2#3#4 143 | { \xsim_print_goal:nnn { \use:c {g__xsim_total_#1_goal_#2_fp} } {#3} {#4} } 144 | 145 | % #1: goal 146 | % #2: sum == 1 147 | % #3: sum != 1 148 | \cs_new_protected:Npn \xsim_print_total_goal_sum:nnn #1#2#3 149 | { \xsim_print_goal:nnn { \use:c {g__xsim_total_goal_#1_fp} } {#2} {#3} } 150 | 151 | % ---------------------------------------------------------------------------- 152 | % the same as the last to functions but for a list of goals: 153 | 154 | % #1: fp variable to be set 155 | % #2: list of goals (separated with +) 156 | % #3: function to be applied to goal names 157 | \cs_new_protected:Npn \__xsim_exercise_goals_sum_aux:Nnn #1#2#3 158 | { 159 | \seq_set_split:Nnn \l__xsim_tmpa_seq {+} {#2} 160 | \seq_set_map:NNn \l__xsim_tmpb_seq \l__xsim_tmpa_seq {#3} 161 | \fp_set:Nn #1 { \seq_use:Nn \l__xsim_tmpb_seq {+} } 162 | } 163 | 164 | % #1: fp variable 165 | % #2: exercise type 166 | % #3: list of goals (separated with +) 167 | \cs_new_protected:Npn \__xsim_exercise_goals_sum:Nnn #1#2#3 168 | { 169 | \__xsim_exercise_goals_sum_aux:Nnn #1 {#3} 170 | { \use:c {g__xsim_total_#2_goal_ \tl_trim_spaces:n {##1} _fp} } 171 | } 172 | 173 | % #1: fp variable 174 | % #2: list of goals (separated with +) 175 | \cs_new_protected:Npn \__xsim_exercise_goals_sum:Nn #1#2 176 | { 177 | \__xsim_exercise_goals_sum_aux:Nnn #1 {#2} 178 | { \use:c {g__xsim_total_goal_ \tl_trim_spaces:n {##1} _fp} } 179 | } 180 | 181 | % #1: exercise type 182 | % #2: list of goals (separated with +) 183 | % #3: sum == 1 184 | % #4: sum != 1 185 | \cs_new_protected:Npn \xsim_print_goals_sum:nnnn #1#2#3#4 186 | { 187 | \__xsim_exercise_goals_sum:Nnn \l__xsim_tmpa_fp {#1} {#2} 188 | \xsim_print_goal:nnn { \l__xsim_tmpa_fp } {#3} {#4} 189 | } 190 | 191 | % #1: list of goals (separated with +) 192 | % #2: sum == 1 193 | % #3: sum != 1 194 | \cs_new_protected:Npn \xsim_print_total_goals_sum:nnn #1#2#3 195 | { 196 | \__xsim_exercise_goals_sum:Nn \l__xsim_tmpa_fp {#1} 197 | \xsim_print_goal:nnn { \l__xsim_tmpa_fp } {#2} {#3} 198 | } 199 | 200 | % ---------------------------------------------------------------------------- 201 | % #1: exercise type 202 | % #2: goal 203 | % #3: relation and value 204 | \prg_new_conditional:Npnn \xsim_if_goal_sum:nnn #1#2#3 {p,T,F,TF} 205 | { 206 | \fp_compare:nTF 207 | { ( \use:c {g__xsim_total_#1_goal_#2_fp} ) #3 } 208 | { \prg_return_true: } 209 | { \prg_return_false: } 210 | } 211 | 212 | % #1: exercise type 213 | % #2: list of goals (separated with +) 214 | % #3: relation and value 215 | \prg_new_protected_conditional:Npnn \xsim_if_goals_sum:nnn #1#2#3 {T,F,TF} 216 | { 217 | \__xsim_exercise_goals_sum:Nnn \l__xsim_tmpa_fp {#1} {#2} 218 | \fp_compare:nTF 219 | { ( \l__xsim_tmpa_fp ) #3 } 220 | { \prg_return_true: } 221 | { \prg_return_false: } 222 | } 223 | 224 | % #1: goal 225 | % #2: relation and value 226 | \prg_new_conditional:Npnn \xsim_if_total_goal_sum:nn #1#2 {p,T,F,TF} 227 | { 228 | \fp_compare:nTF 229 | { ( \use:c {g__xsim_total_goal_#1_fp} ) #2 } 230 | { \prg_return_true: } 231 | { \prg_return_false: } 232 | } 233 | 234 | % #1: list of goals (separated with +) 235 | % #2: relation and value 236 | \prg_new_protected_conditional:Npnn \xsim_if_total_goals_sum:nn #1#2 {T,F,TF} 237 | { 238 | \__xsim_exercise_goals_sum:Nn \l__xsim_tmpa_fp {#1} 239 | \fp_compare:nTF 240 | { ( \l__xsim_tmpa_fp ) #2 } 241 | { \prg_return_true: } 242 | { \prg_return_false: } 243 | } 244 | 245 | % ---------------------------------------------------------------------------- 246 | % #1: exercise type 247 | % #2: goal 248 | % #3: value 249 | \xsim_new_aux_property:cpn {goal} #1#2#3 250 | { \fp_gset:cn {g__xsim_total_#1_goal_#2_fp} {#3} } 251 | 252 | % #1: goal 253 | % #2: value 254 | \xsim_new_aux_property:cpn {totalgoal} #1#2 255 | { \fp_gset:cn {g__xsim_total_goal_#1_fp} {#2} } 256 | 257 | \xsim_at_begin_document:n 258 | { \xsim_foreach_goal:n { \xsim_get_total_goal:n {#1} } } 259 | 260 | % #1: goal 261 | \cs_new_protected:Npn \xsim_get_total_goal:n #1 262 | { 263 | \fp_gset_eq:cc 264 | {g__xsim_total_goal_recorded_#1_fp} 265 | {g__xsim_total_goal_#1_fp} 266 | } 267 | 268 | \xsim_at_end_document:n { \xsim_save_goals: } 269 | 270 | \cs_new_protected:Npn \xsim_save_goals: 271 | { 272 | \xsim_foreach_goal:n 273 | { 274 | \xsim_foreach_exercise_type:n 275 | { 276 | \xsim_add_property_to_aux:nn {goal} 277 | { {####1} {##1} { \fp_to_decimal:c {g__xsim_####1_goal_##1_fp} } } 278 | } 279 | \tl_set:Nx \l__xsim_tmpa_tl 280 | { \fp_to_decimal:c {g__xsim_total_goal_##1_fp} } 281 | \tl_set:Nx \l__xsim_tmpb_tl 282 | { \fp_to_decimal:c {g__xsim_total_goal_recorded_##1_fp} } 283 | \tl_if_eq:NNF \l__xsim_tmpa_tl \l__xsim_tmpb_tl { \xsim_rerun: } 284 | \xsim_add_property_to_aux:nn {totalgoal} 285 | { {##1} { \fp_to_decimal:c {g__xsim_goal_##1_fp} } } 286 | } 287 | } 288 | 289 | % ---------------------------------------------------------------------------- 290 | 291 | \keys_define:nn {xsim} 292 | { 293 | goal-print .code:n = 294 | \cs_set_protected:Npn \__xsim_print_goal:n ##1 {#1} , 295 | grading-table/template .tl_set:N = \l_xsim_grading_table_template_tl , 296 | grading-table/template .initial:n = default , 297 | grading-table/type .tl_set:N = \l_xsim_grading_table_exercise_type_tl , 298 | grading-table/type .initial:n = 299 | } 300 | 301 | \XSIMmoduleend 302 | -------------------------------------------------------------------------------- /code/xsim.grades.code.tex: -------------------------------------------------------------------------------- 1 | \XSIMmodule{grades}{distribute goal sums to grades} 2 | 3 | \msg_new:nnn {xsim} {grade-unknown} 4 | { The~ grade~ `#1'~ has~ never~ been~ declared~ \msg_line_context: } 5 | 6 | \bool_new:N \l__xsim_grades_half_bool 7 | \fp_new:N \l__xsim_grade_round_fp 8 | \fp_zero:N \l__xsim_grade_round_fp 9 | \prop_new:N \l__xsim_relative_grades_prop 10 | \tl_new:N \l__xsim_grade_split_tl 11 | 12 | \cs_new:Npn \__xsim_fp_round_to_half:n #1 13 | { round( 2*(#1),0)/2 } 14 | 15 | \cs_new:Npn \__xsim_grades_round:n #1 16 | { round ( #1 , \l__xsim_grade_round_fp ) } 17 | 18 | % #1: factor 19 | % #2: goal sum 20 | \cs_new:Npn \__xsim_grade_rounded:nn #1#2 21 | { 22 | \bool_if:NTF \l__xsim_grades_half_bool 23 | { \__xsim_fp_round_to_half:n } 24 | { \__xsim_grades_round:n } 25 | { (#1) * (#2) } 26 | } 27 | 28 | \cs_new_protected:Npn \xsim_declare_relative_grades:n #1 29 | { 30 | \seq_set_split:NVn \l__xsim_tmpa_seq \l__xsim_grade_split_tl {#1} 31 | \seq_map_inline:Nn \l__xsim_tmpa_seq 32 | { \__xsim_declare_relative_grade:w ##1 \q_stop } 33 | \xsim_verbose:n {Declaring~ relative~ grade~ distribution} 34 | } 35 | 36 | \cs_new_protected:Npn \__xsim_declare_relative_grade:w #1 = #2 \q_stop 37 | { 38 | \tl_set:Nx \l__xsim_tmpa_tl { \tl_trim_spaces:n {#1} } 39 | \tl_set:Nx \l__xsim_tmpb_tl { \tl_trim_spaces:n {#2} } 40 | \prop_put:NVV \l__xsim_relative_grades_prop 41 | \l__xsim_tmpa_tl 42 | \l__xsim_tmpb_tl 43 | } 44 | 45 | % #1: grade 46 | % #2: sum of points 47 | % #3: code after grade requirement if == 1 48 | % #4: code after grade requirement if != 1 49 | \cs_new_protected:Npn \xsim_get_grade:nnnn #1#2#3#4 50 | { 51 | \prop_get:NnNTF \l__xsim_relative_grades_prop {#1} \l__xsim_tmpa_tl 52 | { 53 | \xsim_print_goal:nnn 54 | { 55 | min( 56 | \__xsim_grade_rounded:nn 57 | { \l__xsim_tmpa_tl } 58 | {#2} , 59 | #2 60 | ) 61 | } 62 | {#3} 63 | {#4} 64 | } 65 | { \msg_error:nnn {xsim} {grade-unknown} {#1} } 66 | } 67 | 68 | % #1: grade 69 | % #2: goal 70 | % #3: code after grade requirement if == 1 71 | % #4: code after grade requirement if != 1 72 | \cs_new_protected:Npn \xsim_get_grade_goal:nnnn #1#2#3#4 73 | { 74 | \xsim_if_goal_exist:nTF {#2} 75 | { 76 | \xsim_get_grade:nnnn 77 | {#1} 78 | { \use:c {g__xsim_total_goal_#2_fp} } 79 | {#3} 80 | {#4} 81 | } 82 | { \msg_error:nnn {xsim} {goal-unknown} {#2} } 83 | } 84 | 85 | % #1: grade 86 | % #2: goal list (separated with +) 87 | % #3: code after grade requirement if == 1 88 | % #4: code after grade requirement if != 1 89 | \cs_new_protected:Npn \xsim_get_grade_requirement:nnnn #1#2#3#4 90 | { 91 | \seq_set_split:Nnn \l__xsim_tmpa_seq {+} {#2} 92 | \fp_zero:N \l__xsim_tmpa_fp 93 | \seq_map_inline:Nn \l__xsim_tmpa_seq 94 | { 95 | \fp_add:Nn \l__xsim_tmpa_fp 96 | { \use:c {g__xsim_total_goal_\tl_trim_spaces:n {##1} _fp} } 97 | } 98 | \xsim_get_grade:nnnn {#1} { \l__xsim_tmpa_fp } {#3} {#4} 99 | } 100 | 101 | % #1: grade 102 | % #2: code after grade requirement if == 1 103 | % #3: code after grade requirement if != 1 104 | \cs_new_protected:Npn \xsim_get_absolute_grade_requirement:nnn #1#2#3 105 | { 106 | \fp_zero:N \l__xsim_tmpa_fp 107 | \xsim_foreach_goal:n 108 | { 109 | \fp_add:Nn \l__xsim_tmpa_fp 110 | { \use:c {g__xsim_total_goal_##1_fp} } 111 | } 112 | \xsim_get_grade:nnnn {#1} { \l__xsim_tmpa_fp } {#2} {#3} 113 | } 114 | 115 | \keys_define:nn {xsim/grades} 116 | { 117 | round .fp_set:N = \l__xsim_grade_round_fp , 118 | half .bool_set:N = \l__xsim_grades_half_bool , 119 | split .tl_set:N = \l__xsim_grade_split_tl , 120 | split .initial:n = {,} 121 | } 122 | 123 | \XSIMmoduleend 124 | -------------------------------------------------------------------------------- /code/xsim.random.code.tex: -------------------------------------------------------------------------------- 1 | \XSIMmodule{random}{randomly select exercises from collections} 2 | 3 | \msg_new:nnn {xsim} {random-numbers-unavailable} 4 | { 5 | You~ are~ compiling~ your~ document~ using ~XeLaTeX.~ Please~ be~ aware~ 6 | that~ random~ selection~ of~ exercises~ is~ unavailable~ in~ XeLaTeX.~ If~ 7 | you~ use~ this~ feature~ you~ can~ safely~ ignore~ this~ message. 8 | } 9 | 10 | \sys_if_engine_xetex:T 11 | { \msg_warning:nn {xsim} {random-numbers-unavailable} } 12 | 13 | \tl_new:N \l_xsim_random_collection_tl 14 | \tl_new:N \l__xsim_print_random_choice_tl 15 | \seq_new:N \g__xsim_random_list_seq 16 | \seq_new:N \l__xsim_allowed_exercise_ids_seq 17 | \int_new:N \g__xsim_random_list_id_int 18 | \bool_new:N \l__xsim_sort_random_bool 19 | \clist_new:N \l_xsim_random_exclude_list_clist 20 | 21 | % #1: random list id 22 | % #2: csv list of integers 23 | \xsim_new_aux_property:cpn {random} #1#2 24 | { 25 | \xsim_random_list_if_exist:nF {#1} 26 | { \xsim_new_random_list:n {#1} } 27 | \xsim_set_random_list:nn {#1} {#2} 28 | } 29 | 30 | \cs_new_protected:Npn \xsim_new_random_list:n #1 31 | { 32 | \xsim_verbose:n {Defining~ new~ random~ list~ `#1'} 33 | \seq_new:c {g__xsim_random_#1 _seq} 34 | } 35 | 36 | \cs_new_protected:Npn \xsim_set_random_list:nn #1#2 37 | { \seq_gset_from_clist:cn {g__xsim_random_#1_seq} {#2} } 38 | 39 | \cs_new_protected:Npn \xsim_set_random_list_from_seq:nN #1#2 40 | { \seq_gset_eq:cN {g__xsim_random_#1_seq} #2 } 41 | 42 | \cs_new:Npn \xsim_use_random_list:nn #1#2 43 | { \seq_use:cn {g__xsim_random_#1_seq} {#2} } 44 | 45 | \cs_new_protected:Npn \xsim_map_random_list:nn #1#2 46 | { \seq_map_inline:cn {g__xsim_random_#1_seq} {#2} } 47 | 48 | \prg_new_conditional:Npnn \xsim_random_list_if_exist:n #1 {p,T,F,TF} 49 | { 50 | \seq_if_exist:cTF {g__xsim_random_#1_seq} 51 | { \prg_return_true: } 52 | { \prg_return_false: } 53 | } 54 | 55 | \prg_new_conditional:Npnn \xsim_random_list_if_empty:n #1 {p,T,F,TF} 56 | { 57 | \seq_if_empty:cTF {g__xsim_random_#1_seq} 58 | { \prg_return_true: } 59 | { \prg_return_false: } 60 | } 61 | 62 | % #1: random list id 63 | % #2: sequence variable to set list from 64 | \cs_new_protected:Npn \xsim_save_random_list:nN #1#2 65 | { % TODO: check if #2 is empty 66 | \xsim_random_list_if_exist:nF {#1} 67 | { \xsim_new_random_list:n {#1} } 68 | \xsim_random_list_if_empty:nT {#1} 69 | { \xsim_set_random_list_from_seq:nN {#1} #2 } 70 | \xsim_verbose:n {Saving~ random~ list~ `#1'} 71 | \xsim_add_property_to_aux:nn {random} 72 | { {#1} { \xsim_use_random_list:nn {#1} {,} } } 73 | } 74 | \cs_generate_variant:Nn \xsim_save_random_list:nN {x} 75 | 76 | % #1: collection 77 | % #2: number of items 78 | % #3: clist variable of excluded ids 79 | \cs_new_protected:Npn \xsim_print_random_list:nnN #1#2#3 80 | { 81 | \xsim_if_collection_exist:nTF {#1} 82 | { 83 | \int_gincr:N \g__xsim_random_list_id_int 84 | \int_compare:nNnTF { \xsim_collection_count:n {#1} } = {0} 85 | { 86 | % TODO: message 87 | \xsim_rerun: 88 | } 89 | { 90 | % generate seq of allowed ids from collection: 91 | \xsim_foreach_exercise_id:n 92 | { 93 | \xsim_get_type_for_id:nN {##1} \l__xsim_tmpa_str 94 | \tl_set_rescan:Nnx \l__xsim_tmpa_tl {} { \l__xsim_tmpa_str } 95 | \xsim_if_in_collection:nVnT {#1} \l__xsim_tmpa_tl {##1} 96 | { 97 | \clist_if_in:NnF #3 {##1} 98 | { \seq_put_right:Nn \l__xsim_allowed_exercise_ids_seq {##1} } 99 | } 100 | } 101 | \int_compare:nNnTF 102 | {#2} 103 | > 104 | { \seq_count:N \l__xsim_allowed_exercise_ids_seq } 105 | { 106 | \int_set:Nn \l__xsim_tmpa_int 107 | { \seq_count:N \l__xsim_allowed_exercise_ids_seq } 108 | } 109 | { \int_set:Nn \l__xsim_tmpa_int {#2} } 110 | % generate random list: 111 | \xsim_generate_random_list:nnnN 112 | { \int_to_alph:n { \g__xsim_random_list_id_int } } 113 | { \seq_count:N \l__xsim_allowed_exercise_ids_seq } 114 | { \l__xsim_tmpa_int } 115 | \g__xsim_random_list_seq 116 | } 117 | \xsim_save_random_list:xN 118 | { \int_to_alph:n { \g__xsim_random_list_id_int } } 119 | \g__xsim_random_list_seq 120 | \xsim_verbose:x 121 | { 122 | Printing~ exercises~ of~ random~ list~ 123 | `\int_to_alph:n { \g__xsim_random_list_id_int }'~ of~ 124 | collection~ `#1' 125 | } 126 | \xsim_print_random_exercises:Nn 127 | \l__xsim_allowed_exercise_ids_seq 128 | { \int_to_alph:n { \g__xsim_random_list_id_int } } 129 | } 130 | { \msg_error:nnn {xsim} {unknown-collection} {#1} } 131 | } 132 | \cs_generate_variant:Nn \xsim_print_random_list:nnN {V} 133 | 134 | % #1: random list id 135 | % #2: max number to choose from 136 | % #3: number of items 137 | % #4: seq variable 138 | \cs_new_protected:Npn \xsim_generate_random_list:nnnN #1#2#3#4 139 | { 140 | \bool_lazy_or:nnT 141 | { !\xsim_random_list_if_exist_p:n {#1} } 142 | { \xsim_random_list_if_empty_p:n {#1} } 143 | { 144 | \xsim_verbose:n 145 | {Generating~ random~ list~ `#1'~ with~ #3~ out~ of~ #2~ items} 146 | \seq_gclear:N #4 147 | \int_compare:nNnF {#2} = 0 148 | { 149 | \int_do_until:nNnn { \seq_count:N #4 } = {#3} 150 | { 151 | \tl_set:Nx \l__xsim_tmpa_tl 152 | { \fp_eval:n { randint(#2) } } 153 | \seq_if_in:NVF #4 154 | \l__xsim_tmpa_tl 155 | { \seq_gput_right:NV #4 \l__xsim_tmpa_tl } 156 | } 157 | } 158 | \bool_if:NT \l__xsim_sort_random_bool 159 | { 160 | \seq_gsort:Nn #4 161 | { 162 | \int_compare:nNnTF {##1} > {##2} 163 | { \sort_return_swapped: } 164 | { \sort_return_same: } 165 | } 166 | } 167 | } 168 | } 169 | 170 | % #1: seq variable of ids 171 | % #2: random list id 172 | \cs_new_protected:Npn \xsim_print_random_exercises:Nn #1#2 173 | { 174 | \seq_if_empty:NF #1 175 | { 176 | \bool_lazy_and:nnT 177 | { \xsim_random_list_if_exist_p:n {#2} } 178 | { !\xsim_random_list_if_empty_p:n {#2} } 179 | { 180 | \xsim_verbose:x 181 | { 182 | Printing~ 183 | \str_case:Vn \l__xsim_print_random_choice_tl 184 | { 185 | {exercises} {exercises~} 186 | {solutions} {solutions~} 187 | {both} { exercises~ and~ solutions~ } 188 | } 189 | of~ random~ list~ `#2'. 190 | } 191 | \xsim_map_random_list:nn {#2} 192 | { 193 | \tl_set:Nx \l__xsim_tmpa_tl 194 | { \seq_item:Nn #1 {##1} } 195 | \tl_set:Nx \l__xsim_tmpb_tl 196 | { \xsim_get_type_for_property:nV {id} \l__xsim_tmpa_tl } 197 | \bool_set_false:N \l__xsim_tmpa_bool 198 | \bool_set_false:N \l__xsim_tmpb_bool 199 | \str_case:VnF \l__xsim_print_random_choice_tl 200 | { 201 | {exercises} { \bool_set_true:N \l__xsim_tmpa_bool } 202 | {solutions} { \bool_set_true:N \l__xsim_tmpb_bool } 203 | {both} { 204 | \bool_set_true:N \l__xsim_tmpa_bool 205 | \bool_set_true:N \l__xsim_tmpb_bool 206 | } 207 | } 208 | { 209 | \msg_warning:nnV {xsim} 210 | {print-collection-choice} 211 | \l__xsim_print_random_choice_tl 212 | } 213 | \bool_if:NT \l__xsim_tmpa_bool 214 | { 215 | \xsim_if_exercise_exist:VVT 216 | \l__xsim_tmpb_tl 217 | \l__xsim_tmpa_tl 218 | { 219 | \xsim_insert:VVnn 220 | \l__xsim_tmpb_tl 221 | \l__xsim_tmpa_tl 222 | {} 223 | {exercise} 224 | } 225 | } 226 | \bool_if:NT \l__xsim_tmpb_bool 227 | { 228 | \xsim_if_solution_exist:VVT 229 | \l__xsim_tmpb_tl 230 | \l__xsim_tmpa_tl 231 | { 232 | \xsim_insert:VVnn 233 | \l__xsim_tmpb_tl 234 | \l__xsim_tmpa_tl 235 | {} 236 | {solution} 237 | } 238 | } 239 | } 240 | } 241 | } 242 | } 243 | 244 | \keys_define:nn {xsim/random} 245 | { 246 | sort .bool_set:N = \l__xsim_sort_random_bool , 247 | sort .initial:n = true , 248 | collection .tl_set:N = \l_xsim_random_collection_tl , 249 | collection .initial:n = all~exercises , 250 | exclude .code:n = \__xsim_exclude_ids:n {#1} , 251 | print .tl_set:N = \l__xsim_print_random_choice_tl , 252 | print .initial:n = exercises 253 | } 254 | 255 | \cs_new_protected:Npn \__xsim_exclude_ids:n #1 256 | { 257 | \seq_clear:N \l__xsim_tmpa_seq 258 | \clist_map_inline:nn {#1} 259 | { 260 | \tl_set:Nx \l__xsim_tmpa_tl 261 | { \xsim_get_id_for_property:nn {ID} {##1} } 262 | \tl_if_blank:VTF \l__xsim_tmpa_tl 263 | { \seq_put_right:Nn \l__xsim_tmpa_seq {##1} } 264 | { 265 | \seq_put_right:Nx \l__xsim_tmpa_seq 266 | { \xsim_get_id_for_property:nn {ID} {##1} } 267 | } 268 | } 269 | \seq_remove_duplicates:N \l__xsim_tmpa_seq 270 | \clist_set_from_seq:NN 271 | \l_xsim_random_exclude_list_clist 272 | \l__xsim_tmpa_seq 273 | } 274 | 275 | \XSIMmoduleend 276 | -------------------------------------------------------------------------------- /code/xsim.start.code.tex: -------------------------------------------------------------------------------- 1 | % ---------------------------------------------------------------------------- 2 | % the XSIM package 3 | % 4 | % eXercise Sheets IMproved 5 | % 6 | % ---------------------------------------------------------------------------- 7 | % Clemens Niederberger 8 | % Web: https://github.com/cgnieder/xsim 9 | % E-Mail: clemens@cnltx.de 10 | % ---------------------------------------------------------------------------- 11 | % Copyright 2017--2022 Clemens Niederberger 12 | % 13 | % This work may be distributed and/or modified under the 14 | % conditions of the LaTeX Project Public License, either version 1.3c 15 | % of this license or (at your option) any later version. 16 | % The latest version of this license is in 17 | % http://www.latex-project.org/lppl.txt 18 | % and version 1.3c or later is part of all distributions of LaTeX 19 | % version 2008/05/04 or later. 20 | % 21 | % This work has the LPPL maintenance status `maintained'. 22 | % 23 | % The Current Maintainer of this work is Clemens Niederberger. 24 | % ---------------------------------------------------------------------------- 25 | % If you have any ideas, questions, suggestions or bugs to report, please 26 | % feel free to contact me. 27 | % ---------------------------------------------------------------------------- 28 | \RequirePackage {l3keys2e,xsimverb} 29 | 30 | \ExplSyntaxOn 31 | 32 | \tl_const:Nn \c_xsim_date_tl {2022/02/13} 33 | \tl_const:Nn \c_xsim_version_major_number_tl {0} 34 | \tl_const:Nn \c_xsim_version_minor_number_tl {21} 35 | \tl_const:Nn \c_xsim_version_subrelease_tl {a} 36 | \tl_const:Nx \c_xsim_version_number_tl 37 | { 38 | \c_xsim_version_major_number_tl . 39 | \c_xsim_version_minor_number_tl 40 | } 41 | \tl_const:Nx \c_xsim_version_tl 42 | { 43 | \c_xsim_version_number_tl 44 | \c_xsim_version_subrelease_tl 45 | } 46 | \tl_const:Nn \c_xsim_info_tl {eXercise ~ Sheets ~ IMproved} 47 | 48 | \ProvidesExplPackage 49 | {xsim} 50 | {\c_xsim_date_tl} 51 | {\c_xsim_version_tl} 52 | {\c_xsim_info_tl} 53 | 54 | % -------------------------------------------------------------------------- 55 | % options, information 56 | 57 | \cs_new_protected:Npn \xsim_bool_provide:N #1 58 | { \bool_if_exist:NF #1 { \bool_new:N #1 } } 59 | 60 | \xsim_bool_provide:N \g__xsim_final_bool 61 | \xsim_bool_provide:N \g__xsim_verbose_bool 62 | \xsim_bool_provide:N \g_xsim_clear_aux_bool 63 | \xsim_bool_provide:N \g__xsim_write_to_file_bool 64 | \xsim_bool_provide:N \g_xsim_use_aux_bool 65 | \xsim_bool_provide:N \g__xsim_rerun_bool 66 | \xsim_bool_provide:N \g__xsim_debug_bool 67 | \xsim_bool_provide:N \g__xsim_blank_bool 68 | 69 | \keys_define:nn {xsim/package} 70 | { 71 | final .bool_gset:N = \g__xsim_final_bool , 72 | verbose .bool_gset:N = \g__xsim_verbose_bool , 73 | debug .bool_gset:N = \g__xsim_debug_bool , 74 | clear-aux .bool_gset:N = \g_xsim_clear_aux_bool , 75 | use-files .bool_gset:N = \g__xsim_write_to_file_bool , 76 | use-files .initial:n = false , 77 | no-files .choice: , 78 | no-files / true .meta:n = { use-files = false } , 79 | no-files / false .meta:n = { use-files = true } , 80 | no-files .default:n = true , 81 | use-aux .bool_gset:N = \g_xsim_use_aux_bool , 82 | use-aux .initial:n = false , 83 | blank .bool_gset:N = \g__xsim_blank_bool , 84 | blank .initial:n = false 85 | } 86 | 87 | \ProcessKeysPackageOptions {xsim/package} 88 | 89 | \keys_define:nn {xsim/package} 90 | { 91 | final .code:n = \msg_error:nnn {xsim} {load-time-option} {final} , 92 | verbose .code:n = \msg_error:nnn {xsim} {load-time-option} {verbose} , 93 | debug .code:n = \msg_error:nnn {xsim} {load-time-option} {debug} , 94 | clear-aux .code:n = \msg_error:nnn {xsim} {load-time-option} {clear-aux} , 95 | use-files .code:n = \msg_error:nnn {xsim} {load-time-option} {use-files} , 96 | no-files .code:n = \msg_error:nnn {xsim} {load-time-option} {no-files} , 97 | use-aux .code:n = \msg_error:nnn {xsim} {load-time-option} {use-aux} , 98 | blank .code:n = \msg_error:nnn {xsim} {load-time-option} {blank} 99 | } 100 | 101 | % -------------------------------------------------------------------------- 102 | 103 | % messages: 104 | \msg_new:nnn {xsim} {load-time-option} 105 | { 106 | `#1'~ is~ a~ load-time~ option! \\ 107 | You~ cannot~ set~ it~ with~ \token_to_str:N \xsimsetup ! \\ 108 | You~ need~ to~ use~ \token_to_str:N \usepackage [#1] {xsim} . 109 | } 110 | 111 | \msg_new:nnn {xsim} {rerun} 112 | { 113 | Exercise~ properties~ may~ have~ changed.~ Rerun~ to~ get~ them~ 114 | synchronized. 115 | } 116 | 117 | \msg_new:nnn {xsim} {verbose} { #1 ~( \msg_line_context: ) } 118 | 119 | % -------------------------------------------------------------------------- 120 | 121 | \cs_new_protected:Npn \xsim_do_rerun: 122 | { \xsim_if_rerun:T { \msg_warning:nn {xsim} {rerun} } } 123 | 124 | % -------------------------------------------------------------------------- 125 | % MODULE mechanism 126 | \msg_new:nnn {xsim} {module-missing} 127 | { 128 | You've~ requested~ the~ xsim~ module~ `#1'~ but~ it~ appears~ to~ 129 | be~ missing~ on~ your~ system.~ Maybe~ you've~ misspelled~ the~ name?~ 130 | Loading~ the~ module~ will~ abort~ \msg_line_context: 131 | } 132 | 133 | \msg_new:nnn {xsim} {loading-module} 134 | { Loading~ module~ `#1'~ ... } 135 | 136 | \msg_new:nnn {xsim} {wrong-module-name} 137 | { The~ module~ file~ name~ is~ `#2'~ but~ it~ provides~ module~ `#1'. } 138 | 139 | \msg_new:nnn {xsim} {forbidden-module} 140 | { 141 | You've~ requested~ the~ xsim~ module~ `modules'~ \msg_line_context: .~ 142 | This~ module~ is~ a~ pseudo~ module~ which~ may~ not~ be~ loaded~ through~ 143 | the~ module~ loading~ mechansim. 144 | } 145 | 146 | % ---------------------------------------------------------------------------- 147 | 148 | \cs_generate_variant:Nn \str_if_eq:nnF {xx} 149 | 150 | \tl_const:Nn \c__xsim_module_extension_tl {code.tex} 151 | \tl_const:Nn \c__xsim_module_prefix_tl {xsim} 152 | 153 | \cs_new_protected:Npn \xsim_load_module:n #1 154 | { 155 | \tl_set:Nx \l_tmpa_tl { \tl_trim_spaces:n {#1} } 156 | \str_if_eq:VnTF \l_tmpa_tl {modules} 157 | { \msg_error:nn {xsim} {forbidden-module} } 158 | { \__xsim_load_module:V \l_tmpa_tl } 159 | } 160 | 161 | \cs_new_protected:Npn \__xsim_load_module:n #1 162 | { 163 | \xsim_if_module_loaded:nF {#1} 164 | { 165 | \xsim_if_module_exist:nTF {#1} 166 | { 167 | \__xsim_module_hook_use:nn {#1} {before} 168 | \msg_info:nnn {xsim} {loading-module} {#1} 169 | \@onefilewithoptions 170 | {\c__xsim_module_prefix_tl.#1}[][] 171 | \c__xsim_module_extension_tl 172 | \__xsim_module_hook_use:nn {#1} {after} 173 | } 174 | { \msg_error:nnn {xsim} {module-missing} {#1} } 175 | } 176 | } 177 | \cs_generate_variant:Nn \__xsim_load_module:n {V} 178 | 179 | \tl_new:N \g__xsim_modules_loaded_tl 180 | 181 | \prg_new_conditional:Npnn \xsim_if_module_loaded:n #1 {p,T,F,TF} 182 | { 183 | \tl_if_in:NnTF \g__xsim_modules_loaded_tl {#1} 184 | { \prg_return_true: } 185 | { \prg_return_false: } 186 | } 187 | 188 | \prg_new_conditional:Npnn \xsim_if_module_exist:n #1 {p,T,F,TF} 189 | { 190 | \file_if_exist:nTF 191 | {\c__xsim_module_prefix_tl.#1.\c__xsim_module_extension_tl} 192 | { \prg_return_true: } 193 | { \prg_return_false: } 194 | } 195 | 196 | % -------------------------------------------------------------------------- 197 | % module hooks: 198 | % #1: module 199 | % #2: code 200 | \cs_new_protected:Npn \xsim_module_after:nn #1#2 201 | { 202 | \xsim_if_module_loaded:nTF {#1} 203 | {#2} 204 | { \__xsim_add_to_module_hook:nnn {#1} {after} {#2} } 205 | } 206 | 207 | % #1: module 208 | % #2: code 209 | \cs_new_protected:Npn \xsim_module_before:nn #1#2 210 | { 211 | % TODO: error in T case? 212 | \xsim_if_module_loaded:nF {#1} 213 | { \__xsim_add_to_module_hook:nnn {#1} {before} {#2} } 214 | } 215 | 216 | % #1: module 217 | % #2: hook name 218 | % #3: code 219 | \cs_new_protected:Npn \__xsim_add_to_module_hook:nnn #1#2#3 220 | { 221 | \xsim_if_module_loaded:nF {#1} 222 | { 223 | \tl_if_exist:cF {g__xsim_module_hook_#1_#2_tl} 224 | { \tl_new:c {g__xsim_module_hook_#1_#2_tl} } 225 | \tl_gput_right:cn {g__xsim_module_hook_#1_#2_tl} {#3} 226 | } 227 | } 228 | 229 | % #1: module 230 | % #2: hook name 231 | \cs_new_protected:Npn \__xsim_module_hook_use:nn #1#2 232 | { 233 | \tl_if_exist:cT {g__xsim_module_hook_#1_#2_tl} 234 | { 235 | \tl_use:c {g__xsim_module_hook_#1_#2_tl} 236 | \tl_gclear:c {g__xsim_module_hook_#1_#2_tl} 237 | } 238 | } 239 | \cs_generate_variant:Nn \__xsim_module_hook_use:nn {V} 240 | 241 | % -------------------------------------------------------------------------- 242 | 243 | \tl_new:N \l__xsim_module_date_tl 244 | \tl_new:N \l__xsim_module_version_tl 245 | 246 | \tl_if_exist:NF \c_xsim_date_tl 247 | { \tl_set:Nx \l__xsim_module_date_tl {\c_xsimverb_date_tl} } 248 | \tl_if_exist:NF \c_xsim_version_tl 249 | { \tl_set:Nx \l__xsim_module_version_tl {\c_xsimverb_version_tl} } 250 | 251 | \hook_gput_code:nnn {package/xsim/after} {xsim} 252 | { 253 | \tl_set:NV \l__xsim_module_date_tl \c_xsim_date_tl 254 | \tl_set:NV \l__xsim_module_version_tl \c_xsim_version_tl 255 | } 256 | 257 | \cs_new_protected:Npn \__xsim_module:nn #1#2 258 | { 259 | \str_if_eq:xxF 260 | {\c__xsim_module_prefix_tl.#1.\c__xsim_module_extension_tl} 261 | {\@currname.\@currext} 262 | { 263 | \msg_error:nnnxx {xsim} {wrong-module-name} 264 | {#1} 265 | {\@currname.\@currext} 266 | } 267 | \ProvidesFile 268 | {\c__xsim_module_prefix_tl.#1.\c__xsim_module_extension_tl} 269 | [ 270 | \l__xsim_module_date_tl 271 | \c_space_tl 272 | v \l__xsim_module_version_tl 273 | \c_space_tl 274 | xsim~ module~ `#1'~ (#2) 275 | ] 276 | } 277 | \cs_generate_variant:Nn \msg_error:nnnn {nnnx} 278 | 279 | % -------------------------------------------------------------------------- 280 | % define a xsim module: 281 | % #1: if star: expl3 mode 282 | % #2: name 283 | % #3: description 284 | \NewDocumentCommand \xsimstyle {smO{}} 285 | { 286 | \__xsim_module:nn {style.#2} {#3} 287 | \IfBooleanT {#1} { \ExplSyntaxOn } 288 | } 289 | 290 | % \cs_new_protected:Npn \xsim_style_options:nn #1#2 291 | % { \keys_define:nn {xsim/#1} {#2} } 292 | 293 | \cs_new_protected:Npn \xsim_load_style:n #1 294 | { \clist_map_inline:nn {#1} { \xsim_load_module:n {style.##1} } } 295 | 296 | \keys_define:nn {xsim} 297 | { load-style .code:n = \xsim_load_style:n {#1} } 298 | 299 | \NewDocumentCommand \loadxsimstyle {m} 300 | { \xsim_load_style:n {#1} } 301 | 302 | % -------------------------------------------------------------------------- 303 | % define internal xsim modules: 304 | \tl_new:N \g_xsim_module_tl 305 | \tl_new:N \g__xsim_module_stop_tl 306 | 307 | \cs_new_protected:Npn \xsim_stop_module:n #1 308 | { \tl_gput_right:Nn \g__xsim_module_stop_tl {{#1}} } 309 | 310 | % #1: name 311 | % #2: description 312 | \cs_set_protected:Npn \XSIMmodule #1#2 313 | { 314 | \msg_log:nnnn {xsim} {loading-module} {#1} {#2} 315 | \tl_gput_right:Nn \g__xsim_modules_loaded_tl {{#1}} 316 | \tl_gset:Nn \g_xsim_module_tl {#1} 317 | \__xsim_module_hook_use:nn {#1} {before} 318 | \tl_map_inline:Nn \g__xsim_module_stop_tl 319 | { 320 | \str_if_eq:nnT {##1} {#1} 321 | { \tl_map_break:n { \__xsim_gobble_module:w } } 322 | } 323 | } 324 | 325 | \cs_set_protected:Npn \XSIMmoduleend 326 | { \__xsim_module_hook_use:Vn \g_xsim_module_tl {after} } 327 | 328 | \cs_new_protected:Npn \__xsim_gobble_module:w #1 \XSIMmoduleend {} 329 | 330 | % -------------------------------------------------------------------------- 331 | -------------------------------------------------------------------------------- /code/xsim.style.layouts.code.tex: -------------------------------------------------------------------------------- 1 | % ---------------------------------------------------------------------------- 2 | % the XSIM package - layouts style 3 | % 4 | % eXercise Sheets IMproved 5 | % 6 | % ---------------------------------------------------------------------------- 7 | % Clemens Niederberger 8 | % Web: https://github.com/cgnieder/xsim 9 | % E-Mail: contact@mychemistry.eu 10 | % ---------------------------------------------------------------------------- 11 | % Copyright 2017--2022 Clemens Niederberger 12 | % 13 | % This work may be distributed and/or modified under the 14 | % conditions of the LaTeX Project Public License, either version 1.3c 15 | % of this license or (at your option) any later version. 16 | % The latest version of this license is in 17 | % http://www.latex-project.org/lppl.txt 18 | % and version 1.3c or later is part of all distributions of LaTeX 19 | % version 2008/05/04 or later. 20 | % 21 | % This work has the LPPL maintenance status `maintained'. 22 | % 23 | % The Current Maintainer of this work is Clemens Niederberger. 24 | % ---------------------------------------------------------------------------- 25 | % If you have any ideas, questions, suggestions or bugs to report, please 26 | % feel free to contact me. 27 | % ---------------------------------------------------------------------------- 28 | \xsimstyle{layouts}[2021/02/02] 29 | 30 | \RequirePackage{needspace} 31 | 32 | \DeclareExerciseEnvironmentTemplate{runin} 33 | {% 34 | \par\vspace{\baselineskip} 35 | \Needspace*{2\baselineskip} 36 | \noindent 37 | \textbf{\XSIMmixedcase{\GetExerciseName}~\GetExerciseProperty{counter}}% 38 | \GetExercisePropertyT{subtitle}{ \textit{#1}} % <<< notice the space 39 | \IfInsideSolutionF{% 40 | \GetExercisePropertyT{points}{% 41 | \marginpar{% 42 | \printgoal{\PropertyValue}% 43 | \GetExercisePropertyT{bonus-points}{+\printgoal{\PropertyValue}}% 44 | \,\IfExerciseGoalSingularTF{points} 45 | {\XSIMtranslate{point}} 46 | {\XSIMtranslate{points}}% 47 | }% 48 | }% 49 | }% 50 | } 51 | {} 52 | 53 | \RequirePackage{array} 54 | 55 | \DeclareExerciseEnvironmentTemplate{margin} 56 | {% 57 | \trivlist 58 | \item[\llap{% 59 | \smash{% 60 | \tabular[t]{@{}r@{}} 61 | \textbf{\XSIMmixedcase{\GetExerciseName}~\GetExerciseProperty{counter}} 62 | \IfExercisePropertySetT{points}{% 63 | \tabularnewline 64 | (% 65 | \printgoal{\GetExerciseProperty{points}}% 66 | \GetExercisePropertyT{bonus-points}{+\printgoal{#1}}% 67 | \,\XSIMtranslate{point-abbr}% 68 | )% 69 | }% 70 | \endtabular 71 | }% 72 | }]\relax 73 | } 74 | {\endtrivlist} 75 | 76 | \DeclareExerciseEnvironmentTemplate{inline} 77 | {% 78 | \textbf{\GetExerciseProperty{counter}}% 79 | \IfInsideSolutionF{% 80 | \GetExercisePropertyT{points}{ % <<< notice the space 81 | (\printgoal{\PropertyValue}% 82 | \GetExercisePropertyT{bonus-points}{+\printgoal{\PropertyValue}}% 83 | \,\IfExerciseGoalSingularTF{points} 84 | {\XSIMtranslate{point}} 85 | {\XSIMtranslate{points}})% 86 | }% 87 | } % <<< notice the space 88 | } 89 | {} 90 | 91 | \DeclareExerciseEnvironmentTemplate{minimal} 92 | {\par\UseExerciseTemplate{begin}{inline}} 93 | {\UseExerciseTemplate{end}{inline}\par} 94 | 95 | \DeclareExerciseEnvironmentTemplate{centered} 96 | {% 97 | \par\vspace{\baselineskip} 98 | \Needspace*{2\baselineskip} 99 | \noindent 100 | \hfil\textbf{\XSIMmixedcase{\GetExerciseName}~\GetExerciseProperty{counter}}% 101 | \GetExercisePropertyT{subtitle}{ \textit{#1}}\hfil 102 | \par\noindent 103 | \IfInsideSolutionF{% 104 | \GetExercisePropertyT{points}{% 105 | \marginpar{% 106 | \printgoal{\PropertyValue}% 107 | \GetExercisePropertyT{bonus-points}{+\printgoal{\PropertyValue}}% 108 | \,\IfExerciseGoalSingularTF{points} 109 | {\XSIMtranslate{point}} 110 | {\XSIMtranslate{points}}% 111 | }% 112 | }% 113 | }% 114 | } 115 | {} 116 | 117 | % ---------------------------------------------------------------------------- 118 | \endinput 119 | 120 | 2020/02/23 - added: inline, centered 121 | - adapt to removed \par from the generic environments 122 | -------------------------------------------------------------------------------- /code/xsim.tags.code.tex: -------------------------------------------------------------------------------- 1 | \XSIMmodule{tags}{tagging of exercises} 2 | 3 | \seq_new:N \l__xsim_tag_types_seq 4 | \bool_new:N \l____xsim_tagged_bool 5 | 6 | \msg_new:nnn {xsim} {tag-exists} 7 | { The~ tag~ type~ `#1'~ already~ exists.~ I~ am~ doing~ nothing. } 8 | 9 | \msg_new:nnn {xsim} {tag-unknown} 10 | { The~ tag~ type~ `#1'~ is~ not~ defined.~ Check~ for~ a~ typo. } 11 | 12 | % #1: name 13 | \cs_new_protected:Npn \xsim_new_tag_type:n #1 14 | { 15 | \xsim_verbose:n { Declaring~ new~ tag~ type~ `#1'. } 16 | \seq_put_right:Nn \l__xsim_tag_types_seq {#1} 17 | \seq_remove_duplicates:N \l__xsim_tag_types_seq 18 | \seq_new:c {l__xsim_chosen_tags_#1_seq} 19 | \bool_new:c {l__xsim_ignore_untagged_#1_bool} 20 | \bool_new:c {l____xsim_tagged_#1_bool} 21 | \bool_new:c {l__xsim_use_unmatched_#1_bool} 22 | \keys_define:nn {xsim} 23 | { 24 | #1/ignore-untagged .bool_set:c = {l__xsim_ignore_untagged_#1_bool} , 25 | #1/ignore-untagged .initial:n = true , 26 | #1 .code:n = \seq_set_from_clist:cn {l__xsim_chosen_tags_#1_seq} {##1} , 27 | #1/use-unmatched .bool_set:c = {l__xsim_use_unmatched_#1_bool} , 28 | #1/use-unmatched .initial:n = false 29 | } 30 | \prg_new_protected_conditional:cpnn {xsim_if_#1_value:n} ##1 {T,F,TF} 31 | { 32 | \seq_if_in:cnTF {l__xsim_chosen_tags_#1_seq} {##1} 33 | { \prg_return_true: } 34 | { \prg_return_false: } 35 | } 36 | \xsim_declare_property:nnnn 37 | { \c_false_bool } 38 | { \c_false_bool } 39 | { \c_false_bool } 40 | {#1} 41 | \xsim_declare_printsolutions_condition:nn {#1} 42 | { \__xsim_printsolutions_if_tagged:nnnnTF {#1} } 43 | \keys_define:nn {xsim/print-solutions} 44 | { 45 | #1 .choice: , 46 | #1/false .code:n = 47 | \__xsim_printsolutions_condition:nn {#1} {false} , 48 | #1/true .code:n = 49 | \__xsim_printsolutions_condition:nn {#1} {true} , 50 | #1/unknown .code:n = 51 | \keys_set:nn {xsim} { #1 = ##1 } 52 | \__xsim_printsolutions_condition:nn {#1} {true} , 53 | #1 .initial:n = false 54 | } 55 | } 56 | 57 | % #1: tag type 58 | \prg_new_protected_conditional:Npnn \xsim_if_tag_type_exist:n #1 {T,F,TF} 59 | { 60 | \seq_if_in:NnTF \l__xsim_tag_types_seq {#1} 61 | { \prg_return_true: } 62 | { \prg_return_false: } 63 | } 64 | \prg_generate_conditional_variant:Nnn \xsim_if_tag_type_exist:n {V} {TF} 65 | 66 | % #1: tag type 67 | % #2: exercise type 68 | % #3: id 69 | % #4: print|use 70 | \prg_new_protected_conditional:Npnn 71 | \__xsim_printsolutions_if_tagged:nnnn #1#2#3#4 {T,F,TF} 72 | { 73 | \xsim_if_in_list:nnTF {#4} {#2-#3=={true}} 74 | { 75 | \__xsim_printsolutions_if_condition:nTF {#1} 76 | { 77 | \__xsim_printsolutions_condition_true: 78 | \xsim_if_tagged:nnnTF {#2} {#3} {#1} 79 | { \prg_return_true: } 80 | { \prg_return_false: } 81 | } 82 | { \prg_return_false: } 83 | } 84 | { \prg_return_false: } 85 | } 86 | 87 | % #1: exercise type 88 | % #2: id 89 | % #3: tag type 90 | \prg_new_protected_conditional:Npnn \xsim_if_tagged:nnn #1#2#3 {T,F,TF} 91 | { 92 | \bool_set_false:c {l____xsim_tagged_#3_bool} 93 | \seq_if_empty:cTF {l__xsim_chosen_tags_#3_seq} 94 | { \bool_set_true:c {l____xsim_tagged_#3_bool} } 95 | { 96 | \seq_set_from_clist:Nx 97 | \l__xsim_tmpa_seq 98 | { \xsim_get_property:nnn {#1} {#2} {#3} } 99 | \seq_if_empty:NTF \l__xsim_tmpa_seq 100 | { 101 | \bool_set_eq:cc 102 | {l____xsim_tagged_#3_bool} 103 | {l__xsim_ignore_untagged_#3_bool} 104 | } 105 | { 106 | \seq_map_inline:Nn \l__xsim_tmpa_seq 107 | { 108 | \seq_if_in:cnT {l__xsim_chosen_tags_#3_seq} {##1} 109 | { 110 | \bool_set_true:c {l____xsim_tagged_#3_bool} 111 | \seq_map_break: 112 | } 113 | } 114 | } 115 | } 116 | \bool_if:cTF {l____xsim_tagged_#3_bool} 117 | { \prg_return_true: } 118 | { \prg_return_false: } 119 | } 120 | 121 | % #1: exercise type 122 | % #2: id 123 | % #3: tag type 124 | % #4: tag values 125 | \prg_new_protected_conditional:Npnn \xsim_has_tags:nnnn #1#2#3#4 {T,F,TF} 126 | { 127 | \bool_set_false:c {l____xsim_tagged_#3_bool} 128 | \seq_set_from_clist:Nn \l__xsim_tmpa_seq {#4} 129 | \seq_if_empty:NTF \l__xsim_tmpa_seq 130 | {% no tag values given: 131 | \bool_set_true:c {l____xsim_tagged_#3_bool} 132 | } 133 | { 134 | \seq_set_from_clist:Nx 135 | \l__xsim_tmpb_seq 136 | { \xsim_get_property:nnn {#1} {#2} {#3} } 137 | \seq_if_empty:NTF \l__xsim_tmpb_seq 138 | {% exercise has no tag values given 139 | % \bool_set_eq:cc 140 | % {l____xsim_tagged_#3_bool} 141 | % {l__xsim_ignore_untagged_#3_bool} 142 | \bool_set_false:c {l____xsim_tagged_#3_bool} 143 | } 144 | { 145 | \seq_map_inline:Nn \l__xsim_tmpb_seq 146 | { 147 | \seq_if_in:NnT \l__xsim_tmpa_seq {##1} 148 | { 149 | \bool_set_true:c {l____xsim_tagged_#3_bool} 150 | \seq_map_break: 151 | } 152 | } 153 | } 154 | } 155 | \bool_if:cTF {l____xsim_tagged_#3_bool} 156 | { \prg_return_true: } 157 | { \prg_return_false: } 158 | } 159 | \prg_generate_conditional_variant:Nnn \xsim_has_tags:nnnn {nnVV} {T,F} 160 | 161 | % #1: exercise type 162 | % #2: id 163 | \prg_new_protected_conditional:Npnn \xsim_if_tagged:nn #1#2 {T,F,TF} 164 | { 165 | \bool_set_true:N \l____xsim_tagged_bool 166 | \seq_map_inline:Nn \l__xsim_tag_types_seq 167 | { 168 | \xsim_if_tagged:nnnF {#1} {#2} {##1} 169 | { 170 | \bool_set_false:N \l____xsim_tagged_bool 171 | \seq_map_break: 172 | } 173 | } 174 | \bool_if:NTF \l____xsim_tagged_bool 175 | { \prg_return_true: } 176 | { \prg_return_false: } 177 | } 178 | 179 | % #1: exercise type 180 | % #2: id 181 | % #3: tag type 182 | \prg_new_protected_conditional:Npnn \xsim_if_tags_match:nnn #1#2#3 {T,F,TF} 183 | { 184 | \bool_set_false:c {l____xsim_tagged_#3_bool} 185 | \seq_if_empty:cTF {l__xsim_chosen_tags_#3_seq} 186 | { \bool_set_true:c {l____xsim_tagged_#3_bool} } 187 | { 188 | \seq_set_from_clist:Nx 189 | \l__xsim_tmpa_seq 190 | { \xsim_get_property:nnn {#1} {#2} {#3} } 191 | \seq_if_empty:NTF \l__xsim_tmpa_seq 192 | { 193 | \bool_set_eq:cc 194 | {l____xsim_tagged_#3_bool} 195 | {l__xsim_ignore_untagged_#3_bool} 196 | } 197 | { 198 | \seq_map_inline:Nn \l__xsim_tmpa_seq 199 | { 200 | \seq_if_in:cnT {l__xsim_chosen_tags_#3_seq} {##1} 201 | { 202 | \bool_set_true:c {l____xsim_tagged_#3_bool} 203 | \seq_map_break: 204 | } 205 | } 206 | } 207 | } 208 | \bool_if:cTF {l____xsim_tagged_#3_bool} 209 | { \prg_return_true: } 210 | { \prg_return_false: } 211 | } 212 | 213 | \prg_new_protected_conditional:Npnn \xsim_if_tagged_use:nn #1#2 {T,F,TF} 214 | { 215 | \bool_set_true:N \l____xsim_tagged_bool 216 | \seq_map_inline:Nn \l__xsim_tag_types_seq 217 | { 218 | \xsim_if_tags_match:nnnF {#1} {#2} {##1} 219 | { 220 | 221 | \bool_if:cF {l__xsim_use_unmatched_##1_bool} 222 | { 223 | \bool_set_false:N \l____xsim_tagged_bool 224 | \seq_map_break: 225 | } 226 | } 227 | } 228 | \bool_if:NTF \l____xsim_tagged_bool 229 | { \prg_return_true: } 230 | { \prg_return_false: } 231 | } 232 | 233 | % #1: exercise type 234 | % #2: id 235 | % #3: tag type 236 | % #4: code 237 | \cs_new_protected:Npn \xsim_foreach_exercise_tag:nnnn #1#2#3#4 238 | { 239 | \seq_set_from_clist:Nx \l__xsim_tmpa_seq 240 | { \xsim_get_property:nnn {#1} {#2} {#3} } 241 | \seq_map_inline:Nn \l__xsim_tmpa_seq {#4} 242 | } 243 | \cs_generate_variant:Nn \xsim_foreach_exercise_tag:nnnn {oo} 244 | 245 | % #1: exercise type 246 | % #2: id 247 | % #3: tag type 248 | % #4: sep 249 | \cs_new_protected:Npn \xsim_exercise_tags_use:nnnn #1#2#3#4 250 | { 251 | \seq_set_from_clist:Nx \l__xsim_tmpa_seq 252 | { \xsim_get_property:nnn {#1} {#2} {#3} } 253 | \seq_use:Nn \l__xsim_tmpa_seq {#4} 254 | } 255 | \cs_generate_variant:Nn \xsim_exercise_tags_use:nnnn {oo} 256 | 257 | % #1: exercise type 258 | % #2: id 259 | % #3: tag type 260 | % #4: sep between two 261 | % #5: sep between more than two 262 | % #6: sep between last two 263 | \cs_new_protected:Npn \xsim_exercise_tags_use:nnnnnn #1#2#3#4#5#6 264 | { 265 | \seq_set_from_clist:Nx \l__xsim_tmpa_seq 266 | { \xsim_get_property:nnn {#1} {#2} {#3} } 267 | \seq_use:Nnnn \l__xsim_tmpa_seq {#4} {#5} {#6} 268 | } 269 | \cs_generate_variant:Nn \xsim_exercise_tags_use:nnnn {oo} 270 | \cs_generate_variant:Nn \xsim_exercise_tags_use:nnnnnn {oo} 271 | 272 | \XSIMmoduleend 273 | -------------------------------------------------------------------------------- /code/xsim.templates.code.tex: -------------------------------------------------------------------------------- 1 | \XSIMmodule{templates}{templates for typesetting exercises} 2 | 3 | \msg_new:nnn {xsim} {unknown-template} 4 | { 5 | You~ are~ trying~ to~ load~ the~ template~ `#2'~ (template~ type~ `#1')~ 6 | \msg_line_context: .~ This~ template~ does~ not~ seem~ to~ be~ defined.~ 7 | I~ am~ using~ the~ template~ `#3'~ (template~ type~ `#1')~ instead. 8 | } 9 | 10 | \msg_new:nnn {xsim} {template-type-exists} 11 | { The~ template~ type~ `#1'~ already~ exists~ \msg_line_context: } 12 | 13 | % ---------------------------------------------------------------------------- 14 | \seq_new:N \l__xsim_template_types_seq 15 | 16 | % #1: template type 17 | \cs_new_protected:Npn \xsim_new_template_type:n #1 18 | { 19 | \seq_if_in:NnTF \l__xsim_template_types_seq {#1} 20 | { \msg_error:nnn {xsim} {template-type-exists} {#1} } 21 | { 22 | \xsim_verbose:n { Declaring~ new~ template~ type~ `#1'. } 23 | \seq_put_right:Nn \l__xsim_template_types_seq {#1} 24 | } 25 | } 26 | 27 | % #1: template type 28 | % #2: template name 29 | % #3: code 30 | \cs_new_protected:Npn \__xsim_add_template:nnn #1#2#3 31 | { 32 | \xsim_verbose:n { Defining~ new~ template~ `#2'~ of~ type~ `#1'. } 33 | \tl_new:c {l__xsim_template_#1_#2_setup_tl} 34 | \xsim_attribute_set:nnn {template::#1} {#2} {#3} 35 | } 36 | 37 | \prg_new_conditional:Npnn \xsim_if_template_exist:nn #1#2 {T,F,TF} 38 | { 39 | \xsim_attribute_if_set:nnTF {template::#1} {#2} 40 | { \prg_return_true: } 41 | { \prg_return_false: } 42 | } 43 | 44 | % #1: template type 45 | % #2: template name 46 | \cs_new_protected:Npn \__xsim_get_template:nn #1#2 47 | { \xsim_attribute_get:nn {template::#1} {#2} } 48 | 49 | % ---------------------------------------------------------------------------- 50 | 51 | % environment templates (types `begin' and `end'): 52 | \xsim_new_template_type:n {begin} 53 | \xsim_new_template_type:n {end} 54 | 55 | % #1: template name 56 | % #2: begin code 57 | % #3: end code 58 | \cs_new_protected:Npn \xsim_declare_environment_template:nnn #1#2#3 59 | { 60 | \__xsim_add_template:nnn {begin} {#1} 61 | { 62 | \__xsim_start_template:nn {begin} {#1} 63 | \__xsim_start_template:nn {end} {#1} 64 | #2 65 | } 66 | \__xsim_add_template:nnn {end} {#1} 67 | { 68 | #3 69 | \__xsim_stop_template:nn {end} {#1} 70 | \__xsim_stop_template:nn {begin} {#1} 71 | } 72 | } 73 | 74 | % ---------------------------------------------------------------------------- 75 | 76 | % heading templates for the solution list (type `heading'): 77 | \xsim_new_template_type:n {heading} 78 | 79 | % #1: template name 80 | % #2: code 81 | \cs_new_protected:Npn \xsim_declare_heading_template:nn #1#2 82 | { 83 | \__xsim_add_template:nnn {heading} {#1} 84 | { 85 | \__xsim_start_template:nn {heading} {#1} 86 | #2 87 | \__xsim_stop_template:nn {heading} {#1} 88 | } 89 | } 90 | 91 | % ---------------------------------------------------------------------------- 92 | 93 | % grading table templates (type `table'): 94 | \xsim_new_template_type:n {table} 95 | 96 | % #1: template name 97 | % #2: code 98 | \cs_new_protected:Npn \xsim_declare_table_template:nn #1#2 99 | { 100 | \__xsim_add_template:nnn {table} {#1} 101 | { 102 | \__xsim_start_template:nn {table} {#1} 103 | #2 104 | \__xsim_stop_template:nn {table} {#1} 105 | } 106 | } 107 | 108 | % ---------------------------------------------------------------------------- 109 | 110 | % using templates: 111 | % setup up the next usage of `template name': 112 | % #1: template type 113 | % #2: template name 114 | % #3: setup code 115 | \cs_new_protected:Npn \xsim_setup_template:nnn #1#2#3 116 | { \tl_set:cn {l__xsim_template_#1_#2_setup_tl} {#3} } 117 | \cs_generate_variant:Nn \xsim_setup_template:nnn {nnV,nVn} 118 | 119 | % #1: template type 120 | % #2: template name 121 | \cs_new_protected:Npn \__xsim_setup_template:nn #1#2 122 | { \tl_use:c {l__xsim_template_#1_#2_setup_tl} } 123 | 124 | % #1: template type 125 | % #2: template name 126 | \cs_new_protected:Npn \__xsim_clear_template_setup:nn #1#2 127 | { \tl_clear:c {l__xsim_template_#1_#2_setup_tl} } 128 | 129 | % #1: template type 130 | % #2: template name 131 | \cs_new_protected:Npn \__xsim_start_template:nn #1#2 132 | { \group_begin: \__xsim_setup_template:nn {#1} {#2} } 133 | 134 | % #1: template type 135 | % #2: template name 136 | \cs_new_protected:Npn \__xsim_stop_template:nn #1#2 137 | { \group_end: \__xsim_clear_template_setup:nn {#1} {#2} } 138 | 139 | % #1: template type 140 | % #2: template name 141 | \cs_new_protected:Npn \xsim_use_template:nn #1#2 142 | { 143 | \xsim_if_template_exist:nnTF {#1} {#2} 144 | { \__xsim_get_template:nn {#1} {#2} } 145 | { 146 | \msg_warning:nnnnn {xsim} {unknown-template} {#1} {#2} {default} 147 | \__xsim_get_template:nn {#1} {default} 148 | } 149 | } 150 | \cs_generate_variant:Nn \xsim_use_template:nn {nx,nV} 151 | 152 | \XSIMmoduleend 153 | -------------------------------------------------------------------------------- /code/xsim.translations.code.tex: -------------------------------------------------------------------------------- 1 | \XSIMmodule{translations}{language settings for XSIM} 2 | 3 | \RequirePackage{translations} 4 | 5 | \msg_new:nnn {xsim} {language-not-defined} 6 | { 7 | You~ chose~ the~ language~ `#1'~ which~ is~ not~ defined~ by~ xsim.~ 8 | `english'~ is~ used~ instead.~ If~ you~ just~ mistyped~ try~ again!~ 9 | Otherwise~ contact~ the~ author~ and~ he'll~ probably~ add~ your~ 10 | language. 11 | } 12 | 13 | \msg_new:nnn {xsim} {empty-translation} 14 | { 15 | No~ translation~ provided~ for~ key~ `#1'~ in~ language~ `#2'~ 16 | \msg_line_context: . 17 | } 18 | 19 | % -------------------------------------------------------------------------- 20 | 21 | \bool_new:N \l__xsim_language_auto_bool 22 | \bool_set_true:N \l__xsim_language_auto_bool 23 | % this token list will hold the chosen language for xsim; since the 24 | % language is either chosen automatically or by option it is only available at 25 | % begin document 26 | \tl_new:N \l_xsim_language_tl 27 | \tl_set:Nn \l_xsim_language_tl {english} 28 | \tl_new:N \l__xsim_current_language_tl 29 | 30 | \tl_const:Nn \c__xsim_keyword_prefix_tl {xsim-keyword-} 31 | 32 | % ---------------------------------------------------------------------------- 33 | 34 | \prop_new:N \g_xsim_translations_prop 35 | 36 | % translate the key #1 37 | \cs_new:Npn \xsim_translate:n #1 38 | { 39 | \bool_if:NTF \l__xsim_language_auto_bool 40 | { \GetTranslation { \c__xsim_keyword_prefix_tl #1 } } 41 | { 42 | \GetTranslationFor 43 | { \l_xsim_language_tl } 44 | { \c__xsim_keyword_prefix_tl #1 } 45 | } 46 | } 47 | 48 | \xsim_at_begin_document:n 49 | { 50 | \bool_if:NTF \l__xsim_language_auto_bool 51 | { 52 | \tl_set:Nx \l_xsim_language_tl 53 | { \@trnslt@language{\@trnslt@current@language} } 54 | } 55 | { 56 | \tl_set_eq:NN 57 | \l_xsim_language_tl 58 | \l__xsim_current_language_tl 59 | } 60 | } 61 | 62 | % ---------------------------------------------------------------------------- 63 | % #1: language 64 | % #2: keyword 65 | % #3: translation 66 | \cs_new_protected:Npn \xsim_declare_translation:nnn #1#2#3 67 | { 68 | \xsim_verbose:n 69 | { Declaring~ `#1'~ tranlation~ of~ `#2':~ `#3'. } 70 | \declaretranslation 71 | {#1} 72 | { \c__xsim_keyword_prefix_tl #2 } 73 | {#3} 74 | \prop_gput:Nnn \g_xsim_translations_prop {#2(#1)} {#3} 75 | } 76 | \cs_generate_variant:Nn \xsim_declare_translation:nnn {V,VnV} 77 | 78 | % #1: key 79 | % #2: csv list: { = , = } 80 | \cs_new_protected:Npn \xsim_declare_translations:nn #1#2 81 | { 82 | \cs_set_protected:Npn \__xsim_declare_translation:n ##1 83 | { \msg_warning:nnnn {xsim} {empty-translation} {#1} {##1} } 84 | \cs_set_protected:Npn \__xsim_declare_translation:nn ##1##2 85 | { \xsim_declare_translation:nnn {##1} {#1} {##2} } 86 | \keyval_parse:NNn 87 | \__xsim_declare_translation:n 88 | \__xsim_declare_translation:nn 89 | {#2} 90 | } 91 | 92 | \cs_new:Npn \__xsim_parse_translate_list_entry:nnn #1#2#3 {} 93 | 94 | \cs_new_protected:Npn \__xsim_parse_translate_list_entry:www #1(#2)\q_mark#3\q_stop 95 | { \__xsim_parse_translate_list_entry:nnn {#1} {#2} {#3} } 96 | 97 | \cs_new_protected:Npn \xsim_for_all_translations_do:n #1 98 | { 99 | \cs_set:Npn \__xsim_parse_translate_list_entry:nnn ##1##2##3 {#1} 100 | \prop_map_inline:Nn \g_xsim_translations_prop 101 | { \__xsim_parse_translate_list_entry:www ##1 \q_mark ##2 \q_stop } 102 | } 103 | 104 | % ---------------------------------------------------------------------------- 105 | 106 | \keys_define:nn {xsim} 107 | { 108 | language .value_required:n = true , 109 | language .code:n = 110 | \tl_if_eq:nnTF {#1} {auto} 111 | { \bool_set_true:N \l__xsim_language_auto_bool } 112 | { 113 | \bool_set_false:N \l__xsim_language_auto_bool 114 | \tl_set:Nn \l__xsim_current_language_tl {#1} 115 | } , 116 | language .initial:n = auto 117 | } 118 | 119 | \XSIMmoduleend 120 | -------------------------------------------------------------------------------- /code/xsim.verbwrite.code.tex: -------------------------------------------------------------------------------- 1 | \XSIMmodule{verbwrite}{write contents of environments verbatim to files} 2 | 3 | \int_new:N \l__xsimverb_tmpa_int 4 | \tl_new:N \l__xsimverb_tmpa_tl 5 | 6 | \iow_new:N \l__xsim_file_contents_iow 7 | \tl_new:N \l_xsim_file_begin_tl 8 | \tl_new:N \l_xsim_file_end_tl 9 | \int_new:N \l_xsim_line_gobble_int 10 | \int_zero:N \l_xsim_line_gobble_int 11 | 12 | \tl_const:Nx \c__xsim_backslash_char_tl { \cs_to_str:N \\ } 13 | 14 | \group_begin: 15 | \char_set_catcode_other:n {37} 16 | \tl_const:Nn \c__xsim_percent_char_tl {%} 17 | \group_end: 18 | 19 | % ---------------------------------------------------------------------------- 20 | \bool_new:N \l__xsim_stream_open_bool 21 | % the `final' option will prevent writing to files: 22 | % #1: write stream 23 | % #2: file name 24 | \cs_new_protected:Npn \__xsim_open_stream:Nn #1#2 25 | { 26 | \file_if_exist:nTF {#2} 27 | { 28 | \xsim_if_final:F 29 | { 30 | \bool_set_true:N \l__xsim_stream_open_bool 31 | \iow_open:Nn #1 {#2} 32 | } 33 | } 34 | { 35 | \bool_set_true:N \l__xsim_stream_open_bool 36 | \iow_open:Nn #1 {#2} 37 | } 38 | } 39 | 40 | % #1: write stream 41 | \cs_new_protected:Npn \__xsim_close_stream:N #1 42 | { \bool_if:NT \l__xsim_stream_open_bool { \iow_close:N #1 } } 43 | 44 | % #1: write stream 45 | % #2: contents 46 | \cs_new_protected:Npn \__xsim_write_to_stream:Nn #1#2 47 | { 48 | \xsim_if_final:F 49 | { 50 | % remove the /one/ space token with catcode 10 that is inserted if 51 | % no options are given to the surrounding environment: 52 | \tl_set:Nn \l__xsimverb_tmpa_tl {#2} 53 | \tl_remove_once:Nn \l__xsimverb_tmpa_tl {~} 54 | % \tl_show:N \l__xsimverb_tmpa_tl 55 | % \int_show:n { \tl_count:N \l__xsimverb_tmpa_tl } 56 | % \tl_analysis_show:N \l__xsimverb_tmpa_tl 57 | \int_zero:N \l__xsimverb_tmpa_int 58 | \int_while_do:nn { \l__xsimverb_tmpa_int < \l_xsim_line_gobble_int } 59 | { 60 | \int_incr:N \l__xsimverb_tmpa_int 61 | \tl_set:Nx \l__xsimverb_tmpa_tl { \tl_tail:N \l__xsimverb_tmpa_tl } 62 | } 63 | \iow_now:NV #1 \l__xsimverb_tmpa_tl 64 | } 65 | } 66 | \cs_generate_variant:Nn \__xsim_write_to_stream:Nn {Nx} 67 | \cs_generate_variant:Nn \iow_now:Nn {NV} 68 | 69 | \cs_new:Npn \__xsim_tab: { \c_space_tl \c_space_tl } 70 | \cs_new:Npn \__xsim_par: { ^^J ^^J } 71 | 72 | % the following is inspired by the definition of the `filecontents' 73 | % environment: 74 | % #1: boolean - if true an active eol needs to be inserted before 75 | % starting to write 76 | % #2: file name 77 | \cs_new_protected:Npn \xsim_file_write_start:nn #1#2 78 | { 79 | % we need to insert an active ^^M if no options are given 80 | % see http://tex.stackexchange.com/q/9035/5049 reasons 81 | \use:nx 82 | { \__xsim_file_write_start:n {#2} } 83 | { \bool_if:nF {#1} { \exp_not:V \c__xsim_active_eol_tl } } 84 | } 85 | \cs_generate_variant:Nn \xsim_file_write_start:nn {nV} 86 | \cs_generate_variant:Nn \use:nn {nx} 87 | 88 | \cs_new_protected:Npn \__xsim_set_verb_catcodes: 89 | { 90 | \seq_map_inline:Nn \l_char_special_seq 91 | { \char_set_catcode_other:N ##1 } 92 | \int_step_inline:nnnn {128} {1} {255} 93 | { \char_set_catcode_letter:n {##1} } 94 | } 95 | 96 | \group_begin: 97 | \char_set_catcode_active:n {13} % ^^M (carriage return, endlinechar) 98 | \char_set_catcode_active:n {12} % ^^L (form feed) 99 | \char_set_catcode_active:n {9} % ^^I (horizontal tab) 100 | % 101 | \tl_const:Nn \c__xsim_active_eol_tl {^^M} % 102 | % 103 | % #1: file name 104 | \cs_new_protected:Npn \__xsim_file_write_start:n #1 % 105 | { % 106 | \group_begin: % 107 | \xsim_if_final:TF % 108 | { \xsim_verbose:x { Not~ (re-)writing~ file~ `#1'. } } % 109 | { \xsim_verbose:x { (Re-)writing~ file~ `#1'. } } % 110 | \__xsim_open_stream:Nn \l__xsim_file_contents_iow {#1} % 111 | \tl_if_blank:VF \l_xsim_file_begin_tl % 112 | { % 113 | \xsim_if_final:F % 114 | { % 115 | \iow_now:Nx \l__xsim_file_contents_iow % 116 | { \exp_not:V \l_xsim_file_begin_tl } % 117 | } % 118 | } % 119 | \__xsim_set_verb_catcodes: % 120 | \tl_set:Nx \l__xsimverb_tmpa_tl % 121 | { \c__xsim_backslash_char_tl end \cs_to_str:N \{ \@currenvir \cs_to_str:N \} } % 122 | \use:x % 123 | { % 124 | \cs_set:cpn {__xsim_tmpa:www} % 125 | ####1 \l__xsimverb_tmpa_tl % 126 | ####2 \l__xsimverb_tmpa_tl % 127 | ####3 \exp_not:N \q_stop: % 128 | } % 129 | { % 130 | \tl_if_blank:nTF {##3} % 131 | { \__xsim_write_to_stream:Nn \l__xsim_file_contents_iow {##1} } % 132 | { % 133 | \cs_set:Npx \__xsim_M:w { \exp_not:N \end {\@currenvir} } % 134 | \char_set_active_eq:nN {13} \__xsim_M:w % 135 | % the last line is `##1 \end{\@currenvir} ##2': 136 | \tl_if_blank:nF {##1} % 137 | { \__xsim_write_to_stream:Nn \l__xsim_file_contents_iow {##1} }% 138 | \tl_if_blank:nF {##2} % 139 | {} % 140 | } % 141 | ^^M % 142 | } % 143 | \char_set_catcode_active:n {13} % 144 | \char_set_catcode_active:n {12} % 145 | \char_set_catcode_active:n {9} % 146 | \cs_set:Npx \__xsim_M:w ##1 ^^M % 147 | { % 148 | \exp_not:N \__xsim_tmpa:www ##1 % 149 | \l__xsimverb_tmpa_tl % 150 | \l__xsimverb_tmpa_tl % 151 | \exp_not:N \q_stop: % 152 | } % 153 | \char_set_active_eq:nN {13} \__xsim_M:w % 154 | \char_set_active_eq:nN {12} \__xsim_par: % 155 | \char_set_active_eq:nN {9} \__xsim_tab: % 156 | } % 157 | \group_end: 158 | 159 | \cs_new_protected:Npn \xsim_file_write_stop: 160 | { 161 | \tl_if_blank:VF \l_xsim_file_end_tl 162 | { 163 | \xsim_if_final:F 164 | { 165 | \iow_now:Nx \l__xsim_file_contents_iow 166 | { \exp_not:V \l_xsim_file_end_tl } 167 | } 168 | } 169 | \__xsim_close_stream:N \l__xsim_file_contents_iow 170 | \group_end: 171 | } 172 | 173 | % ---------------------------------------------------------------------------- 174 | \cs_generate_variant:Nn \tl_set:Nn {Ne} 175 | 176 | \NewDocumentCommand \XSIMfilewritestart {sm} 177 | { 178 | \IfBooleanTF {#1} 179 | { \xsim_file_write_start:nn { \c_false_bool } {#2} } 180 | { \xsim_file_write_start:nn { \c_true_bool } {#2} } 181 | } 182 | 183 | \NewDocumentCommand \XSIMfilewritestop {} 184 | { \xsim_file_write_stop: } 185 | 186 | \NewDocumentCommand \XSIMsetfilebegin {+m} 187 | { \tl_set:Nn \l_xsim_file_begin_tl {#1} } 188 | 189 | \NewDocumentCommand \XSIMsetfilebeginX {+m} 190 | { \tl_set:Ne \l_xsim_file_begin_tl {#1} } 191 | 192 | \NewDocumentCommand \XSIMsetfileend {+m} 193 | { \tl_set:Nn \l_xsim_file_end_tl {#1} } 194 | 195 | \NewDocumentCommand \XSIMsetfileendX {+m} 196 | { \tl_set:Ne \l_xsim_file_end_tl {#1} } 197 | 198 | \NewDocumentCommand \XSIMgobblechars {m} 199 | { \int_set:Nn \l_xsim_line_gobble_int {#1} } 200 | 201 | \XSIMmoduleend 202 | -------------------------------------------------------------------------------- /code/xsimverb.start.code.tex: -------------------------------------------------------------------------------- 1 | % ---------------------------------------------------------------------------- 2 | % the XSIMVERB package 3 | % 4 | % write environments verbatim to files 5 | % 6 | % ---------------------------------------------------------------------------- 7 | % Clemens Niederberger 8 | % Web: https://github.com/cgnieder/xsim 9 | % E-Mail: clemens@cnltx.de 10 | % ---------------------------------------------------------------------------- 11 | % Copyright 2017--2022 Clemens Niederberger 12 | % 13 | % This work may be distributed and/or modified under the 14 | % conditions of the LaTeX Project Public License, either version 1.3c 15 | % of this license or (at your option) any later version. 16 | % The latest version of this license is in 17 | % http://www.latex-project.org/lppl.txt 18 | % and version 1.3c or later is part of all distributions of LaTeX 19 | % version 2008/05/04 or later. 20 | % 21 | % This work has the LPPL maintenance status `maintained'. 22 | % 23 | % The Current Maintainer of this work is Clemens Niederberger. 24 | % ---------------------------------------------------------------------------- 25 | % If you have any ideas, questions, suggestions or bugs to report, please 26 | % feel free to contact me. 27 | % ---------------------------------------------------------------------------- 28 | \RequirePackage {l3keys2e} 29 | \ExplSyntaxOn 30 | 31 | \tl_const:Nn \c_xsimverb_date_tl {2022/02/12} 32 | \tl_const:Nn \c_xsimverb_version_major_number_tl {0} 33 | \tl_const:Nn \c_xsimverb_version_minor_number_tl {4} 34 | \tl_const:Nn \c_xsimverb_version_subrelease_tl {} 35 | \tl_const:Nx \c_xsimverb_version_number_tl 36 | { 37 | \c_xsimverb_version_major_number_tl . 38 | \c_xsimverb_version_minor_number_tl 39 | } 40 | \tl_const:Nx \c_xsimverb_version_tl 41 | { 42 | \c_xsimverb_version_number_tl 43 | \c_xsimverb_version_subrelease_tl 44 | } 45 | \tl_const:Nn \c_xsimverb_info_tl {write~ environments~ verbatim~ to~ files} 46 | 47 | \ProvidesExplPackage 48 | {xsimverb} 49 | {\c_xsimverb_date_tl} 50 | {\c_xsimverb_version_tl} 51 | {\c_xsimverb_info_tl} 52 | 53 | % options, information 54 | 55 | \cs_new_protected:Npn \xsimverb_bool_provide:N #1 56 | { \bool_if_exist:NF #1 { \bool_new:N #1 } } 57 | 58 | \xsimverb_bool_provide:N \g__xsim_final_bool 59 | \xsimverb_bool_provide:N \g__xsim_verbose_bool 60 | \xsimverb_bool_provide:N \g_xsim_clear_aux_bool 61 | \xsimverb_bool_provide:N \g__xsim_write_to_file_bool 62 | \xsimverb_bool_provide:N \g_xsim_use_aux_bool 63 | \xsimverb_bool_provide:N \g__xsim_rerun_bool 64 | \xsimverb_bool_provide:N \g__xsim_debug_bool 65 | \xsimverb_bool_provide:N \g__xsim_blank_bool 66 | 67 | \keys_define:nn {xsimverb} 68 | { 69 | final .bool_gset:N = \g__xsim_final_bool , 70 | verbose .bool_gset:N = \g__xsim_verbose_bool , 71 | debug .bool_gset:N = \g__xsim_debug_bool , 72 | clear-aux .bool_gset:N = \g_xsim_clear_aux_bool , 73 | use-files .bool_gset:N = \g__xsim_write_to_file_bool , 74 | use-files .initial:n = false , 75 | no-files .choice: , 76 | no-files / true .meta:n = { use-files = false } , 77 | no-files / false .meta:n = { use-files = true } , 78 | no-files .default:n = true , 79 | use-aux .bool_gset:N = \g_xsim_use_aux_bool , 80 | use-aux .initial:n = false , 81 | blank .bool_gset:N = \g__xsim_blank_bool , 82 | blank .initial:n = false 83 | } 84 | 85 | \ProcessKeysPackageOptions {xsimverb} 86 | 87 | \cs_if_exist:NF \xsim_if_final:T 88 | { 89 | \prg_new_conditional:Npnn \xsim_if_final: {p,T,F,TF} 90 | { 91 | \bool_if:NTF \g__xsim_final_bool 92 | { \prg_return_true: } 93 | { \prg_return_false: } 94 | } 95 | 96 | \prg_new_conditional:Npnn \xsim_if_verbose: {p,T,F,TF} 97 | { 98 | \bool_if:NTF \g__xsim_verbose_bool 99 | { \prg_return_true: } 100 | { \prg_return_false: } 101 | } 102 | } 103 | 104 | \cs_if_exist:NF \xsim_verbose:n 105 | { 106 | \cs_new_protected:Npn \xsim_verbose:n #1 107 | { \xsim_if_verbose:T { \msg_info:nnn {xsim} {verbose} {#1} } } 108 | \cs_generate_variant:Nn \xsim_verbose:n {x} 109 | } 110 | 111 | % -------------------------------------------------------------------------- 112 | % #1: name 113 | % #2: description 114 | \cs_set_protected:Npn \XSIMmodule #1#2 {} 115 | \cs_set_protected:Npn \XSIMmoduleend {} 116 | 117 | % -------------------------------------------------------------------------- 118 | -------------------------------------------------------------------------------- /code/xsimverb.sty: -------------------------------------------------------------------------------- 1 | % ---------------------------------------------------------------------------- 2 | % the XSIMVERB package 3 | % 4 | % write environments verbatim to files 5 | % 6 | % ---------------------------------------------------------------------------- 7 | % Clemens Niederberger 8 | % Web: https://github.com/cgnieder/xsim 9 | % E-Mail: clemens@cnltx.de 10 | % ---------------------------------------------------------------------------- 11 | % Copyright 2017--2022 Clemens Niederberger 12 | % 13 | % This work may be distributed and/or modified under the 14 | % conditions of the LaTeX Project Public License, either version 1.3c 15 | % of this license or (at your option) any later version. 16 | % The latest version of this license is in 17 | % http://www.latex-project.org/lppl.txt 18 | % and version 1.3c or later is part of all distributions of LaTeX 19 | % version 2008/05/04 or later. 20 | % 21 | % This work has the LPPL maintenance status `maintained'. 22 | % 23 | % The Current Maintainer of this work is Clemens Niederberger. 24 | % ---------------------------------------------------------------------------- 25 | % If you have any ideas, questions, suggestions or bugs to report, please 26 | % feel free to contact me. 27 | % ---------------------------------------------------------------------------- 28 | \RequirePackage {l3keys2e} 29 | \ExplSyntaxOn 30 | 31 | \tl_const:Nn \c_xsimverb_date_tl {2022/02/12} 32 | \tl_const:Nn \c_xsimverb_version_major_number_tl {0} 33 | \tl_const:Nn \c_xsimverb_version_minor_number_tl {4} 34 | \tl_const:Nn \c_xsimverb_version_subrelease_tl {} 35 | \tl_const:Nx \c_xsimverb_version_number_tl 36 | { 37 | \c_xsimverb_version_major_number_tl . 38 | \c_xsimverb_version_minor_number_tl 39 | } 40 | \tl_const:Nx \c_xsimverb_version_tl 41 | { 42 | \c_xsimverb_version_number_tl 43 | \c_xsimverb_version_subrelease_tl 44 | } 45 | \tl_const:Nn \c_xsimverb_info_tl {write~ environments~ verbatim~ to~ files} 46 | 47 | \ProvidesExplPackage 48 | {xsimverb} 49 | {\c_xsimverb_date_tl} 50 | {\c_xsimverb_version_tl} 51 | {\c_xsimverb_info_tl} 52 | 53 | % options, information 54 | 55 | \cs_new_protected:Npn \xsimverb_bool_provide:N #1 56 | { \bool_if_exist:NF #1 { \bool_new:N #1 } } 57 | 58 | \xsimverb_bool_provide:N \g__xsim_final_bool 59 | \xsimverb_bool_provide:N \g__xsim_verbose_bool 60 | \xsimverb_bool_provide:N \g_xsim_clear_aux_bool 61 | \xsimverb_bool_provide:N \g__xsim_write_to_file_bool 62 | \xsimverb_bool_provide:N \g_xsim_use_aux_bool 63 | \xsimverb_bool_provide:N \g__xsim_rerun_bool 64 | \xsimverb_bool_provide:N \g__xsim_debug_bool 65 | \xsimverb_bool_provide:N \g__xsim_blank_bool 66 | 67 | \keys_define:nn {xsimverb} 68 | { 69 | final .bool_gset:N = \g__xsim_final_bool , 70 | verbose .bool_gset:N = \g__xsim_verbose_bool , 71 | debug .bool_gset:N = \g__xsim_debug_bool , 72 | clear-aux .bool_gset:N = \g_xsim_clear_aux_bool , 73 | use-files .bool_gset:N = \g__xsim_write_to_file_bool , 74 | use-files .initial:n = false , 75 | no-files .choice: , 76 | no-files / true .meta:n = { use-files = false } , 77 | no-files / false .meta:n = { use-files = true } , 78 | no-files .default:n = true , 79 | use-aux .bool_gset:N = \g_xsim_use_aux_bool , 80 | use-aux .initial:n = false , 81 | blank .bool_gset:N = \g__xsim_blank_bool , 82 | blank .initial:n = false 83 | } 84 | 85 | \ProcessKeysPackageOptions {xsimverb} 86 | 87 | \cs_if_exist:NF \xsim_if_final:T 88 | { 89 | \prg_new_conditional:Npnn \xsim_if_final: {p,T,F,TF} 90 | { 91 | \bool_if:NTF \g__xsim_final_bool 92 | { \prg_return_true: } 93 | { \prg_return_false: } 94 | } 95 | 96 | \prg_new_conditional:Npnn \xsim_if_verbose: {p,T,F,TF} 97 | { 98 | \bool_if:NTF \g__xsim_verbose_bool 99 | { \prg_return_true: } 100 | { \prg_return_false: } 101 | } 102 | } 103 | 104 | \cs_if_exist:NF \xsim_verbose:n 105 | { 106 | \cs_new_protected:Npn \xsim_verbose:n #1 107 | { \xsim_if_verbose:T { \msg_info:nnn {xsim} {verbose} {#1} } } 108 | \cs_generate_variant:Nn \xsim_verbose:n {x} 109 | } 110 | 111 | % -------------------------------------------------------------------------- 112 | % #1: name 113 | % #2: description 114 | \cs_set_protected:Npn \XSIMmodule #1#2 {} 115 | \cs_set_protected:Npn \XSIMmoduleend {} 116 | 117 | % -------------------------------------------------------------------------- 118 | \XSIMmodule{verbwrite}{write contents of environments verbatim to files} 119 | 120 | \int_new:N \l__xsimverb_tmpa_int 121 | \tl_new:N \l__xsimverb_tmpa_tl 122 | 123 | \iow_new:N \l__xsim_file_contents_iow 124 | \tl_new:N \l_xsim_file_begin_tl 125 | \tl_new:N \l_xsim_file_end_tl 126 | \int_new:N \l_xsim_line_gobble_int 127 | \int_zero:N \l_xsim_line_gobble_int 128 | 129 | \tl_const:Nx \c__xsim_backslash_char_tl { \cs_to_str:N \\ } 130 | 131 | \group_begin: 132 | \char_set_catcode_other:n {37} 133 | \tl_const:Nn \c__xsim_percent_char_tl {%} 134 | \group_end: 135 | 136 | % ---------------------------------------------------------------------------- 137 | \bool_new:N \l__xsim_stream_open_bool 138 | % the `final' option will prevent writing to files: 139 | % #1: write stream 140 | % #2: file name 141 | \cs_new_protected:Npn \__xsim_open_stream:Nn #1#2 142 | { 143 | \file_if_exist:nTF {#2} 144 | { 145 | \xsim_if_final:F 146 | { 147 | \bool_set_true:N \l__xsim_stream_open_bool 148 | \iow_open:Nn #1 {#2} 149 | } 150 | } 151 | { 152 | \bool_set_true:N \l__xsim_stream_open_bool 153 | \iow_open:Nn #1 {#2} 154 | } 155 | } 156 | 157 | % #1: write stream 158 | \cs_new_protected:Npn \__xsim_close_stream:N #1 159 | { \bool_if:NT \l__xsim_stream_open_bool { \iow_close:N #1 } } 160 | 161 | % #1: write stream 162 | % #2: contents 163 | \cs_new_protected:Npn \__xsim_write_to_stream:Nn #1#2 164 | { 165 | \xsim_if_final:F 166 | { 167 | % remove the /one/ space token with catcode 10 that is inserted if 168 | % no options are given to the surrounding environment: 169 | \tl_set:Nn \l__xsimverb_tmpa_tl {#2} 170 | \tl_remove_once:Nn \l__xsimverb_tmpa_tl {~} 171 | % \tl_show:N \l__xsimverb_tmpa_tl 172 | % \int_show:n { \tl_count:N \l__xsimverb_tmpa_tl } 173 | % \tl_analysis_show:N \l__xsimverb_tmpa_tl 174 | \int_zero:N \l__xsimverb_tmpa_int 175 | \int_while_do:nn { \l__xsimverb_tmpa_int < \l_xsim_line_gobble_int } 176 | { 177 | \int_incr:N \l__xsimverb_tmpa_int 178 | \tl_set:Nx \l__xsimverb_tmpa_tl { \tl_tail:N \l__xsimverb_tmpa_tl } 179 | } 180 | \iow_now:NV #1 \l__xsimverb_tmpa_tl 181 | } 182 | } 183 | \cs_generate_variant:Nn \__xsim_write_to_stream:Nn {Nx} 184 | \cs_generate_variant:Nn \iow_now:Nn {NV} 185 | 186 | \cs_new:Npn \__xsim_tab: { \c_space_tl \c_space_tl } 187 | \cs_new:Npn \__xsim_par: { ^^J ^^J } 188 | 189 | % the following is inspired by the definition of the `filecontents' 190 | % environment: 191 | % #1: boolean - if true an active eol needs to be inserted before 192 | % starting to write 193 | % #2: file name 194 | \cs_new_protected:Npn \xsim_file_write_start:nn #1#2 195 | { 196 | % we need to insert an active ^^M if no options are given 197 | % see http://tex.stackexchange.com/q/9035/5049 reasons 198 | \use:nx 199 | { \__xsim_file_write_start:n {#2} } 200 | { \bool_if:nF {#1} { \exp_not:V \c__xsim_active_eol_tl } } 201 | } 202 | \cs_generate_variant:Nn \xsim_file_write_start:nn {nV} 203 | \cs_generate_variant:Nn \use:nn {nx} 204 | 205 | \cs_new_protected:Npn \__xsim_set_verb_catcodes: 206 | { 207 | \seq_map_inline:Nn \l_char_special_seq 208 | { \char_set_catcode_other:N ##1 } 209 | \int_step_inline:nnnn {128} {1} {255} 210 | { \char_set_catcode_letter:n {##1} } 211 | } 212 | 213 | \group_begin: 214 | \char_set_catcode_active:n {13} % ^^M (carriage return, endlinechar) 215 | \char_set_catcode_active:n {12} % ^^L (form feed) 216 | \char_set_catcode_active:n {9} % ^^I (horizontal tab) 217 | % 218 | \tl_const:Nn \c__xsim_active_eol_tl {^^M} % 219 | % 220 | % #1: file name 221 | \cs_new_protected:Npn \__xsim_file_write_start:n #1 % 222 | { % 223 | \group_begin: % 224 | \xsim_if_final:TF % 225 | { \xsim_verbose:x { Not~ (re-)writing~ file~ `#1'. } } % 226 | { \xsim_verbose:x { (Re-)writing~ file~ `#1'. } } % 227 | \__xsim_open_stream:Nn \l__xsim_file_contents_iow {#1} % 228 | \tl_if_blank:VF \l_xsim_file_begin_tl % 229 | { % 230 | \xsim_if_final:F % 231 | { % 232 | \iow_now:Nx \l__xsim_file_contents_iow % 233 | { \exp_not:V \l_xsim_file_begin_tl } % 234 | } % 235 | } % 236 | \__xsim_set_verb_catcodes: % 237 | \tl_set:Nx \l__xsimverb_tmpa_tl % 238 | { \c__xsim_backslash_char_tl end \cs_to_str:N \{ \@currenvir \cs_to_str:N \} } % 239 | \use:x % 240 | { % 241 | \cs_set:cpn {__xsim_tmpa:www} % 242 | ####1 \l__xsimverb_tmpa_tl % 243 | ####2 \l__xsimverb_tmpa_tl % 244 | ####3 \exp_not:N \q_stop: % 245 | } % 246 | { % 247 | \tl_if_blank:nTF {##3} % 248 | { \__xsim_write_to_stream:Nn \l__xsim_file_contents_iow {##1} } % 249 | { % 250 | \cs_set:Npx \__xsim_M:w { \exp_not:N \end {\@currenvir} } % 251 | \char_set_active_eq:nN {13} \__xsim_M:w % 252 | % the last line is `##1 \end{\@currenvir} ##2': 253 | \tl_if_blank:nF {##1} % 254 | { \__xsim_write_to_stream:Nn \l__xsim_file_contents_iow {##1} }% 255 | \tl_if_blank:nF {##2} % 256 | {} % 257 | } % 258 | ^^M % 259 | } % 260 | \char_set_catcode_active:n {13} % 261 | \char_set_catcode_active:n {12} % 262 | \char_set_catcode_active:n {9} % 263 | \cs_set:Npx \__xsim_M:w ##1 ^^M % 264 | { % 265 | \exp_not:N \__xsim_tmpa:www ##1 % 266 | \l__xsimverb_tmpa_tl % 267 | \l__xsimverb_tmpa_tl % 268 | \exp_not:N \q_stop: % 269 | } % 270 | \char_set_active_eq:nN {13} \__xsim_M:w % 271 | \char_set_active_eq:nN {12} \__xsim_par: % 272 | \char_set_active_eq:nN {9} \__xsim_tab: % 273 | } % 274 | \group_end: 275 | 276 | \cs_new_protected:Npn \xsim_file_write_stop: 277 | { 278 | \tl_if_blank:VF \l_xsim_file_end_tl 279 | { 280 | \xsim_if_final:F 281 | { 282 | \iow_now:Nx \l__xsim_file_contents_iow 283 | { \exp_not:V \l_xsim_file_end_tl } 284 | } 285 | } 286 | \__xsim_close_stream:N \l__xsim_file_contents_iow 287 | \group_end: 288 | } 289 | 290 | % ---------------------------------------------------------------------------- 291 | \cs_generate_variant:Nn \tl_set:Nn {Ne} 292 | 293 | \NewDocumentCommand \XSIMfilewritestart {sm} 294 | { 295 | \IfBooleanTF {#1} 296 | { \xsim_file_write_start:nn { \c_false_bool } {#2} } 297 | { \xsim_file_write_start:nn { \c_true_bool } {#2} } 298 | } 299 | 300 | \NewDocumentCommand \XSIMfilewritestop {} 301 | { \xsim_file_write_stop: } 302 | 303 | \NewDocumentCommand \XSIMsetfilebegin {+m} 304 | { \tl_set:Nn \l_xsim_file_begin_tl {#1} } 305 | 306 | \NewDocumentCommand \XSIMsetfilebeginX {+m} 307 | { \tl_set:Ne \l_xsim_file_begin_tl {#1} } 308 | 309 | \NewDocumentCommand \XSIMsetfileend {+m} 310 | { \tl_set:Nn \l_xsim_file_end_tl {#1} } 311 | 312 | \NewDocumentCommand \XSIMsetfileendX {+m} 313 | { \tl_set:Ne \l_xsim_file_end_tl {#1} } 314 | 315 | \NewDocumentCommand \XSIMgobblechars {m} 316 | { \int_set:Nn \l_xsim_line_gobble_int {#1} } 317 | 318 | \XSIMmoduleend 319 | -------------------------------------------------------------------------------- /doc/examples/xsim.blanks.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgnieder/xsim/06e3dba43b96ed493968ddd54add9fc8a1d9a264/doc/examples/xsim.blanks.pdf -------------------------------------------------------------------------------- /doc/examples/xsim.blanks.tex: -------------------------------------------------------------------------------- 1 | \documentclass{article} 2 | \usepackage[ngerman]{babel} 3 | 4 | \usepackage{xsim,lipsum,xcolor} 5 | 6 | \xsimsetup{ 7 | solution/print = true , 8 | blank/filled-style = \underline{\textcolor{red}{#1}} 9 | } 10 | 11 | \begin{document} 12 | 13 | \begin{exercise}[points=3] 14 | Erklären Sie den Begriff. 15 | 16 | \blank[width=4\linewidth,linespread=1.5]{} 17 | \end{exercise} 18 | \begin{solution} 19 | \blank[width=4\linewidth,linespread=1.5]{Die Lösung hier soll rot sein.} 20 | \end{solution} 21 | 22 | \end{document} 23 | -------------------------------------------------------------------------------- /doc/examples/xsim.boxed-headings.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgnieder/xsim/06e3dba43b96ed493968ddd54add9fc8a1d9a264/doc/examples/xsim.boxed-headings.pdf -------------------------------------------------------------------------------- /doc/examples/xsim.boxed-headings.tex: -------------------------------------------------------------------------------- 1 | \documentclass{article} 2 | 3 | \usepackage{tcolorbox} 4 | \usepackage{xsim} 5 | \usepackage{needspace} 6 | 7 | \DeclareExerciseEnvironmentTemplate{custom} 8 | {% 9 | \Needspace*{5\baselineskip} 10 | \begin{tcolorbox} 11 | \textbf{\XSIMmixedcase{\GetExerciseName}~\GetExerciseProperty{counter}.}% 12 | \GetExercisePropertyT{subtitle}{ \textit{#1}}% 13 | \end{tcolorbox} 14 | \noindent 15 | } 16 | {\vspace{\baselineskip}} 17 | 18 | \xsimsetup{exercise/template = custom} 19 | 20 | \usepackage{lipsum} 21 | 22 | \begin{document} 23 | 24 | \begin{exercise}[subtitle=Foo bar baz] 25 | \lipsum[1] 26 | \end{exercise} 27 | 28 | \lipsum[2] 29 | 30 | \end{document} 31 | -------------------------------------------------------------------------------- /doc/examples/xsim.code-and-output.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgnieder/xsim/06e3dba43b96ed493968ddd54add9fc8a1d9a264/doc/examples/xsim.code-and-output.pdf -------------------------------------------------------------------------------- /doc/examples/xsim.code-and-output.tex: -------------------------------------------------------------------------------- 1 | \documentclass{article} 2 | \usepackage{xsimverb,listings,xcolor} 3 | 4 | \lstdefinestyle{mystyle}{ 5 | language = [AlLaTeX]TeX , 6 | basicstyle = \ttfamily , 7 | columns = fullflexible , 8 | commentstyle = \color{gray!70} , 9 | keywordstyle = \color{red!70!black} 10 | } 11 | 12 | \makeatletter 13 | \NewDocumentEnvironment{example}{!o} 14 | {% 15 | \XSIMgobblechars{2}% 16 | \XSIMsetfilebegin{\@percentchar\space file `\jobname.tmp'}% 17 | \XSIMsetfileend{\@percentchar\space bye bye}% 18 | \IfNoValueTF{#1} 19 | {\XSIMfilewritestart*{\jobname.tmp}} 20 | {\XSIMfilewritestart{\jobname.tmp}}% 21 | } 22 | {% 23 | \XSIMfilewritestop 24 | \lstinputlisting[style=mystyle]{\jobname.tmp}% 25 | \input{\jobname.tmp} 26 | } 27 | 28 | \NewDocumentEnvironment{code}{!o} 29 | {% 30 | \XSIMgobblechars{2}% 31 | \IfNoValueTF{#1} 32 | {\XSIMfilewritestart*{\jobname.tmp}} 33 | {\XSIMfilewritestart{\jobname.tmp}}% 34 | } 35 | {% 36 | \XSIMfilewritestop 37 | \lstinputlisting[style=mystyle]{\jobname.tmp}% 38 | } 39 | \makeatother 40 | 41 | \begin{document} 42 | 43 | \begin{example} 44 | bla bla \LaTeX 45 | \end{example} 46 | 47 | \bigskip 48 | 49 | \begin{code} 50 | blubber \LaTeX 51 | \end{code} 52 | 53 | \end{document} 54 | -------------------------------------------------------------------------------- /doc/examples/xsim.collections.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgnieder/xsim/06e3dba43b96ed493968ddd54add9fc8a1d9a264/doc/examples/xsim.collections.pdf -------------------------------------------------------------------------------- /doc/examples/xsim.collections.tex: -------------------------------------------------------------------------------- 1 | \documentclass{article} 2 | \usepackage{xsim} 3 | \usepackage{lipsum} 4 | 5 | \DeclareExerciseCollection[difficulty=easy]{easy} 6 | \DeclareExerciseCollection[difficulty=medium]{medium} 7 | \DeclareExerciseTagging{difficulty} 8 | 9 | \xsimsetup{collect} 10 | 11 | \begin{document} 12 | 13 | \begin{exercise}[use,print] 14 | outside before 15 | \end{exercise} 16 | 17 | \begin{exercise}[difficulty=easy,points=1] 18 | foo one \lipsum[4] 19 | \end{exercise} 20 | \begin{solution} 21 | foo one \lipsum[4] 22 | \end{solution} 23 | \begin{exercise}[difficulty=medium,points=1] 24 | foo two \lipsum[4] 25 | \end{exercise} 26 | \begin{solution} 27 | foo two \lipsum[4] 28 | \end{solution} 29 | \begin{exercise}[difficulty=easy,points=1] 30 | foo three \lipsum[4] 31 | \end{exercise} 32 | \begin{solution} 33 | foo three \lipsum[4] 34 | \end{solution} 35 | 36 | \section{Easy} 37 | \printcollection{easy} 38 | 39 | \section{Medium} 40 | \printcollection{medium} 41 | 42 | \printsolutions[difficulty=medium] 43 | 44 | \end{document} 45 | -------------------------------------------------------------------------------- /doc/examples/xsim.crossref.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgnieder/xsim/06e3dba43b96ed493968ddd54add9fc8a1d9a264/doc/examples/xsim.crossref.pdf -------------------------------------------------------------------------------- /doc/examples/xsim.crossref.tex: -------------------------------------------------------------------------------- 1 | \documentclass{article} 2 | \usepackage{xsim,lipsum,hyperref} 3 | 4 | \DeclareExerciseHeadingTemplate{custom} 5 | {\section{\XSIMexpandcode{\XSIMtranslate{default-heading}}}} 6 | 7 | \DeclareExerciseEnvironmentTemplate{custom} 8 | {% 9 | \IfInsideSolutionTF 10 | {\label{sol:\ExerciseID}} 11 | {\label{ex:\ExerciseID}} 12 | \subsection* 13 | {% 14 | \XSIMmixedcase{\GetExerciseName}% 15 | \IfInsideSolutionTF 16 | { 17 | to \GetExerciseParameter{exercise-name}% 18 | ~\GetExerciseProperty{counter}% 19 | } 20 | {% 21 | ~\GetExerciseProperty{counter} 22 | \GetExercisePropertyT{subtitle} 23 | { {\normalfont\itshape\PropertyValue}}% 24 | }% 25 | } 26 | \noindent\llap{% 27 | \footnotesize\sffamily 28 | \IfInsideSolutionTF 29 | {% 30 | \XSIMmixedcase{\GetExerciseParameter{exercise-name}} 31 | on page~\pageref{ex:\ExerciseID}.% 32 | } 33 | {% 34 | \XSIMmixedcase{\GetExerciseParameter{solution-name}} 35 | on page~\pageref{sol:\ExerciseID}.% 36 | }% 37 | \hspace*{\marginparsep}% 38 | }% 39 | } 40 | {} 41 | \xsimsetup{ 42 | exercise/template = custom , 43 | solution/template = custom , 44 | print-solutions/headings-template = custom 45 | } 46 | 47 | \begin{document} 48 | 49 | \section{Exercises} 50 | \begin{exercise} 51 | \lipsum[4] 52 | \end{exercise} 53 | \begin{solution} 54 | \lipsum[4] 55 | \end{solution} 56 | 57 | \clearpage 58 | \printsolutions 59 | 60 | \end{document} 61 | -------------------------------------------------------------------------------- /doc/examples/xsim.description-list.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgnieder/xsim/06e3dba43b96ed493968ddd54add9fc8a1d9a264/doc/examples/xsim.description-list.pdf -------------------------------------------------------------------------------- /doc/examples/xsim.description-list.tex: -------------------------------------------------------------------------------- 1 | \documentclass{article} 2 | \usepackage{xsim,lipsum} 3 | 4 | \DeclareExerciseEnvironmentTemplate{item} 5 | {\item[\XSIMmixedcase{\GetExerciseName}~\GetExerciseProperty{counter}]} 6 | {} 7 | \xsimsetup{ 8 | exercise/template=item, 9 | solution/template=item, 10 | print-solutions/headings-template=none 11 | } 12 | 13 | \newenvironment{exercises} 14 | {\section{Exercises}\description} 15 | {\enddescription} 16 | 17 | \newenvironment{solutions} 18 | {\section{Solutions}\description} 19 | {\enddescription} 20 | 21 | \begin{document} 22 | 23 | \begin{exercises} 24 | \begin{exercise} 25 | \lipsum[4] 26 | \end{exercise} 27 | \begin{solution} 28 | \lipsum[3] 29 | \end{solution} 30 | \begin{exercise} 31 | \lipsum[12] 32 | \end{exercise} 33 | \begin{solution} 34 | \lipsum[23] 35 | \end{solution} 36 | \end{exercises} 37 | 38 | \begin{solutions} 39 | \printsolutions 40 | \end{solutions} 41 | 42 | \end{document} 43 | -------------------------------------------------------------------------------- /doc/examples/xsim.different-point-types.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgnieder/xsim/06e3dba43b96ed493968ddd54add9fc8a1d9a264/doc/examples/xsim.different-point-types.pdf -------------------------------------------------------------------------------- /doc/examples/xsim.different-point-types.tex: -------------------------------------------------------------------------------- 1 | \documentclass{article} 2 | \usepackage{xsim} 3 | 4 | \DeclareExerciseGoal{A} 5 | \DeclareExerciseGoal{C} 6 | \DeclareExerciseGoal{E} 7 | 8 | \newcommand*\printA{\TotalExerciseGoal{A}{~A~point}{~A~points}} 9 | \newcommand*\printC{\TotalExerciseGoal{C}{~C~point}{~C~points}} 10 | \newcommand*\printE{\TotalExerciseGoal{E}{~E~point}{~E~points}} 11 | 12 | \usepackage{needspace} 13 | \DeclareExerciseEnvironmentTemplate{custom} 14 | {% 15 | \par\vspace{\baselineskip} 16 | \Needspace*{2\baselineskip} 17 | \noindent 18 | \textbf{\GetExerciseProperty{counter}}% 19 | \IfExercisePropertySetT{subtitle} 20 | { \textit{\GetExerciseProperty{subtitle}}} % 21 | \IfInsideSolutionF{% 22 | \marginpar{% 23 | (\IfExercisePropertySetTF{E}{\GetExerciseProperty{E}}{0}/% 24 | \IfExercisePropertySetTF{C}{\GetExerciseProperty{C}}{0}/% 25 | \IfExercisePropertySetTF{A}{\GetExerciseProperty{A}}{0})% 26 | }% 27 | }% 28 | } 29 | {} 30 | \xsimsetup{ 31 | exercise/template = custom , 32 | solution/template = custom 33 | } 34 | \renewcommand*\theexercise{\arabic{exercise}.} 35 | 36 | \begin{document} 37 | 38 | Reachable: \printA, \printC, and \printE. 39 | 40 | \begin{exercise}[E=1] 41 | Differentiate $y=3x^2+5x+3$. 42 | \end{exercise} 43 | 44 | \begin{exercise}[E=2,C=1] 45 | Find the equation of the tangent line to the function $y=x/2$ at $x=2$. 46 | \end{exercise} 47 | 48 | \begin{exercise}[C=1,A=2] 49 | Prove that the derivative of a constant is zero. 50 | \end{exercise} 51 | 52 | \end{document} 53 | -------------------------------------------------------------------------------- /doc/examples/xsim.difficulties.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgnieder/xsim/06e3dba43b96ed493968ddd54add9fc8a1d9a264/doc/examples/xsim.difficulties.pdf -------------------------------------------------------------------------------- /doc/examples/xsim.difficulties.tex: -------------------------------------------------------------------------------- 1 | \documentclass{article} 2 | 3 | \usepackage[clear-aux]{xsim} 4 | \DeclareExerciseTagging{difficulty} 5 | \xsimsetup{ 6 | difficulty={easy,hard} 7 | } 8 | 9 | \DeclareExerciseEnvironmentTemplate{custom} 10 | { 11 | \subsection* 12 | {% 13 | \XSIMmixedcase {\GetExerciseName}\nobreakspace 14 | \GetExerciseProperty{counter}% 15 | \IfExercisePropertySetT{difficulty} 16 | { {\normalfont(\GetExerciseProperty{difficulty})}}% 17 | \IfInsideSolutionF{% 18 | \IfExercisePropertySetT{subtitle} 19 | { {\normalfont\itshape\GetExerciseProperty{subtitle}}}% 20 | }% 21 | }% 22 | \IfExercisePropertySetT{points} 23 | {% 24 | \marginpar 25 | {% 26 | \IfInsideSolutionF{\rule{1.2cm}{1pt}\slash}% 27 | \GetExerciseProperty{points}% 28 | \IfExercisePropertySetT{bonus-points} 29 | {\nobreakspace(+\GetExerciseProperty{bonus-points})} 30 | \nobreakspace\XSIMtranslate{point-abbr}% 31 | }% 32 | }% 33 | } 34 | {} 35 | 36 | \xsimsetup{exercise/template = custom} 37 | 38 | \begin{document} 39 | 40 | \begin{exercise}[difficulty=easy] 41 | An easy question. 42 | \end{exercise} 43 | \begin{exercise}[difficulty=medium] 44 | This one's a bit harder. 45 | \end{exercise} 46 | \begin{exercise}[difficulty=hard] 47 | Now let’s see if you can solve this one. 48 | \end{exercise} 49 | \begin{exercise}[difficulty=medium] 50 | This is medium but printed anyway 51 | \end{exercise} 52 | 53 | \end{document} 54 | -------------------------------------------------------------------------------- /doc/examples/xsim.floating.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgnieder/xsim/06e3dba43b96ed493968ddd54add9fc8a1d9a264/doc/examples/xsim.floating.pdf -------------------------------------------------------------------------------- /doc/examples/xsim.floating.tex: -------------------------------------------------------------------------------- 1 | % floating exercises: 2 | \documentclass{article} 3 | \usepackage{xsim,newfloat,caption,lipsum} 4 | 5 | \DeclareFloatingEnvironment[ 6 | fileext=loe, 7 | listname={List of Exercises}, 8 | name=Exercise, 9 | placement=htp, 10 | ]{ex} 11 | 12 | \DeclareExerciseEnvironmentTemplate{float} 13 | {% 14 | \ex 15 | \captionsetup{labelformat=empty,singlelinecheck=false,listformat=empty} 16 | \IfExercisePropertySetTF{subtitle}{% 17 | \XSIMexpandcode{% 18 | \noexpand\caption{% 19 | \noexpand\textbf{% 20 | \XSIMmixedcase{\GetExerciseName}\nobreakspace 21 | \GetExerciseProperty{counter}% 22 | }: \GetExerciseProperty{subtitle}% 23 | }% 24 | }% 25 | }{% 26 | \caption{% 27 | \textbf{% 28 | \XSIMmixedcase{\GetExerciseName}\nobreakspace 29 | \GetExerciseProperty{counter}% 30 | }% 31 | }% 32 | }% 33 | } 34 | {\endex} 35 | 36 | \xsimsetup{exercise/template = float} 37 | 38 | \begin{document} 39 | 40 | \listofexs 41 | 42 | \begin{exercise} 43 | \lipsum[4] 44 | \end{exercise} 45 | 46 | \begin{exercise}[subtitle=Let's have a look] 47 | \lipsum[4] 48 | \end{exercise} 49 | 50 | \end{document} 51 | -------------------------------------------------------------------------------- /doc/examples/xsim.golatex-80640.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgnieder/xsim/06e3dba43b96ed493968ddd54add9fc8a1d9a264/doc/examples/xsim.golatex-80640.pdf -------------------------------------------------------------------------------- /doc/examples/xsim.golatex-80640.tex: -------------------------------------------------------------------------------- 1 | % http://golatex.de/viewtopic,p,80640.html 2 | \documentclass[fontsize=12pt,parskip=half]{scrartcl} 3 | \usepackage[T1]{fontenc} 4 | \usepackage[ngerman]{babel} 5 | 6 | \newlength\breite 7 | \setlength\breite{160mm} 8 | \newlength\hoehe 9 | \setlength\hoehe{80mm} 10 | 11 | \usepackage[ 12 | hdivide={3.0cm,\breite,}, 13 | vdivide={2.2cm,,2.2cm}]{geometry} 14 | \usepackage[bitstream-charter]{mathdesign} 15 | 16 | \usepackage[babel]{microtype} 17 | 18 | \usepackage[inline]{enumitem} 19 | 20 | \usepackage{amsmath,siunitx} 21 | \sisetup{ 22 | locale = DE , 23 | per-mode = fraction 24 | } 25 | 26 | \usepackage{xsim,needspace,tikz,tcolorbox} 27 | 28 | \xsimsetup{ 29 | exercise/template = gitter , 30 | solution/template = gitter 31 | } 32 | 33 | \DeclareExerciseEnvironmentTemplate{gitter} 34 | {% 35 | \IfInsideSolutionT{% 36 | \tcolorbox[ 37 | detach title , 38 | title = Lösung: , 39 | before upper = {\tcbtitle\space} , 40 | fonttitle = \bfseries , 41 | fontupper = \large , 42 | valign = center , 43 | colframe = black!50!white , 44 | colback = black!12!white , 45 | coltext = blue , 46 | coltitle = blue , 47 | height = \hoehe , 48 | width = \breite , 49 | sharp corners 50 | ] 51 | }% 52 | } 53 | {% 54 | \IfInsideSolutionTF 55 | {\endtcolorbox} 56 | {% 57 | \IfSolutionPrintF{% 58 | \par 59 | \begin{tikzpicture}[semitransparent] 60 | \draw[step=4mm, line width=0.15mm, black!60!white] (0,0) grid 61 | (\breite,\hoehe); 62 | \end{tikzpicture} 63 | \par 64 | } 65 | }% 66 | } 67 | 68 | \begin{document} 69 | 70 | \begin{exercise} 71 | Für die \textbf{Schülerausgabe} sollen Häuschen (Grid) mit Seitenlänge 72 | \SI{4}{\mm} gesetzt werden. 73 | \end{exercise} 74 | \begin{solution} 75 | Hier soll die Lösung stehen: $E=m\cdot c^2$. 76 | \end{solution} 77 | 78 | \xsimsetup{solution/print=true} 79 | 80 | \begin{exercise} 81 | Für die \textbf{Lehrerausgabe} sollen statt Häuschen die Lösung in 82 | z.\,B. einer Box geschrieben werden. Dafür soll die Lösung (bezogen auf 83 | dieses Beispiel) auch in einer Box mit der exakten Breite \SI{160}{\mm} und 84 | der exakten Höhe \SI{80}{\mm} gesetzt werden. Weiter soll natürlich die 85 | Position der Lösungsbox und der Häuschenbox exakt identisch sein. 86 | \end{exercise} 87 | \begin{solution} 88 | Hier soll die Lösung stehen: $E=m\cdot c^2$. 89 | \end{solution} 90 | 91 | \clearpage 92 | 93 | \begin{exercise} 94 | Beschreiben Sie die \textbf{Satzgruppe des Pythagoras}. 95 | \end{exercise} 96 | \begin{solution} 97 | \begin{align*} 98 | \left.\begin{aligned} 99 | c^2 &=a^2+b^2\\ 100 | a^2 &=p\cdot c\;\wedge\; b^2=q\cdot c\\ 101 | h^2 &=p\cdot q 102 | \end{aligned}\right\} 103 | \begin{gathered} 104 | \text{Satzgruppe}\\ 105 | \text{des Pythagoras} 106 | \end{gathered} 107 | \end{align*} 108 | \end{solution} 109 | 110 | \begin{exercise} 111 | Geben Sie die Formel der \textbf{gleichförmigen Bewegung} wieder. Gehen Sie 112 | davon aus, dass Sie 1000~Meter in 113 | \SI[parse-numbers=false]{3\frac{1}{2}}{Minuten} laufen. 114 | \begin{enumerate*}[label=\bfseries\alph*)] 115 | \item Mit welcher Geschwindigkeit legen Sie die Strecke zurück? 116 | \item Geben Sie die Geschwindigkeit in \si{\km\per\hour} an. 117 | \end{enumerate*} 118 | \textbf{Hinweis:} Nehmen Sie zur Berechnung die vereinfachte Form und gehen 119 | Sie davon aus, dass Ihre Geschwindigkeit konstant ist. 120 | \end{exercise} 121 | \begin{solution} 122 | \begin{align*} 123 | s &=v\cdot t+s_0 \\ 124 | 1000 &=v\cdot 210 \\ 125 | v &=\frac{\SI{1000}{\m}}{\SI{210}{\second}} \\ 126 | v &=\SI{4.76}{\m\per\second} = \SI{17.1}{\km\per\hour} 127 | \end{align*} 128 | \end{solution} 129 | 130 | \end{document} 131 | -------------------------------------------------------------------------------- /doc/examples/xsim.golatex-91339.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgnieder/xsim/06e3dba43b96ed493968ddd54add9fc8a1d9a264/doc/examples/xsim.golatex-91339.pdf -------------------------------------------------------------------------------- /doc/examples/xsim.golatex-91339.tex: -------------------------------------------------------------------------------- 1 | % http://golatex.de/viewtopic,p,91339.html 2 | \documentclass[a4paper]{article} 3 | \usepackage[ngerman]{babel} 4 | 5 | \usepackage{xsim,tcolorbox} 6 | \usepackage{amsmath} 7 | \xsimsetup{ 8 | exercise/within = section , 9 | exercise/the-counter = \thesection.\arabic{exercise} , 10 | print-solutions/headings-template=none 11 | } 12 | \SetExerciseParameters{exercise}{ 13 | exercise-template = mine , 14 | solution-template = mine 15 | } 16 | 17 | \DeclareExerciseEnvironmentTemplate{mine} 18 | {% 19 | \tcolorbox[ 20 | % colors: 21 | colback = white , colframe = black , coltitle = black , 22 | % rules: 23 | boxrule = 0pt , toprule = 1pt , bottomrule = 1pt , arc = 0pt , 24 | % spacing: 25 | boxsep = 0pt , left = 0pt , right = 0pt , 26 | % title: 27 | detach title , before upper = \tcbtitle\par\noindent , 28 | fonttitle = \bfseries , 29 | title = \XSIMmixedcase{\GetExerciseName}~\GetExerciseProperty{counter} 30 | ] 31 | } 32 | {\endtcolorbox} 33 | 34 | \DeclareExerciseTranslation{German}{exercise}{Aufgabe} 35 | \DeclareExerciseTagging{difficulty} 36 | 37 | \begin{document} 38 | 39 | \section{Wellenausbreitung im Vakuum und in Materie} 40 | \subsection{Maxwellsche Gleichungen} 41 | 42 | \begin{align*} 43 | \nabla \cdot \vec{E}\left(\vec{r}, t \right) = 44 | \frac{\varrho\left(\vec{r}, t \right)}{\varepsilon_0} 45 | \end{align*} 46 | 47 | \begin{exercise}[difficulty=easy] 48 | Something stupid 49 | \end{exercise} 50 | \begin{solution} 51 | Here is a nonstupid solution for your problem 52 | \end{solution} 53 | 54 | \subsection{Empirischer Zugang zu Wellengleichungen} 55 | 56 | \begin{exercise}[difficulty=hard] 57 | Eine weitere Aufgabe 58 | \end{exercise} 59 | \begin{solution} 60 | Solution Number 2 61 | \end{solution} 62 | 63 | \subsection*{Lösungen} 64 | \printsolutions[section,difficulty=hard] 65 | 66 | \section{Wellenausbreitung im Vakuum und in Materie} 67 | \subsection{Maxwellsche Gleichungen} 68 | 69 | \begin{align*} 70 | \nabla \cdot \vec{E}\left(\vec{r}, t \right) = 71 | \frac{\varrho\left(\vec{r}, t \right)}{\varepsilon_0} 72 | \end{align*} 73 | 74 | \begin{exercise}[difficulty=easy] 75 | Something stupid 76 | \end{exercise} 77 | \begin{solution} 78 | Here is a nonstupid solution for your problem 79 | \end{solution} 80 | 81 | \subsection{Empirischer Zugang zu Wellengleichungen} 82 | 83 | \begin{exercise}[difficulty=hard] 84 | Eine weitere Aufgabe 85 | \end{exercise} 86 | \begin{solution} 87 | Solution Number 2 88 | \end{solution} 89 | 90 | \subsection*{Lösungen} 91 | \printsolutions[section] 92 | 93 | \end{document} 94 | -------------------------------------------------------------------------------- /doc/examples/xsim.grade-distribution.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgnieder/xsim/06e3dba43b96ed493968ddd54add9fc8a1d9a264/doc/examples/xsim.grade-distribution.pdf -------------------------------------------------------------------------------- /doc/examples/xsim.grade-distribution.tex: -------------------------------------------------------------------------------- 1 | \documentclass{article} 2 | \usepackage{xsim} 3 | 4 | \xsimsetup{grades/split=;} 5 | 6 | \DeclareGradeDistribution{ 7 | 1 = 1 ; 8 | 1,5 = .9167 ; 9 | 2 = .8333 ; 10 | 2,5 = .75 ; 11 | 3 = .6667 ; 12 | 3,5 = .5833 ; 13 | 4 = .5 14 | } 15 | 16 | \begin{document} 17 | 18 | \begin{exercise}[points=4] 19 | \end{exercise} 20 | 21 | \begin{exercise}[points=4] 22 | \end{exercise} 23 | 24 | \begin{exercise}[points=4] 25 | \end{exercise} 26 | 27 | \begin{exercise}[points=4,bonus-points=10] 28 | \end{exercise} 29 | 30 | \begin{exercise}[points=4] 31 | \end{exercise} 32 | 33 | \begin{exercise}[points=4] 34 | \end{exercise} 35 | 36 | 37 | \goalsforgrade{points + bonus-points}{1,5} 38 | \goalsforgrade{points+bonus-points}{2} 39 | 40 | \pointsforgrade{1} 41 | \pointsforgrade{1,5} 42 | \pointsforgrade{2} 43 | \pointsforgrade{2,5} 44 | \pointsforgrade{3} 45 | \pointsforgrade{3,5} 46 | \pointsforgrade{4} 47 | 48 | \totalgoalforgrade{1} 49 | \totalgoalforgrade{1,5} 50 | \totalgoalforgrade{2} 51 | \totalgoalforgrade{2,5} 52 | \totalgoalforgrade{3} 53 | \totalgoalforgrade{3,5} 54 | \totalgoalforgrade{4} 55 | 56 | \end{document} 57 | -------------------------------------------------------------------------------- /doc/examples/xsim.hints.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgnieder/xsim/06e3dba43b96ed493968ddd54add9fc8a1d9a264/doc/examples/xsim.hints.pdf -------------------------------------------------------------------------------- /doc/examples/xsim.hints.tex: -------------------------------------------------------------------------------- 1 | % https://tex.stackexchange.com/q/224408/ 2 | \documentclass{article} 3 | \usepackage{xsim} 4 | 5 | \usepackage{needspace} 6 | 7 | \DeclareExerciseProperty{hint} 8 | 9 | % we'll use a description list for the hints: 10 | \newcommand\printhints{% 11 | \begin{description} 12 | \ForEachUsedExerciseByType{% 13 | \GetExercisePropertyT{hint} 14 | {\item[\XSIMmixedcase{\GetExerciseName}~##3]####1}% 15 | }% 16 | \end{description} 17 | } 18 | 19 | \newcommand\hint[1]{\SetExerciseProperty{hint}{#1}} 20 | 21 | \begin{document} 22 | 23 | \section{Problems} 24 | % set hint through option: 25 | \begin{exercise}[subtitle=Pythagoras,hint=This is a hint to the first problem.] 26 | This is the first problem. 27 | \end{exercise} 28 | \begin{solution} 29 | This is the solution to the first problem. 30 | \end{solution} 31 | 32 | \begin{exercise}[subtitle=Another Problem] 33 | This is the second problem. 34 | \end{exercise} 35 | \begin{solution} 36 | This is the solution to the second problem. 37 | \end{solution} 38 | 39 | % set hint with custom command: 40 | \begin{exercise}[subtitle=Yet Another Problem] 41 | This is the third problem. 42 | \hint{This is a hint to the third problem.} 43 | \end{exercise} 44 | \begin{solution} 45 | This is the solution to the third problem. 46 | \end{solution} 47 | 48 | \section{Hints} 49 | \printhints 50 | 51 | \section{Solutions} 52 | \printsolutions[headings=false] 53 | 54 | \end{document} 55 | -------------------------------------------------------------------------------- /doc/examples/xsim.issues-49.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgnieder/xsim/06e3dba43b96ed493968ddd54add9fc8a1d9a264/doc/examples/xsim.issues-49.pdf -------------------------------------------------------------------------------- /doc/examples/xsim.issues-49.tex: -------------------------------------------------------------------------------- 1 | \documentclass{article} 2 | \usepackage{xsim} 3 | 4 | \xsimsetup{ 5 | load-style = layouts , 6 | exercise/template = runin , 7 | solution/template = runin 8 | } 9 | 10 | \usepackage{tasks,fontawesome,fmtcount,multicol} 11 | \NewTasksEnvironment[label=\Alph*),label-width=12pt]{choices}[\choice] 12 | \newcommand*\correct{\refstepcounter{task}\thetask\expanded{\SetExerciseProperty{choice}{\thetask}}} 13 | 14 | \NewTasksEnvironment[label=\Roman*,label-width=12pt]{options}[\option] 15 | 16 | \DeclareExerciseProperty{choice} 17 | 18 | \newcommand*\pkg[1]{\texttt{#1}} 19 | \newcommand*\cls[1]{\texttt{#1}} 20 | 21 | \newcommand\EA[2]{\IfInsideSolutionTF{#2}{#1}} 22 | \newcommand\answer[1]{\IfInsideSolutionT{#1}} 23 | 24 | \begin{document} 25 | 26 | \section{List of exercises} 27 | Solve and answer the following exercises. 28 | 29 | \begin{exercise} 30 | Factor $x^{2}-2x+1$ 31 | \end{exercise} 32 | \begin{solution} 33 | $\left(x-1\right)^{2}$ 34 | \end{solution} 35 | \begin{exercise} 36 | Factor $3x+3y+3z$ 37 | \end{exercise} 38 | \begin{solution} 39 | $3(x+y+z)$ 40 | \end{solution} 41 | 42 | \begin{exercise}[solution] 43 | \EA{True or false?}{} 44 | \begin{tasks}(2) 45 | \task \EA{$\alpha > \delta$}{False} 46 | \task \EA{\LaTeX2e\ is cool?}{Very True!} 47 | \end{tasks} 48 | \end{exercise} 49 | 50 | \begin{exercise}[subtitle=Talking Linux,solution] 51 | \begin{tasks}(2) 52 | \task \EA{You use linux?}{Yes} 53 | \task \EA{Usually uses the package manager?}{Yes} 54 | \end{tasks} 55 | \end{exercise} 56 | 57 | \begin{exercise}[solution] 58 | \EA{Rate the following \LaTeX\ packages and classes.}{} 59 | \begin{tasks}(\EA{3}{1}) 60 | \task \EA{\cls{xsim-exam}}{doesn't exist for now} 61 | \task \EA{\pkg{xsim}}{very good} 62 | \task \EA{\pkg{exsheets}}{obsolete} 63 | \end{tasks} 64 | \end{exercise} 65 | 66 | \begin{exercise} 67 | \begin{choices}(5) 68 | \choice value 69 | \choice value 70 | \choice value 71 | \choice[\correct] correct 72 | \choice value 73 | \end{choices} 74 | \end{exercise} 75 | \begin{solution} 76 | \GetExerciseProperty{choice} 77 | \end{solution} 78 | 79 | \begin{exercise} 80 | \begin{options}(3) 81 | \option $2\alpha+2\delta=90^{\circ}$ 82 | \option $\alpha=\delta$ 83 | \option $\angle EDF=45^{\circ}$ 84 | \end{options} 85 | \begin{choices}(4) 86 | \choice I only 87 | \choice[\correct] II only 88 | \choice I and II only 89 | \choice I and III only 90 | \choice I, II, and III 91 | \end{choices} 92 | \end{exercise} 93 | \begin{solution} 94 | \GetExerciseProperty{choice} 95 | \end{solution} 96 | 97 | \begin{exercise} 98 | \begin{tasks}[label=(\arabic*),label-width=13pt](2) 99 | \task $2\alpha+2\delta=90^{\circ}$ 100 | \task $\angle EDF=45^{\circ}$ 101 | \end{tasks} 102 | \begin{choices}(3) 103 | \choice Alternative A 104 | \choice Alternative B 105 | \choice[\correct] Alternative C 106 | \choice Alternative D 107 | \choice Alternative E 108 | \end{choices} 109 | \end{exercise} 110 | \begin{solution} 111 | \GetExerciseProperty{choice} 112 | \end{solution} 113 | 114 | \clearpage 115 | 116 | \section{Solutions} 117 | \raggedcolumns 118 | \begin{multicols}{2} 119 | \printsolutions[headings=false] 120 | \end{multicols} 121 | 122 | \end{document} 123 | -------------------------------------------------------------------------------- /doc/examples/xsim.listings.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgnieder/xsim/06e3dba43b96ed493968ddd54add9fc8a1d9a264/doc/examples/xsim.listings.pdf -------------------------------------------------------------------------------- /doc/examples/xsim.listings.tex: -------------------------------------------------------------------------------- 1 | % http://tex.stackexchange.com/questions/131546/ 2 | \documentclass{article} 3 | 4 | \usepackage{xcolor} 5 | \usepackage{listings} 6 | \usepackage[use-files]{xsim} 7 | 8 | \lstset{ 9 | frame=single, 10 | xleftmargin=20pt, 11 | numbers=left, 12 | numberstyle=\small, 13 | tabsize=2, 14 | breaklines, 15 | showspaces=false, 16 | showstringspaces=false, 17 | language=C, 18 | basicstyle=\small\ttfamily, 19 | commentstyle=\itshape\color{gray} 20 | } 21 | 22 | \begin{document} 23 | 24 | \begin{exercise}[points=6] 25 | Consider the following C program. 26 | \begin{lstlisting} 27 | #include 28 | 29 | int main(int argc, char *argv[]) { 30 | printf("hello, world\n"); 31 | } 32 | \end{lstlisting} 33 | \end{exercise} 34 | \begin{solution} 35 | Consider the following C program. 36 | \begin{lstlisting} 37 | #include 38 | 39 | int main(int argc, char *argv[]) { 40 | printf("hello, world\n"); 41 | } 42 | \end{lstlisting} 43 | \end{solution} 44 | 45 | \pagebreak 46 | \printsolutions 47 | 48 | \end{document} 49 | -------------------------------------------------------------------------------- /doc/examples/xsim.listofexercises.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgnieder/xsim/06e3dba43b96ed493968ddd54add9fc8a1d9a264/doc/examples/xsim.listofexercises.pdf -------------------------------------------------------------------------------- /doc/examples/xsim.listofexercises.tex: -------------------------------------------------------------------------------- 1 | % https://tex.stackexchange.com/q/94766/ 2 | \documentclass[a4paper,10pt]{book} 3 | \usepackage[utf8]{inputenc} 4 | 5 | \usepackage{xsim} 6 | \xsimsetup{ 7 | exercise/within=chapter, 8 | exercise/template=theorem , 9 | exercise/the-counter=\thechapter.\arabic{exercise} 10 | } 11 | 12 | \DeclareExerciseEnvironmentTemplate{theorem} 13 | {% 14 | \par\addvspace{\baselineskip} 15 | \noindent 16 | \XSIMexpandcode{\noexpand\label{\ExerciseType:\ExerciseID}} 17 | \Large\textbf{% 18 | \space\GetExerciseProperty{counter}% 19 | \GetExercisePropertyT{subtitle}{ (\PropertyValue)}% 20 | } \normalsize\itshape 21 | } 22 | {\par\addvspace{\baselineskip}} 23 | 24 | \usepackage{multicol} 25 | 26 | \newcommand\listofexercises{ 27 | \chapter*{List of Exercises} 28 | \def\CurrentExerciseChapter{}% 29 | \ForEachPrintedExerciseByType{ 30 | \global\let\LastExerciseChapter\CurrentExerciseChapter 31 | \xdef\CurrentExerciseChapter{\ExercisePropertyGet{##1}{##2}{chapter}}% 32 | \XSIMifeqF{\LastExerciseChapter}{\CurrentExerciseChapter} 33 | { 34 | \XSIMifblankF{\LastExerciseChapter}{\end{multicols}} 35 | \begin{multicols}{2}% 36 | [\contentsline{chapter}{Chapter \CurrentExerciseChapter}{}{}] 37 | } 38 | \contentsline 39 | {section} 40 | {% 41 | Exercise \ExercisePropertyGet{##1}{##2}{counter}% 42 | \XSIMifblankF{##4}{ (##4)}% 43 | } 44 | {\pageref{##1:##2}}{}% 45 | } 46 | \end{multicols} 47 | } 48 | 49 | % \usepackage{hyperref} 50 | % \newcommand\theHexercise{\thechapter.\arabic{exercise}} 51 | 52 | \begin{document} 53 | 54 | \chapter{kinetic} 55 | \begin{exercise} 56 | 435-1 57 | \end{exercise} 58 | \begin{exercise}[subtitle=Foo Bar] 59 | 435-2 60 | \end{exercise} 61 | \begin{exercise} 62 | 435-3 63 | \end{exercise} 64 | 65 | \chapter{momentum} 66 | \begin{exercise} 67 | 436-1 68 | \end{exercise} 69 | \begin{exercise} 70 | 436-2 71 | \end{exercise} 72 | \begin{exercise} 73 | 436-3 74 | \end{exercise} 75 | \begin{exercise} 76 | 436-4 77 | \end{exercise} 78 | 79 | \listofexercises 80 | 81 | \end{document} 82 | -------------------------------------------------------------------------------- /doc/examples/xsim.multiplechoice.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgnieder/xsim/06e3dba43b96ed493968ddd54add9fc8a1d9a264/doc/examples/xsim.multiplechoice.pdf -------------------------------------------------------------------------------- /doc/examples/xsim.multiplechoice.tex: -------------------------------------------------------------------------------- 1 | \documentclass{scrartcl} 2 | \usepackage[clear-aux]{xsim} 3 | 4 | \usepackage{enumitem,amssymb,fmtcount} 5 | \newlist{choices}{itemize}{1} 6 | \setlist[choices]{label=$\Box$} 7 | \newcommand*\choice{\item} 8 | 9 | \DeclareExerciseProperty{choices} 10 | \DeclareExerciseProperty*{multiple} 11 | \DeclareExerciseEnvironmentTemplate{mc} 12 | {% 13 | \UseExerciseTemplate{begin}{default}% 14 | \IfExerciseBooleanPropertyTF{multiple} 15 | {Select one or more correct answers} 16 | {% 17 | \GetExercisePropertyT{choices} 18 | {Select \numberstringnum{#1} correct answer\ifnum#1>1 s\fi.}% 19 | }% 20 | \begin{choices} 21 | } 22 | {% 23 | \end{choices} 24 | \UseExerciseTemplate{end}{default}% 25 | } 26 | 27 | \DeclareExerciseType{mc}{ 28 | exercise-env = multiplechoice , 29 | solution-env = correctchoices , 30 | exercise-name = Question , 31 | solution-name = Solution , 32 | exercise-template = mc , 33 | solution-template = mc , 34 | counter = exercise 35 | } 36 | 37 | \xsimsetup{ 38 | exercise/name = Question , 39 | solution/name = Solution 40 | } 41 | 42 | \begin{document} 43 | 44 | \section{Questions} 45 | \begin{multiplechoice}[choices=1] 46 | \choice one 47 | \choice two 48 | \choice three 49 | \choice four 50 | \end{multiplechoice} 51 | 52 | \begin{exercise} 53 | Answer this question on a separate sheet. 54 | \end{exercise} 55 | 56 | \begin{multiplechoice}[multiple] 57 | \choice one 58 | \choice two 59 | \choice three 60 | \choice four 61 | \end{multiplechoice} 62 | 63 | \begin{multiplechoice}[choices=2] 64 | \choice one 65 | \choice two 66 | \choice three 67 | \choice four 68 | \end{multiplechoice} 69 | 70 | \end{document} 71 | -------------------------------------------------------------------------------- /doc/examples/xsim.pointsums.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgnieder/xsim/06e3dba43b96ed493968ddd54add9fc8a1d9a264/doc/examples/xsim.pointsums.pdf -------------------------------------------------------------------------------- /doc/examples/xsim.pointsums.tex: -------------------------------------------------------------------------------- 1 | \documentclass{article} 2 | \usepackage{xsim,lipsum} 3 | 4 | \NewDocumentCommand\printcompletepoints{}{% 5 | \TotalExerciseGoals{points + bonus-points} 6 | {\,\XSIMtranslate{point}} 7 | {\,\XSIMtranslate{points}}% 8 | } 9 | 10 | \NewDocumentCommand\pointsandbonus{}{% 11 | \TotalExerciseGoal{points}{}{}% 12 | \IfExerciseGoalsSumTF{bonus-points}{=0} 13 | {} 14 | {\,(+\,\TotalExerciseGoal{bonus-points}{}{})}% 15 | \,\XSIMtranslate{points}% 16 | } 17 | 18 | \begin{document} 19 | 20 | \begin{exercise}[points=3,bonus-points=1] 21 | \lipsum[4] 22 | \end{exercise} 23 | 24 | \begin{exercise}[points=8,bonus-points=3] 25 | \lipsum[4] 26 | \end{exercise} 27 | 28 | \printtotalpoints\ vs.\@ \printcompletepoints\ vs.\@ \pointsandbonus 29 | 30 | \end{document} 31 | -------------------------------------------------------------------------------- /doc/examples/xsim.randomexercises.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgnieder/xsim/06e3dba43b96ed493968ddd54add9fc8a1d9a264/doc/examples/xsim.randomexercises.pdf -------------------------------------------------------------------------------- /doc/examples/xsim.randomexercises.tex: -------------------------------------------------------------------------------- 1 | \documentclass{article} 2 | \usepackage{xsim} 3 | 4 | \xsimsetup{collect} 5 | 6 | \begin{document} 7 | 8 | \begin{exercise}[ID=A] 9 | exercise A 10 | \end{exercise} 11 | \begin{solution} 12 | solution A 13 | \end{solution} 14 | \begin{exercise}[ID=B] 15 | exercise B 16 | \end{exercise} 17 | \begin{solution} 18 | solution B 19 | \end{solution} 20 | \begin{exercise}[ID=C] 21 | exercise C 22 | \end{exercise} 23 | \begin{solution} 24 | solution C 25 | \end{solution} 26 | \begin{exercise}[ID=D] 27 | exercise D 28 | \end{exercise} 29 | \begin{solution} 30 | solution D 31 | \end{solution} 32 | \begin{exercise}[ID=E] 33 | exercise E 34 | \end{exercise} 35 | \begin{solution} 36 | solution E 37 | \end{solution} 38 | \begin{exercise}[ID=F] 39 | exercise F 40 | \end{exercise} 41 | \begin{solution} 42 | solution F 43 | \end{solution} 44 | 45 | \section*{Exercises} 46 | \printrandomexercises[collection=all exercises,exclude=D]{3} 47 | 48 | \printsolutions 49 | 50 | \end{document} 51 | -------------------------------------------------------------------------------- /doc/examples/xsim.texsx-13635.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgnieder/xsim/06e3dba43b96ed493968ddd54add9fc8a1d9a264/doc/examples/xsim.texsx-13635.pdf -------------------------------------------------------------------------------- /doc/examples/xsim.texsx-13635.tex: -------------------------------------------------------------------------------- 1 | % https://tex.stackexchange.com/q/13635/ 2 | \documentclass{article} 3 | \usepackage{xsim} 4 | 5 | \DeclareExerciseEnvironmentTemplate{theorem:remark} 6 | { 7 | \par\addvspace{\baselineskip} 8 | \noindent 9 | \textit{% 10 | \IfInsideSolutionF{\XSIMmixedcase{\GetExerciseName}~}% 11 | \GetExerciseProperty{counter}}% 12 | \GetExercisePropertyT{subtitle}{ \textup{(#1)}}% 13 | . % 14 | } 15 | {\par\addvspace{\baselineskip}} 16 | 17 | \DeclareExerciseHeadingTemplate{exercises}{\subsection*{Exercises}} 18 | 19 | \xsimsetup{ 20 | exercise/template = theorem:remark , 21 | exercise/within = section , 22 | exercise/the-counter = \thesection.\arabic{exercise} , 23 | print-collection/headings = true , 24 | print-collection/headings-template = exercises 25 | } 26 | 27 | \DeclareExerciseCollection{prime numbers} 28 | \DeclareExerciseCollection{Zeta function} 29 | 30 | \xsimsetup{collect} 31 | 32 | \begin{document} 33 | 34 | \collectexercises{prime numbers} 35 | \section{Prime Numbers} 36 | 37 | A \emph{prime number} is a positive integer other than $1$ that is only 38 | divisible by $1$ and itself. 39 | 40 | \begin{exercise}[subtitle=Euclid's Theorem] 41 | \label{ex:euclid} 42 | Show that there are infinitely many prime numbers. 43 | \end{exercise} 44 | 45 | As you will show in Exercise \ref{ex:euclid}, there are infinitely many 46 | primes. The number of primes that are smaller than a given natural number $n$ 47 | is denoted $\pi(n)$. 48 | 49 | \begin{exercise} 50 | Find an asymptotic formula for $\pi(n)$. \emph{Hint:} You might find 51 | Exercise \ref{ex:zeta} helpful. 52 | \end{exercise} 53 | \collectexercisesstop{prime numbers} 54 | 55 | \printcollection{prime numbers} 56 | 57 | \collectexercises{Zeta function} 58 | \section{Zeta function} 59 | 60 | The zeta function is given by $\zeta(s) = \sum_{n=1}^\infty n^{-s}$, where $s$ 61 | is a complex number with real part bigger than $1$. 62 | \begin{exercise}\label{ex:zeta} 63 | Extend $\zeta$ as far as possible and find all zeros 64 | of the function. 65 | \end{exercise} 66 | For example $\zeta(2) = \frac{\pi^2}{6}$. 67 | 68 | \collectexercisesstop{Zeta function} 69 | 70 | \printcollection{Zeta function} 71 | 72 | \end{document} 73 | -------------------------------------------------------------------------------- /doc/examples/xsim.texsx-155630.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgnieder/xsim/06e3dba43b96ed493968ddd54add9fc8a1d9a264/doc/examples/xsim.texsx-155630.pdf -------------------------------------------------------------------------------- /doc/examples/xsim.texsx-155630.tex: -------------------------------------------------------------------------------- 1 | % https://tex.stackexchange.com/q/155630/ 2 | \documentclass{article} 3 | \usepackage{xsim} 4 | 5 | \DeclareExerciseCollection{foo} 6 | \xsimsetup{collect} 7 | 8 | \begin{document} 9 | 10 | \begin{exercise} 11 | foo 12 | \end{exercise} 13 | \begin{exercise} 14 | bar 15 | \end{exercise} 16 | \begin{exercise} 17 | baz 18 | \end{exercise} 19 | 20 | % shuffle around for a different version: 21 | \printexercise{exercise}{1} 22 | \printexercise{exercise}{3} 23 | \printexercise{exercise}{2} 24 | 25 | \end{document} 26 | -------------------------------------------------------------------------------- /doc/examples/xsim.texsx-199360.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgnieder/xsim/06e3dba43b96ed493968ddd54add9fc8a1d9a264/doc/examples/xsim.texsx-199360.pdf -------------------------------------------------------------------------------- /doc/examples/xsim.texsx-199360.tex: -------------------------------------------------------------------------------- 1 | % http://tex.stackexchange.com/a/199360/ 2 | \documentclass{scrartcl} 3 | \usepackage[clear-aux]{xsim} 4 | 5 | \usepackage{tcolorbox,blindtext} 6 | 7 | \DeclareExerciseEnvironmentTemplate{custom} 8 | {% 9 | \begin{tcolorbox}[ 10 | width = \textwidth , 11 | colbacktitle = \IfInsideSolutionTF{green}{red} , 12 | coltitle = black , 13 | title = {\XSIMmixedcase{\GetExerciseName}~\GetExerciseProperty{counter}}]} 14 | {\end{tcolorbox}} 15 | 16 | \xsimsetup{ 17 | exercise/template = custom , 18 | solution/template = custom 19 | } 20 | 21 | \begin{document} 22 | 23 | \begin{exercise} 24 | First Question 25 | \end{exercise} 26 | \begin{solution} 27 | Yes, it's a question 28 | \end{solution} 29 | 30 | \begin{exercise}[print=false,use] 31 | Question: What is special about Brontosaurs? 32 | \end{exercise} 33 | \begin{solution} 34 | They are thin at one end, thick in the middle and thin on the end again 35 | \end{solution} 36 | 37 | \begin{exercise} 38 | Proof 39 | \begin{equation} 40 | a^2 + b^2 = c^2 41 | \end{equation} 42 | \end{exercise} 43 | \begin{solution} 44 | to be done 45 | \end{solution} 46 | 47 | \begin{exercise} 48 | Cite a Latin Text 49 | \end{exercise} 50 | \begin{solution} 51 | \textcolor{blue}{\blindtext} 52 | \end{solution} 53 | 54 | \begin{exercise} 55 | \textcolor{red}{\textbf{Cite a Latin text again}} 56 | \end{exercise} 57 | 58 | \printsolutions* 59 | 60 | \end{document} 61 | -------------------------------------------------------------------------------- /doc/examples/xsim.texsx-299534.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgnieder/xsim/06e3dba43b96ed493968ddd54add9fc8a1d9a264/doc/examples/xsim.texsx-299534.pdf -------------------------------------------------------------------------------- /doc/examples/xsim.texsx-299534.tex: -------------------------------------------------------------------------------- 1 | % http://tex.stackexchange.com/q/299534/ 2 | \documentclass{article} 3 | \usepackage{pythontex} 4 | \usepackage[use-files]{xsim} 5 | 6 | \begin{document} 7 | 8 | \section{Test} 9 | 10 | \begin{exercise}[subtitle = Codeless Question,points=10] 11 | A question without code, worth 10 points. Subtitle and point values are in 12 | correct place. 13 | \end{exercise} 14 | \begin{solution} 15 | Solution 1 16 | \end{solution} 17 | 18 | \begin{exercise}[subtitle = Codeful Question,points=15] 19 | Now with PythonTeX: 20 | \begin{pyblock} 21 | print("hello, world!") 22 | sum = 0 23 | for j in range(0,100): 24 | sum += j 25 | print(sum) 26 | \end{pyblock} 27 | \end{exercise} 28 | \begin{solution} 29 | Solution 2 30 | \end{solution} 31 | 32 | \end{document} 33 | -------------------------------------------------------------------------------- /doc/examples/xsim.texsx-305110.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgnieder/xsim/06e3dba43b96ed493968ddd54add9fc8a1d9a264/doc/examples/xsim.texsx-305110.pdf -------------------------------------------------------------------------------- /doc/examples/xsim.texsx-305110.tex: -------------------------------------------------------------------------------- 1 | % https://tex.stackexchange.com/q/305110 2 | \documentclass[12pt, a4paper]{book} 3 | \usepackage{xsim} 4 | 5 | \xsimsetup{ 6 | exercise/within = section , 7 | exercise/the-counter = \thesection.\arabic{exercise} 8 | } 9 | 10 | \begin{document} 11 | \part{EXCERCISES} 12 | \chapter{Topic 1} 13 | 14 | \section{Section} 15 | 16 | \begin{exercise} 17 | I'm an excercise. 18 | \end{exercise} 19 | \begin{solution} 20 | I'm a solution. 21 | \end{solution} 22 | 23 | \section{Section} 24 | 25 | \begin{exercise} 26 | I'm an excercise. 27 | \end{exercise} 28 | \begin{solution} 29 | I'm a solution. 30 | \end{solution} 31 | 32 | \chapter{Topic 2} 33 | 34 | \section{Section} 35 | \begin{exercise} 36 | I'm an excercise. 37 | \end{exercise} 38 | \begin{solution} 39 | I'm a solution. 40 | \end{solution} 41 | 42 | \section{Section} 43 | \begin{exercise} 44 | I'm an excercise. 45 | \end{exercise} 46 | \begin{solution} 47 | I'm a solution. 48 | \end{solution} 49 | 50 | \setcounter{chapter}{0} 51 | \part{SOLUTIONS} 52 | 53 | \chapter{Topic 1} 54 | \section{Section} 55 | \printsolutions[chapter=1,section=1] 56 | 57 | \section{Section} 58 | \printsolutions[chapter=1,section=2] 59 | 60 | \chapter{Topic 2} 61 | \section{Section} 62 | \printsolutions[chapter=2,section=1] 63 | 64 | \section{Section} 65 | \printsolutions[chapter=2,section=2] 66 | 67 | \end{document} 68 | -------------------------------------------------------------------------------- /doc/examples/xsim.texsx-308883.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgnieder/xsim/06e3dba43b96ed493968ddd54add9fc8a1d9a264/doc/examples/xsim.texsx-308883.pdf -------------------------------------------------------------------------------- /doc/examples/xsim.texsx-308883.tex: -------------------------------------------------------------------------------- 1 | % https://tex.stackexchange.com/q/308883/ 2 | \documentclass{article} 3 | \usepackage{xsim,siunitx} 4 | \xsimsetup{goal-print={\num{#1}}} 5 | \sisetup{output-decimal-marker={,}} 6 | 7 | \begin{document} 8 | 9 | \begin{exercise}[points=2.5] 10 | foo 11 | \end{exercise} 12 | 13 | \end{document} 14 | -------------------------------------------------------------------------------- /doc/examples/xsim.texsx-338165.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgnieder/xsim/06e3dba43b96ed493968ddd54add9fc8a1d9a264/doc/examples/xsim.texsx-338165.pdf -------------------------------------------------------------------------------- /doc/examples/xsim.texsx-338165.tex: -------------------------------------------------------------------------------- 1 | % http://tex.stackexchange.com/q/338165 2 | \documentclass{article} 3 | \usepackage[T1]{fontenc} 4 | \usepackage{leading,microtype} 5 | \usepackage[french]{babel} 6 | 7 | \usepackage{tasks} 8 | \usepackage{xsim} 9 | \usepackage{tcolorbox} 10 | \tcbuselibrary{breakable, skins} 11 | \settasks{ label = \arabic*. } 12 | 13 | \DeclareExerciseEnvironmentTemplate{boxed}{% 14 | \tcolorbox[ 15 | enhanced , 16 | attach boxed title to top center = {yshift=-7.5pt} , 17 | colback = white , colbacktitle = white , 18 | coltitle = black , colframe = black , 19 | boxed title style = { colframe = white } , 20 | fonttitle=\bfseries, 21 | sharp corners=all, 22 | breakable, 23 | title= 24 | \XSIMmixedcase{\GetExerciseName}% 25 | \IfInsideSolutionF{% 26 | ~\GetExerciseProperty{counter}% 27 | \IfExercisePropertySetT{subtitle}{: \GetExerciseProperty{subtitle}}% 28 | }% 29 | ] 30 | }{\endtcolorbox} 31 | 32 | \xsimsetup{ 33 | exercise/template = boxed , 34 | solution/template = boxed , 35 | solution/print = true 36 | } 37 | 38 | \leading{15pt} 39 | 40 | \newcommand*\complement{\overline} 41 | \newcommand*\union{\cup} 42 | \newcommand*\intersection{\cap} 43 | \newcommand*\set[1]{\{#1\}} 44 | 45 | \begin{document} 46 | 47 | \begin{exercise}[subtitle=Set Calculus] 48 | Soient $E=\set{1,2,3,4,5,6,7}$ et $A$, $B$, $C$ et $D$ quatre parties de E 49 | d\'efinies par $A=\set{1,2,3,4}$, $B=\set{4,5,6,7}$, $C=\set{1,3,5,7}$ et 50 | $D=\set{2,3,4,5,6}$. 51 | \begin{tasks}(2) 52 | \task Calculer $\complement{A}$. 53 | \task Calculer $(A\union B) \intersection (C\union D)$. 54 | \task Calculer $(A\intersection B) \union (C\intersection D)$. 55 | \task Calculer $\complement{(\complement{A}\union B)} \union 56 | \complement{(C\intersection D)}$. 57 | \end{tasks} 58 | \end{exercise} 59 | \begin{solution} 60 | \begin{tasks}(2) 61 | \task $\set{5,6,7}$ 62 | \task $E$ 63 | \task $\set{3,4,5}$ 64 | \task $\set{1,2,3,4,6,7}$ 65 | \end{tasks} 66 | \end{solution} 67 | 68 | \end{document} 69 | -------------------------------------------------------------------------------- /doc/examples/xsim.texsx-350028.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgnieder/xsim/06e3dba43b96ed493968ddd54add9fc8a1d9a264/doc/examples/xsim.texsx-350028.pdf -------------------------------------------------------------------------------- /doc/examples/xsim.texsx-350028.tex: -------------------------------------------------------------------------------- 1 | % http://tex.stackexchange.com/q/350028/ 2 | \documentclass{book} 3 | \usepackage[T1]{fontenc} 4 | \usepackage{xsim} 5 | \usepackage[most]{tcolorbox} 6 | \tcbuselibrary{skins,breakable} 7 | 8 | \DeclareExerciseEnvironmentTemplate{tcolorbox}{% 9 | \tcolorbox[ 10 | enhanced, 11 | colframe=green!20!black, 12 | colback=yellow!10!white, 13 | coltitle=green!40!black, 14 | fonttitle=\bfseries, 15 | underlay={% 16 | \begin{tcbclipinterior} 17 | \shade[ 18 | inner color=\IfInsideSolutionTF{red!50!yellow}{green!80!yellow}, 19 | outer color=yellow!10!white] 20 | (interior.north west) circle (2cm); 21 | \draw[help lines,step=5mm,yellow!80!black,shift={(interior.north west)}] 22 | (interior.south west) grid (interior.north east); 23 | \end{tcbclipinterior}% 24 | }, 25 | attach title to upper=\quad, 26 | title = \XSIMmixedcase{\GetExerciseName}~\GetExerciseProperty{counter} 27 | \IfExercisePropertySetT{points}{% 28 | (\GetExerciseProperty{points} 29 | \IfExerciseGoalSingularTF{points} 30 | {\XSIMtranslate{point}} 31 | {\XSIMtranslate{points}})% 32 | }]% 33 | \IfInsideSolutionT{\label{solution:\ExerciseID}}% 34 | }{% 35 | \endtcolorbox 36 | \vspace*{\baselineskip} 37 | \IfInsideSolutionTF{% 38 | \noindent Exercise~\GetExerciseProperty{counter} is on 39 | page~\GetExerciseProperty{page}.% 40 | }{% 41 | \noindent The solution of this exercise is on 42 | page~\pageref{solution:\ExerciseID}.% 43 | }% 44 | \vspace{\baselineskip} 45 | } 46 | 47 | \xsimsetup{ 48 | exercise/template = tcolorbox , 49 | solution/template = tcolorbox 50 | } 51 | 52 | \usepackage{fmtcount,etoolbox} 53 | \newrobustcmd*\mystringnum[2]{\csname#1stringnum\endcsname{#2}} 54 | \renewcommand*\thechapter{\mystringnum{number}{\value{chapter}}} 55 | \renewcommand*\thesection{\arabic{chapter}.\arabic{section}} 56 | 57 | % for the header: \MakeUppercase{\mystringnum{number}{1}} 58 | % => \mystringnum{NUMBER}{1} 59 | % => \NUMBERstringnum{1} 60 | % elsewhere: \mystringnum{number}{1} 61 | % => \numberstringnum{1} 62 | 63 | \usepackage{totcount} 64 | \regtotcounter{chapter} 65 | 66 | \newcounter{chapters} 67 | \setcounter{chapters}{1} 68 | \newcommand*\printsolutionsperchapter{% 69 | \whileboolexpr 70 | { test { \ifnumless {\value{chapters}} {\totvalue{chapter}+1} } } 71 | {% 72 | \printsolutions[chapter=\value{chapters},headings-template=per-chapter] 73 | \stepcounter{chapters}% 74 | }% 75 | } 76 | 77 | \begin{document} 78 | 79 | \chapter{The First Chapter} 80 | 81 | \begin{exercise} 82 | Compute the derivative of the following function: 83 | \begin{equation*} 84 | f(x) = \sin((\sin x)^2) 85 | \end{equation*} 86 | \end{exercise} 87 | \begin{solution} 88 | The derivative is: 89 | \begin{align*} 90 | f’(x) &= ( \sin((\sin x)^2) )' 91 | = \cos((\sin x)^2) \cdot 2\sin x \cos x 92 | \end{align*} 93 | \end{solution} 94 | 95 | \begin{exercise} 96 | Compute the derivative of the following function: 97 | \begin{equation*} 98 | f(x) = \sin((\sin x)^2) 99 | \end{equation*} 100 | \end{exercise} 101 | \begin{solution} 102 | The derivative is: 103 | \begin{align*} 104 | f’(x) &= ( \sin((\sin x)^2) )' 105 | = \cos((\sin x)^2) \cdot 2\sin x \cos x 106 | \end{align*} 107 | \end{solution} 108 | 109 | \chapter{The Second Chapter} 110 | 111 | \begin{exercise} 112 | Compute the derivative of the following function: 113 | \begin{equation*} 114 | f(x) = (x^2+1) \sqrt{x^4+1} 115 | \end{equation*} 116 | \end{exercise} 117 | \begin{solution} 118 | The derivative is: 119 | \begin{align*} 120 | f’(x) &= ( (x^2+1) \sqrt{x^4+1} )' 121 | = 2x\sqrt{x^4+1} + \frac{2x^3(x^2+1)}{\sqrt{x^4+1}} 122 | \end{align*} 123 | \end{solution} 124 | 125 | \clearpage 126 | \section{Solutions of the Exercices} 127 | 128 | \printsolutionsperchapter 129 | 130 | \end{document} 131 | -------------------------------------------------------------------------------- /doc/examples/xsim.texsx-369065.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgnieder/xsim/06e3dba43b96ed493968ddd54add9fc8a1d9a264/doc/examples/xsim.texsx-369065.pdf -------------------------------------------------------------------------------- /doc/examples/xsim.texsx-369065.tex: -------------------------------------------------------------------------------- 1 | % https://tex.stackexchange.com/q/369065/ 2 | \documentclass{article} 3 | \usepackage{xsim,tcolorbox,needspace} 4 | 5 | \xsimsetup{ 6 | exercise/within=section , 7 | exercise/the-counter = \thesection.\arabic{exercise} , 8 | exercise/template=cyan-box , 9 | exercise/name=Example , 10 | solution/template=red , 11 | solution/print=true 12 | } 13 | 14 | \DeclareExerciseEnvironmentTemplate{cyan-box}{% 15 | \begin{tcolorbox}[arc=0mm,boxrule=1pt,colback=white,colframe=cyan,leftrule=3mm] 16 | \textsf{% 17 | \MakeUppercase{% 18 | \XSIMmixedcase{\GetExerciseName}~\GetExerciseProperty{counter}% 19 | }% 20 | }% 21 | \GetExercisePropertyT{subtitle}{ \textit{#1}}% 22 | \quad 23 | }{\end{tcolorbox}} 24 | 25 | \DeclareExerciseEnvironmentTemplate{red}{% 26 | \par 27 | \Needspace*{2\baselineskip} 28 | \noindent 29 | \textsf{\textcolor{red}{\MakeUppercase{\XSIMmixedcase{\GetExerciseName}}}}% 30 | \quad 31 | }{\par\bigskip} 32 | 33 | \begin{document} 34 | 35 | \section{My first set of exercises} 36 | \begin{exercise} 37 | Prove that $\frac{1}{2}\Delta(f_{ij}f^{ij}) 38 | =\nabla^{k}f^{ij}+f^{ij}f^{k}[2\nabla_{i}R_{jk}-\nabla_{k}R_{ij}]$ 39 | \end{exercise} 40 | \begin{solution} 41 | From \dots 42 | \end{solution} 43 | 44 | \begin{exercise} 45 | Prove that Paulinho is smart. 46 | \end{exercise} 47 | \begin{solution} 48 | All ducks are smart. Paulinho is a duck. Therefore, Paulinho is smart. 49 | \end{solution} 50 | 51 | \begin{exercise} 52 | Prove that Paulinho is smart. 53 | \end{exercise} 54 | \begin{solution} 55 | All ducks are smart. Paulinho is a duck. Therefore, Paulinho is smart. 56 | \end{solution} 57 | 58 | \section{My second set of exercises} 59 | \begin{exercise} 60 | Prove that Paulinho is smart. 61 | \end{exercise} 62 | \begin{solution} 63 | All ducks are smart. Paulinho is a duck. Therefore, Paulinho is smart. 64 | \end{solution} 65 | 66 | \begin{exercise} 67 | Prove that Paulinho is smart. 68 | \end{exercise} 69 | \begin{solution} 70 | All ducks are smart. Paulinho is a duck. Therefore, Paulinho is smart. 71 | \end{solution} 72 | 73 | \end{document} 74 | -------------------------------------------------------------------------------- /doc/examples/xsim.texsx-369636.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgnieder/xsim/06e3dba43b96ed493968ddd54add9fc8a1d9a264/doc/examples/xsim.texsx-369636.pdf -------------------------------------------------------------------------------- /doc/examples/xsim.texsx-369636.tex: -------------------------------------------------------------------------------- 1 | % https://tex.stackexchange.com/q/369686/ 2 | \documentclass[a4paper,11pt]{article} 3 | \usepackage[top=2cm, bottom=3cm, left=4cm, right=4cm]{geometry} 4 | 5 | \usepackage[T1]{fontenc} 6 | \usepackage{fourier} 7 | \usepackage{tgpagella} 8 | 9 | \usepackage{xsim,needspace,adjustbox,scrextend} 10 | 11 | \xsimsetup{ 12 | exercise/the-counter = \arabic{exercise}. , 13 | exercise/template = square 14 | } 15 | 16 | \DeclareExerciseEnvironmentTemplate{square}{% 17 | \Needspace*{2\baselineskip}% 18 | \addmargin[0pt]{.15\textwidth}% 19 | \par\noindent 20 | \adjustbox{ 21 | fbox = 1pt 0pt, 22 | lap = {\textwidth}, 23 | valign = t, 24 | set vsize = {0pt}{0pt} 25 | }{\rule{0pt}{20pt}\hspace{20pt}}% 26 | \textbf{\GetExerciseProperty{counter}} % 27 | }{\endaddmargin\vspace{\baselineskip}} 28 | 29 | \usepackage{lipsum} 30 | 31 | \begin{document} 32 | 33 | \noindent\hrulefill 34 | 35 | \begin{exercise} 36 | \lipsum[1] 37 | \end{exercise} 38 | 39 | \begin{exercise} 40 | \lipsum[2] 41 | \end{exercise} 42 | 43 | \end{document} 44 | -------------------------------------------------------------------------------- /doc/examples/xsim.texsx-369803.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgnieder/xsim/06e3dba43b96ed493968ddd54add9fc8a1d9a264/doc/examples/xsim.texsx-369803.pdf -------------------------------------------------------------------------------- /doc/examples/xsim.texsx-369803.tex: -------------------------------------------------------------------------------- 1 | % https://tex.stackexchange.com/q/369803 2 | \documentclass[a4paper,parskip=half]{scrartcl} 3 | \usepackage[ngerman]{babel} 4 | 5 | \usepackage{amsmath} 6 | \usepackage{amsthm} 7 | \usepackage{amsfonts} 8 | \usepackage{amssymb} 9 | 10 | \usepackage[left=2cm,right=2.5cm,top=2.5cm,bottom=2cm]{geometry} 11 | 12 | \usepackage{xsim,siunitx} 13 | \DeclareExerciseTagging{difficulty} 14 | \DeclareExerciseEnvironmentTemplate{custom}{% 15 | \subsection*{% 16 | \XSIMmixedcase{\GetExerciseName}\nobreakspace 17 | \GetExerciseProperty{counter}% 18 | \IfInsideSolutionF{% 19 | \IfExercisePropertySetT{subtitle} 20 | { {\normalfont(\GetExerciseProperty{subtitle})}}% 21 | }% 22 | }% 23 | }{} 24 | 25 | \xsimsetup{ 26 | exercise/name = \XSIMtranslate{question} , 27 | exercise/template=custom , 28 | solution/print=true 29 | } 30 | 31 | \begin{document} 32 | 33 | \begin{exercise}[ID=wdsw, subtitle = Widerstandswürfel , difficulty = 2] 34 | Gegeben ist ein Würfel, wobei jede der Kanten einen Widerstand von $R = 35 | \SI{1}{\ohm}$ hat. 36 | 37 | Wie groß ist der Widerstand entlang einer Raumdiagonale? 38 | \end{exercise} 39 | \begin{solution} 40 | Wir wollen den Widerstand zwischen den Punkten $X$ und $Y$ bestimmen, also 41 | entlang der Raumdiagonale (siehe Abb. \ref{fig:wdsws1}). Weil die 42 | Raumdiagonale eine Symmetrieachse ist, sollte das Problem symmetrisch sein, 43 | und deswegen eine recht einfache Lösung haben. 44 | \end{solution} 45 | 46 | \end{document} 47 | -------------------------------------------------------------------------------- /doc/examples/xsim.texsx-370642.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgnieder/xsim/06e3dba43b96ed493968ddd54add9fc8a1d9a264/doc/examples/xsim.texsx-370642.pdf -------------------------------------------------------------------------------- /doc/examples/xsim.texsx-370642.tex: -------------------------------------------------------------------------------- 1 | % https://tex.stackexchange.com/q/370642/ 2 | \documentclass[a4paper,12pt]{article} 3 | \usepackage{xsim} 4 | 5 | \DeclareExerciseEnvironmentTemplate{simple} 6 | {\par\noindent\textbf{\GetExerciseProperty{counter}}. } 7 | {\par} 8 | \xsimsetup{exercise/template=simple} 9 | 10 | \begin{document} 11 | 12 | \begin{exercise}\label{eq1} 13 | Let $X$ be such that\dots 14 | \end{exercise} 15 | 16 | \begin{exercise} 17 | In this exercise consider $Y=2$ \dots 18 | \end{exercise} 19 | 20 | \begin{exercise} 21 | Consider $X$ as in exercise~\ref{eq1} (I would like to see the issue 22 | number~1) 23 | \end{exercise} 24 | 25 | \end{document} 26 | -------------------------------------------------------------------------------- /doc/examples/xsim.texsx-391530.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgnieder/xsim/06e3dba43b96ed493968ddd54add9fc8a1d9a264/doc/examples/xsim.texsx-391530.pdf -------------------------------------------------------------------------------- /doc/examples/xsim.texsx-391530.tex: -------------------------------------------------------------------------------- 1 | % https://tex.stackexchange.com/q/391530 2 | \documentclass{article} 3 | \usepackage{xsim} 4 | 5 | \DeclareExerciseType{subquestion}{ 6 | exercise-env = question , 7 | solution-env = answer , 8 | exercise-name = Question , 9 | solution-name = Answer , 10 | exercise-template = item , 11 | solution-template = item 12 | } 13 | 14 | \DeclareExerciseProperty{title} 15 | 16 | \makeatletter 17 | \DeclareExerciseEnvironmentTemplate{named}{% 18 | \subsection*{% 19 | \GetExercisePropertyTF{title} 20 | {#1} 21 | {??\@latex@warning{Please give an exercise title}}% 22 | }% 23 | }{} 24 | \makeatother 25 | 26 | \DeclareExerciseEnvironmentTemplate{item}{\item}{} 27 | \DeclareExerciseCollection{exercise-pool} 28 | 29 | \xsimsetup{ exercise/template = named } 30 | 31 | \begin{document} 32 | 33 | \collectexercises{exercise-pool} 34 | \begin{question} 35 | Who is the Defence Minister? 36 | \end{question} 37 | \begin{question} 38 | Who is the Home Minister? 39 | \end{question} 40 | \begin{question} 41 | Who is the Finance Minister? 42 | \end{question} 43 | \begin{question} 44 | Who is the External Affairs Minister? 45 | \end{question} 46 | \collectexercisesstop{exercise-pool} 47 | 48 | \begin{exercise}[title=Answer the following in one sentence:] 49 | \begin{enumerate} 50 | \item Who is the President? 51 | \item Who is the Prime Minister? 52 | \printrandomexercises[collection=exercise-pool]{2} 53 | \end{enumerate} 54 | \end{exercise} 55 | 56 | \end{document} 57 | -------------------------------------------------------------------------------- /doc/examples/xsim.texsx-395273.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgnieder/xsim/06e3dba43b96ed493968ddd54add9fc8a1d9a264/doc/examples/xsim.texsx-395273.pdf -------------------------------------------------------------------------------- /doc/examples/xsim.texsx-395273.tex: -------------------------------------------------------------------------------- 1 | \documentclass{article} 2 | \usepackage{xsim,tcolorbox,needspace} 3 | 4 | % declare a boolean property: 5 | \DeclareExerciseProperty*{short} 6 | % declare a tag like property: 7 | \DeclareExerciseTagging{level} 8 | 9 | % declare a template which typesets exercises differently according to given 10 | % properties: 11 | \DeclareExerciseEnvironmentTemplate{exercise} 12 | {% 13 | \renewcommand*\theenumi{\theexercise.\arabic{enumi}}% 14 | \par\addvspace{\baselineskip} 15 | \Needspace*{2\baselineskip} 16 | \noindent 17 | \GetExercisePropertyT{level}{\marginpar{\sffamily Level: #1}}% 18 | \textbf{\XSIMmixedcase{\GetExerciseName}~\GetExerciseProperty{counter}.} % 19 | \GetExercisePropertyT{subtitle}{\textit{#1}}% 20 | \IfExerciseBooleanPropertyF{short}{\par\noindent}% 21 | } 22 | {} 23 | 24 | % declare a tcolorbox template for the solutions: 25 | \DeclareExerciseEnvironmentTemplate{solution} 26 | {\tcolorbox[colback=yellow,colframe=red]} 27 | {\endtcolorbox} 28 | 29 | % declare a user command for short answers: 30 | \NewDocumentCommand\answer{m}{% 31 | \IfSolutionPrintT{% 32 | \UseExerciseTemplate{begin}{solution}% 33 | #1% 34 | \UseExerciseTemplate{end}{solution}% 35 | }{}% 36 | } 37 | 38 | % setup exercises and solutions: 39 | \SetExerciseParameters{exercise}{ 40 | exercise-template = exercise , 41 | solution-template = solution 42 | } 43 | 44 | % remove this option to hide the answers: 45 | \xsimsetup{solution/print=true} 46 | 47 | \usepackage{lipsum} 48 | 49 | \begin{document} 50 | 51 | \begin{exercise}[level=hard,short] 52 | Just a short exercise 53 | \end{exercise} 54 | \begin{solution} 55 | The somewhat longer solution to the short exercise. \lipsum[1] 56 | \end{solution} 57 | 58 | \begin{exercise}[subtitle=This one has a title,level=easy] 59 | Answer the following questions. 60 | \begin{enumerate} 61 | \item question \answer{answer} 62 | \item question \answer{answer} 63 | \end{enumerate} 64 | \end{exercise} 65 | 66 | \begin{exercise} 67 | A long exercise. \lipsum[4]\answer{The answer} 68 | \end{exercise} 69 | 70 | \begin{exercise}[level=medium,short] 71 | Another short exercise.\answer{The answer} 72 | \end{exercise} 73 | 74 | \end{document} 75 | -------------------------------------------------------------------------------- /doc/examples/xsim.texsx-466584.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgnieder/xsim/06e3dba43b96ed493968ddd54add9fc8a1d9a264/doc/examples/xsim.texsx-466584.pdf -------------------------------------------------------------------------------- /doc/examples/xsim.texsx-466584.tex: -------------------------------------------------------------------------------- 1 | % https://tex.stackexchange.com/q/466584 2 | \documentclass{article} 3 | \usepackage{xsim} 4 | \usepackage{needspace} 5 | \usepackage{tasks} 6 | 7 | \DeclareExerciseEnvironmentTemplate{exandsol}{% 8 | \par\vspace{\baselineskip} 9 | \Needspace*{2\baselineskip} 10 | \noindent\sffamily 11 | \textbf{\XSIMmixedcase{\GetExerciseName}~\GetExerciseProperty{counter}}% 12 | \GetExercisePropertyT{subtitle}{\hspace{3em}{\small#1}}\par 13 | \normalfont 14 | }{} 15 | 16 | \DeclareExerciseEnvironmentTemplate{flushright}{% 17 | \begin{flushright} 18 | \begin{minipage}{.4\linewidth} 19 | \textsf{Solutions:}\par\normalfont 20 | }{% 21 | \end{minipage}% 22 | \end{flushright}% 23 | } 24 | 25 | \xsimsetup{ 26 | exercise/within = section , 27 | exercise/template = exandsol , 28 | solution/template = flushright , 29 | solution/print = true 30 | } 31 | 32 | \renewcommand*\theexercise{\thesection-\arabic{exercise}} 33 | \newcommand\QA[2]{\IfInsideSolutionTF{#2}{#1}} 34 | 35 | \newcommand*\answer[1]{% 36 | \begingroup 37 | \def\ExerciseType{exercise}% 38 | \IfSolutionPrintT{\printsolution{exercise}{#1}}% 39 | \endgroup 40 | } 41 | 42 | \begin{document} 43 | 44 | \setcounter{section}{1} 45 | \setcounter{exercise}{30} 46 | 47 | \begin{exercise}[ID=one,solution,subtitle=Factorize as much as possible the following expressions.] 48 | \begin{tasks} 49 | \task \QA{$(2x-3)^2 - (3x-2)^2 =$}{$-(x+5)(5x-1)$} 50 | \task \QA{$(x^2-25) - 2(5-x)(x+6) =$}{$(x+5)(3x-17)$} 51 | \task \QA{$2x(x+2) + (x+1)^2 + 2 =$}{$3(x+1)^2$} 52 | \end{tasks} 53 | \end{exercise} 54 | \answer{one} 55 | 56 | \end{document} 57 | -------------------------------------------------------------------------------- /doc/examples/xsim.texsx-498299.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgnieder/xsim/06e3dba43b96ed493968ddd54add9fc8a1d9a264/doc/examples/xsim.texsx-498299.pdf -------------------------------------------------------------------------------- /doc/examples/xsim.texsx-498299.tex: -------------------------------------------------------------------------------- 1 | % https://tex.stackexchange.com/q/498299 2 | \documentclass{article} 3 | \usepackage[no-files]{xsim} 4 | \usepackage{tasks} 5 | 6 | \DeclareExerciseEnvironmentTemplate{item} 7 | {\item[\GetExerciseProperty{counter}]} 8 | {} 9 | 10 | \DeclareExerciseProperty{answer} 11 | 12 | \newcommand*\answer[1]{% 13 | \XSIMexpandcode{% 14 | \SetExerciseProperty{answer} 15 | { (\noexpand\textit{\alph{task}}) \unexpanded{#1}}}% 16 | #1% 17 | } 18 | 19 | \newcommand*\getanswers{% 20 | \def\betweenanswers{\def\betweenanswers{\hspace{2em}}}% 21 | \ForEachUsedExerciseByID{% 22 | \betweenanswers##3\ExercisePropertyGet{##1}{##2}{answer}% 23 | }% 24 | } 25 | 26 | \xsimsetup{ 27 | exercise/template = item, 28 | exercise/the-counter = \arabic{exercise}. 29 | } 30 | 31 | \NewTasksEnvironment[ 32 | label = (\textit{\alph*}) , 33 | label-width = 14pt 34 | ]{choice}[\choice] 35 | 36 | \newenvironment{questions} 37 | {\itemize} 38 | {\enditemize} 39 | 40 | \begin{document} 41 | 42 | \section{Problems} 43 | \begin{questions} 44 | \begin{exercise} 45 | What is the product of $-2$ and $3$? 46 | \begin{choice}(4) 47 | \choice \answer{$-6$} 48 | \choice $6$ 49 | \choice $5$ 50 | \choice $-5$ 51 | \end{choice} 52 | \end{exercise} 53 | \begin{exercise} 54 | What is the sum of the sides of a polygon called? 55 | \begin{choice}(2) 56 | \choice Leg 57 | \choice \answer{Perimeter} 58 | \choice Area 59 | \choice Volume 60 | \end{choice} 61 | \end{exercise} 62 | \begin{exercise} 63 | What is the sum of $-2$ and $-3$? 64 | \begin{choice}(4) 65 | \choice $-6$ 66 | \choice $6$ 67 | \choice $5$ 68 | \choice \answer{$-5$} 69 | \end{choice} 70 | \end{exercise} 71 | \end{questions} 72 | 73 | \section{Answers} 74 | \getanswers 75 | 76 | \end{document} 77 | -------------------------------------------------------------------------------- /doc/examples/xsim.texsx-549540.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgnieder/xsim/06e3dba43b96ed493968ddd54add9fc8a1d9a264/doc/examples/xsim.texsx-549540.pdf -------------------------------------------------------------------------------- /doc/examples/xsim.texsx-549540.tex: -------------------------------------------------------------------------------- 1 | % https://tex.stackexchange.com/q/549540/ 2 | \documentclass[12pt]{article} 3 | \usepackage[T1]{fontenc} 4 | 5 | \usepackage{parskip} 6 | \usepackage{geometry} 7 | \geometry{ a4paper, left=5mm, right=5mm, top=15mm } 8 | 9 | \usepackage{amsmath,amssymb} 10 | 11 | \usepackage{multicol} 12 | \setlength{\columnsep}{1mm} 13 | \setlength{\columnseprule}{0.2pt} 14 | 15 | \usepackage[most]{tcolorbox} 16 | 17 | \usepackage{siunitx} 18 | \usepackage{xsim} 19 | \usepackage{tasks} 20 | 21 | \makeatletter 22 | \newtcolorbox{examtitle}[2][]{ 23 | halign=flush center, 24 | colframe=gray!70!black, 25 | fonttitle=\Large, 26 | enhanced, 27 | breakable, 28 | colback=white, 29 | attach boxed title to top right={yshift=-2pt}, title={#2}, 30 | boxed title size=standard, 31 | boxrule=0pt, 32 | boxed title style={ 33 | sharp corners, 34 | rounded corners=northeast, 35 | colback=tcbcolframe, 36 | boxrule=0pt}, 37 | sharp corners=north, 38 | overlay unbroken={ 39 | \path[fill=tcbcolback] 40 | ([xshift=2pt]title.south west) 41 | to[out=180, in=0] ([xshift=-1.5cm]title.west)-- 42 | (title.west-|frame.west) |- 43 | ([xshift=2pt]title.south west)--cycle; 44 | \path[fill=tcbcolframe] (title.south west) 45 | to[out=180, in=0] ([xshift=-1.5cm]title.west)-- 46 | (title.west-|frame.west) 47 | [rounded corners=\kvtcb@arc] |- 48 | (title.north-|frame.north) 49 | [sharp corners] -| (title.south west); 50 | \draw[line width=.5mm, rounded corners=\kvtcb@arc, 51 | tcbcolframe] 52 | (title.north east) rectangle 53 | (frame.south west); 54 | }, 55 | overlay first={ 56 | \path[fill=tcbcolback] 57 | ([xshift=2pt]title.south west) 58 | to[out=180, in=0] ([xshift=-1.5cm]title.west)-- 59 | (title.west-|frame.west) |- 60 | ([xshift=2pt]title.south west)--cycle; 61 | \path[fill=tcbcolframe] (title.south west) 62 | to[out=180, in=0] ([xshift=-1.5cm]title.west)-- 63 | (title.west-|frame.west) 64 | [rounded corners=\kvtcb@arc] |- 65 | (title.north-|frame.north) 66 | [sharp corners] -| (title.south west); 67 | \draw[line width=.5mm, rounded corners=\kvtcb@arc, 68 | tcbcolframe] 69 | (frame.south west) |- (title.north) -| 70 | (frame.south east); 71 | }, 72 | overlay middle={ 73 | \draw[line width=.5mm, tcbcolframe] 74 | (frame.north west)--(frame.south west) 75 | (frame.north east)--(frame.south east); 76 | }, 77 | overlay last={ 78 | \draw[line width=.5mm, rounded corners=\kvtcb@arc, 79 | tcbcolframe] 80 | (frame.north west) |- (frame.south) -| 81 | (frame.north east); 82 | }, 83 | #1 84 | } 85 | \makeatother 86 | 87 | \xsimsetup{ 88 | load-style = layouts , 89 | exercise/template = minimal , 90 | exercise/the-counter = \arabic{exercise}. , 91 | exercise/end-hook = \vspace{\baselineskip} 92 | } 93 | 94 | \NewTasksEnvironment[ 95 | label = (\Alph*) , 96 | label-format = \bfseries , 97 | label-width = 21pt 98 | ]{choices}[\choice] 99 | 100 | \DeclareExerciseProperty{answer} 101 | \newcommand*\answer[1]{% 102 | \SetExpandedExerciseProperty{answer}{ \thetask\ \unexpanded{#1}}% 103 | #1% 104 | } 105 | 106 | \newcommand*\getanswers{% 107 | \def\betweenanswers{\def\betweenanswers{\hspace{2em}}}% 108 | \ForEachUsedExerciseByID{% 109 | \betweenanswers##3\ExercisePropertyGet{##1}{##2}{answer}% 110 | }% 111 | } 112 | 113 | \begin{document} 114 | 115 | \begin{examtitle}{Test 1} 116 | Angles in parallel lines 117 | \end{examtitle} 118 | 119 | \begin{multicols*}{2} 120 | \begin{exercise} 121 | If the ratio of two supplementary angles is $\frac{4}{11}$, what is the 122 | measure of the small angle? 123 | \begin{choices}(5) 124 | \choice \ang{36} 125 | \choice \ang{44} 126 | \choice \answer{\ang{48}} 127 | \choice \ang{52} 128 | \choice \ang{60} 129 | \end{choices} 130 | \end{exercise} 131 | \begin{exercise} 132 | Is this really a question? 133 | \begin{choices}(4) 134 | \choice \answer{yes} 135 | \choice no 136 | \choice maybe 137 | \choice no idea 138 | \end{choices} 139 | \end{exercise} 140 | \begin{exercise} 141 | This really is a question! 142 | \begin{choices}(4) 143 | \choice yes 144 | \choice \answer{no} 145 | \choice maybe 146 | \choice no idea 147 | \end{choices} 148 | \end{exercise} 149 | \subsection*{Answers} 150 | \getanswers 151 | \end{multicols*} 152 | 153 | \end{document} 154 | -------------------------------------------------------------------------------- /doc/examples/xsim.texsx-576998.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgnieder/xsim/06e3dba43b96ed493968ddd54add9fc8a1d9a264/doc/examples/xsim.texsx-576998.pdf -------------------------------------------------------------------------------- /doc/examples/xsim.texsx-576998.tex: -------------------------------------------------------------------------------- 1 | % https://tex.stackexchange.com/q/576998 2 | \documentclass[twocolumn]{book} 3 | \usepackage{xsim} 4 | 5 | \DeclareExerciseEnvironmentTemplate{number-only}{% 6 | \par\noindent 7 | \textbf{\GetExerciseProperty{counter}}% 8 | \GetExercisePropertyT{subtitle}{ \textit{#1}} % 9 | }{\par} 10 | 11 | \newcommand\printsectionexercises{% 12 | \ForEachUsedExerciseByType{% 13 | \ifnum\ExercisePropertyGet{##1}{##2}{chapter-value}=\value{chapter} 14 | \ifnum\ExercisePropertyGet{##1}{##2}{section-value}=\value{section} 15 | \XSIMprint{exercise}{##1}{##2}% 16 | \fi 17 | \fi 18 | }% 19 | } 20 | 21 | \renewcommand\printsolutions{% 22 | \def\currentchapter{}% 23 | \def\currentsection{}% 24 | \def\lastchapter{}% 25 | \def\lastsection{}% 26 | \ForEachUsedExerciseByType{% 27 | \let\lastchapter\currentchapter 28 | \let\lastsection\currentsection 29 | \edef\currentchapter{\ExercisePropertyGet{##1}{##2}{chapter-value}}% 30 | \edef\currentsection{\ExercisePropertyGet{##1}{##2}{section-value}}% 31 | \ifx\lastchapter\currentchapter\else 32 | \section*{Chapter \ExercisePropertyGet{##1}{##2}{chapter}} 33 | \fi 34 | \ifx\lastsection\currentsection\else 35 | \subsection*{Exercises \ExercisePropertyGet{##1}{##2}{section}} 36 | \fi 37 | \XSIMprint{solution}{##1}{##2}% 38 | }% 39 | } 40 | 41 | \xsimsetup{ 42 | exercise/template = number-only , 43 | solution/template = number-only , 44 | exercise/within = section , 45 | exercise/the-counter = \arabic{exercise}. , 46 | exercise/print = false 47 | } 48 | 49 | \begin{document} 50 | 51 | \setcounter{chapter}{13} 52 | \chapter{} 53 | \section{Cats as pets} 54 | Text text text\dots 55 | \begin{exercise} 56 | Draw a cat. 57 | \end{exercise} 58 | \begin{solution} 59 | Drawing a cat. 60 | \end{solution} 61 | 62 | Text text text\dots 63 | \begin{exercise} 64 | Bathe a cat. 65 | \end{exercise} 66 | \begin{solution} 67 | Bathing a cat. 68 | \end{solution} 69 | 70 | Text text text\dots 71 | \begin{exercise} 72 | Trace the history of cats through time. 73 | \end{exercise} 74 | \begin{solution} 75 | Tracing the history of cats through time. 76 | \end{solution} 77 | 78 | \subsection*{Exercises \thesection} 79 | \printsectionexercises 80 | 81 | \section{Frogs as pets} 82 | Text text text\dots 83 | \begin{exercise} 84 | Lick a frog. 85 | \end{exercise} 86 | \begin{solution} 87 | Licking a frog. 88 | \end{solution} 89 | 90 | Text text text\dots 91 | \begin{exercise} 92 | Bathe a frog. 93 | \end{exercise} 94 | \begin{solution} 95 | Bathing a frog. 96 | \end{solution} 97 | 98 | Text text text\dots 99 | \begin{exercise} 100 | Feed a frog. 101 | \end{exercise} 102 | \begin{solution} 103 | Feeding a frog. 104 | \end{solution} 105 | 106 | \subsection*{Exercises \thesection} 107 | \printsectionexercises 108 | 109 | \setcounter{chapter}{20} 110 | \chapter{} 111 | 112 | \section{The joys of fish} 113 | Text text text\dots 114 | \begin{exercise} 115 | Catch a fish. 116 | \end{exercise} 117 | \begin{solution} 118 | Catching a fish. 119 | \end{solution} 120 | 121 | Text text text\dots 122 | \begin{exercise} 123 | Draw a fish. 124 | \end{exercise} 125 | \begin{solution} 126 | Drawing a fish. 127 | \end{solution} 128 | 129 | \subsection*{Exercises \thesection} 130 | \printsectionexercises 131 | 132 | \chapter*{Solutions to the exercises} 133 | \printsolutions 134 | 135 | \end{document} 136 | -------------------------------------------------------------------------------- /doc/examples/xsim.texsx-580636.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgnieder/xsim/06e3dba43b96ed493968ddd54add9fc8a1d9a264/doc/examples/xsim.texsx-580636.pdf -------------------------------------------------------------------------------- /doc/examples/xsim.texsx-580636.tex: -------------------------------------------------------------------------------- 1 | % https://tex.stackexchange.com/q/580636/ 2 | \documentclass{article} 3 | \usepackage[use-files]{xsim} 4 | 5 | \usepackage[colorlinks,allcolors=blue]{hyperref} 6 | 7 | \DeclareExerciseProperty{hints} 8 | \newcounter{hint} 9 | \renewcommand\theHhint{\ExerciseID.\arabic{hint}} 10 | \newcounter{hints} 11 | \newcounter{step} 12 | 13 | \NewDocumentEnvironment{hint}{}{% 14 | \stepcounter{hint}% 15 | \XSIMsetfilebegin{% 16 | \par 17 | \refstepcounter{hint}\label{hint:\ExerciseID:\arabic{hint}}% 18 | \noindent\textbf{Hint~\thehint\ to exercise \GetExerciseProperty{counter}}% 19 | \hfill Back to exercise \ref{ex:\ExerciseID}\par 20 | \noindent 21 | }% 22 | \XSIMsetfileend{\par\addvspace{\bigskipamount}}% 23 | \XSIMfilewritestart{\jobname-hint-\ExerciseID-\arabic{hint}.tex}% 24 | }{% 25 | \XSIMfilewritestop 26 | \stepcounter{hints}% 27 | \SetExpandedExerciseProperty{hints}{\arabic{hints}}% 28 | } 29 | 30 | \DeclareExerciseEnvironmentTemplate{hints}{% 31 | \setcounter{hint}{0}% 32 | \setcounter{hints}{0}% 33 | \par\noindent 34 | \textbf{\XSIMmixedcase{\GetExerciseName}\GetExerciseProperty{counter}:}\hfill 35 | \IfExercisePropertySetT{hints}{% 36 | \setcounter{step}{0}% 37 | \def\hintcomma{\def\hintcomma{, }}% 38 | Hint\ifnum\GetExerciseProperty{hints}=1\else s\fi: 39 | \loop\unless\ifnum\value{step}=\GetExerciseProperty{hints} 40 | \stepcounter{step}% 41 | \hintcomma\ref{hint:\ExerciseID:\arabic{step}}% 42 | \repeat 43 | \par\noindent 44 | }% 45 | }{\par\addvspace{\bigskipamount}} 46 | 47 | \xsimsetup{ 48 | exercise/within = section , 49 | exercise/begin-hook = \label{ex:\ExerciseID} , 50 | exercise/template = hints 51 | } 52 | 53 | \newcommand\printhints{% 54 | \ForEachUsedExerciseByType{% 55 | \setcounter{step}{0}% 56 | \setcounter{hint}{0}% 57 | \loop\unless\ifnum\value{step}=\GetExerciseProperty{hints} 58 | \stepcounter{step}% 59 | \input{\jobname-hint-\ExerciseID-\arabic{step}.tex}% 60 | \repeat 61 | }% 62 | } 63 | 64 | \begin{document} 65 | 66 | \section{Exercises} 67 | \begin{exercise} 68 | Description of the exercise. Run the following command 69 | \begin{verbatim} 70 | print("Hello world") 71 | Verbatim &^%$&\content 72 | \end{verbatim} 73 | \begin{hint} 74 | Run the example from the command line with the python command. 75 | \end{hint} 76 | \begin{hint} 77 | The solution is 42. 78 | \end{hint} 79 | \end{exercise} 80 | 81 | \begin{exercise} 82 | Another exercise 83 | \begin{hint} 84 | The first ten million years were the worst. Some \verb+&$+. 85 | \end{hint} 86 | \end{exercise} 87 | 88 | 89 | \section{Hints} 90 | \printhints 91 | 92 | \end{document} 93 | -------------------------------------------------------------------------------- /doc/examples/xsim.texwelt-15093.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgnieder/xsim/06e3dba43b96ed493968ddd54add9fc8a1d9a264/doc/examples/xsim.texwelt-15093.pdf -------------------------------------------------------------------------------- /doc/examples/xsim.texwelt-15093.tex: -------------------------------------------------------------------------------- 1 | % http://texwelt.de/wissen/fragen/15093/ 2 | \documentclass[paper=a4]{scrartcl} 3 | \usepackage[ngerman]{babel} 4 | 5 | \usepackage{xsim,needspace} 6 | 7 | \DeclareExerciseTagging{AFB} 8 | \DeclareExerciseEnvironmentTemplate{myexam} 9 | { 10 | \par\vspace{\baselineskip} 11 | \Needspace*{3\baselineskip} 12 | \noindent 13 | \textbf{\IfInsideSolutionTF{Lösung}{Aufgabe}~\GetExerciseProperty{counter}.}% 14 | \GetExercisePropertyT{subtitle}{\quad\textit{#1}}% 15 | \hfill 16 | \GetExercisePropertyT{AFB}{Schwierigkeit: #1}% 17 | \GetExercisePropertyT{points}{% 18 | \marginpar{% 19 | \PropertyValue 20 | \GetExercisePropertyT{bonus-points}{+\PropertyValue}% 21 | \,P.% 22 | }% 23 | }% 24 | \par\noindent 25 | } 26 | {} 27 | 28 | \xsimsetup{exercise/template=myexam} 29 | 30 | \begin{document} 31 | 32 | \begin{exercise}[subtitle=Eine Frage, AFB=1, points=3] 33 | Das ist eine sehr tolle Frage. 34 | \end{exercise} 35 | 36 | \begin{exercise}[AFB=2, points=3] 37 | Das ist eine sehr tolle Frage. 38 | \end{exercise} 39 | 40 | \begin{exercise}[AFB=3] 41 | Das ist eine sehr tolle Frage. 42 | \end{exercise} 43 | 44 | \begin{exercise}[subtitle=Eine andere Frage, AFB=4, points=3] 45 | Das ist eine sehr tolle Frage. 46 | \end{exercise} 47 | 48 | \begin{exercise}[subtitle=Eine Frage, AFB=2] 49 | Das ist eine sehr tolle Frage. 50 | \end{exercise} 51 | 52 | \end{document} 53 | 54 | % andere Idee: 55 | \documentclass[paper=a4]{scrartcl} 56 | \usepackage[utf8]{inputenc} 57 | \usepackage[ngerman]{babel} 58 | 59 | \usepackage{xsim} 60 | 61 | \DeclareExerciseTagging{AFB} 62 | 63 | \DeclareExerciseEnvironmentTemplate{AFB}{% 64 | \subsection*{% 65 | \XSIMmixedcase{\GetExerciseName}\nobreakspace 66 | \GetExerciseProperty{counter}% 67 | \IfExercisePropertySetT{subtitle}% 68 | { {\normalfont\itshape\GetExerciseProperty{subtitle}}}% 69 | } 70 | \marginpar{% 71 | \GetExercisePropertyT{AFB}{% 72 | \leavevmode\llap{Schwierigkeit: \PropertyValue\hspace*{\marginparsep}}% 73 | }% 74 | \GetExercisePropertyT{points}{% 75 | \PropertyValue 76 | \nobreakspace\XSIMtranslate{points}% 77 | }% 78 | }% 79 | }{} 80 | 81 | \DeclareExerciseEnvironmentTemplate{AFBsol}{% 82 | \subsection*{% 83 | \XSIMmixedcase{\GetExerciseName}\nobreakspace 84 | \GetExerciseProperty{counter}% 85 | \IfExercisePropertySetT{subtitle}% 86 | { {\normalfont\itshape\GetExerciseProperty{subtitle}}}% 87 | } 88 | \textit{\small 89 | \GetExercisePropertyT{AFB}{Schwierigkeit: \PropertyValue}% 90 | \GetExercisePropertyT{points}{% 91 | \IfExercisePropertySetT{AFB}{ }% 92 | (\PropertyValue\nobreakspace\XSIMtranslate{points})% 93 | }% 94 | }% 95 | \par\noindent 96 | }{} 97 | 98 | \DeclareExerciseTranslation{German}{default-heading}{Lösungen} 99 | 100 | \xsimsetup{ 101 | exercise/template=AFB , 102 | solution/template=AFBsol , 103 | exercise/name=Aufgabe 104 | } 105 | 106 | \begin{document} 107 | 108 | \begin{exercise}[subtitle=Eine Frage, AFB=1, points=3] 109 | Das ist eine sehr tolle Frage. 110 | \end{exercise} 111 | \begin{solution} 112 | Das ist eine tolle Lösung! 113 | \end{solution} 114 | \begin{exercise}[AFB=2, points=3] 115 | Das ist eine sehr tolle Frage. 116 | \end{exercise} 117 | 118 | \begin{exercise}[AFB=3] 119 | Das ist eine sehr tolle Frage. 120 | \end{exercise} 121 | 122 | \begin{exercise}[subtitle=Eine andere Frage, AFB=4, points=3] 123 | Das ist eine sehr tolle Frage. 124 | \end{exercise} 125 | 126 | \begin{exercise}[subtitle=Eine Frage, AFB=2] 127 | Das ist eine sehr tolle Frage. 128 | \end{exercise} 129 | 130 | \printsolutions 131 | 132 | \end{document} 133 | -------------------------------------------------------------------------------- /doc/examples/xsim.texwelt-23968.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgnieder/xsim/06e3dba43b96ed493968ddd54add9fc8a1d9a264/doc/examples/xsim.texwelt-23968.pdf -------------------------------------------------------------------------------- /doc/examples/xsim.texwelt-23968.tex: -------------------------------------------------------------------------------- 1 | % http://texwelt.de/wissen/fragen/23968/ 2 | \documentclass{article} 3 | \usepackage{xsim} 4 | 5 | % new property: 6 | \DeclareExerciseProperty{shortsolution} 7 | 8 | % new environment: 9 | \NewDocumentEnvironment{shortsolution}{+b} 10 | {% 11 | \edef\ExerciseType{\csname g_xsim_exercise_type_tl\endcsname}% 12 | \edef\ExerciseID{\csname g_xsim_exercise_id_tl\endcsname}% 13 | \SetExerciseProperty{shortsolution}{#1}% 14 | } 15 | {} 16 | 17 | % we'll use a description list for the list of short solutions: 18 | \newcommand\printshortsolutions{% 19 | \begin{description} 20 | \ForEachUsedExerciseByType{% 21 | \GetExercisePropertyT{shortsolution} 22 | {\item[Short Solution ##3]####1}% 23 | }% 24 | \end{description} 25 | } 26 | 27 | \begin{document} 28 | 29 | \section{Problems} 30 | % set shortsolution through option: 31 | \begin{exercise}[subtitle=Pythagoras] 32 | This is the first problem. 33 | \end{exercise} 34 | \begin{shortsolution} 35 | This is a shortsolution to the first problem. 36 | \end{shortsolution} 37 | \begin{solution} 38 | This is the solution to the first problem. 39 | \end{solution} 40 | 41 | \begin{exercise}[subtitle=Another Problem] 42 | This is the second problem. 43 | \end{exercise} 44 | \begin{solution} 45 | This is the solution to the second problem. 46 | \end{solution} 47 | 48 | % set shortsolution with custom command: 49 | \begin{exercise}[subtitle=Yet Another Problem] 50 | This is the third problem. 51 | \end{exercise} 52 | \begin{shortsolution} 53 | This is a shortsolution to the third problem. 54 | \end{shortsolution} 55 | \begin{solution} 56 | This is the solution to the third problem. 57 | \end{solution} 58 | 59 | \section{Shortsolutions} 60 | \printshortsolutions 61 | 62 | \section{Solutions} 63 | \printsolutions[headings=false] 64 | 65 | \end{document} 66 | -------------------------------------------------------------------------------- /doc/examples/xsim.texwelt-6698.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgnieder/xsim/06e3dba43b96ed493968ddd54add9fc8a1d9a264/doc/examples/xsim.texwelt-6698.pdf -------------------------------------------------------------------------------- /doc/examples/xsim.texwelt-6698.tex: -------------------------------------------------------------------------------- 1 | % http://texwelt.de/wissen/fragen/6698/ 2 | \documentclass{article} 3 | \usepackage[ngerman]{babel} 4 | 5 | \usepackage{needspace} 6 | \usepackage{xsim} 7 | \xsimsetup{ 8 | exercise/name = Aufgabe , 9 | solution/name = Lösung , 10 | exercise/within = section , 11 | exercise/the-counter = \thesection.\arabic{exercise} , 12 | exercise/template = mine 13 | } 14 | 15 | \newif\iflist 16 | 17 | \DeclareExerciseEnvironmentTemplate{mine}{ 18 | \par\vspace{\baselineskip} 19 | \Needspace*{3\baselineskip} 20 | \noindent 21 | \textbf{\GetExerciseName~\GetExerciseProperty{counter}}% 22 | \GetExercisePropertyT{subtitle}{\quad\textit{#1}}% 23 | \iflist 24 | \GetExercisePropertyT{page}{ (Seite~#1)}% 25 | \fi 26 | % not necessary if you don't use points: 27 | \GetExercisePropertyT{points}{% 28 | \marginpar{% 29 | \PropertyValue 30 | \GetExercisePropertyT{bonus-points}{+\PropertyValue}% 31 | \,\XSIMtranslate{points-abbr}% 32 | }% 33 | }% 34 | \par\noindent 35 | } 36 | {} 37 | 38 | \usepackage{multicol} 39 | 40 | \begin{document} 41 | 42 | \section{Erstes Kapitel} 43 | \begin{exercise} 44 | Eine erste Aufgabe 45 | \end{exercise} 46 | \begin{exercise} 47 | Eine zweite Aufgabe 48 | \end{exercise} 49 | 50 | \subsection{Erstes Unterkapitel} 51 | \begin{exercise} 52 | Eine Aufgabe in einem Unterkapitel 53 | \end{exercise} 54 | \begin{exercise} 55 | Noch eine Aufgabe in einem Unterkapitel 56 | \end{exercise} 57 | 58 | \subsubsection{Tiefer geschachteltes Unterkapitel} 59 | \begin{exercise} 60 | Noch eine Aufgabe 61 | \end{exercise} 62 | 63 | \subsubsection{Weiter geschachtelt} 64 | \begin{exercise} 65 | Eine weitere Aufgabe 66 | \end{exercise} 67 | 68 | \subsection{Zweites Unterkapitel} 69 | \begin{exercise} 70 | Und eine weitere Aufgabe 71 | \end{exercise} 72 | 73 | \clearpage 74 | 75 | \section{Zweites Kapitel} 76 | \begin{exercise} 77 | Eine Aufgabe in einem anderen Kapitel 78 | \end{exercise} 79 | 80 | \begin{multicols}{2}[\section{Aufgabenübersicht}] 81 | \listtrue 82 | \printcollection{all exercises} 83 | \end{multicols} 84 | 85 | \end{document} 86 | -------------------------------------------------------------------------------- /doc/examples/xsim.various.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgnieder/xsim/06e3dba43b96ed493968ddd54add9fc8a1d9a264/doc/examples/xsim.various.pdf -------------------------------------------------------------------------------- /doc/examples/xsim.various.tex: -------------------------------------------------------------------------------- 1 | \documentclass{article} 2 | \usepackage[use-files]{xsim} 3 | \usepackage{lipsum,tcolorbox} 4 | 5 | \DeclareExerciseType{question}{ 6 | exercise-env = question , 7 | solution-env = hint , 8 | exercise-name = Question , 9 | solution-name = Hint , 10 | exercise-template = default , 11 | solution-template = default , 12 | counter = exercise % shares a counter with the `exercise' type 13 | } 14 | 15 | \DeclareExerciseType{problem}{ 16 | exercise-env = problem , 17 | solution-env = answer , 18 | exercise-name = Problem , 19 | solution-name = Answer , 20 | exercise-template = tcolorbox , 21 | solution-template = tcolorbox 22 | } 23 | 24 | \DeclareExerciseProperty{grade} 25 | \DeclareExerciseProperty{difficulty} 26 | 27 | \tcbuselibrary{breakable} 28 | \DeclareExerciseEnvironmentTemplate{tcolorbox} 29 | {% 30 | \newcommand*\writehere{% 31 | \IfInsideSolutionTF{}{% 32 | \tcblower 33 | \emph{Your answer:} 34 | \vspace*{4cm} 35 | }% 36 | } 37 | \vspace{\baselineskip} 38 | \tcolorbox[ 39 | colback = red!5!white , 40 | colframe = red!75!black , 41 | colbacktitle = yellow!50!red , 42 | coltitle = red!25!black , 43 | fonttitle = \bfseries , 44 | subtitle style = { 45 | boxrule = 0.4pt , 46 | colback = yellow!50!red!25!white 47 | } , 48 | breakable , 49 | title = \GetExerciseName~\GetExerciseProperty{counter} 50 | \IfExercisePropertySetT{points}{% 51 | (\GetExerciseProperty{points} 52 | \IfExerciseGoalSingularTF{points} 53 | {\XSIMtranslate{point}} 54 | {\XSIMtranslate{points}})% 55 | }] 56 | \IfInsideSolutionF{% 57 | \IfExercisePropertySetT{tags}{% 58 | Tags: \ListExerciseTags{tags}{, } \par 59 | }% 60 | }% 61 | } 62 | {% 63 | \endtcolorbox 64 | \vspace{\baselineskip} 65 | } 66 | 67 | \xsimsetup{ 68 | % tags = {geometry} , 69 | % topics = {geometry} 70 | % tags/ingore-untagged % if true untagged exercise will be printed regardless 71 | % % which tags have been chosen 72 | } 73 | 74 | \begin{document} 75 | 76 | \gradingtable \par \bigskip 77 | 78 | Total: \printtotalpoints \par 79 | from questions: \printpoints{question} \par 80 | from exercises: \printpoints{exercise} \par 81 | from problems: \printpoints{problem} \par \bigskip 82 | 83 | Total bonus: \printtotalbonus \par 84 | from questions: \printbonus{question} \par 85 | from exercises: \printbonus{exercise} \par 86 | from problems: \printbonus{problem} \par 87 | 88 | % 1 89 | \begin{exercise}[points=4,bonus-points=1,topics=geometry,tags={geometry,triangles},grade=7] 90 | \lipsum[1] 91 | \begin{verbatim} 92 | foo x^2 y^3 \gna 93 | \end{verbatim} 94 | \end{exercise} 95 | \begin{solution}[print] 96 | This is the solution to \ExerciseType\ \GetExerciseProperty{counter}. 97 | \begin{verbatim} 98 | foo x^2 y^3 \gna 99 | \end{verbatim} 100 | \end{solution} 101 | 102 | % 2 103 | \begin{exercise}[subtitle=Foo,points=5,topics=analysis,tags={analysis,functions},grade=11] 104 | \lipsum[2] 105 | \end{exercise} 106 | \begin{solution} 107 | This is the solution to \ExerciseType\ \GetExerciseProperty{counter}. 108 | \end{solution} 109 | 110 | % 3 111 | \begin{problem}[tags={analysis,functions}] 112 | \lipsum[3] 113 | \writehere 114 | \end{problem} 115 | \begin{answer} 116 | This is the solution to \ExerciseType\ \GetExerciseProperty{counter}. 117 | \end{answer} 118 | 119 | % 4 120 | \begin{question} 121 | \lipsum[4] 122 | 123 | \verb+\ExerciseID+: \GetExerciseAliasProperty{ID} 124 | 125 | \verb+\GetExerciseProperty{id}+: \GetExerciseProperty{id} 126 | 127 | \verb+\GetExerciseAliasProperty{ID}+: \GetExerciseAliasProperty{ID} 128 | 129 | \verb+\GetExerciseProperty{ID}+: \GetExerciseProperty{ID} 130 | \end{question} 131 | \begin{hint} 132 | This is the solution to \ExerciseType\ \GetExerciseProperty{counter}. 133 | \end{hint} 134 | 135 | % 5 136 | \begin{problem}[points=2] 137 | \lipsum[3] 138 | 139 | \verb+\ExerciseID+: \GetExerciseAliasProperty{ID} 140 | 141 | \verb+\GetExerciseProperty{id}+: \GetExerciseProperty{id} 142 | 143 | \verb+\GetExerciseAliasProperty{ID}+: \GetExerciseAliasProperty{ID} 144 | 145 | \verb+\GetExerciseProperty{ID}+: \GetExerciseProperty{ID} 146 | \writehere 147 | \end{problem} 148 | \begin{answer} 149 | This is the solution to \ExerciseType\ \GetExerciseProperty{counter}. 150 | \end{answer} 151 | 152 | % 6 153 | \begin{problem}[points=1] 154 | \lipsum[3] 155 | 156 | \verb+\ExerciseID+: \GetExerciseAliasProperty{ID} 157 | 158 | \verb+\GetExerciseProperty{id}+: \GetExerciseProperty{id} 159 | 160 | \verb+\GetExerciseAliasProperty{ID}+: \GetExerciseAliasProperty{ID} 161 | 162 | \verb+\GetExerciseProperty{ID}+: \GetExerciseProperty{ID} 163 | \end{problem} 164 | \begin{answer} 165 | This is the solution to \ExerciseType\ \GetExerciseProperty{counter}. 166 | \end{answer} 167 | 168 | % 7 169 | \begin{exercise}[ID=test] 170 | \lipsum[5] 171 | 172 | \verb+\ExerciseID+: \GetExerciseAliasProperty{ID} 173 | 174 | \verb+\GetExerciseProperty{id}+: \GetExerciseProperty{id} 175 | 176 | \verb+\GetExerciseAliasProperty{ID}+: \GetExerciseAliasProperty{ID} 177 | 178 | \verb+\GetExerciseProperty{ID}+: \GetExerciseProperty{ID} 179 | \end{exercise} 180 | \begin{solution} 181 | This is the solution to \ExerciseType\ \GetExerciseProperty{counter}. 182 | \end{solution} 183 | 184 | % 8 185 | \begin{exercise}[print=false,use=false] 186 | \lipsum[5] 187 | \end{exercise} 188 | \begin{solution} 189 | This is the solution to \ExerciseType\ \GetExerciseProperty{counter}. 190 | \end{solution} 191 | 192 | % \printsolutionstype{exercise} 193 | 194 | \printsolutions* 195 | 196 | \section{Statistics} 197 | 198 | \ForEachUsedExerciseByType{% 199 | \noindent\XSIMmixedcase{\ExerciseParameterGet{#1}{exercise-name}}~#3: \\ 200 | \hspace*{2em}id: #2, type: #1, subtitle: #4, points: #5, bonus: #6\par \medskip 201 | } 202 | 203 | \bigskip 204 | 205 | \ForEachUsedExerciseByID{% 206 | \noindent\XSIMmixedcase{\ExerciseParameterGet{#1}{exercise-name}}~#3: \\ 207 | \hspace*{2em}id: #2, type: #1, subtitle: #4, points: #5, bonus: #6\par \medskip 208 | } 209 | 210 | \bigskip 211 | 212 | \ForEachUsedExerciseByType{% 213 | \ExercisePropertyIfSetT{#1}{#2}{points} 214 | { \XSIMmixedcase{\ExerciseParameterGet{#1}{exercise-name}}~#3: #5~points\par }% 215 | } 216 | 217 | \bigskip 218 | 219 | Number of questions: \numberofquestions \par 220 | Number of exercises: \numberofexercises \par 221 | Number of problems: \numberofproblems 222 | 223 | \section{Grading tables} 224 | 225 | \gradingtable[template=default*,type=exercise] \par \bigskip 226 | 227 | \gradingtable[template=default*,type=problem] \par \bigskip 228 | 229 | \gradingtable[template=default*] \par \bigskip 230 | 231 | % vertical 232 | \gradingtable[type=exercise] \par \bigskip 233 | 234 | \gradingtable[type=problem] \par \bigskip 235 | 236 | \gradingtable 237 | 238 | \end{document} 239 | -------------------------------------------------------------------------------- /doc/xsim-manual.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgnieder/xsim/06e3dba43b96ed493968ddd54add9fc8a1d9a264/doc/xsim-manual.pdf -------------------------------------------------------------------------------- /xsim.build: -------------------------------------------------------------------------------- 1 | # ---------------------------------------------------------------------------- 2 | # the XSIM package 3 | # 4 | # eXercise Sheets IMproved 5 | # 6 | # ---------------------------------------------------------------------------- 7 | # Clemens Niederberger 8 | # Web: https://github.com/cgnieder/xsim 9 | # E-Mail: contact@mychemistry.eu 10 | # ---------------------------------------------------------------------------- 11 | # Copyright 2017--2022 Clemens Niederberger 12 | # 13 | # -------------------------------------------------------------------------- 14 | # this is a personal bash script to build the xsim package 15 | # and very likely not of use for anybody else 16 | # 17 | # !! USE WITH CAUTION !! 18 | # 19 | # -------------------------------------------------------------------------- 20 | #!/bin/bash 21 | 22 | pkgname="xsim" 23 | moduleext="code.tex" 24 | styname="${pkgname}.sty" 25 | verbname="${pkgname}verb.sty" 26 | layoutsname="${pkgname}.style.layouts.code.tex" 27 | program="arara" 28 | manualfile="${pkgname}-manual" 29 | zipname="$pkgname" 30 | 31 | build=true 32 | cleancode=false 33 | cleandoc=false 34 | cleanexamples=false 35 | cleanup=false 36 | createzip=false 37 | manual=false 38 | runmktexlsr=false 39 | update=false 40 | silent=false 41 | 42 | usage="script for buiding the $pkgname package 43 | 44 | ./$(basename "$0") [option(s) [value]] 45 | 46 | where valid options are: 47 | -b build sty file from modules (default: $build) 48 | -d deletes auxiliary files from a latex compilation 49 | allowed values: 'none', 'all', 'code', 'doc', 'examples' (default: 'none') 50 | -f name of manual file (without .tex) (default: '$manualfile') 51 | -h show this help 52 | -l run latex to (re-) create manual (default: $manual) 53 | -m run mktexlsr, only when used together with -u (default: $runmktexlsr) 54 | -n do nothing and exit 55 | -o output file for creating the style file (default: '$styname') 56 | -p program for building the manual (default: '$program') 57 | -s silent, avoid messages (default: $silent) 58 | -u update local tex repository (default: $update) 59 | -z create zip file for CTAN upload (default: $createzip)" 60 | 61 | # options: 62 | while [ -n "$1" ]; do 63 | case "$1" in 64 | -b|--build) 65 | case "$2" in 66 | true) 67 | shift ;; 68 | false) 69 | build=false 70 | shift ;; 71 | *) ;; 72 | esac ;; 73 | -d|--delete) 74 | case "$2" in 75 | none) 76 | cleanup=false ;; 77 | all) 78 | cleanup=true 79 | cleancode=true 80 | cleandoc=true 81 | cleanexamples=true ;; 82 | code) 83 | cleanup=true 84 | cleancode=true ;; 85 | doc) 86 | cleanup=true 87 | cleandoc=true ;; 88 | examples) 89 | cleanup=true 90 | cleanexamples=true ;; 91 | *) 92 | echo "invalid value '$2'" 93 | exit 1 ;; 94 | esac 95 | shift ;; 96 | -f|--file) 97 | manualfile="$2" 98 | shift ;; 99 | -h|--help) 100 | echo "$usage" 101 | exit 0 ;; 102 | -l|--latex) 103 | case "$2" in 104 | true) 105 | manual=true 106 | shift ;; 107 | false) 108 | manual=false 109 | shift ;; 110 | *) 111 | manual=true ;; 112 | esac ;; 113 | -m|--mktexlsr) 114 | case "$2" in 115 | true) 116 | runmktexlsr=true 117 | shift ;; 118 | false) 119 | runmktexlsr=false 120 | shift ;; 121 | *) 122 | runmktexlsr=true ;; 123 | esac ;; 124 | -n|--nothing) 125 | exit 0 ;; 126 | -o|--output) 127 | styname="$2" 128 | shift ;; 129 | -p|--program) 130 | program="$2" 131 | shift ;; 132 | -s|--silent) 133 | case "$2" in 134 | true) 135 | slient=true 136 | shift ;; 137 | false) 138 | silent=false 139 | shift ;; 140 | *) 141 | silent=true ;; 142 | esac ;; 143 | -u|--update) 144 | case "$2" in 145 | true) 146 | update=true 147 | shift ;; 148 | false) 149 | update=false 150 | shift ;; 151 | *) 152 | update=true ;; 153 | esac ;; 154 | -v|--version) 155 | zipname="${zipname}_v$2" 156 | shift ;; 157 | -z|--zip) 158 | case "$2" in 159 | true) 160 | createzip=true 161 | shift ;; 162 | false) 163 | createzip=false 164 | shift ;; 165 | *) 166 | createzip=true ;; 167 | esac ;; 168 | *) echo "unknown option '$1'" 169 | exit 1 ;; 170 | esac 171 | shift 172 | done 173 | 174 | if [ "$silent" == true ] ; then 175 | verbose=false 176 | else 177 | verbose=true 178 | fi 179 | 180 | START_DIR="${PWD}" 181 | DEV_DIR=~/LaTeX/dev 182 | SNAPSHOT_DIR=~/LaTeX/snapshots 183 | XSIM_DEV_DIR=${DEV_DIR}/$pkgname 184 | CODE_DIR=${XSIM_DEV_DIR}/code 185 | DOC_DIR=${XSIM_DEV_DIR}/doc 186 | EXAMPLES_DIR=${DOC_DIR}/examples 187 | TEXMFLOCAL_DIR=/usr/local/texlive/texmf-local 188 | LATEXLOCAL_DIR=${TEXMFLOCAL_DIR}/tex/latex/local 189 | BIBLOCAL_DIR=${TEXMFLOCAL_DIR}/bibtex/bib/local 190 | 191 | # files to be "cleaned": 192 | AUX_FILES="" 193 | if [ "$cleanup" == true ] ; then 194 | if [ "$cleancode" == true ] ; then 195 | AUX_FILES="${AUX_FILES} 196 | ${CODE_DIR}/*~" 197 | fi 198 | if [ "$cleandoc" == true ] ; then 199 | AUX_FILES="${AUX_FILES} 200 | ${DOC_DIR}/*~ 201 | ${DOC_DIR}/*synctex* 202 | ${DOC_DIR}/*.run.xml 203 | ${DOC_DIR}/*.aux 204 | ${DOC_DIR}/*.acr 205 | ${DOC_DIR}/*.xsim 206 | ${DOC_DIR}/*.log 207 | ${DOC_DIR}/*.out 208 | ${DOC_DIR}/*.bbl 209 | ${DOC_DIR}/*.bcf 210 | ${DOC_DIR}/*.bib 211 | ${DOC_DIR}/*.blg 212 | ${DOC_DIR}/*.idx 213 | ${DOC_DIR}/*.ilg 214 | ${DOC_DIR}/*.ind 215 | ${DOC_DIR}/*.tmp 216 | ${DOC_DIR}/*.toc 217 | ${DOC_DIR}/*.lof 218 | ${DOC_DIR}/*.lot" 219 | fi 220 | if [ "$cleanexamples" == true ] ; then 221 | AUX_FILES="${AUX_FILES} 222 | ${EXAMPLES_DIR}/*~ 223 | ${EXAMPLES_DIR}/*synctex* 224 | ${EXAMPLES_DIR}/*.run.xml 225 | ${EXAMPLES_DIR}/*.aux 226 | ${EXAMPLES_DIR}/*.acr 227 | ${EXAMPLES_DIR}/*.xsim 228 | ${EXAMPLES_DIR}/*.log 229 | ${EXAMPLES_DIR}/*.out 230 | ${EXAMPLES_DIR}/*.bbl 231 | ${EXAMPLES_DIR}/*.bcf 232 | ${EXAMPLES_DIR}/*.bib 233 | ${EXAMPLES_DIR}/*.blg 234 | ${EXAMPLES_DIR}/*.idx 235 | ${EXAMPLES_DIR}/*.ilg 236 | ${EXAMPLES_DIR}/*.ind 237 | ${EXAMPLES_DIR}/*.tmp 238 | ${EXAMPLES_DIR}/*.toc 239 | ${EXAMPLES_DIR}/*.lof 240 | ${EXAMPLES_DIR}/*.lot 241 | ${EXAMPLES_DIR}/*-body.tex" 242 | fi 243 | fi 244 | 245 | 246 | if [ "$build" == true ] ; then 247 | if [ "$verbose" == true ] ; then 248 | echo "writing style file $styname ..." 249 | fi 250 | # change to the code directory 251 | cd ${CODE_DIR} 252 | # build sty file from modules: 253 | cat \ 254 | $pkgname.start.$moduleext \ 255 | $pkgname.base.$moduleext \ 256 | $pkgname.auxfile.$moduleext \ 257 | $pkgname.properties.$moduleext \ 258 | $pkgname.environments.$moduleext \ 259 | $pkgname.templates.$moduleext \ 260 | $pkgname.tags.$moduleext \ 261 | $pkgname.goals.$moduleext \ 262 | $pkgname.exercises.$moduleext \ 263 | $pkgname.solutions.$moduleext \ 264 | $pkgname.collections.$moduleext \ 265 | $pkgname.blanks.$moduleext \ 266 | $pkgname.grades.$moduleext \ 267 | $pkgname.random.$moduleext \ 268 | $pkgname.translations.$moduleext \ 269 | $pkgname.interface.$moduleext \ 270 | $pkgname.definitions.$moduleext \ 271 | > $styname 272 | # append necessary end: 273 | echo -e "% finish package:\n\ 274 | \\hook_gput_code:nnn {enddocument} {toplevel} { \\\\xsim_close_aux:\\\\xsim_do_rerun: }\n\ 275 | %----------------------------------------------------------------------------\n\ 276 | \\\\file_input_stop:"\ 277 | >> $styname 278 | # build xsimverb.sty 279 | if [ "$verbose" == true ] ; then 280 | echo "writing style file $verbname ..." 281 | fi 282 | cat \ 283 | ${pkgname}verb.start.$moduleext \ 284 | $pkgname.verbwrite.$moduleext \ 285 | > $verbname 286 | fi 287 | 288 | # build manual 289 | if [ "$manual" == true ] ; then 290 | cd ${DOC_DIR} 291 | if [ "$verbose" == true ] ; then 292 | echo "running '$program' on '$manualfile'..." 293 | fi 294 | $program $manualfile 295 | fi 296 | 297 | # remove temporary and auxiliary files 298 | if [ "$cleanup" == true ] ; then 299 | if [ "$verbose" == true ] ; then 300 | echo "deleting auxiliary files..." 301 | fi 302 | for file in ${AUX_FILES} 303 | do 304 | if [ ! -e "${file}" ]; then continue 305 | else 306 | if [ "$verbose" == true ] ; then 307 | echo "deleting file '${file}' ..." 308 | fi 309 | rm "${file}" 310 | fi 311 | done 312 | fi 313 | 314 | # move new sty file to local repo 315 | if [ "$update" == true ] ; then 316 | if [ "$verbose" == true ] ; then 317 | echo "updating texmf-local..." 318 | fi 319 | if [ ! -d "${LATEXLOCAL_DIR}/$pkgname" ]; then 320 | if [ "$verbose" == true ] ; then 321 | echo "creating directory '${LATEXLOCAL_DIR}/$pkgname' ..." 322 | fi 323 | mkdir ${LATEXLOCAL_DIR}/$pkgname 324 | fi 325 | cd ${CODE_DIR} 326 | cp $styname ${LATEXLOCAL_DIR}/$pkgname 327 | cp $verbname ${LATEXLOCAL_DIR}/$pkgname 328 | cp $layoutsname ${LATEXLOCAL_DIR}/$pkgname 329 | if [ "$runmktexlsr" == true ] ; then 330 | if [ "$verbose" == true ] ; then 331 | echo "running mktexlsr ..." 332 | fi 333 | mktexlsr 334 | fi 335 | fi 336 | 337 | if [ "$createzip" == true ] ; then 338 | if [ -f "${SNAPSHOT_DIR}/$pkgname/$zipname.zip" ] ; then 339 | rm ${SNAPSHOT_DIR}/$pkgname/$zipname.zip 340 | fi 341 | if [ "$verbose" == true ] ; then 342 | echo "creating zip archive $zipname.zip ..." 343 | fi 344 | cd ${XSIM_DEV_DIR} 345 | mkdir $pkgname/ 346 | mkdir $pkgname/examples 347 | cp ${CODE_DIR}/$styname $pkgname/ 348 | cp ${CODE_DIR}/$verbname $pkgname/ 349 | cp ${CODE_DIR}/$layoutsname $pkgname/ 350 | cp ${DOC_DIR}/$manualfile.tex $pkgname/ 351 | cp ${DOC_DIR}/$manualfile.pdf $pkgname/ 352 | cp ${DOC_DIR}/$manualfile.cls $pkgname/ 353 | cp ${DOC_DIR}/examples/$pkgname.*.tex $pkgname/examples/ 354 | cp ${DOC_DIR}/examples/$pkgname.*.pdf $pkgname/examples/ 355 | cp README $pkgname/ 356 | cp HISTORY $pkgname/ 357 | zip -r $zipname.zip $pkgname/ 358 | rm -r $pkgname/ 359 | mv $zipname.zip ${SNAPSHOT_DIR}/$pkgname 360 | fi 361 | 362 | cd ${START_DIR} 363 | 364 | exit 0 365 | --------------------------------------------------------------------------------