diff options
author | Karl Berry <karl@freefriends.org> | 2017-05-19 21:12:44 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2017-05-19 21:12:44 +0000 |
commit | b6a9d061f27e2822b7de379c66c030d9ea0e8fb3 (patch) | |
tree | 7a9b6e488d40920bb153db1f0e7be10f8df3935a /Master | |
parent | 910f589664407d620dc2a30c7b1de1a10e715df1 (diff) |
xsim (19may17)
git-svn-id: svn://tug.org/texlive/trunk@44430 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master')
84 files changed, 10586 insertions, 1 deletions
diff --git a/Master/texmf-dist/doc/latex/xsim/README b/Master/texmf-dist/doc/latex/xsim/README new file mode 100644 index 00000000000..b8da799ff7d --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/README @@ -0,0 +1,83 @@ +-------------------------------------------------------------------------- +XSIM 2017/05/19 v0.8a + + eXercise Sheets IMproved + +-------------------------------------------------------------------------- +Clemens Niederberger +Web: https://github.com/cgnieder/xsim +E-Mail: contact@mychemistry.eu +-------------------------------------------------------------------------- +Copyright 2017 Clemens Niederberger + +This work may be distributed and/or modified under the +conditions of the LaTeX Project Public License, either version 1.3 +of this license or (at your option) any later version. +The latest version of this license is in + http://www.latex-project.org/lppl.txt +and version 1.3 or later is part of all distributions of LaTeX +version 2005/12/01 or later. + +This work has the LPPL maintenance status `maintained'. + +The Current Maintainer of this work is Clemens Niederberger. +-------------------------------------------------------------------------- +The xsim package consists of the code files: + xsim.sty + xsimverb.sty + xsim.base.code.tex + xsim.blanks.code.tex + xsim.collections.code.tex + xsim.definitions.code.tex + xsim.environments.code.tex + xsim.exercises.code.tex + xsim.goals.code.tex + xsim.grades.code.tex + xsim.interface.code.tex + xsim.modules.code.tex + xsim.properties.code.tex + xsim.random.code.tex + xsim.solutions.code.tex + xsim.tags.code.tex + xsim.templates.code.tex + xsim.translations.code.tex + xsim.verbwrite.code.tex +-------------------------------------------------------------------------- +The xsim package consists of the documentation files: + README + xsim.history, xsim.ideas + xsim_manual.tex, xsim_manual.pdf + xsim-manual.cls +-------------------------------------------------------------------------- +The xsim package consists of the example files: + xsim.blanks.tex, xsim.blanks.pdf + xsim.boxed-headings.tex, xsim.boxed-headings.pdf + xsim.code-and-output.tex, xsim.code-and-output.pdf + xsim.collections.tex, xsim.collections.pdf + xsim.crossref.tex, xsim.crossref.pdf + xsim.description-list.tex, xsim.description-list.pdf + xsim.different-point-types.tex, xsim.different-point-types.pdf + xsim.difficulties.tex, xsim.difficulties.pdf + xsim.floating.tex, xsim.floating.pdf + xsim.grade-distribution.tex, xsim.grade-distribution.pdf + xsim.listings.tex, xsim.listings.pdf + xsim.multiplechoice.tex, xsim.multiplechoice.pdf + xsim.pointsums.tex, xsim.pointsums.pdf + xsim.randomexercises.tex, xsim.randomexercises.pdf + xsim.various.tex, xsim.various.pdf + xsim.texsx-199360.tex, xsim.texsx-199360.pdf + xsim.texsx-299534.tex, xsim.texsx-299534.pdf + xsim.texsx-305110.tex, xsim.texsx-305110.pdf + xsim.texsx-338165.tex, xsim.texsx-338165.pdf + xsim.texsx-350028.tex, xsim.texsx-350028.pdf + xsim.texsx-369065.tex, xsim.texsx-369065.pdf + xsim.texsx-369803.tex, xsim.texsx-369803.pdf + xsim.texsx-369686.tex, xsim.texsx-369686.pdf + xsim.texwelt-6698.tex, xsim.texwelt-6698.pdf + xsim.texwelt-15093.tex, xsim.texwelt-15093.pdf + xsim.golatex-16824.tex, xsim.golatex-16824.pdf + xsim.golatex-18844.tex, xsim.golatex-18844.pdf +-------------------------------------------------------------------------- +If you have any ideas, questions, suggestions or bugs to report, please +feel free to contact me. +-------------------------------------------------------------------------- diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.blanks.pdf b/Master/texmf-dist/doc/latex/xsim/examples/xsim.blanks.pdf Binary files differnew file mode 100644 index 00000000000..dd26d671570 --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.blanks.pdf diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.blanks.tex b/Master/texmf-dist/doc/latex/xsim/examples/xsim.blanks.tex new file mode 100644 index 00000000000..b479e961c2c --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.blanks.tex @@ -0,0 +1,23 @@ +\documentclass{article} +\usepackage[utf8]{inputenc} +\usepackage[ngerman]{babel} + +\usepackage{xsim,lipsum,xcolor} + +\xsimsetup{ + solution/print = true , + blank/filled-style = \underline{\textcolor{red}{#1}} +} + +\begin{document} + +\begin{exercise}[points=3] + Erklären Sie den Begriff. + + \blank[width=4\linewidth,linespread=1.5]{} +\end{exercise} +\begin{solution} + \blank[width=4\linewidth,linespread=1.5]{Die Lösung hier soll rot sein.} +\end{solution} + +\end{document} diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.boxed-headings.pdf b/Master/texmf-dist/doc/latex/xsim/examples/xsim.boxed-headings.pdf Binary files differnew file mode 100644 index 00000000000..99ba5bbc2a6 --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.boxed-headings.pdf diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.boxed-headings.tex b/Master/texmf-dist/doc/latex/xsim/examples/xsim.boxed-headings.tex new file mode 100644 index 00000000000..9ff47d9d992 --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.boxed-headings.tex @@ -0,0 +1,30 @@ +\documentclass{article} + +\usepackage{tcolorbox} +\usepackage{xsim} +\usepackage{needspace} + +\DeclareExerciseEnvironmentTemplate{custom} + {% + \Needspace*{5\baselineskip} + \begin{tcolorbox} + \textbf{\XSIMmixedcase{\GetExerciseName}~\GetExerciseProperty{counter}.}% + \GetExercisePropertyT{subtitle}{ \textit{#1}}% + \end{tcolorbox} + \noindent + } + {\vspace{\baselineskip}} + +\xsimsetup{exercise/template = custom} + +\usepackage{lipsum} + +\begin{document} + +\begin{exercise}[subtitle=Foo bar baz] + \lipsum[1] +\end{exercise} + +\lipsum[2] + +\end{document} diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.code-and-output.pdf b/Master/texmf-dist/doc/latex/xsim/examples/xsim.code-and-output.pdf Binary files differnew file mode 100644 index 00000000000..bbbcfbc18a7 --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.code-and-output.pdf diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.code-and-output.tex b/Master/texmf-dist/doc/latex/xsim/examples/xsim.code-and-output.tex new file mode 100644 index 00000000000..f753f13939e --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.code-and-output.tex @@ -0,0 +1,53 @@ +\documentclass{article} +\usepackage{xsimverb,listings,xcolor} + +\lstdefinestyle{mystyle}{ + language = [AlLaTeX]TeX , + basicstyle = \ttfamily , + columns = fullflexible , + commentstyle = \color{gray!70} , + keywordstyle = \color{red!70!black} +} + +\makeatletter +\NewDocumentEnvironment{example}{o} + {% + \XSIMgobblechars{2}% + \XSIMsetfilebegin{\@percentchar\space file `\jobname.tmp'}% + \XSIMsetfileend{\@percentchar\space bye bye}% + \IfNoValueTF{#1} + {\XSIMfilewritestart*{\jobname.tmp}} + {\XSIMfilewritestart{\jobname.tmp}}% + } + {% + \XSIMfilewritestop + \lstinputlisting[style=mystyle]{\jobname.tmp}% + \input{\jobname.tmp} + } + +\NewDocumentEnvironment{code}{o} + {% + \XSIMgobblechars{2}% + \IfNoValueTF{#1} + {\XSIMfilewritestart*{\jobname.tmp}} + {\XSIMfilewritestart{\jobname.tmp}}% + } + {% + \XSIMfilewritestop + \lstinputlisting[style=mystyle]{\jobname.tmp}% + } +\makeatother + +\begin{document} + +\begin{example} + bla bla \LaTeX +\end{example} + +\bigskip + +\begin{code} + blubber \LaTeX +\end{code} + +\end{document} diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.collections.pdf b/Master/texmf-dist/doc/latex/xsim/examples/xsim.collections.pdf Binary files differnew file mode 100644 index 00000000000..fd785cc0574 --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.collections.pdf diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.collections.tex b/Master/texmf-dist/doc/latex/xsim/examples/xsim.collections.tex new file mode 100644 index 00000000000..beca1910055 --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.collections.tex @@ -0,0 +1,62 @@ +\documentclass{article} +\usepackage{xsim} + +\DeclareExerciseCollection{foo-easy} +\DeclareExerciseCollection{foo-medium} +\DeclareExerciseTagging{difficulty} + +\usepackage{filecontents,lipsum} +\begin{filecontents*}{foo.tex} +\begin{exercise}[difficulty=easy,points=1] + foo one \lipsum[4] +\end{exercise} +\begin{solution} + foo one \lipsum[4] +\end{solution} +\begin{exercise}[difficulty=medium,points=1] + foo two \lipsum[4] +\end{exercise} +\begin{solution} + foo two \lipsum[4] +\end{solution} +\begin{exercise}[difficulty=easy,points=1] + foo three \lipsum[4] +\end{exercise} +\begin{solution} + foo three \lipsum[4] +\end{solution} +\end{filecontents*} + +\begin{document} + +\begin{exercise} + outside before +\end{exercise} + +\collectexercises{foo-easy} +\xsimsetup{difficulty=easy} +\input{foo.tex} +\collectexercisesstop{foo-easy} +% collection `foo-easy' now contains all exercises of file `foo.tex' tagged +% with `difficulty=easy' + +\collectexercises{foo-medium} +\xsimsetup{difficulty=medium} +\input{foo.tex} +\collectexercisesstop{foo-medium} +% collection `foo-medium' now contains all exercises of file `foo.tex' +% tagged with `difficulty=medium' + +\section{Easy} +\printcollection{foo-easy} + +\section{Medium} +\printcollection{foo-medium} + +\printsolutions[difficulty=medium] + +\section{All Exercises and Their Solutions Again, in Order of Appearance} + +\printcollection[print=both]{all exercises} + +\end{document} diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.crossref.pdf b/Master/texmf-dist/doc/latex/xsim/examples/xsim.crossref.pdf Binary files differnew file mode 100644 index 00000000000..8151a0cef3f --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.crossref.pdf diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.crossref.tex b/Master/texmf-dist/doc/latex/xsim/examples/xsim.crossref.tex new file mode 100644 index 00000000000..fa2fbbb509d --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.crossref.tex @@ -0,0 +1,60 @@ +\documentclass{article} +\usepackage{xsim,lipsum,hyperref} + +\DeclareExerciseHeadingTemplate{custom} + {\section{\XSIMtranslate{default-heading}}} + +\DeclareExerciseEnvironmentTemplate{custom} + {% + \IfInsideSolutionTF + {\label{sol:\ExerciseID}} + {\label{ex:\ExerciseID}} + \subsection* + {% + \XSIMmixedcase{\GetExerciseName}% + \IfInsideSolutionTF + { + to \GetExerciseParameter{exercise-name}% + ~\GetExerciseProperty{counter}% + } + {% + ~\GetExerciseProperty{counter} + \GetExercisePropertyT{subtitle} + { {\normalfont\itshape\PropertyValue}}% + }% + } + \noindent\llap{% + \footnotesize\sffamily + \IfInsideSolutionTF + {% + \XSIMmixedcase{\GetExerciseParameter{exercise-name}} + on page~\pageref{ex:\ExerciseID}.% + } + {% + \XSIMmixedcase{\GetExerciseParameter{solution-name}} + on page~\pageref{sol:\ExerciseID}.% + }% + \hspace*{\marginparsep}% + }% + } + {} +\xsimsetup{ + exercise/template = custom , + solution/template = custom , + print-solutions/headings-template = custom +} + +\begin{document} + +\section{Exercises} +\begin{exercise} + \lipsum[4] +\end{exercise} +\begin{solution} + \lipsum[4] +\end{solution} + +\clearpage +\printsolutions + +\end{document} diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.description-list.pdf b/Master/texmf-dist/doc/latex/xsim/examples/xsim.description-list.pdf Binary files differnew file mode 100644 index 00000000000..d506ad960bc --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.description-list.pdf diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.description-list.tex b/Master/texmf-dist/doc/latex/xsim/examples/xsim.description-list.tex new file mode 100644 index 00000000000..f3c9ed6d74f --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.description-list.tex @@ -0,0 +1,42 @@ +\documentclass{article} +\usepackage{xsim,lipsum} + +\DeclareExerciseEnvironmentTemplate{item} + {\item[\XSIMmixedcase{\GetExerciseName}~\GetExerciseProperty{counter}]} + {} +\xsimsetup{ + exercise/template=item, + solution/template=item, + print-solutions/headings-template=none +} + +\newenvironment{exercises} + {\section{Exercises}\description} + {\enddescription} + +\newenvironment{solutions} + {\section{Solutions}\description} + {\enddescription} + +\begin{document} + +\begin{exercises} + \begin{exercise} + \lipsum[4] + \end{exercise} + \begin{solution} + \lipsum[3] + \end{solution} + \begin{exercise} + \lipsum[12] + \end{exercise} + \begin{solution} + \lipsum[23] + \end{solution} +\end{exercises} + +\begin{solutions} + \printsolutions +\end{solutions} + +\end{document} diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.different-point-types.pdf b/Master/texmf-dist/doc/latex/xsim/examples/xsim.different-point-types.pdf Binary files differnew file mode 100644 index 00000000000..b1de5d63253 --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.different-point-types.pdf diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.different-point-types.tex b/Master/texmf-dist/doc/latex/xsim/examples/xsim.different-point-types.tex new file mode 100644 index 00000000000..0ac35367760 --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.different-point-types.tex @@ -0,0 +1,52 @@ +\documentclass{article} +\usepackage{xsim} + +\DeclareExerciseGoal{A} +\DeclareExerciseGoal{C} +\DeclareExerciseGoal{E} + +\newcommand*\printA{\TotalExerciseGoal{A}{~A~point}{~A~points}} +\newcommand*\printC{\TotalExerciseGoal{C}{~C~point}{~C~points}} +\newcommand*\printE{\TotalExerciseGoal{E}{~E~point}{~E~points}} + +\usepackage{needspace} +\DeclareExerciseEnvironmentTemplate{custom} + {% + \par\vspace{\baselineskip} + \Needspace*{2\baselineskip} + \noindent + \textbf{\GetExerciseProperty{counter}}% + \IfExercisePropertySetT{subtitle} + { \textit{\GetExerciseProperty{subtitle}}} % + \IfInsideSolutionF{% + \marginpar{% + (\IfExercisePropertySetTF{E}{\GetExerciseProperty{E}}{0}/% + \IfExercisePropertySetTF{C}{\GetExerciseProperty{C}}{0}/% + \IfExercisePropertySetTF{A}{\GetExerciseProperty{A}}{0})% + }% + }% + } + {} +\xsimsetup{ + exercise/template = custom , + solution/template = custom +} +\renewcommand*\theexercise{\arabic{exercise}.} + +\begin{document} + +Reachable: \printA, \printC, and \printE. + +\begin{exercise}[E=1] + Differentiate $y=3x^2+5x+3$. +\end{exercise} + +\begin{exercise}[E=2,C=1] + Find the equation of the tangent line to the function $y=x/2$ at $x=2$. +\end{exercise} + +\begin{exercise}[C=1,A=2] + Prove that the derivative of a constant is zero. +\end{exercise} + +\end{document} diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.difficulties.pdf b/Master/texmf-dist/doc/latex/xsim/examples/xsim.difficulties.pdf Binary files differnew file mode 100644 index 00000000000..846f19e2012 --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.difficulties.pdf diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.difficulties.tex b/Master/texmf-dist/doc/latex/xsim/examples/xsim.difficulties.tex new file mode 100644 index 00000000000..02712f15d66 --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.difficulties.tex @@ -0,0 +1,53 @@ +\documentclass{article} + +\usepackage[clear-aux]{xsim} +\DeclareExerciseTagging{difficulty} +\xsimsetup{ + difficulty={easy,hard} +} + +\DeclareExerciseEnvironmentTemplate{custom} + { + \subsection* + {% + \XSIMmixedcase {\GetExerciseName}\nobreakspace + \GetExerciseProperty{counter}% + \IfExercisePropertySetT{difficulty} + { {\normalfont(\GetExerciseProperty{difficulty})}}% + \IfInsideSolutionF{% + \IfExercisePropertySetT{subtitle} + { {\normalfont\itshape\GetExerciseProperty{subtitle}}}% + }% + }% + \IfExercisePropertySetT{points} + {% + \marginpar + {% + \IfInsideSolutionF{\rule{1.2cm}{1pt}\slash}% + \GetExerciseProperty{points}% + \IfExercisePropertySetT{bonus-points} + {\nobreakspace(+\GetExerciseProperty{bonus-points})} + \nobreakspace\XSIMtranslate{point-abbr}% + }% + }% + } + {} + +\xsimsetup{exercise/template = custom} + +\begin{document} + +\begin{exercise}[difficulty=easy] + An easy question. +\end{exercise} +\begin{exercise}[difficulty=medium] + This one's a bit harder. +\end{exercise} +\begin{exercise}[difficulty=hard] + Now let’s see if you can solve this one. +\end{exercise} +\begin{exercise}[difficulty=medium] + This is medium but printed anyway +\end{exercise} + +\end{document} diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.floating.pdf b/Master/texmf-dist/doc/latex/xsim/examples/xsim.floating.pdf Binary files differnew file mode 100644 index 00000000000..e2e96537ef1 --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.floating.pdf diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.floating.tex b/Master/texmf-dist/doc/latex/xsim/examples/xsim.floating.tex new file mode 100644 index 00000000000..08448df35a6 --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.floating.tex @@ -0,0 +1,50 @@ +% floating exercises: +\documentclass{article} +\usepackage{xsim,newfloat,caption,lipsum} + +\DeclareFloatingEnvironment[ + fileext=loe, + listname={List of Exercises}, + name=Exercise, + placement=htp, +]{ex} + +\DeclareExerciseEnvironmentTemplate{float} + {% + \ex + \captionsetup{labelformat=empty,singlelinecheck=false,listformat=empty} + \IfExercisePropertySetTF{subtitle}{% + \XSIMexpandcode{% + \noexpand\caption{% + \noexpand\textbf{% + \XSIMmixedcase{\GetExerciseName}\nobreakspace + \GetExerciseProperty{counter}% + }: \GetExerciseProperty{subtitle}% + }% + }% + }{% + \caption{% + \textbf{% + \XSIMmixedcase{\GetExerciseName}\nobreakspace + \GetExerciseProperty{counter}% + }% + }% + }% + } + {\endex} + +\xsimsetup{exercise/template = float} + +\begin{document} + +\listofexs + +\begin{exercise} + \lipsum[4] +\end{exercise} + +\begin{exercise}[subtitle=Let's have a look] + \lipsum[4] +\end{exercise} + +\end{document} diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.golatex-16824.pdf b/Master/texmf-dist/doc/latex/xsim/examples/xsim.golatex-16824.pdf Binary files differnew file mode 100644 index 00000000000..76cf1617cbd --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.golatex-16824.pdf diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.golatex-16824.tex b/Master/texmf-dist/doc/latex/xsim/examples/xsim.golatex-16824.tex new file mode 100644 index 00000000000..3a324d4221f --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.golatex-16824.tex @@ -0,0 +1,131 @@ +% http://golatex.de/schueler-und-lehrerloesung-im-gleichen-texfile-t16824.html +\documentclass[fontsize=12pt,parskip=half]{scrartcl} +\usepackage[utf8]{inputenc} +\usepackage[T1]{fontenc} +\usepackage[ngerman]{babel} + +\newlength\breite +\setlength\breite{160mm} +\newlength\hoehe +\setlength\hoehe{80mm} + +\usepackage[ + hdivide={3.0cm,\breite,}, + vdivide={2.2cm,,2.2cm}]{geometry} +\usepackage[bitstream-charter]{mathdesign} + +\usepackage[babel]{microtype} + +\usepackage[inline]{enumitem} + +\usepackage{amsmath,siunitx} +\sisetup{ + locale = DE , + per-mode = fraction +} + +\usepackage{xsim,needspace,tikz,tcolorbox} + +\xsimsetup{ + exercise/template = gitter , + solution/template = gitter +} + +\DeclareExerciseEnvironmentTemplate{gitter} + {% + \IfInsideSolutionT{% + \tcolorbox[ + detach title , + title = Lösung: , + before upper = {\tcbtitle\space} , + fonttitle = \bfseries , + fontupper = \large , + valign = center , + colframe = black!50!white , + colback = black!12!white , + coltext = blue , + coltitle = blue , + height = \hoehe , + width = \breite , + sharp corners + ] + }% + } + {% + \IfInsideSolutionTF + {\endtcolorbox} + {% + \IfSolutionPrintF{% + \par + \begin{tikzpicture}[semitransparent] + \draw[step=4mm, line width=0.15mm, black!60!white] (0,0) grid + (\breite,\hoehe); + \end{tikzpicture} + \par + } + }% + } + +\begin{document} + +\begin{exercise} + Für die \textbf{Schülerausgabe} sollen Häuschen (Grid) mit Seitenlänge + \SI{4}{\mm} gesetzt werden. +\end{exercise} +\begin{solution} + Hier soll die Lösung stehen: $E=m\cdot c^2$. +\end{solution} + +\xsimsetup{solution/print=true} + +\begin{exercise} + Für die \textbf{Lehrerausgabe} sollen statt Häuschen die Lösung in + z.\,B. einer Box geschrieben werden. Dafür soll die Lösung (bezogen auf + dieses Beispiel) auch in einer Box mit der exakten Breite \SI{160}{\mm} und + der exakten Höhe \SI{80}{\mm} gesetzt werden. Weiter soll natürlich die + Position der Lösungsbox und der Häuschenbox exakt identisch sein. +\end{exercise} +\begin{solution} + Hier soll die Lösung stehen: $E=m\cdot c^2$. +\end{solution} + +\clearpage + +\begin{exercise} + Beschreiben Sie die \textbf{Satzgruppe des Pythagoras}. +\end{exercise} +\begin{solution} + \begin{align*} + \left.\begin{aligned} + c^2 &=a^2+b^2\\ + a^2 &=p\cdot c\;\wedge\; b^2=q\cdot c\\ + h^2 &=p\cdot q + \end{aligned}\right\} + \begin{gathered} + \text{Satzgruppe}\\ + \text{des Pythagoras} + \end{gathered} + \end{align*} +\end{solution} + +\begin{exercise} + Geben Sie die Formel der \textbf{gleichförmigen Bewegung} wieder. Gehen Sie + davon aus, dass Sie 1000~Meter in + \SI[parse-numbers=false]{3\frac{1}{2}}{Minuten} laufen. + \begin{enumerate*}[label=\bfseries\alph*)] + \item Mit welcher Geschwindigkeit legen Sie die Strecke zurück? + \item Geben Sie die Geschwindigkeit in \si{\km\per\hour} an. + \end{enumerate*} + \textbf{Hinweis:} Nehmen Sie zur Berechnung die vereinfachte Form und gehen + Sie davon aus, dass Ihre Geschwindigkeit konstant ist. +\end{exercise} +\begin{solution} + \begin{align*} + s &=v\cdot t+s_0 \\ + 1000 &=v\cdot 210 \\ + v &=\frac{\SI{1000}{\m}}{\SI{210}{\second}} \\ + v &=\SI{4.76}{\m\per\second} = \SI{17.1}{\km\per\hour} + \end{align*} +\end{solution} + +\end{document} diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.golatex-18844.pdf b/Master/texmf-dist/doc/latex/xsim/examples/xsim.golatex-18844.pdf Binary files differnew file mode 100644 index 00000000000..97cb4659e06 --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.golatex-18844.pdf diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.golatex-18844.tex b/Master/texmf-dist/doc/latex/xsim/examples/xsim.golatex-18844.tex new file mode 100644 index 00000000000..aa49dd64e1b --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.golatex-18844.tex @@ -0,0 +1,94 @@ +% http://golatex.de/aufgabe-loesungs-umgebung-t18844.html +\documentclass[18pt,a4paper]{article} +\usepackage[utf8]{inputenc} +\usepackage[ngerman]{babel} + +\usepackage{xsim,tcolorbox} +\usepackage{amsmath} +\xsimsetup{ + exercise/within = section , + exercise/the-counter = \thesection.\arabic{exercise} , + print-solutions/headings-template=none +} +\SetExerciseParameters{exercise}{ + exercise-template = mine , + solution-template = mine +} + +\DeclareExerciseEnvironmentTemplate{mine} + {% + \tcolorbox[ + % colors: + colback = white , colframe = black , coltitle = black , + % rules: + boxrule = 0pt , toprule = 1pt , bottomrule = 1pt , arc = 0pt , + % spacing: + boxsep = 0pt , left = 0pt , right = 0pt , + % title: + detach title , before upper = \tcbtitle\par\noindent , + fonttitle = \bfseries , + title = \XSIMmixedcase{\GetExerciseName}~\GetExerciseProperty{counter} + ] + } + {\endtcolorbox} + +\DeclareExerciseTranslation{German}{exercise}{Aufgabe} +\DeclareExerciseTagging{difficulty} + +\begin{document} + +\section{Wellenausbreitung im Vakuum und in Materie} +\subsection{Maxwellsche Gleichungen} + +\begin{align*} + \nabla \cdot \vec{E}\left(\vec{r}, t \right) = + \frac{\varrho\left(\vec{r}, t \right)}{\varepsilon_0} +\end{align*} + +\begin{exercise}[difficulty=easy] +Something stupid +\end{exercise} +\begin{solution} +Here is a nonstupid solution for your problem +\end{solution} + +\subsection{Empirischer Zugang zu Wellengleichungen} + +\begin{exercise}[difficulty=hard] +Eine weitere Aufgabe +\end{exercise} +\begin{solution} +Solution Number 2 +\end{solution} + +\subsection*{Lösungen} +\printsolutions[section,difficulty=hard] + +\section{Wellenausbreitung im Vakuum und in Materie} +\subsection{Maxwellsche Gleichungen} + +\begin{align*} + \nabla \cdot \vec{E}\left(\vec{r}, t \right) = + \frac{\varrho\left(\vec{r}, t \right)}{\varepsilon_0} +\end{align*} + +\begin{exercise}[difficulty=easy] +Something stupid +\end{exercise} +\begin{solution} +Here is a nonstupid solution for your problem +\end{solution} + +\subsection{Empirischer Zugang zu Wellengleichungen} + +\begin{exercise}[difficulty=hard] +Eine weitere Aufgabe +\end{exercise} +\begin{solution} +Solution Number 2 +\end{solution} + +\subsection*{Lösungen} +\printsolutions[section] + +\end{document} diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.grade-distribution.pdf b/Master/texmf-dist/doc/latex/xsim/examples/xsim.grade-distribution.pdf Binary files differnew file mode 100644 index 00000000000..248358c4a16 --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.grade-distribution.pdf diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.grade-distribution.tex b/Master/texmf-dist/doc/latex/xsim/examples/xsim.grade-distribution.tex new file mode 100644 index 00000000000..8e9731de24d --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.grade-distribution.tex @@ -0,0 +1,56 @@ +\documentclass{article} +\usepackage{xsim} + +\xsimsetup{grades/split=;} + +\DeclareGradeDistribution{ + 1 = 1 ; + 1,5 = .9167 ; + 2 = .8333 ; + 2,5 = .75 ; + 3 = .6667 ; + 3,5 = .5833 ; + 4 = .5 +} + +\begin{document} + +\begin{exercise}[points=4] +\end{exercise} + +\begin{exercise}[points=4] +\end{exercise} + +\begin{exercise}[points=4] +\end{exercise} + +\begin{exercise}[points=4,bonus-points=10] +\end{exercise} + +\begin{exercise}[points=4] +\end{exercise} + +\begin{exercise}[points=4] +\end{exercise} + + +\goalsforgrade{points + bonus-points}{1,5} +\goalsforgrade{points+bonus-points}{2} + +\pointsforgrade{1} +\pointsforgrade{1,5} +\pointsforgrade{2} +\pointsforgrade{2,5} +\pointsforgrade{3} +\pointsforgrade{3,5} +\pointsforgrade{4} + +\totalgoalforgrade{1} +\totalgoalforgrade{1,5} +\totalgoalforgrade{2} +\totalgoalforgrade{2,5} +\totalgoalforgrade{3} +\totalgoalforgrade{3,5} +\totalgoalforgrade{4} + +\end{document} diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.listings.pdf b/Master/texmf-dist/doc/latex/xsim/examples/xsim.listings.pdf Binary files differnew file mode 100644 index 00000000000..0d388f2c708 --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.listings.pdf diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.listings.tex b/Master/texmf-dist/doc/latex/xsim/examples/xsim.listings.tex new file mode 100644 index 00000000000..6dd302feb09 --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.listings.tex @@ -0,0 +1,48 @@ +% http://tex.stackexchange.com/questions/131546/ +\documentclass{article} + +\usepackage{xcolor} +\usepackage{listings} +\usepackage{xsim} + +\lstset{ + frame=single, + xleftmargin=20pt, + numbers=left, + numberstyle=\small, + tabsize=2, + breaklines, + showspaces=false, + showstringspaces=false, + language=C, + basicstyle=\small\ttfamily, + commentstyle=\itshape\color{gray} +} + +\begin{document} + +\begin{exercise}[points=6] +Consider the following C program. +\begin{lstlisting} +#include <stdio.h> + +int main(int argc, char *argv[]) { + printf("hello, world\n"); +} +\end{lstlisting} +\end{exercise} +\begin{solution} +Consider the following C program. +\begin{lstlisting} +#include <stdio.h> + +int main(int argc, char *argv[]) { + printf("hello, world\n"); +} +\end{lstlisting} +\end{solution} + +\pagebreak +\printsolutions + +\end{document} diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.multiplechoice.pdf b/Master/texmf-dist/doc/latex/xsim/examples/xsim.multiplechoice.pdf Binary files differnew file mode 100644 index 00000000000..02dac6c4df9 --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.multiplechoice.pdf diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.multiplechoice.tex b/Master/texmf-dist/doc/latex/xsim/examples/xsim.multiplechoice.tex new file mode 100644 index 00000000000..e0db3eb0c52 --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.multiplechoice.tex @@ -0,0 +1,70 @@ +\documentclass{scrartcl} +\usepackage[clear-aux]{xsim} + +\usepackage{enumitem,amssymb,fmtcount} +\newlist{choices}{itemize}{1} +\setlist[choices]{label=$\Box$} +\newcommand*\choice{\item} + +\DeclareExerciseProperty{choices} +\DeclareExerciseProperty*{multiple} +\DeclareExerciseEnvironmentTemplate{mc} + {% + \UseExerciseTemplate{begin}{default}% + \IfExerciseBooleanPropertyTF{multiple} + {Select one or more correct answers} + {% + \GetExercisePropertyT{choices} + {Select \numberstringnum{#1} correct answer\ifnum#1>1 s\fi.}% + }% + \begin{choices} + } + {% + \end{choices} + \UseExerciseTemplate{end}{default}% + } + +\DeclareExerciseType{mc}{ + exercise-env = multiplechoice , + solution-env = correctchoices , + exercise-name = Question , + solution-name = Solution , + exercise-template = mc , + solution-template = mc , + counter = exercise +} + +\xsimsetup{ + exercise/name = Question , + solution/name = Solution +} + +\begin{document} + +\section{Questions} +\begin{multiplechoice}[choices=1] + \choice one + \choice two + \choice three + \choice four +\end{multiplechoice} + +\begin{exercise} + Answer this question on a separate sheet. +\end{exercise} + +\begin{multiplechoice}[multiple] + \choice one + \choice two + \choice three + \choice four +\end{multiplechoice} + +\begin{multiplechoice}[choices=2] + \choice one + \choice two + \choice three + \choice four +\end{multiplechoice} + +\end{document} diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.pointsums.pdf b/Master/texmf-dist/doc/latex/xsim/examples/xsim.pointsums.pdf Binary files differnew file mode 100644 index 00000000000..aa822a1bd7a --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.pointsums.pdf diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.pointsums.tex b/Master/texmf-dist/doc/latex/xsim/examples/xsim.pointsums.tex new file mode 100644 index 00000000000..29d7ac0cdc1 --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.pointsums.tex @@ -0,0 +1,30 @@ +\documentclass{article} +\usepackage{xsim,lipsum} + +\NewDocumentCommand\printcompletepoints{}{% + \TotalExerciseGoals{points + bonus-points} + {\,\XSIMtranslate{point}} + {\,\XSIMtranslate{points}}% +} + +\NewDocumentCommand\pointsandbonus{}{% + \TotalExerciseGoal{points}{}{}% + \IfExerciseGoalsSumTF{bonus-points}{=0} + {} + {\,(+\,\TotalExerciseGoal{bonus-points}{}{})}% + \,\XSIMtranslate{points}% +} + +\begin{document} + +\begin{exercise}[points=3,bonus-points=1] + \lipsum[4] +\end{exercise} + +\begin{exercise}[points=8,bonus-points=3] + \lipsum[4] +\end{exercise} + +\printtotalpoints\ vs.\@ \printcompletepoints\ vs.\@ \pointsandbonus + +\end{document} diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.randomexercises.pdf b/Master/texmf-dist/doc/latex/xsim/examples/xsim.randomexercises.pdf Binary files differnew file mode 100644 index 00000000000..773d34f495b --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.randomexercises.pdf diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.randomexercises.tex b/Master/texmf-dist/doc/latex/xsim/examples/xsim.randomexercises.tex new file mode 100644 index 00000000000..60877b1a4ab --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.randomexercises.tex @@ -0,0 +1,58 @@ +\documentclass{article} +\usepackage{xsim} + +\DeclareExerciseCollection{foo} + +\usepackage{filecontents} +\begin{filecontents*}{random.tex} +\begin{exercise}[ID=A] + exercise A +\end{exercise} +\begin{solution} + solution A +\end{solution} +\begin{exercise}[ID=B] + exercise B +\end{exercise} +\begin{solution} + solution B +\end{solution} +\begin{exercise}[ID=C] + exercise C +\end{exercise} +\begin{solution} + solution C +\end{solution} +\begin{exercise}[ID=D] + exercise D +\end{exercise} +\begin{solution} + solution D +\end{solution} +\begin{exercise}[ID=E] + exercise E +\end{exercise} +\begin{solution} + solution E +\end{solution} +\begin{exercise}[ID=F] + exercise F +\end{exercise} +\begin{solution} + solution F +\end{solution} +\end{filecontents*} + +\begin{document} + +\collectexercises{foo} +\input{random.tex} +\collectexercisesstop{foo} + +\section*{Exercises} +\printrandomexercises[collection=foo,exclude=D]{3} + +\section*{Solutions} +\printsolutions* + +\end{document} diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-199360.pdf b/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-199360.pdf Binary files differnew file mode 100644 index 00000000000..94925495985 --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-199360.pdf diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-199360.tex b/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-199360.tex new file mode 100644 index 00000000000..334275140ab --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-199360.tex @@ -0,0 +1,60 @@ +% http://tex.stackexchange.com/a/199360/ +\documentclass{scrartcl} +\usepackage[clear-aux]{xsim} + +\usepackage{tcolorbox,blindtext} + +\DeclareExerciseEnvironmentTemplate{custom} + {% + \begin{tcolorbox}[ + width = \textwidth , + colbacktitle = \IfInsideSolutionTF{green}{red} , + coltitle = black , + title = {\XSIMmixedcase{\GetExerciseName}~\GetExerciseProperty{counter}}]} + {\end{tcolorbox}} + +\xsimsetup{ + exercise/template = custom , + solution/template = custom +} + +\begin{document} + +\begin{exercise} + First Question +\end{exercise} +\begin{solution} + Yes, it's a question +\end{solution} + +\begin{exercise}[print=false,use] + Question: What is special about Brontosaurs? +\end{exercise} +\begin{solution} + They are thin at one end, thick in the middle and thin on the end again +\end{solution} + +\begin{exercise} + Proof +\begin{equation} + a^2 + b^2 = c^2 +\end{equation} +\end{exercise} +\begin{solution} + to be done +\end{solution} + +\begin{exercise} + Cite a Latin Text +\end{exercise} +\begin{solution} + \textcolor{blue}{\blindtext} +\end{solution} + +\begin{exercise} + \textcolor{red}{\textbf{Cite a Latin text again}} +\end{exercise} + +\printsolutions* + +\end{document} diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-299534.pdf b/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-299534.pdf Binary files differnew file mode 100644 index 00000000000..c006aeb34c3 --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-299534.pdf diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-299534.tex b/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-299534.tex new file mode 100644 index 00000000000..1c2be46df39 --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-299534.tex @@ -0,0 +1,32 @@ +% http://tex.stackexchange.com/q/299534/ +\documentclass{article} +\usepackage{pythontex} +\usepackage{xsim} + +\begin{document} + +\section{Test} + +\begin{exercise}[subtitle = Codeless Question,points=10] + A question without code, worth 10 points. Subtitle and point values are in + correct place. +\end{exercise} +\begin{solution} + Solution 1 +\end{solution} + +\begin{exercise}[subtitle = Codeful Question,points=15] +Now with PythonTeX: +\begin{pyblock} +print("hello, world!") +sum = 0 +for j in range(0,100): + sum += j +print(sum) +\end{pyblock} +\end{exercise} +\begin{solution} + Solution 2 +\end{solution} + +\end{document} diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-305110.pdf b/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-305110.pdf Binary files differnew file mode 100644 index 00000000000..fb92e875a91 --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-305110.pdf diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-305110.tex b/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-305110.tex new file mode 100644 index 00000000000..c10928da0ce --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-305110.tex @@ -0,0 +1,67 @@ +% https://tex.stackexchange.com/q/305110 +\documentclass[12pt, a4paper]{book} +\usepackage{xsim} + +\xsimsetup{ + exercise/within = section , + exercise/the-counter = \thesection.\arabic{exercise} +} + +\begin{document} +\part{EXCERCISES} +\chapter{Topic 1} + +\section{Section} + +\begin{exercise} + I'm an excercise. +\end{exercise} +\begin{solution} + I'm a solution. +\end{solution} + +\section{Section} + +\begin{exercise} + I'm an excercise. +\end{exercise} +\begin{solution} + I'm a solution. +\end{solution} + +\chapter{Topic 2} + +\section{Section} +\begin{exercise} + I'm an excercise. +\end{exercise} +\begin{solution} + I'm a solution. +\end{solution} + +\section{Section} +\begin{exercise} + I'm an excercise. +\end{exercise} +\begin{solution} + I'm a solution. +\end{solution} + +\setcounter{chapter}{0} +\part{SOLUTIONS} + +\chapter{Topic 1} +\section{Section} +\printsolutions[chapter=1,section=1] + +\section{Section} +\printsolutions[chapter=1,section=2] + +\chapter{Topic 2} +\section{Section} +\printsolutions[chapter=2,section=1] + +\section{Section} +\printsolutions[chapter=2,section=2] + +\end{document} diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-338165.pdf b/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-338165.pdf Binary files differnew file mode 100644 index 00000000000..f6557530a1d --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-338165.pdf diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-338165.tex b/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-338165.tex new file mode 100644 index 00000000000..e48d8880dab --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-338165.tex @@ -0,0 +1,72 @@ +% http://tex.stackexchange.com/q/338165 +\documentclass{article} +\usepackage[T1]{fontenc} +\usepackage{leading,microtype} +\usepackage[french]{babel} + +\usepackage{tasks} +\usepackage{xsim} +\usepackage{tcolorbox} +\tcbuselibrary{breakable, skins} +\settasks{ + counter-format = tsk. +} + +\DeclareExerciseEnvironmentTemplate{boxed} + {% + \tcolorbox[ + enhanced , + attach boxed title to top center = {yshift=-7.5pt} , + colback = white , colbacktitle = white , + coltitle = black , colframe = black , + boxed title style = { colframe = white } , + fonttitle=\bfseries, + sharp corners=all, + breakable, + title= + \XSIMmixedcase{\GetExerciseName}% + \IfInsideSolutionF{% + ~\GetExerciseProperty{counter}% + \IfExercisePropertySetT{subtitle}{: \GetExerciseProperty{subtitle}}% + }% + ] + } + {\endtcolorbox} + +\xsimsetup{ + exercise/template = boxed , + solution/template = boxed , + solution/print = true +} + +\leading{15pt} + +\newcommand*\complement{\overline} +\newcommand*\union{\cup} +\newcommand*\intersection{\cap} +\newcommand*\set[1]{\{#1\}} + +\begin{document} + +\begin{exercise}[subtitle=Set Calculus] + Soient $E=\set{1,2,3,4,5,6,7}$ et $A$, $B$, $C$ et $D$ quatre parties de E + d\'efinies par $A=\set{1,2,3,4}$, $B=\set{4,5,6,7}$, $C=\set{1,3,5,7}$ et + $D=\set{2,3,4,5,6}$. + \begin{tasks}(2) + \task Calculer $\complement{A}$. + \task Calculer $(A\union B) \intersection (C\union D)$. + \task Calculer $(A\intersection B) \union (C\intersection D)$. + \task Calculer $\complement{(\complement{A}\union B)} \union + \complement{(C\intersection D)}$. + \end{tasks} +\end{exercise} +\begin{solution} + \begin{tasks}(2) + \task $\set{5,6,7}$ + \task $E$ + \task $\set{3,4,5}$ + \task $\set{1,2,3,4,6,7}$ + \end{tasks} +\end{solution} + +\end{document} diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-350028.pdf b/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-350028.pdf Binary files differnew file mode 100644 index 00000000000..ef781218a8e --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-350028.pdf diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-350028.tex b/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-350028.tex new file mode 100644 index 00000000000..ebe090413c9 --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-350028.tex @@ -0,0 +1,135 @@ +% http://tex.stackexchange.com/q/350028/ +\documentclass{book} + +\usepackage{xsimverb} +\usepackage{xsim} +\usepackage[most]{tcolorbox} +\tcbuselibrary{skins,breakable} + +\DeclareExerciseEnvironmentTemplate{tcolorbox} + {% + \tcolorbox[ + enhanced, + colframe=green!20!black, + colback=yellow!10!white, + coltitle=green!40!black, + fonttitle=\bfseries, + underlay={% + \begin{tcbclipinterior} + \shade[ + inner color=\IfInsideSolutionTF{red!50!yellow}{green!80!yellow}, + outer color=yellow!10!white] + (interior.north west) circle (2cm); + \draw[help lines,step=5mm,yellow!80!black,shift={(interior.north west)}] + (interior.south west) grid (interior.north east); + \end{tcbclipinterior}% + }, + attach title to upper=\quad, + title = \XSIMmixedcase{\GetExerciseName}~\GetExerciseProperty{counter} + \IfExercisePropertySetT{points}{% + (\GetExerciseProperty{points} + \IfExerciseGoalSingularTF{points} + {\XSIMtranslate{point}} + {\XSIMtranslate{points}})% + }]% + \IfInsideSolutionT{\label{solution:\ExerciseID}}% + } + {% + \endtcolorbox + \vspace*{\baselineskip} + \IfInsideSolutionTF + {% + \noindent Exercise~\GetExerciseProperty{counter} is on + page~\GetExerciseProperty{page}.% + } + {% + \noindent The solution of this exercise is on + page~\pageref{solution:\ExerciseID}.% + }% + \vspace{\baselineskip} + } + +\xsimsetup{ + exercise/template = tcolorbox , + solution/template = tcolorbox +} + +\usepackage{fmtcount,etoolbox} +\newrobustcmd*\mystringnum[2]{\csname#1stringnum\endcsname{#2}} +\renewcommand*\thechapter{\mystringnum{number}{\value{chapter}}} +\renewcommand*\thesection{\arabic{chapter}.\arabic{section}} + +% for the header: \MakeUppercase{\mystringnum{number}{1}} +% => \mystringnum{NUMBER}{1} +% => \NUMBERstringnum{1} +% elsewhere: \mystringnum{number}{1} +% => \numberstringnum{1} + +\usepackage{totcount} +\regtotcounter{chapter} + +\newcounter{chapters} +\setcounter{chapters}{1} +\newcommand*\printsolutionsperchapter{% + \whileboolexpr + { test { \ifnumless {\value{chapters}} {\totvalue{chapter}+1} } } + {% + \printsolutions[chapter=\value{chapters},headings-template=per-chapter] + \stepcounter{chapters}% + }% +} + +\begin{document} + +\chapter{The First Chapter} + +\begin{exercise} + Compute the derivative of the following function: + \begin{equation*} + f(x) = \sin((\sin x)^2) + \end{equation*} +\end{exercise} +\begin{solution} + The derivative is: + \begin{align*} + f’(x) &= ( \sin((\sin x)^2) )' + = \cos((\sin x)^2) \cdot 2\sin x \cos x + \end{align*} +\end{solution} + +\begin{exercise} + Compute the derivative of the following function: + \begin{equation*} + f(x) = \sin((\sin x)^2) + \end{equation*} +\end{exercise} +\begin{solution} + The derivative is: + \begin{align*} + f’(x) &= ( \sin((\sin x)^2) )' + = \cos((\sin x)^2) \cdot 2\sin x \cos x + \end{align*} +\end{solution} + +\chapter{The Second Chapter} + +\begin{exercise} + Compute the derivative of the following function: + \begin{equation*} + f(x) = (x^2+1) \sqrt{x^4+1} + \end{equation*} +\end{exercise} +\begin{solution} + The derivative is: + \begin{align*} + f’(x) &= ( (x^2+1) \sqrt{x^4+1} )' + = 2x\sqrt{x^4+1} + \frac{2x^3(x^2+1)}{\sqrt{x^4+1}} + \end{align*} +\end{solution} + +\clearpage +\section{Solutions of the Exercices} + +\printsolutionsperchapter + +\end{document} diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-369065.pdf b/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-369065.pdf Binary files differnew file mode 100644 index 00000000000..6aa9ab572bb --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-369065.pdf diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-369065.tex b/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-369065.tex new file mode 100644 index 00000000000..b62b85127a4 --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-369065.tex @@ -0,0 +1,77 @@ +% https://tex.stackexchange.com/q/369065/ +\documentclass{article} +\usepackage{xsim,tcolorbox,needspace} + +\xsimsetup{ + exercise/within=section , + exercise/the-counter = \thesection.\arabic{exercise} , + exercise/template=cyan-box , + exercise/name=Example , + solution/template=red , + solution/print=true +} + +\DeclareExerciseEnvironmentTemplate{cyan-box} + {% + \begin{tcolorbox}[arc=0mm,boxrule=1pt,colback=white,colframe=cyan,leftrule=3mm] + \textsf{% + \MakeUppercase{% + \XSIMmixedcase{\GetExerciseName}~\GetExerciseProperty{counter}% + }% + }% + \GetExercisePropertyT{subtitle}{ \textit{#1}}% + \quad + } + {\end{tcolorbox}} + +\DeclareExerciseEnvironmentTemplate{red} + {% + \par + \Needspace*{2\baselineskip} + \noindent + \textsf{\textcolor{red}{\MakeUppercase{\XSIMmixedcase{\GetExerciseName}}}}% + \quad + } + {\par\bigskip} + +\begin{document} + +\section{My first set of exercises} +\begin{exercise} + Prove that $\frac{1}{2}\Delta(f_{ij}f^{ij}) + =\nabla^{k}f^{ij}+f^{ij}f^{k}[2\nabla_{i}R_{jk}-\nabla_{k}R_{ij}]$ +\end{exercise} +\begin{solution} + From \dots +\end{solution} + +\begin{exercise} + Prove that Paulinho is smart. +\end{exercise} +\begin{solution} + All ducks are smart. Paulinho is a duck. Therefore, Paulinho is smart. +\end{solution} + +\begin{exercise} + Prove that Paulinho is smart. +\end{exercise} +\begin{solution} + All ducks are smart. Paulinho is a duck. Therefore, Paulinho is smart. +\end{solution} + +\section{My second set of exercises} +\begin{exercise} + Prove that Paulinho is smart. +\end{exercise} +\begin{solution} + All ducks are smart. Paulinho is a duck. Therefore, Paulinho is smart. +\end{solution} + +\begin{exercise} + Prove that Paulinho is smart. +\end{exercise} +\begin{solution} + All ducks are smart. Paulinho is a duck. Therefore, Paulinho is smart. +\end{solution} + +\end{document} diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-369636.pdf b/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-369636.pdf Binary files differnew file mode 100644 index 00000000000..2bc106f3035 --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-369636.pdf diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-369636.tex b/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-369636.tex new file mode 100644 index 00000000000..e13b8653f4c --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-369636.tex @@ -0,0 +1,46 @@ +% https://tex.stackexchange.com/q/369686/ +\documentclass[a4paper,11pt]{article} +\usepackage[top=2cm, bottom=3cm, left=4cm, right=4cm]{geometry} + +\usepackage[T1]{fontenc} +\usepackage{fourier} +\usepackage{tgpagella} +\usepackage[utf8]{inputenc} + +\usepackage{xsim,needspace,adjustbox,scrextend} + +\xsimsetup{ + exercise/the-counter = \arabic{exercise}. , + exercise/template = square +} + +\DeclareExerciseEnvironmentTemplate{square} + {% + \Needspace*{2\baselineskip}% + \addmargin[0pt]{.15\textwidth}% + \par\noindent + \adjustbox{ + fbox = 1pt 0pt, + lap = {\textwidth}, + valign = t, + set vsize = {0pt}{0pt} + }{\rule{0pt}{20pt}\hspace{20pt}}% + \textbf{\GetExerciseProperty{counter}} % + } + {\endaddmargin\vspace{\baselineskip}} + +\usepackage{lipsum} + +\begin{document} + +\noindent\hrulefill + +\begin{exercise} + \lipsum[1] +\end{exercise} + +\begin{exercise} + \lipsum[2] +\end{exercise} + +\end{document} diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-369803.pdf b/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-369803.pdf Binary files differnew file mode 100644 index 00000000000..73eab39f10b --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-369803.pdf diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-369803.tex b/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-369803.tex new file mode 100644 index 00000000000..58b6800f937 --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.texsx-369803.tex @@ -0,0 +1,50 @@ +% https://tex.stackexchange.com/q/369803 +\documentclass[a4paper,parskip=half]{scrartcl} +\usepackage[utf8]{inputenc} +\usepackage[ngerman]{babel} + +\usepackage{amsmath} +\usepackage{amsthm} +\usepackage{amsfonts} +\usepackage{amssymb} + +\usepackage[left=2cm,right=2.5cm,top=2.5cm,bottom=2cm]{geometry} + +\usepackage{xsim,siunitx} +\DeclareExerciseTagging{difficulty} +\DeclareExerciseEnvironmentTemplate{custom} + {% + \subsection* + {% + \XSIMmixedcase{\GetExerciseName}\nobreakspace + \GetExerciseProperty{counter}% + \IfInsideSolutionF + {% + \IfExercisePropertySetT{subtitle} + { {\normalfont(\GetExerciseProperty{subtitle})}}% + }% + }% + }{} + +\xsimsetup{ + exercise/name = \XSIMtranslate{question} , + exercise/template=custom , + solution/print=true +} + +\begin{document} + +\begin{exercise}[ID=wdsw, subtitle = Widerstandswürfel , difficulty = 2] + Gegeben ist ein Würfel, wobei jede der Kanten einen Widerstand von $R = + \SI{1}{\ohm}$ hat. + + Wie groß ist der Widerstand entlang einer Raumdiagonale? +\end{exercise} +\begin{solution} + Wir wollen den Widerstand zwischen den Punkten $X$ und $Y$ bestimmen, also + entlang der Raumdiagonale (siehe Abb. \ref{fig:wdsws1}). Weil die + Raumdiagonale eine Symmetrieachse ist, sollte das Problem symmetrisch sein, + und deswegen eine recht einfache Lösung haben. +\end{solution} + +\end{document} diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.texwelt-15093.pdf b/Master/texmf-dist/doc/latex/xsim/examples/xsim.texwelt-15093.pdf Binary files differnew file mode 100644 index 00000000000..3dc9fb16494 --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.texwelt-15093.pdf diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.texwelt-15093.tex b/Master/texmf-dist/doc/latex/xsim/examples/xsim.texwelt-15093.tex new file mode 100644 index 00000000000..1f3fcfefcb7 --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.texwelt-15093.tex @@ -0,0 +1,133 @@ +% http://texwelt.de/wissen/fragen/15093/ +\documentclass[paper=a4]{scrartcl} +\usepackage[utf8]{inputenc} +\usepackage[ngerman]{babel} + +\usepackage{xsim,needspace} + +\DeclareExerciseTagging{AFB} +\DeclareExerciseEnvironmentTemplate{myexam} + { + \par\vspace{\baselineskip} + \Needspace*{3\baselineskip} + \noindent + \textbf{\IfInsideSolutionTF{Lösung}{Aufgabe}~\GetExerciseProperty{counter}.}% + \GetExercisePropertyT{subtitle}{\quad\textit{#1}}% + \hfill + \GetExercisePropertyT{AFB}{Schwierigkeit: #1}% + \GetExercisePropertyT{points}{% + \marginpar{% + \PropertyValue + \GetExercisePropertyT{bonus-points}{+\PropertyValue}% + \,P.% + }% + }% + \par\noindent + } + {} + +\xsimsetup{exercise/template=myexam} + +\begin{document} + +\begin{exercise}[subtitle=Eine Frage, AFB=1, points=3] + Das ist eine sehr tolle Frage. +\end{exercise} + +\begin{exercise}[AFB=2, points=3] + Das ist eine sehr tolle Frage. +\end{exercise} + +\begin{exercise}[AFB=3] + Das ist eine sehr tolle Frage. +\end{exercise} + +\begin{exercise}[subtitle=Eine andere Frage, AFB=4, points=3] + Das ist eine sehr tolle Frage. +\end{exercise} + +\begin{exercise}[subtitle=Eine Frage, AFB=2] + Das ist eine sehr tolle Frage. +\end{exercise} + +\end{document} + +% andere Idee: +\documentclass[paper=a4]{scrartcl} +\usepackage[utf8]{inputenc} +\usepackage[ngerman]{babel} + +\usepackage{xsim} + +\DeclareExerciseTagging{AFB} + +\DeclareExerciseEnvironmentTemplate{AFB}{% + \subsection*{% + \XSIMmixedcase{\GetExerciseName}\nobreakspace + \GetExerciseProperty{counter}% + \IfExercisePropertySetT{subtitle}% + { {\normalfont\itshape\GetExerciseProperty{subtitle}}}% + } + \marginpar{% + \GetExercisePropertyT{AFB}{% + \leavevmode\llap{Schwierigkeit: \PropertyValue\hspace*{\marginparsep}}% + }% + \GetExercisePropertyT{points}{% + \PropertyValue + \nobreakspace\XSIMtranslate{points}% + }% + }% +}{} + +\DeclareExerciseEnvironmentTemplate{AFBsol}{% + \subsection*{% + \XSIMmixedcase{\GetExerciseName}\nobreakspace + \GetExerciseProperty{counter}% + \IfExercisePropertySetT{subtitle}% + { {\normalfont\itshape\GetExerciseProperty{subtitle}}}% + } + \textit{\small + \GetExercisePropertyT{AFB}{Schwierigkeit: \PropertyValue}% + \GetExercisePropertyT{points}{% + \IfExercisePropertySetT{AFB}{ }% + (\PropertyValue\nobreakspace\XSIMtranslate{points})% + }% + }% + \par\noindent +}{} + +\DeclareExerciseTranslation{German}{default-heading}{Lösungen} + +\xsimsetup{ + exercise/template=AFB , + solution/template=AFBsol , + exercise/name=Aufgabe +} + +\begin{document} + +\begin{exercise}[subtitle=Eine Frage, AFB=1, points=3] + Das ist eine sehr tolle Frage. +\end{exercise} +\begin{solution} + Das ist eine tolle Lösung! +\end{solution} +\begin{exercise}[AFB=2, points=3] + Das ist eine sehr tolle Frage. +\end{exercise} + +\begin{exercise}[AFB=3] + Das ist eine sehr tolle Frage. +\end{exercise} + +\begin{exercise}[subtitle=Eine andere Frage, AFB=4, points=3] + Das ist eine sehr tolle Frage. +\end{exercise} + +\begin{exercise}[subtitle=Eine Frage, AFB=2] + Das ist eine sehr tolle Frage. +\end{exercise} + +\printsolutions + +\end{document} diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.texwelt-6698.pdf b/Master/texmf-dist/doc/latex/xsim/examples/xsim.texwelt-6698.pdf Binary files differnew file mode 100644 index 00000000000..000663bf445 --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.texwelt-6698.pdf diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.texwelt-6698.tex b/Master/texmf-dist/doc/latex/xsim/examples/xsim.texwelt-6698.tex new file mode 100644 index 00000000000..9e388b9f690 --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.texwelt-6698.tex @@ -0,0 +1,86 @@ +% http://texwelt.de/wissen/fragen/6698/ +\documentclass{article} +\usepackage[utf8]{inputenc} +\usepackage[ngerman]{babel} + +\usepackage{needspace} +\usepackage{xsim} +\xsimsetup{ + exercise/name = Aufgabe , + solution/name = Lösung , + exercise/within = section , + exercise/the-counter = \thesection.\arabic{exercise} , + exercise/template = mine +} + +\newif\iflist + +\DeclareExerciseEnvironmentTemplate{mine}{ + \par\vspace{\baselineskip} + \Needspace*{3\baselineskip} + \noindent + \textbf{\GetExerciseName~\GetExerciseProperty{counter}}% + \GetExercisePropertyT{subtitle}{\quad\textit{#1}}% + \iflist + \GetExercisePropertyT{page}{ (Seite~#1)}% + \fi + % not necessary if you don't use points: + \GetExercisePropertyT{points}{% + \marginpar{% + \PropertyValue + \GetExercisePropertyT{bonus-points}{+\PropertyValue}% + \,\XSIMtranslate{points-abbr}% + }% + }% + \par\noindent +} +{} + +\usepackage{multicol} + +\begin{document} + +\section{Erstes Kapitel} +\begin{exercise} + Eine erste Aufgabe +\end{exercise} +\begin{exercise} + Eine zweite Aufgabe +\end{exercise} + +\subsection{Erstes Unterkapitel} +\begin{exercise} + Eine Aufgabe in einem Unterkapitel +\end{exercise} +\begin{exercise} + Noch eine Aufgabe in einem Unterkapitel +\end{exercise} + +\subsubsection{Tiefer geschachteltes Unterkapitel} +\begin{exercise} + Noch eine Aufgabe +\end{exercise} + +\subsubsection{Weiter geschachtelt} +\begin{exercise} + Eine weitere Aufgabe +\end{exercise} + +\subsection{Zweites Unterkapitel} +\begin{exercise} + Und eine weitere Aufgabe +\end{exercise} + +\clearpage + +\section{Zweites Kapitel} +\begin{exercise} + Eine Aufgabe in einem anderen Kapitel +\end{exercise} + +\begin{multicols}{2}[\section{Aufgabenübersicht}] + \listtrue + \printcollection{all exercises} +\end{multicols} + +\end{document} diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.various.pdf b/Master/texmf-dist/doc/latex/xsim/examples/xsim.various.pdf Binary files differnew file mode 100644 index 00000000000..b8f033c7599 --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.various.pdf diff --git a/Master/texmf-dist/doc/latex/xsim/examples/xsim.various.tex b/Master/texmf-dist/doc/latex/xsim/examples/xsim.various.tex new file mode 100644 index 00000000000..1b7b13f98b3 --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/examples/xsim.various.tex @@ -0,0 +1,237 @@ +\documentclass{article} +\usepackage{xsim,lipsum,tcolorbox} + +\DeclareExerciseType{question}{ + exercise-env = question , + solution-env = hint , + exercise-name = Question , + solution-name = Hint , + exercise-template = default , + solution-template = default , + counter = exercise % shares a counter with the `exercise' type +} + +\DeclareExerciseType{problem}{ + exercise-env = problem , + solution-env = answer , + exercise-name = Problem , + solution-name = Answer , + exercise-template = tcolorbox , + solution-template = tcolorbox +} + +\DeclareExerciseProperty{grade} +\DeclareExerciseProperty{difficulty} + +\tcbuselibrary{breakable} +\DeclareExerciseEnvironmentTemplate{tcolorbox} + {% + \newcommand*\writehere{% + \IfInsideSolutionTF{}{% + \tcblower + \emph{Your answer:} + \vspace*{4cm} + }% + } + \vspace{\baselineskip} + \tcolorbox[ + colback = red!5!white , + colframe = red!75!black , + colbacktitle = yellow!50!red , + coltitle = red!25!black , + fonttitle = \bfseries , + subtitle style = { + boxrule = 0.4pt , + colback = yellow!50!red!25!white + } , + breakable , + title = \GetExerciseName~\GetExerciseProperty{counter} + \IfExercisePropertySetT{points}{% + (\GetExerciseProperty{points} + \IfExerciseGoalSingularTF{points} + {\XSIMtranslate{point}} + {\XSIMtranslate{points}})% + }] + \IfInsideSolutionF{% + \IfExercisePropertySetT{tags}{% + Tags: \ListExerciseTags{tags}{, } \par + }% + }% + } + {% + \endtcolorbox + \vspace{\baselineskip} + } + +\xsimsetup{ + % tags = {geometry} , + % topics = {geometry} + % tags/ingore-untagged % if true untagged exercise will be printed regardless + % % which tags have been chosen +} + +\begin{document} + +\gradingtable \par \bigskip + +Total: \printtotalpoints \par +from questions: \printpoints{question} \par +from exercises: \printpoints{exercise} \par +from problems: \printpoints{problem} \par \bigskip + +Total bonus: \printtotalbonus \par +from questions: \printbonus{question} \par +from exercises: \printbonus{exercise} \par +from problems: \printbonus{problem} \par + +% 1 +\begin{exercise}[points=4,bonus-points=1,topics=geometry,tags={geometry,triangles},grade=7] + \lipsum[1] +\begin{verbatim} +foo x^2 y^3 \gna +\end{verbatim} +\end{exercise} +\begin{solution}[print] + This is the solution to \ExerciseType\ \GetExerciseProperty{counter}. +\begin{verbatim} +foo x^2 y^3 \gna +\end{verbatim} +\end{solution} + +% 2 +\begin{exercise}[subtitle=Foo,points=5,topics=analysis,tags={analysis,functions},grade=11] + \lipsum[2] +\end{exercise} +\begin{solution} + This is the solution to \ExerciseType\ \GetExerciseProperty{counter}. +\end{solution} + +% 3 +\begin{problem}[tags={analysis,functions}] + \lipsum[3] + \writehere +\end{problem} +\begin{answer} + This is the solution to \ExerciseType\ \GetExerciseProperty{counter}. +\end{answer} + +% 4 +\begin{question} + \lipsum[4] + + \verb+\ExerciseID+: \GetExerciseAliasProperty{ID} + + \verb+\GetExerciseProperty{id}+: \GetExerciseProperty{id} + + \verb+\GetExerciseAliasProperty{ID}+: \GetExerciseAliasProperty{ID} + + \verb+\GetExerciseProperty{ID}+: \GetExerciseProperty{ID} +\end{question} +\begin{hint} + This is the solution to \ExerciseType\ \GetExerciseProperty{counter}. +\end{hint} + +% 5 +\begin{problem}[points=2] + \lipsum[3] + + \verb+\ExerciseID+: \GetExerciseAliasProperty{ID} + + \verb+\GetExerciseProperty{id}+: \GetExerciseProperty{id} + + \verb+\GetExerciseAliasProperty{ID}+: \GetExerciseAliasProperty{ID} + + \verb+\GetExerciseProperty{ID}+: \GetExerciseProperty{ID} + \writehere +\end{problem} +\begin{answer} + This is the solution to \ExerciseType\ \GetExerciseProperty{counter}. +\end{answer} + +% 6 +\begin{problem}[points=1] + \lipsum[3] + + \verb+\ExerciseID+: \GetExerciseAliasProperty{ID} + + \verb+\GetExerciseProperty{id}+: \GetExerciseProperty{id} + + \verb+\GetExerciseAliasProperty{ID}+: \GetExerciseAliasProperty{ID} + + \verb+\GetExerciseProperty{ID}+: \GetExerciseProperty{ID} +\end{problem} +\begin{answer} + This is the solution to \ExerciseType\ \GetExerciseProperty{counter}. +\end{answer} + +% 7 +\begin{exercise}[ID=test] + \lipsum[5] + + \verb+\ExerciseID+: \GetExerciseAliasProperty{ID} + + \verb+\GetExerciseProperty{id}+: \GetExerciseProperty{id} + + \verb+\GetExerciseAliasProperty{ID}+: \GetExerciseAliasProperty{ID} + + \verb+\GetExerciseProperty{ID}+: \GetExerciseProperty{ID} +\end{exercise} +\begin{solution} + This is the solution to \ExerciseType\ \GetExerciseProperty{counter}. +\end{solution} + +% 8 +\begin{exercise}[print=false,use=false] + \lipsum[5] +\end{exercise} +\begin{solution} + This is the solution to \ExerciseType\ \GetExerciseProperty{counter}. +\end{solution} + +% \printsolutionstype{exercise} + +\printsolutions* + +\section{Statistics} + +\ForEachUsedExerciseByType{% + \noindent\XSIMmixedcase{\ExerciseParameterGet{#1}{exercise-name}}~#3: \\ + \hspace*{2em}id: #2, type: #1, subtitle: #4, points: #5, bonus: #6\par \medskip +} + +\bigskip + +\ForEachUsedExerciseByID{% + \noindent\XSIMmixedcase{\ExerciseParameterGet{#1}{exercise-name}}~#3: \\ + \hspace*{2em}id: #2, type: #1, subtitle: #4, points: #5, bonus: #6\par \medskip +} + +\bigskip + +\ForEachUsedExerciseByType{% + \ExercisePropertyIfSetT{#1}{#2}{points} + { \XSIMmixedcase{\ExerciseParameterGet{#1}{exercise-name}}~#3: #5~points\par }% +} + +\bigskip + +Number of questions: \numberofquestions \par +Number of exercises: \numberofexercises \par +Number of problems: \numberofproblems + +\section{Grading tables} + +\gradingtable[template=default*,type=exercise] \par \bigskip + +\gradingtable[template=default*,type=problem] \par \bigskip + +\gradingtable[template=default*] \par \bigskip + +% vertical +\gradingtable[type=exercise] \par \bigskip + +\gradingtable[type=problem] \par \bigskip + +\gradingtable + +\end{document} diff --git a/Master/texmf-dist/doc/latex/xsim/xsim.history b/Master/texmf-dist/doc/latex/xsim/xsim.history new file mode 100644 index 00000000000..895e7a47a3b --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/xsim.history @@ -0,0 +1,81 @@ +-------------------------------------------------------------------------- + +XSIM -- eXercise Sheets IMproved + +-------------------------------------------------------------------------- +Clemens Niederberger +Web: https://github.com/cgnieder/xsim +E-Mail: contact@mychemistry.eu +-------------------------------------------------------------------------- +Copyright 2017 Clemens Niederberger + +This work may be distributed and/or modified under the +conditions of the LaTeX Project Public License, either version 1.3 +of this license or (at your option) any later version. +The latest version of this license is in + http://www.latex-project.org/lppl.txt +and version 1.3 or later is part of all distributions of LaTeX +version 2005/12/01 or later. + +This work has the LPPL maintenance status `maintained'. + +The Current Maintainer of this work is Clemens Niederberger. +-------------------------------------------------------------------------- + +HISTORY: + + v0.0 2017/02/09 - start with coding the first ideas + v0.1 2017/03/19 - first draft which actually seems to do everything as + planned + v0.2 2017/03/21 - bugfix in the verbwrite module + - add `use!' and `print!' properties + - add the concepts of `noupdate' and `boolean' properties + v0.4 2017/03/24 - \IfExerciseBooleanPropertyTF + - \GetExercisePropertyTF, \PropertyValue + - \printallsolutions + - \UseExerciseTemplate + - bug fix in solution environments: now get printed again + when option `print=true' is used + - bug fix to the translations of the solution list headings: + exercise name instead of exercise type is now printed + - \AddtoExerciseTypeGoal, \AddtoExerciseGoal + \AddtoExerciseTypeGoalPrint, \AddtoExerciseGoalPrint, + \ExerciseGoalValuePrint + - \addpoints, \addbonus, \points, \printgoal + v0.5 2017/03/30 - add style file mechanism + - make solution print conditions `section' and `chapter' + combinable + v0.5a 2017/04/15 - fix wrong translation of the `default-heading' + v0.5b 2017/04/16 - add \SetExerciseProperty + v0.6 2017/04/27 - official interface for grade distributions + - refine hook management (environment module) + v0.6a 2017/04/28 - refine \blank command, add documentation for said command + v0.7 2017/05/09 - \xsim_list_length:n + - new boolean property `used' + - when an exercise is collected the counter isn't stepped + but only when the exercise is inserted for the first + time; when this happens the new property `used' is set to + `true' + - make setting boolean properties case insensitive + - add missing pieces to manual (eg `page' property...) + - \TotalExerciseGoals and \TotalExerciseTypeGoals + - \XSIMifchapterTF + - \xsim_if_goal_sum:nnnTF and friends, + \IfExerciseTypeGoalsSumTF and \IfExerciseGoalsSumTF + - some more hints in the manual regarding collections + v0.8 2017/05/18 - bug fix in \xsim_set_property:nnnn + - random exercise lists from collections + - \xsim_collection_count:n + - \GetExerciseIdForProperty and \GetExerciseTypeForProperty + for unique properties + - set property `print=false' during collection and only to + true when the corresponding exercises actually are + printed + - do not insert \par at the beginning and end of exercises + and solutions; this should be left to the templates! + - new option `print-collection/print' which allows to + choose between exercises, solutions, and both to be + printed + - new parameter `solution-counter' in order to avoid + possible conflicts with existing counters + v0.8a 2017/05/19 - \IfPrintSolutionTF diff --git a/Master/texmf-dist/doc/latex/xsim/xsim.ideas b/Master/texmf-dist/doc/latex/xsim/xsim.ideas new file mode 100644 index 00000000000..bb43c7fec07 --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/xsim.ideas @@ -0,0 +1,31 @@ +-------------------------------------------------------------------------- + +XSIM -- eXercise Sheets IMproved + +-------------------------------------------------------------------------- +Clemens Niederberger +Web: https://github.com/cgnieder/xsim +E-Mail: contact@mychemistry.eu +-------------------------------------------------------------------------- +Copyright 2017 Clemens Niederberger + +This work may be distributed and/or modified under the +conditions of the LaTeX Project Public License, either version 1.3 +of this license or (at your option) any later version. +The latest version of this license is in + http://www.latex-project.org/lppl.txt +and version 1.3 or later is part of all distributions of LaTeX +version 2005/12/01 or later. + +This work has the LPPL maintenance status `maintained'. + +The Current Maintainer of this work is Clemens Niederberger. +-------------------------------------------------------------------------- + +IDEAS: + +- a document class `xsim-exam' for creating exams +- a mechanism for providing variants of an exam +- provide a switch: either write the environments to an external file + or save it to an auxiliary file ? (not really sure about this one -- + probably not) diff --git a/Master/texmf-dist/doc/latex/xsim/xsim_manual.pdf b/Master/texmf-dist/doc/latex/xsim/xsim_manual.pdf Binary files differnew file mode 100644 index 00000000000..3a0fa539656 --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/xsim_manual.pdf diff --git a/Master/texmf-dist/doc/latex/xsim/xsim_manual.tex b/Master/texmf-dist/doc/latex/xsim/xsim_manual.tex new file mode 100644 index 00000000000..2e351c7a64e --- /dev/null +++ b/Master/texmf-dist/doc/latex/xsim/xsim_manual.tex @@ -0,0 +1,2188 @@ +% !arara: pdflatex: { action: nonstopmode } +% !arara: biber +% arara: pdflatex: { action: nonstopmode } +% arara: pdflatex: { action: nonstopmode } +% arara: pdflatex: { action: nonstopmode } +% ---------------------------------------------------------------------------- +% the XSIM package +% +% eXercise Sheets IMproved +% +% ---------------------------------------------------------------------------- +% Clemens Niederberger +% Web: https://github.com/cgnieder/xsim +% E-Mail: contact@mychemistry.eu +% ---------------------------------------------------------------------------- +% Copyright 2017 Clemens Niederberger +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +% +% This work has the LPPL maintenance status `maintained'. +% +% The Current Maintainer of this work is Clemens Niederberger. +% ---------------------------------------------------------------------------- +% If you have any ideas, questions, suggestions or bugs to report, please +% feel free to contact me. +% ---------------------------------------------------------------------------- +\documentclass{xsim-manual} + +\usepackage{filecontents} +\begin{filecontents*}{\jobname.bib} +@online{texsx:romannumeral, + author = {Bruno Le Floch} , + title = {Cunning (La)TeX tricks} , + urldate = {2017-03-02} , + url = {http://tex.stackexchange.com/a/19769/} +} +@online{texsx:tagged/exsheets, + title = {Questions tagged `exsheets'} , + author = {various} , + url = {http://tex.stackexchange.com/questions/tagged/exsheets} , + urldate = {2017-05-15} +} +\end{filecontents*} +\addbibresource{\jobname.bib} + +\begin{document} + +\section{Licence, Requirements and \textsc{readme}} +\license + +\xsim\ loads the packages \pkg{expl3}~\cite{bnd:l3kernel}, +\pkg{xparse}~\cite{bnd:l3packages}, \pkg{etoolbox}~\cite{pkg:etoolbox}, +\pkg{array}~\cite{pkg:array} \pkg{booktabs}~\cite{pkg:booktabs} and +\pkg{translations}~\cite{pkg:translations}. All of these packages are present +on a modern and up to date \TeX\ distribution such as \TeX~Live or MiK\TeX\ so +no further action should be needed. When you are using \xsim\ you should be +using an up to date \TeX\ distribution, anyway. + +\begin{bewareofthedog} + Newer versions of \xsim\ may depend on newer versions of the support + packages. Remember: it is always dangerous to update single packages. + Always update your \TeX\ distribution if you want an up to date version of a + package. Be careful: if you're in the middle of an important project it + might be better to wait with the update until you've finished the project. + Every update might be breaking some things. +\end{bewareofthedog} + +\section{Motivation and Background} + +It has been quite a while since I first published +\pkg{exsheets}~\cite{pkg:exsheets} in June 2012. Since then it has gained a +user base and a little bit of popularity as the number of questions on tex.sx +shows (103~at the time of writing)~\cite{texsx:tagged/exsheets}. User +questions, bug reports and feature requests improved it over the time. It +still has a version number starting with a zero, though, which in my +versioning system means I still consider it experimental. + +This is due to several facts. It lacks a few features which I consider +essential for a full version~1. For one thing it is not possible to have +several kinds of exercises numbered independently. Using verbatim material +such as listings inside exercises and solutions is not possible and the +current workaround isn't that ideal either. One request which dates back +quite a while now was to have different types of points to exercises\ldots + +All of those aren't easy to add due to the way \pkg{exsheets} is implemented +right now. As a consequence I wanted to re-implement \pkg{exsheets} for a long +time. This is what lead to \xsim. Internally the package works completely +different. + +\begin{bewareofthedog} + \xsim\ will be the official successor of \pkg{exsheets} which is now + considered obsolete but will stay alive and will still receive bugfix + releases. However, new features will not be added to \pkg{exsheets} any + more. +\end{bewareofthedog} + +\section{How to Read the Manual}\label{sec:how-read-manual} + +\subsection{Nomenclature} + +Throughout this manual certain terms are used. This section explains their +meaning in this manual. + +\acuseall +\printacronyms[heading=none] + +\subsection{Package Options}\label{sec:package-options} +\xsim\ has these package options: +\begin{options} + \opt{verbose} + Writes extensive information about what \xsim\ is doing into the log + file. + \opt{final} + If used the exercise and solution environments will not rewrite the + environment body files. + \opt{clear-aux} + If used every time the total number of exercise changes \xsim\ will write + \emph{less} information to the auxfile on the next run and only if the + number of exercises stays stable between compilations the needed + information will be written to the auxfile. \emph{This needs more + compilations until everything stabilizes but should reduce the + probability of possibly faulty exercises after changes to the document.} + The \option{final} option automatically disables this option. See also + sections~\vref{sec:how-exerc-envir} and~\vref{sec:resolve-getting}. +\end{options} + +Those options are used the usual way as package option +\begin{sourcecode} + \usepackage[verbose]{xsim} +\end{sourcecode} +or as global option +\begin{sourcecode} + \documentclass[verbose]{article} +\end{sourcecode} +or via the setup command: +\begin{commands} + \command{xsimsetup}[\marg{options}] + Set up \xsim's package options and all other options described at + other places in the manual. +\end{commands} + +\subsection{Setting Options} +Apart from the package options already described in +section~\vref{sec:package-options} \xsim\ has further options. Those can be +\enquote{toplevel} options or options belonging to a module. +\begin{options} + \keyval*{toplevel}{value} + A toplevel option. + \keyval*{sublevel}{value}\Module*{module} + A sublevel option belonging to the module \module*{module} +\end{options} +Both kinds of options are set with \cs{xsimsetup}: +\begin{sourcecode} + \xsimsetup{ + toplevel = {value} , + module/sublevel = {value} + } +\end{sourcecode} + +\subsection{Command descriptions} + +Some commands do have a \expandablesymbol\ symbol printed next to their +names. This indicates that the command is expandable, \ie, it is usable in an +\cs*{edef} or \cs*{write} context and will expand according to its +description. All other commands are engine protected, \ie, in the sense of +\eTeX's \cs*{protected}. + +Some command name descriptions end with \code{\TF}. +\begin{commands} + \command*{SomeCommand\TF}[\meta{arguments}\marg{true}\marg{false}] + A command with maybe some arguments and ending with the two arguments + \meta{true} and \meta{false}. +\end{commands} +This means two things: the command is a conditional which tests something and +depending on the outcome of the test leaves either the \meta{true} argument +(\code{T}) or the \meta{false} argument (\code{F}) in the input stream. It +also means two additional commands exist: +\begin{commands} + \command*{SomeCommandT}[\meta{arguments}\marg{true}] + The same as \cs*{SomeCommandTF} but only with the \meta{true} argument and + no \meta{false} argument. + \command*{SomeCommandF}[\meta{arguments}\marg{false}] + The same as \cs*{SomeCommandTF} but only with the \meta{false} argument and + no \meta{true} argument. +\end{commands} + + +\section{Exercises and Solutions} + +The two predefined environments for exercises and solutions are the following +ones: +\begin{environments} + \environment{exercise}[\oarg{\acsp*{prop}}] + Input and typeset an exercise. See section~\vref{sec:exercise-properties} + for details on exercise \acsp*{prop}. + \environment{solution}[\oarg{options}] + Input and typeset the solution to the exercise of the previous + \env{exercise} environment. See section~\vref{sec:printing-solutions} for + details on options of solutions. +\end{environments} + +\begin{example} + \begin{exercise} + A first example for an exercise. + \end{exercise} + \begin{solution} + A first example for a solution. + \end{solution} +\end{example} + +As can be seen in the example a solution is not printed with the default +setup. This can be changed using the following option. +\begin{options} + \keybool{print}\Module{solution}\Default{false} + Set if solutions are printed or or not. +\end{options} + +The option (belonging to the module \module*{solution}) can either be set +locally as option to the \env{solution} environment +\begin{sourcecode} + \begin{solution}[print=true] + A first example for a solution. + \end{solution} +\end{sourcecode} +or with the setup command for all following solutions: +\begin{sourcecode} + \xsimsetup{ + solution/print = true + } +\end{sourcecode} + +There is an completely analoguous option for the \env{exercise} environment: +\begin{options} + \keybool{print}\Module{exercise}\Default{true} + Set if exercises are printed or or not. +\end{options} +More details on those two environments can be found in +section~\vref{sec:using-printing}. + +\section{How the Exercise Environments Work}\label{sec:how-exerc-envir} +Both enviroments write the contents of their bodies verbatim to external files +following a certain naming structure: +\begin{itemize} + \item + \code{\meta{jobname}-\meta{type}-\meta{id}-exercise|solution-body.tex} +\end{itemize} +The name starts with the name of the job (which is the name of the document +itself) followed by type and id of the corresponding exercise and then +followed by the environment type. For example both enviroments from the first +example have been written to files named +\begin{itemize} + \item \verbcode+xsim_manual-exercise-1-exercise-body.tex+ and + \item \verbcode+xsim_manual-exercise-1-solution-body.tex+, respectively. +\end{itemize} +Details on the \meta{type} of an exercise will be given in +section~\vref{sec:new-exercise-types}. \emph{The \meta{id} of an exercise is + a positive integer unique to each exercise environment regardless if the + exercise is being printed or used at all.} + +These external files are input when the respective exercise or solution is +printed. An advantage of using external files is that \emph{verbatim material + is allowed} inside the environments. Each of those files contains some +information about itself and where and why it was generated\footnote{In this + example the sourcecode line number is misleading as the example where the + file was generated itself was an external file where the \env{exercise} + environment indeed \emph{was} on line~1.}: + +\inputsourcecode{exercises/xsim_manual-exercise-1-exercise-body.tex} + +Arguably one downside of the approach using external files for each exercise +and its solution is that your project folder will be cluttered with files. In +order to deal with this somehow \xsim\ offers the following option: +\begin{options} + \keyval{path}{path name}\Default + With this option a subfolder or path within the main project folder can be + given. Exercises will be written to and included from this path. + \emph{The path must exist on your system before you can use it!} This + document uses \keyis{path}{exercises}. +\end{options} + +\begin{bewareofthedog} + \xsim\ writes a lot of stuff to the auxfile for re-using information on + subsequent compilations. If you add exercises, change properties \etc\ it + might happen that wrong information is staying in the auxfile and is wrongly + used by \xsim. In such cases deleting the auxfile and doing a few fresh + compilations may resolve your problems. + + Sometimes the \emph{existence of exercise or solution files from earlier + compilations} may lead to wrong lists of exercises or solutions. In such + cases it can be useful to delete all those files and doing a fresh + compilation. It may be helpful to use a subfolder for those exernal files + which will make deleting them a little bit easier. (Don't forget to both + create the subfolder and set \option{path} accordingly then.) + + Using the \option{clear-aux} option might help to reduce erroneous exercises. +\end{bewareofthedog} + +\section{New Exercise Types}\label{sec:new-exercise-types} + +It is easy to define new exercise environments together with a corresponding +solution environment using the following command: +\begin{commands} + \command{DeclareExerciseType}[\marg{type}\marg{parameters}] + Declare a new exercise type analoguous to the \env{exercise} and + \env{solution} environments. +\end{commands} +Declaring a new exercise type will also define a new command: +\begin{commands} + \command{numberof\meta{exercise-env}s} + These commands hold the absolut number of used exercises of type + \meta{type}. The meaning of \meta{exercise-env} will become clear below + when the exercise parameters are explained. It is always the same as the + exercise environment name. +\end{commands} +\begin{example} + There are \numberofexercises~exercises and \numberofproblems~problem in this + manual. +\end{example} +\xsim's pre-defined environment pair has been defined as follows: +\begin{sourcecode} + \DeclareExerciseType{exercise}{ + exercise-env = exercise , + solution-env = solution , + exercise-name = \XSIMtranslate{exercise} , + solution-name = \XSIMtranslate{solution} , + exercise-template = default , + solution-template = default + } +\end{sourcecode} + +The above already is an example for almost all parameters that can (and often +must) be set. Here is the complete list: +\begin{parameters} + \paraval{exercise-env}{exercise environment name} + The name for the environment used for the exercises of type \meta{type}. + \emph{This parameter is mandatory.} It can't be changed afterwards. + \paraval{solution-env}{solution environment name} + The name for the environment used for the solutions of type \meta{type}. + \emph{This parameter is mandatory.} It can't be changed afterwards. + \paraval{exercise-name}{exercise name} + The name of the exercises of type \meta{type} -- used for typesetting. + \emph{This parameter is mandatory.} + \paraval{solution-name}{solution name} + The name of the solutions of type \meta{type} -- used for typesetting. + \emph{This parameter is mandatory.} + \paraval{exercise-template}{exercise template} + The template used for typesetting the exercises of type \meta{type}. + \emph{This parameter is mandatory.} See + section~\vref{sec:styl-exerc-templ} for details on templates. + \paraval{solution-template}{solution template} + The template used for typesetting the exercises of type \meta{type}. + \emph{This parameter is mandatory.} See + section~\vref{sec:styl-exerc-templ} for details on templates. + \paraval{counter}{counter name} + The counter used for the exercises of type \meta{type}. If not explicitly + set the counter with the same name as \parameter{exercise-env} is used. + Otherwise the specified counter is used. This enables to have different + types of exercises sharing a common counter. \emph{This parameter can't + be changed afterwards.} If the explicit or implicit counter does not + exist, yet, it will be defined. + \paraval{solution-counter}{counter name} + The counter used for the solutions of type \meta{type}. If not explicitly + set the counter with the same name as \parameter{solution-env} is used. + Otherwise the specified counter is used. This enables to have different + types of solutions sharing a common counter although this doesn't actually + make much sense. But it can be useful to avoid using an already existing + counter. \emph{This parameter can't be changed afterwards.} If the + explicit or implicit counter does not exist, yet, it will be defined. The + sole purpose of this counter is to be able to label solutions so they can + be \cs*{pageref}ed. + \paraval{number}{integer} + An internal parameter that is used to keep track of the number of + exercises of a type. This parameter cannot be set or changed by the + user. +\end{parameters} + +It is possible to change some of the parameters after an exercise type has +been defined. Those include \parameter{exercise-name}, +\parameter{solution-name}, \parameter{exercise-template}, and +\parameter{solution-template}: +\begin{commands} + \command{SetExerciseParameter}[\marg{type}\marg{parameter}\marg{value}] + Usable to set a single parameter to a new value. + \command{SetExerciseParameters}[\marg{type}\marg{parameters}] + Set several parameters at once. \meta{parameters} is a csv list of + key/value pairs. +\end{commands} +If you try to set an already set but fixed parameter like +\parameter{exercise-env} a warning will be written to the log file. For all +parameters that can be changed also options exist wich can be set via +\cs{xsimsetup}. They are explained in +section~\vref{sec:environment-options-hooks}. + +\begin{bewareofthedog} + All exercises of a type use the parameters + (\eg, \parameter{exercise-template}) that are \emph{currently active}. If + you want exercises with a different look or different names in the same + document you should use different exercises types. +\end{bewareofthedog} + +\section{Exercise Properties}\label{sec:exercise-properties} + +\subsection{Predefined Properties} + +Exercise like the \env{exercise} environment and possibly others defined with +\cs{DeclareExerciseType} have a number of predefined \acsp*{prop}: +\begin{properties} + \propval{id}{integer} + Holds the internal id of an exercise. \emph{Cannot be set by the user}. + \propval{ID}{text} + Holds the user id of an exercise if defined. Otherwise it is equal to + \property{id}. + \propval{counter}{text} + Holds the counter value represenation of an exercise (\ie, what you + usually know as \cs*{the\meta{counter}}). \emph{Cannot be set by the + user}. + \propval{counter-value}{integer} + Holds the counter value of an exercise (\ie, what you usually know as + \cs*{arabic}\marg{counter}). \emph{Cannot be set by the user}. + \propval{subtitle}{text} + Holds the subtitle of an exercise. + \propval{points}{number} + Holds the reachable points of an exercise. + \propval{bonus-points}{number} + Holds the reachable bonus-points of an exercise. + \propbool{print} + Holds the print boolean of an exercise. + \propbool{print\bang} + Holds a special print boolean of an exercise, see + page~\pageref{property:print!}. + \propbool{use} + Holds the usage boolean of an exercise. + \propbool{use\bang} + Holds a special usage boolean of an exercise, see + page~\pageref{property:print!}. + \propbool{used} + True if an exercise has been used at least once. For an existing exercise + this is only false for exercises that have been collected + (\cf~section~\vref{sec:collecting-exercises}). + \propval{tags}{csv list of tags} + Holds the list of tags the exercise should be associated with. + \propval{topics}{csv list of topics} + Holds the list of topics the exercise should be associated with. + \propval{page}{text} + Holds the page counter value represenation of an exercise (\ie, what you + usually know as \cs*{thepage}). + \propval{page-value}{integer} + Holds the page counter value of an exercise (\ie, what you usually know as + \cs*{arabic}\Marg{page}). + \propval{section}{text} + Holds the section counter value represenation of an exercise (\ie, what + you usually know as \cs*{thesection}). + \propval{section-value}{integer} + Holds the section counter value of an exercise (\ie, what you usually know + as \cs*{arabic}\Marg{section}). + \propval{chapter}{text} + Holds the chapter counter value represenation of an exercise (\ie, what + you usually know as \cs*{thechapter}). \emph{Only if a command + \cs*{chapter} \emph{and} a counter \code{chapter} exist.} + \propval{chapter-value}{integer} + Holds the chapter counter value of an exercise (\ie, what you usually know + as \cs*{arabic}\Marg{chapter}). \emph{Only if a command \cs*{chapter} + \emph{and} a counter \code{chapter} exist.} +\end{properties} + +Some of these \acsp*{prop} are fixed and cannot be set by the user. Those +include \property{id}, \property{counter}, and \property{counter-value}. The +others can be set using the optional argument of the exercise environment. + +\begin{example} + \begin{exercise}[subtitle={This is a subtitle},points=4,bonus-points=1] + An exercise where some properties have been set. + \end{exercise} +\end{example} + +\subsection{Declaring Own Properties} + +\xsim\ offers the possibility to declare additional exercise properties: +\begin{commands} + \command{DeclareExerciseProperty}[\barg\sarg\narg\marg{property}] + Declares the property \meta{property}. + + If used with the optional \barg\ star a unique property is defined which + means that each exercise must have a property value distinct from all + other exercises (all means all -- \emph{independent from the exercise type}). + + If used with the optional \sarg\ a boolean property is defined which + means that it only should get the values \code{true} or \code{false} and + if used without value it gets the value \code{true} instead of an empty + value. If any other value is used the property is set to + \code{false}. A boolean option obviously cannot be unique. The optional + \sarg\ takes precedence over the optional \barg, \ie, if both are present + the property is boolean \emph{but not} unique. + + If used with the optional \narg\ a property is defined which won't get + updated through subsequent compilation runs but is only set when the + exercise is used. + \command{DeclareExercisePropertyAlias}[\marg{property 1}\marg{property 2}] + Declares \meta{property 1} to be an alias of \meta{property 2}. This + means that each time \meta{property 2} is set \meta{property 1} will be + set to the same value \emph{unless} it has been set already. As an + example: property \property{ID} is an alias of property \property{id}. +\end{commands} + +This is better demonstrated with an example: +\begin{example} + \begin{exercise} + \lipsum[4] % from package `lipsum' + \verb+\GetExerciseProperty{id}+: \GetExerciseProperty{id} \par + \verb+\GetExerciseAliasProperty{ID}+: \GetExerciseAliasProperty{ID} \par + \verb+\GetExerciseProperty{ID}+: \GetExerciseProperty{ID} + \end{exercise} + \begin{exercise}[ID=foo-bar] + \lipsum[4] + \verb+\GetExerciseProperty{id}+: \GetExerciseProperty{id} \par + \verb+\GetExerciseAliasProperty{ID}+: \GetExerciseAliasProperty{ID} \par + \verb+\GetExerciseProperty{ID}+: \GetExerciseProperty{ID} + \end{exercise} +\end{example} + +The power of properties will get more clear when reading +section~\vref{sec:styl-exerc-templ} about templates. + +\subsection{A Special Kind of Property: Exercise Goals}\label{sec:goals} + +Exercise goals are a generic concept in \xsim\ for exercise properties like +\property{points} or \property{bonus-points}. Those are properties which can +(only) get a decimal number as value the sum of which is calculated and +available (after a compilation) throughout the document. +\begin{commands} + \command{DeclareExerciseGoal}[\marg{goal}] + Declare a new exercise goal named \meta{goal} and also a property called + \meta{goal}. + \command{TotalExerciseTypeGoal}[\marg{type}\marg{goal}\marg{singular}\marg{plural}] + Get the sum of goal \meta{goal} for all exercises of type \meta{type}. + \meta{singular} and \meta{plural} are placed after the sum in the input + stream depending on whether the sum equals~$1$ or not. + \command{TotalExerciseTypeGoals}[\marg{type}\marg{list of + goals}\marg{singular}\marg{plural}] + Get the sum of goal all goals in \meta{list of goals} for all exercises of + type \meta{type}. The goal names in \meta{list of goals} must be + separated with \code{+}. \meta{singular} and \meta{plural} are placed + after the sum in the input stream depending on whether the sum equals~$1$ + or not. + \command{TotalExerciseGoal}[\marg{goal}\marg{singular}\marg{plural}] + Get the sum of goal \meta{goal} for all exercises. \meta{singular} and + \meta{plural} are placed after the sum in the input stream depending on + whether the sum equals~$1$ or not. + \command{TotalExerciseGoals}[\marg{list of + goals}\marg{singular}\marg{plural}] + Get the sum of goal all goals in \meta{list of goals} for all exercises. + The goal names in \meta{list of goals} must be separated with + \code{+}. \meta{singular} and \meta{plural} are placed after the sum in + the input stream depending on whether the sum equals~$1$ or not. + \command{AddtoExerciseTypeGoal}[\marg{type}\marg{goal}\marg{value}] + Adds \meta{value} to the goal \meta{goal} of exercise type \meta{type}. + \command{AddtoExerciseTypeGoalPrint}[\marg{type}\marg{goal}\marg{value}% + \marg{singular}\marg{plural}] + Adds \meta{value} to the goal \meta{goal} of exercise type \meta{type}. + The value and -- depending on wether the value equals $1$ or not -- + \meta{singular} or \meta{plural} are left in the input stream. + \command{AddtoExerciseGoal}[\marg{goal}\marg{value}] + Adds \meta{value} to the goal \meta{goal} of the current exercise + type. (To be used within exercises.) + \command{AddtoExerciseTypeGoalPrint}[\marg{goal}\marg{value}% + \marg{singular}\marg{plural}] + Adds \meta{value} to the goal \meta{goal} of the current exercise type. + The value and -- depending on wether the value equals $1$ or not -- + \meta{singular} or \meta{plural} are left in the input stream. (To be used + within exercises.) + \command{ExerciseGoalValuePrint}[\marg{value}\marg{singular}\marg{plural}] + Print \meta{value} and -- depending on wether the value equals $1$ or not -- + \meta{singular} or \meta{plural}. + \command{printgoal}[\marg{value}] + Print \meta{value} according to option \option{goal-print}. Defined in + terms of \cs{ExerciseGoalValuePrint}. + \command{printpoints}[\marg{type}] + Print the sum of points for all exercises of type \meta{type} followed by + an appropriate translation of the words \enquote{point} or + \enquote{points}, respectively\footnote{See section~\vref{sec:exerc-transl} + for details on the definition and usage of language dependent words.}. + Defined in terms of \cs{TotalExerciseTypeGoal}. + \command{printtotalpoints} + Print the sum of points for all exercises followed by an appropriate + translation of the words \enquote{point} or \enquote{points}, + respectively. Defined in terms of \cs{TotalExerciseGoal}. + \command{addpoints}[\sarg\marg{value}] + Adds \meta{value} to the points of the current exercise type. (To be used + within exercises.) Prints the value followed by an appropriate + translation of the words \enquote{point} or \enquote{points}, + respectively. The starred version prints nothing. Defined in terms of + \cs{AddtoExerciseGoal} and \cs{AddtoExerciseGoalPrint}. + \command{points}[\marg{value}] + Print \meta{value}followed by an appropriate translation of the words + \enquote{point} or \enquote{points}, respectively. Defined in terms of + \cs{ExerciseGoalValuePrint}. + \command{printbonus}[\marg{type}] + Print the sum of bonus points for all exercises of type \meta{type} + followed by an appropriate translation of the words \enquote{point} or + \enquote{points}, respectively. Defined in terms of + \cs{TotalExerciseTypeGoal}. + \command{printtotalbonus} + Print the sum of bonus points for all exercises followed by an appropriate + translation of the words \enquote{point} or \enquote{points}, + respectively. Defined in terms of \cs{TotalExerciseGoal}. + \command{addbonus}[\sarg\marg{value}] + Adds \meta{value} to the bonus points of the current exercise type. (To be + used within exercises.) Prints the value followed by an appropriate + translation of the words \enquote{point} or \enquote{points}, + respectively. The starred version prints nothing. Defined in terms of + \cs{AddtoExerciseGoal} and \cs{AddtoExerciseGoalPrint}. +\end{commands} + +The two existing goals are defined with +\begin{sourcecode} + \DeclareExerciseGoal{points} + \DeclareExerciseGoal{bonus-points} +\end{sourcecode} + +When goal values are printed the decimal number is fed to a function which can +be changed using the following option: +\begin{options} + \keyval{goal-print}{code}\Default{\#1} + How to format goal values. Use \code{\#1} to refer to the actual number. +\end{options} + +At last some examples for a custom command: let's say you want a command which +prints the complete sum for all exercises of all exercise types of both +\property{points} \emph{and} \property{bonus-points} added up: +\begin{sourcecode} + \NewDocumentCommand\printsumofpointsandbonus{}{% + \TotalExerciseGoals{points+bonus-points} + {\,\XSIMtranslate{point}} + {\,\XSIMtranslate{points}}% + } +\end{sourcecode} +Here is how you could mimick the command \cs*{totalpoints} from +\pkg{exsheets}: +\begin{sourcecode} + \NewDocumentCommand\pointsandbonus{}{% + \TotalExerciseGoal{points}{}{}% + \IfExerciseGoalsSumF{bonus-points}{=0} + {\,(+\,\TotalExerciseGoal{bonus-points}{}{})}% + \,\XSIMtranslate{points}% + } +\end{sourcecode} + + +\subsection{A Special Kind of Property: Exercise Tags}\label{sec:tags} + +Exercise tags are a generic concept in \xsim\ for exercise properties like +\property{tags} or \property{topics}. Those are properties which can (only) +get a csv list of strings as value. Those strings can be used to selectively +use exercises. See section~\vref{sec:using-printing} for details on +\emph{usage} of exercises and the difference to \emph{printing} an exercise +and how to use exercise tags for selection. +\begin{commands} + \command{DeclareExerciseTagging}[\marg{tag}] + This defines an exercise tagging group named \meta{tag}. It also defines a + property named \meta{tag}. In addition two options are defined: an option + named \code{\meta{tag}} which can be used for selection and an boolean + option \code{\meta{tag}/ignore-untagged}. +\end{commands} +The two existing tagging groups have been defined and preset with the +following code: +\begin{sourcecode} + \DeclareExerciseTagging{tags} + \DeclareExerciseTagging{topics} + \xsimsetup{tags/ingore-untagged=false} +\end{sourcecode} +This means that these options are available: +\begin{options} + \keyval{tags}{csv list of tags} + Choose the set of tags whose associated exercises should be printed. + \keyval{topics}{csv list of topics} + Choose the set of tags whose associated exercises should be printed. + \keybool{ignore-tagging}\Module{tags}\Default{false} + If set to true exercises with no tags will be printed even if tags have + been chosen with the option \option{tags}. + \keybool{ignore-tagging}\Module{topics}\Default{true} + If set to true exercises with no topics will be printed even if tags have + been chosen with the option \option{topics}. +\end{options} + +It may happen that you choose certain tags for printing and want one or two +exercises to be printed or used even if they don't match the tagging +criteria. For this reason two additional properties exist which can be set to +an exercise:\label{property:print!} +\begin{properties} + \propbool{print\bang} + If set to true the exercise will be printed (and thus used) regardless of + other conditions. + \propbool{use\bang} + If set to true the exercise will be used regardless of other conditions. +\end{properties} + +\section{Using and Printing an Exercise}\label{sec:using-printing} +\subsection{What the Environments do} + +When an exercise is started with \environ{exercise} (or other environments +defined through \cs{DeclareExerciseType}) then different things happen +depending on different settings: +\begin{itemize} + \item If the \emph{insert mode} is active nothing happens, see + section~\vref{sec:collecting-exercises} for details on this. + \item Else the id integer is incremented. + \item If the exercise is \emph{used} the corresponding counter is stepped + and the exercise is added to the \enquote{use list}. The properties + \property{counter} and \property{use} are updated accordingly. + \item If an exercise is \emph{printed} then it is also \emph{used}. An + exercise that isn't used cannot be printed. Being printed means two + things: being added to the \enquote{print list} and being typeset at the + position where the exercise is placed in the source file. If an exercise + is \emph{not printed but used} it means that the counter will be stepped. + This can be useful for creating an exercise sheet only containing the + solutions for some exercises. + \item If an exercise is printed certain hooks and template code is inserted + around the environment body. +\end{itemize} + +\begin{example} + \begin{exercise}[print=false] + This exercise will not be printed but the exercise counter will be + incremented nonetheless. Its solution will be printed in the list of + solutions. + \end{exercise} + \begin{solution} + The solution of the exercise that has not been printed. + \end{solution} +\end{example} + +The schematic structure of an exercise is shown in +figure~\vref{fig:schematic-structure}. + +\begin{figure} + \centering + \begin{tikzpicture} + \node[draw,minimum width=.7\linewidth] at (0,0) {pre hook}; + \node[draw,minimum width=.7\linewidth] at (0,-1) {begin template code}; + \node[draw,minimum width=.7\linewidth] at (0,-2) {begin hook}; + \node[draw,minimum width=.7\linewidth] at (0,-3) {environment body}; + \node[draw,minimum width=.7\linewidth] at (0,-4) {end hook}; + \node[draw,minimum width=.7\linewidth] at (0,-5) {end template code}; + \node[draw,minimum width=.7\linewidth] at (0,-6) {post hook}; + \end{tikzpicture} + \caption{Schematic structure of an exercise or solution.}\label{fig:schematic-structure} +\end{figure} + +\subsection{Environment Options \& Hooks}\label{sec:environment-options-hooks} + +For each exercise type there are the following options for both environments, +the environments' names are the module names for the options (here using the +\enquote{exercise} type): +\begin{options} + \keybool{print}\Module{exercise}\Default{true} + Determines if exercises of type \enquote{exercise} are printed. + \keybool{use}\Module{exercise}\Default{true} + Determines if exercises of type \enquote{exercise} are used. + \keyval{within}{counter}\Module{exercise}\Default + Adds the exercise counter to the reset list of the counter + \meta{counter}. \emph{Beware that if the counter is a shared counter + this will affect \emph{all objects} using this counter!} + \keyval{the-counter}{code}\Module{exercise} + An interface for redefining the counter representation command + \cs*{the\meta{counter}}. + \keyval{template}{template}\Module{exercise} + An interface for \cs{SetExerciseParameter}\Marg{exercise}% + \Marg{exercise-template}\marg{template}. + \keyval{template}{template}\Module{solution} + An interface for \cs{SetExerciseParameter}\Marg{exercise}% + \Marg{solution-template}\marg{template}. + \keyval{name}{name}\Module{exercise} + An interface for \cs{SetExerciseParameter}\Marg{exercise}% + \Marg{exercise-name}\marg{name}. + \keyval{name}{name}\Module{solution} + An interface for \cs{SetExerciseParameter}\Marg{exercise}% + \Marg{solution-name}\marg{name}. + \keyval{pre-hook}{code}\Module{exercise}\Default + The code for the \emph{pre exercise hook} for exercises of the type + \enquote{exercise}. + \keyval{begin-hook}{code}\Module{exercise}\Default + The code for the \emph{begin exercise hook} for exercises of the type + \enquote{exercise}. + \keyval{end-hook}{code}\Module{exercise}\Default + The code for the \emph{end exercise hook} for exercises of the type + \enquote{exercise}. + \keyval{post-hook}{code}\Module{exercise}\Default + The code for the \emph{post exercise hook} for exercises of the type + \enquote{exercise}. + \keybool{print}\Module{solution}\Default{false} + Determines if solutions of type \enquote{exercise} are printed. + \keyval{pre-hook}{code}\Module{solution}\Default + The code for the \emph{pre solution hook} for solutions of the type + \enquote{exercise}. + \keyval{begin-hook}{code}\Module{solution}\Default + The code for the \emph{begin solution hook} for solutions of the type + \enquote{exercise}. + \keyval{end-hook}{code}\Module{solution}\Default + The code for the \emph{end solution hook} for solutions of the type + \enquote{exercise}. + \keyval{post-hook}{code}\Module{solution}\Default + The code for the \emph{post solution hook} for solutions of the type + \enquote{exercise}. + % TODO +\end{options} + +\subsection{(Re-) Inserting a Certain Exercise} +If you know type and \property{id} of an exercise you can (re-)insert every +existing exercise, \ie, every exercise whose external file exists. +\begin{commands} + \command{printexercise}[\marg{type}\marg{id}] + Inserts the exercise of type \meta{type} with the \property{id} + \meta{id}. +\end{commands} +\begin{example} + \printexercise{exercise}{5} +\end{example} + +\section{Collecting Exercises}\label{sec:collecting-exercises} + +\subsection{Background} +\xsim\ knows the concept of \enquote{exercise collections}. A collection of +exercises can be useful when you want to print a certain group of exercises +several times. Each collection must have a unique name with which you can +refer to the corresponding collection. A collection is realized by declaring +the collection and by surrounding the exercises belonging to the collection +with a certain pair of commands (this is explained in the next section). + +Let's say you have several files of math exercises where one only contains +geometry exercises and another only calculus exercises and so on. Surrounding +the \cs*{input} of each file with said pair of commands for a certain +collection all exercises of the corresponding file now are a collection which +then can be printed at once whereever you want the collection of exercises to +be printed. By choosing certain tags (see section~\vref{sec:tags}) inside +each collection you could even cherry-pick exercises from the external file. + +\subsection{Usage} +\emph{A collection must be declared in the preamble.} Using a pair of +commands explained below exercises between those commands are added to the +corresponding collection but not printed. After a collection is completed the +collection can be printed as often as needed. +\begin{commands} + \command{DeclareExerciseCollection}[\marg{collection name}] + Define a new collection \meta{collection name} in the document preamble. + \command{collectexercisestype}[\marg{collection name}\marg{exercise type}] + Opens the collection \meta{collection name} which now collects all + exercises of type \meta{exercise type} until the collection is closed with + \cs{collectexercisesstop}. Collections of other types are not + collected\footnote{This command starts a group with + \cs*{begingroup}!}. + \command{collectexercises}[\marg{collection name}] + Opens the collection \meta{collection name} which now collects all + exercises until the collection is closed with + \cs{collectexercisesstop}\footnote{This command starts a group with + \cs*{begingroup}!}. + \command{collectexercisesstop}[\marg{collection name}] + Closes the collection \meta{collection name}\footnote{This command ends + a group with \cs*{endgroup}!}. + \command{printcollection}[\oarg{options}\marg{collection name}] + Prints the collection \meta{collection name}, \ie, all exercises collected + earlier. This command cannot be used before the corresponding collection + has been closed correctly. +\end{commands} + +Valid options are the following: +\begin{options} + \keybool{headings}\Module{print-collection}\Default{false} + If true a heading for each exercise type is inserted. + \keyval{headings-template}{template}\Module{print-collection}\Default{collection} + The heading template used when \keyis{headings}{true}. + \keychoice{print}{exercises,solutions,both}\Module{print-collection}\Default{exercises} + Determines wether \cs{printcollection} prints the exercises or the + solutions of the collection. When you choose \code{both} exercises and + solutions are printed alternately. +\end{options} + +Those options can also be set via \cs{xsimsetup} using the module +\module{print-collection}. + +\begin{bewareofthedog} + Please be aware that exercises are not used or printed while they are + collected. Nonetheless the property \property{use} is set to \code{true} + (so that solutions can be printed even if the exercises are not) and the + property \property{print} is set to \code{false}. Also their counters are + \emph{not stepped} during the process. This only happens when they are + printed the first time, \cf~the \property{used} property. At that time + also the properties \property{page}, \property{section} and + \property{chapter} are set and the property \property{print} is set to + \code{true}. +\end{bewareofthedog} + +The usage should be clear: +\begin{example} + \collectexercises{foo} + \begin{exercise} + This exercise is added to the collection `foo'. + \end{exercise} + \begin{exercise} + This exercise is also added to the collection `foo'. + \end{exercise} + \begin{exercise} + So is this. + \end{exercise} + \begin{exercise} + As well as this one. + \end{exercise} + \collectexercisesstop{foo} +\end{example} +Once the collection is closed it can be printed: +\begin{example} + \printcollection{foo} +\end{example} + +You can open several collections at the same time: +\begin{sourcecode} + \collectexercises{foo} + ... + \collectexercisestype{bar}{exercises} + ... + \collectexercisesstop{bar} + ... + \collectexercisesstop{foo} +\end{sourcecode} +Exercises will be added to each open collection. + +There is one generic collection called \enquote{\code{all exercises}}. As the +name already suggests it will hold all exercises. So if you say +\begin{sourcecode} + \printcollection{all exercises} +\end{sourcecode} +all exercises will be printed. + +\begin{bewareofthedog} + If you use \cs*{label}s inside of exercises and you print exercises more + than once in your document (by reusing a collection for example) you will + get +\begin{sourcecode} + LaTeX Warning: There were multiply-defined labels. +\end{sourcecode} + Equally if you have environments like \environ{equation} which step a + counter inside an exercise or solution the counter will be stepped each time + the exercise is used. +\end{bewareofthedog} + +At last now an example using external files, collections and tags: +\begin{sourcecode} + % preamble: + % \DeclareExerciseCollection{foo-easy} + % \DeclareExerciseCollection{foo-medium} + % \DeclareExerciseTagging{difficulty} + + % document: + \collectexercises{foo-easy} + \xsimsetup{difficulty=easy} + \input{foo.tex} + \collectexercisesstop{foo-easy} + % collection `foo-easy' now contains all exercises of file `foo.tex' tagged + % with `difficulty=easy' + + \collectexercises{foo-medium} + \xsimsetup{difficulty=medium} + \input{foo.tex} + \collectexercisesstop{foo-medium} + % collection `foo-medium' now contains all exercises of file `foo.tex' + % tagged with `difficulty=medium' +\end{sourcecode} + +\begin{bewareofthedog} + The recommended usage is similar to the last example. Actually a collection + can be printed \emph{before} it is opened, too. (This needs \emph{at least} + two compilations, though.) However, it is safer printing a collection only + once and only \emph{after it has been collected}. No guaranties are given + that properties are set correctly if you use the collection before. You + usually also will make sure that the exercises in a collection are unique, + \ie, that an exercises is not part of several collections -- at least not if + both collections are printed in the same document. +\end{bewareofthedog} + +\section{Printing Random Exercises From a Collection} +\xsim\ provides the possibility of selecting random exercises from a +collection (\cf~section~\vref{sec:collecting-exercises}). +\begin{commands} + \command{printrandomexercises}[\oarg{options}\marg{number}] + This command prints \meta{number} random exercises from the collection + chosen with option \option{collection}, see below. When this command is + used it generates a random list of integers which is written to the + \code{aux} file. On the subsequent compilations the according exercises + are printed. \emph{If you want to regenerate the random list you have to + delete the \code{aux} file before compiling.} +\end{commands} +Valid options for this command are: +\begin{options} + \keybool{sort}\Module{random}\Default{true} + Determines wether the random chosen exercises should be sorted according + to their order of definition in the collection or not. + \keyval{collection}{collection}\Module{random}\Default{all exercises} + The collection from which the exercises are to be chosen from. + \keyval{exclude}{csv list of ids}\Module{random} + A list of \property{id}s or \property{ID}s of exercises \emph{not} to be + chosen. + \keychoice{print}{exercises,solutions,both}\Module{random}\Default{exercises} + Determines wether \cs{printrandomexercises} prints the exercises or the + solutions. When you choose \code{both} exercises and solutions are + printed alternately. +\end{options} + +\begin{example} + \printrandomexercises[collection=foo]{2} +\end{example} + +The example above of course doesn't make much sense but if have a collection +which collects exercises from an external file and the exercise haven't been +printed in the document before then you will get a list of subsequently +numbered exercises. + +\section{Printing Solutions}\label{sec:printing-solutions} + +There are different commands for printing the solutions to exercises: +\begin{commands} + \command{printsolutionstype}[\sarg\oarg{options}\marg{exercise type}] + Prints the solutions of all used exercises of type \meta{exercise type}. + The starred version only prints the solutions of all printed exercises of + type \meta{exercise type}. + \command{printsolutions}[\sarg\oarg{options}] + Prints the solutions of all used exercises of all types ordered by type. + The starred version only prints the solutions of all printed exercises of + all types. + \command{printallsolutions}[\sarg\oarg{options}] + Prints the solutions of all used exercises of all types ordered by + appearance in the document. The starred version only prints the solutions + of all printed exercises of all types. + \command{printsolution}[\oarg{options}\marg{type}\marg{id}] + Prints the solution of the exercise of type \meta{type} with the + \property{id} \meta{id}. +\end{commands} + +\begin{example} + \printsolutionstype{exercise} +\end{example} + +The options can be diveded into two groups. The ones in the first group +modify the layout. +\begin{options} + \keybool{headings}\Default{true} + If true a heading for each exercise type is inserted. + \keyval{headings-template}{template}\Default{default} + The heading template used when \keyis{headings}{true}. +\end{options} + +The ones in the second group set conditions selecting which solutions are +printed. If you combine those conditions a solution is printed if it meets +either of the conditions. +\begin{options} + \keychoice{section}{\default{true},false,\meta{integer}}\Default{false} + If you set \keyis{section}{true} only solutions of exercises of the + current section are printed. If you set \keyis{section}{4} only solutions + of exercises in a section with number~$4$ are printed. + \keychoice{chapter}{\default{true},false,\meta{integer}}\Default{false} + If you set \keyis{chapter}{true} only solutions of exercises of the + current chapter are printed. If you set \keyis{chapter}{4} only solutions + of exercises in a chapter with number~$4$ are printed. + \keychoice{collection}{false,\meta{collection name}}\Default{false} + If used only solutions of exercises belonging to collection + \meta{collection name} are printed. +\end{options} + +The conditions can be combined. The following call will only print solutions +from exercises in section~3 of chapter~2: +\begin{sourcecode} + \printsolutions[chapter=2,section=3] +\end{sourcecode} + +\begin{bewareofthedog} + The selection per section or per chapter relies on the \emph{counter + numbers} of the sections or chapters, respectively. This means if section + numbers are reset (\eg\ by \cs*{chapter} or \cs*{appendix}) and you have + exercises from \emph{different} sections with \emph{the same section number} + the solutions of \emph{all those exercises} will be printed. This means you + only should use the \option{section} selection when section are the top + document level headings (apart from parts) and you have no exercises in the + appendix. Similar considerations are valid for the \option{chapter} + selection. +\end{bewareofthedog} + +All options can also be set via \cs{xsimsetup} using the module +\module{print-solutions}. + +\begin{example} + \printsolutions[section=4,headings-template=per-section] +\end{example} + +\begin{example} + \printsolution{exercise}{5} +\end{example} + +\section{Grading Tables}\label{sec:grading-tables} +When you create exercises it may not only be desirable to be able to add +points and bonus-points to a question (see section~\vref{sec:goals} about +exercise goals) but also to be able to output a grading table. \xsim\ has +built-in means for this. +\begin{commands} + \command{gradingtable}[\oarg{options}] + Print a grading table. +\end{commands} +Valid options for this command are +\begin{options} + \keyval{template}{template}\Default{default} + Choose the template used for the grading table. + \keyval{type}{exercise type}\Default + Choose the exercise type for which the table is printed. +\end{options} +Both option defaults can be changed with \cs{xsimsetup} setting the options +using \module{grading-table}: +\begin{sourcecode} + \xsimsetup{ + grading-table/template = default* + } +\end{sourcecode} + +An example: +\begin{example} + \gradingtable[type=exercise] +\end{example} + +Or using the \enquote{\code{default*}} template: +\begin{example} + \gradingtable[template=default*,type=exercise] +\end{example} + +Available templates and how to define new ones are explained in +sections~\vref{sec:grad-table-templ} and~\vref{sec:template-examples}. \xsim\ +per default provides two templates \enquote{\code{default}} and +\enquote{\code{default*}}, the first one has a vertical layout, the second a +horizontal layout. Both templates can be used per type like in the examples +above or for all types at once by leaving the specification \option{type} +away: +\begin{example} + \gradingtable +\end{example} + +\section{Styling the Exercises -- Templates}\label{sec:styl-exerc-templ} + +\subsection{Background} +Whenever \xsim\ outputs something to be typeset it uses so-called templates +for the task. \xsim\ knows of three different kinds of templates: +\begin{itemize} + \item environment templates (see section~\vref{sec:envir-templ}), + \item heading templates (see section~\vref{sec:heading-templates}) and + \item grading table templates (see section~\vref{sec:grad-table-templ}) +\end{itemize} + +The most important one for the styling of the exercises are the environment +templates. Those templates give you complete control over the look and +arrangement of an exercise. To be able to do this \xsim\ provides a large +number of commands which can be used only inside template +definitions\footnote{The last sentence is wrong: those commands can be used + anywhere but most of them only give useful results inside of templates.}. +Those commands are explained in the next section. Their usage will hopefully +become clear in the examples in section~\vref{sec:template-examples}. Having +full control over the layout comes at a price: you need to be able to program +yourself in order to achieve certain layouts\footnote{I plan to incorporate + the most common layouts -- and maybe some fancy ones, too -- in the examples + section~\vref{sec:template-examples} but at the time of writing this is still + up in the air.}. + +\subsection{Commands for Usage in Template Definitions} +\subsubsection{Goals} +\begin{commands} + \command{IfExerciseGoal\TF}[\marg{goal}\marg{relation and + value}\marg{true}\marg{false}] + Checks the sum of goal \meta{goal} against \meta{relation and value}. + \command{IfExerciseGoalSingular\TF}[\marg{goal}\marg{true}\marg{false}] + Checks if the value of the goal \meta{goal} of the current exercise + equals~$1$. This is the same as \\ + \cs{IfExerciseGoalTF}\marg{goal}\Marg{=1}\marg{true}\marg{false}. + \command{IfExerciseTypeGoalsSum\TF}[\marg{type}\marg{list of + goals}\marg{relation and value}\marg{true}\marg{false}] + Ckecks the sum of all goals in \meta{list of goals} for the exercises of + type \meta{type} against \meta{relation and value}. + \command{IfExerciseGoalsSum\TF}[\marg{type}\marg{list of + goals}\marg{relation and value}\marg{true}\marg{false}] + Ckecks the sum of all goals in \meta{list of goals} for all exercises of + all types against \meta{relation and value}. + \command{TotalExerciseTypeGoal}[\marg{goal}\marg{type}\marg{singular}\marg{plural}] + Print the sum of goal \meta{goal} for the exercises of type \meta{type} + and append \meta{singular} or \meta{plural} depending on wether the sum + equals~$1$ or not. + \command{TotalExerciseGoal}[\marg{goal}\marg{singular}\marg{plural}] + Print the sum of goal \meta{goal} for all exercises of all types + and append \meta{singular} or \meta{plural} depending on wether the sum + equals~$1$ or not. +\end{commands} + +\subsubsection{Properties} +\begin{commands} + \expandable\command{IfExercisePropertyExist\TF}[\marg{property}\marg{true}% + \marg{false}] + Tests wether an exercise property with the name \meta{property} is defined. + \command{IfExercisePropertySet\TF}[\marg{property}\marg{true}\marg{false}] + Tests wether the exercise property \meta{property} has been set for the + current exercise. + \expandable\command{GetExerciseProperty}[\marg{property}] + Retrieves the value of the property \meta{property} for the current + exercise. + \command{GetExerciseProperty\TF}[\marg{property}\marg{true}\marg{false}] + Tests wether the exercise property \meta{property} has been set for the + current exercise. Inside the \meta{true} branch you can refer to the + retrieved value either with \code{\#1} or with \cs{PropertyValue}. + \emph{This command expands its contents inside a group.} + \command{GetExerciseIdForProperty}[\marg{property}\marg{value}] + Retrieves the property \property{id} of the exercise where the property + \meta{property} has the value \meta{value}. \emph{This only works for + \emph{unique} properties!} + \command{GetExerciseTypeForProperty}[\marg{property}\marg{value}] + Retrieves the property \property{type} of the exercise where the + property \meta{property} has the value \meta{value}. \emph{This only + works for \emph{unique} properties!} + \command{SetExerciseProperty}[\marg{type}\marg{id}\marg{property}\marg{value}] + Set the property \meta{property} of exercise of type \meta{type} and id + \meta{id} to \meta{value}. + \expandable\command{IfExerciseBooleanProperty\TF}[\marg{property}% + \marg{true}\marg{false}] + Checks wether the boolean property \meta{property} has value \code{true} + or \meta{false} and leaves the corresponding argument in the input + stream. Gives an error if \meta{property} is not a boolean property. + \expandable\command{GetExerciseAliasProperty}[\marg{property}] + Retrieves the value of the property of which \meta{property} is an alias + of for the current exercise. + \command{SaveExerciseProperty}[\marg{property}\meta{macro}] + Saves the value of the property \meta{property} for the current + exercise in macro \meta{macro}. + \command{GlobalSaveExerciseProperty} + Globally saves the value of the property \meta{property} for the current + exercise in macro \meta{macro}. + \command{ExercisePropertyIfSet\TF}[\marg{type}\marg{id}\marg{property}% + \marg{true}\marg{false}] + Test if the property \meta{property} has been set for the exercise of type + \meta{type} with id \meta{id}. + \expandable\command{ExercisePropertyGet}[\marg{type}\marg{id}\marg{property}] + Retrieves the value of the property \meta{property} for the exercise of type + \meta{type} with id \meta{id}. + \expandable\command{ExercisePropertyGetAlias}[\marg{type}\marg{id}\marg{property}] + Retrieves the value of the property of which \meta{property} is an alias + of for the exercise of type \meta{type} with id \meta{id}. + \command{ExercisePropertySave}[\marg{type}\marg{id}\marg{property}\meta{macro}] + Saves the value of the property \meta{property} for the exercise of type + \meta{type} with id \meta{id} in macro \meta{macro}. + \command{ExercisePropertyGlobalSave}[\marg{type}\marg{id}\marg{property}\meta{macro}] + Globally saves the value of the property \meta{property} for the exercise + of type \meta{type} with id \meta{id} in macro \meta{macro}. +\end{commands} + +\subsubsection{Parameters} +\begin{commands} + \expandable\command{GetExerciseParameter}[\marg{parameter}] + Retrieves the value of the parameter \meta{paramater} for the current exercise. + \expandable\command{GetExerciseName} + Retrieves the value of the parameter \parameter{exercise-name} for the + current exercise or of the parameter \parameter{solution-name} for the + current solution. + \expandable\command{ExerciseParameterGet}[\marg{type}\marg{id}\marg{parameter}] + Retrieves the value of the parameter \meta{parameter} for the exercise of type + \meta{type} with id \meta{id}. +\end{commands} + +\subsubsection{Tags} +\begin{commands} + \command{ForEachExerciseTag}[\marg{type}\marg{code}] + Loops over all tags of tag type \meta{type} for the current exercise + applying \meta{code} each time. Inside \meta{code} you can refer to the + corresponding tag with \code{\#1}. + \command{ListExerciseTags}[\marg{type}\marg{between}] + Lists all tags of tag type \meta{type} for the current exercise using + \meta{between} as a separator. + \command{UseExerciseTags}[\marg{type}\marg{between + two}\marg{between}\marg{between last two}] + Lists all tags of tag type \meta{type} for the current exercise using + \meta{between} as a separator and \meta{between last two} as separator + between the last two tags of the list. If the list only consists of two + tags \meta{between two} is used as separator. +\end{commands} + +\subsubsection{Further Commands for Usage in Template Definitions} +\begin{commands} + \expandable\command{ExerciseType} + Can be used to refer to the current exercise type. + \expandable\command{ExerciseID} + Can be used to refer to the current exercise id. + \expandable\command{ExerciseCollection} + Can be used in certain templates to refer to the collection that is + currently inserted. + \expandable\command{numberofusedexercises} + Holds the total number of used exercises. Useful in table template + definitions. + \expandable\command{ExerciseTableType}[\marg{code}] + In table template definitions this macro either expands to the given + exercise type or -- if no type has been given -- to \meta{code}. + \expandable\command{IfInsideSolution\TF}[\marg{true}\marg{false}] + Tests if the template is used inside a solution environment or not. + \expandable\command{IfPrintSolution\TF}[\marg{true}\marg{false}] + Tests if the option \option{print} for the solutions of the current + \cs{ExerciseType} is set to \code{true} or \code{false}. + \command{ForEachPrintedExerciseByType}[\marg{code}] + Loops over each \emph{printed} exercise ordered by the exercise types and + within each type by id. Inside \meta{code} you can refer to several + properties of the corresponding exercise: + \begin{itemize} + \item \code{\#1}: the type of the exercise + \item \code{\#2}: the id of the exercise + \item \code{\#3}: the \property{counter} property of the exercise + \item \code{\#4}: the \property{subtitle} property of the exercise + \item \code{\#5}: the \property{points} property of the exercise + \item \code{\#6}: the \property{bonus-points} property of the exercise + \end{itemize} + \command{ForEachUsedExerciseByType}[\marg{code}] + Loops over each \emph{used} exercise ordered by the exercise types and + within each type by id. Inside \meta{code} you can refer to several + properties of the corresponding exercise: + \begin{itemize} + \item \code{\#1}: the type of the exercise + \item \code{\#2}: the id of the exercise + \item \code{\#3}: the \property{counter} property of the exercise + \item \code{\#4}: the \property{subtitle} property of the exercise + \item \code{\#5}: the \property{points} property of the exercise + \item \code{\#6}: the \property{bonus-points} property of the exercise + \end{itemize} + \command{ForEachPrintedExerciseByID} + Loops over each \emph{printed} exercise order by the exercise id. Inside + \meta{code} you can refer to several properties of the corresponding + exercise: + \begin{itemize} + \item \code{\#1}: the type of the exercise + \item \code{\#2}: the id of the exercise + \item \code{\#3}: the \property{counter} property of the exercise + \item \code{\#4}: the \property{subtitle} property of the exercise + \item \code{\#5}: the \property{points} property of the exercise + \item \code{\#6}: the \property{bonus-points} property of the exercise + \end{itemize} + \command{ForEachUsedExerciseByID} + Loops over each \emph{used} exercise order by the exercise id. Inside + \meta{code} you can refer to several properties of the corresponding + exercise: + \begin{itemize} + \item \code{\#1}: the type of the exercise + \item \code{\#2}: the id of the exercise + \item \code{\#3}: the \property{counter} property of the exercise + \item \code{\#4}: the \property{subtitle} property of the exercise + \item \code{\#5}: the \property{points} property of the exercise + \item \code{\#6}: the \property{bonus-points} property of the exercise + \end{itemize} + \expandable\command{XSIMtranslate}[\marg{keyword}] + Delivers the translation of \meta{keyword} according to the current + document language (in the meaning of a \pkg{babel}~\cite{pkg:babel} or + \pkg{polyglossia}~\cite{pkg:polyglossia} language). Existing keywords and + keyword translations (and how to add new ones) are explained in + section~\vref{sec:exerc-transl}. + \command{XSIMexpandcode}[\marg{code}] + Expands \meta{code} like \cs*{edef} does and leaves the result in the + input stream. + \expandable\command{XSIMifchapter\TF}[\marg{true}\marg{false}] + Returns \meta{true} if both a macro \cs*{chapter} and a counter + \code{chapter} are defined and \meta{false} otherwise. + \command{XSIMmixedcase}[\marg{code}] + Converts the full expansion\footnote{This is a \cs*{romannumeral} + expansion~\cite{texsx:romannumeral}.\label{fn:romannumeral}} of + \meta{code} to mixed case: \\ + \verbcode+\XSIMmixedcase{this is some text}+ \XSIMmixedcase{this is some + text} \\ + \emph{This command expands \meta{code} before converting it}. + \command{XSIMputright}[\meta{macro}\marg{code}] + Extends the macro definition of \meta{macro} with \meta{code} putting it + to the right. This is more or less a local version of the LaTeX kernel + macro \cs*{g@addto@macro}. + \expandable\command{XSIMifeq\TF}[\marg{code 1}\marg{code + 2}\marg{true}\marg{false}] + Checks if the full expansion\footref{fn:romannumeral} of \meta{code 1} and + \meta{code 2} is the same tokenlist. + \expandable\command{XSIMifblank\TF}[\marg{code}\marg{true}\marg{false}] + Checks if the full expansion\footref{fn:romannumeral} of \meta{code} is + blank (\ie, if it is empty or only consists of spaces). +\end{commands} + +\subsection{Declaring Templates} +\subsubsection{Environment Templates}\label{sec:envir-templ} +\begin{commands} + \command{DeclareExerciseEnvironmentTemplate}[\marg{name}\marg{begin + code}\marg{end code}] + Declare the environment template \meta{name}. +\end{commands} +Environment templates are used by the exercise and solution environments. +Those are the templates set with the parameters \parameter{exercise-template} +and \parameter{solution-template}. + +The predefined template is called \enquote{\code{default}}, see +section~\vref{sec:exercise-templ-default}. + +\subsubsection{Heading Templates}\label{sec:heading-templates} +\begin{commands} + \command{DeclareExerciseHeadingTemplate}[\marg{name}\marg{code}] + Declare the heading template \meta{name}. +\end{commands} +Heading templates are used by \cs{printsolutions}, \cs{printsolutionstype} and +\cs{printcollection}. Those are the templates set with the option +\option{headings-template} of the modules \module{print-solutions} and +\module{print-collection}. + +The predefined templates are \enquote{\code{default}}, +\enquote{\code{collection}}, \enquote{\code{per-section}} and +\enquote{\code{per-chapter}} see section~\vref{sec:headings-templates}. + +\subsubsection{Grading Table Templates}\label{sec:grad-table-templ} +\begin{commands} + \command{DeclareExerciseTableTemplate}[\marg{name}\marg{code}] + Declare the grading table template \meta{name}. +\end{commands} +Table templates are used by \cs{gradingtable}. Those are the templates set +with the option \option{template} of module \module{grading-table} + +The predefined templates are \enquote{\code{default}} and +\enquote{\code{default}}, see sections~\vref{sec:table-templ-default} +and~\vref{sec:table-templ-default*}. + +\subsection{Examples}\label{sec:template-examples} + +The repository of this package\footnote{GitHub: + \url{https://github.com/cgnieder/xsim/}, CTAN: + \url{http://www.ctan.org/pkg/xsim/}} currently includes +\theexamplefiles~example documents demonstrating how different aspects of this +package work or how different kinds of problems can be solved or how different +kinds of layouts can be achieved as well as how solve concrete problems that +have come up in different \LaTeX\ forums, see +section~\vref{sec:example-files}. + +\subsubsection{The \code{default} Exercise Template}\label{sec:exercise-templ-default} + +Below the definition of the \code{default} exercise template provided by +\xsim\ is shown: + +\begin{sourcecode} + \DeclareExerciseEnvironmentTemplate{default}{% + \subsection* + {% + \XSIMmixedcase{\GetExerciseName}\nobreakspace + \GetExerciseProperty{counter}% + \IfInsideSolutionF + {% + \GetExercisePropertyT{subtitle} + { {\normalfont\itshape\PropertyValue}}% + }% + } + \GetExercisePropertyT{points} + {% + \marginpar + {% + \IfInsideSolutionF{\rule{1.2cm}{1pt}\slash}% + \PropertyValue + \GetExercisePropertyT{bonus-points}{~(+\PropertyValue)}% + ~\XSIMtranslate {point-abbr}% + }% + }% + } + {} +\end{sourcecode} + +\subsubsection{A New Exercise Type Using \pkg*{tcolorbox}} +Let's say we want exercises to be put in a \env*{tcolorbox}. We want a bold +title and. if given, an italic subtitle. Exercises should also have the +points after the subtitle in parentheses if given. Let's also say we want +those to be an additional exercise type in addition to the ones \xsim\ already +provides. This is shown with the following code which is also how the +problems in this manual have been defined: + +\begin{sourcecode} + \DeclareExerciseEnvironmentTemplate{tcolorbox} + {% + \tcolorbox[ + colback = red!5!white , + colframe = red!75!black , + colbacktitle = yellow!50!red , + coltitle = red!25!black , + breakable , + drop shadow , + beforeafter skip = .5\baselineskip , + title = + \textbf{\GetExerciseName~\GetExerciseProperty{counter}}% + \GetExercisePropertyT{subtitle}{ \textit{\PropertyValue}}% + \IfInsideSolutionF{% + \GetExercisePropertyT{points}{ % notice the space + (% + \PropertyValue + \IfExerciseGoalSingularTF{points} + {\XSIMtranslate{point}} + {\XSIMtranslate{points}}% + )% + }% + }% + ]% + } + {\endtcolorbox} + + \DeclareExerciseType{problem}{ + exercise-env = problem , + solution-env = answer , + exercise-name = Problem , + solution-name = Answer , + exercise-template = tcolorbox , + solution-template = tcolorbox + } +\end{sourcecode} + +See it in action: +\begin{example} + \begin{problem}[subtitle=My subtitle,points=5] + This is a problem using a subtitle and points. + \end{problem} + \begin{answer} + This is the answer to problem~\GetExerciseProperty{counter}. + \end{answer} +\end{example} + +\subsubsection{Mimicking \pkg*{exsheets}' \code{runin} Template} + +The following example shows how you could mimick \pkg*{exsheets}' \code{runin} +template. The outcome isn't exactly the same since \pkg{exsheets} doesn't use +\cs*{marginpar} but the result should look very similar. A safer definition +would use a real sectioning command for the title. + +\begin{sourcecode} + \usepackage{needspace} + \DeclareExerciseEnvironmentTemplate{runin} + {% + \par\vspace{\baselineskip} + \Needspace*{2\baselineskip} + \noindent + \textbf{\XSIMmixedcase{\GetExerciseName}~\GetExerciseProperty{counter}}% + \GetExercisePropertyT{subtitle}{ \textit{#1}} % + \GetExercisePropertyT{points}{% + \marginpar{% + \PropertyValue + \GetExercisePropertyT{bonus-points}{+\PropertyValue}% + \,\IfExerciseGoalSingularTF{points} + {\XSIMtranslate{point}} + {\XSIMtranslate{points}}% + }% + }% + } + {} +\end{sourcecode} + +See it in action: +\begin{example} + \xsimsetup{exercise/template=runin} + \renewcommand*\theexercise{\arabic{exercise}.} + \begin{exercise}[subtitle=exsheets' runin,points=2.5] + \lipsum[4] + \end{exercise} +\end{example} + +\subsubsection{Mimicking \pkg*{exsheets}' \code{margin} Template} + +The following example shows how you could mimick \pkg*{exsheets}' +\code{margin} template. + +\begin{sourcecode} + \usepackage{needspace} + \DeclareExerciseEnvironmentTemplate{margin} + {% + \par\vspace{\baselineskip} + \Needspace*{2\baselineskip} + \noindent + \llap{% + \smash{% + \tabular[t]{@{}r@{}} + \textbf{\XSIMmixedcase{\GetExerciseName}~\GetExerciseProperty{counter}} + \IfExercisePropertySetT{points}{% + \tabularnewline + (% + \GetExerciseProperty{points}% + \GetExercisePropertyT{bonus-points}{+#1}% + \,\XSIMtranslate{point-abbr}% + )% + }% + \endtabular + } % notice the space + }% + } + {} +\end{sourcecode} + +See it in action: +\begin{example} + \xsimsetup{exercise/template=margin} + \renewcommand*\theexercise{\arabic{exercise}.} + \begin{exercise}[subtitle=exsheets' margin,points=2.5] + \lipsum[4] + \end{exercise} +\end{example} + +\subsubsection{The Headings Templates}\label{sec:headings-templates} +\xsim\ defines four heading templates which only differ by which text they +output: +\begin{sourcecode} + \DeclareExerciseHeadingTemplate{default} + {\section*{\XSIMtranslate{default-heading}}} + \DeclareExerciseHeadingTemplate{collection} + {\section*{\XSIMtranslate{collection-heading}}} + \DeclareExerciseHeadingTemplate{per-section} + {\section*{\XSIMtranslate{per-section-heading}}} + \DeclareExerciseHeadingTemplate{per-chapter} + {\section*{\XSIMtranslate{per-chapter-heading}}} +\end{sourcecode} +Section~\vref{sec:exerc-transl} shows how the translations are defined. + +\subsubsection{The \code{default} Table Template}\label{sec:table-templ-default} +This template is the one used for grading tables per default. It has a +vertical layout. + +\begin{sourcecode} + \DeclareExerciseTableTemplate{default}{% + \XSIMputright\ExerciseTableCode{% + \toprule + \XSIMifblankTF{\ExerciseType} + {} + {\XSIMmixedcase{\GetExerciseParameter{exercise-name}}} + & + \XSIMmixedcase{\XSIMtranslate{points}} & + \XSIMtranslate{reached} \\ + \midrule + }% + \ForEachUsedExerciseByType{% + \XSIMifeqTF{#1}{\ExerciseTableType{#1}} + {% + \XSIMifblankTF{\ExerciseType} + {% + \XSIMputright\ExerciseTableCode{% + \XSIMmixedcase{\ExerciseParameterGet{#1}{exercise-name} }% + }% + } + {}% + \XSIMputright\ExerciseTableCode + {#3 & \XSIMifblankTF{#5}{\printgoal{0}}{\printgoal{#5}} & \\ }% + } + {}% + } + \XSIMputright\ExerciseTableCode{% + \midrule + \XSIMtranslate{total} & + \XSIMifblankTF{\ExerciseType} + {\TotalExerciseGoal{points}{}{}} + {\TotalExerciseTypeGoal{\ExerciseType}{points}{}{}} & + \\ \bottomrule + }% + \XSIMexpandcode{% + \noexpand\begin{tabular}{\XSIMifblankTF{\ExerciseType}{l}{c}cc} + \noexpand\ExerciseTableCode + \noexpand\end{tabular}% + }% + } +\end{sourcecode} + +The part +\begin{sourcecode} + \XSIMifblankTF{\ExerciseType}{ ... }{ ... } +\end{sourcecode} +repeatedly checks if an exercise type has been given for the table. This +makes it possible to design the table differently if it is for one exercise +type only (the \code{true} case) or for all exercise types (the \code{false} +case). \cs*{ExerciseTableType}\marg{code} either expands to the given +exercise type or to \meta{code}. + +\subsubsection{The \code{default*} Table Template}\label{sec:table-templ-default*} +The second of the predefined grading table templates. It has a horizontal +layout. +\begin{bewareofthedog} + If you have a lot of exercises the width of a table with this layout may + exceed the text width of the document! +\end{bewareofthedog} + +\begin{sourcecode} + \DeclareExerciseTableTemplate{default*}{% + \XSIMputright\ExerciseTableCode{% + \toprule + \XSIMifblankTF{\ExerciseType} + {} + {\XSIMmixedcase{\GetExerciseParameter{exercise-name}}} + &% + }% + \ForEachUsedExerciseByType{% + \XSIMifeqTF {#1} { \ExerciseTableType {#1} } + { + \XSIMifblankTF{\ExerciseType} + {% + \XSIMputright\ExerciseTableCode{% + \XSIMmixedcase{\ExerciseParameterGet{#1}{exercise-name} }% + }% + } + {}% + \XSIMputright\ExerciseTableCode{#3 &} + } + {}% + }% + \XSIMputright\ExerciseTableCode{% + \XSIMtranslate{total} \\ + \midrule + \XSIMmixedcase{\XSIMtranslate{points}} & + }% + \ForEachUsedExerciseByType{% + \XSIMifeqTF{#1}{\ExerciseTableType{#1}} + {% + \XSIMputright\ExerciseTableCode{% + \XSIMifblankTF{#5}{\printgoal{0}}{\printgoal{#5}} &}% + } + {}% + }% + \XSIMputright\ExerciseTableCode{% + \XSIMifblankTF{\ExerciseType} + {\TotalExerciseGoal{points}{}{}} + {\TotalExerciseTypeGoal{\ExerciseType}{points}{}{}}% + \\ \midrule + \XSIMtranslate{reached} &% + }% + \ForEachUsedExerciseByType{% + \XSIMifeqTF{#1}{\ExerciseTableType{#1}} + {\XSIMputright\ExerciseTableCode{&}} + {}% + }% + \XSIMputright\ExerciseTableCode{ \\ \bottomrule }% + \def\numberofcolumns{% + \XSIMifblankTF{\ExerciseType} + {\numberofusedexercises} + {\csname numberof \ExerciseType s\endcsname}% + }% + \XSIMifeqF{\numberofcolumns}{0} + {% + \begin{tabular}{l*{\numberofcolumns}{c}c} + \ExerciseTableCode + \end {tabular}% + }% + } +\end{sourcecode} + +The part +\begin{sourcecode} + \XSIMifblankTF{\ExerciseType}{ ... }{ ... } +\end{sourcecode} +repeatedly checks if an exercise type has been given for the table. This +makes it possible to design the table differently if it is for one exercise +type only (the \code{true} case) or for all exercise types (the \code{false} +case). \cs*{ExerciseTableType}\marg{code} either expands to the given +exercise type or to \meta{code}. + +\section{Exercise Translations}\label{sec:exerc-transl} + +\begin{commands} + \command{DeclareExerciseTranslation}[\marg{keyword}\marg{language}\marg{translation}] + Declare the translation of \meta{keyword} for language \meta{language}. + \command{DeclareExerciseTranslations}[\marg{keyword}\marg{translations}] + Declare the translations of \meta{keyword} for several languages at once. + See an example of the usage below. + \expandable\command{XSIMtranslate}[\marg{keyword}] + Delivers the translation of \meta{keyword} according to the current + document language (in the meaning of a \pkg{babel}~\cite{pkg:babel} or + \pkg{polyglossia}~\cite{pkg:polyglossia} language). + \command{ForEachExerciseTranslation}[\marg{code}] + Loops over all translations of all keywords known to \xsim. Inside + \meta{code} you can refer to the keyword with \code{\#1}, to the language + with \code{\#2}, and to the translation with \code{\#3}. +\end{commands} + +As an example how to use \cs{DeclareExerciseTranslations} here is how the +translations for \code{exercise} have been defined: + +\begin{sourcecode} + \DeclareExerciseTranslations{exercise}{ + Fallback = exercise , + English = exercise , + French = exercice , + German = \"Ubung + } +\end{sourcecode} + +Table~\vref{tab:translation-keys} shows all existing keywords with all +predefined translations. + +\ForEachExerciseTranslation{ + \appto\translationtable{\texttt{#1} & #2 & \texttt{\detokenize{#3}} \\} +} + +\begin{longtable}{llp{.55\linewidth}} + \caption{Translation keywords predefined by \xsim.} + \label{tab:translation-keys} \\ + \toprule + \bfseries keyword & \bfseries language & \bfseries translation \\ + \midrule + \endfirsthead + \toprule + \bfseries keyword & \bfseries language & \bfseries translation \\ + \midrule + \endhead + \bottomrule + \endlastfoot + \midrule + & & \hfill\emph{continues} \\ + \endfoot + \translationtable +\end{longtable} + +\section{Cloze Tests and Blank Lines} + +Similar to \pkg{exsheets} \xsim\ provides a command \cs{blank}: +\begin{commands} + \command{blank}[\sarg\oarg{options}\marg{text to be filled in}] + Creates a blank in normal text or in an exercise but fills the text of its + argument if inside a solution. If used at the \emph{begin of a paragraph} + \cs{blank} will do two things: it will set the linespread according to an + option explained below and will insert \cs*{par} after the lines. The + starred version doesn't do these things. +\end{commands} + +Those are the options for customization: +\begin{options} + \keyval{blank-style}{code}\Module{blank}\Default{\cs*{underline}\Marg{\#1}} + Instructions for typesetting the blank cloze. Refer to the filled in + space with \code{\#1}. + \keyval{filled-style}{code}\Module{blank}\Default{\cs*{underline}\Marg{\#1}} + Instructions for typesetting the filled cloze. Refer to the filled in text + with \code{\#1} + \keyval{style}{code} + Shortcut for setting both \option{blank-style} and \option{filled-style} + at once. + \keyval{scale}{decimal number}\Module{blank}\Default{\code{1}} +\textsc{} Scales the blank to \meta{decimal number} times its natural width. + \keyval{width}{dim}\Module{blank}\Default + Sets the blank to a width of \meta{dim}. This takes precendence over + \option{scale}. + \keyval{linespread}{decimal number}\Module{blank}\Default{\code{1}} + Set the linespread for the blank lines. This only has an effect if + \cs{blank} is used at the begin of a paragraph. + \keyval{line-increment}{dim}\Module{blank}\Default{\code{1pt}} + The blank line is built in multiples of this value. If the value is too + large you may end up with uneven lines. If the value is too small you may + end up with a non-ending compilation. Experiment with values to find the + suiting one for your use case. + \keyval{line-minimum-length}{dim}\Module{blank}\Default{\code{2em}} + The minimal length a line must have before it is built step by step. +\end{options} + +\begin{example} + This is a \blank{blank} outside in normal text. + \begin{exercise} + Try to fill in \blank[width=4cm]{these} blanks. All of them + \blank{are created} by using the \cs{blank} \blank{command}. + \end{exercise} + \xsimsetup{blank/filled-style=\textcolor{red}{#1}} + \begin{solution}[print] + Try to fill in \blank[width=4cm]{these} blanks. All of them + \blank{are created} by using the \cs{blank} \blank{command}. + \end{solution} +\end{example} +A number of empty lines are easily created by setting the \option{width} +option: +\begin{example} + Write up the pros and cons of \xsim\ over \pkg{exsheets}: + + \blank[width=4.8\linewidth,linespread=1.5]{} +\end{example} + +\edef\lastsection{\arabic{section}} + +\appendix + +\section{Future Plans} + +\xsim\ is complete in so far as it is perfectly usable to create exams or +exercise and solution sections in books with the most freedom in layout +already. But still there are features which would be useful additions. Below +I list all ideas that I currently plan to add to \xsim: +\begin{itemize} + \item a document class \code{xsim-exam} for creating exams; this class + should itself feature the possibility of creating different versions of an + exam, maybe already provide multiple choice questions and so on; one could + also think about automatic creation of running headers and footers, \ie, + means for changing the layout of the exam; following the spirit of \xsim\ + this should probably be done using templates as well. +\end{itemize} +I am very open to suggestions regarding features, both in general and +specifically regarding the document class. + +\section{FAQ \& How to\dots} +This section serves as a kind of gallery showing solutions to common +problems. I expect this section to grow over the years. Some examples +especially regarding other layouts are also shown in example files added to +this package. + +\subsection{\dots Know if \xsim\ Needs Another Compilation?} +If \xsim\ wants you to recompile your document it writes the following to the +logfile: +\begin{sourcecode} + ************************************************* + * xsim warning: "rerun" + * + * Exercise properties may have changed. Rerun to get them synchronized. + ************************************************* +\end{sourcecode} +So just check the logfile regularly (which you should be doing anyway) and +keep your eyes open. + +\subsection{\dots Resolve Getting Repeatedly Wrong Exercise Properties or + Wrong Exercise Lists?}\label{sec:resolve-getting} +\xsim\ writes a lot of stuff to the auxfile for re-using information on +subsequent compilations. If you add exercises, change properties \etc\ it +might happen that wrong information is staying in the auxfile and is wrongly +used by \xsim. In such cases deleting the auxfile and doing a few fresh +compilations may resolve your problems. + +Sometimes the \emph{existence of exercise or solution files from earlier + compilations} may lead to wrong lists of exercises or solutions. In such +cases it can be useful to delete all those files and doing a fresh +compilation. It may be helpful to use a subfolder for those exernal files +which will make deleting them a little bit easier. (Don't forget to both +create the subfolder and set \option{path} accordingly then.) + +Using the \option{clear-aux} option might help to reduce erroneous exercises. + +\subsection{\dots Resolve Strange Errors After Updating?} +\xsim\ writes a lot of stuff to the auxfile. An update may well change how +this is done so deleting the auxfile and doing a few fresh compilations may +resolve your problems. + +\subsection{\code{! TeX capacity exceeded, sorry [text input levels=15].} + Why?} +Did you try to use an exercise or solution in a macro of some sort? This +generally will fail\footnote{The reasons are not entirely clear to me.}. But +there should never be the need to hide the environments inside of a macro, +anyway. + +\subsection{\code{Runaway argument? !File ended while scanning use of \^\^M.} Why?} +Did you try to use an exercise or solution in a macro of some sort? This +generally will fail. But there should never be the need to hide the +environments inside of a macro, anyway. + +\subsection{\dots Put a Star (or Another Symbol) in Headings of Exercises That + Are Special?} + +The code below shows one possible modification of an exercise template which +allows to easily create bonus exercises: +\begin{sourcecode} + % preamble: + \usepackage{amsymb} + % declare boolean property: + \DeclareExerciseProperty*{bonus} + \DeclareExerciseEnvironmentTemplate{bonus} + {% + \subsection* + {% + % test for boolean property and insert star symbol if true: + \IfExerciseBooleanPropertyT{bonus}{\llap{$\bigstar$ }Bonus }% + \XSIMmixedcase{\GetExerciseName}\nobreakspace + \GetExerciseProperty{counter}% + \IfInsideSolutionF + {% + \IfExercisePropertySetT{subtitle} + { {\normalfont\itshape\GetExerciseProperty{subtitle}}}% + }% + } + \GetExercisePropertyT{points} + {% + \marginpar + {% + \IfInsideSolutionF{\rule{1.2cm}{1pt}\slash}% + \PropertyValue + \GetExercisePropertyT{bonus-points} + {\nobreakspace(+\PropertyValue)}% + \nobreakspace\XSIMtranslate{point-abbr}% + }% + }% + } + {} +\end{sourcecode} + +The usage is now as follows: +\begin{example} + \xsimsetup{exercise/template = bonus} + % set the boolean property to true + \begin{exercise}[bonus] + A bonus question. + \end{exercise} +\end{example} + +\subsection{\dots Create and Use \xsim\ Style Files?} + +\xsim\ offers you the possibility to create own \emph{style files}. Let's say +you want to have a style called \code{math-exam}. Then you need to save all +necessary definitions in a file called: +\begin{center} + \code{xsim.math-exam.code.tex} +\end{center} +The first command in the file should be \cs{xsimstyle}\Marg{math-exam}. This +file can now be loaded into your document using +\cs{loadxsimstyle}\Marg{math-exam}: +\begin{sourcecode} + \documentclass[DIV=18,parskip=half]{scrartcl} + \usepackage[T1]{fontenc} + \usepackage[utf8]{inputenc} + + \usepackage[clear-aux]{xsim} + \loadxsimstyle{math-exam} + + \title{Math Exam \#3} + \date{2017-03-28} +\end{sourcecode} + +In this style file stuff like template and property definitions should +happen. This is more or less a convenient way to +\begin{itemize} + \item keep the preamble \enquote{clean} and + \item define re-usable styles without the need of copying the document + preamble to another document. +\end{itemize} +A style file is like a package or class file, \ie, \code{@} has category +code~11 (letter). + +The formal description of the commands: +\begin{commands} + \command{xsimstyle}[\sarg\marg{style name}] + The first command in a \xsim\ style file called \code{xsim.\meta{style + name}.code.tex} which defines the \xsim\ style \meta{style name}. The + starred version activates expl3 syntax\footnote{Those users who want this + will know what it means. If you don't know what it means you will not + need it.}. + \command{loadxsimstyle}[\marg{csv list of style names}] + Load one or more styles into the document. +\end{commands} + +\begin{bewareofthedog} + At the moment this mechanism offers no advantages over creating a custom + package or simply \cs*{input}ing a file. Future versions might provide + additional features. +\end{bewareofthedog} + +\subsection{\dots Print All Solutions Grouped by Section?} +Here is an idea how to get a list of all solutions grouped by the section the +corresponding exercises are appearing in. +\begin{sourcecode} + % preamble: + % \usepackage{etoolbox} + % \newcounter{sections} + + % document: + \setcounter{sections}{1} + \whileboolexpr + { test {\ifnumless{\value{sections}}{\value{section}+1}} } + { + \printsolutions[section=\value{sections},headings-template=per-section] + \stepcounter{sections} + } +\end{sourcecode} +For this manual we then get the following list\footnote{Taking care of the + fact that we're in the appendix now which means we can't use + \cs*{value}\Marg{section}. Therefore this manual does + \cs*{edef}\cs*{lastsection}\Marg{\cs*{arabic}\Marg{section}} right before + \cs*{appendix}}. + +\newcounter{sections} +\setcounter{sections}{1} +\whileboolexpr + { test {\ifnumless{\value{sections}}{\lastsection+1}} } + { + \printsolutions[section=\value{sections},headings-template=per-section] + \stepcounter{sections} + } + +\section{The \pkg*{xsimverb} package}\label{sec:xsimverb-package} +\xsim\ comes bundled with another package called \pkg{xsimverb}. This package +loads a very small subset of \xsim\ which allows to create environments which +write their contents verbatim to external files. It provides the following +commands (which of course are also available in \xsim, too): + +\begin{commands} + \command{XSIMfilewritestart}[\sarg\marg{file name}] + Start writing to the file named \meta{file name}. This should be the + \emph{last} command in the \emph{begin} definition of an environment. If + is is used in an environment with arguments where the \emph{last} argument + is optional you should check if the optional argument is given and use + the starred version if the test is negative. This is demonstrated in an + example below using \pkg{xparse}'s \cs{NewDocumentEnvironment}. \emph{If + you want an environment with only an optional argument you \emph{should} + use \pkg{xparse}'s commands to define it. Due to the way how + \cs*{newenvironment} scans for optional arguments you'll otherwise may + end up with leading spaces gobbled from the first line in your + environment.} + \command{XSIMfilewritestop} + Stop writing to the file. This should be the \emph{first} command in the + \emph{end} definition of an environment. + \command{XSIMsetfilebegin}[\marg{code}] + This command can be used to write something to the external file + \emph{before} the environment contents. Must be set before + \cs{XSIMfilewritestart} in the \emph{begin} definition. + \command{XSIMsetfileend}[\marg{code}] + This command can be used to write something to the external file + \emph{after} the environment contents. Must be set before + \cs{XSIMfilewritestart} in the \emph{begin} definition. + \command{XSIMgobblechars}[\marg{integer}] + Determines how many characters are cut off of the beginning of each line + of the environment body before it is written to the file. The default + value is~$0$. +\end{commands} + +An example of how to use those commands: +\begin{sourcecode} + \documentclass{article} + \usepackage{xsimverb,listings} + + \makeatletter + \NewDocumentEnvironment{example}{o} + {% + \XSIMsetfilebegin{\@percentchar\space file `\jobname.tmp'}% + \XSIMsetfileend{\@percentchar\space bye bye}% + \IfNoValueTF{#1} + {\XSIMfilewritestart*{\jobname.tmp}} + {\XSIMfilewritestart{\jobname.tmp}}% + } + {% + \XSIMfilewritestop + \lstinputlisting[language={[LaTeX]TeX}]{\jobname.tmp}% + \input{\jobname.tmp} + } + \makeatother + + \begin{document} + + \begin{example} + bla bla \LaTeX + \end{example} + + \end{document} +\end{sourcecode} + +The \code{tmp} file produced by the above example will contain the following +three lines (if the file itself was called \code{test.tex}): +\begin{sourcecode} + % file `test.tmp' + bla bla \LaTeX + % bye bye +\end{sourcecode} + +\section{All Exercise Examples} + +\begin{bewareofthedog} + You will notice that some exercises from + section~\vref{sec:template-examples} look differently in this section. That + is because all exercises of a type use the template that's \emph{currently + active}. If you want exercises with a different look you should use + different exercises types. +\end{bewareofthedog} + +The following list is created with this code: +\begin{sourcecode} + \xsimsetup{exercise/template = bonus} + \printcollection[headings]{all exercises} +\end{sourcecode} + +\xsimsetup{exercise/template = bonus} +\printcollection[headings]{all exercises} + +\section{All Solution Examples} +\printsolutions + +\section{Example Documents Coming With This Package}\label{sec:example-files} +The repository of this package\footnote{GitHub: + \url{https://github.com/cgnieder/xsim/}, CTAN: + \url{http://www.ctan.org/pkg/xsim/}} currently includes +\theexamplefiles~example documents demonstrating how different aspects of this +package work or how different kinds of problems can be solved or how different +kinds of layouts can be achieved as well as how solve concrete problems that +have come up in different \LaTeX\ forums. + +\listexamplefiles + +\printbibliography + +\end{document} diff --git a/Master/texmf-dist/tex/latex/xsim/xsim-manual.cls b/Master/texmf-dist/tex/latex/xsim/xsim-manual.cls new file mode 100644 index 00000000000..56121054dd8 --- /dev/null +++ b/Master/texmf-dist/tex/latex/xsim/xsim-manual.cls @@ -0,0 +1,755 @@ +% ---------------------------------------------------------------------------- +% the XSIM package +% +% eXercise Sheets IMproved +% +% ---------------------------------------------------------------------------- +% Clemens Niederberger +% Web: https://github.com/cgnieder/xsim +% E-Mail: contact@mychemistry.eu +% ---------------------------------------------------------------------------- +% Copyright 2017 Clemens Niederberger +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +% +% This work has the LPPL maintenance status `maintained'. +% +% The Current Maintainer of this work is Clemens Niederberger. +% ---------------------------------------------------------------------------- +% If you have any ideas, questions, suggestions or bugs to report, please +% feel free to contact me. +% ---------------------------------------------------------------------------- +% +% please ignore the contents of this file -- it is not a good example for +% coding... +% +\ProvidesClass{xsim-manual}[2017/04/14] + +\LoadClass[load-preamble,add-index]{cnltx-doc} +\RequirePackage{imakeidx} +\RequirePackage[utf8]{inputenc} +\RequirePackage{xsim} + +\RequirePackage{geometry} +\geometry{ + left = 3.8cm , + right = 2.8cm +} + +\setcnltx{ + package = {xsim}, + info = + \textsc{e\textcolor{cnltx}{X}ercise \textcolor{cnltx}{S}heets + \textcolor{cnltx}{IM}proved} \\ + the official successor of the \cnltxpackagenameformat{exsheets} package , + url = https://github.com/cgnieder/xsim , + authors = Clemens Niederberger , + email = contact@mychemistry.eu , + quote-format = \small\biolinumLF , + add-cmds = { + blank , + addbonus , + addpoints , + AddtoExerciseGoal , + AddtoExerciseGoalPrint , + AddtoExerciseTypeGoal , + AddtoExerciseTypeGoalPrint , + blank , + collectexercises , + collectexercisestype , + collectexercisesstop , + DeclareExerciseCollection , + DeclareExerciseEnvironmentTemplate , + DeclareExerciseGoal , + DeclareExerciseHeadingTemplate , + DeclareExerciseProperty , + DeclareExercisePropertyAlias , + DeclareExerciseTableTemplate , + DeclareExerciseTagging , + DeclareExerciseTranslation , + DeclareExerciseTranslations , + DeclareExerciseType , + DeclareGradeDistribution , + ExerciseCollection , + ExerciseGoalValuePrint , + ExerciseID , + ExerciseParameterGet , + ExercisePropertyGet , + ExercisePropertyGetAlias , + ExercisePropertyGlobalSave , + ExercisePropertyIfSetF , + ExercisePropertyIfSetT , + ExercisePropertyIfSetTF , + ExercisePropertySave , + ExerciseTableType , + ExerciseTableCode , + ExerciseType , + ForeachExerciseTag , + ForEachExerciseTranslation , + ForEachPrintedExerciseByType , + ForEachPrintedExerciseByID , + ForEachUsedExerciseByType , + ForEachUsedExerciseByID , + GetExerciseAliasProperty , + GetExerciseName , + GetExerciseParameter , + GetExerciseProperty , + GetExercisePropertyF , + GetExercisePropertyT , + GetExercisePropertyTF , + GlobalSaveExerciseProperty , + gradingtable , + IfExerciseBooleanPropertyF , + IfExerciseBooleanPropertyT , + IfExerciseBooleanPropertyTF , + IfExerciseGoalF , + IfExerciseGoalF , + IfExerciseGoalTF , + IfExerciseGoalSingularF , + IfExerciseGoalSingularT , + IfExerciseGoalSingularTF , + IfExerciseGoalsSumF , + IfExerciseGoalsSumT , + IfExerciseGoalsSumTF , + IfExercisePropertyExistF , + IfExercisePropertyExistT , + IfExercisePropertyExistTF , + IfExercisePropertySetF , + IfExercisePropertySetT , + IfExercisePropertySetTF , + IfExerciseTypeGoalsSumF , + IfExerciseTypeGoalsSumT , + IfExerciseTypeGoalsSumTF , + IfInsideSolutionF , + IfInsideSolutionT , + IfInsideSolutionTF , + loadxsimstyle , + numberofexercises , + numberofusedexercises , + points , + printallsolutions , + printcollection , + printexercise , + printgoal , + printpoints , + printrandomexercises , + printsolution , + printsolutions , + printsolutionstype , + PropertyValue , + SaveExerciseProperty , + SetExerciseParameter , + SetExerciseParameters , + theexercise , + TotalExerciseGoal , + TotalExerciseGoals , + TotalExerciseTypeGoal , + TotalExerciseTypeGoals , + UseExerciseTags , + UseExerciseTagsX , + UseExerciseTemplate , + XSIMexpandcode , + XSIMsetfilebegin , + XSIMfilewritestart , + XSIMfilewritestop , + XSIMgobblechars , + XSIMsetfileend , + XSIMifblankT , + XSIMifblankF , + XSIMifblankTF , + XSIMifchapterF , + XSIMifchapterT , + XSIMifchapterTF , + XSIMifeqF , + XSIMifeqT , + XSIMifeqTF , + XSIMmixedcase , + XSIMputright , + xsimsetup , + xsimstyle , + XSIMtranslate + } , + add-envs = { exercise , solution } , + add-silent-cmds = { + @percentchar , + bottomrule , + breite , + choice , + cs , + DeclareFloatingEnvironment , + enddescription , + endtcolorbox , + hoehe , + iflist , + IfNoValueTF , + ifnumless , + lipsum , + lstdefinestyle , + lstset , + midrule , + Needspace , + NewDocumentCommand , + NewDocumentEnvironment , + newlist , + numberofcolumns , + numberofproblems , + pkg , + pointsandbonus , + printA, printC, printE , + printcompletepoints , + printsumofpointsandbonus , + setlist , + settasks , + tcbuselibrary , + tcolorbox , + thesection , + toprule , + whileboolexpr , + xsim + } , + pre-output = { \let\marginpar\marginnote } , + add-listings-options = { + numberstyle = \tiny\noncopy + } , + index-setup = { level = \section } , + makeindex-setup = { columns = 2 , columnsep = 1em } , + module-sep = {\texttt{/}}% +} + +\renewcommand*\cnltx@module@text[2]{% + \begingroup + \reversemarginpar + \setlength\marginparsep{1em}% + \marginnote{\hfill\llap{\module#1{#2}\cnltx@module@sep}}% + \endgroup +} + +\RequirePackage{accsupp} +\newcommand*\noncopy[1]{% + \BeginAccSupp{method=escape,ActualText={}}% + #1% + \EndAccSupp{}% +} + +\def\libertine@figurestyle{LF} +\RequirePackage[libertine]{newtxmath} +\def\libertine@figurestyle{OsF} + +\RequirePackage{refcount} + +\renewcommand*\footref[1]{% + \begingroup + \unrestored@protected@xdef\@thefnmark{\getrefnumber{#1}}% + \endgroup + \@footnotemark +} + +\newcommand*\eTeX{% + \texorpdfstring + {\mbox{$\epsilon$-\TeX}} + {e-TeX}% +} + +\RequirePackage[ + backend=biber, + style=cnltx, + sortlocale=en_US, + indexing=cite]{biblatex} +\addbibresource{cnltx.bib} + +\RequirePackage[biblatex]{embrac} +\ChangeEmph{[}[,.02em]{]}[.055em,-.08em] +\ChangeEmph{(}[-.01em,.04em]{)}[.04em,-.05em] + +\defbibheading{bibliography}{\section{References}} + +\colorlet{property}{orange} +\newidxcmd\property{\code{\textcolor{property}{#1}}}[ (property)] +\newrobustcmd*\prop{\@ifstar{\cnltx@prop@star}{\cnltx@prop@nostar}} + +\RequirePackage{marginnote} + +\renewcommand*\module@idx@app{ (option class)} + +\newrobustcmd*\cnltx@prop@star{% + \cnltx@ifdash + {\cnltx@prop@aux*\meta} + {\cnltx@prop@aux*\marg}% +} +\newrobustcmd*\cnltx@prop@nostar{% + \cnltx@ifdash + {\cnltx@prop@aux{}\meta} + {\cnltx@prop@aux{}\marg}% +} +\newcommand*\cnltx@prop@aux[4]{% + \code{\property#1{#3}\cnltx@isvalue#2{#4}}% +} + +\newrobustcmd*\propis{% + \@ifstar + {\cnltx@propis*} + {\cnltx@propis{}}% +} +\newrobustcmd*\cnltx@propis[1]{% + \cnltx@ifdash + {\cnltx@prop@aux{#1}\@firstofone} + {\cnltx@prop@aux{#1}\Marg}% +} +\newrobustcmd*\choiceprop{% + \@ifstar + {\cnltx@choiceprop@star} + {\cnltx@choiceprop@nostar}% +} +\def\cnltx@choiceprop@star#1#2{% + \code{\property*{#1}\cnltx@isvalue\choices{#2}}} +\def\cnltx@choiceprop@nostar#1#2{% + \code{\property{#1}\cnltx@isvalue\choices{#2}}} +\newcommand*\boolprop{% + \@ifstar + {\cnltx@boolprop@star} + {\cnltx@boolprop@nostar}% +} +\def\cnltx@boolprop@star#1{\choiceprop*{#1}{\default{true},false}} +\def\cnltx@boolprop@nostar#1{\choiceprop{#1}{\default{true},false}} + +\newenvironment{properties} + {% + \def\propert{\@cnltx@option@item\property}% + \def\propval{\@cnltx@option@item\prop}% + \def\proplit{\@cnltx@option@item\propis}% + \def\propchoice{\@cnltx@option@item\choiceprop}% + \def\propbool{\@cnltx@option@item\boolprop}% + \cnltxlist + } + {\endcnltxlist} + +\colorlet{parameter}{blue} +\newidxcmd\parameter{\code{\textcolor{parameter}{#1}}}[ (parameter)] +\newrobustcmd*\para{\@ifstar{\cnltx@para@star}{\cnltx@para@nostar}} + +\newrobustcmd*\cnltx@para@star{% + \cnltx@ifdash + {\cnltx@para@aux*\meta} + {\cnltx@para@aux*\marg}% +} +\newrobustcmd*\cnltx@para@nostar{% + \cnltx@ifdash + {\cnltx@para@aux{}\meta} + {\cnltx@para@aux{}\marg}% +} +\newcommand*\cnltx@para@aux[4]{% + \code{\parameter#1{#3}\cnltx@isvalue#2{#4}}% +} + +\newrobustcmd*\parais{% + \@ifstar + {\cnltx@parais*} + {\cnltx@parais{}}% +} +\newrobustcmd*\cnltx@parais[1]{% + \cnltx@ifdash + {\cnltx@para@aux{#1}\@firstofone} + {\cnltx@para@aux{#1}\Marg}% +} +\newrobustcmd*\choicepara{% + \@ifstar + {\cnltx@choicepara@star} + {\cnltx@choicepara@nostar}% +} +\def\cnltx@choicepara@star#1#2{% + \code{\parameter*{#1}\cnltx@isvalue\choices{#2}}} +\def\cnltx@choicepara@nostar#1#2{% + \code{\parameter{#1}\cnltx@isvalue\choices{#2}}} +\newcommand*\boolpara{% + \@ifstar + {\cnltx@boolpara@star} + {\cnltx@boolpara@nostar}% +} +\def\cnltx@boolpara@star#1{\choicepara*{#1}{\default{true},false}} +\def\cnltx@boolpara@nostar#1{\choicepara{#1}{\default{true},false}} + +\newenvironment{parameters} + {% + \def\param{\@cnltx@option@item\parameter}% + \def\paraval{\@cnltx@option@item\para}% + \def\paralit{\@cnltx@option@item\parais}% + \def\parachoice{\@cnltx@option@item\choicepara}% + \def\parabool{\@cnltx@option@item\boolpara}% + \cnltxlist + } + {\endcnltxlist} + +\RequirePackage{acro} + +\DeclareAcronym{prop}{ + short = property , + long = \emph{Properties} are options of exercises which are individual for + each exercise and can be retrieved and used in exercise templates. , + short-plural-form = properties +} + +\DeclareAcronym{para}{ + short = parameter , + long = \emph{Parameters} are options of exercise types which are the same + for each exercise of a type and can be retrieved and used in exercise + templates. +} + +\DeclareAcronym{goal}{ + short = goal , + long = \emph{Goals} are a certain type of \acsp*{prop} with a numerical + value the sum of which is available throughout the document. +} + +\DeclareAcronym{tag}{ + short = tag , + long = \emph{Tags} are a certain type of \acsp*{prop} with a csv list as + value which can be used for selective usage of exercises. +} + +\DeclareAcronym{coll}{ + short = collection , + long = A \emph{collection} bundles a number of exercises of one type or all + types of exercises within certain barriers in the document. Those + exercise collections can be printed at any place in the document. +} + +\DeclareAcronym{tmpl}{ + short = template , + long = {\emph{Templates} are generic code frameworks which are used for + typesetting \xsim's objects such as exercises, solutions, or grading + tables.} +} + +\ExplSyntaxOn +\NewAcroCommand \Acs + { + \acro_first_upper: + \acro_short:n {#1} + } +\NewAcroCommand \Acsp + { + \acro_first_upper: + \acro_plural: + \acro_short:n {#1} + } +\ExplSyntaxOff + +\newcommand*\environ{\@ifstar\environ@star\environ@nostar} +\newcommand*\environ@star[1]{\beginenv*\Marg{\env*{#1}}} +\newcommand*\environ@nostar[1]{\beginenv*\Marg{\env{#1}}} + +\RequirePackage{tcolorbox} +\tcbuselibrary{skins,breakable} +\tcbset{enhanced,enhanced jigsaw} + +\newtcolorbox{bewareofthedog}{ + colback = white , + colframe = red , + underlay={% + \path[draw=none] + (interior.south west) + rectangle node[red]{\Huge\bfseries !} + ([xshift=-4mm]interior.north west); + }% +} + +\newtcolorbox{cnltxcode}[1][]{ + boxrule = 1pt , + colback = cnltxbg , + colframe = cnltx , + arc = 5pt , + beforeafter skip = .5\baselineskip ,% + #1% +} + +\RenewDocumentEnvironment{sourcecode}{O{}} + {% + \pgfqkeys{/cnltx}{#1}% + \setlength\cnltx@sidebysidewidth + {\dimexpr .45\columnwidth -\lst@xleftmargin -\lst@xrightmargin\relax}% + \XSIMexpandcode{% + \noexpand\lstset{ + style=cnltx, + \ifboolexpe{ bool {cnltx@sidebyside} and not bool {cnltx@codeonly} } + {linewidth=\cnltx@sidebysidewidth,}{}% + \expandonce\cnltx@local@listings@options + }% + }% + \XSIMgobblechars{2}% + \XSIMifblankTF{#1} + {\XSIMfilewritestart*{\jobname.tmp}} + {\XSIMfilewritestart{\jobname.tmp}}% + } + {% + \XSIMfilewritestop + \cnltxcode[breakable]% + \lstinputlisting[style=cnltx]{\jobname.tmp}% + \endcnltxcode + } + +\RenewDocumentEnvironment{example} {O{}} + {% + \pgfqkeys{/cnltx}{#1}% + \setlength\cnltx@sidebysidewidth + {\dimexpr .45\columnwidth -\lst@xleftmargin -\lst@xrightmargin\relax}% + \XSIMexpandcode{% + \noexpand\lstset{ + style=cnltx, + \ifboolexpe{ bool {cnltx@sidebyside} and not bool {cnltx@codeonly} } + {linewidth=\cnltx@sidebysidewidth,}{}% + \expandonce\cnltx@local@listings@options + }% + }% + \XSIMgobblechars{2}% + \XSIMifblankTF{#1} + {\XSIMfilewritestart*{\jobname.tmp}} + {\XSIMfilewritestart{\jobname.tmp}}% + } + {% + \XSIMfilewritestop + \ifbool{cnltx@sidebyside} + {% + \cnltxcode + \noindent + \minipage[c]{\cnltx@sidebysidewidth}% + \cnltx@pre@source@hook + \lstinputlisting[style=cnltx] {\jobname.tmp}% + \cnltx@after@source@hook + \endminipage\hfill + \minipage[c]{\cnltx@sidebysidewidth}% + \cnltx@pre@example@hook + \input {\jobname.tmp}% + \cnltx@after@example@hook + \endminipage + } + {% + \cnltxcode[breakable]% + \cnltx@pre@source@hook + \lstinputlisting{\jobname.tmp}% + \cnltx@after@source@hook + \tcblower + \cnltx@pre@example@hook + \input {\jobname.tmp}% + \cnltx@after@example@hook + }% + \endcnltxcode + } + +\renewrobustcmd*\inputsourcecode[2][]{% + \begingroup + \pgfqkeys{/cnltx}{#1}% + \XSIMexpandcode{% + \noexpand\lstset{ + style=cnltx,% + \expandonce\cnltx@local@listings@options + }% + }% + \cnltxcode[breakable]% + \lstinputlisting{#2}% + \endcnltxcode + \endgroup +} + +\RequirePackage{longtable,booktabs} + +\RequirePackage{lipsum} +\RequirePackage{varioref} +\RequirePackage{bookmark} + +\xsimsetup{ + clear-aux , + path = exercises +} + +\DeclareExerciseCollection{foo} + +\newrobustcmd*\TF{% + \colorlet{outside}{.}% + \textcolor{red}{\underline{\textcolor{outside}{TF}}}% +} + +\newcommand*\narg{\textcolor{argument}{\code{-}}} +\newcommand*\barg{\textcolor{argument}{\code{\bang}}} + +\newrobustcmd\bang{!} + +\renewrobustcmd*\code[1]{\begingroup\codefont\let\^\textasciicircum#1\endgroup} + +\DeclareExerciseEnvironmentTemplate{tcolorbox} + {% + \tcolorbox[ + colback = red!5!white , + colframe = red!75!black , + colbacktitle = yellow!50!red , + coltitle = red!25!black , + subtitle style = { + boxrule = 0.4pt , + colback = yellow!50!red!25!white + } , + breakable , + drop shadow , + beforeafter skip = .5\baselineskip , + title = + \textbf{\GetExerciseName~\GetExerciseProperty{counter}}% + \GetExercisePropertyT{subtitle} + { \textit{\PropertyValue}}% + \IfInsideSolutionF{% + \GetExercisePropertyT{points} + { % notice the space + (\PropertyValue + \IfExerciseGoalSingularTF{points} + {\XSIMtranslate{point}} + {\XSIMtranslate{points}})% + }% + }% + ]% + } + {\endtcolorbox} + +\RequirePackage{needspace} + +\DeclareExerciseEnvironmentTemplate{runin} + {% + \par\vspace{\baselineskip} + \Needspace*{2\baselineskip} + \noindent + \textbf{\XSIMmixedcase{\GetExerciseName}~\GetExerciseProperty{counter}}% + \GetExercisePropertyT{subtitle}{ \textit{#1}} % + \GetExercisePropertyT{points}{% + \marginpar{% + \PropertyValue + \GetExercisePropertyT{bonus-points}{+\PropertyValue}% + \,\IfExerciseGoalSingularTF{points} + {\XSIMtranslate{point}} + {\XSIMtranslate{points}}% + }% + }% + } + {} + +\DeclareExerciseEnvironmentTemplate{margin} + {% + \par\vspace{\baselineskip} + \Needspace*{2\baselineskip} + \noindent + \llap{% + \smash{% + \tabular[t]{@{}r@{}} + \textbf{\XSIMmixedcase{\GetExerciseName}~\GetExerciseProperty{counter}} + \IfExercisePropertySetT{points}{% + \tabularnewline + (% + \GetExerciseProperty{points}% + \GetExercisePropertyT{bonus-points}{+#1}% + \,\XSIMtranslate{point-abbr}% + )% + }% + \endtabular + } % notice the space + }% + } + {} + +\DeclareExerciseProperty*{bonus} +\DeclareExerciseEnvironmentTemplate{bonus} + {% + \subsection* + {% + \IfExerciseBooleanPropertyT{bonus}{\llap{$\bigstar$ }Bonus }% + \XSIMmixedcase{\GetExerciseName}\nobreakspace + \GetExerciseProperty{counter}% + \IfInsideSolutionF + {% + \IfExercisePropertySetT{subtitle} + { {\normalfont\itshape\GetExerciseProperty{subtitle}}}% + }% + } + \GetExercisePropertyT{points} + {% + \marginpar + {% + \IfInsideSolutionF{\rule{1.2cm}{1pt}\slash}% + \PropertyValue + \GetExercisePropertyT{bonus-points} + {\nobreakspace(+\PropertyValue)}% + \nobreakspace\XSIMtranslate{point-abbr}% + }% + }% + } + {} + +\DeclareExerciseType{problem}{ + exercise-env = problem , + solution-env = answer , + exercise-name = Problem , + solution-name = Answer , + exercise-template = tcolorbox , + solution-template = tcolorbox +} + +\RequirePackage{hyperref,bookmark} + +\newcounter{examplefile} +\newcounter{examplefiles} +\newcommand*\xsim@add@example[1]{% + \listadd\xsim@examplefiles{#1}% + \stepcounter{examplefiles}% +} +\newcommand*\listexamplefiles{% + \def\do##1{% + \stepcounter{examplefile}% + \begin{cnltxcode}[ + sidebyside align=top seam,sidebyside, + righthand width=\linewidth/4, + sidebyside gap=0pt, + lower separated=false, + title=Example~\theexamplefile\ \enquote{##1} + \href{../examples/xsim.##1.tex}{\color{white}[\TeX]} + \href{../examples/xsim.##1.pdf}{\color{white}[PDF]}% + ] + \lstinputlisting[style=cnltx,lastline=10]{../examples/xsim.##1.tex} + \tcblower + \fbox{% + \href{../examples/xsim.##1.pdf}{% + \includegraphics[width=.8\linewidth]{../examples/{xsim.##1}.pdf}}}% + \end{cnltxcode} + }% + \dolistloop\xsim@examplefiles +} + +\xsim@add@example{blanks} +\xsim@add@example{boxed-headings} +\xsim@add@example{code-and-output} +\xsim@add@example{collections} +\xsim@add@example{crossref} +\xsim@add@example{description-list} +\xsim@add@example{different-point-types} +\xsim@add@example{difficulties} +\xsim@add@example{floating} +\xsim@add@example{grade-distribution} +\xsim@add@example{listings} +\xsim@add@example{multiplechoice} +\xsim@add@example{pointsums} +\xsim@add@example{randomexercises} +\xsim@add@example{various} +\xsim@add@example{texsx-199360} +\xsim@add@example{texsx-299534} +\xsim@add@example{texsx-305110} +\xsim@add@example{texsx-338165} +\xsim@add@example{texsx-350028} +\xsim@add@example{texsx-369065} +\xsim@add@example{texsx-369636} +\xsim@add@example{texsx-369803} +\xsim@add@example{texwelt-6698} +\xsim@add@example{texwelt-15093} +\xsim@add@example{golatex-16824} +\xsim@add@example{golatex-18844} + +\endinput diff --git a/Master/texmf-dist/tex/latex/xsim/xsim.auxfile.code.tex b/Master/texmf-dist/tex/latex/xsim/xsim.auxfile.code.tex new file mode 100644 index 00000000000..2a0f95846f3 --- /dev/null +++ b/Master/texmf-dist/tex/latex/xsim/xsim.auxfile.code.tex @@ -0,0 +1,182 @@ +% ---------------------------------------------------------------------------- +% the XSIM package - auxfile module +% +% eXercise Sheets IMproved +% +% ---------------------------------------------------------------------------- +% Clemens Niederberger +% Web: https://github.com/cgnieder/xsim +% E-Mail: contact@mychemistry.eu +% ---------------------------------------------------------------------------- +% Copyright 2017 Clemens Niederberger +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +% +% This work has the LPPL maintenance status `maintained'. +% +% The Current Maintainer of this work is Clemens Niederberger. +% ---------------------------------------------------------------------------- +% If you have any ideas, questions, suggestions or bugs to report, please +% feel free to contact me. +% ---------------------------------------------------------------------------- +\XSIMmodule{auxfile}{writing stuff to the aux file} + +\cs_new_protected:Npn \xsim_write_to_aux:n #1 + { \iow_now:Nn \@auxout {#1} } +\cs_generate_variant:Nn \xsim_write_to_aux:n {x} + +% -------------------------------------------------------------------------- + +\cs_new_protected:Npn \XSIM #1 { \use:c {XSIMaux#1} } + +\AtBeginDocument + { + \xsim_write_to_aux:x + { \token_to_str:N \providecommand \token_to_str:N \XSIM [1] {} } + } + +\cs_new_protected:Npn \xsim_new_aux_cs:cpn #1 + { \cs_new_protected:cpn {XSIMaux#1} } + +\cs_new_protected:Npn \xsim_add_cs_to_aux:nn #1#2 + { + \xsim_verbose:n { Writing~ command~ \XSIM {#1}~ to~ aux~ file } + \xsim_write_to_aux:x { \XSIM {#1} #2 } + } + +% ---------------------------------------------------------------------------- +% list for recording values that need to be written to the aux file and +% updated at begin document + +% define list: +% #1: name +\cs_new_protected:Npn \xsim_new_list:n #1 + { + \xsim_verbose:n { Defining~ new~ auxfile~ list~ `#1'. } + \prop_new:c {g__xsim_list_#1_prop} + \seq_new:c {g__xsim_list_#1_seq} + \seq_new:c {g__xsim_list_recorded_#1_seq} + \xsim_new_aux_cs:cpn {#1} ##1 + { + \prop_gclear:c {g__xsim_list_#1_prop} + \tl_if_blank:nF {##1} + { + \seq_gset_split:cnx {g__xsim_list_#1_seq} {|} + { \tl_to_str:n {##1} } + \seq_map_inline:cn {g__xsim_list_#1_seq} + { \prop_gput:cnn {g__xsim_list_#1_prop} {####1} {} } + } + } + \AtBeginDocument + { + \seq_gclear:c {g__xsim_list_recorded_#1_seq} + \seq_set_eq:Nc \l__xsim_tmpa_seq {g__xsim_list_#1_seq} + \seq_map_inline:Nn \l__xsim_tmpa_seq + { + \str_set:Nn \l__xsim_tmpa_str {##1} + \seq_gput_right:cV {g__xsim_list_recorded_#1_seq} \l__xsim_tmpa_str + } + \seq_gremove_duplicates:c {g__xsim_list_recorded_#1_seq} + } + } + +% add to or remove from list: +% #1: name +% #2: entry +\cs_new_protected:Npn \xsim_add_to_list:nn #1#2 + { + \xsim_verbose:n { Adding~ `#2'~ to~ list~ `#1'. } + \str_set:Nn \l__xsim_tmpa_str {#2} + \prop_gput:cnn {g__xsim_list_#1_prop} {#2} {} + \seq_if_in:cVT {g__xsim_list_#1_seq} \l__xsim_tmpa_str + { \seq_gremove_all:cV {g__xsim_list_#1_seq} \l__xsim_tmpa_str } + \seq_gput_right:cV {g__xsim_list_#1_seq} \l__xsim_tmpa_str + } +\cs_generate_variant:Nn \xsim_add_to_list:nn {nx} +\cs_generate_variant:Nn \seq_if_in:NnT {cV} +\cs_generate_variant:Nn \seq_gremove_all:Nn {cV} +\cs_generate_variant:Nn \seq_gput_right:Nn {cV} +\cs_generate_variant:Nn \seq_gset_split:Nnn {cnx} + +% #1: name +% #2: entry +\cs_new_protected:Npn \xsim_remove_from_list:nn #1#2 + { + \xsim_verbose:n { Removing~ `#2'~ to~ list~ `#1'. } + \str_set:Nn \l__xsim_tmpa_str {#2} + \prop_if_in:cnT {g__xsim_list_#1_prop} {#2} + { \prop_gremove:cn {g__xsim_list_#1_prop} {#2} } + \seq_if_in:cVT {g__xsim_list_#1_seq} \l__xsim_tmpa_str + { \seq_gremove_all:cV {g__xsim_list_#1_seq} \l__xsim_tmpa_str } + \seq_if_in:cVT {g__xsim_list_recorded#1_seq} \l__xsim_tmpa_str + { \seq_gremove_all:cV {g__xsim_list_recorded_#1_seq} \l__xsim_tmpa_str } + } +\cs_generate_variant:Nn \xsim_remove_from_list:nn {nx} + +% check if in list: +% #1: name +% #2: entry +\prg_new_conditional:Npnn \xsim_if_in_list:nn #1#2 {p,T,F,TF} + { + \prop_if_in:cnTF {g__xsim_list_#1_prop} {#2} + { \prg_return_true: } + { \prg_return_false: } + } +\cs_generate_variant:Nn \xsim_if_in_list:nnTF {nx} +\cs_generate_variant:Nn \xsim_if_in_list:nnT {nx} + +\cs_new:Npn \xsim_list_show:n #1 + { \prop_show:c {g__xsim_list_#1_prop} } + +\bool_new:N \l__xsim_empty_lists_bool +\cs_new_protected:Npn \xsim_empty_lists: + { \bool_set_true:N \l__xsim_empty_lists_bool } + +% update list -- should be used inside \AtEndDocument: +% #1: name +\cs_new_protected:Npn \xsim_update_list:n #1 + { + \xsim_verbose:n { Updating~ list~ `#1'. } + \seq_remove_duplicates:c {g__xsim_list_#1_seq} + \seq_remove_duplicates:c {g__xsim_list_recorded_#1_seq} + \str_set:Nx \l__xsim_tmpa_str + { \seq_use:cn {g__xsim_list_#1_seq} {} } + \str_set:Nx \l__xsim_tmpb_str + { \seq_use:cn {g__xsim_list_recorded_#1_seq} {} } + \str_if_eq:NNF \l__xsim_tmpa_str \l__xsim_tmpb_str + { \xsim_rerun: } + \bool_if:NF \l__xsim_empty_lists_bool + { + \xsim_add_cs_to_aux:nn {#1} + { { \seq_use:cn {g__xsim_list_#1_seq} {|} } } + } + } + +% loop over list: +% #1: name +% #2: code +\cs_new_protected:Npn \xsim_foreach_list_entry:nn #1#2 + { \seq_map_inline:cn {g__xsim_list_recorded_#1_seq} {#2} } + +\cs_new_protected:Npn \xsim_foreach_new_list_entry:nn #1#2 + { \seq_map_inline:cn {g__xsim_list_#1_seq} {#2} } + +% length of a list: +% #1: name +\cs_new:Npn \xsim_list_count:n #1 + { \seq_count:c {g__xsim_list_recorded_#1_seq} } + +% item of a list: +% #1: name +% #2: integer +\cs_new:Npn \xsim_list_item:nn #1#2 + { \seq_item:cn {g__xsim_list_recorded_#1_seq} {#2} } + +% ---------------------------------------------------------------------------- +\tex_endinput:D diff --git a/Master/texmf-dist/tex/latex/xsim/xsim.base.code.tex b/Master/texmf-dist/tex/latex/xsim/xsim.base.code.tex new file mode 100644 index 00000000000..30be8b9d18f --- /dev/null +++ b/Master/texmf-dist/tex/latex/xsim/xsim.base.code.tex @@ -0,0 +1,169 @@ +% ---------------------------------------------------------------------------- +% the XSIM package - base module +% +% eXercise Sheets IMproved +% +% ---------------------------------------------------------------------------- +% Clemens Niederberger +% Web: https://github.com/cgnieder/xsim +% E-Mail: contact@mychemistry.eu +% ---------------------------------------------------------------------------- +% Copyright 2017 Clemens Niederberger +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +% +% This work has the LPPL maintenance status `maintained'. +% +% The Current Maintainer of this work is Clemens Niederberger. +% ---------------------------------------------------------------------------- +% If you have any ideas, questions, suggestions or bugs to report, please +% feel free to contact me. +% ---------------------------------------------------------------------------- +\XSIMmodule{base}{basic functionality of the package} + +\xsim_load_modules:n {auxfile} + +% ---------------------------------------------------------------------------- +% variants of kernel functions: +\cs_generate_variant:Nn \seq_set_split:Nnn {Nnx,NV} +\cs_generate_variant:Nn \seq_gset_split:Nnn {c} +\cs_generate_variant:Nn \seq_count:N {c} +\cs_generate_variant:Nn \seq_if_empty:NT {c} +\cs_generate_variant:Nn \prop_put:Nnn {cxx} +\cs_generate_variant:Nn \prop_gput:Nnn {Nx,Nnx,cxx} +\cs_generate_variant:Nn \prop_item:Nn {c} +\cs_generate_variant:Nn \prop_if_in:NnTF {Nx} +\cs_generate_variant:Nn \use:nn {nx} +\cs_generate_variant:Nn \file_input:n {V,x} +\cs_generate_variant:Nn \file_if_exist:nT {V,x} +\cs_generate_variant:Nn \file_if_exist:nTF {V} +\cs_generate_variant:Nn \msg_error:nnnnn {nnnxx} +\cs_generate_variant:Nn \keys_define:nn {nx} +\cs_generate_variant:Nn \keys_set:nn {xn} +\cs_generate_variant:Nn \tl_mixed_case:n {x,f} +\cs_generate_variant:Nn \tl_if_eq:nnTF {ff,V} +\cs_generate_variant:Nn \tl_if_eq:nnT {x} +\cs_generate_variant:Nn \tl_if_blank:nTF {f} +\cs_generate_variant:Nn \tl_set_rescan:Nnn {Nnn} +\cs_generate_variant:Nn \iow_now:Nn {NV} +\cs_generate_variant:Nn \str_if_eq:nnT {x} +\cs_generate_variant:Nn \iow_now:Nn {NV} + +% ---------------------------------------------------------------------------- +% temporary variables: +\tl_new:N \l__xsim_tmpa_tl +\tl_new:N \l__xsim_tmpb_tl +\tl_new:N \l__xsim_tmpc_tl +\tl_new:N \l__xsim_tmpd_tl + +\str_new:N \l__xsim_tmpa_str +\str_new:N \l__xsim_tmpb_str +\str_new:N \l__xsim_tmpc_str + +\bool_new:N \l__xsim_tmpa_bool +\bool_new:N \l__xsim_tmpb_bool +\bool_new:N \l__xsim_tmpc_bool + +\dim_new:N \l__xsim_tmpa_dim +\dim_new:N \l__xsim_tmpb_dim +\dim_new:N \l__xsim_tmpc_dim + +\seq_new:N \l__xsim_tmpa_seq +\seq_new:N \l__xsim_tmpb_seq +\seq_new:N \l__xsim_tmpc_seq + +\int_new:N \l__xsim_tmpa_int +\int_new:N \l__xsim_tmpb_int +\int_new:N \l__xsim_tmpc_int + +\box_new:N \l__xsim_tmpa_box +\box_new:N \l__xsim_tmpb_box +\box_new:N \l__xsim_tmpc_box + +\clist_new:N \l__xsim_tmpa_clist +\clist_new:N \l__xsim_tmpb_clist +\clist_new:N \l__xsim_tmpc_clist + +% ---------------------------------------------------------------------------- + +\prg_new_conditional:Npnn \xsim_if_komascript: {T,F,TF} + { + \cs_if_exist:cTF {KOMAClassName} + { \prg_return_true: } + { \prg_return_false: } + } + +% ---------------------------------------------------------------------------- + +\prg_new_conditional:Npnn \xsim_if_final: {p,T,F,TF} + { + \bool_if:NTF \g_xsim_final_bool + { \prg_return_true: } + { \prg_return_false: } + } + +\prg_new_conditional:Npnn \xsim_if_verbose: {p,T,F,TF} + { + \bool_if:NTF \g_xsim_verbose_bool + { \prg_return_true: } + { \prg_return_false: } + } + +\prg_new_conditional:Npnn \xsim_if_rerun: {p,T,F,TF} + { + \bool_if:NTF \g__xsim_rerun_bool + { \prg_return_true: } + { \prg_return_false: } + } + +\prg_new_conditional:Npnn \xsim_if_clear_aux: {p,T,F,TF} + { + \xsim_if_final:TF + { \prg_return_false: } + { + \bool_if:NTF \g_xsim_clear_aux_bool + { \prg_return_true: } + { \prg_return_false: } + } + } + +\cs_new_protected:Npn \xsim_verbose:n #1 + { \xsim_if_verbose:T { \msg_info:nnn {xsim} {verbose} {#1} } } +\cs_generate_variant:Nn \xsim_verbose:n {x} + +\cs_new_protected:Npn \xsim_rerun: + { \bool_gset_true:N \g__xsim_rerun_bool } + +\prg_new_conditional:Npnn \xsim_if_chapter: {p,T,F,TF} + { + \bool_if:nTF + { \cs_if_exist_p:N \chapter && \cs_if_exist_p:N \c@chapter } + { \prg_return_true: } + { \prg_return_false: } + } + +% ---------------------------------------------------------------------------- + +% #1: macro name +% #2: 0 to 9 times `n' (= number of arguments of internal item) +% #3: code; may contain a suiting \__xsim_loop_item:<nnn> +\cs_new_protected:Npn \xsim_define_loop_macro:Nnn #1#2#3 + { + \xsim_verbose:n { Defining~ loop~ macro~ #1 } + \cs_new_protected:Npn #1 ##1##2 + { \cs_set:cn {__xsim_loop_item:#2} {##2} #3 } + } + +% ---------------------------------------------------------------------------- + +\cs_new_protected:Npn \xsim_setup:n #1 + { \keys_set:nn {xsim} {#1} } + +% ---------------------------------------------------------------------------- +\tex_endinput:D diff --git a/Master/texmf-dist/tex/latex/xsim/xsim.blanks.code.tex b/Master/texmf-dist/tex/latex/xsim/xsim.blanks.code.tex new file mode 100644 index 00000000000..323b7bd52f9 --- /dev/null +++ b/Master/texmf-dist/tex/latex/xsim/xsim.blanks.code.tex @@ -0,0 +1,154 @@ +% ---------------------------------------------------------------------------- +% the XSIM package - blanks module +% +% eXercise Sheets IMproved +% +% ---------------------------------------------------------------------------- +% Clemens Niederberger +% Web: https://github.com/cgnieder/xsim +% E-Mail: contact@mychemistry.eu +% ---------------------------------------------------------------------------- +% Copyright 2017 Clemens Niederberger +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +% +% This work has the LPPL maintenance status `maintained'. +% +% The Current Maintainer of this work is Clemens Niederberger. +% ---------------------------------------------------------------------------- +% If you have any ideas, questions, suggestions or bugs to report, please +% feel free to contact me. +% ---------------------------------------------------------------------------- +\XSIMmodule{blanks}{add blanks, cloze} + +\bool_new:N \l__xsim_blank_width_bool +\bool_new:N \l__xsim_blank_linespread_bool +\tl_new:N \l__xsim_blank_linespread_tl +\tl_new:N \l__xsim_blank_scale_tl +\dim_new:N \l__xsim_blank_dim +\dim_new:N \l__xsim_blank_line_increment_dim +\dim_new:N \l__xsim_blank_line_minimum_length_dim +\box_new:N \l__xsim_blank_box + +\cs_new_protected:Npn \xsim_write_cloze_blank:n #1 {#1} +\cs_new_protected:Npn \xsim_write_cloze_filled:n #1 {#1} + +\keys_define:nn {xsim/blank} + { + blank-style .code:n = + \cs_set_protected:Npn \xsim_write_cloze_blank:n ##1 {#1} , + blank-style .initial:n = \underline {#1} , + filled-style .code:n = + \cs_set_protected:Npn \xsim_write_cloze_filled:n ##1 {#1} , + filled-style .initial:n = \underline {#1} , + style .meta:n = + { + blank-style = #1 , + filled-style = #1 + } , + scale .tl_set:N = \l__xsim_blank_scale_tl , + scale .initial:n = 1 , + width .code:n = + { + \bool_set_true:N \l__xsim_blank_width_bool + \dim_set:Nn \l__xsim_blank_dim {#1} + } , + linespread .code:n = + \bool_set_true:N \l__xsim_blank_linespread_bool + \tl_set:Nn \l__xsim_blank_linespread_tl {#1} , + linespread .initial:n = 1 , + line-increment .dim_set:N = \l__xsim_blank_line_increment_dim , + line-increment .initial:n = 1pt , + line-minimum-length .dim_set:N = \l__xsim_blank_line_minimum_length_dim , + line-minimum-length .initial:n = 2em + } + +\cs_new_protected:Npn \xsim_blank:n #1 + { + \box_clear:N \l__xsim_blank_box + \mode_if_math:TF + { \hbox_set:Nn \l__xsim_blank_box { $ \m@th \mathpalette{}{#1} $ } } + { \hbox_set:Nn \l__xsim_blank_box {#1} } + \xsim_if_inside_solution:TF + { \xsim_write_cloze_filled:n {#1} } + { + \bool_if:NTF \l__xsim_blank_width_bool + { \__xsim_blank_skip:V \l__xsim_blank_dim } + { \__xsim_blank_skip:n { \box_wd:N \l__xsim_blank_box } } + } + } + +\cs_new_protected:Npn \__xsim_blank_skip:n #1 + { + \bool_if:NTF \l__xsim_blank_width_bool + { \dim_set:Nn \l__xsim_tmpa_dim {#1} } + { + \fp_set:Nn \l__xsim_tmpa_fp + { \dim_to_fp:n {#1} * \l__xsim_blank_scale_tl } + \dim_set:Nn \l__xsim_tmpa_dim { \fp_to_dim:N \l__xsim_tmpa_fp } + } + \dim_compare:nTF + { \l__xsim_tmpa_dim > \l__xsim_blank_line_minimum_length_dim } + { + \mode_if_math:TF + { \xsim_write_cloze_blank:n { \skip_horizontal:N \l__xsim_tmpa_dim } } + { + \dim_do_while:nn { \l__xsim_tmpa_dim > \c_zero_dim } + { + % I wonder what the correct l3 way would be -- if there is + % one, yet: + \tex_hfil:D + \tex_penalty:D \hyphenpenalty + \tex_hfilneg:D + \dim_compare:nTF + { \l__xsim_tmpa_dim < \l__xsim_blank_line_increment_dim } + { \xsim_write_cloze_blank:n { \skip_horizontal:N \l__xsim_tmpa_dim } } + { + \xsim_write_cloze_blank:n + { \skip_horizontal:N \l__xsim_blank_line_increment_dim } + } + \dim_sub:Nn \l__xsim_tmpa_dim { \l__xsim_blank_line_increment_dim } + } + } + } + { \xsim_write_cloze_blank:n { \skip_horizontal:N \l__xsim_tmpa_dim } } + } +\cs_generate_variant:Nn \__xsim_blank_skip:n { V } + +% ---------------------------------------------------------------------------- +\tex_endinput:D + +the following code from Heiko Oberdieck in d.c.t.t served as inspiration +and basis for the \blank command: +https://groups.google.com/d/msg/de.comp.text.tex/fZLwraH04jE/o1RSdFXjGuIJ + +\makeatletter +\newcommand*{\luecke}{% + \begingroup + \setlength{\dimen@}{6cm}% + \ifdim\dimen@>2em % + \underline{\hspace{1em}}% + \advance\dimen@ by -2em\relax + \@whiledim\dimen@>0pt\do{% + \penalty\hyphenpenalty + \ifdim\dimen@<1pt % + \underline{\hspace{\dimen@}}% + \else + \underline{\hspace{1pt}}% + \fi + \advance\dimen@ by -1pt % + }% + \underline{\hspace{1em}}% + \else + \underline{\hspace{\dimen@}}% + \fi + \endgroup + \xspace +} +\makeatother diff --git a/Master/texmf-dist/tex/latex/xsim/xsim.collections.code.tex b/Master/texmf-dist/tex/latex/xsim/xsim.collections.code.tex new file mode 100644 index 00000000000..8bf0c0bc705 --- /dev/null +++ b/Master/texmf-dist/tex/latex/xsim/xsim.collections.code.tex @@ -0,0 +1,395 @@ +% ---------------------------------------------------------------------------- +% the XSIM package - collections module +% +% eXercise Sheets IMproved +% +% ---------------------------------------------------------------------------- +% Clemens Niederberger +% Web: https://github.com/cgnieder/xsim +% E-Mail: contact@mychemistry.eu +% ---------------------------------------------------------------------------- +% Copyright 2017 Clemens Niederberger +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +% +% This work has the LPPL maintenance status `maintained'. +% +% The Current Maintainer of this work is Clemens Niederberger. +% ---------------------------------------------------------------------------- +% If you have any ideas, questions, suggestions or bugs to report, please +% feel free to contact me. +% ---------------------------------------------------------------------------- +\XSIMmodule{collections}{collect exercises and print collected exercises} + +\xsim_load_modules:n {base} + +\prop_new:N \g__xsim_collections_prop +\bool_new:N \l____xsim_active_bool + +\msg_new:nnn {xsim} {collection-exists} + { + The~ collection~ `#1'~ you're~ trying~ to~ define~ \msg_line_context: + \c_space_tl already~ exists. + } + +\msg_new:nnn {xsim} {collection-active} + { + You~ can't~ print~ collection~ `#1'~ while~ it~ is~ still~ active~ + \msg_line_context: + } + +\msg_new:nnn {xsim} {unknown-collection} + { + You're~ trying~ to~ use~ the~ collection~ `#1'~ \msg_line_context: + \c_space_tl but~ no~ collection~ with~ that~ name~ exists.~ You~ need~ to~ + define~ it~ first! + } + +\msg_new:nnn {xsim} {print-collection-choice} + { + The~ choice~ `#1'~ for~ the~ option~ `print-collection/print'~ does~ not~ + exist.~ I'm~ using~ `exercises'~ instead~ \msg_line_context: + } + +% ---------------------------------------------------------------------------- + +% #1: collection name +\cs_new_protected:Npn \xsim_new_collection:n #1 + { + \xsim_if_collection_exists:nTF {#1} + { \msg_error:nnn {xsim} {collection-exists} {#1} } + { + \xsim_verbose:n { Declaring~ new~ collection~ `#1'. } + \prop_gput:Nnn \g__xsim_collections_prop {#1} { \c_false_bool } + \xsim_new_list:n {collection:#1} + \seq_new:c {g__xsim_collection_#1_seq} + } + } + +% #1: collection name +\prg_new_conditional:Npnn \xsim_if_collection_exists:n #1 {T,F,TF} + { + \prop_if_in:NnTF \g__xsim_collections_prop {#1} + { \prg_return_true: } + { \prg_return_false: } + } + +\xsim_new_collection:n {all~ exercises} + +\cs_new_protected:Npn \xsim_foreach_collection:n #1 + { \prop_map_inline:Nn \g__xsim_collections_prop {#1} } + +% ---------------------------------------------------------------------------- + +% #1: collection name +% #2: type +\cs_new_protected:Npn \xsim_activate_collection:nn #1#2 + { + \xsim_if_collection_active:nTF {#1} + { % TODO: error + } + { + \xsim_verbose:n { Activating~ collection~ `#1'. } + \prop_gput:Nnn \g__xsim_collections_prop {#1} { \c_true_bool } + \tl_if_blank:nF {#2} + { \seq_gput_right:cn {g__xsim_collection_#1_seq} {#2} } + } + } + +\cs_new_protected:Npn \xsim_activate_collection:n #1 + { \xsim_activate_collection:nn {#1} {} } + +% #1: collection name +\cs_new_protected:Npn \xsim_deactivate_collection:n #1 + { + \xsim_if_collection_active:nTF {#1} + { + \xsim_verbose:n { Deactivating~ collection~ `#1'. } + \prop_gput:Nnn \g__xsim_collections_prop {#1} { \c_false_bool } + \seq_gclear:c {g__xsim_collection_#1_seq} + } + { % TODO: warning + } + } + +% start collection for an exercise type: +% #1: collection name +% #2: type +\cs_new_protected:Npn \xsim_start_collection:nn #1#2 + { + \group_begin: + \xsim_if_collection_exists:nF {#1} + { \msg_error:nnn {xsim} {unknown-collection} {#1} } + \xsim_activate_collection:nn {#1} {#2} + \xsim_setup:n { #2/print = false } + } + +% start collection for all exercise types: +% #1: collection name +\cs_new_protected:Npn \xsim_start_collection:n #1 + { + \group_begin: + \xsim_if_collection_exists:nF {#1} + { \msg_error:nnn {xsim} {unknown-collection} {#1} } + \xsim_activate_collection:n {#1} + \xsim_foreach_exercise_type:n + { \xsim_setup:n { ##1/print = false } } + } + +% stop collection: +% #1: collection name +\cs_new_protected:Npn \xsim_stop_collection:n #1 + { + \xsim_deactivate_collection:n {#1} + \group_end: + } + +% ---------------------------------------------------------------------------- + +% #1: collection name +% #2: type +% #3: id +\cs_new_protected:Npn \xsim_add_to_collection:nnn #1#2#3 + { + \seq_if_empty:cTF {g__xsim_collection_#1_seq} + { \__xsim_add_to_collection:nnn {#1} {#2} {#3} } + { + \seq_if_in:cnT {g__xsim_collection_#1_seq} {#2} + { \__xsim_add_to_collection:nnn {#1} {#2} {#3} } + } + } + +% #1: collection name +% #2: type +% #3: id +\cs_new_protected:Npn \__xsim_add_to_collection:nnn #1#2#3 + { + \xsim_verbose:n + { Adding~ exercise~ type~ `#2'~ id~ `#3'~ to~ collection~ `#1'. } + \xsim_add_to_list:nn {collection:#1} {#2-#3} + } + +\cs_new:Npn \xsim_collection_count:n #1 + { \xsim_list_count:n {collection:#1} } + +% #1: type +% #2: id +\cs_new_protected:Npn \xsim_update_collections:nn #1#2 + { + \xsim_if_insert_mode:F + { + \xsim_exercise_if_use:nnT {#1} {#2} + { \xsim_add_to_collection:nnn {all~ exercises} {#1} {#2} } + \xsim_foreach_collection:n + { + \xsim_exercise_if_use:nnTF {#1} {#2} + { + \xsim_if_collection_active:nT {##1} + { \xsim_add_to_collection:nnn {##1} {#1} {#2} } + } + { \xsim_remove_from_list:nn {collection:##1} {#1-#2} } + } + } + } +\cs_generate_variant:Nn \xsim_update_collections:nn {nV} + +% #1: collection name +\cs_new_protected:Npn \xsim_get_collections: + { + \xsim_foreach_collection:n + { + \xsim_foreach_list_entry:nn {collection:##1} + { \__xsim_list_to_collection:nww {##1} ####1 \q_stop } + } + } + +\cs_new_protected:Npn \__xsim_list_to_collection:nww #1#2-#3 \q_stop + { \xsim_add_to_collection:nnn {#1} {#2} {#3} } + +% ---------------------------------------------------------------------------- + +% #1: collection name +% #2: type +% #3: id +\prg_new_conditional:Npnn \xsim_if_in_collection:nnn #1#2#3 {T,F,TF} + { + \xsim_if_in_list:nnTF {collection:#1} {#2-#3} + { \prg_return_true: } + { \prg_return_false: } + } +\cs_generate_variant:Nn \xsim_if_in_collection:nnnTF {V} +\cs_generate_variant:Nn \xsim_if_in_collection:nnnT {x,nV} + +% ---------------------------------------------------------------------------- + +\bool_new:N \l__xsim_printcollection_headings_bool +\tl_new:N \l__xsim_printcollection_headings_template_tl +\tl_new:N \l__xsim_print_collection_choice_tl + +\keys_define:nn {xsim/print-collection} + { + headings .bool_set:N = \l__xsim_printcollection_headings_bool , + headings .initial:n = false , + headings-template .tl_set:N = \l__xsim_printcollection_headings_template_tl , + headings-template .initial:n = collection , + print .choice: , + print/exercises .code:n = + \tl_set:Nn \l__xsim_print_collection_choice_tl {exercise} , + print/solutions .code:n = + \tl_set:Nn \l__xsim_print_collection_choice_tl {solution} , + print/both .code:n = + \tl_set:Nn \l__xsim_print_collection_choice_tl {both} , + print/unknown .code:n = + \msg_warning:nnn {xsim} {print-collection-choice} {#1} + \tl_set:Nn \l__xsim_print_collection_choice_tl {exercise} , + print .initial:n = exercises + } + +% #1: options +% #2: collection name +\cs_new_protected:Npn \xsim_print_collection:nn #1#2 + { + \xsim_if_collection_active:nTF {#2} + { \msg_error:nnn {xsim} {collection-active} {#2} } + { + \xsim_verbose:x + { + Printing~ + \l__xsim_print_collection_choice_tl \c_space_tl + \str_if_eq:onT { \l__xsim_print_collection_choice_tl } {both} + { exercises~ and~ solutions~ } + of~ collection~ `#2' + } + \group_begin: + \keys_set:nn {xsim/print-collection} {#1} + \tl_set:Nn \ExerciseCollection {#2} + \xsim_foreach_exercise_type:n + { + \tl_set:Nn \ExerciseType {##1} + \bool_if:NT \l__xsim_printcollection_headings_bool + { + \bool_set_false:N \l__xsim_tmpa_bool + \xsim_foreach_exercise_id:n + { + \xsim_if_in_collection:nnnT {#2} {##1} {####1} + { + \tl_if_eq:VnTF + \l__xsim_print_collection_choice_tl + {both} + { + \xsim_if_exercise_exists:nnT {##1} {####1} + { \bool_set_true:N \l__xsim_tmpa_bool } + } + { + \use:c + { + xsim_if_ + \l__xsim_print_collection_choice_tl + _exists:nnT + } + {##1} + {####1} + { \bool_set_true:N \l__xsim_tmpa_bool } + } + } + } + \bool_if:NT \l__xsim_tmpa_bool + { + \xsim_use_template:nV + {heading} + \l__xsim_printcollection_headings_template_tl + } + } + \xsim_foreach_exercise_id:n + { + \xsim_if_in_collection:nnnT {#2} {##1} {####1} + { + \tl_if_eq:VnTF + \l__xsim_print_collection_choice_tl + {both} + { + \xsim_if_exercise_exists:nnT {##1} {####1} + { \xsim_insert:nnnn {##1} {####1} {} {exercise} } + \xsim_if_solution_exists:nnT {##1} {####1} + { \xsim_insert:nnnn {##1} {####1} {} {solution} } + } + { + \use:c + { + xsim_if_ + \l__xsim_print_collection_choice_tl + _exists:nnT + } + {##1} + {####1} + { + \xsim_insert:nnnV + {##1} + {####1} + {} + \l__xsim_print_collection_choice_tl + } + } + } + } + } + \group_end: + } + } + +% ---------------------------------------------------------------------------- + +% #1: collection name +\prg_new_conditional:Npnn \xsim_if_collection_active:n #1 {T,F,TF} + { + \prop_if_in:NnTF \g__xsim_collections_prop {#1} + { + \bool_if:nTF + { + !\str_if_eq_x_p:nn {#1} {all~ exercises} && + \prop_item:Nn \g__xsim_collections_prop {#1} + } + { \prg_return_true: } + { \prg_return_false: } + } + { \prg_return_false: } + } + +\prg_new_protected_conditional:Npnn \xsim_if_collections_active: {T,F,TF} + { + \bool_set_false:N \l____xsim_active_bool + \prop_map_inline:Nn \g__xsim_collections_prop + { + \xsim_if_collection_active:nT {##1} + { + \bool_set_true:N \l____xsim_active_bool + \prop_map_break: + } + } + \bool_if:NTF \l____xsim_active_bool + { \prg_return_true: } + { \prg_return_false: } + } + +% ---------------------------------------------------------------------------- + +\AtBeginDocument + { + \xsim_get_collections: + \xsim_activate_collection:n {all~ exercises} + } + +\AtEndDocument + { + \xsim_deactivate_collection:n {all~ exercises} + \xsim_foreach_collection:n { \xsim_update_list:n {collection:#1} } + } + +% ---------------------------------------------------------------------------- +\tex_endinput:D diff --git a/Master/texmf-dist/tex/latex/xsim/xsim.definitions.code.tex b/Master/texmf-dist/tex/latex/xsim/xsim.definitions.code.tex new file mode 100644 index 00000000000..a30c44a76fc --- /dev/null +++ b/Master/texmf-dist/tex/latex/xsim/xsim.definitions.code.tex @@ -0,0 +1,430 @@ +% ---------------------------------------------------------------------------- +% the XSIM package - definitions module +% +% eXercise Sheets IMproved +% +% ---------------------------------------------------------------------------- +% Clemens Niederberger +% Web: https://github.com/cgnieder/xsim +% E-Mail: contact@mychemistry.eu +% ---------------------------------------------------------------------------- +% Copyright 2017 Clemens Niederberger +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +% +% This work has the LPPL maintenance status `maintained'. +% +% The Current Maintainer of this work is Clemens Niederberger. +% ---------------------------------------------------------------------------- +% If you have any ideas, questions, suggestions or bugs to report, please +% feel free to contact me. +% ---------------------------------------------------------------------------- +\XSIMmodule{definitions}{definition of user commands} + +\xsim_load_modules:n {base,exercises,blanks,translations,interface,grades,random} + +% not exactly a user choice: the `exercises' environments rely on them: +\DeclareExerciseParameter*!{exercise-env} +\DeclareExerciseParameter*!{solution-env} +\DeclareExerciseParameter !{exercise-name} +\DeclareExerciseParameter !{solution-name} +\DeclareExerciseParameter !{exercise-template} +\DeclareExerciseParameter !{solution-template} +\DeclareExerciseParameter* {counter} +\DeclareExerciseParameter* {solution-counter} +\DeclareExerciseParameter* {number} + +% ---------------------------------------------------------------------------- + +% not exactly a user choice, must be present at various places: +\DeclareExerciseProperty! {id} +\DeclareExerciseProperty! {ID} +\DeclareExerciseProperty {counter} +\DeclareExerciseProperty {counter-value} +\DeclareExerciseProperty * {print} +\DeclareExerciseProperty *-{print!} +\DeclareExerciseProperty * {use} +\DeclareExerciseProperty * {used} +\DeclareExerciseProperty *-{use!} +\XSIMifchapterT{ + \DeclareExerciseProperty {chapter-value} + \DeclareExerciseProperty {chapter} +} +\DeclareExerciseProperty {section-value} +\DeclareExerciseProperty {section} + +% those are additional and wouldn't *need* to be present except for +% pre-defined templates which make use of them: +\DeclareExerciseProperty {subtitle} +\DeclareExerciseProperty {points} +\DeclareExerciseProperty {bonus-points} +\DeclareExerciseProperty {page-value} +\DeclareExerciseProperty {page} + +\DeclareExercisePropertyAlias {ID} {id} + +% ---------------------------------------------------------------------------- + +\DeclareExerciseTagging {tags} +\DeclareExerciseTagging {topics} + +\xsimsetup{tags/ingore-untagged=false} + +% ---------------------------------------------------------------------------- + +\DeclareExerciseGoal {points} +\DeclareExerciseGoal {bonus-points} + +\NewDocumentCommand \printgoal {m} + { \ExerciseGoalValuePrint {#1} {} {} } + +\NewDocumentCommand \points {m} + { + \ExerciseGoalValuePrint {#1} + { \, \XSIMtranslate {point} } + { \, \XSIMtranslate {points} } + } + +\NewDocumentCommand \addpoints {sm} + { + \AddtoExerciseGoal {points} {#2} + \IfBooleanF {#1} { \points {#2} } + } + +\NewDocumentCommand \printpoints {m} + { + \TotalExerciseTypeGoal {#1} {points} + { \, \XSIMtranslate {point} } + { \, \XSIMtranslate {points} } + } + +\NewDocumentCommand \printtotalpoints {} + { + \TotalExerciseGoal {points} + { \, \XSIMtranslate {point} } + { \, \XSIMtranslate {points} } + } + +\NewDocumentCommand \addbonus {sm} + { + \AddtoExerciseGoal {bonus-points} {#2} + \IfBooleanF {#1} { \points {#2} } + } + +\NewDocumentCommand \printbonus {m} + { + \TotalExerciseTypeGoal {#1} {bonus-points} + { \, \XSIMtranslate {point} } + { \, \XSIMtranslate {points} } + } + +\NewDocumentCommand \printtotalbonus {} + { + \TotalExerciseGoal {bonus-points} + { \, \XSIMtranslate {point} } + { \, \XSIMtranslate {points} } + } + +% ---------------------------------------------------------------------------- +\NewDocumentCommand \pointsforgrade {m} + { + \GetGradeRequirementForGoal {#1} {points} + { \, \XSIMtranslate {point} } + { \, \XSIMtranslate {points} } + } + +\NewDocumentCommand \goalsforgrade {mm} + { + \GetGradeRequirementForGoals {#2} {#1} + { \, \XSIMtranslate {point} } + { \, \XSIMtranslate {points} } + } + +\NewDocumentCommand \totalgoalforgrade {m} + { + \GetGradeRequirement {#1} + { \, \XSIMtranslate {point} } + { \, \XSIMtranslate {points} } + } + +% ---------------------------------------------------------------------------- + +\DeclareExerciseType {exercise} { + exercise-env = exercise , + solution-env = solution , + exercise-name = \XSIMtranslate {exercise} , + solution-name = \XSIMtranslate {solution} , + exercise-template = default , + solution-template = default +} + +% ---------------------------------------------------------------------------- + +\DeclareExerciseEnvironmentTemplate {default} + { + \subsection* + { + \XSIMmixedcase { \GetExerciseName } \nobreakspace + \GetExerciseProperty {counter} + \IfInsideSolutionF + { + \IfExercisePropertySetT {subtitle} + { ~ { \normalfont \itshape \GetExerciseProperty {subtitle} } } + } + } + \GetExercisePropertyT {points} + { + \marginpar + { + \IfInsideSolutionF { \rule {1.2cm} {1pt} \slash } + \PropertyValue + \GetExercisePropertyT {bonus-points} + { \nobreakspace ( + \PropertyValue ) } + \nobreakspace\XSIMtranslate {point-abbr} + } + } + } + {} + +% ---------------------------------------------------------------------------- + +\DeclareExerciseHeadingTemplate {none} {} + +\DeclareExerciseHeadingTemplate {default} + { \section* { \XSIMtranslate {default-heading} } } + +\DeclareExerciseHeadingTemplate {collection} + { \section* { \XSIMtranslate {collection-heading} } } + +\DeclareExerciseHeadingTemplate {per-section} + { \section* { \XSIMtranslate {per-section-heading} } } + +\DeclareExerciseHeadingTemplate {per-chapter} + { \section* { \XSIMtranslate {per-chapter-heading} } } + +% ---------------------------------------------------------------------------- + +\RequirePackage{array,booktabs} + +\DeclareExerciseTableTemplate {default*} + { + \XSIMputright \ExerciseTableCode + { + \toprule + \XSIMifblankTF {\ExerciseType} + {} + { \XSIMmixedcase { \GetExerciseParameter {exercise-name} } } + & + } + \ForEachUsedExerciseByType + { + \XSIMifeqTF {#1} { \ExerciseTableType {#1} } + { + \XSIMifblankTF { \ExerciseType } + { + \XSIMputright \ExerciseTableCode + { + \XSIMmixedcase + { \ExerciseParameterGet {#1} {exercise-name} ~ } + } + } + {} + \XSIMputright \ExerciseTableCode { #3 & } + } + {} + } + \XSIMputright \ExerciseTableCode + { + \XSIMtranslate {total} \\ + \midrule \XSIMmixedcase { \XSIMtranslate {points} } & + } + \ForEachUsedExerciseByType + { + \XSIMifeqTF {#1} { \ExerciseTableType {#1} } + { + \XSIMputright \ExerciseTableCode + { \XSIMifblankTF {#5} {\printgoal{0}} {\printgoal{#5}} & } + } + {} + } + \XSIMputright \ExerciseTableCode + { + \XSIMifblankTF {\ExerciseType} + { \TotalExerciseGoal {points} {} {} } + { \TotalExerciseTypeGoal {\ExerciseType} {points} {} {} } + \\ \midrule + \XSIMtranslate {reached} & + } + \ForEachUsedExerciseByType + { + \XSIMifeqTF {#1} { \ExerciseTableType {#1} } + { \XSIMputright \ExerciseTableCode {&} } + {} + } + \XSIMputright \ExerciseTableCode { \\ \bottomrule } + \def\numberofcolumns{ + \XSIMifblankTF {\ExerciseType} + {\numberofusedexercises} + {\csname numberof \ExerciseType s\endcsname} + } + \XSIMifeqF{\numberofcolumns}{0} + { + \begin {tabular} {l*{\numberofcolumns}{c}c} + \ExerciseTableCode + \end {tabular} + } + } + +\DeclareExerciseTableTemplate {default} + { + \XSIMputright \ExerciseTableCode + { + \toprule + \XSIMifblankTF {\ExerciseType} + {} + { \XSIMmixedcase { \GetExerciseParameter {exercise-name} } } + & + \XSIMmixedcase { \XSIMtranslate {points} } & + \XSIMtranslate {reached} \\ + \midrule + } + \ForEachUsedExerciseByType + { + \XSIMifeqTF {#1} { \ExerciseTableType {#1} } + { + \XSIMifblankTF { \ExerciseType } + { + \XSIMputright \ExerciseTableCode + { + \XSIMmixedcase + { \ExerciseParameterGet {#1} {exercise-name} ~ } + } + } + {} + \XSIMputright \ExerciseTableCode + { #3 & \XSIMifblankTF {#5} {\printgoal{0}} {\printgoal{#5}} & \\ } + } + {} + } + \XSIMputright \ExerciseTableCode + { + \midrule + \XSIMtranslate {total} & + \XSIMifblankTF {\ExerciseType} + { \TotalExerciseGoal {points} {} {} } + { \TotalExerciseTypeGoal {\ExerciseType} {points} {} {} } & + \\ \bottomrule + } + \XSIMexpandcode + { + \noexpand \begin {tabular} {\XSIMifblankTF{\ExerciseType}{l}{c}cc} + \noexpand \ExerciseTableCode + \noexpand \end {tabular} + } + } + +% ---------------------------------------------------------------------------- + +\DeclareExerciseTranslations {exercise} { + Fallback = exercise , + English = exercise , + French = exercice , + German = \"Ubung +} + +\DeclareExerciseTranslations {question} { + Fallback = question , + English = question , + French = question , + German = Aufgabe +} + +\DeclareExerciseTranslations {solution} { + Fallback = solution , + English = solution , + French = solution , + German = L\"osung +} + +\DeclareExerciseTranslations {point-abbr} { + Fallback = p. , + English = p. , + French = p. , + German = P. +} + +\DeclareExerciseTranslations {point} { + Fallback = point , + English = point , + French = point , + German = Punkt +} + +\DeclareExerciseTranslations {points} { + Fallback = points , + English = points , + French = points , + German = Punkte +} + +\DeclareExerciseTranslations {reached} { + Fallback = reached , + English = reached , + French = atteint , + German = erreicht +} + +\DeclareExerciseTranslations {total} { + Fallback = total , + English = total , + French = totalement , + German = insgesamt +} + +\DeclareExerciseTranslations {default-heading} { + Fallback = \XSIMmixedcase { \GetExerciseParameter {solution-name} s }~ + to~ the~ \XSIMmixedcase { \GetExerciseParameter {exercise-name} s} , + English = \XSIMmixedcase { \GetExerciseParameter {solution-name} s }~ + to~ the~ \XSIMmixedcase { \GetExerciseParameter {exercise-name} s} , + German = \XSIMmixedcase { \GetExerciseParameter {solution-name} en }~ + zu~ den~ \XSIMmixedcase { \GetExerciseParameter {exercise-name} en} +} + +\DeclareExerciseTranslations {collection-heading} { + Fallback = \XSIMmixedcase { \GetExerciseParameter {exercise-name} s } , + English = \XSIMmixedcase { \GetExerciseParameter {exercise-name} s } , + German = \XSIMmixedcase { \GetExerciseParameter {exercise-name} en } +} + +\DeclareExerciseTranslations {per-section-heading} { + Fallback = \XSIMmixedcase { \GetExerciseParameter {solution-name} s }~ + to~ the~ \XSIMmixedcase { \GetExerciseParameter {exercise-name} s}~ + of~ Section \nobreakspace \ExerciseSection , + English = \XSIMmixedcase { \GetExerciseParameter {solution-name} s }~ + to~ the~ \XSIMmixedcase { \GetExerciseParameter {exercise-name} s}~ + of~ Section \nobreakspace \ExerciseSection , + German = \XSIMmixedcase { \GetExerciseParameter {solution-name} en }~ + zu~ den~ \XSIMmixedcase { \GetExerciseParameter {exercise-name} en}~ + in~ Abschnitt \nobreakspace \ExerciseSection +} + +\DeclareExerciseTranslations {per-chapter-heading} { + Fallback = \XSIMmixedcase { \GetExerciseParameter {solution-name} s }~ + to~ the~ \XSIMmixedcase { \GetExerciseParameter {exercise-name} s}~ + of~ Chapter \nobreakspace \ExerciseChapter , + English = \XSIMmixedcase { \GetExerciseParameter {solution-name} s }~ + to~ the~ \XSIMmixedcase { \GetExerciseParameter {exercise-name} s}~ + of~ Chapter \nobreakspace \ExerciseChapter , + German = \XSIMmixedcase { \GetExerciseParameter {solution-name} en }~ + zu~ den~ \XSIMmixedcase { \GetExerciseParameter {exercise-name} en}~ + in~ Kapitel \nobreakspace \ExerciseChapter +} + +% ---------------------------------------------------------------------------- +\tex_endinput:D diff --git a/Master/texmf-dist/tex/latex/xsim/xsim.environments.code.tex b/Master/texmf-dist/tex/latex/xsim/xsim.environments.code.tex new file mode 100644 index 00000000000..43a46ab6146 --- /dev/null +++ b/Master/texmf-dist/tex/latex/xsim/xsim.environments.code.tex @@ -0,0 +1,345 @@ +% ---------------------------------------------------------------------------- +% the XSIM package - environments module +% +% eXercise Sheets IMproved +% +% ---------------------------------------------------------------------------- +% Clemens Niederberger +% Web: https://github.com/cgnieder/xsim +% E-Mail: contact@mychemistry.eu +% ---------------------------------------------------------------------------- +% Copyright 2017 Clemens Niederberger +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +% +% This work has the LPPL maintenance status `maintained'. +% +% The Current Maintainer of this work is Clemens Niederberger. +% ---------------------------------------------------------------------------- +% If you have any ideas, questions, suggestions or bugs to report, please +% feel free to contact me. +% ---------------------------------------------------------------------------- +\XSIMmodule{environments}{generic code for exercise and solution environments} + +\xsim_load_modules:n {templates,verbwrite} + +\tl_new:N \l__xsim_file_name_signature_tl +\tl_new:N \l__xsim_file_path_tl +\tl_new:N \l__xsim_file_path_and_name_tl +\tl_new:N \l__xsim_file_name_tl +\bool_new:N \l__xsim_options_given_bool +\bool_new:N \l__xsim_insert_mode_bool + +% ---------------------------------------------------------------------------- + +\keys_define:nn {xsim} + { path .tl_set:N = \l__xsim_file_path_tl } + +% ---------------------------------------------------------------------------- + +\tl_const:Nn \c__xsim_comment_line_tl { \c__xsim_percent_char_tl } +\tl_const:Nn \c__xsim_comment_line_fill_tl { \prg_replicate:nn {72} {-} } +\tl_const:Nn \c__xsim_comment_line_indent_tl { \c_space_tl \c_space_tl } + +\cs_new:Npn \__xsim_comment_line_and_feed:n #1 + { \__xsim_comment_line:n {#1} ^^J } + +\cs_new:Npn \__xsim_comment_line:n #1 + { + \c__xsim_comment_line_tl + \tl_if_blank:nF {#1} { \c_space_tl } + #1 + } + +\cs_new:Npn \__xsim_two_digits:n #1 + { \int_compare:nT { #1 < 10 } {0} \int_eval:n {#1} } + +% #1: type +% #2: id +% #3: exercise|solution +\cs_new_protected:Npn \__xsim_set_file_signature:nnn #1#2#3 + { \tl_set:Nn \l__xsim_file_name_signature_tl {#1-#2-#3} } +\cs_generate_variant:Nn \__xsim_set_file_signature:nnn {nx,nV} + +\tl_set:Nn \l__xsim_file_name_tl + { \c_sys_jobname_str - \l__xsim_file_name_signature_tl -body.tex } + +\tl_set:Nn \l__xsim_file_path_and_name_tl + { + \tl_if_blank:VF \l__xsim_file_path_tl + { \l__xsim_file_path_tl / } + \l__xsim_file_name_tl + } + +% #1: type +% #2: id +% #3: exercise|solution +% #4: file name +% #5: path +\cs_new_protected:Npn \__xsim_file_info:nnnnn #1#2#3#4#5 + { + \tl_set:Nn \l_xsim_file_begin_tl + { + \__xsim_comment_line_and_feed:n { \c__xsim_comment_line_fill_tl } + \__xsim_comment_line_and_feed:n {file~ `#4'} + \tl_if_blank:nF {#5} + { + \__xsim_comment_line_and_feed:n + { \c__xsim_comment_line_indent_tl in~ folder~ `#5/'} + } + \__xsim_comment_line_and_feed:n {} + \__xsim_comment_line_and_feed:n + { + \c__xsim_comment_line_indent_tl + \c__xsim_comment_line_indent_tl + #3~ of~ type~ `#1'~ with~ id~ `#2' + } + \__xsim_comment_line_and_feed:n {} + \__xsim_comment_line_and_feed:n + {generated~ by~ the~ `\@currenvir'~ environment~ of~ the} + \__xsim_comment_line_and_feed:n + { + \c__xsim_comment_line_indent_tl + `xsim'~ package~ v \c_xsim_version_tl + \c_space_tl (\c_xsim_date_tl) + } + \__xsim_comment_line_and_feed:n + { + from~ source~ `\c_sys_jobname_str'~ on~ + \int_use:N \c_sys_year_int / + \__xsim_two_digits:n { \c_sys_month_int } / + \__xsim_two_digits:n { \c_sys_day_int } ~ + \msg_line_context: + } + \__xsim_comment_line:n { \c__xsim_comment_line_fill_tl } + } + } +\cs_generate_variant:Nn \__xsim_file_info:nnnnn {nnnVV} + +% ---------------------------------------------------------------------------- + +% #1: type +% #2: id +% #3: exercise|solution +\cs_new_protected:Npn \xsim_save_environment_body:nnn #1#2#3 + { + \xsim_verbose:n + { Starting~ to~ write~ #3~ environment~ type~ `#1'~ id~ `#2' } + \__xsim_set_file_signature:nnn {#1} {#2} {#3} + \__xsim_file_info:nnnVV {#1} {#2} {#3} + \l__xsim_file_name_tl + \l__xsim_file_path_tl + \int_zero:N \l_xsim_line_gobble_int + \xsim_file_write_start:nV + { \l__xsim_options_given_bool } + \l__xsim_file_path_and_name_tl + } + +\cs_new_protected:Npn \xsim_save_environment_body_end: + { \xsim_file_write_stop: } + +% ---------------------------------------------------------------------------- +% #1: type +% #2: exercise|solution +% #3: hook +\cs_new_protected:Npn \xsim_new_hook:nnn #1#2#3 + { + \xsim_verbose:n { Defining~ new~ #1~ (#2)~ hook~ `#3' } + \tl_new:c {l__xsim_#1_#2_#3_hook_tl} + \keys_define:nx {xsim} + { + \xsim_get_parameter:nn {#1} {#2-env}/#3-hook .tl_set:N = + \exp_not:c {l__xsim_#1_#2_#3_hook_tl} + } + } + +% #1: type +% #2: exercise|solution +% #3: hook +\cs_new:Npn \xsim_use_hook:nnn #1#2#3 + { \exp_not:v {l__xsim_#1_#2_#3_hook_tl} } + +% #1: type +% #2: exercise|solution +% #3: hook +% #4: code +\cs_new_protected:Npn \xsim_set_hook:nnnn #1#2#3#4 + { + \xsim_verbose:n { Setting~ #1~ (#2)~ hook~ `#3' } + \tl_set:cn {l__xsim_#1_#2_#3_hook_tl} {#4} + } + +% #1: type +% #2: exercise|solution +% #3: hook +% #4: code +\cs_new_protected:Npn \xsim_addto_hook:nnnn #1#2#3#4 + { + \xsim_verbose:n { Adding~ to~ #1~ (#2)~ hook~ `#3' } + \tl_put_right:cn {l__xsim_#1_#2_#3_hook_tl} {#4} + } + +% ---------------------------------------------------------------------------- + +% #1: type +% #2: id +% #3: exercise|solution +\cs_new_protected:Npn \xsim_start_environment:nnn #1#2#3 + { \xsim_save_environment_body:nnn {#1} {#2} {#3} } +\cs_generate_variant:Nn \xsim_start_environment:nnn {nV} + +% #1: type +% #2: id +% #3: exercise|solution +\cs_new_protected:Npn \xsim_stop_environment:nnn #1#2#3 + { + \xsim_save_environment_body_end: + \xsim_if_print:nnnTF {#1} {#2} {#3} + { \xsim_typeset_environment:nnn {#1} {#2} {#3} } + { \xsim_use_hook:nnn {#1} {#3} {print-false} } + } +\cs_generate_variant:Nn \xsim_stop_environment:nnn {nV} + +% #1: type +% #2: id +% #3: exercise|solution +\cs_new_protected:Npn \xsim_typeset_environment:nnn #1#2#3 + { + \xsim_verbose:n + { Typesetting~ #3~ environment~ type~ `#1'~ id~ `#2' } + \use:x + { + \exp_not:N \par + \xsim_use_hook:nnn {#1} {#3} {pre} + \xsim_use_template:nn + {begin} + { \xsim_get_parameter:nn {#1} {#3-template} } + \xsim_use_hook:nnn {#1} {#3} {begin} + \file_if_exist:nTF { \exp_not:V \l__xsim_file_path_and_name_tl } + { \file_input:n { \exp_not:V \l__xsim_file_path_and_name_tl } } + { + \xsim_verbose:n + { File~ `\l__xsim_file_path_and_name_tl'~ doesn't~ exist. } + } + \xsim_use_hook:nnn {#1} {#3} {end} + \xsim_use_template:nn + {end} + { \xsim_get_parameter:nn {#1} {#3-template} } + \xsim_use_hook:nnn {#1} {#3} {post} + \exp_not:N \par + } + } + +% #1: type +% #2: id +% #3: options +% #4: exercise|solution +\cs_new_protected:Npn \xsim_insert:nnnn #1#2#3#4 + { + \__xsim_set_file_signature:nnn {#1} {#2} {#4} + \file_if_exist:VTF \l__xsim_file_path_and_name_tl + { + \xsim_verbose:n + { Inserting~ #4~ type~ `#1'~ id~ `#2'. } + \group_begin: + \xsim_insert_mode: + \use:c {xsim_start_#4:nn} {#1} {#3} + \tl_set:Nn \ExerciseType {#1} + \tl_set:Nn \ExerciseID {#2} + \str_if_eq:nnT {#4} {exercise} + { + \xsim_if_boolean_property:nnnF {#1} {#2} {used} + { + \xsim_step_exercise_counter:nn {#1} {#2} + \xsim_set_properties:nnx {#1} {#2} + { + page-value = \arabic{page} , + page = \thepage , + section-value = \arabic{section} , + section = \thesection + } + } + \xsim_if_property_exist:nT {chapter} + { + \xsim_set_properties:nnx {#1} {#2} + { + chapter-value = \arabic{chapter} , + chapter = \thechapter + } + } + \xsim_set_properties:nnn {#1} {#2} + { print=true , used=true } + } + \use:x + { + \xsim_use_hook:nnn {#1} {#4} {pre} + \xsim_use_template:nn + {begin} + { \xsim_get_parameter:nn {#1} {#4-template} } + \xsim_use_hook:nnn {#1} {#4} {begin} + \file_input:n { \exp_not:V \l__xsim_file_path_and_name_tl } + \xsim_use_hook:nnn {#1} {#4} {end} + \xsim_use_template:nn + {end} + { \xsim_get_parameter:nn {#1} {#4-template} } + \xsim_use_hook:nnn {#1} {#4} {post} + } + \group_end: + } + { + \xsim_verbose:n + { File~ `\l__xsim_file_path_and_name_tl'~ doesn't~ exist. } + } + } +\cs_generate_variant:Nn \xsim_insert:nnnn {nV,VV,nnnV} + +\prg_new_conditional:Npnn \xsim_if_insert_mode: {T,F,TF} + { + \bool_if:NTF \l__xsim_insert_mode_bool + { \prg_return_true: } + { \prg_return_false: } + } + +\cs_new_protected:Npn \xsim_insert_mode: + { \bool_set_true:N \l__xsim_insert_mode_bool } + +% ---------------------------------------------------------------------------- + +% #1: type +% #2: exercise|solution +\cs_new_protected:Npn \xsim_new_environment:nn #1#2 + { + \xsim_verbose:n { Defining~ #2~ environment~ type~ `#1'. } + \xsim_new_hook:nnn {#1} {#2} {pre} + \xsim_new_hook:nnn {#1} {#2} {begin} + \xsim_new_hook:nnn {#1} {#2} {end} + \xsim_new_hook:nnn {#1} {#2} {post} + \xsim_new_hook:nnn {#1} {#2} {print-false} + \NewDocumentEnvironment + { \xsim_get_parameter:nn {#1} {#2-env} } {o} + { + \IfNoValueTF {##1} + { + \bool_set_false:N \l__xsim_options_given_bool + \use:c {xsim_start_#2:nn} {#1} {} + } + { + \bool_set_true:N \l__xsim_options_given_bool + \use:c {xsim_start_#2:nn} {#1} {##1} + } + \xsim_start_environment:nVn {#1} \g_xsim_exercise_id_tl {#2} + } + { + \xsim_stop_environment:nVn {#1} \g_xsim_exercise_id_tl {#2} + \use:c {xsim_stop_#2:n} {#1} + } + } + +% ---------------------------------------------------------------------------- +\tex_endinput:D diff --git a/Master/texmf-dist/tex/latex/xsim/xsim.exercises.code.tex b/Master/texmf-dist/tex/latex/xsim/xsim.exercises.code.tex new file mode 100644 index 00000000000..59434ec3071 --- /dev/null +++ b/Master/texmf-dist/tex/latex/xsim/xsim.exercises.code.tex @@ -0,0 +1,515 @@ +% ---------------------------------------------------------------------------- +% the XSIM package - exercises module +% +% eXercise Sheets IMproved +% +% ---------------------------------------------------------------------------- +% Clemens Niederberger +% Web: https://github.com/cgnieder/xsim +% E-Mail: contact@mychemistry.eu +% ---------------------------------------------------------------------------- +% Copyright 2017 Clemens Niederberger +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +% +% This work has the LPPL maintenance status `maintained'. +% +% The Current Maintainer of this work is Clemens Niederberger. +% ---------------------------------------------------------------------------- +% If you have any ideas, questions, suggestions or bugs to report, please +% feel free to contact me. +% ---------------------------------------------------------------------------- +\XSIMmodule{exercises}{main exercises definitions} + +\xsim_load_modules:n + { + base, properties, environments, templates, solutions, tags, goals, + collections + } + +\seq_new:N \l__xsim_parameters_seq +\seq_new:N \l__xsim_fixed_parameters_seq +\seq_new:N \l__xsim_mandatory_parameters_seq +\prop_new:N \g__xsim_exercises_prop +\int_gzero_new:N \g_xsim_id_int +\int_gzero_new:N \g_xsim_max_id_int +\tl_new:N \l_xsim_current_id_tl +\tl_new:N \g_xsim_exercise_id_tl +\tl_new:N \ExerciseID +\bool_new:N \l____xsim_print_bool + +% ---------------------------------------------------------------------------- + +\msg_new:nnn {xsim} {parameter-fixed} + { + You~ tried~ to~ set~ parameter~ `#2'~ for~ type~ `#1'~ \msg_line_context: + . ~ However,~ parameter~ `#2'~ is~ a~ fixed~ parameter~ that~ already~ + has~ been~ set~ for~ type~ `#1'.~ Its~ value~ can't~ be~ changed! + } + +\msg_new:nnn {xsim} {type-exists} + { + You~ try~ to~ define~ exercise~ type~ `#1'~ \msg_line_context: .~ + However,~ the~ exercise~ type~ `#1'~ already~ exists. + } + +\msg_new:nnn {xsim} {mandatory-parameter} + { + You~ forget~ to~ set~ the~ mandatory~ parameter~ `#1'~ when~ defining~ + exercise~ type~ `#2'. + } + +% ---------------------------------------------------------------------------- + +\xsim_new_list:n {types} + +% #1: true|false (fixed parameter) +% #2: true|false (mandatory parameter) +% #3: parameter name +\cs_new_protected:Npn \xsim_declare_parameter:nnn #1#2#3 + { + \xsim_verbose:n { Declaring~ parameter~ `#3'. } + \xsim_if_parameter_exist:nF {#3} + { + \seq_put_right:Nn \l__xsim_parameters_seq {#3} + \bool_if:cT {c_#1_bool} + { \seq_put_right:Nn \l__xsim_fixed_parameters_seq {#3} } + \bool_if:cT {c_#2_bool} + { \seq_put_right:Nn \l__xsim_mandatory_parameters_seq {#3} } + } + } + +\cs_new_protected:Npn \xsim_remove_parameter:n #1 + { + \xsim_verbose:n { Removing~ parameter~ `#1'. } + \xsim_if_parameter_exist:nT {#1} + { \seq_remove_all:Nn \l__xsim_parameters_seq {#1} } + } + +\prg_new_conditional:Npnn \xsim_if_parameter_exist:n #1 {p,T,F,TF} + { + \seq_if_in:NnTF \l__xsim_parameters_seq {#1} + { \prg_return_true: } + { \prg_return_false: } + } +\cs_generate_variant:Nn \xsim_if_parameter_exist:nT {x} + +\prg_new_conditional:Npnn \xsim_if_parameter_fixed:n #1 {p,T,F,TF} + { + \seq_if_in:NnTF \l__xsim_fixed_parameters_seq {#1} + { \prg_return_true: } + { \prg_return_false: } + } + +% #1: type +% #2: csv list of parameters +\cs_new_protected:Npn \xsim_set_parameters:nn #1#2 + { + \clist_map_inline:nn {#2} + { + \seq_set_split:Nnx \l__xsim_tmpa_seq {=} { \tl_trim_spaces:n {##1} } + \xsim_set_parameter:nxx {#1} + { \seq_item:Nn \l__xsim_tmpa_seq {1} } + { \seq_item:Nn \l__xsim_tmpa_seq {2} } + } + } +\cs_generate_variant:Nn \xsim_set_parameters:nn {nx} + +% #1: type +\cs_new_protected:Npn \xsim_check_mandatory_parameters:n #1 + { + \seq_map_inline:Nn \l__xsim_mandatory_parameters_seq + { + \xsim_if_parameter:nnF {#1} {##1} + { \msg_error:nnnn {xsim} {mandatory-parameter} {##1} {#1} } + } + } + +% #1: type +\prg_new_conditional:Npnn \xsim_if_type:n #1 {p,T,F,TF} + { + \prop_if_exist:cTF {l__xsim_#1_type_parameters_prop} + { \prg_return_true: } + { \prg_return_false: } + } + +% #1: type +% #2: parameter +% #3: value +\cs_new_protected:Npn \xsim_set_parameter:nnn #1#2#3 + { + \xsim_if_parameter_exist:nT {#2} + { + \xsim_if_parameter_fixed:nTF {#1} + { + \xsim_if_parameter:nnTF {#1} {#2} + { + \msg_warning:nnnn {xsim} {parameter-fixed} {#1} {#2} + \xsim_verbose:n + { + Not~ setting~ already~ set~ and~ fixed~ parameter~ `#2'~ + for~ type~ `#1'. + } + } + { + \xsim_verbose:n + { Setting~ parameter~ `#2'~ for~ type~ `#1'~ to~ `#3'. } + \prop_put:cnn {l__xsim_#1_type_parameters_prop} {#2} {#3} + } + } + { + \xsim_verbose:n + { Setting~ parameter~ `#2'~ for~ type~ `#1'~ to~ `#3'. } + \prop_put:cnn {l__xsim_#1_type_parameters_prop} {#2} {#3} + } + } + } +\cs_generate_variant:Nn \xsim_set_parameter:nnn {nnx,nxx} + +% #1: type +% #2: parameter +\cs_new:Npn \xsim_get_parameter:nn #1#2 + { \prop_item:cn {l__xsim_#1_type_parameters_prop} {#2} } +\cs_generate_variant:Nn \xsim_get_parameter:nn {o} + +\prg_new_conditional:Npnn \xsim_if_parameter:nn #1#2 {p,T,F,TF} + { + \prop_if_in:cnTF {l__xsim_#1_type_parameters_prop} {#2} + { \prg_return_true: } + { \prg_return_false: } + } + +% ---------------------------------------------------------------------------- +% inside the argument `#1' refers to the type +\cs_new_protected:Npn \xsim_foreach_exercise_type:n #1 + { \xsim_foreach_new_list_entry:nn {types} {#1} } + +\cs_new_protected:Npn \xsim_foreach_exercise_id:n #1 + { \int_step_inline:nnnn {1} {1} { \g_xsim_max_id_int } {#1} } + +\cs_new:Npn \__xsim_loop_item:nnnnnn #1#2#3#4#5#6 {} +\cs_generate_variant:Nn \__xsim_loop_item:nnnnnn {VVxxxx} + +% #1: type +% #2: id +% #3: boolean property +\cs_new:Npn \__xsim_deliver_exercise_details:nnn #1#2#3 + { + \xsim_if_in_list:nnT {#3} {#1-#2=={true}} + { + \tl_set_rescan:Nnx \l__xsim_tmpa_tl {} {#1} + \tl_set_rescan:Nnx \l__xsim_tmpb_tl {} {#2} + \__xsim_loop_item:VVxxxx + \l__xsim_tmpa_tl % #1 + \l__xsim_tmpb_tl % #2 + { \xsim_get_property:nnn {#1} {#2} {counter} } % #3 + { \xsim_get_property:nnn {#1} {#2} {subtitle} } % #4 + { \xsim_get_property:nnn {#1} {#2} {points} } % #5 + { \xsim_get_property:nnn {#1} {#2} {bonus-points} } % #6 + } + } + +% #1: boolean property +% #2: loop code +\xsim_define_loop_macro:Nnn \xsim_foreach_exercise_type_id:nn + {nnnnnn} + { + \xsim_foreach_exercise_type:n + { + \xsim_foreach_exercise_id:n + { \__xsim_deliver_exercise_details:nnn {##1} {####1} {#1} } + } + } + +\xsim_define_loop_macro:Nnn \xsim_foreach_exercise_id_type:nn + {nnnnnn} + { + \xsim_foreach_exercise_id:n + { + \xsim_foreach_exercise_type:n + { \__xsim_deliver_exercise_details:nnn {####1} {##1} {#1} } + } + } + +\cs_new_protected:Npn \xsim_define_exercise_type_variables:n #1 + { + \prop_new:c {l__xsim_#1_type_parameters_prop} + \bool_new:c {l__xsim_#1_solution_print_bool} + \bool_new:c {l__xsim_#1_exercise_print_bool} + \bool_new:c {l__xsim_#1_exercise_use_bool} + } + +\cs_new_protected:Npn \xsim_define_counters:n #1 + { + \xsim_verbose:n { Defining~ counters~ for~ new~ exercise~ type~ `#1' } + \cs_if_exist:cF { c@ \xsim_get_parameter:nn {#1} {counter} } + { \newcounter { \xsim_get_parameter:nn {#1} {counter} } } + \cs_if_exist:cF { c@ \xsim_get_parameter:nn {#1} {solution-counter} } + { \newcounter { \xsim_get_parameter:nn {#1} {solution-counter} } } + \cs_if_exist:cF { c@ number of \xsim_get_parameter:nn {#1} {exercise-env} s } + { \newcounter { number of \xsim_get_parameter:nn {#1} {exercise-env} s } } + } + +% #1: type +% #2: id +\cs_new_protected:Npn \xsim_step_exercise_counter:nn #1#2 + { + \refstepcounter { \xsim_get_parameter:nn {#1} {counter} } + \xsim_set_properties:nnx {#1} {#2} + { + counter = \use:c { the \xsim_get_parameter:nn {#1} {counter} } , + counter-value = \arabic { \xsim_get_parameter:nn {#1} {counter} } + } + } +\cs_generate_variant:Nn \xsim_step_exercise_counter:nn {nV} + +% #1: type +\cs_new_protected:Npn \xsim_declare_exercise_type:nn #1#2 + { + \xsim_if_type:nTF {#1} + { \msg_error:nnn {xsim} {type-exists} {#1} } + { + \xsim_verbose:n { Declaring~ new~ exercise~ type~ `#1'. } + \xsim_define_exercise_type_variables:n {#1} + \xsim_add_to_list:nn {types} {#1} + \xsim_set_parameters:nn {#1} {#2} + \xsim_set_parameter:nnx {#1} {number} + { number of \xsim_get_parameter:nn {#1} {exercise-env} s } + \xsim_check_mandatory_parameters:n {#1} + \xsim_if_parameter:nnF {#1} {counter} + { + \xsim_set_parameters:nx {#1} + { counter = \xsim_get_parameter:nn {#1} {exercise-env} } + } + \xsim_if_parameter:nnF {#1} {solution-counter} + { + \xsim_set_parameters:nx {#1} + { solution-counter = \xsim_get_parameter:nn {#1} {solution-env} } + } + \xsim_define_counters:n {#1} + \xsim_verbose:n { Defining~ options~ for~ new~ exercise~ type~ `#1' } + \keys_define:nx {xsim} + { + \xsim_get_parameter:nn {#1} {solution-env} / print + .bool_set:N = \exp_not:c {l__xsim_#1_solution_print_bool} , + \xsim_get_parameter:nn {#1} {solution-env} / print + .initial:n = false , + \xsim_get_parameter:nn {#1} {exercise-env} / print + .bool_set:N = \exp_not:c {l__xsim_#1_exercise_print_bool} , + \xsim_get_parameter:nn {#1} {exercise-env} / print + .initial:n = true , + \xsim_get_parameter:nn {#1} {exercise-env} / use + .bool_set:N = \exp_not:c {l__xsim_#1_exercise_use_bool} , + \xsim_get_parameter:nn {#1} {exercise-env} / use + .initial:n = true , + \xsim_get_parameter:nn {#1} {exercise-env} / within .code:n = + \exp_not:N \@addtoreset { \xsim_get_parameter:nn {#1} {counter} } {####1}, + \xsim_get_parameter:nn {#1} {exercise-env} / the-counter .code:n = + \cs_set:cpn {the \xsim_get_parameter:nn {#1} {counter} } {####1} , + \xsim_get_parameter:nn {#1} {exercise-env} / template + .code:n = \xsim_set_parameter:nnn {#1} {exercise-template} {####1} , + \xsim_get_parameter:nn {#1} {solution-env} / template + .code:n = \xsim_set_parameter:nnn {#1} {solution-template} {####1} , + \xsim_get_parameter:nn {#1} {exercise-env} / name + .code:n = \xsim_set_parameter:nnn {#1} {exercise-name} {####1} , + \xsim_get_parameter:nn {#1} {solution-env} / name + .code:n = \xsim_set_parameter:nnn {#1} {solution-name} {####1} + } + \xsim_new_environment:nn {#1} {exercise} + \xsim_new_environment:nn {#1} {solution} + } + } + +% #1: type +% #2: id +\prg_new_conditional:Npnn \xsim_if_exercise_exists:nn #1#2 {T,F,TF} + { + \__xsim_set_file_signature:nnn {#1} {#2} {exercise} + \file_if_exist:VTF \l__xsim_file_path_and_name_tl + { \prg_return_true: } + { \prg_return_false: } + } +\cs_generate_variant:Nn \xsim_if_exercise_exists:nnT {VV} + +% #1: type +% #2: options +\cs_new_protected:Npn \xsim_start_exercise:nn #1#2 + { + \xsim_if_insert_mode:F + { + \int_gincr:N \g_xsim_id_int + \int_compare:nF { \g_xsim_max_id_int > \g_xsim_id_int } + { \int_gset_eq:NN \g_xsim_max_id_int \g_xsim_id_int } + \xsim_set_properties:nxx {#1} { \int_use:N \g_xsim_id_int } + { + print = true , + use = true , + \exp_not:n {#2} , + id = \int_use:N \g_xsim_id_int , + section-value = \arabic{section} , + section = \thesection , + page-value = \arabic{page} , + page = \thepage , + used = false + } + \xsim_if_property_exist:nT {chapter} + { + \xsim_set_properties:nxx {#1} { \int_use:N \g_xsim_id_int } + { + chapter-value = \arabic{chapter} , + chapter = \thechapter + } + } + \tl_gclear:N \g_xsim_exercise_id_tl + \xsim_gsave_property:nxnN {#1} { \int_use:N \g_xsim_id_int } {id} + \g_xsim_exercise_id_tl + \tl_gset_eq:NN \ExerciseID \g_xsim_exercise_id_tl + \tl_gset:Nn \ExerciseType {#1} + \xsim_verbose:x + { + Starting~ exercise~ type~ `#1' with~ id~ + ` \g_xsim_exercise_id_tl '. + } + \xsim_exercise_if_use:nVTF {#1} \g_xsim_exercise_id_tl + { + \stepcounter { \xsim_get_parameter:nn {#1} {number} } + % don't step if in active collection: + \xsim_if_collections_active:TF + { + \xsim_set_property:nVnn {#1} \g_xsim_exercise_id_tl + {print} + {false} + } + { + \xsim_step_exercise_counter:nV {#1} \g_xsim_exercise_id_tl + \xsim_set_property:nVnn {#1} \g_xsim_exercise_id_tl + {used} + {true} + } + \xsim_set_property:nVnn {#1} \g_xsim_exercise_id_tl + {use} + {true} + \xsim_update_goals:nV {#1} \g_xsim_exercise_id_tl + } + { + \xsim_set_properties:nVn {#1} \g_xsim_exercise_id_tl + { use = false , print = false } + } + \xsim_update_collections:nV {#1} \g_xsim_exercise_id_tl + } + } + +\cs_new_protected:Npn \xsim_stop_exercise:n #1 {} + +% ---------------------------------------------------------------------------- +% #1: type +% #2: id +\prg_new_protected_conditional:Npnn \xsim_exercise_if_print:nn #1#2 {T,F,TF} + { + \xsim_if_boolean_property:nnnTF {#1} {#2} {print!} + { \prg_return_true: } + { + \bool_set_true:N \l____xsim_print_bool + \bool_if:cF {l__xsim_#1_exercise_print_bool} + { \bool_set_false:N \l____xsim_print_bool } + \xsim_if_tagged:nnF {#1} {#2} + { \bool_set_false:N \l____xsim_print_bool } + \xsim_if_boolean_property:nnnF {#1} {#2} {print} + { \bool_set_false:N \l____xsim_print_bool } + \bool_if:NTF \l____xsim_print_bool + { \prg_return_true: } + { \prg_return_false: } + } + } +\cs_generate_variant:Nn \xsim_exercise_if_print:nnT {nV} +\cs_generate_variant:Nn \xsim_exercise_if_print:nnTF {nV} + +% #1: type +% #2: id +\prg_new_protected_conditional:Npnn \xsim_exercise_if_use:nn #1#2 {T,F,TF} + { + \xsim_if_boolean_property:nnnTF {#1} {#2} {use!} + { \prg_return_true: } + { + \xsim_exercise_if_print:nnTF {#1} {#2} + { \prg_return_true: } + { + \bool_if:cTF {l__xsim_#1_exercise_use_bool} + { + \xsim_if_boolean_property:nnnTF {#1} {#2} {use} + { + \xsim_if_tagged:nnTF {#1} {#2} + { \prg_return_true: } + { \prg_return_false: } + } + { \prg_return_false: } + } + { \prg_return_false: } + } + + } + } +\cs_generate_variant:Nn \xsim_exercise_if_use:nnT {nV} +\cs_generate_variant:Nn \xsim_exercise_if_use:nnTF {nV} + +% #1: type +% #2: id +% #3: exercise|solution +\prg_new_protected_conditional:Npnn \xsim_if_print:nnn #1#2#3 {T,F,TF} + { + \use:c {xsim_#3_if_print:nnTF} {#1} {#2} + { \prg_return_true: } + { \prg_return_false: } + } + +% ---------------------------------------------------------------------------- + +\xsim_new_aux_cs:cpn {total-number} #1 + { \int_gset:Nn \g_xsim_max_id_int {#1} } + +\RequirePackage {etoolbox} + +\AtEndPreamble + { + \xsim_foreach_exercise_type:n + { + \tl_new:c { number of #1 s } + \tl_set:cn { number of #1 s } {0} + \xsim_new_aux_cs:cpn {#1} ##1 + { \tl_gset:cn { number of #1 s } {##1} } + } + } + +\AtBeginDocument + { + \xsim_foreach_exercise_type:n + { + \xsim_write_to_aux:x + { \token_to_str:N \providecommand \token_to_str:N \numberof #1 s {} } + } + } + +\AtEndDocument + { + \xsim_if_clear_aux:T + { + \int_compare:nNnF { \g_xsim_max_id_int } = { \g_xsim_id_int } + { \xsim_empty_lists: } + } + \xsim_add_cs_to_aux:nn {total-number} { { \int_use:N \g_xsim_id_int } } + \xsim_foreach_exercise_type:n + { + \xsim_add_cs_to_aux:nn {#1} + { { \arabic { \xsim_get_parameter:nn {#1} {number} } } } + } + \xsim_update_list:n {types} + } + +% ---------------------------------------------------------------------------- +\tex_endinput:D diff --git a/Master/texmf-dist/tex/latex/xsim/xsim.goals.code.tex b/Master/texmf-dist/tex/latex/xsim/xsim.goals.code.tex new file mode 100644 index 00000000000..8a881eb22ad --- /dev/null +++ b/Master/texmf-dist/tex/latex/xsim/xsim.goals.code.tex @@ -0,0 +1,307 @@ +% ---------------------------------------------------------------------------- +% the XSIM package - goals module +% +% eXercise Sheets IMproved +% +% ---------------------------------------------------------------------------- +% Clemens Niederberger +% Web: https://github.com/cgnieder/xsim +% E-Mail: contact@mychemistry.eu +% ---------------------------------------------------------------------------- +% Copyright 2017 Clemens Niederberger +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +% +% This work has the LPPL maintenance status `maintained'. +% +% The Current Maintainer of this work is Clemens Niederberger. +% ---------------------------------------------------------------------------- +% If you have any ideas, questions, suggestions or bugs to report, please +% feel free to contact me. +% ---------------------------------------------------------------------------- +\XSIMmodule{goals}{counting of points and bonus points} + +\xsim_load_modules:n {properties,exercises} + +\msg_new:nnn {xsim} {goal-unknown} + { The~ goal~ `#1'~ has~ never~ been~ declared~ \msg_line_context: } + +\seq_new:N \l__xsim_goals_seq +\tl_new:N \l_xism_grading_table_template_tl +\tl_new:N \l_xism_grading_table_exercise_type_tl + +% #1: name +\cs_new_protected:Npn \xsim_declare_exercise_goal:n #1 + { + \xsim_if_goal_exists:nF {#1} + { + \xsim_verbose:n { Declaring~ new~ goal~ `#1'. } + \xsim_declare_property:nnnn + { \c_false_bool } + { \c_false_bool } + { \c_false_bool } + {#1} + \seq_put_right:Nn \l__xsim_goals_seq {#1} + \fp_gzero_new:c {g__xsim_goal_#1_fp} + \fp_gzero_new:c {l__xsim_current_goal_#1_fp} + \fp_if_exist:cF {g__xsim_total_goal_#1_fp} + { \fp_new:c {g__xsim_total_goal_#1_fp} } + \fp_if_exist:cF {g__xsim_total_goal_recorded_#1_fp} + { \fp_new:c {g__xsim_total_goal_recorded_#1_fp} } + \AtBeginDocument + { + \xsim_foreach_exercise_type:n + { + \fp_gzero_new:c {g__xsim_##1_goal_#1_fp} + \fp_if_exist:cF {g__xsim_total_##1_goal_#1_fp} + { \fp_new:c {g__xsim_total_##1_goal_#1_fp} } + } + } + } + } + +\prg_new_conditional:Npnn \xsim_if_goal_exists:n #1 {p,T,F,TF} + { + \seq_if_in:NnTF \l__xsim_goals_seq {#1} + { \prg_return_true: } + { \prg_return_false: } + } + +% #1: exercise type +% #2: id +% #3: goal +\cs_new_protected:Npn \xsim_update_goal:nnn #1#2#3 + { + \xsim_if_goal_exists:nT {#3} + { + \fp_gadd:cn {g__xsim_goal_#3_fp} + { 0 \xsim_get_property:nnn {#1} {#2} {#3} } + \fp_gadd:cn {g__xsim_#1_goal_#3_fp} + { 0 \xsim_get_property:nnn {#1} {#2} {#3} } + } + } + +% #1: exercise type +% #2: id +\cs_new_protected:Npn \xsim_update_goals:nn #1#2 + { + \xsim_foreach_goal:n + { \xsim_update_goal:nnn {#1} {#2} {##1} } + } +\cs_generate_variant:Nn \xsim_update_goals:nn {nV} + +\cs_new_protected:Npn \xsim_foreach_goal:n #1 + { \seq_map_inline:Nn \l__xsim_goals_seq {#1} } + +% #1: exercise type +% #2: id +% #3: goal +% #4: value +\cs_new_protected:Npn \xsim_addto_goal:nnnn #1#2#3#4 + { + \xsim_if_goal_exists:nT {#3} + { + \xsim_verbose:n { Adding~ `#4'~ to~ `#3'~ goal~ of~ #1~ #2 } + \fp_gadd:cn {g__xsim_goal_#3_fp} {#4} + \fp_gadd:cn {g__xsim_#1_goal_#3_fp} {#4} + \fp_add:cn {l__xsim_current_goal_#3_fp} {#4} + } + } +\cs_generate_variant:Nn \xsim_addto_goal:nnnn {xx,nVnx} + +% #1: exercise type +% #2: id +% #3: goal +% #4: relation and value +\prg_new_conditional:Npnn \xsim_if_goal_value:nnnn #1#2#3#4 {p,T,F,TF} + { + \fp_compare:nTF + { (0 \xsim_get_property:nnn {#1} {#2} {#3}) #4 } + { \prg_return_true: } + { \prg_return_false: } + } +\cs_generate_variant:Nn \xsim_if_goal_value:nnnnTF {xx} + +% ---------------------------------------------------------------------------- +% a function which can be used to modify how the numbers of a goal are +% printed: +\cs_new_protected:Npn \__xsim_print_goal:n #1 {#1} +\cs_generate_variant:Nn \__xsim_print_goal:n {x} + +% #1: value +% #2: value == 1 +% #3: value != 1 +\cs_new_protected:Npn \xsim_print_goal:nnn #1#2#3 + { + \__xsim_print_goal:n { \fp_to_decimal:n {#1} } + \fp_compare:nTF { (#1) = 1 } {#2} {#3} + } + +% #1: exercise type +% #2: goal +% #3: sum == 1 +% #4: sum != 1 +\cs_new_protected:Npn \xsim_print_goal_sum:nnnn #1#2#3#4 + { \xsim_print_goal:nnn { \use:c {g__xsim_total_#1_goal_#2_fp} } {#3} {#4} } + +% #1: goal +% #2: sum == 1 +% #3: sum != 1 +\cs_new_protected:Npn \xsim_print_total_goal_sum:nnn #1#2#3 + { \xsim_print_goal:nnn { \use:c {g__xsim_total_goal_#1_fp} } {#2} {#3} } + +% ---------------------------------------------------------------------------- +% the same as the last to functions but for a list of goals: + +% #1: fp variable to be set +% #2: list of goals (separated with +) +% #3: function to be applied to goal names +\cs_new_protected:Npn \__xsim_exercise_goals_sum_aux:Nnn #1#2#3 + { + \seq_set_split:Nnn \l__xsim_tmpa_seq {+} {#2} + \seq_set_map:NNn \l__xsim_tmpb_seq \l__xsim_tmpa_seq {#3} + \fp_set:Nn #1 { \seq_use:Nn \l__xsim_tmpb_seq {+} } + } + +% #1: fp variable +% #2: exercise type +% #3: list of goals (separated with +) +\cs_new_protected:Npn \__xsim_exercise_goals_sum:Nnn #1#2#3 + { + \__xsim_exercise_goals_sum_aux:Nnn #1 {#3} + { \exp_not:c {g__xsim_total_#2_goal_ \tl_trim_spaces:n {##1} _fp} } + } + +% #1: fp variable +% #2: list of goals (separated with +) +\cs_new_protected:Npn \__xsim_exercise_goals_sum:Nn #1#2 + { + \__xsim_exercise_goals_sum_aux:Nnn #1 {#2} + { \exp_not:c {g__xsim_total_goal_ \tl_trim_spaces:n {##1} _fp} } + } + +% #1: exercise type +% #2: list of goals (separated with +) +% #3: sum == 1 +% #4: sum != 1 +\cs_new_protected:Npn \xsim_print_goals_sum:nnnn #1#2#3#4 + { + \__xsim_exercise_goals_sum:Nnn \l__xsim_tmpa_fp {#1} {#2} + \xsim_print_goal:nnn { \l__xsim_tmpa_fp } {#3} {#4} + } + +% #1: list of goals (separated with +) +% #2: sum == 1 +% #3: sum != 1 +\cs_new_protected:Npn \xsim_print_total_goals_sum:nnn #1#2#3 + { + \__xsim_exercise_goals_sum:Nn \l__xsim_tmpa_fp {#1} + \xsim_print_goal:nnn { \l__xsim_tmpa_fp } {#2} {#3} + } + +% ---------------------------------------------------------------------------- +% #1: exercise type +% #2: goal +% #3: relation and value +\prg_new_conditional:Npnn \xsim_if_goal_sum:nnn #1#2#3 {p,T,F,TF} + { + \fp_compare:nTF + { ( \use:c {g__xsim_total_#1_goal_#2_fp} ) #3 } + { \prg_return_true: } + { \prg_return_false: } + } + +% #1: exercise type +% #2: list of goals (separated with +) +% #3: relation and value +\prg_new_protected_conditional:Npnn \xsim_if_goals_sum:nnn #1#2#3 {T,F,TF} + { + \__xsim_exercise_goals_sum:Nnn \l__xsim_tmpa_fp {#1} {#2} + \fp_compare:nTF + { ( \l__xsim_tmpa_fp ) #3 } + { \prg_return_true: } + { \prg_return_false: } + } + +% #1: goal +% #2: relation and value +\prg_new_conditional:Npnn \xsim_if_total_goal_sum:nn #1#2 {p,T,F,TF} + { + \fp_compare:nTF + { ( \use:c {g__xsim_total_goal_#1_fp} ) #2 } + { \prg_return_true: } + { \prg_return_false: } + } + +% #1: list of goals (separated with +) +% #2: relation and value +\prg_new_protected_conditional:Npnn \xsim_if_total_goals_sum:nn #1#2 {T,F,TF} + { + \__xsim_exercise_goals_sum:Nn \l__xsim_tmpa_fp {#1} + \fp_compare:nTF + { ( \l__xsim_tmpa_fp ) #2 } + { \prg_return_true: } + { \prg_return_false: } + } + +% ---------------------------------------------------------------------------- +% #1: exercise type +% #2: goal +% #3: value +\xsim_new_aux_cs:cpn {goal} #1#2#3 + { \fp_gset:cn {g__xsim_total_#1_goal_#2_fp} {#3} } + +% #1: goal +% #2: value +\xsim_new_aux_cs:cpn {totalgoal} #1#2 + { \fp_gset:cn {g__xsim_total_goal_#1_fp} {#2} } + +\AtBeginDocument + { + \seq_map_inline:Nn \l__xsim_goals_seq + { + \fp_gset_eq:cc + {g__xsim_total_goal_recorded_#1_fp} + {g__xsim_total_goal_#1_fp} + } + } + +\AtEndDocument + { + \seq_map_inline:Nn \l__xsim_goals_seq + { + \xsim_foreach_exercise_type:n + { + \xsim_add_cs_to_aux:nn {goal} + { {##1} {#1} { \fp_to_decimal:c {g__xsim_##1_goal_#1_fp} } } + } + \tl_set:Nx \l__xsim_tmpa_tl + { \fp_to_decimal:c {g__xsim_total_goal_#1_fp} } + \tl_set:Nx \l__xsim_tmpb_tl + { \fp_to_decimal:c {g__xsim_total_goal_recorded_#1_fp} } + \tl_if_eq:NNF \l__xsim_tmpa_tl \l__xsim_tmpb_tl { \xsim_rerun: } + \xsim_add_cs_to_aux:nn {totalgoal} + { {#1} { \fp_to_decimal:c {g__xsim_goal_#1_fp} } } + } + } + +% ---------------------------------------------------------------------------- + +\keys_define:nn {xsim} + { + goal-print .code:n = + \cs_set_protected:Npn \__xsim_print_goal:n ##1 {#1} , + grading-table/template .tl_set:N = \l_xism_grading_table_template_tl , + grading-table/template .initial:n = default , + grading-table/type .tl_set:N = \l_xism_grading_table_exercise_type_tl , + grading-table/type .initial:n = + } + +% ---------------------------------------------------------------------------- +\tex_endinput:D diff --git a/Master/texmf-dist/tex/latex/xsim/xsim.grades.code.tex b/Master/texmf-dist/tex/latex/xsim/xsim.grades.code.tex new file mode 100644 index 00000000000..0fe0d162db5 --- /dev/null +++ b/Master/texmf-dist/tex/latex/xsim/xsim.grades.code.tex @@ -0,0 +1,153 @@ +% ---------------------------------------------------------------------------- +% the XSIM package - grades module +% +% eXercise Sheets IMproved +% +% ---------------------------------------------------------------------------- +% Clemens Niederberger +% Web: https://github.com/cgnieder/xsim +% E-Mail: contact@mychemistry.eu +% ---------------------------------------------------------------------------- +% Copyright 2017 Clemens Niederberger +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +% +% This work has the LPPL maintenance status `maintained'. +% +% The Current Maintainer of this work is Clemens Niederberger. +% ---------------------------------------------------------------------------- +% If you have any ideas, questions, suggestions or bugs to report, please +% feel free to contact me. +% ---------------------------------------------------------------------------- +\XSIMmodule{grades}{distribute goal sums to grades} + +\xsim_load_modules:n {goals} + +\msg_new:nnn {xsim} {grade-unknown} + { The~ grade~ `#1'~ has~ never~ been~ declared~ \msg_line_context: } + +\bool_new:N \l__xsim_grades_half_bool +\fp_new:N \l__xsim_grade_round_fp +\fp_zero:N \l__xsim_grade_round_fp +\prop_new:N \l__xsim_relative_grades_prop +\tl_new:N \l__xsim_grade_split_tl + +\cs_new:Npn \__xsim_fp_round_to_half:n #1 + { round( 2*(#1),0)/2 } + +\cs_new:Npn \__xsim_grades_round:n #1 + { round ( #1 , \l__xsim_grade_round_fp ) } + +% #1: factor +% #2: goal sum +\cs_new:Npn \__xsim_grade_rounded:nn #1#2 + { + \bool_if:NTF \l__xsim_grades_half_bool + { \__xsim_fp_round_to_half:n } + { \__xsim_grades_round:n } + { (#1) * (#2) } + } + +\cs_new_protected:Npn \xsim_declare_relative_grades:n #1 + { + \seq_set_split:NVn \l__xsim_tmpa_seq \l__xsim_grade_split_tl {#1} + \seq_map_inline:Nn \l__xsim_tmpa_seq + { \__xsim_declare_relative_grade:w ##1 \q_stop } + \xsim_verbose:n {Declaring~ relative~ grade~ distribution} + } + +\cs_new_protected:Npn \__xsim_declare_relative_grade:w #1 = #2 \q_stop + { + \tl_set:Nx \l__xsim_tmpa_tl { \tl_trim_spaces:n {#1} } + \tl_set:Nx \l__xsim_tmpb_tl { \tl_trim_spaces:n {#2} } + \prop_put:NVV \l__xsim_relative_grades_prop + \l__xsim_tmpa_tl + \l__xsim_tmpb_tl + } + +% #1: grade +% #2: sum of points +% #3: code after grade requirement if == 1 +% #4: code after grade requirement if != 1 +\cs_new_protected:Npn \xsim_get_grade:nnnn #1#2#3#4 + { + \prop_get:NnNTF \l__xsim_relative_grades_prop {#1} \l__xsim_tmpa_tl + { + \xsim_print_goal:nnn + { + min( + \__xsim_grade_rounded:nn + { \l__xsim_tmpa_tl } + {#2} , + #2 + ) + } + {#3} + {#4} + } + { \msg_error:nnn {xsim} {grade-unknown} {#1} } + } + +% #1: grade +% #2: goal +% #3: code after grade requirement if == 1 +% #4: code after grade requirement if != 1 +\cs_new_protected:Npn \xsim_get_grade_goal:nnnn #1#2#3#4 + { + \xsim_if_goal_exists:nTF {#2} + { + \xsim_get_grade:nnnn + {#1} + { \use:c {g__xsim_total_goal_#2_fp} } + {#3} + {#4} + } + { \msg_error:nnn {xsim} {goal-unknown} {#2} } + } + +% #1: grade +% #2: goal list (separated with +) +% #3: code after grade requirement if == 1 +% #4: code after grade requirement if != 1 +\cs_new_protected:Npn \xsim_get_grade_requirement:nnnn #1#2#3#4 + { + \seq_set_split:Nnn \l__xsim_tmpa_seq {+} {#2} + \fp_zero:N \l__xsim_tmpa_fp + \seq_map_inline:Nn \l__xsim_tmpa_seq + { + \fp_add:Nn \l__xsim_tmpa_fp + { \use:c {g__xsim_total_goal_\tl_trim_spaces:n {##1} _fp} } + } + \xsim_get_grade:nnnn {#1} { \l__xsim_tmpa_fp } {#3} {#4} + } + +% #1: grade +% #2: code after grade requirement if == 1 +% #3: code after grade requirement if != 1 +\cs_new_protected:Npn \xsim_get_absolute_grade_requirement:nnn #1#2#3 + { + \fp_zero:N \l__xsim_tmpa_fp + \xsim_foreach_goal:n + { + \fp_add:Nn \l__xsim_tmpa_fp + { \use:c {g__xsim_total_goal_##1_fp} } + } + \xsim_get_grade:nnnn {#1} { \l__xsim_tmpa_fp } {#2} {#3} + } + +\keys_define:nn {xsim/grades} + { + round .fp_set:N = \l__xsim_grade_round_fp , + half .bool_set:N = \l__xsim_grades_half_bool , + split .tl_set:N = \l__xsim_grade_split_tl , + split .initial:n = {,} + } + +% ---------------------------------------------------------------------------- +\tex_endinput:D diff --git a/Master/texmf-dist/tex/latex/xsim/xsim.interface.code.tex b/Master/texmf-dist/tex/latex/xsim/xsim.interface.code.tex new file mode 100644 index 00000000000..b1006f49356 --- /dev/null +++ b/Master/texmf-dist/tex/latex/xsim/xsim.interface.code.tex @@ -0,0 +1,565 @@ +% ---------------------------------------------------------------------------- +% the XSIM package - interface module +% +% eXercise Sheets IMproved +% +% ---------------------------------------------------------------------------- +% Clemens Niederberger +% Web: https://github.com/cgnieder/xsim +% E-Mail: contact@mychemistry.eu +% ---------------------------------------------------------------------------- +% Copyright 2017 Clemens Niederberger +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +% +% This work has the LPPL maintenance status `maintained'. +% +% The Current Maintainer of this work is Clemens Niederberger. +% ---------------------------------------------------------------------------- +% If you have any ideas, questions, suggestions or bugs to report, please +% feel free to contact me. +% ---------------------------------------------------------------------------- +\XSIMmodule{interface}{user interface} + +\NewDocumentCommand \DeclareExerciseEnvironmentTemplate {m+m+m} + { \xsim_declare_environment_template:nnn {#1} {#2} {#3} } +\@onlypreamble \DeclareExerciseEnvironmentTemplate + +\NewDocumentCommand \DeclareExerciseHeadingTemplate {m+m} + { \xsim_declare_heading_template:nn {#1} {#2} } +\@onlypreamble \DeclareExerciseHeadingTemplate + +\NewDocumentCommand \DeclareExerciseTableTemplate {m+m} + { \xsim_declare_table_template:nn {#1} {#2} } +\@onlypreamble \DeclareExerciseTableTemplate + +\NewDocumentCommand \UseExerciseTemplate {mm} + { \xsim_use_template:nn {#1} {#2} } + +% ---------------------------------------------------------------------------- + +\NewDocumentCommand \DeclareExerciseType {mm} + { \xsim_declare_exercise_type:nn {#1} {#2} } +\@onlypreamble \DeclareExerciseType + +\NewExpandableDocumentCommand \numberofusedexercises {} + { \int_use:N \g_xsim_max_id_int } + +% ---------------------------------------------------------------------------- + +\NewExpandableDocumentCommand \IfInsideSolutionTF {+m+m} + { \xsim_if_inside_solution:TF {#1} {#2} } + +\NewExpandableDocumentCommand \IfInsideSolutionT {+m} + { \IfInsideSolutionTF {#1} {} } + +\NewExpandableDocumentCommand \IfInsideSolutionF {+m} + { \IfInsideSolutionTF {} {#1} } + +\NewExpandableDocumentCommand \IfSolutionPrintTF {+m+m} + { \xsim_if_solution_print:nTF {\ExerciseType} {#1} {#2} } + +\NewExpandableDocumentCommand \IfSolutionPrintT {+m} + { \IfSolutionPrintTF {#1} {} } + +\NewExpandableDocumentCommand \IfSolutionPrintF {+m} + { \IfSolutionPrintTF {} {#1} } + +% ---------------------------------------------------------------------------- + +\NewDocumentCommand \DeclareExerciseProperty {t!st-m} + { + \IfBooleanTF {#2} + { + \IfBooleanTF {#3} + { + \xsim_declare_property:nnnn + { \c_false_bool } + { \c_true_bool } + { \c_true_bool } + {#4} + } + { + \xsim_declare_property:nnnn + { \c_false_bool } + { \c_true_bool } + { \c_false_bool } + {#4} + } + } + { + \IfBooleanTF {#1} + { + \IfBooleanTF {#3} + { + \xsim_declare_property:nnnn + { \c_true_bool } + { \c_false_bool } + { \c_true_bool } + {#4} + } + { + \xsim_declare_property:nnnn + { \c_true_bool } + { \c_false_bool } + { \c_false_bool } + {#4} + } + } + { + \IfBooleanTF {#3} + { + \xsim_declare_property:nnnn + { \c_false_bool } + { \c_false_bool } + { \c_true_bool } + {#4} + } + { + \xsim_declare_property:nnnn + { \c_false_bool } + { \c_false_bool } + { \c_false_bool } + {#4} + } + } + } + } +\@onlypreamble \DeclareExerciseProperty + +\NewDocumentCommand \DeclareExercisePropertyAlias {mm} + { \xsim_make_property_alias:nn {#1} {#2} } +\@onlypreamble \DeclareExercisePropertyAlias + +\NewDocumentCommand \SetExerciseProperty {mmm+m} + { \xsim_set_property:nnnn {#1} {#2} {#3} {#4} } + +\NewExpandableDocumentCommand \IfExercisePropertyExistTF {+m+m+m} + { \xsim_if_property_exist:nTF {#1} {#2} {#3} } + +\NewExpandableDocumentCommand \IfExercisePropertyExistT {+m+m} + { \IfExercisePropertyExistTF {#1} {#2} {} } + +\NewExpandableDocumentCommand \IfExercisePropertyExistF {+m+m} + { \IfExercisePropertyExistTF {#1} {} {#2} } + +\NewDocumentCommand \IfExercisePropertySetTF {m+m+m} + { \xsim_if_property_set:xxnTF {\ExerciseType} {\ExerciseID} {#1} {#2} {#3} } + +\NewDocumentCommand \IfExercisePropertySetT {m+m} + { \IfExercisePropertySetTF {#1} {#2} {} } + +\NewDocumentCommand \IfExercisePropertySetF {m+m} + { \IfExercisePropertySetTF {#1} {} {#2} } + +\NewExpandableDocumentCommand \GetExerciseProperty {m} + { \xsim_get_property:oon {\ExerciseType} {\ExerciseID} {#1} } + +\NewExpandableDocumentCommand \GetExerciseAliasProperty {m} + { + \xsim_get_property:oof + {\ExerciseType} + {\ExerciseID} + { \xsim_property_alias:n {#1} } + } + +\NewDocumentCommand \GetExercisePropertyTF {m+m+m} + { + \xsim_get_property_if_set:oonTF {\ExerciseType} {\ExerciseID} {#1} + {#2} + {#3} + } + +\NewDocumentCommand \GetExercisePropertyT {m+m} + { \GetExercisePropertyTF {#1} {#2} {} } +\NewDocumentCommand \GetExercisePropertyF {m+m+m} + { \GetExercisePropertyTF {#1} {} {#2} } + +\NewExpandableDocumentCommand \GetExerciseIdForProperty {mm} + { \xsim_get_id_for_property:nn {#1} {#2} } + +\NewExpandableDocumentCommand \GetExerciseTypeForProperty {mm} + { \xsim_get_type_for_property:nn {#1} {#2} } + +\NewExpandableDocumentCommand \IfExerciseBooleanPropertyTF {+m+m+m} + { + \xsim_if_boolean_property:oonTF {\ExerciseType} {\ExerciseID} {#1} + {#2} + {#3} + } + +\NewExpandableDocumentCommand \IfExerciseBooleanPropertyT {+m+m} + { \IfExerciseBooleanPropertyTF {#1} {#2} {} } +\NewExpandableDocumentCommand \IfExerciseBooleanPropertyF {+m+m} + { \IfExerciseBooleanPropertyTF {#1} {} {#2} } + +\NewDocumentCommand \SaveExerciseProperty {mm} + { \xsim_save_property:xxnN {\ExerciseType} {\ExerciseID} {#1} #2 } + +\NewDocumentCommand \GlobalSaveExerciseProperty {mm} + { \xsim_gsave_property:xxnN {\ExerciseType} {\ExerciseID} {#1} #2 } + +% ---------------------------------------------------------------------------- + +\NewDocumentCommand \DeclareExerciseParameter {st!m} + { + \IfBooleanTF {#1} + { + \IfBooleanTF {#2} + { \xsim_declare_parameter:nnn {true} {true} {#3} } + { \xsim_declare_parameter:nnn {true} {false} {#3} } + } + { + \IfBooleanTF {#2} + { \xsim_declare_parameter:nnn {false} {true} {#3} } + { \xsim_declare_parameter:nnn {false} {false} {#3} } + } + } + +\NewExpandableDocumentCommand \GetExerciseParameter {m} + { \xsim_get_parameter:on {\ExerciseType} {#1} } + +\NewDocumentCommand \SetExerciseParameter {mmm} + { \xsim_set_parameter:nnn {#1} {#2} {#3} } + +\NewDocumentCommand \SetExerciseParameters {mm} + { \xsim_set_parameters:nn {#1} {#2} } + +\NewExpandableDocumentCommand \GetExerciseName {} + { + \IfInsideSolutionTF + { \GetExerciseParameter {solution-name} } + { \GetExerciseParameter {exercise-name} } + } + +% ---------------------------------------------------------------------------- + +\NewDocumentCommand \ExercisePropertyIfSetTF {mmm+m+m} + { \xsim_if_property_set:nnnTF {#1} {#2} {#3} {#4} {#5} } + +\NewDocumentCommand \ExercisePropertyIfSetT {mmm+m} + { \ExercisePropertyIfSetTF {#1} {#2} {#3} {#4} {} } + +\NewDocumentCommand \ExercisePropertyIfSetF {mmm+m} + { \ExercisePropertyIfSetTF {#1} {#2} {#3} {} {#4} } + +\NewExpandableDocumentCommand \ExercisePropertyGet {mmm} + { \xsim_get_property:nnn {#1} {#2} {#3} } + +\NewExpandableDocumentCommand \ExercisePropertyGetAlias {mm} + { \xsim_get_property:nnf {#1} {#2} { \xsim_property_alias:n {#1} } } + +\NewDocumentCommand \ExercisePropertySave {mmmm} + { \xsim_save_property:nnnN {#1} {#2} {#3} #4 } + +\NewDocumentCommand \ExercisePropertyGlobalSave {mmmm} + { \xsim_gsave_property:nnnN {#1} {#2} {#3} #4 } + +\NewExpandableDocumentCommand \ExerciseParameterGet {mm} + { \xsim_get_parameter:nn {#1} {#2} } + +% ---------------------------------------------------------------------------- + +\NewExpandableDocumentCommand \XSIMtranslate {m} + { \xsim_translate:n {#1} } + +\NewDocumentCommand \XSIMexpandcode {+m} + { \use:x {#1} } + +\NewExpandableDocumentCommand \XSIMmixedcase {m} + { \tl_mixed_case:f {#1} } + +\NewDocumentCommand \XSIMputright {mm} + { \tl_put_right:Nn #1 {#2} } + +\NewExpandableDocumentCommand \XSIMifeqTF {+m+m+m+m} + { \tl_if_eq:ffTF {#1} {#2} {#3} {#4} } + +\NewExpandableDocumentCommand \XSIMifeqT {+m+m+m} + { \XSIMifeqTF {#1} {#2} {#3} {} } + +\NewExpandableDocumentCommand \XSIMifeqF {+m+m+m} + { \XSIMifeqTF {#1} {#2} {} {#3} } + +\NewExpandableDocumentCommand \XSIMifblankTF {+m+m+m} + { \tl_if_blank:fTF {#1} {#2} {#3} } + +\NewExpandableDocumentCommand \XSIMifblankT {+m+m} + { \XSIMifblankTF {#1} {#2} {} } + +\NewExpandableDocumentCommand \XSIMifblankF {+m+m} + { \XSIMifblankTF {#1} {} {#2} {} } + +% ---------------------------------------------------------------------------- + +\NewDocumentCommand \DeclareExerciseGoal {m} + { \xsim_declare_exercise_goal:n {#1} } +\@onlypreamble \DeclareExerciseGoal + +\NewDocumentCommand \IfExerciseGoalTF {mm+m+m} + { + \xsim_if_goal_value:xxnnTF + {\ExerciseType} {\ExerciseID} {#1} + {#2} + {#3} {#4} + } + +\NewDocumentCommand \IfExerciseGoalT {mm+m} + { \IfExerciseGoalTF {#1} {#2} {#3} {} } + +\NewDocumentCommand \IfExerciseGoalF {mm+m} + { \IfExerciseGoalTF {#1} {#2} {} {#3} } + +\NewDocumentCommand \IfExerciseGoalSingularTF {mmm} + { \IfExerciseGoalTF {#1} {=1} {#2} {#3} } + +\NewDocumentCommand \IfExerciseGoalSingularT {mm} + { \IfExerciseGoalT {#1} {=1} {#2} } + +\NewDocumentCommand \IfExerciseGoalSingularF {mm} + { \IfExerciseGoalF {#1} {=1} {#2} } + +\NewDocumentCommand \IfExerciseTypeGoalsSumTF {mmm+m+m} + { \xsim_if_goals_sum:nnnTF {#1} {#2} {#3} {#4} {#5} } + +\NewDocumentCommand \IfExerciseTypeGoalsSumT {mmm+m} + { \IfExerciseTypeGoalsSumTF {#1} {#2} {#3} {#4} {} } + +\NewDocumentCommand \IfExerciseTypeGoalsSumF {mmm+m} + { \IfExerciseTypeGoalsSumTF {#1} {#2} {#3} {} {#4} } + +\NewDocumentCommand \IfExerciseGoalsSumTF {mm+m+m} + { \xsim_if_total_goals_sum:nnTF {#1} {#2} {#3} {#4} } + +\NewDocumentCommand \IfExerciseGoalsSumT {mm+m} + { \IfExerciseGoalsSumTF {#1} {#2} {#3} {} } + +\NewDocumentCommand \IfExerciseGoalsSumF {mm+m} + { \IfExerciseGoalsSumTF {#1} {#2} {} {#3} } + +\NewDocumentCommand \TotalExerciseTypeGoal {mmmm} + { \xsim_print_goal_sum:nnnn {#1} {#2} {#3} {#4} } + +\NewDocumentCommand \TotalExerciseTypeGoals {mmmm} + { \xsim_print_goals_sum:nnnn {#1} {#2} {#3} {#4} } + +\NewDocumentCommand \TotalExerciseGoal {mmm} + { \xsim_print_total_goal_sum:nnn {#1} {#2} {#3} } + +\NewDocumentCommand \TotalExerciseGoals {mmm} + { \xsim_print_total_goals_sum:nnn {#1} {#2} {#3} } + +\NewDocumentCommand \AddtoExerciseTypeGoal {mmmm} + { \xsim_addto_goal:nnnn {#1} {#2} {#3} {#4} } + +\NewDocumentCommand \AddtoExerciseGoal {mm} + { \xsim_addto_goal:xxnn {\ExerciseType} {\ExerciseID} {#1} {#2} } + +\NewDocumentCommand \ExerciseGoalValuePrint {mmm} + { \xsim_print_goal:nnn {#1} {#2} {#3} } + +\NewDocumentCommand \AddtoExerciseTypeGoalPrint {mmmmmm} + { + \xsim_addto_goal:nnnn {#1} {#2} {#3} {#4} + \xsim_print_goal:nnn {#4} {#5} {#6} + } + +\NewDocumentCommand \AddtoExerciseGoalPrint {mmmm} + { + \xsim_addto_goal:xxnn {\ExerciseType} {\ExerciseID} {#1} {#2} + \xsim_print_goal:nnn {#2} {#3} {#4} + } + +% ---------------------------------------------------------------------------- +\NewDocumentCommand \DeclareGradeDistribution {m} + { \xsim_declare_relative_grades:n {#1} } + +\NewDocumentCommand \GetGradeRequirementForGoal {mmmm} + { \xsim_get_grade_goal:nnnn {#1} {#2} {#3} {#4} } + +\NewDocumentCommand \GetGradeRequirementForGoals {mmmm} + { \xsim_get_grade_requirement:nnnn {#1} {#2} {#3} {#4} } + +\NewDocumentCommand \GetGradeRequirement {mmm} + { \xsim_get_absolute_grade_requirement:nnn {#1} {#2} {#3} } + +% ---------------------------------------------------------------------------- + +\NewDocumentCommand \DeclareExerciseTagging {m} + { \xsim_new_tag_type:n {#1} } +\@onlypreamble \DeclareExerciseTagging + +\NewDocumentCommand \ForEachExerciseTag {m+m} + { \xsim_foreach_exercise_tag:oonn {\ExerciseType} {\ExerciseID} {#1} {#2} } + +\NewDocumentCommand \ListExerciseTags {mm} + { \xsim_exercise_tags_use:oonn {\ExerciseType} {\ExerciseID} {#1} {#2} } + +\NewDocumentCommand \UseExerciseTags {mmmm} + { + \xsim_exercise_tags_use:oonnnn + {\ExerciseType} + {\ExerciseID} + {#1} + {#2} + {#3} + {#4} + } + +% ---------------------------------------------------------------------------- + +\NewDocumentCommand \ForEachPrintedExerciseByType {+m} + { \xsim_foreach_exercise_type_id:nn {print} {#1} } + +\NewDocumentCommand \ForEachPrintedExerciseByID {+m} + { \xsim_foreach_exercise_id_type:nn {print} {#1} } + +\NewDocumentCommand \ForEachUsedExerciseByType {+m} + { \xsim_foreach_exercise_type_id:nn {use} {#1} } + +\NewDocumentCommand \ForEachUsedExerciseByID {+m} + { \xsim_foreach_exercise_id_type:nn {use} {#1} } + +% ---------------------------------------------------------------------------- + +\NewDocumentCommand \DeclareExerciseTranslations {mm} + { \xsim_declare_translations:nn {#1} {#2} } +\@onlypreamble \DeclareExerciseTranslations + +\NewDocumentCommand \DeclareExerciseTranslation {mmm} + { \xsim_declare_translation:nnn {#1} {#2} {#3} } +\@onlypreamble \DeclareExerciseTranslation + +\NewDocumentCommand \ForEachExerciseTranslation {+m} + { \xsim_for_all_translations_do:n {#1} } + +% ---------------------------------------------------------------------------- + +\NewDocumentCommand \DeclareExerciseCollection {m} + { \xsim_new_collection:n {#1} } +\@onlypreamble \DeclareExerciseCollection + +\NewDocumentCommand \collectexercisestype {mm} + { \xsim_start_collection:nn {#1} {#2} } + +\NewDocumentCommand \collectexercises {m} + { \xsim_start_collection:n {#1} } + +\NewDocumentCommand \collectexercisesstop {m} + { \xsim_stop_collection:n {#1} } + +\NewDocumentCommand \printcollection {O{}m} + { \xsim_print_collection:nn {#1} {#2} } + +\NewDocumentCommand \printrandomexercises {O{}m} + { + \group_begin: + \keys_set:nn {xsim/random} {#1} + \xsim_print_random_list:VnV + \l_xsim_random_collection_tl + {#2} + \l_xsim_random_exclude_list_tl + \group_end: + } + +% ---------------------------------------------------------------------------- + +\NewDocumentCommand \blank {som} + { + \group_begin: + \IfNoValueF {#2} { \keys_set:nn {xsim/blank} {#2} } + \mode_if_vertical:TF + { + \IfBooleanTF {#1} + { \xsim_blank:n {#3} } + { + \bool_if:NT \l__xsim_blank_linespread_bool + { \linespread { \l__xsim_blank_linespread_tl } \selectfont } + \noindent \null \xsim_blank:n {#3} \par + } + } + { \xsim_blank:n {#3} } + \group_end: + } + +\NewDocumentCommand \examspace { sm } + { + \IfBooleanTF {#1} + { \xsim_examspace:nn { \c_true_bool } {#2} } + { \xsim_examspace:nn { \c_false_bool } {#2} } + } + +% ---------------------------------------------------------------------------- + +\NewDocumentCommand \gradingtable {O{}} + { + \group_begin: + \keys_set:nn {xsim/grading-table} { template = default , type = , #1} + \xsim_setup_template:nnV {table} \l_xism_grading_table_template_tl + { + \providecommand* \ExerciseTableCode {} + \providecommand* \ExerciseTableType [1] {} + \providecommand* \ExerciseType {} + \tl_set_eq:NN \ExerciseType \l_xism_grading_table_exercise_type_tl + \renewcommand* \ExerciseTableCode {} + \renewcommand* \ExerciseTableType [1] + { \XSIMifblankTF { \ExerciseType } {##1} { \ExerciseType } } + } + \xsim_use_template:nV {table} \l_xism_grading_table_template_tl + \group_end: + } + +% ---------------------------------------------------------------------------- + +\NewDocumentCommand \printsolution {O{}mm} + { \xsim_insert:nnnn {#2} {#3} {#1} {solution} } + +\NewDocumentCommand \printexercise {O{}mm} + { \xsim_insert:nnnn {#2} {#3} {#1} {exercise} } + +% ---------------------------------------------------------------------------- + +\NewDocumentCommand \printsolutionstype {sO{}m} + { + \IfBooleanTF {#1} + { \xsim_print_type_solutions:nnn { \c_true_bool } {#2} {#3} } + { \xsim_print_type_solutions:nnn { \c_false_bool } {#2} {#3} } + } + +\NewDocumentCommand \printsolutions {sO{}} + { + \IfBooleanTF {#1} + { \xsim_print_all_solutions_per_type:nn { \c_true_bool } {#2} } + { \xsim_print_all_solutions_per_type:nn { \c_false_bool } {#2} } + } + +\NewDocumentCommand \printallsolutions {sO{}} + { + \IfBooleanTF {#1} + { \xsim_print_all_solutions_per_id:nn { \c_true_bool } {#2} } + { \xsim_print_all_solutions_per_id:nn { \c_false_bool } {#2} } + } + +% ---------------------------------------------------------------------------- + +\NewDocumentCommand \xsimsetup {m} + { \xsim_setup:n {#1} } + +% ---------------------------------------------------------------------------- +\NewExpandableDocumentCommand \XSIMifchapterTF {+m+m} + { \xsim_if_chapter:TF {#1} {#2} } + +\NewExpandableDocumentCommand \XSIMifchapterT {+m} + { \xsim_if_chapter:T {#1} } + +\NewExpandableDocumentCommand \XSIMifchapterF {+m} + { \xsim_if_chapter:F {#1} } + +% ---------------------------------------------------------------------------- +\tex_endinput:D diff --git a/Master/texmf-dist/tex/latex/xsim/xsim.modules.code.tex b/Master/texmf-dist/tex/latex/xsim/xsim.modules.code.tex new file mode 100644 index 00000000000..1e5d7d5cfa1 --- /dev/null +++ b/Master/texmf-dist/tex/latex/xsim/xsim.modules.code.tex @@ -0,0 +1,211 @@ +% ---------------------------------------------------------------------------- +% the XSIM package - modules module +% +% eXercise Sheets IMproved +% +% ---------------------------------------------------------------------------- +% Clemens Niederberger +% Web: https://github.com/cgnieder/xsim +% E-Mail: contact@mychemistry.eu +% ---------------------------------------------------------------------------- +% Copyright 2017 Clemens Niederberger +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +% +% This work has the LPPL maintenance status `maintained'. +% +% The Current Maintainer of this work is Clemens Niederberger. +% ---------------------------------------------------------------------------- +% If you have any ideas, questions, suggestions or bugs to report, please +% feel free to contact me. +% ---------------------------------------------------------------------------- +% +% this is a pseudo module as it does the actual definitions for the whole +% module loading stuff; we do this so both packages `xsimverb' and `xsim' can +% use the `verbwrite' module +\RequirePackage{scrlfile} +\ExplSyntaxOn + +\msg_new:nnn {xsim} {module-missing} + { + You've~ requested~ the~ xsim~ module~ `#1'~ but~ it~ appears~ to~ + be~ missing~ on~ your~ system.~ Maybe~ you've~ misspelled~ the~ name?~ + Loading~ the~ module~ will~ abort~ \msg_line_context: + } + +\msg_new:nnn {xsim} {loading-module} + { Loading~ module~ `#1'~ ... } + +\msg_new:nnn {xsim} {wrong-module-name} + { The~ module~ file~ name~ is~ `#2'~ but~ it~ provides~ module~ `#1'. } + +\msg_new:nnn {xsim} {forbidden-module} + { + You've~ requested~ the~ xsim~ module~ `modules'~ \msg_line_context: .~ + This~ module~ is~ a~ pseudo~ module~ which~ may~ not~ be~ loaded~ through~ + the~ module~ loading~ mechansim. + } + +% ---------------------------------------------------------------------------- + +\tl_const:Nn \c__xsim_module_extension_tl {code.tex} +\tl_const:Nn \c__xsim_module_prefix_tl {xsim} + +\seq_new:N \g__xsim_loaded_modules_seq +\prop_new:N \g__xsim_loaded_modules_prop + +\cs_new_protected:Npn \xsim_load_modules:n #1 + { \clist_map_inline:nn {#1} { \xsim_load_module:n {##1} } } + +\cs_new_protected:Npn \xsim_load_module:n #1 + { + \tl_set:Nx \l_tmpa_tl { \tl_trim_spaces:n {#1} } + \str_if_eq_x:nnTF { \l_tmpa_tl } {modules} + { \msg_error:nn {xsim} {forbidden-module} } + { \__xsim_load_module:V \l_tmpa_tl } + } + +\cs_new_protected:Npn \__xsim_load_module:n #1 + { + \xsim_if_module_loaded:nF {#1} + { + \xsim_if_module_exist:nTF {#1} + { + \__xsim_use_module_hook:nn {#1} {before} + \msg_info:nnn {xsim} {loading-module} {#1} + \@onefilewithoptions + {\c__xsim_module_prefix_tl.#1}[][] + \c__xsim_module_extension_tl + \__xsim_use_module_hook:nn {#1} {after} + } + { \msg_error:nnn {xsim} {module-missing} {#1} } + } + } +\cs_generate_variant:Nn \__xsim_load_module:n { V } + +\prg_new_conditional:Npnn \xsim_if_module_loaded:n #1 {p,T,F,TF} + { + \seq_if_in:NnTF \g__xsim_loaded_modules_seq {#1} + { \prg_return_true: } + { \prg_return_false: } + } + +\prg_new_conditional:Npnn \xsim_if_module_exist:n #1 {p,T,F,TF} + { + \file_if_exist:nTF + {\c__xsim_module_prefix_tl.#1.\c__xsim_module_extension_tl} + { \prg_return_true: } + { \prg_return_false: } + } + +% -------------------------------------------------------------------------- +% module hooks: +% #1: module +% #2: code +\cs_new_protected:Npn \xsim_after_module:nn #1#2 + { + \xsim_if_module_loaded:nTF {#1} + {#2} + { \__xsim_add_to_module_hook:nnn {#1} {after} {#2} } + } + +% #1: module +% #2: code +\cs_new_protected:Npn \xsim_before_module:nn #1#2 + { + \xsim_if_module_loaded:nF {#1} + { \__xsim_add_to_module_hook:nnn {#1} {before} {#2} } + } + +% #1: module +% #2: hook name +% #3: code +\cs_new_protected:Npn \__xsim_add_to_module_hook:nnn #1#2#3 + { + \xsim_if_module_loaded:nF {#1} + { + \tl_if_exist:cF {g__xsim_module_#1_#2_hook_tl} + { \tl_new:c {g__xsim_module_#1_#2_hook_tl} } + \tl_gput_right:cn {g__xsim_module_#1_#2_hook_tl} {#3} + } + } + +% #1: module +% #2: hook name +\cs_new_protected:Npn \__xsim_use_module_hook:nn #1#2 + { + \tl_if_exist:cT {g__xsim_module_#1_#2_hook_tl} + { + \tl_use:c {g__xsim_module_#1_#2_hook_tl} + \tl_gclear:c {g__xsim_module_#1_#2_hook_tl} + } + } + +% -------------------------------------------------------------------------- + +\tl_new:N \l__xsim_module_date_tl +\tl_new:N \l__xsim_module_version_tl + +\tl_if_exist:NF \c_xsim_date_tl + { \tl_set:Nx \l__xsim_module_date_tl {\c_xsimverb_date_tl} } +\tl_if_exist:NF \c_xsim_version_tl + { \tl_set:Nx \l__xsim_module_version_tl {\c_xsimverb_version_tl} } + +\AfterPackage*{xsim} + { + \tl_set:Nx \l__xsim_module_date_tl {\c_xsim_date_tl} + \tl_set:Nx \l__xsim_module_version_tl {\c_xsim_version_tl} + } + +\cs_new_protected:Npn \__xsim_module:nn #1#2 + { + \seq_gput_right:Nn \g__xsim_loaded_modules_seq {#1} + \prop_gput:Nnn \g__xsim_loaded_modules_prop {#1} {#2} + \str_if_eq_x:nnF + {\c__xsim_module_prefix_tl.#1.\c__xsim_module_extension_tl} + {\@currname.\@currext} + { + \msg_error:nnnxx {xsim} {wrong-module-name} + {#1} + {\@currname.\@currext} + } + \ProvidesFile + {\c__xsim_module_prefix_tl.#1.\c__xsim_module_extension_tl} + [ + \l__xsim_module_date_tl + \c_space_tl + v \l__xsim_module_version_tl + \c_space_tl + xsim~ module~ `#1'~ (#2) + ] + } +\cs_generate_variant:Nn \msg_error:nnnn {nnnx} + +% -------------------------------------------------------------------------- +% define a xsim module: +% #1: name +% #2: description +\NewDocumentCommand \XSIMmodule {mm} { \__xsim_module:nn {#1} {#2} +\ExplSyntaxOn } + +% -------------------------------------------------------------------------- +% style files +\NewDocumentCommand \xsimstyle {sm} + { + \__xsim_module:nn {#2} {} + \IfBooleanF {#1} { \ExplSyntaxOn } + } + +\cs_new_protected:Npn \xsim_style_options:nn #1#2 + { \keys_define:nn {xsim/#1} {#2} } + +\NewDocumentCommand \loadxsimstyle {m} { \xsim_load_module:n {#1} } + +% -------------------------------------------------------------------------- +\tex_endinput:D diff --git a/Master/texmf-dist/tex/latex/xsim/xsim.properties.code.tex b/Master/texmf-dist/tex/latex/xsim/xsim.properties.code.tex new file mode 100644 index 00000000000..ec88d1be00a --- /dev/null +++ b/Master/texmf-dist/tex/latex/xsim/xsim.properties.code.tex @@ -0,0 +1,495 @@ +% ---------------------------------------------------------------------------- +% the XSIM package - properties module +% +% eXercise Sheets IMproved +% +% ---------------------------------------------------------------------------- +% Clemens Niederberger +% Web: https://github.com/cgnieder/xsim +% E-Mail: contact@mychemistry.eu +% ---------------------------------------------------------------------------- +% Copyright 2017 Clemens Niederberger +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +% +% This work has the LPPL maintenance status `maintained'. +% +% The Current Maintainer of this work is Clemens Niederberger. +% ---------------------------------------------------------------------------- +% If you have any ideas, questions, suggestions or bugs to report, please +% feel free to contact me. +% ---------------------------------------------------------------------------- +\XSIMmodule{properties}{properties of exercises} + +\xsim_load_modules:n {base,auxfile} + +\msg_new:nnn {xsim} {unknown-property} + { + You~ tried~ to~ set~ the~ property~ `#1'~ \msg_line_context: . \\ + This~ property~ does~ not~ exist.~ Check~ for~ a~ typo~ or~ \\ + define~ the~ property~ yourself. + } + +\msg_new:nnn {xsim} {property-unique} + { + You~ tried~ to~ set~ the~ property~ `#1'~ \msg_line_context: . \\ + This~ property~ has~ to~ have~ a~ unique~ value~ and~ thus~ \\ + cannot~ be~ set~ to~ `#2'~ since~ this~ value~ is~ already~ talen. + } + +\msg_new:nnn {xsim} {no-boolean-property} + { + You~ tried~ to~ check~ the~ boolean~ value~ of~ property~ `#1'~ + \msg_line_context: . \\ + However,~ property~ `#1'~ is~ not~ a~ boolean~ property! + } + +\seq_new:N \l__xsim_properties_seq +\seq_new:N \l__xsim_boolean_properties_seq +\seq_new:N \l__xsim_unique_properties_seq +\seq_new:N \l__xsim_noupdate_properties_seq +\prop_new:N \g__xsim_properties_prop + +% new property: +% #1: boolean if unique +% #2: boolean if boolean +% #3: boolean if noupdate +% #4: property name +\cs_new_protected:Npn \xsim_declare_property:nnnn #1#2#3#4 + { + \xsim_if_property_exist:nF {#4} + { + \seq_put_right:Nn \l__xsim_properties_seq {#4} + \bool_if:nTF {#3} + { + \seq_if_in:NnF \l__xsim_noupdate_properties_seq {#4} + { \seq_put_right:Nn \l__xsim_noupdate_properties_seq {#4} } + } + { \xsim_new_list:n {#4} } + \bool_if:nTF {#2} + { + \xsim_verbose:n + { Declaring~ new~ boolean~ exercise~ property~ `#4'. } + \seq_if_in:NnF \l__xsim_boolean_properties_seq {#4} + { \seq_put_right:Nn \l__xsim_boolean_properties_seq {#4} } + } + { + \bool_if:nTF {#1} + { + \xsim_verbose:n + { Declaring~ new~ unique~ exercise~ property~ `#4'. } + \seq_if_in:NnF \l__xsim_unique_properties_seq {#4} + { \seq_put_right:Nn \l__xsim_unique_properties_seq {#4} } + \seq_new:c {l__xsim_unique_property_#4_values_seq} + \prop_new:c {g__xsim_property_#4_type_prop} + \prop_new:c {g__xsim_property_#4_id_prop} + } + { \xsim_verbose:n { Declaring~ new~ exercise~ property~ `#4'. } } + } + \bool_if:nF {#3} + { + \AtEndDocument { \xsim_update_list:n {#4} } + \AtBeginDocument { \__xsim_set_property_from_list:n {#4} } + } + } + } + +% check if property exists: +\prg_new_conditional:Npnn \xsim_if_property_exist:n #1 {p,T,F,TF} + { + \seq_if_in:NnTF \l__xsim_properties_seq {#1} + { \prg_return_true: } + { \prg_return_false: } + } +\cs_generate_variant:Nn \xsim_if_property_exist:nTF {x} + +\prg_new_conditional:Npnn \xsim_if_property_noupdate:n #1 {p,T,F,TF} + { + \seq_if_in:NnTF \l__xsim_noupdate_properties_seq {#1} + { \prg_return_true: } + { \prg_return_false: } + } +\cs_generate_variant:Nn \xsim_if_property_noupdate:nF {V} + +\prg_new_conditional:Npnn \xsim_if_property_boolean:n #1 {p,T,F,TF} + { + \seq_if_in:NnTF \l__xsim_boolean_properties_seq {#1} + { \prg_return_true: } + { \prg_return_false: } + } + +\prg_new_conditional:Npnn \xsim_if_property_unique:n #1 {p,T,F,TF} + { + \seq_if_in:NnTF \l__xsim_unique_properties_seq {#1} + { \prg_return_true: } + { \prg_return_false: } + } + +% #1: property +% #2: value +\prg_new_conditional:Npnn \xsim_if_property_unique_value:nn #1#2 {p,T,F,TF} + { + \xsim_if_property_unique:nTF {#1} + { + \seq_if_in:cnTF {l__xsim_unique_property_#1_values_seq} {#2} + { \prg_return_true: } + { \prg_return_false: } + } + { \prg_return_false: } + } + +% #1: type +% #2: id +% #3: property +% #4: value +\cs_new_protected:Npn \xsim_set_property:nnnn #1#2#3#4 + { + \xsim_if_property_exist:nTF {#3} + { + \xsim_if_property_set:nnnTF {#1} {#2} {#3} + { + \xsim_if_property_unique_value:nnTF {#3} {#4} + { \msg_warning:nnnn {xsim} {property-unique} {#3} {#4} } + { + \xsim_if_property_boolean:nTF {#3} + { \__xsim_set_boolean_property:nnnn {#1} {#2} {#3} {#4} } + { + \xsim_if_property_unique:nTF {#3} + { \__xsim_set_unique_property:nnnn {#1} {#2} {#3} {#4} } + { \__xsim_set_property:nnnn {#1} {#2} {#3} {#4} } + } + } + } + { + \xsim_if_property_boolean:nTF {#3} + { \__xsim_set_boolean_property:nnnn {#1} {#2} {#3} {#4} } + { + \xsim_if_property_unique:nTF {#3} + { \__xsim_set_unique_property:nnnn {#1} {#2} {#3} {#4} } + { \__xsim_set_property:nnnn {#1} {#2} {#3} {#4} } + } + } + } + { \msg_error:nnn {xsim} {unknown-property} {#3} } + } +\cs_generate_variant:Nn \xsim_set_property:nnnn {nnxx,nnnV,nV,nVnx,nnnx} + +\cs_new_protected:Npn \__xsim_set_boolean_property:nnnn #1#2#3#4 + { + \str_case_x:nnTF { \str_lower_case:n {#4} } + { + {} {} + {true} {} + } + { \__xsim_set_property:nnnn {#1} {#2} {#3} {true} } + { \__xsim_set_property:nnnn {#1} {#2} {#3} {false} } + } + +\cs_new_protected:Npn \__xsim_set_unique_property:nnnn #1#2#3#4 + { + \__xsim_set_property:nnnn {#1} {#2} {#3} {#4} + \__xsim_set_property_reverse:nnnn {#1} {#2} {#3} {#4} + } + +% #1: type +% #2: id +% #3: property +\cs_new_protected:Npn \xsim_unset_property:nnn #1#2#3 + { + \xsim_if_property_exist:nTF {#3} + { \__xsim_unset_property:nnn {#1} {#2} {#3} } + { \msg_error:nnn {xsim} {unknown-property} {#3} } + } +\cs_generate_variant:Nn \xsim_unset_property:nnn {nx,nnx,nV} + +% #1: type +% #2: id +% #3: property +% #4: value +\cs_new_protected:Npn \__xsim_set_property:nnnn #1#2#3#4 + { + \xsim_verbose:n + { + Setting~ property~ `#3'~ of~ exercise~ type~ `#1'~ id~ `#2'~ to~ + value~ `#4'. + } + \__xsim_remove_property_from_list:nnn {#1} {#2} {#3} + % now we can safely add the property to the list: + \xsim_add_to_list:nn {#3} {#1-#2=={#4}} + \prop_gput:Nnn \g__xsim_properties_prop {#2!#1!#3} {#4} + } +\cs_generate_variant:Nn \__xsim_set_property:nnnn {VVnV} + +% #1: type +% #2: id +% #3: property +% #4: value +\cs_new_protected:Npn \__xsim_set_property_reverse:nnnn #1#2#3#4 + { + \prop_gput:cnn {g__xsim_property_#3_type_prop} {#4} {#1} + \prop_gput:cnn {g__xsim_property_#3_id_prop} {#4} {#2} + } + +% #1: type +% #2: id +% #3: property +\cs_new_protected:Npn \__xsim_unset_property:nnn #1#2#3 + { + \xsim_verbose:n + { Un-setting~ property~ `#3'~ of~ exercise~ type~ `#1'~ id~ `#2'. } + \__xsim_remove_property_from_list:nnn {#1} {#2} {#3} + \prop_gremove:Nn \g__xsim_properties_prop {#2!#1!#3} + } + +\tl_set:Nx \l__xsim_tmpa_tl { \cs_to_str:N \{ } +\tl_set:Nx \l__xsim_tmpb_tl { \cs_to_str:N \} } +\use:x + { + \cs_new_protected:Npn + \exp_not:N \__xsim_extract_property_list_entry:NNNwww + ##1##2##3##4-##5== \l__xsim_tmpa_tl ##6 \l__xsim_tmpb_tl + \exp_not:N \q_stop + } + { + \str_set:Nn #1 {#4} + \str_set:Nn #2 {#5} + \str_set:Nn #3 {#6} + } + +\cs_new_protected:Npn \__xsim_remove_property_from_list:nnn #1#2#3 + { + % make sure we change the entry if it has been recorded previously: + \xsim_foreach_list_entry:nn {#3} + { + \__xsim_extract_property_list_entry:NNNwww + \l__xsim_tmpa_str \l__xsim_tmpb_str \l__xsim_tmpc_str ##1 \q_stop + \str_if_eq:xnT { \l__xsim_tmpa_str - \l__xsim_tmpb_str } {#1-#2} + { + \xsim_remove_from_list:nx {#3} + { #1-#2 == {\l__xsim_tmpc_str} } + } + } + % make sure we change the entry if it has been set during the current run: + \xsim_foreach_new_list_entry:nn {#3} + { + \__xsim_extract_property_list_entry:NNNwww + \l__xsim_tmpa_str \l__xsim_tmpb_str \l__xsim_tmpc_str ##1 \q_stop + \str_if_eq:xnT { \l__xsim_tmpa_str - \l__xsim_tmpb_str } {#1-#2} + { + \xsim_remove_from_list:nx {#3} + { #1-#2 == {\l__xsim_tmpc_str} } + } + } + } + +\cs_new_protected:Npn \__xsim_set_property_from_list:n #1 + { + \xsim_foreach_list_entry:nn {#1} + { + \__xsim_extract_property_list_entry:NNNwww + \l__xsim_tmpa_str \l__xsim_tmpb_str \l__xsim_tmpc_str ##1 \q_stop + \tl_set_rescan:Nnx \l__xsim_tmpc_tl {} { \l__xsim_tmpc_str } + \__xsim_set_property:VVnV + \l__xsim_tmpa_str + \l__xsim_tmpb_str + {#1} + \l__xsim_tmpc_tl + } + } + +% set properties: +% #1: type +% #2: id +% #3: csv list of properties +\cs_new_protected:Npn \xsim_set_properties:nnn #1#2#3 + { + \clist_map_inline:nn {#3} + { + \seq_set_split:Nnx \l__xsim_tmpa_seq {=} { \tl_trim_spaces:n {##1} } + \xsim_set_property:nnxx + {#1} + {#2} + { \seq_item:Nn \l__xsim_tmpa_seq {1} } + { \seq_item:Nn \l__xsim_tmpa_seq {2} } + } + \xsim_property_set_aliases:nn {#1} {#2} + } +\cs_generate_variant:Nn \xsim_set_properties:nnn {nnx,nxx,nV,nVx} + +% check if property is set: +% #1: type +% #2: id +% #3: property +\prg_new_protected_conditional:Npnn \xsim_if_property_set:nnn #1#2#3 {T,F,TF} + { + \prop_if_in:NxTF \g__xsim_properties_prop + { #2 ! #1 ! #3 } + { \prg_return_true: } + { \prg_return_false: } + } +\cs_generate_variant:Nn \xsim_if_property_set:nnnTF {nnx,xx,nV} +\cs_generate_variant:Nn \xsim_if_property_set:nnnF {nx,nnx,xx} +\cs_generate_variant:Nn \xsim_if_property_set:nnnT {nnx,xx} + +% ---------------------------------------------------------------------------- + +\prop_new:N \g__xsim_property_aliases_prop +\seq_new:N \g__xsim_property_aliases_seq + +% #1: property +\prg_new_conditional:Npnn \xsim_if_property_alias:n #1 {p,T,F,TF} + { + \prop_if_in:NnTF \g__xsim_property_aliases_prop {#1} + { \prg_return_true: } + { \prg_return_false: } + } + +% #1: property +\cs_new:Npn \xsim_property_alias:n #1 + { \prop_item:Nn \g__xsim_property_aliases_prop {#1} } + +% #1: property +% #2: alias of +\cs_new_protected:Npn \xsim_make_property_alias:nn #1#2 + { + \xsim_if_property_alias:nF {#1} + { + \xsim_verbose:n + { Making~ property~ `#1'~ an~ alias~ of~ property~ `#2'. } + \prop_new:c {g__xsim_property_#1_alias_prop} + \prop_gput:Nnn \g__xsim_property_aliases_prop {#1} {#2} + \seq_gput_right:Nn \g__xsim_property_aliases_seq {#1} + } + } + +% #1: type +% #2: id +% #3: property +\cs_new_protected:Npn \xsim_property_set_alias:nnn #1#2#3 + { + \xsim_if_property_set:nnnF {#1} {#2} {#3} + { + \xsim_if_property_set:nnxT {#1} {#2} + { \xsim_property_alias:n {#3} } + { + \xsim_set_property:nnnx {#1} {#2} {#3} + { + \xsim_get_property:nnf {#1} {#2} + { \xsim_property_alias:n {#3} } + } + } + } + \xsim_if_property_set:nnxT {#1} {#2} + { \xsim_property_alias:n {#3} } + { + \prop_gput:cxx {g__xsim_property_#3_alias_prop} + { \xsim_get_property:nnn {#1} {#2} {#3} } + { + \xsim_get_property:nnf {#1} {#2} + { \xsim_property_alias:n {#3} } + } + } + } +\cs_generate_variant:Nn \xsim_property_set_alias:nnn {nV} + +% #1: type +% #2: id +\cs_new_protected:Npn \xsim_property_set_aliases:nn #1#2 + { + \seq_map_inline:Nn \g__xsim_property_aliases_seq + { \xsim_property_set_alias:nnn {#1} {#2} {##1} } + } + +% ---------------------------------------------------------------------------- + +% retrieve properties: +% #1: type +% #2: id +% #3: property +\cs_new:Npn \xsim_get_property:nnn #1#2#3 + { \prop_item:Nn \g__xsim_properties_prop { #2 ! #1 ! #3 } } +\cs_generate_variant:Nn \xsim_get_property:nnn {nx,xx,oo,no,nnf,nf,oof,nV} + +\cs_new:Npn \__xsim_get_property_tmp:n #1 {} +\cs_generate_variant:Nn \__xsim_get_property_tmp:n {V} + +% #1: property +% #2: value +\cs_new:Npn \xsim_get_id_for_property:nn #1#2 + { \prop_item:cn {g__xsim_property_#1_id_prop} {#2} } + +% #1: property +% #2: value +\cs_new:Npn \xsim_get_type_for_property:nn #1#2 + { \prop_item:cn {g__xsim_property_#1_type_prop} {#2} } +\cs_generate_variant:Nn \xsim_get_type_for_property:nn {nV} + +% #1: type +% #2: id +% #3: property +\cs_new_protected:Npn \xsim_get_property_if_set:nnnTF #1#2#3#4#5 + { + \group_begin: + \xsim_if_property_exist:nTF {#3} + { + \xsim_if_property_set:nnnTF {#1} {#2} {#3} + { + \tl_set:Nx \PropertyValue + { \xsim_get_property:nnn {#1} {#2} {#3} } + \cs_set:Npn \__xsim_get_property_tmp:n ##1 {#4} + \__xsim_get_property_tmp:V \PropertyValue + } + {#5} + } + { \msg_error:nnn {xsim} {unknown-property} {#3} } + \group_end: + } +\cs_new_protected:Npn \xsim_get_property_if_set:nnnT #1#2#3#4 + { \xsim_get_property_if_set:nnnTF {#1} {#2} {#3} {#4} {} } +\cs_new_protected:Npn \xsim_get_property_if_set:nnnF #1#2#3#4 + { \xsim_get_property_if_set:nnnTF {#1} {#2} {#3} {} {#4} } +\cs_generate_variant:Nn \xsim_get_property_if_set:nnnTF {oo} + +% #1: type +% #2: id +% #3: property +\prg_new_conditional:Npnn \xsim_if_boolean_property:nnn #1#2#3 {T,F,TF} + { + \xsim_if_property_exist:nTF {#3} + { + \xsim_if_property_boolean:nTF {#3} + { + \xsim_if_property_set:nnnTF {#1} {#2} {#3} + { + \bool_if:cTF { c_ \xsim_get_property:nnn {#1} {#2} {#3} _bool} + { \prg_return_true: } + { \prg_return_false: } + } + { \prg_return_false: } + } + { \msg_error:nnn {xsim} {no-boolean-property} {#3} } + } + { \msg_error:nnn {xsim} {unknown-property} {#3} } + } +\cs_generate_variant:Nn \xsim_if_boolean_property:nnnTF {oo} +\cs_generate_variant:Nn \xsim_if_boolean_property:nnnF {nV} + +\cs_new_protected:Npn \xsim_save_property:nnnN #1#2#3#4 + { \prop_get:NnN \g__xsim_properties_prop { #2 ! #1 ! #3 } #4 } +\cs_generate_variant:Nn \xsim_save_property:nnnN {nx,xx} + +\cs_new_protected:Npn \xsim_gsave_property:nnnN #1#2#3#4 + { + \xsim_save_property:nnnN {#1} {#2} {#3} #4 + \tl_gset:NV #4 #4 + } +\cs_generate_variant:Nn \xsim_gsave_property:nnnN {nx,xx} + +% ---------------------------------------------------------------------------- +\tex_endinput:D diff --git a/Master/texmf-dist/tex/latex/xsim/xsim.random.code.tex b/Master/texmf-dist/tex/latex/xsim/xsim.random.code.tex new file mode 100644 index 00000000000..3120c800bd8 --- /dev/null +++ b/Master/texmf-dist/tex/latex/xsim/xsim.random.code.tex @@ -0,0 +1,307 @@ +% ---------------------------------------------------------------------------- +% the XSIM package - random module +% +% eXercise Sheets IMproved +% +% ---------------------------------------------------------------------------- +% Clemens Niederberger +% Web: https://github.com/cgnieder/xsim +% E-Mail: contact@mychemistry.eu +% ---------------------------------------------------------------------------- +% Copyright 2017 Clemens Niederberger +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +% +% This work has the LPPL maintenance status `maintained'. +% +% The Current Maintainer of this work is Clemens Niederberger. +% ---------------------------------------------------------------------------- +% If you have any ideas, questions, suggestions or bugs to report, please +% feel free to contact me. +% ---------------------------------------------------------------------------- +\XSIMmodule{random}{randomly select exercises from collections} + +\xsim_load_modules:n {collections} + +\tl_new:N \l_xsim_random_collection_tl +\tl_new:N \l_xsim_random_exclude_list_tl +\tl_new:N \l__xsim_print_random_choice_tl +\tl_const:Nn \c__xsim_print_random_both_tl {both} +\tl_const:Nn \c__xsim_print_random_exercise_tl {exercise} +\tl_const:Nn \c__xsim_print_random_solution_tl {solution} +\seq_new:N \g__xsim_random_list_seq +\seq_new:N \l__xsim_allowed_exercise_ids_seq +\int_new:N \g__xsim_random_list_id_int +\bool_new:N \l__xsim_sort_random_bool + +% #1: random list id +% #2: csv list of integers +\xsim_new_aux_cs:cpn {random} #1#2 + { + \xsim_random_list_if_exist:nF {#1} + { \xsim_new_random_list:n {#1} } + \xsim_set_random_list:nn {#1} {#2} + } + +\cs_new_protected:Npn \xsim_new_random_list:n #1 + { + \xsim_verbose:n {Defining~ new~ random~ list~ `#1'} + \seq_new:c {g__xsim_random_#1 _seq} + } + +\cs_new_protected:Npn \xsim_set_random_list:nn #1#2 + { \seq_gset_from_clist:cn {g__xsim_random_#1_seq} {#2} } + +\cs_new_protected:Npn \xsim_set_random_list_from_seq:nN #1#2 + { \seq_gset_eq:cN {g__xsim_random_#1_seq} #2 } + +\cs_new:Npn \xsim_use_random_list:nn #1#2 + { \seq_use:cn {g__xsim_random_#1_seq} {#2} } + +\cs_new_protected:Npn \xsim_map_random_list:nn #1#2 + { \seq_map_inline:cn {g__xsim_random_#1_seq} {#2} } + +\prg_new_conditional:Npnn \xsim_random_list_if_exist:n #1 {p,T,F,TF} + { + \seq_if_exist:cTF {g__xsim_random_#1_seq} + { \prg_return_true: } + { \prg_return_false: } + } + +\prg_new_conditional:Npnn \xsim_random_list_if_empty:n #1 {p,T,F,TF} + { + \seq_if_empty:cTF {g__xsim_random_#1_seq} + { \prg_return_true: } + { \prg_return_false: } + } + +% #1: random list id +% #2: sequence variable to set list from +\cs_new_protected:Npn \xsim_save_random_list:nN #1#2 + { + \xsim_random_list_if_exist:nF {#1} + { \xsim_new_random_list:n {#1} } + \xsim_random_list_if_empty:nT {#1} + { \xsim_set_random_list_from_seq:nN {#1} #2 } + \xsim_verbose:n {Saving~ random~ list~ `#1'} + \xsim_add_cs_to_aux:nn {random} + { {#1} { \xsim_use_random_list:nn {#1} {,} } } + } + +% #1: collection +% #2: number of items +% #3: csv list of excluded ids +\cs_new_protected:Npn \xsim_print_random_list:nnn #1#2#3 + { + \xsim_if_collection_exists:nTF {#1} + { + \int_gincr:N \g__xsim_random_list_id_int + \int_compare:nNnTF { \xsim_collection_count:n {#1} } = {0} + { \xsim_rerun: } + { + % generate seq of allowed ids from collection: + \xsim_foreach_exercise_id:n + { + \tl_set:Nx \l__xsim_tmpa_tl + { \xsim_get_type_for_property:nn {id} {##1} } + \xsim_if_in_collection:nVnT {#1} \l__xsim_tmpa_tl {##1} + { + \clist_if_in:nnF {#3} {##1} + { \seq_put_right:Nn \l__xsim_allowed_exercise_ids_seq {##1} } + } + } + \int_compare:nNnTF + {#2} + > + { \seq_count:N \l__xsim_allowed_exercise_ids_seq } + { + \int_set:Nn \l__xsim_tmpa_int + { \seq_count:N \l__xsim_allowed_exercise_ids_seq } + } + { \int_set:Nn \l__xsim_tmpa_int {#2} } + % generate random list: + \xsim_generate_random_list:nnnN + { \int_to_alph:n { \g__xsim_random_list_id_int } } + { \seq_count:N \l__xsim_allowed_exercise_ids_seq } + { \l__xsim_tmpa_int } + \g__xsim_random_list_seq + } + \xsim_save_random_list:nN + { \int_to_alph:n { \g__xsim_random_list_id_int } } + \g__xsim_random_list_seq + \xsim_verbose:x + { + Printing~ exercises~ of~ random~ list~ + `\int_to_alph:n { \g__xsim_random_list_id_int }'~ of~ + collection~ `#1' + } + \xsim_print_random_exercises:Nn + \l__xsim_allowed_exercise_ids_seq + { \int_to_alph:n { \g__xsim_random_list_id_int } } + } + { \msg_error:nnn {xsim} {unknown-collection} {#1} } + } +\cs_generate_variant:Nn \xsim_print_random_list:nnn {VnV} + +% #1: random list id +% #2: max number to choose from +% #3: number of items +% #4: seq variable +\cs_new_protected:Npn \xsim_generate_random_list:nnnN #1#2#3#4 + { + \bool_if:nT + { + !\xsim_random_list_if_exist_p:n {#1} + || + \xsim_random_list_if_empty_p:n {#1} + } + { + \xsim_verbose:n + {Generating~ random~ list~ `#1'~ with~ #3~ out~ of~ #2~ items} + \seq_gclear:N #4 + \int_do_until:nNnn { \seq_count:N #4 } = {#3} + { + \tl_set:Nx \l__xsim_tmpa_tl + { \fp_eval:n { randint(#2) } } + \seq_if_in:NVF #4 + \l__xsim_tmpa_tl + { \seq_gput_right:NV #4 \l__xsim_tmpa_tl } + } + \bool_if:NT \l__xsim_sort_random_bool + { + \seq_sort:Nn #4 + { + \int_compare:nNnTF {##1} > {##2} + { \sort_return_swapped: } + { \sort_return_same: } + } + } + } + } + +% #1: seq variable of ids +% #2: random list id +\cs_new_protected:Npn \xsim_print_random_exercises:Nn #1#2 + { + \bool_if:nT + { + \xsim_random_list_if_exist_p:n {#2} + && + !\xsim_random_list_if_empty_p:n {#2} + } + { + \xsim_verbose:x + { + Printing~ + \l__xsim_print_random_choice_tl \c_space_tl + \str_if_eq:onT { \l__xsim_print_random_choice_tl } {both} + { exercises~ and~ solutions~ } + of~ random~ list~ `#2' + } + \xsim_map_random_list:nn {#2} + { + \tl_set:Nx \l__xsim_tmpa_tl + { \seq_item:Nn #1 {##1} } + \tl_set:Nx \l__xsim_tmpb_tl + { \xsim_get_type_for_property:nV {id} \l__xsim_tmpa_tl } + \bool_if:nT + { + \tl_if_eq_p:NN + \l__xsim_print_random_choice_tl + \c__xsim_print_random_both_tl + || + \tl_if_eq_p:NN + \l__xsim_print_random_choice_tl + \c__xsim_print_random_exercise_tl + } + { + \xsim_if_exercise_exists:VVT + \l__xsim_tmpb_tl + \l__xsim_tmpa_tl + { + \xsim_insert:VVnn + \l__xsim_tmpb_tl + \l__xsim_tmpa_tl + {} + {exercise} + } + } + \bool_if:nT + { + \tl_if_eq_p:NN + \l__xsim_print_random_choice_tl + \c__xsim_print_random_both_tl + || + \tl_if_eq_p:NN + \l__xsim_print_random_choice_tl + \c__xsim_print_random_solution_tl + } + { + \xsim_if_solution_exists:VVT + \l__xsim_tmpb_tl + \l__xsim_tmpa_tl + { + \xsim_insert:VVnn + \l__xsim_tmpb_tl + \l__xsim_tmpa_tl + {} + {solution} + } + } + } + } + } + +\keys_define:nn {xsim/random} + { + sort .bool_set:N = \l__xsim_sort_random_bool , + sort .initial:n = true , + collection .tl_set:N = \l_xsim_random_collection_tl , + collection .initial:n = all~exercises , + exclude .code:n = \__xsim_exclude_ids:n {#1} , + print .choice: , + print/exercises .code:n = + \tl_set:Nn \l__xsim_print_random_choice_tl {exercise} , + print/solutions .code:n = + \tl_set:Nn \l__xsim_print_random_choice_tl {solution} , + print/both .code:n = + \tl_set:Nn \l__xsim_print_random_choice_tl {both} , + print/unknown .code:n = + \msg_warning:nnn {xsim} {print-collection-choice} {#1} + \tl_set:Nn \l__xsim_print_random_choice_tl {exercise} , + print .initial:n = exercises + } + +\cs_new_protected:Npn \__xsim_exclude_ids:n #1 + { + \seq_clear:N \l__xsim_tmpa_seq + \clist_map_inline:nn {#1} + { + \tl_set:Nx \l__xsim_tmpa_tl + { \xsim_get_id_for_property:nn {ID} {##1} } + \tl_if_blank:NTF \l__xsim_tmpa_tl + { \seq_put_right:Nn \l__xsim_tmpa_seq {##1} } + { + \seq_put_right:Nx \l__xsim_tmpa_seq + { \xsim_get_id_for_property:nn {ID} {##1} } + } + } + \seq_remove_duplicates:N \l__xsim_tmpa_seq + \tl_set:Nx \l_xsim_random_exclude_list_tl + { \seq_use:Nn \l__xsim_tmpa_seq {,} } + } + +% use this in the exclude list: +% \xsim_get_type_for_property:nn {id} {} +% or a combination of: +% \xsim_get_type_for_property:nn {ID} {} +% \xsim_get_id_for_property:nn {ID} {} + +% ---------------------------------------------------------------------------- +\tex_endinput:D diff --git a/Master/texmf-dist/tex/latex/xsim/xsim.solutions.code.tex b/Master/texmf-dist/tex/latex/xsim/xsim.solutions.code.tex new file mode 100644 index 00000000000..101c19aa23c --- /dev/null +++ b/Master/texmf-dist/tex/latex/xsim/xsim.solutions.code.tex @@ -0,0 +1,402 @@ +% ---------------------------------------------------------------------------- +% the XSIM package - solutions module +% +% eXercise Sheets IMproved +% +% ---------------------------------------------------------------------------- +% Clemens Niederberger +% Web: https://github.com/cgnieder/xsim +% E-Mail: contact@mychemistry.eu +% ---------------------------------------------------------------------------- +% Copyright 2017 Clemens Niederberger +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +% +% This work has the LPPL maintenance status `maintained'. +% +% The Current Maintainer of this work is Clemens Niederberger. +% ---------------------------------------------------------------------------- +% If you have any ideas, questions, suggestions or bugs to report, please +% feel free to contact me. +% ---------------------------------------------------------------------------- +\XSIMmodule{solutions}{managing solutions} + +\xsim_load_modules:n {tags,properties} + +\bool_new:N \l_xsim_inside_solution_bool +\bool_new:N \l__xsim_printsolutions_headings_bool +\bool_new:N \l__xsim_printsolutions_conditions_bool +\bool_new:N \l____xsim_this_condition_bool + +\prop_new:N \l__xsim_printsolutions_conditions_prop + +\int_new:N \l_xsim_printsolutions_section_int +\int_new:N \l_xsim_printsolutions_chapter_int + +\tl_new:N \l__xsim_printsolutions_headings_template_tl +\tl_new:N \ExerciseSection +\tl_new:N \ExerciseChapter +\tl_new:N \l__xsim_printsolutions_collection_tl + +% ---------------------------------------------------------------------------- + +\prg_new_conditional:Npnn \xsim_if_inside_solution: {p,T,F,TF} + { + \bool_if:NTF \l_xsim_inside_solution_bool + { \prg_return_true: } + { \prg_return_false: } + } + +\prg_new_conditional:Npnn \xsim_if_solution_print:n #1 {p,T,F,TF} + { + \bool_if:cTF {l__xsim_#1_solution_print_bool} + { \prg_return_true: } + { \prg_return_false: } + } + +% #1: type +% #2: id +\prg_new_protected_conditional:Npnn \xsim_solution_if_print:nn #1#2 {T,F,TF} + { + \bool_set_true:N \l____xsim_print_bool + \xsim_if_tagged:nnF {#1} {#2} + { \bool_set_false:N \l____xsim_print_bool } + \xsim_if_boolean_property:nnnF {#1} {#2} {print} + { \bool_set_false:N \l____xsim_print_bool } + \bool_if:cF {l__xsim_#1_solution_print_bool} + { \bool_set_false:N \l____xsim_print_bool } + \bool_if:NTF \l____xsim_print_bool + { \prg_return_true: } + { \prg_return_false: } + } +\cs_generate_variant:Nn \xsim_solution_if_print:nnT {nV,oo} + +% #1: type +% #2: id +\prg_new_conditional:Npnn \xsim_if_solution_exists:nn #1#2 {T,F,TF} + { + \__xsim_set_file_signature:nnn {#1} {#2} {solution} + \file_if_exist:VTF \l__xsim_file_path_and_name_tl + { \prg_return_true: } + { \prg_return_false: } + } +\cs_generate_variant:Nn \xsim_if_solution_exists:nnT {VV} + +% #1: type +% #2: options +\cs_new_protected:Npn \xsim_start_solution:nn #1#2 + { + \keys_set:xn { xsim/\xsim_get_parameter:nn {#1} {solution-env} } {#2} + \bool_set_true:N \l_xsim_inside_solution_bool + \refstepcounter { \xsim_get_parameter:nn {#1} {solution-counter} } + } + +\cs_new_protected:Npn \xsim_stop_solution:n #1 {} + +% ---------------------------------------------------------------------------- + +% per section condition: +% #1: type +% #2: id +% #3: boolean property +\prg_new_protected_conditional:Npnn + \__xsim_if_solutions_per_section:nnn #1#2#3 {T,F,TF} + { + \xsim_if_in_list:nnTF {#3} {#1-#2=={true}} + { + \__xsim_printsolutions_if_condition:nTF {per-section} + { + \__xsim_printsolutions_condition_true: + \xsim_if_in_list:nxTF {section-value} + { #1-#2 == { \int_use:N \l_xsim_printsolutions_section_int } } + { + \tl_set:Nx \ExerciseSection + { \xsim_get_property:nnn {#1} {#2} {section} } + \prg_return_true: + } + { \prg_return_false: } + } + { \prg_return_false: } + } + { \prg_return_false: } + } + +% per chapter condition: +% #1: type +% #2: id +% #3: boolean property +\prg_new_protected_conditional:Npnn + \__xsim_if_solutions_per_chapter:nnn #1#2#3 {T,F,TF} + { + \xsim_if_in_list:nnTF {#3} {#1-#2=={true}} + { + \__xsim_printsolutions_if_condition:nTF {per-chapter} + { + \__xsim_printsolutions_condition_true: + \xsim_if_in_list:nxTF {chapter-value} + { #1-#2 == { \int_use:N \l_xsim_printsolutions_chapter_int } } + { + \tl_set:Nx \ExerciseChapter + { \xsim_get_property:nnn {#1} {#2} {chapter} } + \prg_return_true: + } + { \prg_return_false: } + } + { \prg_return_false: } + } + { \prg_return_false: } + } + +% per collection condition: +% #1: type +% #2: id +% #3: boolean property +\prg_new_protected_conditional:Npnn + \__xsim_if_solutions_in_collection:nnn #1#2#3 {T,F,TF} + { + \xsim_if_in_list:nnTF {#3} {#1-#2=={true}} + { + \__xsim_printsolutions_if_condition:nTF {per-collection} + { + \__xsim_printsolutions_condition_true: + \tl_if_blank:VTF \l__xsim_printsolutions_collection_tl + { \prg_return_false: } + { + \xsim_if_in_collection:VnnTF + \l__xsim_printsolutions_collection_tl + {#1} + {#2} + { \prg_return_true: } + { \prg_return_false: } + } + } + { \prg_return_false: } + } + { \prg_return_false: } + } + +% ---------------------------------------------------------------------------- +% conditions mechanism +\cs_new_protected:Npn \__xsim_printsolutions_condition_false: + { \bool_set_false:N \l__xsim_printsolutions_conditions_bool } + +\cs_new_protected:Npn \__xsim_printsolutions_condition_true: + { \bool_set_true:N \l__xsim_printsolutions_conditions_bool } + +% #1: type +% #2: id +% #3: boolean property +\prg_new_conditional:Npnn + \__xsim_printsolutions_if_conditions:nnn #1#2#3 {T,F,TF} + { + \bool_if:NTF \l__xsim_printsolutions_conditions_bool + { \prg_return_true: } + { + \xsim_if_in_list:nnTF {#3} {#1-#2=={true}} + { \prg_return_false: } + { \prg_return_true: } + } + } + +% #1: name +% #2: condition +\cs_new_protected:Npn \__xsim_declare_printsolutions_condition:nn #1#2 + { + \bool_new:c {l__xsim_printsolutions_#1_condition_bool} + \prop_put:Nnn \l__xsim_printsolutions_conditions_prop {#1} {#2} + } + +\prg_new_conditional:Npnn \__xsim_printsolutions_if_condition:n #1 {T,F,TF} + { + \bool_if:cTF {l__xsim_printsolutions_#1_condition_bool} + { \prg_return_true: } + { \prg_return_false: } + } + +% #1: name +% #2: true|false +\cs_new_protected:Npn \__xsim_printsolutions_condition:nn #1#2 + { \bool_set_eq:cc {l__xsim_printsolutions_#1_condition_bool} {c_#2_bool} } + +% false if any condition is false for this solution: +% #1: type +% #2: id +% #3: boolean property +\prg_new_protected_conditional:Npnn + \__xsim_printsolutions_check_conditions:nnn #1#2#3 {T,F,TF} + { + \__xsim_printsolutions_condition_false: + \bool_set_true:N \l____xsim_this_condition_bool + \prop_map_inline:Nn \l__xsim_printsolutions_conditions_prop + { + \bool_if:cT {l__xsim_printsolutions_##1_condition_bool} + { + ##2 {#1} {#2} {#3} + { } + { \bool_set_false:N \l____xsim_this_condition_bool } + } + } + \bool_if:NTF \l____xsim_this_condition_bool + { \prg_return_true: } + { \prg_return_false: } + } + + +% #1: type +% #2: id +% #3: boolean property +% #4: code +\cs_new_protected:Npn \xsim_if_this_solution_do:nnnn #1#2#3#4 + { + \xsim_if_solution_exists:nnT {#1} {#2} + { \__xsim_printsolutions_check_conditions:nnnT {#1} {#2} {#3} {#4} } + } + +% #1: type +% #2: boolean property +% #3: code +\cs_new_protected:Npn \xsim_if_solutions_do:nnn #1#2#3 + { + \xsim_foreach_exercise_type_id:nn {#2} + { \xsim_if_this_solution_do:nnnn {#1} {##2} {#2} {#3} } + } + +% ---------------------------------------------------------------------------- +% #1: boolean -- if true only the solutions of printed exercises will be +% output +% #2: options +% #3: type +\cs_new_protected:Npn \xsim_print_type_solutions:nnn #1#2#3 + { + \xsim_verbose:n + { Printing~ solutions~ for~ exercise~ type~ `#3'. } + \group_begin: + \keys_set:nn {xsim/print-solutions} {#2} + \bool_set_false:N \l__xsim_tmpa_bool + \bool_if:nTF {#1} + { + \xsim_if_solutions_do:nnn {#3} {print} + { \bool_set_true:N \l__xsim_tmpa_bool } + } + { + \xsim_if_solutions_do:nnn {#3} {use} + { \bool_set_true:N \l__xsim_tmpa_bool } + } + \tl_set:Nn \ExerciseType {#3} + \bool_if:NT \l__xsim_tmpa_bool + { + \bool_if:NT \l__xsim_printsolutions_headings_bool + { + \xsim_use_template:nV + {heading} + \l__xsim_printsolutions_headings_template_tl + } + } + \bool_if:nTF {#1} + { + \xsim_if_solutions_do:nnn {#3} {print} + { \xsim_insert:nnnn {#3} {##2} {} {solution} } + } + { + \xsim_if_solutions_do:nnn {#3} {use} + { \xsim_insert:nnnn {#3} {##2} {} {solution} } + } + \group_end: + } + +% #1: boolean -- if true only the solutions of printed exercises will be +% output +% #2: options +\cs_new_protected:Npn \xsim_print_all_solutions_per_type:nn #1#2 + { + \xsim_foreach_exercise_type:n + { \xsim_print_type_solutions:nnn {#1} {#2} {##1} } + } + +% #1: boolean -- if true only the solutions of printed exercises will be +% output +% #2: options +\cs_new_protected:Npn \xsim_print_all_solutions_per_id:nn #1#2 + { + \xsim_verbose:n { Printing~ solutions. } + \group_begin: + \keys_set:nn {xsim/print-solutions} {#2} + \bool_set_false:N \l__xsim_tmpa_bool + \bool_if:nTF {#1} + { + \xsim_foreach_exercise_id_type:nn {print} + { + \xsim_if_this_solution_do:nnnn {##1} {##2} {print} + { \xsim_insert:nnnn {##1} {##2} {} {solution} } + } + } + { + \xsim_foreach_exercise_id_type:nn {use} + { + \xsim_if_this_solution_do:nnnn {##1} {##2} {use} + { \xsim_insert:nnnn {##1} {##2} {} {solution} } + } + } + \group_end: + } + +% ---------------------------------------------------------------------------- + +\__xsim_declare_printsolutions_condition:nn {per-section} + { \__xsim_if_solutions_per_section:nnnTF } +\__xsim_declare_printsolutions_condition:nn {per-chapter} + { \__xsim_if_solutions_per_chapter:nnnTF } +\__xsim_declare_printsolutions_condition:nn {per-collection} + { \__xsim_if_solutions_in_collection:nnnTF } + +% ---------------------------------------------------------------------------- + +\keys_define:nn {xsim/print-solutions} + { + headings .bool_set:N = \l__xsim_printsolutions_headings_bool , + headings .initial:n = true , + headings-template .tl_set:N = \l__xsim_printsolutions_headings_template_tl , + headings-template .initial:n = default , + section .choice: , + section/true .code:n = + \__xsim_printsolutions_condition:nn {per-section} {true} + \int_set:Nn \l_xsim_printsolutions_section_int { \value {section} } , + section/false .code:n = + \__xsim_printsolutions_condition:nn {per-section} {false} , + section/unknown .code:n = + \__xsim_printsolutions_condition:nn {per-section} {true} + \int_set:Nn \l_xsim_printsolutions_section_int {#1} , + section .default:n = true , + section .initial:n = false , + chapter .choice: , + chapter/true .code:n = + \__xsim_printsolutions_condition:nn {per-chapter} {true} + \int_set:Nn \l_xsim_printsolutions_chapter_int { \value {chapter} } , + chapter/false .code:n = + \__xsim_printsolutions_condition:nn {per-chapter} {false} , + chapter/unknown .code:n = + \__xsim_printsolutions_condition:nn {per-chapter} {true} + \int_set:Nn \l_xsim_printsolutions_chapter_int {#1} , + chapter .default:n = true , + chapter .initial:n = false , + collection .choice: , + collection/false .code:n = + \__xsim_printsolutions_condition:nn {per-collection} {false} , + collection/unknown .code:n = + \xsim_if_collection_exists:nT {#1} + { + \__xsim_printsolutions_condition:nn {per-collection} {true} + \tl_set:Nn \l__xsim_printsolutions_collection_tl {#1} + } , + collection .initial:n = false + } + +% ---------------------------------------------------------------------------- + +\tex_endinput:D diff --git a/Master/texmf-dist/tex/latex/xsim/xsim.sty b/Master/texmf-dist/tex/latex/xsim/xsim.sty new file mode 100644 index 00000000000..7bc7248c47e --- /dev/null +++ b/Master/texmf-dist/tex/latex/xsim/xsim.sty @@ -0,0 +1,109 @@ +% ---------------------------------------------------------------------------- +% the XSIM package +% +% eXercise Sheets IMproved +% +% ---------------------------------------------------------------------------- +% Clemens Niederberger +% Web: https://github.com/cgnieder/xsim +% E-Mail: contact@mychemistry.eu +% ---------------------------------------------------------------------------- +% Copyright 2017 Clemens Niederberger +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +% +% This work has the LPPL maintenance status `maintained'. +% +% The Current Maintainer of this work is Clemens Niederberger. +% ---------------------------------------------------------------------------- +% If you have any ideas, questions, suggestions or bugs to report, please +% feel free to contact me. +% ---------------------------------------------------------------------------- +\RequirePackage {expl3,xparse} + +\ExplSyntaxOn + +\tl_const:Nn \c_xsim_date_tl {2017/05/19} +\tl_const:Nn \c_xsim_version_major_number_tl {0} +\tl_const:Nn \c_xsim_version_minor_number_tl {8} +\tl_const:Nn \c_xsim_version_subrelease_tl {a} +\tl_const:Nx \c_xsim_version_number_tl + { + \c_xsim_version_major_number_tl . + \c_xsim_version_minor_number_tl + } +\tl_const:Nx \c_xsim_version_tl + { + \c_xsim_version_number_tl + \c_xsim_version_subrelease_tl + } +\tl_const:Nn \c_xsim_info_tl {eXercise ~ Sheets ~ IMproved} + +\ProvidesExplPackage + {xsim} + {\c_xsim_date_tl} + {\c_xsim_version_tl} + {\c_xsim_info_tl} + +% -------------------------------------------------------------------------- + +% options, information + +\bool_new:N \g_xsim_final_bool +\bool_new:N \g_xsim_verbose_bool +\bool_new:N \g_xsim_clear_aux_bool + +\keys_define:nn {xsim} + { + final .bool_gset:N = \g_xsim_final_bool , + verbose .bool_gset:N = \g_xsim_verbose_bool , + clear-aux .bool_gset:N = \g_xsim_clear_aux_bool + } + +\DeclareOption {final} + { \bool_gset_true:N \g_xsim_final_bool } + +\DeclareOption {verbose} + { \bool_gset_true:N \g_xsim_verbose_bool } + +\DeclareOption {clear-aux} + { \bool_gset_true:N \g_xsim_clear_aux_bool } + +\ProcessOptions \scan_stop: + +% -------------------------------------------------------------------------- + +% messages: +\msg_new:nnn {xsim} {rerun} + { + Exercise~ properties~ may~ have~ changed.~ Rerun~ to~ get~ them~ + synchronized. + } + +\msg_new:nnn {xsim} {verbose} { #1 ~(\msg_line_context:) } + +% -------------------------------------------------------------------------- + +\bool_new:N \g__xsim_rerun_bool + +\cs_new_protected:Npn \xsim_do_rerun: + { \xsim_if_rerun:T { \msg_warning:nn {xsim} {rerun} } } + +% -------------------------------------------------------------------------- + +% load module mechanism: +\tl_set:Nn \l_tmpa_tl {code.tex} +\@onefilewithoptions {xsim.modules} [][] \l_tmpa_tl + +% -------------------------------------------------------------------------- +\xsim_load_modules:n {definitions} + +\AtEndDocument { \xsim_do_rerun: } + +\tex_endinput:D diff --git a/Master/texmf-dist/tex/latex/xsim/xsim.tags.code.tex b/Master/texmf-dist/tex/latex/xsim/xsim.tags.code.tex new file mode 100644 index 00000000000..b438afb203e --- /dev/null +++ b/Master/texmf-dist/tex/latex/xsim/xsim.tags.code.tex @@ -0,0 +1,195 @@ +% ---------------------------------------------------------------------------- +% the XSIM package - tags module +% +% eXercise Sheets IMproved +% +% ---------------------------------------------------------------------------- +% Clemens Niederberger +% Web: https://github.com/cgnieder/xsim +% E-Mail: contact@mychemistry.eu +% ---------------------------------------------------------------------------- +% Copyright 2017 Clemens Niederberger +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +% +% This work has the LPPL maintenance status `maintained'. +% +% The Current Maintainer of this work is Clemens Niederberger. +% ---------------------------------------------------------------------------- +% If you have any ideas, questions, suggestions or bugs to report, please +% feel free to contact me. +% ---------------------------------------------------------------------------- +\XSIMmodule{tags}{tagging of exercises} + +\xsim_load_modules:n {properties} + +\seq_new:N \l__xsim_tag_types_seq +\bool_new:N \l____xsim_tagged_bool + +\cs_new_protected:Npn \xsim_set_seq_from_clist:Nn #1#2 + { + \seq_clear:N #1 + \clist_map_inline:nn {#2} + { \tl_if_blank:nF {##1} { \seq_put_right:Nn #1 {##1} } } + } +\cs_generate_variant:Nn \xsim_set_seq_from_clist:Nn {c,Nx} + +% #1: name +\cs_new_protected:Npn \xsim_new_tag_type:n #1 + { + \xsim_verbose:n { Declaring~ new~ tag~ type~ `#1'. } + \seq_put_right:Nn \l__xsim_tag_types_seq {#1} + \seq_remove_duplicates:N \l__xsim_tag_types_seq + \seq_new:c {l__xsim_chosen_tags_#1_seq} + \bool_new:c {l__xsim_ignore_untagged_#1_bool} + \bool_new:c {l____xsim_tagged_#1_bool} + \keys_define:nn {xsim} + { + #1/ingore-untagged .bool_set:c = {l__xsim_ignore_untagged_#1_bool} , + #1/ignore-untagged .initial:n = true , + #1 .code:n = + \xsim_set_seq_from_clist:cn {l__xsim_chosen_tags_#1_seq} {##1} + } + \xsim_declare_property:nnnn + { \c_false_bool } + { \c_false_bool } + { \c_false_bool } + {#1} + \__xsim_declare_printsolutions_condition:nn {#1} + { \__xsim_printsolutions_if_tagged:nnnnTF {#1} } + \keys_define:nn {xsim/print-solutions} + { + #1 .choice: , + #1/false .code:n = + \__xsim_printsolutions_condition:nn {#1} {false} , + #1/true .code:n = + \__xsim_printsolutions_condition:nn {#1} {true} , + #1/unknown .code:n = + \keys_set:nn {xsim} { #1 = ##1 } + \__xsim_printsolutions_condition:nn {#1} {true} , + #1 .initial:n = false + } + } + +% #1: tag type +% #2: exercise type +% #3: id +% #4: print|use +\prg_new_protected_conditional:Npnn + \__xsim_printsolutions_if_tagged:nnnn #1#2#3#4 {T,F,TF} + { + \xsim_if_in_list:nnTF {#4} {#2-#3=={true}} + { + \__xsim_printsolutions_if_condition:nTF {#1} + { + \__xsim_printsolutions_condition_true: + % TODO: doesn't return anything + \xsim_if_tagged:nnnTF {#2} {#3} {#1} + { \prg_return_true: } + { \prg_return_false: } + } + { \prg_return_false: } + } + { \prg_return_false: } + } + +% #1: exercise type +% #2: id +% #3: tag type +\prg_new_protected_conditional:Npnn \xsim_if_tagged:nnn #1#2#3 {T,F,TF} + { + \bool_set_false:c {l____xsim_tagged_#3_bool} + \seq_if_empty:cTF {l__xsim_chosen_tags_#3_seq} + { \bool_set_true:c {l____xsim_tagged_#3_bool} } + { + \xsim_set_seq_from_clist:Nx + \l__xsim_tmpa_seq + { \xsim_get_property:nnn {#1} {#2} {#3} } + \seq_if_empty:NTF \l__xsim_tmpa_seq + { + \bool_set_eq:cc + {l____xsim_tagged_#3_bool} + {l__xsim_ignore_untagged_#3_bool} + } + { + \seq_map_inline:Nn \l__xsim_tmpa_seq + { + \seq_if_in:cnT {l__xsim_chosen_tags_#3_seq} {##1} + { + \bool_set_true:c {l____xsim_tagged_#3_bool} + \seq_map_break: + } + } + } + } + \bool_if:cTF {l____xsim_tagged_#3_bool} + { \prg_return_true: } + { \prg_return_false: } + } + +% #1: exercise type +% #2: id +\prg_new_protected_conditional:Npnn \xsim_if_tagged:nn #1#2 {T,F,TF} + { + \bool_set_true:N \l____xsim_tagged_bool + \seq_map_inline:Nn \l__xsim_tag_types_seq + { + \xsim_if_tagged:nnnF {#1} {#2} {##1} + { + \bool_set_false:N \l____xsim_tagged_bool + \seq_map_break: + } + } + \bool_if:NTF \l____xsim_tagged_bool + { \prg_return_true: } + { \prg_return_false: } + } + + +% #1: exercise type +% #2: id +% #3: tag type +% #4: code +\cs_new_protected:Npn \xsim_foreach_exercise_tag:nnnn #1#2#3#4 + { + \xsim_set_seq_from_clist:Nx \l__xsim_tmpa_seq + { \xsim_get_property:nnn {#1} {#2} {#3} } + \seq_map_inline:Nn \l__xsim_tmpa_seq {#4} + } +\cs_generate_variant:Nn \xsim_foreach_exercise_tag:nnnn {oo} + +% #1: exercise type +% #2: id +% #3: tag type +% #4: sep +\cs_new_protected:Npn \xsim_exercise_tags_use:nnnn #1#2#3#4 + { + \xsim_set_seq_from_clist:Nx \l__xsim_tmpa_seq + { \xsim_get_property:nnn {#1} {#2} {#3} } + \seq_use:Nn \l__xsim_tmpa_seq {#4} + } +\cs_generate_variant:Nn \xsim_exercise_tags_use:nnnn {oo} + +% #1: exercise type +% #2: id +% #3: tag type +% #4: sep between two +% #5: sep between more than two +% #6: sep between last two +\cs_new_protected:Npn \xsim_exercise_tags_use:nnnnnn #1#2#3#4#5#6 + { + \xsim_set_seq_from_clist:Nx \l__xsim_tmpa_seq + { \xsim_get_property:nnn {#1} {#2} {#3} } + \seq_use:Nnnn \l__xsim_tmpa_seq {#4} {#5} {#6} + } +\cs_generate_variant:Nn \xsim_exercise_tags_use:nnnn {oo} +\cs_generate_variant:Nn \xsim_exercise_tags_use:nnnnnn {oo} + +% ---------------------------------------------------------------------------- +\tex_endinput:D diff --git a/Master/texmf-dist/tex/latex/xsim/xsim.templates.code.tex b/Master/texmf-dist/tex/latex/xsim/xsim.templates.code.tex new file mode 100644 index 00000000000..f08ff904b4c --- /dev/null +++ b/Master/texmf-dist/tex/latex/xsim/xsim.templates.code.tex @@ -0,0 +1,172 @@ +% ---------------------------------------------------------------------------- +% the XSIM package - templates module +% +% eXercise Sheets IMproved +% +% ---------------------------------------------------------------------------- +% Clemens Niederberger +% Web: https://github.com/cgnieder/xsim +% E-Mail: contact@mychemistry.eu +% ---------------------------------------------------------------------------- +% Copyright 2017 Clemens Niederberger +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +% +% This work has the LPPL maintenance status `maintained'. +% +% The Current Maintainer of this work is Clemens Niederberger. +% ---------------------------------------------------------------------------- +% If you have any ideas, questions, suggestions or bugs to report, please +% feel free to contact me. +% ---------------------------------------------------------------------------- +\XSIMmodule{templates}{properties of exercises} + +\xsim_load_modules:n {base} + +\msg_new:nnn {xsim} {unknown-template} + { + You~ are~ trying~ to~ load~ the~ template~ `#2'~ (template~ type~ `#1')~ + \msg_line_context: .~ This~ template~ does~ not~ seem~ to~ be~ defined.~ + I~ am~ using~ the~ template~ `#3'~ (template~ type~ `#1')~ instead. + } + +% #1: template type +\cs_new_protected:Npn \xsim_new_template_type:n #1 + { + \xsim_verbose:n { Declaring~ new~ template~ type~ `#1'. } + \prop_new:c {l__xsim_#1_template_prop} + } + +% #1: template type +% #2: template name +% #3: code +\cs_new_protected:Npn \__xsim_add_template:nnn #1#2#3 + { + \xsim_verbose:n { Defining~ new~ template~ `#2'~ of~ type~ `#1'. } + \tl_new:c {l__xsim_template_#1_#2_setup_tl} + \prop_put:cnn {l__xsim_#1_template_prop} {#2} {#3} + } + +\prg_new_conditional:Npnn \xsim_if_template_exists:nn #1#2 {T,F,TF} + { + \prop_if_in:cnTF {l__xsim_#1_template_prop} {#2} + { \prg_return_true: } + { \prg_return_false: } + } + +% #1: template type +% #2: template name +\cs_new_protected:Npn \__xsim_get_template:nn #1#2 + { \prop_item:cn {l__xsim_#1_template_prop} {#2} } + +% ---------------------------------------------------------------------------- + +% environment templates (types `begin' and `end'): +\xsim_new_template_type:n {begin} +\xsim_new_template_type:n {end} + +% #1: template name +% #2: begin code +% #3: end code +\cs_new_protected:Npn \xsim_declare_environment_template:nnn #1#2#3 + { + \__xsim_add_template:nnn {begin} {#1} + { + \__xsim_start_template:nn {begin} {#1} + \__xsim_start_template:nn {end} {#1} + #2 + } + \__xsim_add_template:nnn {end} {#1} + { + #3 + \__xsim_stop_template:nn {end} {#1} + \__xsim_stop_template:nn {begin} {#1} + } + } + +% ---------------------------------------------------------------------------- + +% heading templates for the solution list (type `heading'): +\xsim_new_template_type:n {heading} + +% #1: template name +% #2: code +\cs_new_protected:Npn \xsim_declare_heading_template:nn #1#2 + { + \__xsim_add_template:nnn {heading} {#1} + { + \__xsim_start_template:nn {heading} {#1} + #2 + \__xsim_stop_template:nn {heading} {#1} + } + } + +% ---------------------------------------------------------------------------- + +% grading table templates (type `table'): +\xsim_new_template_type:n {table} + +% #1: template name +% #2: code +\cs_new_protected:Npn \xsim_declare_table_template:nn #1#2 + { + \__xsim_add_template:nnn {table} {#1} + { + \__xsim_start_template:nn {table} {#1} + #2 + \__xsim_stop_template:nn {table} {#1} + } + } + +% ---------------------------------------------------------------------------- + +% using templates: +% setup up the next usage of `template name': +% #1: template type +% #2: template name +% #3: setup code +\cs_new_protected:Npn \xsim_setup_template:nnn #1#2#3 + { \tl_set:cn {l__xsim_template_#1_#2_setup_tl} {#3} } +\cs_generate_variant:Nn \xsim_setup_template:nnn {nnV} + +% #1: template type +% #2: template name +\cs_new_protected:Npn \__xsim_setup_template:nn #1#2 + { \tl_use:c {l__xsim_template_#1_#2_setup_tl} } + +% #1: template type +% #2: template name +\cs_new_protected:Npn \__xsim_clear_template_setup:nn #1#2 + { \tl_clear:c {l__xsim_template_#1_#2_setup_tl} } + +% #1: template type +% #2: template name +\cs_new_protected:Npn \__xsim_start_template:nn #1#2 + { \group_begin: \__xsim_setup_template:nn {#1} {#2} } + +% #1: template type +% #2: template name +\cs_new_protected:Npn \__xsim_stop_template:nn #1#2 + { \group_end: \__xsim_clear_template_setup:nn {#1} {#2} } + +% #1: template type +% #2: template name +\cs_new_protected:Npn \xsim_use_template:nn #1#2 + { + \xsim_if_template_exists:nnTF {#1} {#2} + { \__xsim_get_template:nn {#1} {#2} } + { + \msg_warning:nnnnn {xsim} {unknown-template} {#1} {#2} {default} + \__xsim_get_template:nn {#1} {default} + } + } +\cs_generate_variant:Nn \xsim_use_template:nn {nx,nV} + +% ---------------------------------------------------------------------------- +\tex_endinput:D diff --git a/Master/texmf-dist/tex/latex/xsim/xsim.translations.code.tex b/Master/texmf-dist/tex/latex/xsim/xsim.translations.code.tex new file mode 100644 index 00000000000..a52d3708632 --- /dev/null +++ b/Master/texmf-dist/tex/latex/xsim/xsim.translations.code.tex @@ -0,0 +1,146 @@ +% ---------------------------------------------------------------------------- +% the XSIM package - translations module +% +% eXercise Sheets IMproved +% +% ---------------------------------------------------------------------------- +% Clemens Niederberger +% Web: https://github.com/cgnieder/xsim +% E-Mail: contact@mychemistry.eu +% ---------------------------------------------------------------------------- +% Copyright 2017 Clemens Niederberger +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +% +% This work has the LPPL maintenance status `maintained'. +% +% The Current Maintainer of this work is Clemens Niederberger. +% ---------------------------------------------------------------------------- +% If you have any ideas, questions, suggestions or bugs to report, please +% feel free to contact me. +% ---------------------------------------------------------------------------- +\XSIMmodule{translations}{language settings for XSIM} + +\RequirePackage{translations} + +\msg_new:nnn {xsim} {language-not-defined} + { + You~ chose~ the~ language~ `#1'~ which~ is~ not~ defined~ by~ xsim.~ + `english'~ is~ used~ instead.~ If~ you~ just~ mistyped~ try~ again!~ + Otherwise~ contact~ the~ author~ and~ he'll~ probably~ add~ your~ language. + } + +% -------------------------------------------------------------------------- + +\bool_new:N \l__xsim_language_auto_bool +\bool_set_true:N \l__xsim_language_auto_bool +% this token list will hold the chosen language for xsim; since the +% language is either chosen automatically or by option it is only available at +% begin document +\tl_new:N \l_xsim_language_tl +\tl_set:Nn \l_xsim_language_tl {english} +\tl_new:N \l__xsim_current_language_tl + +\tl_const:Nn \c__xsim_keyword_prefix_tl {xsim-keyword-} + +% ---------------------------------------------------------------------------- + +\prop_new:N \g_xsim_translations_prop + +% translate the key #1 +\cs_new:Npn \xsim_translate:n #1 + { + \bool_if:NTF \l__xsim_language_auto_bool + { \GetTranslation { \c__xsim_keyword_prefix_tl #1 } } + { + \GetTranslationFor + { \l_xsim_language_tl } + { \c__xsim_keyword_prefix_tl #1 } + } + } + +\AtBeginDocument{ + \bool_if:NTF \l__xsim_language_auto_bool + { + \tl_set:Nx \l_xsim_language_tl + { \@trnslt@language{\@trnslt@current@language} } + } + { + \tl_set_eq:NN + \l_xsim_language_tl + \l__xsim_current_language_tl + } +} + +% ---------------------------------------------------------------------------- +% #1: keyword +% #2: language +% #3: translation +\cs_new_protected:Npn \__xsim_declare_translation:nw #1#2=#3\q_stop + { + \tl_set:Nx \l__xsim_tmpa_tl { \tl_trim_spaces:n {#2} } + \tl_set:Nx \l__xsim_tmpb_tl { \tl_trim_spaces:n {#3} } + \xsim_declare_translation:VnV + \l__xsim_tmpa_tl + {#1} + \l__xsim_tmpb_tl + } + +% #1: language +% #2: keyword +% #3: translation +\cs_new_protected:Npn \xsim_declare_translation:nnn #1#2#3 + { + \xsim_verbose:n + { Declaring~ `#1'~ tranlation~ of~ `#2':~ `#3'. } + \declaretranslation + {#1} + { \c__xsim_keyword_prefix_tl #2 } + {#3} + \prop_gput:Nnn \g_xsim_translations_prop {#2(#1)} {#3} + } +\cs_generate_variant:Nn \xsim_declare_translation:nnn {V,VnV} + +% #1: key +% #2: csv list: { <lang1> = <translation1> , <lang2> = <translation2> } +\cs_new_protected:Npn \xsim_declare_translations:nn #1#2 + { + \clist_map_inline:nn {#2} + { \__xsim_declare_translation:nw {#1} ##1 \q_stop } + } + +\cs_new:Npn \__xsim_parse_translate_list_entry:nnn #1#2#3 {} + +\cs_new_protected:Npn \__xsim_parse_translate_list_entry:www #1(#2)\q_mark#3\q_stop + { \__xsim_parse_translate_list_entry:nnn {#1} {#2} {#3} } + +\cs_new_protected:Npn \xsim_for_all_translations_do:n #1 + { + \cs_set:Npn \__xsim_parse_translate_list_entry:nnn ##1##2##3 {#1} + \prop_map_inline:Nn \g_xsim_translations_prop + { \__xsim_parse_translate_list_entry:www ##1 \q_mark ##2 \q_stop } + } + +% ---------------------------------------------------------------------------- + +\keys_define:nn {xsim} + { + language .value_required:n = true , + language .code:n = + \tl_if_eq:nnTF {#1} {auto} + { \bool_set_true:N \l__xsim_language_auto_bool } + { + \bool_set_false:N \l__xsim_language_auto_bool + \tl_set:Nn \l__xsim_current_language_tl {#1} + } , + language .initial:n = auto + } + +% ---------------------------------------------------------------------------- +\tex_endinput:D diff --git a/Master/texmf-dist/tex/latex/xsim/xsim.verbwrite.code.tex b/Master/texmf-dist/tex/latex/xsim/xsim.verbwrite.code.tex new file mode 100644 index 00000000000..ae0338463b1 --- /dev/null +++ b/Master/texmf-dist/tex/latex/xsim/xsim.verbwrite.code.tex @@ -0,0 +1,208 @@ +% ---------------------------------------------------------------------------- +% the XSIM package - verbwrite module +% +% eXercise Sheets IMproved +% +% ---------------------------------------------------------------------------- +% Clemens Niederberger +% Web: https://github.com/cgnieder/xsim +% E-Mail: contact@mychemistry.eu +% ---------------------------------------------------------------------------- +% Copyright 2017 Clemens Niederberger +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +% +% This work has the LPPL maintenance status `maintained'. +% +% The Current Maintainer of this work is Clemens Niederberger. +% ---------------------------------------------------------------------------- +% If you have any ideas, questions, suggestions or bugs to report, please +% feel free to contact me. +% ---------------------------------------------------------------------------- +\XSIMmodule{verbwrite}{write contents of environments verbatim to files} + +\xsim_load_modules:n {base} + +\iow_new:N \l__file_contents_iow +\tl_new:N \l_xsim_file_begin_tl +\tl_new:N \l_xsim_file_end_tl +\int_new:N \l_xsim_line_gobble_int +\int_zero:N \l_xsim_line_gobble_int + +\tl_const:Nx \c__xsim_backslash_char_tl { \cs_to_str:N \\ } + +\group_begin: + \char_set_catcode_other:n {37} + \tl_const:Nn \c__xsim_percent_char_tl {%} +\group_end: + +% ---------------------------------------------------------------------------- + +% the `final' option will prevent writing to files: +% #1: write stream +% #2: file name +\cs_new_protected:Npn \__xsim_open_stream:Nn #1#2 + { + \file_if_exist:nTF {#2} + { \xsim_if_final:F { \iow_open:Nn #1 {#2} } } + { + % \g_xsim_final_bool is a global variable; however, if it is true and + % the exercise file doesn't exist, yet, we need to set it locally to + % false in order to ensure that the file is correctly written and the + % stream closed afterwards + \bool_set_false:N \g_xsim_final_bool + \iow_open:Nn #1 {#2} + } + } + +% #1: write stream +\cs_new_protected:Npn \__xsim_close_stream:N #1 + { \xsim_if_final:F { \iow_close:N #1 } } + +% #1: write stream +% #1: contents +\cs_new_protected:Npn \__xsim_write_to_stream:Nn #1#2 + { + \xsim_if_final:F + { + % remove the /one/ space token with catcode 10 that is inserted if + % no options are given to the surrounding environment: + \tl_set:Nn \l__xsim_tmpa_tl {#2} + \tl_remove_once:Nn \l__xsim_tmpa_tl {~} + \int_zero:N \l__xsim_tmpa_int + \int_while_do:nn { \l__xsim_tmpa_int < \l_xsim_line_gobble_int } + { + \int_incr:N \l__xsim_tmpa_int + \tl_set:Nx \l__xsim_tmpa_tl { \tl_tail:N \l__xsim_tmpa_tl } + } + \iow_now:NV #1 \l__xsim_tmpa_tl + } + } +\cs_generate_variant:Nn \__xsim_write_to_stream:Nn {Nx} + +\cs_new:Npn \__xsim_tab: { \c_space_tl \c_space_tl } +\cs_new:Npn \__xsim_par: { ^^J ^^J } + +% the following is inspired by the definition of the `filecontents' +% environment: +% #1: boolean - if true an active eol needs to be inserted before +% starting to write +% #2: file name +\cs_new_protected:Npn \xsim_file_write_start:nn #1#2 + { + % we need to insert an active ^^M if no options are given + % see http://tex.stackexchange.com/q/9035/5049 reasons + \use:nx + { \__xsim_file_write_start:n {#2} } + { \bool_if:nF {#1} { \c__xsim_active_eol_tl } } + } +\cs_generate_variant:Nn \xsim_file_write_start:nn {nV} + +\group_begin: +\char_set_catcode_active:n {13} % ^^M (carriage return, endlinechar) +\char_set_catcode_active:n {12} % ^^L (form feed) +\char_set_catcode_active:n {9} % ^^I (horizontal tab) +% +\tl_const:Nn \c__xsim_active_eol_tl {^^M} % +% +% #1: file name +\cs_new_protected:Npn \__xsim_file_write_start:n #1 % + { % + \group_begin: % + \xsim_if_final:TF % + { \xsim_verbose:x { Not~ (re-)writing~ file~ `#1'. } } % + { \xsim_verbose:x { (Re-)writing~ file~ `#1'. } } % + \__xsim_open_stream:Nn \l__file_contents_iow {#1} % + \tl_if_blank:VF \l_xsim_file_begin_tl % + { % + \xsim_if_final:F % + { % + \iow_now:Nx \l__file_contents_iow % + { \l_xsim_file_begin_tl } % + } % + } % + \seq_map_inline:Nn \l_char_special_seq % + { \char_set_catcode_other:N ##1 } % + \int_step_inline:nnnn {128} {1} {255} % + { \char_set_catcode_letter:n {##1} } % + \tl_set:Nx \l__xsim_tmpa_tl % + { \c__xsim_backslash_char_tl end \cs_to_str:N \{ \@currenvir \cs_to_str:N \} } % + \use:x % + { % + \cs_set:cpn {__xsim_tmpa:www} % + ####1 \l__xsim_tmpa_tl % + ####2 \l__xsim_tmpa_tl % + ####3 \exp_not:N \q_stop: % + } % + { % + \tl_if_blank:nTF {##3} % + { \__xsim_write_to_stream:Nn \l__file_contents_iow {##1} } % + { % + \cs_set:Npx \__xsim_M:w { \exp_not:N \end {\@currenvir} } % + \char_set_active_eq:nN {13} \__xsim_M:w % + % the last line is `##1 \end{\@currenvir} ##2': + % \tl_if_blank:nF {##1} % + % { \__xsim_write_to_stream:Nn \l__file_contents_iow {##1} }% + % \tl_if_blank:nF {##2} % + % {}% + } % + ^^M % + } % + \char_set_catcode_active:n {13} % + \char_set_catcode_active:n {12} % + \char_set_catcode_active:n {9} % + \cs_set:Npx \__xsim_M:w ##1 ^^M % + { % + \exp_not:N \__xsim_tmpa:www ##1 % + \l__xsim_tmpa_tl % + \l__xsim_tmpa_tl % + \exp_not:N \q_stop: % + } % + \char_set_active_eq:nN {13} \__xsim_M:w % + \char_set_active_eq:nN {12} \__xsim_par: % + \char_set_active_eq:nN {9} \__xsim_tab: % + } % +\group_end: + +\cs_new_protected:Npn \xsim_file_write_stop: + { + \tl_if_blank:VF \l_xsim_file_end_tl + { + \xsim_if_final:F + { + \iow_now:Nx \l__file_contents_iow + { \l_xsim_file_end_tl } + } + } + \__xsim_close_stream:N \l__file_contents_iow + \group_end: + } + +% ---------------------------------------------------------------------------- + +\NewDocumentCommand \XSIMfilewritestart {sm} + { + \IfBooleanTF {#1} + { \xsim_file_write_start:nn { \c_false_bool } {#2} } + { \xsim_file_write_start:nn { \c_true_bool } {#2} } + } + +\NewDocumentCommand \XSIMfilewritestop {} + { \xsim_file_write_stop: } + +\NewDocumentCommand \XSIMsetfilebegin {+m} + { \tl_set:Nn \l_xsim_file_begin_tl {#1} } + +\NewDocumentCommand \XSIMsetfileend {+m} + { \tl_set:Nn \l_xsim_file_end_tl {#1} } + +\NewDocumentCommand \XSIMgobblechars {m} + { \int_set:Nn \l_xsim_line_gobble_int {#1} } + +% ---------------------------------------------------------------------------- diff --git a/Master/texmf-dist/tex/latex/xsim/xsimverb.sty b/Master/texmf-dist/tex/latex/xsim/xsimverb.sty new file mode 100644 index 00000000000..da6ab48c9ee --- /dev/null +++ b/Master/texmf-dist/tex/latex/xsim/xsimverb.sty @@ -0,0 +1,66 @@ +% ---------------------------------------------------------------------------- +% the XSIMVERB package +% +% write environments verbatim to files +% +% ---------------------------------------------------------------------------- +% Clemens Niederberger +% Web: https://github.com/cgnieder/xsim +% E-Mail: contact@mychemistry.eu +% ---------------------------------------------------------------------------- +% Copyright 2017 Clemens Niederberger +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +% +% This work has the LPPL maintenance status `maintained'. +% +% The Current Maintainer of this work is Clemens Niederberger. +% ---------------------------------------------------------------------------- +% If you have any ideas, questions, suggestions or bugs to report, please +% feel free to contact me. +% ---------------------------------------------------------------------------- + +\@ifpackageloaded{xsim}{\endinput}{} +\RequirePackage {expl3,xparse} +\ExplSyntaxOn + +\tl_const:Nn \c_xsimverb_date_tl {2017/03/19} +\tl_const:Nn \c_xsimverb_version_major_number_tl {0} +\tl_const:Nn \c_xsimverb_version_minor_number_tl {1} +\tl_const:Nn \c_xsimverb_version_subrelease_tl {} +\tl_const:Nx \c_xsimverb_version_number_tl + { + \c_xsimverb_version_major_number_tl . + \c_xsimverb_version_minor_number_tl + } +\tl_const:Nx \c_xsimverb_version_tl + { + \c_xsimverb_version_number_tl + \c_xsimverb_version_subrelease_tl + } +\tl_const:Nn \c_xsimverb_info_tl {write environments verbatim to files} + +\ProvidesExplPackage + {xsimverb} + {\c_xsimverb_date_tl} + {\c_xsimverb_version_tl} + {\c_xsimverb_info_tl} + +% -------------------------------------------------------------------------- + +% load module mechanism: +\tl_set:Nn \l_tmpa_tl {code.tex} +\@onefilewithoptions {xsim.modules} [][] \l_tmpa_tl + +% -------------------------------------------------------------------------- + +\xsim_load_module:n {verbwrite} + +% -------------------------------------------------------------------------- +\tex_endinput:D diff --git a/Master/tlpkg/bin/tlpkg-ctan-check b/Master/tlpkg/bin/tlpkg-ctan-check index 4cc40e17c97..54c9760b053 100755 --- a/Master/tlpkg/bin/tlpkg-ctan-check +++ b/Master/tlpkg/bin/tlpkg-ctan-check @@ -670,7 +670,7 @@ my @TLP_working = qw( xii xifthen xint xits xkeyval xlop xltxtra xmltex xmpincl xnewcommand xoptarg xpatch xpeek xpiano xpicture xpinyin xprintlen xpunctuate - xq xsavebox xskak xstring xtab xunicode + xq xsavebox xsim xskak xstring xtab xunicode xwatermark xyling xymtex xypic xypic-tut-pt xytree yafoot yagusylo yaletter yannisgr yathesis yax ycbook ydoc yfonts yfonts-t1 yhmath diff --git a/Master/tlpkg/libexec/ctan2tds b/Master/tlpkg/libexec/ctan2tds index 33f0f0d7855..36658036b9b 100755 --- a/Master/tlpkg/libexec/ctan2tds +++ b/Master/tlpkg/libexec/ctan2tds @@ -1272,6 +1272,7 @@ chomp ($Build = `cd $Master/../Build/source && pwd`); 'wsuipa' => '&PREHOOK_wsuipa', 'yathesis' => '&PREHOOK_flatten1', 'xepersian' => '&PREHOOK_flatten1', + 'xsim' => '&PREHOOK_xsim', ); @@ -1370,6 +1371,7 @@ chomp ($Build = `cd $Master/../Build/source && pwd`); 'velthuis' => '&POSTvelthuis', 'xecyr' => '&POSTxecyr', 'xetex-pstricks' => '&POSTxetexpstricks', + 'xsim' => '&POSTxsim', 'xymtex' => '&POSTxymtex', 'zhmetrics' => '&POSTzhmetrics', ); @@ -5316,6 +5318,12 @@ sub PREHOOK_wsuipa { &SYSTEM ("$MV changes/* doc/* macros/* mf/* pk/* tfm/* ."); } +sub PREHOOK_xsim { + print "PREHOOK_$package - flatten doc, but not others\n"; + # we want doc files at top, but keep examples/ and code/ subdirs + &SYSTEM ("$MV doc/* ."); +} + sub prehook_pod2man { my ($author,@scripts) = @_; @@ -6261,6 +6269,11 @@ sub POSTxetexpstricks { # &mv_with_mkdir ("*", "$DEST/xindy/modules/lang/persian/"); #} +sub POSTxsim { + print "POST$package - move code/ subdir\n"; + &mv_with_mkdir ("code/*", "$DEST/tex/latex/$package"); +} + sub POSTxymtex { print "POST$package - rm .BAK old-doc, move subdirectories\n"; &SYSTEM ("rm -rf old-doc"); diff --git a/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc b/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc index da0c0fb3e8f..332eda7a22c 100644 --- a/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc +++ b/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc @@ -1131,6 +1131,7 @@ depend xpeek depend xprintlen depend xpunctuate depend xsavebox +depend xsim depend xstring depend xtab depend xwatermark diff --git a/Master/tlpkg/tlpsrc/xsim.tlpsrc b/Master/tlpkg/tlpsrc/xsim.tlpsrc new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/Master/tlpkg/tlpsrc/xsim.tlpsrc |