diff options
Diffstat (limited to 'Master')
-rw-r--r-- | Master/texmf-dist/doc/latex/exsheets/README | 46 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/exsheets/exsheets_en.pdf | bin | 0 -> 681099 bytes | |||
-rw-r--r-- | Master/texmf-dist/doc/latex/exsheets/exsheets_en.tex | 2118 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/exsheets/cntformats.sty | 324 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/exsheets/exsheets.sty | 2045 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/exsheets/exsheets_configurations.cfg | 5 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/exsheets/exsheets_headings.cfg | 302 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/exsheets/exsheets_headings.def | 371 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/exsheets/exsheets_tasks.cfg | 56 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/exsheets/exsheets_tasks.def | 334 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/exsheets/translations.sty | 311 | ||||
-rw-r--r-- | Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc | 1 | ||||
-rw-r--r-- | Master/tlpkg/tlpsrc/exsheets.tlpsrc | 0 |
13 files changed, 5913 insertions, 0 deletions
diff --git a/Master/texmf-dist/doc/latex/exsheets/README b/Master/texmf-dist/doc/latex/exsheets/README new file mode 100644 index 00000000000..4ac38eeb800 --- /dev/null +++ b/Master/texmf-dist/doc/latex/exsheets/README @@ -0,0 +1,46 @@ +-------------------------------------------------------------------------- +EXSHEETS v0.2b - 2012/10/08 + +bundled packages: +the EXSHEETS package + Yet another package for the creation of exercise sheets +the TRANSLATIONS package + a simple translator +the CNTFORMATS package + A different way to read counters. + +All mentioned packages are described in exsheets_en.pdf +-------------------------------------------------------------------------- +Clemens Niederberger +Web: https://bitbucket.org/cgnieder/exsheets/ +E-Mail: contact@mychemistry.eu +-------------------------------------------------------------------------- +Copyright 2011-2012 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 exsheets package consists of the files + - exsheets.sty, exsheets_headings.def, exsheets_headings.cfg, + exsheets_tasks.def, exsheets_tasks.cfg, exsheets_configurations.cfg, + - exsheets_en.tex, exsheets_en.pdf, + - README +-------------------------------------------------------------------------- +The translations package consists of the files + - translations.sty +-------------------------------------------------------------------------- +The cntformats package consists of the files + - cntformats.sty +-------------------------------------------------------------------------- +If you have any ideas, questions, suggestions or bugs to report, please +feel free to contact me. +--------------------------------------------------------------------------
\ No newline at end of file diff --git a/Master/texmf-dist/doc/latex/exsheets/exsheets_en.pdf b/Master/texmf-dist/doc/latex/exsheets/exsheets_en.pdf Binary files differnew file mode 100644 index 00000000000..8125d021770 --- /dev/null +++ b/Master/texmf-dist/doc/latex/exsheets/exsheets_en.pdf diff --git a/Master/texmf-dist/doc/latex/exsheets/exsheets_en.tex b/Master/texmf-dist/doc/latex/exsheets/exsheets_en.tex new file mode 100644 index 00000000000..f8e2eefd934 --- /dev/null +++ b/Master/texmf-dist/doc/latex/exsheets/exsheets_en.tex @@ -0,0 +1,2118 @@ +% arara: pdflatex +% arara: biber +% arara: pdflatex +% arara: pdflatex +% -------------------------------------------------------------------------- +% the EXSHEETS package +% +% Yet another package for the creation of exercise sheets +% +% -------------------------------------------------------------------------- +% Clemens Niederberger +% Web: https://bitbucket.org/cgnieder/exsheets/ +% E-Mail: contact@mychemistry.eu +% -------------------------------------------------------------------------- +% Copyright 2011-2012 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 exsheets package consists of the files +% - exsheets.sty, exsheets_headings.def, exsheets_headings.cfg, +% exsheets_tasks.def, exsheets_tasks.cfg, exsheets_configurations.cfg, +% - exsheets_en.tex, exsheets_en.pdf, +% - README +% -------------------------------------------------------------------------- +% If you have any ideas, questions, suggestions or bugs to report, please +% feel free to contact me. +% -------------------------------------------------------------------------- +% +% if you want to compile this documentation you'll need the document class +% `cnpkgdoc' which you can get here: +% https://bitbucket.org/cgnieder/cnpkgdoc/ +% the class is licensed LPPL 1.3 or later +% +% use `xelatex' and `biber' for compilation +% +\RequirePackage{setspace} +\documentclass[DIV10,toc=index,toc=bib,numbers=noendperiod]{cnpkgdoc} +% ---------------------------------------------------------------------------- +% document layout and typographic features +\docsetup{ + pkg = {[load-headings,load-tasks]exsheets} , + url = {https://bitbucket.org/cgnieder/exsheets/} , + title = ExSheets , + name = ExSheets , + language = en , + modules = true , + code-box = { + backgroundcolor = gray!7!white , + skipbelow = .6\baselineskip plus .5ex minus .5ex , + skipabove = .6\baselineskip plus .5ex minus .5ex , + innerleftmargin = 1.5em , + innerrightmargin = 2.5em + } , + gobble = 1 +} +\cnpkgusecolorscheme{friendly} + +\usepackage{embrac}[2012/06/29] + \ChangeEmph{[}[,.02em]{]}[.055em,-.08em] + \ChangeEmph{(}[-.01em,.04em]{)}[.04em,-.05em] +\usepackage{microtype} +\usepackage[multiple]{fnpct} + +\renewcommand*\othersectionlevelsformat[3]{\textcolor{main}{#3\autodot}\enskip} +\renewcommand*\partformat{\textcolor{main}{\partname~\thepart\autodot}} + +\pagestyle{headings} + +\setcapindent{1.5em} +\setkomafont{caption}{\normalfont\footnotesize\sffamily} +\setkomafont{captionlabel}{\normalfont\footnotesize\sffamily\scshape} + +\usepackage{booktabs,array,ragged2e} + +% ---------------------------------------------------------------------------- +% code examples +% ExSheets: +\addcmds{ + acs, addpoints, blank, bigstar, bottomrule, citetitle, cmd, color, + DeclareInstance, DeclareTemplateInterface, DeclareQuestionProperty, + DebugExSheets, endspacing, GetQuestionProperty, grade, includequestions, + midrule, points, PrintIfIncludeActiveF, PrintIfIncludeActiveT, + PrintIfIncludeActiveTF, printsolutions, PrintSolutionsTF, + QuestionNumber, s, sample, setlength, SetQuestionProperties, SetupExSheets, + spacing, square, sumpoints, tabcolsep, task, textcite, textcolor, toprule, + totalpoints +} + +% translations: +\newcommand*\translations{{\scshape\textcolor{main}{translations}}\xspace} +\addcmds{ + cuisine, DeclareLanguage, DeclareLanguageAlias, DeclareTranslation, + GetTranslation, GetTranslationFor, kitchen, LoadDictionary, + LoadDictionaryFor, NewTranslation, ProvideDictionaryFor, + RenewTranslation, SaveTranslation, SaveTranslationFor, selectlanguage +} + +% cntformats: +\newcommand*\cntformats{{\scshape\textcolor{main}{cntformats}}\xspace} +\addcmds{ + @cntfmts@parsed@pattern, AddCounterPattern, eSaveCounterPattern, + NewCounterPattern, ReadCounterFrom, ReadCounterPattern, + ReadCounterPatternFrom, SaveCounterPattern, tmpa, tmpb +} + +% ---------------------------------------------------------------------------- +% other packages, bibliography, index +\usepackage{xcoffins,wasysym,enumitem,acro,booktabs,siunitx} +\DeclareAcronym{id}{id}{Identifier} +\DeclareAcronymFormat{id}{\scshape} + +\usepackage{filecontents} +\begin{filecontents}{\jobname.ist} + heading_prefix "{\\bfseries " + heading_suffix "\\hfil}\\nopagebreak\n" + headings_flag 1 + delim_0 "\\dotfill " + delim_1 "\\dotfill " + delim_2 "\\dotfill " + delim_r "\\textendash" + suffix_2p "\\nohyperpage{\\,f.}" + suffix_3p "\\nohyperpage{\\,ff.}" +\end{filecontents} + +\usepackage{imakeidx} +% \indexsetup{level=\section*} +\makeindex[intoc,options={-sl \jobname.ist}] + +\usepackage{csquotes} +\usepackage[backend=biber]{biblatex} +\addbibresource{biblatex-examples.bib} +\addbibresource{\jobname.bib} + +\begin{filecontents}{\jobname.bib} +@package{answers, + title = {answers}, + author = {Mike Piff}, + maintainer = {Joseph Wright}, + date = {2010-10-11}, + version = {2.13}, + url = {http://www.ctan.org/pkg/answers/} +} +@package{enumitem, + title = {enumitem}, + author = {Javier Bezos}, + date = {2011-09-28}, + version = {3.5.2}, + url = {http://www.ctan.org/pkg/enumitem/} +} +@package{exam, + title = {exam}, + author = {Philip Hirschhorn}, + date = {2011-05-22}, + version = {2.4}, + url = {http://www.ctan.org/pkg/exam/} +} +@package{examdesign, + title = {examdesign}, + author = {Jason Alexander}, + date = {2001-03-26}, + version = {1.1}, + url = {http://www.ctan.org/pkg/examdesign/} +} +@package{exercise, + title = {exercise}, + author = {Paul Pichaureau}, + date = {2012-05-08}, + version = {1.58}, + url = {http://www.ctan.org/pkg/answers/} +} +@package{multienum, + title = {multienum}, + author = {Dennis Kletzing}, + date = {2005-05-19}, + version = {n.n.}, + url = {http://www.ctan.org/pkg/multienum/} +} +@package{probsoln, + title = {probsoln}, + author = {Nicola L. C. Talbot}, + date = {2011-12-10}, + version = {3.02}, + url = {http://www.ctan.org/pkg/probsolns/} +} +\end{filecontents} + +% ---------------------------------------------------------------------------- +% example definitions that have to be done in the preamble: +\DeclareQuestionProperty{points} +\DeclareQuestionProperty{notes} +\DeclareQuestionProperty{reference} +\DeclareQuestionProperty{topic} + +\DeclareRelGrades{ + 1 = 1 , + {1,5} = .9167 , + 2 = .8333 , + {2,5} = .75 , + 3 = .6667 , + {3,5} = .5833 , + 4 = .5 +} + +\DeclareTranslation{English}{Kueche}{kitchen} +\DeclareTranslation{German}{Kueche}{K\"uche} +\DeclareTranslation{Spanish}{Kueche}{cocina} +\DeclareTranslation{French}{Kueche}{cuisine} + +\usepackage{alphalph} +\makeatletter +\NewPatternFormat{aa}{\alphalph@alph} +\makeatother +\NewCounterPattern{testa}{ta} + +% ---------------------------------------------------------------------------- +% custom commands +\newcommand*\Default[1]{% + \hfill\llap + {% + \ifblank{#1}% + {(initially~empty)}% + {Default:~\code{#1}}% + }% + \newline +} +\newcommand*\required{\hfill\llap{required}\newline} +\newcommand*\optional{\hfill\llap{optional}\newline} + +\newcommand*\nooption[2]{\item[\code{\textcolor{key}{#1} = #2}] \cnpkgdocarrow\ } + +\newcommand*\unexpsign{$\RHD$} +\newcommand*\expsign{\textcolor{red}{$\rhd$}} +\renewcommand*\cnpkgdoctriangle{\unexpsign} +\newcommand*\expandable{% + \def\cnpkgdoctriangle{% + \expsign + \gdef\cnpkgdoctriangle{\unexpsign}}} + +% ---------------------------------------------------------------------------- +% title page +\TitlePicture{% + \parbox{.8\linewidth}{% + \ExSheets provides means to create exercises or questions and their + corresponding solutions. The questions can be divided into classes and/or + topics and can be printed selectively. Meta-data to questions can be added + and recovered.\par + The solutions may be printed where they are, can be collected and printed at + a later point in the document alltogether or section-wise or selectively by + \acs{id}.\par + \ExSheets provides a comprehensive interface for styling the headings of + questions and solutions.}} + +\begin{document} +\part{Preliminary}\secidx{Preliminary} +\section{Licence and Requirements} +\secidx[Licence]{Preliminary}\secidx[Requirements]{Preliminary} +\ExSheets is placed under the terms of the LaTeX Project Public License, +version 1.3 or later (\url{http://www.latex-project.org/lppl.txt}). +It has the status ``maintained.'' + +\ExSheets loads and needs the following packages: \paket*{l3kernel}, +\paket{xparse}, \paket{xtemplate}, \paket{l3sort}, \paket{l3keys2e}, +\paket{xcolor}, \paket{ulem}, \paket{etoolbox}, \paket{environ}, \paket{lcg} +and \paket{silence}. \ExSheets calls \cmd{normalem} (from the \paket{ulem} package). + +\section{Motivation}\secidx[Motivation]{Preliminary} +There are already quite a number of packages that allow the creation of exercise +sheets or written exams. Just to name the most common ones: \paket{exam}~\cite{exam}, +\paket{examdesign}~\cite{examdesign}, \paket{exercise}~\cite{exercise}, +\paket{probsoln}~\cite{probsoln}, \paket{answers}~\cite{answers} (and +\href{http://www.ctan.org/characterization/primary/document-types/exams-exercise-sets-and-answers/}{many more}). + +One thing I missed in all packages that I've tried out\footnote{Well, probably I +didn't try hard enough\ldots} was a high flexibility in choosing which questions +and solutions should be printed, where which solutions should be printed and so +on, combined with the possibility to assign questions to different classes so one +could for example create two versions of an exam out of the box. And --~I can't +get enough~-- I also want to be able to use/design different layouts for questions +additional to a standard section-like format. All these points are realized in +\ExSheets. + +Additionally one should be able to assign some sort of meta-data to questions +that of course should be easily reusable. How this can be done is explained +in section~\ref{sec:additional_info}. + +Then there is --~at least in Germany~-- the habit of having lists of exercises +aligned in columns but counting from the left to the right instead from up to +down. \ExSheets provides a possibility for that (see section~\ref{sec:tasks}). +I am not quite content with it as it works now, though\footnote{There are still +other possibilities, for example take a look here: +\url{http://tex.stackexchange.com/questions/67966/enumerate-in-multicols} or at +the \paket*{multienum} package~\cite{multienum}.}. + +On the other hand \ExSheets doesn't --~and probably won't~-- offer a real +possibility for creating multiple choice questions. As a fact it doesn't provide +many (if any) means to specify the \emph{type} of question or the structure. If +these are your needs take a look at \paket{examdesign}, for example. Or exploit +the possibilities \paket{enumitem}~\cite{enumitem} gives you. + +I had the idea for this package in 2008. Back then my \TeX\ skills were by far +not good enough to write it. Actually, even today I wouldn't have been able to +realize it without all the l3 packages like \paket*{l3kernel} and \paket*{l3packages}. +I actively began to develop \ExSheets in spring 2011 but it wasn't until now +(September 2012) that I consider it stable enough for wider usage. At the time +of writing (\today) there still are probably lots of rough edges let alone bugs +so I am very interested in all kinds of feedback. + +\section{Additional Packages} +\ExSheets actually bundles three packages: \ExSheets, \translations and \cntformats. +\translations is described in part~\ref{part:translations} and \cntformats in +part~\ref{part:cntformats}. These two packages provide functionality that is used +by \ExSheets. They can, however, be used independently from \ExSheets. + +\section{Installation}\secidx[Installation]{Preliminary} +If you install \ExSheets manually beware to put the files +\begin{itemize} + \item[]\verb+exsheets_headings.def+ + \item[]\verb+exsheets_headings.cfg+ + \item[]\verb+exsheets_tasks.def+ + \item[]\verb+exsheets_tasks.cfg+ +\end{itemize} +in the same directory as the \code{exsheets.sty} file\footnote{That is, a directory +like \code{texmf-local/tex/latex/exsheets}, probably}. You \emph{can} install the +other two packages, \translations and \cntformats, in different locations but since +they belong to \ExSheets they probably should be placed in the same directory. + +As with every manual package installation you need to make sure to put the files +in a directory where \TeX\ can find them and afterwards update the database. +\secidx*{Preliminary} + +\part{The \ExSheets package}\label{part:exsheets}\secidx{\ExSheets}[ExSheets] +\section{Package Usage} +\subsection{Setup}\secidx{Setup} +The \ExSheets package has three different types of options, kind of. The first +type are the classic package options which are used when you load \ExSheets: +\begin{beispiel}[code only] + \usepackage[<options>]{exsheets} +\end{beispiel} +These options are described in section~\ref{sec:options}. + +The second type are options that belong to a specific environment or command. +These options are either used directly with the environment/command +\begin{beispiel}[code only] + \begin{env}[<options>] + ... + \end{env} +\end{beispiel} +or can be set with the setup command: +\begin{beschreibung} + \Befehl{SetupExSheets}[<module>]{<options>} +\end{beschreibung} +The options of the second type all belong to \textcolor{module}{\code{modules}}. +Let's say you want to specify some options of the \code{question} environment. +You can then say the following: +\begin{beispiel}[code only] + \SetupExSheets[question]{option1,option2=value2} + % or: + \SetupExSheets{question/option1,question/option2=value2} +\end{beispiel} +The \textcolor{module}{\code{module}} an option belongs to is written in the left +margin next to the when the option is described. + +The third type aren't options at all, actually. However, thanks to the great +\paket{xtemplate} package you are able to define your own instances of some of +the objects used be \ExSheets. This is explained in a little more detail in +part~\ref{part:style} on page~\pageref{part:style}\,ff. +\secidx*{Setup} + +\subsection{Package Options}\label{sec:options}\secidx{Package Options} +The package \ExSheets has some options, namely the following ones: +\begin{beschreibung} + %% color + \Option{color}{<colour>}\Default{exsheetsblue} + A custom colour that is used in certain but very rare circumstances. + %% counter-format + \Option{counter-format}{<counter-format>}\Default{qu.} + Formatting of the counter of the questions. This option takes a special kind + of string that is described in section~\ref{ssec:counter}. + \Option{counter-within}{<counter>}\Default{} + Resets the \code{question} counter with every step of \code{<counter>}. + %% headings + \Option{headings}{<instance>}\Default{block} + Choose the style of the questions' and solutions' headings. There are two + predefined styles: \code{block} and \code{runin}. + %% headings-format + \Option{headings-format}{<code>}\Default{\cmd{normalsize}\cmd{bfseries}} + This code is placed immediately before the headings of the questions and + solutions. + %% load-headings + \Option{load-headings}{\default{true}|false}\Default{false} + Loads additional styles for the headings. More on this is described in + section~\ref{sec:exsheets-headings}. + %% load-tasks + \Option{load-tasks}{\default{true}|false}\Default{false} + Loads additional styles for the \code{tasks} environment. See section~\ref{sec:tasks}. + %% totoc + \Option{totoc}{\default{true}|false}\Default{false} + This option adds the questions and solutions with their names and numbers to + the table of contents. + %% questions-totoc + \Option{questions-totoc}{\default{true}|false}\Default{false} + This option adds the questions with their names and numbers to the table of + contents. + %% solutions-totoc + \Option{solutions-totoc}{\default{true}|false}\Default{false} + This option adds the solutions with their names and numbers to the table of + contents. + %% toc-level + \Option{toc-level}{<toc level>}\Default{subsection} + This option sets the level in which questions and solutions should appear in + the table of contents. + %% questions-toc-level + \Option{questions-toc-level}{<toc level>}\Default{subsection} + This option sets the level in which questions should appear in the table of + contents. + %% solutions-toc-level + \Option{solutions-toc-level}{<toc level>}\Default{subsection} + This option sets the level in which solutions should appear in the table of + contents. + %% use-ref + \Option{use-ref}{\default{true}|false}\Default{false} + enable referencing to sections and chapters in a way that the references can + be used with \cmd{printsolutions}, see section~\ref{sssec:print_specific_section} + for details. +\end{beschreibung} +The \code{toc} options are demonstrated with section~\ref{sec:solutions:list} and +the solutions printed there being listed in the table of contents. +\secidx*{Package Options} + +\subsection{Create Questions/Exercises and their Solutions} +Now, let's start with the most important part: the questions and (possibly) their +respective solutions. +\subsubsection{The \code{question} Environment}\label{ssec:questions} +Questions are written inside the \code{question} environment: +\begin{beschreibung} + \Umg{question}[<options>]{\unskip\ma{<points>} ... } +\end{beschreibung} +\begin{beispiel} + \begin{question} + This is our very first very difficult to solve question! + \end{question} +\end{beispiel} +As you can see a heading is automatically created and the question is numbered. +You can of course change both the numbering and the naming, but more on that later. + +The \code{question} environment takes an optional argument \ma{<points>} that can +be used to assign points to the question (as is common in written exams): +\begin{beispiel} + \begin{question}{3} + This is our first difficult question that is worth 3 points! + \end{question} +\end{beispiel} +These points are saved internally (see section~\ref{sec:points} for reasons why) +and are written to the right margin next to the question heading in the default +setting. + +You can also assign bonus points by inserting \code{<point>+<bonus points>} as +argument. +\begin{beispiel} + \begin{question}{1+1} + This question is worth 1 point and 1 bonus point. + \end{question} + \begin{question}{+3} + This question is a bonus question. It is worth 3 bonus points. + \end{question} +\end{beispiel} + +\subsubsection{Options to the \code{question} Environment}\secidx[options]{questions} +The \code{question} environment takes one or more of the following options: +\begin{beschreibung} + \Option[question]{type}{exam|exercise}\Default{exercise} + determines the type of question and changes the default name of a question + from ``Exercise'' to ``Question''. These default names are language dependent.\\ + If you use \cmd*{usepackage}[ngerman]{babel}, for example, then the names + are ``\"Ubung and ``Aufgabe''. + \Option[question]{name}{<name>}\Default{} + sets a custom name. All predefined names are discarded. + \Option[question]{print}{\default{true}|false}\Default{true} + prints or hides the question. + \Option[question]{ID}{<id>}\Default{} + assigns a custom \acs{id} to the question. See section~\ref{ssec:ids} for further + information. + \Option[question]{class}{<class>}\Default{} + assigns a class to the question. See section~\ref{sec:classes} for further + information. + \Option[question]{topic}{<topic>}\Default{} + assigns a topic to the question. See section~\ref{sec:topics} for further + information. + \Option[question]{use}{\default{true}|false}\Default{true} + discards the question. Or not. +\end{beschreibung} +\begin{beispiel} + \begin{question}[type=exam] + This question has the type \texttt{exam}. The default name has changed from + ``Exercise'' to ``Question''. + \end{question} + \begin{question}[name=Fancy name] + This question has a custom name. + \end{question} + \begin{question}[print=false] + This question is not printed. + \end{question} +\end{beispiel} + +The difference between \key{print} and \key{use} lies behind the scenes: with +\key{print}{false} the question is not printed, but it still gets an individual +ID, is numbered, and a possible solution is saved. This is for example useful +when you want to print a sample solution for an exam. With \key{use}{false} it +is fully discarded which means it is not accessible through an \acs{id} and a possible +solution will not be saved. +\secidx*{questions} + +\subsubsection{The \code{solution} Environment}\secidx{solutions} +If you want to save/print (more on the exact usage in section~\ref{sec:solutions}) +a solution you have to use the \code{solution} environment \emph{after} the +question it belongs to and \emph{before} the next question. +\begin{beschreibung} + \Umg{solution}[<options>]{...} +\end{beschreibung} +\begin{beispiel} + \begin{question}[ID=first]\label{qu:question_with_solution} + This is our first question that gets a solution! + \end{question} + \begin{solution} + This is the solution to exercise~\ref{qu:question_with_solution}! + \end{solution} +\end{beispiel} +You can see that in the default settings the solution is \emph{not} written to the +document. It has been saved, though, for possible later usage. We will see the +solution later! + +\subsubsection{Options to the \code{solution} Environment}\secidx[options]{solutions} +The \code{solutions} environment also has options, namely these: +\begin{beschreibung} + \Option[solution]{name}{<name>}\Default{} + sets a custom name. + \Option[solution]{print}{\default{true}|false}\Default{false} + prints or hides the solution. +\end{beschreibung} +Their meaning is the same as those for the \code{question} environment. +\begin{beispiel} + \begin{question}{5} + The solution to this questions gets printed where it is. + \end{question} + \begin{solution}[print] + See? This solution gets printed where you have put it in the code of + your document. + \end{solution} + \begin{question}{2.5} + The solution to this questions gets printed where it is \emph{and} + has a fancy name. Have you noticed that you can assign partial + points? + \end{question} + \begin{solution}[print,name=Fancy name] + See? This solution gets printed where you have put it and has a fancy + name! + \end{solution} +\end{beispiel} +\secidx*{solutions} + +\subsubsection{Setting the Counter}\label{ssec:counter}\secidx{Setting the Counter} +The package option \key{counter-format} allows you to specify how +the question counter is formatted. + +The input is an arbitrary string which means you can have anything as counter +number. However, the letter combinations \code{ch}, \code{se}, \code{qu} and +\code{tsk} are replaced with the counters for the chapter, section, question +or tasks (see section~\ref{sec:tasks}), respectively. While the last one is not +really useful in this case the others allow for a combined numbering. Each of +these letter combinations can have an optional argument that specifies the format +of the respective counter. \code{1}: \cmd{arabic}, \code{a}: \cmd{alph}, \code{A}: +\cmd{Alph}, \code{r}: \cmd{roman} and \code{R}: \cmd{Roman}. +\begin{beispiel} + \SetupExSheets{counter-format=Nr~se~(qu[a])} + \begin{question} + A question with a differently formatted number. + \end{question} +\end{beispiel} +\secidx*{Setting the Counter} + +\subsubsection{Language Settings}\secidx{Language Settings} +The names of the questions and solutions are language dependent. If you use +\paket{babel} or \paket{polyglossia} \ExSheets will adapt to the document +language. Exsheets has a number of translations but surely not all! If you miss +a language please drop me a line in an email% +\footnote{\href{mailto:contact@mychemistry.eu}{contact@mychemistry.eu}} +containing the \paket{babel} language name and the correct translations for +questions (possibly distinguishing between exercises and exam questions) and +solutions. + +Until I implement it you can add something like this to your preamble (example +for Danish) and try if it works: +\begin{beispiel}[code only] + \DeclareTranslation{Danish}{exsheets-exercise-name} + {\O{}velse} + \DeclareTranslation{Danish}{exsheets-question-name} + {Opgave} + \DeclareTranslation{Danish}{exsheets-solution-name} + {Opl\o{}sning} +\end{beispiel} +If this isn't working it means that the language you're using is unknown to +the \translations package (see part~\ref{part:translations}). In this case please +notify me, too. You then can still use the \key{name} options. +\secidx*{Language Settings} + +\subsection{Counting Points}\label{sec:points}\secidx{Counting Points} +\subsubsection{The Commands} +You have seen in section~\ref{ssec:questions} that you can assign points to a +question. If you do so these points are printed into the margin\footnote{Well, +not necessarily. It depends on the heading style you have chosen.} and are counted +internally. But there are additional commands to assign points or bonus points +and a number of commands to retrieve the sum of points and/or bonus points. +\begin{beschreibung} + \Befehl{addpoints}*{<num>}\newline + This command can be used to add points assigned to subquestions. + \cmd{addpoints} will print the points (with ``unit'') \emph{and} add them to + the sum of all points, \cmd{addpoints}* will only add them but print nothing. + \Befehl{points}*{<num>}\newline + This command will only print the points (with ``unit'') but won't add them + to the sum of points. + \Befehl{addbonus}*{<num>}\newline + This command can be used to add bonus points assigned to subquestions. + \cmd{addbonus} will print the points (with ``unit'') \emph{and} add them to + the sum of all bonus points, \cmd{addbonus}* will only add them but print nothing. + \Befehl{bonus}*{<num>}\newline + This command will only print the bonus points (with ``unit'') but won't add them + to the sum of bonus points. + \Befehl{pointssum}*\newline + Prints the sum of all points with or without (starred version) ``unit'': + \pointssum + \Befehl{currentpointssum}*\newline + Prints the current sum of points with or without (starred version) ``unit'': + \currentpointssum + \Befehl{bonussum}*\newline + Prints the sum of all bonus points with or without (starred version) ``unit'': + \bonussum + \Befehl{currentbonussum}*\newline + Prints the current sum of bonus points with or without (starred version) ``unit'': + \currentbonussum + \Befehl{totalpoints}*\newline + prints the sum of the points \emph{and} the sum of the bonus points with ``unit'': + \totalpoints + The starred version prints the sum of the points without ``unit'': \totalpoints*. +\end{beschreibung} +The last three commands need at least \emph{two} \LaTeX\ runs to get the sum right. + +Suppose you have an exercise worth \points{4} which consists of four questions +listed with an \code{enumerate} environment that are all worth \points{1} each. +You have two possibilities to display and count them: +\begin{beispiel} + % uses package `enumitem' + \begin{question}{4} + \begin{enumerate}[label=\alph*)] + \item blah (\points{1}) + \item blah (\points{1}) + \item blah (\points{1}) + \item blah (\points{1}) + \end{enumerate} + \end{question} + \begin{question} + \begin{enumerate}[label=\alph*)] + \item blah (\addpoints{1}) + \item blah (\addpoints{1}) + \item blah (\addpoints{1}) + \item blah (\addpoints{1}) + \end{enumerate} + \end{question} +\end{beispiel} + +\subsubsection{Options}\secidx[options]{Counting Points} +\begin{beschreibung} + \Option[points]{name}{<name>}\Default{P.} + Choose the ``unit'' for the points. If you like to differentiate between a + single point and more than one point you can give a plural ending seperated + with a slash: \key{name}{point/s}. This sets also the name of the bonus points. + \Option[points]{name-plural}{<plural form of name>}\Default{} + Instead of forming the plural form with an ending to the singular form this + option allows to set an extra word for it. This sets also the plural form for + the bonus points. + \Option[points]{bonus-name}{<name>}\Default{P.} + Choose the ``unit'' for the bonus points. If you like to differentiate between a + single point and more than one point you can give a plural ending seperated + with a slash: \key{bonus-name}{point/s}. + \Option[points]{bonus-plural}{<plural form of name>}\Default{} + Instead of forming the plural form with an ending to the singular form this + option allows to set an extra word for it. + \Option[points]{use-name}{\default{true}|false}\Default{true} + Don't display the name at all. Or do. + \Option[points]{number-format}{<any code>}\Default{} + This option allows formatting of the number, \eg italics: + \key{number-format}{\cmd{textit}}. + \Option[points]{bonus-format}{<any code>}\Default{} + This option allows formatting of the number of the bonus points, \eg italics: + \key{bonus-format}{\cmd{textit}}. + \Option[points]{parse}{\default{true}|false}\Default{true} + If set to \code{false} the points are not counted and the \cmd{totalpoints}, + \cmd{pointssum} and \cmd{bonussum} commands won't know their value. + \Option[points]{separate-bonus}{\default{true}|false}\Default{false} + This option determines whether points and bonus points each get their own + unit when they appear together (in the margin or with \cmd{totalpoints}). + \Option[points]{pre-bonus}{<tokens>}\Default{(+} + Code to be inserted before the bonus points when they follow normal points. + \Option[points]{post-bonus}{<tokens>}\Default{)} + Code to be inserted after the bonus points when they follow normal points. +\end{beschreibung} +\begin{beispiel} + \SetupExSheets[points]{name=point/s,number-format=\color{red}} + \begin{question}{1} + This one's easy so only 1 point can be earned. + \end{question} + \begin{question}{7.5} + But this one's hard! 7.5 points are in there for you! + \end{question} +\end{beispiel} +\secidx*{Counting Points} + +\subsection{A Grade Distribution}\secidx{Grade Distribution} +Probably this is a rather esoteric feature but it could proof useful in some cases. +Suppose you are a German math teacher and want to grade exactly corresponding to +the number of points relative to the sum of total points, regardless of how big +that might be. You could do something like this to present your grading decisions +for the exam: +\begin{beispiel} + % preamble: + % \DeclareRelGrades{ + % 1 = 1 , + % {1,5} = .9167 , + % 2 = .8333 , + % {2,5} = .75 , + % 3 = .6667 , + % {3,5} = .5833 , + % 4 = .5 + % } + \small\setlength\tabcolsep{2pt} + \begin{tabular}{r|*8c} + Punkte + & $\grade*{1}$ & $\le\grade*{1}$ & $\le\grade*{1,5}$ & $\le\grade*{2}$ + & $\le\grade*{2,5}$ & $\le\grade*{3}$ & $\le\grade*{3,5}$ & $<\grade*{4}$ \\ + Note + & 1 & 1--2 & 2 & 2--3 & 3 & 3--4 & 4 & 5 + \end{tabular} +\end{beispiel} + +These are the available commands and options: +\begin{beschreibung} + \Befehl{DeclareRelGrades}{<grade>=<num>,...}\newline + This command is used to define grades and assign the percentage of total + points to them. + \Befehl{grade}*{<grade>}\newline + Gives the number of points corresponding to a grade depending on the value + of \cmd{pointssum} with or without (starred version) ``unit''. + \Option[grades]{round}{<num>}\Default{0} + The number of decimals the points of a grade are rounded to. This doesn't apply + to the maximum number of points if the rounded number would be bigger than the + actual sum. + \Option[grades]{half}{\default{true}|false}\Default{false} + If set to \code{true} points are rounded either to full or to half points. +\end{beschreibung} +\secidx*{Grade Distribution} + +\subsection{Printing Solutions}\label{sec:solutions}\secidx[print]{solutions} +You have already seen that you can print solutions where they are using the +\key[solution]{print} option. But \ExSheets offers you quite more possibilities. + +In the next subsections the usage of the command +\begin{beschreibung} + \Befehl{printsolutions}[<setting>] +\end{beschreibung} +is discussed. + +Before we do that a hint: remember that you can set the option \key{print} globally: +\begin{beispiel}[code only] + % in the preamble + \SetupExSheets{solution/print=true} +\end{beispiel} + +Now if you want to typeset some text depending on the option being true or not +you can use the following commands: +\begin{beschreibung} + \expandable\Befehl{PrintSolutionsTF}{<true code>}\ma{<false code>} + \expandable\Befehl{PrintSolutionsT}{<true code>} + \expandable\Befehl{PrintSolutionsF}{<false code>} +\end{beschreibung} +They might come in handy if you want two versions of an exercise sheet, one with +the exercises and one with the solutions, and you want to add different titles +to these versions, for instance. + +\subsubsection{Print all}\secidx[print!all]{solutions} +The first and easiest usage of \cmd{printsolutions} is the following: +\begin{beispiel}[code only] + \printsolutions +\end{beispiel} +There is nothing more to say, really. It prints all solutions you have specified +except those belonging to a question with option \key{use}{false}. Yes, there's +one more point: \cmd{printsolutions} only knows the solutions that have been set +\emph{before} its usage! This is also true for every usage explained in the next +sections. + +\begin{beispiel}[below] + \printsolutions +\end{beispiel} + +\subsubsection{Print per chapter/section}\secidx[print!per section/chapter]{solutions} +\minisec{Current chapter/section} +If you are not creating an exercise sheet or an exam but are writing a textbook +you maybe want a section at the end of each chapter showing the solution to the +exercises presented in that chapter. In this case use the command as follows: +\begin{beispiel}[code only] + \printsolutions[section] + % or + \printsolutions[chapter] +\end{beispiel} +Again, this is pretty much self-explaining. The solutions to the questions of the +current chapter\footnote{Only if the document class you're using \emph{has} +chapters, of course!} or section are printed. +\begin{beispiel} + \begin{question} + This is the first and only question in this section. + \end{question} + \begin{solution} + This will be one of a few solutions printed by the following call of + \cmd{printsolutions}. + \end{solution} + And now: + \printsolutions[section] +\end{beispiel} + +\minisec{Specific chapter/section}\label{sssec:print_specific_section} +You can also print only the solutions from chapters or sections other than the +current ones. The syntax is fairly easy: +\begin{beispiel}[below] + \printsolutions[section={1-7,10}] + % the same for chapters: + % \printsolutions[chapter={1-7,10}] +\end{beispiel} +Don't forget that \cmd{printsolutions} cannot know the solutions from section~10 +yet. It is just used to demonstrate the syntax. You can also use an open range, +\eg something like +\begin{beispiel}[code only] + \printsolutions[section={-4,10-}] +\end{beispiel} +This would print the solutions from sections~1--4 and from all sections with +number 10\footnote{Or rather where \cmd{value}{section} is 10 or greater -- the +actual counter formatting is irrelevant.} and greater. + +There is an obvious disadvantage: you have to know the section numbers! But there +is a solution: use the package option \key{use-ref}{true}. Then you can do something +like +\begin{beispiel}[code only] + % in the preamble: + \usepackage[use-ref]{exsheets} + % somewhere in your code after \section{A really cool section title}: + \label{sec:ReallyCool} + % somewhere later in your code: + \printsolutions[section={-\S{sec:ReallyCool}}] + % which will print all solutions from questions up to and + % including the really cool section +\end{beispiel} +With the package option \key{use-ref}{true} each usage of \cmd{label} will create +additional labels (one preceded with \code{exse:} and another one with \code{exch:}) +which store the section number and the chapter number, respectively. These are used +internally by two commands \cmd{S} and \cmd{C} which refer to the section number +and the chapter number the label was created in. \emph{These commands are only +available as arguments of} \cmd{printsolutions}. + +Since some packages like the well known \paket{hyperref} for example redefine +\cmd{label} \key{use-ref} won't work in together with it. In this case don't +use \key{use-ref} and set \cmd{exlabel}{<label>} instead to remember the +section/the chapter number. Its usage is just like \cmd{label}. So the safest way +is as follows: +\begin{beispiel}[code only] + % in the preamble: + \usepackage{exsheets} + % somewhere in your code after \section{A really cool section title}: + \exlabel{sec:ReallyCool} + % somewhere later in your code: + \printsolutions[section={-\S{sec:ReallyCool}}] + % which will print all solutions from questions up to and + % including the really cool section +\end{beispiel} +Please be aware that the labels must be processed in a previous \LaTeX\ run before +\cmd{S} and \cmd{C} can pass them on to \cmd{printsolutions}. + +\subsubsection{Print by \texorpdfstring{\acs{id}}{ID}}\label{ssec:ids}\secidx[print!by ID]{solutions} +Now comes the best part: you can also print selected solutions! Every question +has an \acs{id}. To see which \acs{id} a question has you can call the following command: +\begin{beschreibung} + \Befehl{DebugExSheets}{true|false} +\end{beschreibung} +Let's create some more questions and take a look what this command does: +\begin{beispiel} + \DebugExSheets{true} + \begin{question}[ID=nice!] + A question with a nice \acs{id}! + \end{question} + \begin{solution} + The solution to the question with the nice \acs{id}. + \end{solution} + \begin{question}{3.75} + Yet another question. But this time with quarter points! + \end{question} + \begin{solution} + Yet another solution. + \end{solution} +\end{beispiel} + +So now we can call some specific solutions: +\begin{beispiel} + \printsolutions[byID={first,nice!,10,14}] +\end{beispiel} +This makes use of the \paket{l3sort} package which at the time of writing is still +considered experimental. In case you wonder where solution~14 is: question~14 +has no solution given. + +If you don't want that the solutions are sorted automatically but appear in the +order given you can use the option +\begin{beschreibung} + \Option[solution]{sorted}{\default{true}|false}\Default{true} + Sort solutions given by \acs{id} or don't. +\end{beschreibung} + +\subsection{Using Classes}\label{sec:classes}\secidx{Classes} +For creating different variants of a written exam or different difficulty levels +of an exercise sheet it comes in handy if one can assign certain classes to questions +and then tell \ExSheets only to use one ore more specific classes. +\begin{beschreibung} + \Option{use-classes}{<list of classes>}\Default{} + When this option is used only the questions belonging to the specified classes + are printed and have their solutions saved. +\end{beschreibung} +\begin{beispiel} + \SetupExSheets{use-classes={easy,hard}} + \begin{question}[class=easy] + This one's easy. + \end{question} + \begin{question}[class=middle] + This one's a little bit harder. + \end{question} + \begin{question}[class=hard] + Let's see if you can solve this one! + \end{question} +\end{beispiel} +Questions of classes that are not used are fully discarded. \emph{This also means +that questions that don't have a class assigned are discarded.} +\secidx*{Classes} +\ExplSyntaxOn + \bool_set_false:N \g__exsheets_use_classes_bool +\ExplSyntaxOff + +\subsection{Using Topics}\label{sec:topics}\secidx{Topics} +Similarly to classes one can assign topics to questions. The usage is practically +identical, the semantic meaning is different. +\begin{beschreibung} + \Option{use-topics}{<list of topics>}\Default{} + When this option is used only the questions belonging to the specified topics + are printed and have their solutions saved. +\end{beschreibung} +\begin{beispiel} + \SetupExSheets{use-topics={trigonometry}} + \begin{question}[topic=trigonometry] + A trigonometry question. + \end{question} + \begin{question}[topic=arithmetics] + A arithmetics question + \end{question} +\end{beispiel} +Questions of topics that are not used are fully discarded. \emph{This also means +that questions that don't have a topic assigned are discarded.} + +If you set both \key{use-classes} and \key{use-topics} then only questions +will be used that \emph{match both categories}. + +Ideally one could assign more than one topic to a question but this is \emph{not} +supported yet. +\secidx*{Topics} +\ExplSyntaxOn + \bool_set_false:N \g__exsheets_use_topics_bool +\ExplSyntaxOff + +\subsection{Adding and Using Additional Information to Questions}\label{sec:additional_info} +\secidx{Additional Information to Questions} +For managing lots of questions and corresponding solutions it can be very useful +to be able to save and recover additional information to the questions. This is +possible with the following commands. First the ones for saving: +\begin{beschreibung} + \Befehl{DeclareQuestionProperty}{<name>}\newline + This command defines a question property \code{<name>}. It can only be used + in the document preamble. + \Befehl{SetQuestionProperties}{<name>=<value>,...}\newline + Set the properties for a specific question. this command can only be used + inside the \code{question} environment. +\end{beschreibung} +Now the commands for recovering the properties: +\begin{beschreibung} + \Befehl{QuestionNumber}{<id>}\newline + Recover the number of the question with the \acs{id} \code{<id>}. The number + is displayed according to the format set with \key{counter-format}. + \Befehl{GetQuestionProperty}{<name>}\ma{<id>}\newline + Recover the property \code{<name>} of the question with the \acs{id} \code{<id>}. + Of course the property must have been declared before. +\end{beschreibung} + +Let's say we have declared the properties \code{points}, \code{notes}, \code{reference} +and \code{topic}. Then we can do the following: +\begin{beispiel} + % uses `biblatex' + \begin{question}[ID=center,topic=LaTeX]{3} + Explain how you could center text in a \LaTeX\ document. + \SetQuestionProperties{ + points = 3, + topic = \TeX/\LaTeX , + notes = {How to center text.}, + reference = {\textcite{companion}}} + \end{question} + \begin{solution} + To center a short part of the text body one can use the \texttt{center} + environment (\points{1}). Inside an environment like \texttt{table} one + should use \texttt{\string\centering} (\points{1}). For single lines + there is also the \texttt{\string\centerline} command (\points{1}). + \end{solution} + \begin{question}[ID=knuthbooks,topic=LaTeX]{2} + Name two books by D.\,E.\,Knuth. + \SetQuestionProperties{ + points = 2, + topic = \TeX/\LaTeX , + notes = {Books by Knuth.}, + reference = {\textcite{knuth:ct:a,knuth:ct:b,knuth:ct:c,knuth:ct:d,knuth:ct:e}}} + \end{question} + \begin{solution} + For example two volumes from \citetitle{knuth:ct}: + \citetitle{knuth:ct:a,knuth:ct:b,knuth:ct:c,knuth:ct:d,knuth:ct:e}. Each valid + answer is worth \points{1} + \end{solution} +\end{beispiel} + +It is now possible to recover these values later: +\begin{beispiel} + % uses `booktabs' + \begin{center} + \begin{tabular}{lll} + \toprule + Question & Property & \\ + \midrule + \QuestionNumber{center} + & Points & \GetQuestionProperty{points}{center} \\ + & Topic & \GetQuestionProperty{topic}{center} \\ + & References & \GetQuestionProperty{reference}{center} \\ + & Note & \GetQuestionProperty{notes}{center} \\ + \midrule + \QuestionNumber{knuthbooks} + & Points & \GetQuestionProperty{points}{knuthbooks} \\ + & Topic & \GetQuestionProperty{topic}{knuthbooks} \\ + & References & \GetQuestionProperty{reference}{knuthbooks} \\ + & Note & \GetQuestionProperty{notes}{knuthbooks} \\ + \bottomrule + \end{tabular} + \end{center} +\end{beispiel} + +\secidx*{Additional Information to Questions} + +\subsection{Selectively Include Questions from External Files}\label{sec:include} +\secidx{Include from External Files} +Suppose you have one or more files with questions prepared to use them as a kind +of database. One for class A, say, one for class B, one for class C and so one, +something like this: +\begin{beispiel}[code only] + % this is file classA.tex + \begin{question}[class=A,ID=A1,topic=X] + First question of class A, topic X. + \end{question} + \begin{solution} + First solution of class A. + \end{solution} + \begin{question}[class=A,ID=A2,topic=Y] + Second question of class A, topic Y. + \end{question} + \begin{solution} + Second solution of class A. + \end{solution} + ... + % end of file classA.tex + \endinput +\end{beispiel} +You can of course just \cmd{input} or \cmd{include} it but that would of course +include the whole file into your document. But would't it be nice to just include +selected questions? Or maybe a five random questions from the file? That is +possible with the following command: +\begin{beschreibung} + \Befehl{includequestions}[<options>]{<list of filenames>} +\end{beschreibung} +If you use it without options it will have the same effect as \cmd{input}. There +are however the following options: +\begin{beschreibung} + \Option[include]{all}{\default{true}|false} + \Option[include]{IDs}{<list of IDs>}\Default{} + Includes only the specified questions. + \Option[include]{random}{<num>}\Default{} + Includes \code{<num>} randomly selected questions. This option uses the + \paket{lcg} package to create the pseudo-random numbers. + \Option[include]{seed}{<num>}\Default{-1} + Sets the seed for the pseudo-random numbers. +\end{beschreibung} +The usage should be self-explainable: +\begin{beispiel}[code only] + % include questions A1, A3 and A4: + \includequestions[IDs={A1,A3,A4}]{classA.tex} + % or include 3 random questions: + \includequestions[random=3]{classA} +\end{beispiel} +In order to be able to select the questions \ExSheets needs to \cmd{input} the +file twice. The first time the available questions are detemined, the second time +the selected questions are used. This unfortunately means that anything that is +\emph{not} part of a question or solution is also input twice. Either don't do +that or use one of the following commands for control: +\begin{beschreibung} + \Befehl{PrintIfIncludeActiveTF}\ma{<true code>}\ma{<false code>} + \Befehl{PrintIfIncludeActiveT}\ma{<true code>} + \Befehl{PrintIfIncludeActiveF}\ma{<false code>} +\end{beschreibung} + +If you use the \key{random} option you need to be aware of the following facts: +the options \key{use-classes}, \key{use-topics} and \key{question/print} are not +considered when selecting the questions which means you might end up with less +questions included than you've specified. The option \key{question/use} is also +not taken into consideration. In fact it is completely ignored and the questions +are included anyway. I'm still not sure this is a feature or a bug\ldots +\secidx*{Include from External Files} + +\subsection{The \code{tasks} Environment}\label{sec:tasks}\secidx{tasks} +\subsubsection{How it works} +The \code{tasks} environment is similar to a list like \code{enumerate} but not +the same. The first difference: there is no pagebreak possible inside an item but +only between items. The second difference: the enumeration default is a), b), c) +\ldots The third difference: the input syntax: +\begin{beschreibung} + \Umg{tasks}[<options>]{\unskip\ma{<num of columns>} list of tasks, each ended by + a semicolon} +\end{beschreibung} +Let's use some sample text in the next few examples: +\begin{beispiel}[code only] + \def\s{This is some sample text we will use to create a somewhat longer text + spanning a few lines.} + \def\sample{\s\ \s\par\s} +\end{beispiel} +\def\s{This is some sample text we will use to create a somewhat longer text + spanning a few lines.} +\def\sample{\s\ \s\par\s} +\begin{beispiel}[below] + Some text before the list. + \begin{tasks} + \sample ; + \sample ; + \sample ; + \end{tasks} + And also some text after it. +\end{beispiel} +The environment takes the optional argument \ma{<num of columns>} with which the +number of columns used by the environment is specified. +\begin{beispiel}[below] + \begin{tasks}{2} + \sample ; + \s\ \s ; + \s ; + \sample ; + \s\par\s ; + \end{tasks} +\end{beispiel} + +\subsubsection{Available Options}\secidx[Options]{tasks} +The environment has some options, namely these: +\begin{beschreibung} + \Option[tasks]{style}{<instance>}\Default{} + Choose the instance to be used. Read more on this in section~\ref{sec:exsheets-tasks}. + \Option[tasks]{label}{<label specs>}\Default{} + Sets a custom label. The letters \code{tsk} are replaced with the task-counter. + An optional argument directly following these letters specifies the counter format: + \code{1}: \cmd{arabic}, \code{a}: \cmd{alph}, \code{A}: \cmd{Alph}, \code{r}: + \cmd{roman} and \code{R}: \cmd{Roman}. + \Option[tasks]{label-width}{<dim>}\Default{3ex} + Sets the width of the item labels. + \Option[tasks]{before-skip}{<skip>}\Default{.33\cmd{baselineskip}} + Sets the skip before the list. + \Option[tasks]{after-skip}{<skip>}\Default{.33\cmd{baselineskip}} + Sets the skip after the list. +\end{beschreibung} + +Now the same list as above but with three columns and a different label: +\begin{beispiel}[below] + \begin{tasks}[label=(tsk[r]),label-width=4ex]{3} + \sample ; + \s\ \s ; + \s ; + \sample ; + \s\par\s ; + \end{tasks} +\end{beispiel} + +Let's use it inside a question: +\begin{beispiel} + \SetupExSheets[tasks]{label=qu.tsk,label-width=5ex} + \begin{question}[type=exam]{4} + I have these two tasks for you. Shall we begin? + \begin{tasks}{2} + The first task: easy! ; + The second task: even more so! ; + \end{tasks} + \end{question} + \begin{solution}[print] + Now, let's see\ldots\ ah, yes: + \begin{tasks} + This is the first solution. Told you it was easy. ; + This is the second solution. And of course you knew that! ; + \end{tasks} + \end{solution} +\end{beispiel} + +\subsubsection{Available Instances} +When you use the package option \key{load-tasks} there are currently three +additional instances for the \code{tasks} are available: +\begin{description} + \item[itemize] uses \cmd{labelitemi} as labels. + \item[enumerate] enumerates the items with 1., 2., \ldots + \item[multiplechoice] a --~well~-- `multiple choice' list. +\end{description} +\begin{beispiel} + \begin{tasks}[style=itemize]{2} + that's just how\ldots ; + \ldots we expected ; + \end{tasks} + \begin{tasks}[style=enumerate]{2} + that's just how\ldots ; + \ldots we expected ; + \end{tasks} + \begin{tasks}[style=multiplechoice]{2} + that's just how\ldots ; + \ldots we expected ; + \end{tasks} +\end{beispiel} + +\subsubsection{Custom Labels}\secidx[Custom Labels]{tasks} +If you want to change a single label inside a list, you can use +\begin{beschreibung} + \Befehl{task}{<label>} +\end{beschreibung} +in one of the tasks. This will temporarily overwrite the default label. +\begin{beispiel} + \begin{tasks}[style=itemize] + a standard item ; + another one ; + \task{+}a different one ; + and another one ; + \end{tasks} +\end{beispiel} +\secidx*{tasks} + +\subsection{Filling in the Blanks}\secidx{Blanks} +Both in exercise sheets and in exams it is sometimes desirable to be able to +create \blank{blanks} that have to be filled in. Or may be some more lines: +\blank[width=5\linewidth]{} + +\begin{beschreibung} + \Befehl{blank}[<options>]{<text to be filled in>}\newline + creates a blank in normal text or in a question but fills the text of its + argument if inside a solution. +\end{beschreibung} + +The options are these: +\begin{beschreibung} + \Option[blank]{style}{line|wave|dline|dotted|dashed}\Default{line} + The style of the line. + \Option[blank]{width}{<dim>}\Default{} + The width of the line. If it is not used the width of the filled in text is used. +\end{beschreibung} +\begin{beispiel} + \begin{question} + Try to fill in \blank[width=4cm]{these} blanks. All of them + \blank[style=dotted]{are created} by using the \cmd{blank} + \blank[style=dashed]{command}. + \end{question} + \begin{solution}[print] + Try to fill in \blank[width=4cm]{these} blanks. All of them + \blank[style=dotted]{are created} by using the \cmd{blank} + \blank[style=dashed]{command}. + \end{solution} +\end{beispiel} +A number of empty lines are easily created by setting the width option: +\begin{beispiel} + % \usepackage{setspace} + \spacing{2}\blank[width=4.8\linewidth]{}\endspacing +\end{beispiel} +\secidx*{Blanks} + +\section{Styling your Exercise/Exam Sheets}\label{part:style} +\subsection{Background} +The \ExSheets package makes extensive use of \LaTeX3's coffins\footnote{See the +documentation to the \paket*{xcoffins} package for more information on that.} as +well as its templates concept\footnote{Have a look into the documentation to the +\paket*{xtemplate} package.}. The latter allows a rather easy extension and +customization of some of \ExSheets' environments. To be more precise: you can +define your own instances for the headings used for questions and solutions +and for the \code{tasks} environment. + +What this package doesn't provide is changing the background of questions or +framing them. But this is easily possible using the \paket{mdframed} package +and its \cmd*{surroundwithmdframed} copmmand. + +\subsection{The \code{exsheets-headings} Object}\label{sec:exsheets-headings} +\secidx{The `exsheets-headings' Object} +\ExSheets defines the object \code{exsheets-headings} and one template for it, +the `default' template. The package also defines two instances of this template, +the `block' instance and the `runin' instance. + +\begin{beispiel} + \SetupExSheets{headings=block} + \begin{question}{1} + a `block' heading + \end{question} + \SetupExSheets{headings=runin} + \begin{question}{1} + a `runin' heading + \end{question} +\end{beispiel} + +\subsubsection{Available Options} +This section only lists the options that can be used when defining an instance +of the `default' template. The following subsections will give loads of examples +of their usage. The options are listed in the definition for the template interface: + +\begin{beispiel}[code only] + \DeclareTemplateInterface{exsheets-heading}{default}{3} + { + % option : type = default + runin : boolean = false , + indent-first : boolean = false , + toc-reversed : boolean = false , + vscale : real = 1 , + above : length = 2pt , + below : length = 2pt , + main : tokenlist = , + pre-code : tokenlist = , + post-code : tokenlist = , + title-format : tokenlist = , + title-pre-code : tokenlist = , + title-post-code : tokenlist = , + number-format : tokenlist = , + number-pre-code : tokenlist = , + number-post-code : tokenlist = , + points-format : tokenlist = , + points-pre-code : tokenlist = , + points-post-code : tokenlist = , + join : tokenlist = , + attach : tokenlist = + } +\end{beispiel} + + +Each heading is built with at most four coffins available with the names `main', +`title', `number' and `points'. Those coffins place possibly the whole heading, +the title, the question number and the assigned points. The only coffin that's +always typeset is the `main' coffin, which is empty per default. + +Coffins can be joined (two become one, the first extends its bounding box to contain +the second) using the following syntax: +\begin{beispiel}[code only] + join = coffin1[handle11,handle12]coffin2[handle21,handle22](x-offset,y-offset) +\end{beispiel} +The syntax for attaching (two become one, the first does \emph{not} extend its +bounding box around the second) the syntax is the same. + +More on coffin handles is described in the documentation for the \paket{xcoffins}. +Figure~\ref{fig:handles} briefly demonstrates the available handle pairs. + +\begin{figure}[ht] + \centering + \parbox{4.5cm}{% + \NewCoffin\ExampleCoffin + \SetHorizontalCoffin\ExampleCoffin{\color{gray!30}\rule{4cm}{4cm}}% + \DisplayCoffinHandles\ExampleCoffin{blue}% + } + \caption{Available handles for a horizontal coffin.}\label{fig:handles} +\end{figure} + +The following subsections will show all definitions of the instances available +with the package option \key{load-headings} and how they look. This will hopefully +give you enough ideas to create your own instance if you want to have another +heading style than the ones available. + +Of you use the option \key{load-headings} each of the following instances is +available through the option \key{headings}{<instance>}. + +\subsubsection{The `block' Instance} +\begin{beispiel}[code only] + \DeclareInstance{exsheets-heading}{block}{default} + { + join = { title[r,B]number[l,B](1ex,0pt) } , + attach = + { + main[l,vc]title[l,vc](0pt,0pt) ; + main[r,vc]points[l,vc](\marginparsep,0pt) + } + } +\end{beispiel} +\SetupExSheets{headings=block} +\begin{question}{1} + A `block' heading. \sample +\end{question} + +\subsubsection{The `runin' Instance} +\begin{beispiel}[code only] + \DeclareInstance{exsheets-heading}{runin}{default} + { + runin = true , + number-post-code = \space , + attach = + { main[l,vc]points[l,vc](\linewidth+\marginparsep,0pt) } , + join = + { + main[r,vc]title[r,vc](0pt,0pt) ; + main[r,vc]number[l,vc](1ex,0pt) + } + } +\end{beispiel} +\SetupExSheets{headings=runin} +\begin{question}{1} + A `runin' heading. \sample +\end{question} + +\subsubsection{The `simple' Instance} +\begin{beispiel}[code only] + \DeclareInstance{exsheets-heading}{simple}{default} + { + title-format = \normalsize , + points-pre-code = ( , + points-post-code = ) , + attach = { main[l,t]number[l,t](0pt,0pt) } , + join = + { + number[r,b]title[l,b](1ex,0pt) ; + main[l,b]points[l,t](1em,0pt) + } + } +\end{beispiel} +\SetupExSheets{headings=simple} +\begin{question}{1} + A `simple' heading. \sample +\end{question} + +\subsubsection{The `block-rev' Instance} +\begin{beispiel}[code only] + \DeclareInstance{exsheets-heading}{block-rev}{default} + { + toc-reversed = true , + join = { number[r,B]title[l,B](1ex,0pt) } , + attach = + { + main[l,vc]number[l,vc](0pt,0pt) ; + main[r,vc]points[l,vc](\marginparsep,0pt) + } + } +\end{beispiel} +\SetupExSheets{headings=block-rev} +\begin{question}{1} + A `block-rev' heading. \sample +\end{question} + +\subsubsection{The `block-wp' Instance} +\begin{beispiel}[code only] + \DeclareInstance{exsheets-heading}{block-wp}{default} + { + points-pre-code = ( , + points-post-code = ) , + join = + { + title[r,B]number[l,B](1ex,0pt) ; + title[r,B]points[l,B](1ex,0pt) + } , + attach = { main[l,vc]title[l,vc](0pt,0pt) } + } +\end{beispiel} +\SetupExSheets{headings=block-wp} +\begin{question}{1} + A `block-wp' heading. \sample +\end{question} + +\subsubsection{The `block-wp-rev' Instance} +\begin{beispiel}[code only] + \DeclareInstance{exsheets-heading}{block-wp-rev}{default} + { + toc-reversed = true , + points-pre-code = ( , + points-post-code = ) , + join = + { + number[r,B]title[l,B](1ex,0pt) ; + number[r,B]points[l,B](1ex,0pt) + } , + attach = { main[l,vc]number[l,vc](0pt,0pt) } + } +\end{beispiel} +\SetupExSheets{headings=block-wp-rev} +\begin{question}{1} + A `block-wp-rev' heading. \sample +\end{question} + +\subsubsection{The `block-nr' Instance} +\begin{beispiel}[code only] + \DeclareInstance{exsheets-heading}{block-nr}{default} + { + attach = + { + main[l,vc]number[l,vc](0pt,0pt) ; + main[r,vc]points[l,vc](\marginparsep,0pt) + } + } +\end{beispiel} +\SetupExSheets{headings=block-nr} +\begin{question}{1} + A `block-nr' heading. \sample +\end{question} + +\subsubsection{The `block-nr-wp' Instance} +\begin{beispiel}[code only] + \DeclareInstance{exsheets-heading}{block-nr-wp}{default} + { + points-pre-code = ( , + points-post-code = ) , + join = { number[r,vc]points[l,vc](1ex,0pt) } , + attach = { main[l,vc]number[l,vc](0pt,0pt) } + } +\end{beispiel} +\SetupExSheets{headings=block-nr-wp} +\begin{question}{1} + A `block-nr-wp' heading. \sample +\end{question} + +\subsubsection{The `runin-rev' Instance} +\begin{beispiel}[code only] + \DeclareInstance{exsheets-heading}{runin-rev}{default} + { + toc-reversed = true , + runin = true , + title-post-code = \space , + attach = + { main[l,vc]points[l,vc](\linewidth+\marginparsep,0pt) } , + join = + { + main[r,vc]number[r,vc](0pt,0pt) ; + main[r,vc]title[l,vc](1ex,0pt) + } + } +\end{beispiel} +\SetupExSheets{headings=runin-rev} +\begin{question}{1} + A `runin-rev' heading. \sample +\end{question} + +\subsubsection{The `runin-wp' Instance} +\begin{beispiel}[code only] + \DeclareInstance{exsheets-heading}{runin-wp}{default} + { + runin = true , + points-pre-code = ( , + points-post-code = )\space , + join = + { + main[r,vc]title[r,vc](0pt,0pt) ; + main[r,vc]number[l,vc](1ex,0pt) ; + main[r,vc]points[l,vc](1ex,0pt) + } + } +\end{beispiel} +\SetupExSheets{headings=runin-wp} +\begin{question}{1} + A `runin-wp' heading. \sample +\end{question} + +\subsubsection{The `runin-wp-rev' Instance} +\begin{beispiel}[code only] + \DeclareInstance{exsheets-heading}{runin-wp-rev}{default} + { + toc-reversed = true , + runin = true , + points-pre-code = ( , + points-post-code = )\space , + join = + { + main[r,vc]number[r,vc](0pt,0pt) ; + main[r,vc]title[l,vc](1ex,0pt) ; + main[r,vc]points[l,vc](1ex,0pt) + } + } +\end{beispiel} +\SetupExSheets{headings=runin-wp-rev} +\begin{question}{1} + A `runin-wp-rev' heading. \sample +\end{question} + +\subsubsection{The `runin-nr' Instance} +\begin{beispiel}[code only] + \DeclareInstance{exsheets-heading}{runin-nr}{default} + { + runin = true , + number-post-code = \space , + attach = + { main[l,vc]points[l,vc](\linewidth+\marginparsep,0pt) } , + join = { main[r,vc]number[l,vc](0pt,0pt) } + } +\end{beispiel} +\SetupExSheets{headings=runin-nr} +\begin{question}{1} + A `runin-nr' heading. \sample +\end{question} + +\subsubsection{The `runin-fixed-nr' Instance} +\begin{beispiel}[code only] + \DeclareInstance{exsheets-heading}{runin-fixed-nr}{default} + { + runin = true , + number-pre-code = \hbox to 2em \bgroup , + number-post-code = \hfil\egroup , + attach = + { main[l,vc]points[l,vc](\linewidth+\marginparsep,0pt) } , + join = { main[r,vc]number[l,vc](0pt,0pt) } + } +\end{beispiel} +\SetupExSheets{headings=runin-fixed-nr} +\begin{question}{1} + A `runin-fixed-nr' heading. \sample +\end{question} + +\subsubsection{The `runin-nr-wp' Instance} +\needspace{2\baselineskip} +\begin{beispiel}[code only] + \DeclareInstance{exsheets-heading}{runin-nr-wp}{default} + { + runin = true , + points-pre-code = ( , + points-post-code = )\space , + join = + { + main[r,vc]number[l,vc](0pt,0pt) ; + main[r,vc]points[l,vc](1ex,0pt) + } + } +\end{beispiel} +\SetupExSheets{headings=runin-nr-wp} +\begin{question}{1} + A `runin-nr-wp' heading. \sample +\end{question} + +\subsubsection{The `centered' Instance} +\begin{beispiel}[code only] + \DeclareInstance{exsheets-heading}{centered}{default} + { + join = { title[r,B]number[l,B](1ex,0pt) } , + attach = + { + main[hc,vc]title[hc,vc](0pt,0pt) ; + main[r,vc]points[l,vc](\marginparsep,0pt) + } + } +\end{beispiel} +\SetupExSheets{headings=centered} +\begin{question}{1} + A `centered' heading. \sample +\end{question} + +\subsubsection{The `centered-wp' Instance} +\begin{beispiel}[code only] + \DeclareInstance{exsheets-heading}{centered-wp}{default} + { + points-pre-code = ( , + points-post-code = ) , + join = + { + title[r,B]number[l,B](1ex,0pt) ; + title[r,B]points[l,B](1ex,0pt) + } , + attach = { main[hc,vc]title[hc,vc](0pt,0pt) } + } +\end{beispiel} +\SetupExSheets{headings=centered-wp} +\begin{question}{1} + A `centered-wp' heading. \sample +\end{question} + +\subsubsection{The `margin' Instance} +\begin{beispiel}[code only] + \DeclareInstance{exsheets-heading}{margin}{default} + { + runin = true , + number-post-code = \space , + points-pre-code = ( , + points-post-code = )\space , + join = { title[r,b]number[l,b](1ex,0pt) } , + attach = + { + main[l,vc]title[r,vc](0pt,0pt) ; + main[l,b]points[r,t](0pt,0pt) + } + } +\end{beispiel} +\SetupExSheets{headings=margin} +\begin{question}{1} + A `margin' heading. \sample +\end{question} + +\subsubsection{The `margin-nr' Instance} +\begin{beispiel}[code only] + \DeclareInstance{exsheets-heading}{margin-nr}{default} + { + runin = true , + attach = + { + main[l,vc]number[r,vc](-1ex,0pt) ; + main[r,vc]points[l,vc](\linewidth+\marginparsep,0pt) + } + } +\end{beispiel} +\SetupExSheets{headings=margin-nr} +\begin{question}{1} + A `margin-nr' heading. \sample +\end{question} + +\subsubsection{The `raggedleft' Instance} +\begin{beispiel}[code only] + \DeclareInstance{exsheets-heading}{raggedleft}{default} + { + join = { title[r,B]number[l,B](1ex,0pt) } , + attach = + { + main[r,vc]title[r,vc](0pt,0pt) ; + main[r,vc]points[l,vc](\marginparsep,0pt) + } + } +\end{beispiel} +\SetupExSheets{headings=raggedleft} +\begin{question}{1} + A `raggedleft' heading. \sample +\end{question} + +\subsubsection{The `fancy' Instance} +\begin{beispiel}[code only] + \DeclareInstance{exsheets-heading}{fancy}{default} + { + toc-reversed = true , + indent-first = true , + vscale = 2 , + pre-code = \rule{\linewidth}{1pt} , + post-code = \rule{\linewidth}{1pt} , + title-format = \large\scshape\color{exsheetsred} , + number-format = \large\bfseries\color{exsheetsblue} , + points-format = \itshape , + join = { number[r,B] title[l,B] (1ex,0pt) } , + attach = + { + main[hc,vc]number[hc,vc](0pt,0pt) ; + main[l,vc]points[r,vc](-\marginparsep,0pt) + } + } +\end{beispiel} +\SetupExSheets{headings=fancy} +\begin{question}{1} + A `fancy' heading. \sample +\end{question} + +\subsubsection{The `fancy-wp' Instance} +\begin{beispiel}[code only] + \DeclareInstance{exsheets-heading}{fancy-wp}{default} + { + toc-reversed = true , + indent-first = true , + vscale = 2 , + pre-code = \rule{\linewidth}{1pt} , + post-code = \rule{\linewidth}{1pt} , + title-format = \large\scshape\color{exsheetsred} , + number-format = \large\bfseries\color{exsheetsblue} , + points-format = \itshape , + points-pre-code = ( , + points-post-code = ) , + join = + { + number[r,B]title[l,B](1ex,0pt) ; + number[r,B]points[l,B](1ex,0pt) + } , + attach = { main[hc,vc]number[hc,vc](0pt,0pt) } + } +\end{beispiel} +\SetupExSheets{headings=fancy-wp} +\begin{question}{1} + A `fancy-wp' heading. \sample +\end{question} +\secidx*{The `exsheets-headings' Object} + +\subsection{The \code{exsheets-tasks} Object}\label{sec:exsheets-tasks} +\secidx{The `exsheets-tasks' Object} +The second object that's defined by \ExSheets is the `exsheets-tasks' object. +This time there are four instances available for the one template (again +`default') that was defined. + +\subsubsection{Available Options} +This section only lists the options that can be used when defining an instance +of the `default' template. The following subsections will give some examples +of their usage. + +\begin{beispiel}[code only] + \DeclareTemplateInterface{exsheets-tasks}{default}{3} + { + % option : type = default + enumerate : boolean = true , + label : tokenlist , + indent : length = 2.5em , + label-format : tokenlist = tsk[a]) , + label-width : length = 3ex , + after-item-skip : length = 2ex + } +\end{beispiel} + +\subsubsection{Predefined Instances} +This is rather brief this time: +\begin{beispiel}[code only] + % ALPHABETIZE: a) b) c) + \DeclareInstance{exsheets-tasks}{alphabetize}{default}{} + % available when `load-tasks=true': + % ITEMIZE: + \DeclareInstance{exsheets-tasks}{itemize}{default} + { enumerate = false } + % ENUMERATE: + \DeclareInstance{exsheets-tasks}{enumerate}{default} + { label-format = tsk. } + % MULTIPLECHOICE: + \DeclareInstance{exsheets-tasks}{multiplechoice}{default} + { + enumerate = false , + label = \choicebox , + } +\end{beispiel} +\secidx*{The `exsheets-tasks' Object} + +\subsection{Load Custom Configurations}\secidx{Custom Configurations} +If you have custom configurations you want to be loaded automatically then save +them in a file \code{exsheets\_configurations.cfg}. If this file is present it +will be loaded \cmd*{AtBeginDocument}. +\secidx*{Custom Configurations} +\secidx*{\ExSheets}[ExSheets] + +\part{The \translations package}\label{part:translations}\secidx{\translations}[translations] +\section{Motivation}\secidx[Motivation]{\translations}[translations] +I wrote this package when I was in need for an expandable version of +\paket*{translator}'s \cmd{translate}. If you don't need that then there is no +need whatsoever for this package as \paket*{translator} from the \paket{beamer} +bundle provides all the functionality \translations does (except for: +\paket{translator}'s \cmd{translate} isn't expandable, \cmd{GetTranslation} is.). + +\section{Usage}\secidx[Usage]{\translations}[translations] +These are the commands provided by \translations: +\begin{beschreibung} + \Befehl{DeclareLanguage}{<lang>}\newline + Declare a language that can be used by \translations. If the language already + exists it will be silently redefined. This command can only be used in the preamble. + \Befehl{DeclareLanguageAlias}{<lang2>}\ma{<lang1>}\newline + Declares \code{<lang2>} to be an alias of \code{<lang1>}. If \code{<lang1>} + doesn't exist yet a warning will be raised and it will be defined. This command + can only be used in the preamble. + \Befehl{NewTranslation}{<lang>}\ma{<key>}\ma{<translation>}\newline + Defines a translation of key \code{<key>} for the language \code{<lang>}. + An error will be raised if a translation of \code{<key>} already exists. + This command can only be used in the preamble. + \Befehl{RenewTranslation}{<lang>}\ma{<key>}\ma{<translation>}\newline + Redefines a translation of key \code{<key>} for the language \code{<lang>}. + An error will be raised if no translation of \code{<key>} exists. + This command can only be used in the preamble. + \Befehl{DeclareTranslation}{<lang>}\ma{<key>}\ma{<translation>}\newline + Defines a translation of key \code{<key>} for the language \code{<lang>}. + No error will be raised if a translation of \code{<key>} already exists. + This command can only be used in the preamble. + \expandable\Befehl{GetTranslationFor}{<lang>}\ma{<key>}\newline + Fetches and prints the translation of \code{<key>} for the language \code{<lang>}. + This command is expandable. + \expandable\Befehl{GetTranslation}{<key>}\newline + Fetches and prints the translation of \code{<key>} for the currently active + language (as for example set by \paket{babel}). This command is expandable. + \Befehl{SaveTranslationFor}{<cmd>}\ma{<lang>}\ma{<key>}\newline + Fetches and saves the translation of \code{<key>} for the language \code{<lang>} + in the macro \code{<cmd>}. + \Befehl{SaveTranslation}{<cmd>}\ma{<key>}\newline + Fetches and saves the translation of \code{<key>} or the currently active + language (as for example set by \paket{babel}) in the macro \code{<cmd>}. + \Befehl{LoadDictionary}{<name>}\newline + Loads a file named \code{<name>-<lang>.trsl} where \code{<lang>} corresponds + to the lowercase name of the current language as defined with + \cmd{DeclareLanguage}. This file should contain the translations for the + specified language. + \Befehl{LoadDictionaryFor}{<lang>}\ma{<name>}\newline + Loads a file named \code{<name>-<lang>.trsl}. +\end{beschreibung} +Quite a number of languages already are defined, either directly or via an alias. +So, before you define a language you should take a look in \code{translations.sty} +if the language doesn't already exist. + +Here is a small example of usage: +\begin{beispiel} + % in the preamble: + % \DeclareTranslation{English}{Kueche}{kitchen} + % \DeclareTranslation{German}{Kueche}{K\"uche} + % \DeclareTranslation{Spanish}{Kueche}{cocina} + % \DeclareTranslation{French}{Kueche}{cuisine} + + \GetTranslation{Kueche} + \SaveTranslation\kitchen{Kueche} + \SaveTranslationFor\cuisine{french}{Kueche} + + \selectlanguage{ngerman} + \GetTranslation{Kueche} \kitchen\ \GetTranslationFor{spanish}{Kueche} + \cuisine +\end{beispiel} + +A typical dictionary file should look as follows: +\begin{beispiel}[code only] + % this is file housing-german.trsl + \ProvideDictionaryFor{german}{housing}[<version info>] + \DeclareTranslation{German}{kitchen (housing)}{K\"uche} + \DeclareTranslation{German}{bathroom (housing)}{Bad} + \DeclareTranslation{German}{living room (housing)}{Wohnzimmer} + \DeclareTranslation{German}{bedroom (housing)}{Schlafzimmer} + ... + \endinput +\end{beispiel} +\secidx*{\translations}[translations] + +\part{The \cntformats package}\label{part:cntformats}\secidx{\cntformats}[cntformats] +\section{Motivation}\secidx[Motivation]{\cntformats}[cntformats] +\cntformats provides a way to format counters with what I will call patterns. +This does not in any way effect the usual \LaTeXe\ way of treating counters and +does not use \cmd*{the<counter>} nor is it affected by the redefinition of them. + +This package is aimed at package or class authors and probably not very useful +for document authors. + +\section{Example}\secidx[Example]{\cntformats}[cntformats] +A use case typically looks as follows: +\begin{beispiel} + \ReadCounterPattern{se.sse} +\end{beispiel} +where the key \code{se} stands for the current value of the \code{section} counter +and \code{sse} for \code{subsection}, respectively. \code{se.sse} is an example +for what will be called \emph{pattern}. The keys for the counters can have optional +arguments that specify the format: +\begin{beispiel} + \stepcounter{subsection} + \ReadCounterPattern{se[A](sse[r])} +\end{beispiel} +\code{A} stands for \cmd{Alph} and \code{r} for \cmd{roman}. A complete list can +be found in table~\ref{tab:predefined:formats} on page~\pageref{tab:predefined:formats}. +As you can see you can insert arbitrary other tokens in a pattern that won't be +changed. + +\section{Usage}\secidx[Usage]{\cntformats}[cntformats] +In order to make counters known to \cntformats the following commands are used: +\begin{beschreibung} + \Befehl{AddCounterPattern}*[<module>]{<counter>}\ma{<pattern>}\newline + This command will make the (existing) counter \code{<counter>} known to + \cntformats and assign the pattern \code{<pattern>} to it. + \Befehl{NewCounterPattern}*[<module>]{<counter>}\ma{<pattern>}\newline + This command will create a new counter \code{<counter>}, make it known to + \cntformats and assign the pattern \code{<pattern>} to it. + \Befehl{ReadCounterFrom}[<module>]{<counter>}\ma{<internal cmd>}\newline + If you use one of the commands above with the starred version the number for + the pattern is not automatically fetched from the internal \cmd*{c@<counter>}. + This can now be assigned with \cmd{ReadCounterFrom} where \code{<internal cmd>} + is the macro that holds the number. +\end{beschreibung} +The commands above can only be used in the document preamble. + +After the creation of these pattern markers one wants to be able to use them. +There are a number of macros that allow different aspects of usage. +\begin{beschreibung} + \Befehl{ReadCounterPattern}[<module>]{<pattern>}\newline + Reads, interprets and prints a pattern. + \expandable\Befehl{@cntfmts@parsed@pattern}\newline + After \cmd{ReadCounterPattern} has been used the current pattern interpretation + is stored in this macro. The \emph{interpretation} is \emph{not} what is printed. + See the examples below for details. + \Befehl{ReadCounterPatternFrom}[<module>]{<macro that holds pattern>}\newline + Reads, interprets and prints a pattern that's stored in a macro.\\ + Otherwise the same as \cmd{ReadCounterPattern}. + \Befehl{SaveCounterPattern}{<cmd a>}\ma{<cmd b>}\ma{<pattern>}\newline + Saves the \code{<pattern>} in \code{<cmd a>} and the interpreted pattern in + \code{<cmd b>}. + \Befehl{eSaveCounterPattern}[<module>]{<cmd a>}\ma{<cmd b>}\ma{<pattern>}\newline + Saves the \code{<pattern>} in \code{<cmd a>} and the expanded pattern in + \code{<cmd b>}. + \Befehl{SaveCounterPatternFrom}[<module>]{<cmd a>}\ma{<cmd b>}\ma{<macro that + holds pattern>}\newline + Like \cmd{SaveCounterPattern} but reads the pattern from a macro. + \Befehl{eSaveCounterPatternFrom}[<module>]{<cmd a>}\ma{<cmd b>}\ma{<macro that + holds pattern>}\newline + Like \cmd{eSaveCounterPattern} but reads the pattern from a macro. +\end{beschreibung} + +The optional argument \code{<module>} should be specific for a package, say, so +that different patterns for the \code{section} for example don't interfer with +each other. If you leave the argument the default module \code{cntfmts} is used. + +The \ExSheets packages uses the commands with the module \code{exsheets}. +You can find the following lines in \ExSheets' code: +\begin{beispiel}[code only] + \AddCounterPattern*[exsheets]{section}{se} + \ReadCounterFrom[exsheets]{section} + \l__exsheets_counter_sec_int + + \NewCounterPattern*[exsheets]{question}{qu} + \ReadCounterFrom[exsheets]{question} + \l__exsheets_counter_qu_int +\end{beispiel} + +Now let's see a short example that hopefully explains what the macros do: +\begin{beispiel} + % preamble + % \NewCounterPattern{testa}{ta} + \setcounter{testa}{11} + \ReadCounterPattern{ta} + \ReadCounterPattern{ta[a]} \\ + \ttfamily\makeatletter + \meaning\@cntfmts@parsed@pattern + + \bigskip + \SaveCounterPattern\tmpa\tmpb{ta[a]} + \meaning\tmpa \\ + \meaning\tmpb + + \bigskip + \eSaveCounterPattern\tmpa\tmpb{ta[a]} + \meaning\tmpa \\ + \meaning\tmpb +\end{beispiel} +You can see that somehow additional (empty) groups and a \cmd*{relax} found their +way into the interpreted and thus the expanded pattern. This is due to the fact +that reading optional arguments expandably isn't easy and must have some safety +net. + +\section{Predefined Patterns and Formats}\secidx[Predefined Patterns]{\cntformats}[cntformats] +\cntformats predefines a number of pattern keys. These are listed in +table~\ref{tab:predefined:patterns}. + +\begin{multicols}{2} +\begin{center} + \centering + \captionof{table}{Predefined Patterns for the module \code{cntfmts}.}\label{tab:predefined:patterns} + \begin{tabular}{>{\ttfamily}l>{\ttfamily}l} + \toprule + \normalfont\bfseries counter & \normalfont\bfseries pattern \\ + \midrule + chapter & ch \\ + section & se \\ + subsection & sse \\ + subsubsection & ssse \\ + paragraph & pg \\ + \bottomrule + \end{tabular} + + \captionof{table}{Predefined Formats}\label{tab:predefined:formats} + \begin{tabular}{>{\ttfamily}ll} + \toprule + \normalfont\bfseries key & \normalfont\bfseries format \\ + \midrule + 1 & \cmd{arabic} \\ + a & \cmd{alph} \\ + A & \cmd{Alph} \\ + r & \cmd{roman} \\ + R & \cmd{Roman} \\ + \bottomrule + \end{tabular} +\end{center} +\end{multicols} + +Table~\ref{tab:predefined:formats} lists the predefined formats. If you want you +can add own formats. +\begin{beschreibung} + \Befehl{NewPatternFormat}{<pattern>}\ma{<format>}\newline + \code{<format>} is a number presentation command like \cmd{@alph}. This + command can only be used in the preamble. +\end{beschreibung} + +\begin{beispiel} + % preamble + % \usepackage{alphalph} + % \makeatletter + % \NewPatternFormat{aa}{\alphalph@alph} + % \makeatother + \ReadCounterPattern{se[aa]} +\end{beispiel} +\secidx*{\cntformats}[cntformats] + +\appendix +\part{Appendix} +\addsec{A List of all Solutions used in this Manual}\label{sec:solutions:list} +\SetupExSheets{headings=block,solutions-totoc} +\printsolutions + +{\EmbracOff\RaggedRight\printbibliography} + +\setindexpreamble{Section titles are indicated \textbf{bold}, packages \textsf{sans +serif}, commands \code{\textbackslash\textcolor{code}{brown}}, options \textcolor +{key}{\code{yellow}} and modules \textcolor{module}{\code{blue}}.} +\printindex +\end{document}
\ No newline at end of file diff --git a/Master/texmf-dist/tex/latex/exsheets/cntformats.sty b/Master/texmf-dist/tex/latex/exsheets/cntformats.sty new file mode 100644 index 00000000000..41e4cef75d3 --- /dev/null +++ b/Master/texmf-dist/tex/latex/exsheets/cntformats.sty @@ -0,0 +1,324 @@ +% -------------------------------------------------------------------------- +% the CNTFORMATS package +% +% A different way to read counters +% +% This package is part of the exsheets bundle +% -------------------------------------------------------------------------- +% Clemens Niederberger +% Web: https://bitbucket.org/cgnieder/exsheets/ +% E-Mail: contact@mychemistry.eu +% -------------------------------------------------------------------------- +% Copyright 2012 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 cntformats package consists of the files +% - cntformats.sty +% -------------------------------------------------------------------------- +% If you have any ideas, questions, suggestions or bugs to report, please +% feel free to contact me. +% -------------------------------------------------------------------------- +\def\cntfmts@date{2012/10/08} +\def\cntfmts@version{v0.2b} + +\ProvidesPackage{cntformats}[\cntfmts@date\space \cntfmts@version\space A different way to read counters.] +\RequirePackage{etoolbox,xparse} +% -------------------------------------------------------------------------- +% message handling +\def\@cntfmts@error@message{% + For details have a look at the `exsheets' manual.} + +\def\@cntfmts@create@message#1{% + \ifstrequal{#1}{Error} + {% + \lowercase{\csdef{@cntfmts@#1}}##1{% + \csuse{Package#1}{cntformats}{##1}{\@cntfmts@error@message}}% + }{% + \lowercase{\csdef{@cntfmts@#1}}##1{% + \csuse{Package#1}{cntformats}{##1}}% + }} +\@cntfmts@create@message{Error} +\@cntfmts@create@message{Warning} +\@cntfmts@create@message{WarningNoLine} +\@cntfmts@create@message{Info} + +\def\@cntfmts@err@already@defined#1{% + \@cntfmts@error{The counter `#1' already exists!}} +\def\@cntfmts@err@unknown@counter#1{% + \@cntfmts@error{The counter `#1' is undefined!}} +\def\@cntfmts@err@pattern@defined#1#2{% + \@cntfmts@error{The pattern `#2' for module `#1' is already defined!}} +\def\@cntfmts@err@pattern@undefined#1#2{% + \@cntfmts@error{The pattern `#2' for module `#1' is undefined!}} + +% ---------------------------------------------------------------------------- +% tokenlist analyzing and manipulating +% if you happen to read this code and notice some obvious reasons why these +% macros shoudn't be used like this, please send me your improved version +% (seriously! But please explain why yours is better) +\def\ifintl#1#2{% + \def\@cntfmts@intl@tmpa##1#2{}% + \expandafter\if\expandafter\relax\expandafter + \detokenize\expandafter{\@cntfmts@intl@tmpa#1{}{}#2}\relax% + \expandafter\@secondoftwo + \else + \expandafter\@firstoftwo + \fi +} +\def\ifintlcs#1{% + \expandafter\ifintl\expandafter{#1}} + +\long\def\replaceonceincs#1#2#3{% + \ifintlcs#1{#2}% + {\@cntfmts@replace@once@incs#1{#2}{#3}}{}% +} +\long\def\@cntfmts@replace@once@incs#1#2#3{% + \def\@cntfmts@replo@tmpa##1#2##2\q@stop{% + \def#1{##1#3##2}}% + \expandafter\@cntfmts@replo@tmpa#1\q@stop +} + +\long\def\replaceallin#1#2#3{% + \def\@cntfmts@repla@tmpa{#1}% + \replaceonceincs\@cntfmts@repla@tmpa{#2}{#3}% + \ifintlcs\@cntfmts@repla@tmpa{#2}% + {\expandafter\replaceallin\expandafter{\@cntfmts@repla@tmpa}{#2}{#3}}% + {\expandonce\@cntfmts@repla@tmpa}% +} +\long\def\replaceallincs#1#2#3{% + \replaceonceincs#1{#2}{#3}% + \ifintlcs#1{#2}{\replaceallincs#1{#2}{#3}}{}% +} + +% ---------------------------------------------------------------------------- +% expansion tools +% heavily inspired by expl3's \exp_args:N<spec> +\long\def\@cntfmts@getnextbraced#1#2#3{#2\@cntfmts@firstofone{#3{#1}}} +\long\def\@cntfmts@firstofone#1{#1} +\long\def\@cntfmts@braced@unexpanded#1\@cntfmts@firstofone#2#3{% + #1\@cntfmts@firstofone{#2{#3}}} +\long\def\@cntfmts@braced@expandedonce#1\@cntfmts@firstofone#2#3{% + \expandafter\@cntfmts@getnextbraced\expandafter{#3}{#1}{#2}} + +\long\def\@cntfmts@expand@first{% + \@cntfmts@braced@expandedonce + \@cntfmts@firstofone} + +\long\def\@cntfmts@expand@second{% + \@cntfmts@braced@unexpanded + \@cntfmts@braced@expandedonce + \@cntfmts@firstofone} + +\long\def\@cntfmts@expand@third{% + \@cntfmts@braced@unexpanded + \@cntfmts@braced@unexpanded + \@cntfmts@braced@expandedonce + \@cntfmts@firstofone} + +% ---------------------------------------------------------------------------- +% expandable commands with optional argument (and no mandatory) +% this is probably not very robust. If you know what you're doing you're +% probably able to define a better version yourself. If not, don't use it +\long\def\@cntfmts@isopt@#1[#2\q@marker#3#{% + \if\relax\detokenize{#1#2}\relax + \expandafter\@firstoftwo + \else + \expandafter\@secondoftwo + \fi} +\long\def\@cntfmts@isopt#1#2#3{% + \@cntfmts@isopt@#1\q@marker[\q@marker{#2#1}{#2[{#3}]{#1}}} + +\long\def\@cntfmts@defwopt#1[#2]#3{% + \long\def#1##1{\@cntfmts@isopt{##1}{\csuse{\@cntfmts@strip@bs#1@opt}}{#2}}% + \long\csdef{\@cntfmts@strip@bs#1@opt}[##1]{#3}} + +\def\@cntfmts@strip@bs{\expandafter\@gobble\string} + +% ---------------------------------------------------------------------------- +% #1: module +% #2: counter +\def\@cntfmts@def@counter@read#1#2#3{% + \@cntfmts@expand@second\csdef + {@#1@read@#3@counter}% + {\csname @#1@read@#2@counter\endcsname}} + +% create pattern for an existing counter: +% #1: module +% #2: counter +% #3: id +\newcommand*\@cntfmts@add@counter@pattern[3][cntfmts]{% + \ifcsdef{the#2} + {}{\@cntfmts@err@unknown@counter{#2}}% + \ifcsdef{@#1@#2@counter} + {\@cntfmts@err@pattern@defined{#1}{#2}} + {\csdef{@#1@#2@counter}{}}% + \listcsadd{@#1@counter@ids}{#3}% + \@cntfmts@def@counter@read{#1}{#2}{#3}% +} + +\newcommand*\@cntfmts@add@counter@pattern@nostar[3][cntfmts]{% + \@cntfmts@add@counter@pattern[#1]{#2}{#3}% + \@cntfmts@expand@third + \@cntfmts@create@read@counter{#1}{#2}{\csname c@#2\endcsname}} + +\newrobustcmd*\AddCounterPattern{% + \@ifstar + {\@cntfmts@add@counter@pattern} + {\@cntfmts@add@counter@pattern@nostar}} +\@onlypreamble\AddCounterPattern + +% create pattern for a new counter +% #1: counter +% #2: id +\newcommand*\@cntfmts@new@counter@pattern[3][cntfmts]{% + \ifcsdef{the#2} + {\@cntfmts@err@counter@defined{#2}}{}% + \newcounter{#2}% + \listcsadd{@#1@counter@ids}{#3}% + \@cntfmts@def@counter@read{#1}{#2}{#3}% + \csdef{@#1@#2@counter}{} +} + +\newcommand*\@cntfmts@new@counter@pattern@nostar[3][cntfmts]{% + \@cntfmts@new@counter@pattern[#1]{#2}{#3}% + \@cntfmts@expand@third + \@cntfmts@create@read@counter{#1}{#2}{\csname c@#2\endcsname}} + +\newrobustcmd*\NewCounterPattern{% + \@ifstar + {\@cntfmts@new@counter@pattern} + {\@cntfmts@new@counter@pattern@nostar}} +\@onlypreamble\NewCounterPattern + +% renew pattern: +\newcommand*\@cntfmts@renew@counter@pattern[3][cntfmts]{% + \ifcsdef{the#2} + {}{\@cntfmts@err@unknown@counter{#2}}% + \ifcsdef{@#1@#2@counter}{} + {\@cntfmts@err@pattern@undefined{#1}{#2}}% + \ifinlistcs{@#1@counter@ids}{#3} + {}{\listcsadd{@#1@counter@ids}{#3}}% + \@cntfmts@def@counter@read{#1}{#2}{#3}% +} + +\newcommand*\@cntfmts@renew@counter@pattern@nostar[3][cntfmts]{% + \@cntfmts@renew@counter@pattern[#1]{#2}{#3}% + \@cntfmts@expand@third + \@cntfmts@create@read@counter{#1}{#2}{\csname c@#2\endcsname}} + +\newrobustcmd\RenewCounterPattern{% + \@ifstar + {\@cntfmts@renew@counter@pattern} + {\@cntfmts@renew@counter@pattern@nostar}} +\@onlypreamble\RenewCounterPattern + +% ---------------------------------------------------------------------------- +% assign a different internal command to <counter> than \c@<counter> +% can/must be used after a call from \AddCounterPattern* or +% \NewCounterPattern* +% #1: module +% #2: counter +% #3: internal command +\def\@cntfmts@create@read@counter#1#2#3{% + \expandafter\@cntfmts@defwopt\csname @#1@read@#2@counter\endcsname[]{% + \ifblank{##1} + {\@arabic{#3}} + {\csuse{@cntfmts@counter@type@##1}{#3}}% + }% +} + +\newrobustcmd*\ReadCounterFrom[3][cntfmts]{% + \@cntfmts@create@read@counter{#1}{#2}{#3}} + +% ---------------------------------------------------------------------------- +% pattern formats +% #1: key +% #2: number presentation command like \@alph +\def\@cntfmts@new@pattern@format#1#2{% + \csdef{@cntfmts@counter@type@#1}{#2}} + +\newrobustcmd*\NewPatternFormat[2]{% + \@cntfmts@new@pattern@format{#1}{#2}} +\@onlypreamble\NewPatternFormat + +% ---------------------------------------------------------------------------- +% interpret and print pattern: +% #1: module +% #2: list +% #3: pattern +\def\@cntfmts@read@counter@pattern#1#2#3{% + \def\@cntfmts@parsed@pattern{#3\relax}% + \forlistcsloop{\@cntfmts@replace@pattern{#1}}{#2}% +} +% #1: module +% #2: pattern-key +\def\@cntfmts@replace@pattern#1#2{% + \replaceallincs\@cntfmts@parsed@pattern + {#2}{{}\csuse{@#1@read@#2@counter}}} + +\newrobustcmd*\ReadCounterPattern[2][cntfmts]{% + \@cntfmts@read@counter@pattern{#1}{@#1@counter@ids}{#2}\@cntfmts@parsed@pattern} + +\newrobustcmd*\ReadCounterPatternFrom[2][cntfmts]{% + \@cntfmts@expand@third\@cntfmts@read@counter@pattern{#1}{@#1@counter@ids}{#2}% + \@cntfmts@parsed@pattern} + +% #1: save pattern in +% #2: save interpretation in +% #3: pattern +% #4: module +\newcommand*\@cntfmts@save@counter@pattern[4]{% + \@cntfmts@read@counter@pattern{#4}{@#4@counter@ids}{#3}% + \let#2\@cntfmts@parsed@pattern + \def#1{#3}% +} + +\newcommand*\@cntfmts@esave@counter@pattern[4]{% + \@cntfmts@read@counter@pattern{#4}{@#4@counter@ids}{#3}% + \edef#2{\@cntfmts@parsed@pattern}% + \def#1{#3}% +} + +\newrobustcmd*\SaveCounterPattern[4][cntfmts]{% + \@cntfmts@save@counter@pattern{#2}{#3}{#4}{#1}} + +\newrobustcmd*\SaveCounterPatternFrom[4][cntfmts]{% + \@cntfmts@expand@third\@cntfmts@save@counter@pattern{#2}{#3}{#4}{#1}} + +\newrobustcmd*\eSaveCounterPattern[4][cntfmts]{% + \@cntfmts@esave@counter@pattern{#2}{#3}{#4}{#1}} + +\newrobustcmd*\eSaveCounterPatternFrom[4][cntfmts]{% + \@cntfmts@expand@third\@cntfmts@esave@counter@pattern{#2}{#3}{#4}{#1}} + +% ---------------------------------------------------------------------------- +% predefined formats and pattern +\NewPatternFormat{a}{\@alph} +\NewPatternFormat{A}{\@Alph} +\NewPatternFormat{1}{\@arabic} +\NewPatternFormat{r}{\@roman} +\NewPatternFormat{R}{\@Roman} + +\ifdef\theparagraph + {\AddCounterPattern{paragraph}{pg}}{} +\ifdef\thesubsubsection + {\AddCounterPattern{subsubsection}{ssse}}{} +\ifdef\thesubsection + {\AddCounterPattern{subsection}{sse}}{} +\ifdef\thesection + {\AddCounterPattern{section}{se}}{} +\ifdef\thechapter + {\AddCounterPattern{chapter}{ch}}{} + +\endinput
\ No newline at end of file diff --git a/Master/texmf-dist/tex/latex/exsheets/exsheets.sty b/Master/texmf-dist/tex/latex/exsheets/exsheets.sty new file mode 100644 index 00000000000..db748f1baf5 --- /dev/null +++ b/Master/texmf-dist/tex/latex/exsheets/exsheets.sty @@ -0,0 +1,2045 @@ +% ---------------------------------------------------------------------------- +% the EXSHEETS package +% +% Yet another package for the creation of exercise sheets +% +% ---------------------------------------------------------------------------- +% Clemens Niederberger +% Web: https://bitbucket.org/cgnieder/exsheets/ +% E-Mail: contact@mychemistry.eu +% ---------------------------------------------------------------------------- +% Copyright 2011-2012 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 exsheets package consists of the files +% - exsheets.sty, exsheets_headings.def, exsheets_headings.cfg, +% exsheets_tasks.def, exsheets_tasks.cfg, exsheets_configurations.cfg, +% - exsheets_en.tex, exsheets_en.pdf, +% - README +% ---------------------------------------------------------------------------- +% If you have any ideas, questions, suggestions or bugs to report, please +% feel free to contact me. +% ---------------------------------------------------------------------------- +\def\exsheets@date{2012/10/08} +\def\exsheets@version{0.2b} + +\RequirePackage { expl3 , xparse } +\ProvidesExplPackage + {exsheets} + {\exsheets@date} + {\exsheets@version} + {Yet another package for the creation of exercise sheets and exams.} + +% ---------------------------------------------------------------------------- +% temporary variables +\tl_new:N \l__exsheets_tmpa_tl +\tl_new:N \l__exsheets_tmpb_tl +\tl_new:N \l__exsheets_tmpc_tl +\int_new:N \l__exsheets_tmpa_int +\int_new:N \l__exsheets_tmpb_int +\dim_new:N \l__exsheets_tmpa_dim +\seq_new:N \l__exsheets_tmpa_seq +\fp_new:N \l__exsheets_tmpa_fp +\clist_new:N \l__exsheets_tmpa_clist + +% ---------------------------------------------------------------------------- +% messages +\msg_new:nnn { exsheets} { totalpoints } + { + You~need~to~activate~"points/parse"~if~you~want~to~use~ + \token_to_str:N \totalpoints .~I~will~do~nothing~instead. + } + +\msg_new:nnn { exsheets} { headings } + { + You~requested~the~headings~instance~`#1'~which~is~not~defined.~Did~you~ + forget~to~use~the~package~option~`load-headings'?~Anyway,~I~will~use~the~ + instance~`block'~instead~and~pretend~nothing~happened. + } + +\msg_new:nnn { exsheets } { random } + { + You~asked~me~to~select~#1~questions~from~file~#2~but~there~are~only~#3.~ + I'll~select~all~of~them. + } + +\msg_new:nnn { exsheets } { only-inside-question } + { + The~command~\token_to_str:N #1 \c_space_tl can~only~be~used~inside~ + the~question~environment. + } + +\msg_new:nnn { exsheets } { loading-configurations } + { Loading~custom~configurations~file~`exsheets_configurations.cgf'. } + +\msg_new:nnn { exsheets } { deprecated-command } + { + The~command~"~\token_to_str:N #1 \c_space_tl"~is~deprecated.~ + Use~"~\token_to_str:N #2 \c_space_tl"~instead. + } + +\msg_new:nnn { exsheets } { grade-missing } + { The~grade~`#1'~has~never~been~declared. } + +\msg_new:nnn { exsheets } { grade-parse } + { + I~cannot~calculate~the~points~for~grade~`#1'~since~you're~using~the~option~ + `points/parse=false'. + } + +\cs_new:Npn \exsheets_depr_cmd:nn #1#2 + { + \cs_new:Npn #1 + { \msg_warning:nnnn { exsheets } { deprecated-command } { #1 } { #2 } #2 } + } + +% ---------------------------------------------------------------------------- +\RequirePackage + { xtemplate , l3sort , l3keys2e , xcolor , etoolbox , environ , lcg , silence } + +% ---------------------------------------------------------------------------- +% color: +\xdefinecolor { exsheetsblue } { rgb } { 0.02 , 0.04 , 0.48 } +\xdefinecolor { exsheetsred } { rgb } { 0.65 , 0.04 , 0.07 } +\tl_new:N \g__exsheets_color_tl +\tl_gset:Nn \g__exsheets_color_tl { exsheetsblue } + +% ---------------------------------------------------------------------------- +% how are questions/solutions/... counted? +\bool_new:N \l__exsheets_print_number_bool +\bool_set_true:N \l__exsheets_print_number_bool + +\tl_new:N \l__exsheets_qu_counter_pattern_tl +\tl_set:Nn \l__exsheets_qu_counter_pattern_tl { qu. } +\tl_new:N \l__exsheets_qu_counter_interpretation_tl +\tl_new:N \l__exsheets_counter_patterns_tl +\tl_new:N \l__exsheets_current_pattern_interpretation_tl +\tl_new:N \l__exsheets_current_pattern_tl + +\RequirePackage { cntformats } + +\cs_if_exist:NT \thechapter + { + \AddCounterPattern* [ exsheets ] { chapter } { ch } + \ReadCounterFrom [ exsheets ] { chapter } \l__exsheets_counter_ch_int + } + +\AddCounterPattern* [ exsheets ] { section } { se } +\ReadCounterFrom [ exsheets ] { section } \l__exsheets_counter_sec_int + +\NewCounterPattern* [ exsheets ] { question } { qu } +\ReadCounterFrom [ exsheets ] { question } \l__exsheets_counter_qu_int + +% ---------------------------------------------------------------------------- +% (also) package options: +\bool_new:N \l__exsheets_load_headings_bool +\bool_new:N \l__exsheets_load_tasks_bool +\bool_new:N \l__exsheets_solutions_by_ref_bool +\bool_new:N \l__exsheets_questions_totoc_bool +\bool_new:N \l__exsheets_solutions_totoc_bool + +\tl_new:N \l__exsheets_heading_instance_tl +\tl_set:Nn \l__exsheets_heading_instance_tl { block } +\tl_new:N \l__exsheets_heading_title_user_format_tl +\tl_set:Nn \l__exsheets_heading_title_user_format_tl { \normalsize\bfseries } +\tl_new:N \l__exsheets_questions_toclevel_tl +\tl_set:Nn \l__exsheets_questions_toclevel_tl { subsection } +\tl_new:N \l__exsheets_solutions_toclevel_tl +\tl_set:Nn \l__exsheets_solutions_toclevel_tl { subsection } + +\AtBeginDocument{ + \cs_if_exist:NF \phantomsection + { \cs_new:Npn \phantomsection {} } +} + +\keys_define:nn { exsheets } + { + color .tl_gset:N = \g__exsheets_color_tl , + counter-format .code:n = + \SaveCounterPattern [ exsheets ] + \l__exsheets_qu_counter_pattern_tl + \l__exsheets_qu_counter_interpretation_tl + { #1 } , + counter-within .code:n = \@addtoreset{question}{#1} , + headings .tl_set:N = \l__exsheets_heading_instance_tl , + load-headings .bool_set:N = \l__exsheets_load_headings_bool , + headings-format .tl_set:N = \l__exsheets_heading_title_user_format_tl , + load-tasks .bool_set:N = \l__exsheets_load_tasks_bool , + use-ref .bool_set:N = \l__exsheets_solutions_by_ref_bool , + totoc .choice: , + totoc / true .code:n = + \bool_set_true:N \l__exsheets_questions_totoc_bool + \bool_set_true:N \l__exsheets_solutions_totoc_bool , + totoc / false .code:n = + \bool_set_false:N \l__exsheets_questions_totoc_bool + \bool_set_false:N \l__exsheets_solutions_totoc_bool , + totoc .default:n = true , + questions-totoc .bool_set:N = \l__exsheets_questions_totoc_bool , + solutions-totoc .bool_set:N = \l__exsheets_solutions_totoc_bool , + toc-level .code:n = + \tl_set:Nn \l__exsheets_questions_toclevel_tl { #1 } + \tl_set:Nn \l__exsheets_solutions_toclevel_tl { #1 } , + questions-toc-level .tl_set:N = \l__exsheets_questions_toclevel_tl , + solutions-toc-level .tl_set:N = \l__exsheets_solutions_toclevel_tl + } +\keys_set:nn { exsheets} { counter-format = qu. } + +% process package options: +\ProcessKeysOptions { exsheets } + +% ---------------------------------------------------------------------------- +% points for exercises +\bool_new:N \l__exsheets_points_questions_default_bool +\bool_set_false:N \l__exsheets_points_questions_default_bool +\bool_new:N \l__exsheets_parse_points_bool +\bool_set_true:N \l__exsheets_parse_points_bool +\bool_new:N \l__exsheets_points_name_bool +\bool_set_true:N \l__exsheets_points_name_bool +\bool_new:N \l__exsheets_points_separate_bonus_bool + +\fp_new:N \g__exsheets_points_sum_fp +\fp_new:N \l__exsheets_points_default_fp +\fp_set:Nn \l__exsheets_points_default_fp { 1 } +\fp_new:N \l__exsheets_question_points_fp +\fp_new:N \g__exsheets_total_points_fp +\fp_new:N \g__exsheets_bonus_sum_fp +\fp_new:N \l__exsheets_question_bonus_fp +\fp_new:N \g__exsheets_total_bonus_fp + +\tl_new:N \l__exsheets_points_name_tl +\tl_set:Nn \l__exsheets_points_name_tl { P. } +\tl_new:N \l__exsheets_points_name_plural_tl +\tl_set:Nn \l__exsheets_points_name_plural_tl { P. } +\tl_new:N \l__exsheets_bonus_name_tl +\tl_set:Nn \l__exsheets_bonus_name_tl { P. } +\tl_new:N \l__exsheets_bonus_name_plural_tl +\tl_set:Nn \l__exsheets_bonus_name_plural_tl { P. } +\tl_new:N \l__exsheets_points_number_format_tl +\tl_new:N \l__exsheets_bonus_number_format_tl +\tl_new:N \l__exsheets_points_pre_bonus_marker_tl +\tl_set:Nn \l__exsheets_points_pre_bonus_marker_tl { (+ } +\tl_new:N \l__exsheets_points_post_bonus_marker_tl +\tl_set:Nn \l__exsheets_points_post_bonus_marker_tl { ) } + +\cs_new_nopar:Npn \exsheets_set_points_name:n #1 + { + \tl_if_in:nnTF { #1 } { / } + { \__exsheets_set_points_name_aux:nn #1 \q_stop } + { \__exsheets_set_points_name_aux:nn #1 / \q_stop } + } + +\cs_new_nopar:Npn \__exsheets_set_points_name_aux:nn #1/#2 \q_stop + { + \tl_set:Nn \l__exsheets_points_name_tl { #1 } + \tl_set:Nn \l__exsheets_points_name_plural_tl { #1#2 } + } + +\cs_new_nopar:Npn \exsheets_set_bonus_name:n #1 + { + \tl_if_in:nnTF { #1 } { / } + { \__exsheets_set_bonus_name_aux:nn #1 \q_stop } + { \__exsheets_set_bonus_name_aux:nn #1 / \q_stop } + } + +\cs_new_nopar:Npn \__exsheets_set_bonus_name_aux:nn #1/#2 \q_stop + { + \tl_set:Nn \l__exsheets_bonus_name_tl { #1 } + \tl_set:Nn \l__exsheets_bonus_name_plural_tl { #1#2 } + } + +% FIXME: \fp_add will deprecate! +\cs_new_nopar:Npn \exsheets_add_points:n #1 + { \fp_gadd:Nn \g__exsheets_points_sum_fp { #1 } } +\cs_generate_variant:Nn \exsheets_add_points:n { V } + +\cs_new_nopar:Npn \exsheets_add_bonus:n #1 + { \fp_gadd:Nn \g__exsheets_bonus_sum_fp { #1 } } +\cs_generate_variant:Nn \exsheets_add_bonus:n { V } + +\cs_new_nopar:Npn \exsheets@sum@of@points #1 + { \fp_gset:Nn \g__exsheets_total_points_fp { #1 } } + +\cs_new_nopar:Npn \exsheets@sum@of@bonus #1 + { \fp_gset:Nn \g__exsheets_total_bonus_fp { #1 } } + +\cs_new_nopar:Npn \exsheets_parse_points:n #1 + { + \group_begin: + \tl_use:N \l__exsheets_points_number_format_tl + { + \bool_if:NTF \l__exsheets_parse_points_bool + { \exsheets_num:n { \fp_to_decimal:n { #1 } } } + { \use:n { \fp_to_decimal:n { #1 } } } + } + \group_end: + } +\cs_generate_variant:Nn \exsheets_parse_points:n { V } + +\cs_new_nopar:Npn \exsheets_parse_bonus:n #1 + { + \group_begin: + \tl_use:N \l__exsheets_bonus_number_format_tl + { + \bool_if:NTF \l__exsheets_parse_points_bool + { \exsheets_num:n { \fp_to_decimal:n { #1 } } } + { \use:n { \fp_to_decimal:n { #1 } } } + } + \group_end: + } +\cs_generate_variant:Nn \exsheets_parse_bonus:n { V } + +\cs_new_nopar:Npn \exsheets_num:n #1 + { + \group_begin: + \fp_set:Nn \l__exsheets_tmpa_tl { #1 } + \fp_to_tl:N \l__exsheets_tmpa_tl + \group_end: + } +\cs_generate_variant:Nn \exsheets_num:n { x } + +\cs_new_nopar:Npn \exsheets_points_name:n #1 + { + \bool_if:NT \l__exsheets_points_name_bool + { + \, + \hbox:n + { + \bool_if:NTF \l__exsheets_parse_points_bool + { + \tl_if_eq:nnTF { #1 } { ?? } + { \tl_use:N \l__exsheets_points_name_plural_tl } + { + \fp_compare:nTF { #1 <= 1 } + { \tl_use:N \l__exsheets_points_name_tl } + { \tl_use:N \l__exsheets_points_name_plural_tl } + } + } + { \tl_use:N \l__exsheets_points_name_plural_tl } + } + } + } +\cs_generate_variant:Nn \exsheets_points_name:n { V } + +\cs_new_nopar:Npn \exsheets_bonus_name:n #1 + { + \bool_if:NT \l__exsheets_points_name_bool + { + \, + \hbox:n + { + \bool_if:NTF \l__exsheets_parse_points_bool + { + \tl_if_eq:nnTF { #1 } { ?? } + { \tl_use:N \l__exsheets_bonus_name_plural_tl } + { + \fp_compare:nTF { #1 <= 1 } + { \tl_use:N \l__exsheets_bonus_name_tl } + { \tl_use:N \l__exsheets_bonus_name_plural_tl } + } + } + { \tl_use:N \l__exsheets_bonus_name_plural_tl } + } + } + } +\cs_generate_variant:Nn \exsheets_bonus_name:n { V } + +\NewDocumentCommand \addpoints { sm } + { + \bool_if:NTF \l__exsheets_inside_question_bool + { + \exsheets_add_points:n { #2 } + \IfBooleanF { #1 } { \exsheets_print_points:n { #2 } } + } + { \msg_error:nnn { exsheets } { only-inside-question } { \addpoints } } + } + +\NewDocumentCommand \addbonus { sm } + { + \bool_if:NTF \l__exsheets_inside_question_bool + { + \exsheets_add_bonus:n { #2 } + \IfBooleanF { #1 } { \exsheets_print_bonus:n { #2 } } + } + { \msg_error:nnn { exsheets } { only-inside-question } { \addbonus } } + } + +\NewDocumentCommand \points { sm } + { + \IfBooleanTF { #1 } + { \exsheets_parse_points:n { #2 } } + { \exsheets_print_points:n { #2 } } + } + +\NewDocumentCommand \bonus { sm } + { + \IfBooleanTF { #1 } + { \exsheets_parse_bonus:n { #2 } } + { \exsheets_print_bonus:n { #2 } } + } + +\cs_new_nopar:Npn \exsheets_print_points:n #1 + { + \exsheets_parse_points:n { #1 } + \exsheets_points_name:n { #1 } + } +\cs_generate_variant:Nn \exsheets_print_points:n { V } + +\cs_new_nopar:Npn \exsheets_print_bonus:n #1 + { + \exsheets_parse_bonus:n { #1 } + \exsheets_bonus_name:n { #1 } + } +\cs_generate_variant:Nn \exsheets_print_bonus:n { V } + +\NewDocumentCommand \pointssum { s } + { + \IfBooleanTF { #1 } + { \exsheets_parse_points:n { \g__exsheets_total_points_fp } } + { \exsheets_print_points:n { \g__exsheets_total_points_fp } } + } + +\NewDocumentCommand \bonussum { s } + { + \IfBooleanTF { #1 } + { \exsheets_parse_bonus:n { \g__exsheets_total_bonus_fp } } + { \exsheets_print_bonus:n { \g__exsheets_total_bonus_fp } } + } + +\NewDocumentCommand \currentpointssum { s } + { + \IfBooleanTF { #1 } + { \exsheets_parse_points:n { \g__exsheets_points_sum_fp } } + { \exsheets_print_points:n { \g__exsheets_points_sum_fp } } + } + +\NewDocumentCommand \currentbonussum { s } + { + \IfBooleanTF { #1 } + { \exsheets_parse_bonus:n { \g__exsheets_bonus_sum_fp } } + { \exsheets_print_bonus:n { \g__exsheets_bonus_sum_fp } } + } + +\NewDocumentCommand \totalpoints { s } + { + \exsheets_totalpoints: + \IfBooleanF { #1 } + { + \bool_if:nT + { + \l__exsheets_points_separate_bonus_bool || + \fp_compare_p:n { \g__exsheets_total_bonus_fp = 0 } + } + { \exsheets_points_name:n { \g__exsheets_total_points_fp } } + } + \exsheets_totalbonus: + \IfBooleanF { #1 } + { + \fp_compare:nF { \g__exsheets_total_bonus_fp = 0 } + { + \bool_if:NTF \l__exsheets_points_separate_bonus_bool + { \exsheets_bonus_name:n { \g__exsheets_total_bonus_fp } } + { + \exsheets_points_name:n + { \g__exsheets_total_points_fp + \g__exsheets_total_bonus_fp } + } + } + } + } + +\exsheets_depr_cmd:nn { \sumpoints } { \totalpoints* } + +\cs_new_nopar:Npn \exsheets_totalpoints: + { + \bool_if:NTF \l__exsheets_parse_points_bool + { + \fp_compare:nTF { \g__exsheets_total_points_fp = 0 } + { ?? \, \exsheets_points_name:n { ?? } } + { + \exsheets_parse_points:n + { \g__exsheets_total_points_fp } + } + } + { \msg_warning:nn { exsheets } { totalpoints } } + } + +\cs_new_nopar:Npn \exsheets_totalbonus: + { + \bool_if:NT \l__exsheets_parse_points_bool + { + \fp_compare:nF { \g__exsheets_total_bonus_fp = 0 } + { + \tl_use:N \c_space_tl + \tl_use:N \l__exsheets_points_pre_bonus_marker_tl + \exsheets_parse_bonus:n + { \g__exsheets_total_bonus_fp } + \tl_use:N \l__exsheets_points_post_bonus_marker_tl + } + } + } + +\keys_define:nn { exsheets / points } + { + name .code:n = + \exsheets_set_points_name:n { #1 } + \exsheets_set_bonus_name:n { #1 } , + name-plural .code:n = + \tl_set:Nn \l__exsheets_points_name_plural_tl { #1 } + \tl_set:Nn \l__exsheets_bonus_name_plural_tl { #1 } , + bonus-name .code:n = \exsheets_set_bonus_name:n { #1 } , + bonus-plural .tl_set:N = \l__exsheets_bonus_name_plural_tl , + pre-bonus .tl_set:N = \l__exsheets_points_pre_bonus_marker_tl , + post-bonus .tl_set:N = \l__exsheets_points_post_bonus_marker_tl , + use-name .bool_set:N = \l__exsheets_points_name_bool , + number-format .tl_set:N = \l__exsheets_points_number_format_tl , + bonus-format .tl_set:N = \l__exsheets_bonus_number_format_tl , + parse .bool_set:N = \l__exsheets_parse_points_bool , + separate-bonus .bool_set:N = \l__exsheets_points_separate_bonus_bool + } + +% ---------------------------------------------------------------------------- +% Noten-Verteilung +\prop_new:N \l__exsheets_relgrades_prop +\fp_new:N \l__exsheets_grade_round_fp +\fp_zero:N \l__exsheets_grade_round_fp +\bool_new:N \l__exsheets_grades_half_bool + +\cs_new:Npn \__exsheets_fp_round_to_half:n #1 + { round( 2*(#1),0)/2 } + +\cs_new:Npn \__exsheets_grades_round:n #1 + { round ( #1 , \l__exsheets_grade_round_fp ) } + +\cs_new:Npn \__exsheets_grade_rounded: + { + \bool_if:NTF { \l__exsheets_grades_half_bool } + { \__exsheets_fp_round_to_half:n } + { \__exsheets_grades_round:n } + { \g__exsheets_total_points_fp * \l__exsheets_tmpa_fp } + } + +\cs_new:Npn \exsheets_strip_braces:N #1 + { \exp_after:wN \__exsheets_strip_braces:w \exp_after:wN #1#1 \q_stop } +\cs_new:Npn \__exsheets_strip_braces:w #1#2 \q_stop + { \tl_set:Nn #1 { #2 } } + +\cs_new:Npn \__exsheets_declare_relgrades:n #1 + { + \clist_set:Nn \l__exsheets_tmpa_clist { #1 } + \clist_map_inline:Nn \l__exsheets_tmpa_clist + { \__exsheets_declare_relgrade:w ##1 \q_stop } + } + +\cs_new:Npn \__exsheets_declare_relgrade:w #1 = #2 \q_stop + { + \tl_set:Nn \l__exsheets_tmpa_tl { #1 } + \tl_set:Nn \l__exsheets_tmpb_tl { #2 } + \tl_trim_spaces:N \l__exsheets_tmpa_tl + \exsheets_strip_braces:N \l__exsheets_tmpa_tl + \tl_trim_spaces:N \l__exsheets_tmpb_tl + \exsheets_strip_braces:N \l__exsheets_tmpb_tl + \prop_put:NVV \l__exsheets_relgrades_prop + \l__exsheets_tmpa_tl + \l__exsheets_tmpb_tl + } + +\NewDocumentCommand \DeclareRelGrades { m } + { \__exsheets_declare_relgrades:n { #1 } } +\@onlypreamble\DeclareRelGrades + +\cs_new:Npn \__exsheets_grade:nn #1#2 + { + \prop_get:NnNTF \l__exsheets_relgrades_prop { #2 } \l__exsheets_tmpa_fp + { + \bool_if:NTF \l__exsheets_parse_points_bool + { + \exsheets_parse_points:n + { min( \__exsheets_grade_rounded: , \g__exsheets_total_points_fp ) } + \int_compare:nT { #1 = 1 } + { + \exsheets_points_name:n + { min( \__exsheets_grade_rounded: , \g__exsheets_total_points_fp ) } + } + } + { \msg_warning:nnn { exsheets } { grade-parse } { #1 } \textbf{??} } + } + { \msg_warning:nnn { exsheets } { grade-missing } { #1 } \textbf{??} } + } + +\NewDocumentCommand \grade { sm } + { + \IfBooleanTF { #1 } + { \__exsheets_grade:nn { 0 } { #2 } } + { \__exsheets_grade:nn { 1 } { #2 } } + } + +\keys_define:nn { exsheets / grades } + { + round .fp_set:N = \l__exsheets_grade_round_fp , + half .bool_set:N = \l__exsheets_grades_half_bool + } + +% ---------------------------------------------------------------------------- +% Aufgaben und Lösungen + +% Einteilung in Klassen und Themen +\prop_new:N \g__exsheets_questions_class_prop +\prop_new:N \g__exsheets_classes_prop +\prop_new:N \g__exsheets_classes_active_prop +\prop_new:N \g__exsheets_questions_topic_prop +\prop_new:N \g__exsheets_topics_prop +\prop_new:N \g__exsheets_topics_active_prop + +\bool_new:N \g__exsheets_questions_use_bool +\bool_gset_true:N \g__exsheets_questions_use_bool +\bool_new:N \l__exsheets_questions_use_bool +\bool_set_true:N \l__exsheets_questions_use_bool +\bool_new:N \l__exsheets_questions_deactivate_bool +\bool_new:N \l__exsheets_questions_class_bool +\bool_set_false:N \l__exsheets_questions_class_bool +\bool_new:N \g__exsheets_use_classes_bool +\bool_gset_false:N \g__exsheets_use_classes_bool +\bool_new:N \l__exsheets_class_active_bool +\bool_new:N \l__exsheets_questions_topic_bool +\bool_set_false:N \l__exsheets_questions_topic_bool +\bool_new:N \g__exsheets_use_topics_bool +\bool_gset_false:N \g__exsheets_use_topics_bool +\bool_new:N \l__exsheets_topic_active_bool +\bool_new:N \l__exsheets_solutions_use_bool +\bool_set_true:N \l__exsheets_solutions_use_bool + +\tl_new:N \l__exsheets_questions_class_tl +\tl_new:N \l__exsheets_questions_topic_tl + +\dim_new:N \l__exsheets_questions_skip_below_dim +\dim_set:Nn \l__exsheets_questions_skip_below_dim { .5\baselineskip } +\dim_new:N \l__exsheets_solutions_skip_below_dim +\dim_set:Nn \l__exsheets_solutions_skip_below_dim { .5\baselineskip } + +\cs_new_nopar:Npn \exsheets_glue:N #1 + { \cleaders \vbox:n {} \skip_vertical:N #1 } + +\keys_define:nn { exsheets } + { + use-classes .code:n = + { + \bool_gset_true:N \g__exsheets_use_classes_bool + \__exsheets_activate_classes:n { #1 } + } , + use-topics .code:n = + { + \bool_gset_true:N \g__exsheets_use_topics_bool + \__exsheets_activate_topics:n { #1 } + } , + skip-below .code:n = + \dim_set:Nn \l__exsheets_questions_skip_below_dim { #1 } + \dim_set:Nn \l__exsheets_solutions_skip_below_dim { #1 } + } + +\cs_new:Npn \__exsheets_activate_classes:n #1 + { + \prop_gclear:N \g__exsheets_classes_active_prop + \seq_set_split:Nnn \l__exsheets_tmpa_seq { , } { #1 } + \seq_map_inline:Nn \l__exsheets_tmpa_seq + { + \prop_gput:Nnn \g__exsheets_classes_active_prop + { ##1 } { \__exsheets_dummy: } + } + } + +\cs_new:Npn \__exsheets_activate_topics:n #1 + { + \prop_gclear:N \g__exsheets_topics_active_prop + \seq_set_split:Nnn \l__exsheets_tmpa_seq { , } { #1 } + \seq_map_inline:Nn \l__exsheets_tmpa_seq + { + \prop_gput:Nnn \g__exsheets_topics_active_prop + { ##1 } { \__exsheets_dummy: } + } + } + +\cs_new_nopar:Npn \__exsheets_questions_use_classes: + { + % is there a class provided? + \bool_if:NT \l__exsheets_questions_class_bool + { + % add class to questions property + \prop_gput:Nff \g__exsheets_questions_class_prop + { \int_to_arabic:n { \g__exsheets_questions_id_int } } + { \l__exsheets_questions_class_tl } + % add to classes list, if it's a new one + \prop_get:NoN \g__exsheets_classes_prop + { \l__exsheets_questions_class_tl } + \l__exsheets_tmpa_tl + \tl_if_eq:NNT \l__exsheets_tmpa_tl \q_no_value + { + \prop_gput:Nfn \g__exsheets_classes_prop + { \l__exsheets_questions_class_tl } + { \__exsheets_dummy: } + } + } + % are we using classes? + \bool_if:NT \g__exsheets_use_classes_bool + { + % is this question an active one? + \prop_get:NoN \g__exsheets_classes_active_prop + { \l__exsheets_questions_class_tl } + \l__exsheets_tmpa_tl + \tl_if_eq:NNTF \l__exsheets_tmpa_tl \q_no_value + { + \bool_set_false:N \l__exsheets_class_active_bool + \bool_set_false:N \l__exsheets_questions_print_bool + } + { \bool_set_true:N \l__exsheets_class_active_bool } + } + } + +\cs_new_nopar:Npn \__exsheets_questions_use_topics: + { + % is there a topic provided? + \bool_if:NT \l__exsheets_questions_topic_bool + { + % add topic to questions property + \prop_gput:Nff \g__exsheets_questions_topic_prop + { \int_to_arabic:n { \g__exsheets_questions_id_int } } + { \l__exsheets_questions_topic_tl } + % add to topics list, if it's a new one + \prop_get:NoN \g__exsheets_topics_prop + { \l__exsheets_questions_topic_tl } + \l__exsheets_tmpa_tl + \tl_if_eq:NNT \l__exsheets_tmpa_tl \q_no_value + { + \prop_gput:Nfn \g__exsheets_topics_prop + { \l__exsheets_questions_topic_tl } + { \__exsheets_dummy: } + } + } + % are we using topics? + \bool_if:NT \g__exsheets_use_topics_bool + { + % is this question an active one? + \prop_get:NoN \g__exsheets_topics_active_prop + { \l__exsheets_questions_topic_tl } + \l__exsheets_tmpa_tl + \tl_if_eq:NNTF \l__exsheets_tmpa_tl \q_no_value + { + \bool_set_false:N \l__exsheets_topic_active_bool + \bool_set_false:N \l__exsheets_questions_print_bool + } + { \bool_set_true:N \l__exsheets_topic_active_bool } + } + \int_set:Nn \l__exsheets_counter_qu_int { \arabic{question} } + } + +\cs_new_nopar:Npn \__exsheets_solutions_use_classes: + { + % are we using classes? + \bool_if:NT \g__exsheets_use_classes_bool + { + % is the question to this solution an active one? + % get question number from ID + \prop_get:NoN \g__exsheets_questions_id_prop + { \g__exsheets_questions_current_id_tl } \l__exsheets_tmpa_tl + % get question class from number + \prop_get:NoN \g__exsheets_questions_class_prop + { \l__exsheets_tmpa_tl } \l__exsheets_tmpb_tl + % test if class is active + \prop_get:NoN \g__exsheets_classes_active_prop + { \l__exsheets_tmpb_tl } \l__exsheets_tmpc_tl + \tl_if_eq:NNTF \l__exsheets_tmpc_tl \q_no_value + { \bool_set_false:N \l__exsheets_solutions_use_bool } + { \bool_set_true:N \l__exsheets_solutions_use_bool } + } + } + +\cs_new_nopar:Npn \__exsheets_solutions_use_topics: + { + % are we using topics? + \bool_if:NTF \g__exsheets_use_topics_bool + { + % is the question to this solution an active one? + % get question number from ID + \prop_get:NoN \g__exsheets_questions_id_prop + { \g__exsheets_questions_current_id_tl } \l__exsheets_tmpa_tl + % get question topic from number + \prop_get:NoN \g__exsheets_questions_topic_prop + { \l__exsheets_tmpa_tl } \l__exsheets_tmpb_tl + % test if topic is active + \prop_get:NoN \g__exsheets_topics_active_prop + { \l__exsheets_tmpb_tl } \l__exsheets_tmpc_tl + \tl_if_eq:NNT \l__exsheets_tmpc_tl \q_no_value + { \bool_set_false:N \l__exsheets_solutions_use_bool } + } + { + \bool_if:NF \g__exsheets_use_classes_bool + { \bool_set_true:N \l__exsheets_solutions_use_bool } + } + } + +% ---------------------------------------------------------------------------- +% die 'question' Umgebung +\tl_new:N \l__exsheets_questions_name_tl +\tl_set:Nn \l__exsheets_questions_name_tl { Question } +\tl_new:N \l__exsheets_exsheets_name_tl +\tl_set:Nn \l__exsheets_exsheets_name_tl { Exercise } + +\bool_new:N \l__exsheets_questions_print_bool +\bool_set_true:N \l__exsheets_questions_print_bool +\bool_new:N \l__exsheets_inside_question_bool + +\int_new:N \g__exsheets_questions_id_int +\int_gzero:N \g__exsheets_questions_id_int + +\NewEnviron { __exsheets_questions_internal: } + { + \cspreto { BODY } { \ifhmode \vspace*{0pt} \fi } + \csappto { BODY } + { + \par + \dim_compare:nNnT { \parskip } = { 0pt } + { \exsheets_glue:N \l__exsheets_questions_skip_below_dim } + } + \bool_if:nT + { + \l__exsheets_questions_print_bool && + \g__exsheets_questions_use_bool && + !\l__exsheets_questions_deactivate_bool + } + { + \__exsheets_save_number_in:N \g__exsheets_question_number_prop + \BODY + } + } + +\prop_new:N \g__exsheets_questions_id_prop + +\tl_new:N \l__exsheets_questions_id_tl +\tl_new:N \g__exsheets_questions_current_id_tl +\tl_new:N \l__exsheets_title_tl + +\bool_new:N \l__exsheets_points_not_given_bool + +\cs_new:Npn \__exsheets_read_points:w #1+#2+#3 \q_stop + { + \tl_if_blank:nTF { #1 } + { \fp_zero:N \l__exsheets_question_points_fp } + { \fp_set:Nn \l__exsheets_question_points_fp { #1 } } + \tl_if_blank:nTF { #2 } + { \fp_zero:N \l__exsheets_question_bonus_fp } + { + \tl_if_blank:nTF { #3 } + { \fp_zero:N \l__exsheets_question_bonus_fp } + { \fp_set:Nn \l__exsheets_question_bonus_fp { #2 } } + } + } +\cs_new:Npn \__exsheets_read_points:n #1 + { \__exsheets_read_points:w #1++ \q_stop } + +\NewDocumentEnvironment { question } { og } + { + \bool_set_true:N \l__exsheets_inside_question_bool + \bool_if:NT \l__exsheets_questions_use_bool + { \bool_gset_true:N \g__exsheets_questions_use_bool } + % Optionen: + \IfNoValueF { #1 } { \keys_set:nn { exsheets / question } { #1 } } + % Punktevergabe: + \IfNoValueTF { #2 } + { + \__exsheets_read_points:n { 0 } + \bool_if:NT \l__exsheets_points_questions_default_bool + { + \fp_set_eq:NN + \l__exsheets_question_points_fp + \l__exsheets_points_default_fp + } + } + { \__exsheets_read_points:n { #2 } } + % ID: + \int_gincr:N \g__exsheets_questions_id_int + \tl_if_blank:VTF \l__exsheets_questions_id_tl + { + \prop_gput:NVV \g__exsheets_questions_id_prop + \g__exsheets_questions_id_int + \g__exsheets_questions_id_int + \tl_gset:Nx \g__exsheets_questions_current_id_tl + { \int_use:N \g__exsheets_questions_id_int } + } + { + \prop_gput:NVV \g__exsheets_questions_id_prop + \l__exsheets_questions_id_tl + \g__exsheets_questions_id_int + \tl_gset:Nx \g__exsheets_questions_current_id_tl + { \tl_use:N \l__exsheets_questions_id_tl } + } + % Auswahl der Frage: + \__exsheets_select_question:V \g__exsheets_questions_current_id_tl + \bool_if:nT + { + \g__exsheets_questions_use_bool && + !\l__exsheets_questions_deactivate_bool + } + { + \__exsheets_questions_use_classes: + \__exsheets_questions_use_topics: + \bool_if:nT + { + ( \l__exsheets_class_active_bool && \l__exsheets_topic_active_bool ) || + ( \l__exsheets_class_active_bool && !\g__exsheets_use_topics_bool ) || + ( !\g__exsheets_use_classes_bool && \l__exsheets_topic_active_bool ) || + ( !\g__exsheets_use_classes_bool && !\g__exsheets_use_topics_bool ) + } + { \refstepcounter{question} } + \cs_if_exist:NT \chapter + { \int_set:Nn \l__exsheets_counter_ch_int { \arabic{chapter} } } + \int_set:Nn \l__exsheets_counter_sec_int { \arabic{section} } + \int_set:Nn \l__exsheets_counter_qu_int { \arabic{question} } + \bool_if:nT + { + ( + \l__exsheets_points_questions_default_bool && + \l__exsheets_parse_points_bool + ) || + ( + \l__exsheets_parse_points_bool && + \l__exsheets_questions_print_bool + ) + } + { + \exsheets_add_points:V \l__exsheets_question_points_fp + \exsheets_add_bonus:V \l__exsheets_question_bonus_fp + } + \bool_if:NT \l__exsheets_questions_print_bool + { + \bool_if:NTF \l__exsheets_exam_bool + { \tl_set_eq:NN \l__exsheets_title_tl \l__exsheets_questions_name_tl } + { \tl_set_eq:NN \l__exsheets_title_tl \l__exsheets_exsheets_name_tl } + \__exsheets_use_heading:VVVnn + \l__exsheets_heading_instance_tl + \l__exsheets_title_tl + \l__exsheets_qu_counter_interpretation_tl + { \l__exsheets_question_points_fp } + { \l__exsheets_question_bonus_fp } + } + } + \__exsheets_questions_internal: + } + { \end__exsheets_questions_internal: } + +% current question number: +\prop_new:N \g__exsheets_question_number_prop + +\cs_new_protected:Npn \exsheets@save@number #1#2 + { \expandafter\global\expandafter\edef\csname exsheets@question@#1\endcsname{#2} } + +\cs_new:Npn \__exsheets_save_number_in:N #1 + { + \bool_if:NTF \l__exsheets_print_number_bool + { + \cs_if_exist:NTF \thechapter + { + \prop_gput:Nfx #1 + { \int_use:N \g__exsheets_questions_id_int } + { \arabic{chapter}-\arabic{section}-\arabic{question} } + \iow_now:Nx \@auxout + { + \exsheets@save@number + { \g__exsheets_questions_current_id_tl } + { \arabic{chapter}-\arabic{section}-\arabic{question} } + } + } + { + \prop_gput:Nfx #1 + { \int_use:N \g__exsheets_questions_id_int } + { -\arabic{section}-\arabic{question} } + \iow_now:Nx \@auxout + { + \exsheets@save@number + { \g__exsheets_questions_current_id_tl } + { -\arabic{section}-\arabic{question} } + } + } + } + { + \cs_if_exist:NTF \thechapter + { + \prop_gput:Nfx #1 + { \int_use:N \g__exsheets_questions_id_int } + { @@@\arabic{chapter}-\arabic{section}-\arabic{question} } + \iow_now:Nx \@auxout + { + \exsheets@save@number + { \g__exsheets_questions_current_id_tl } + { @@@\arabic{chapter}-\arabic{section}-\arabic{question} } + } + } + { + \prop_gput:Nfx #1 + { \int_use:N \g__exsheets_questions_id_int } + { @@@-\arabic{section}-\arabic{question} } + \iow_now:Nx \@auxout + { + \exsheets@save@number + { \g__exsheets_questions_current_id_tl } + { @@@-\arabic{section}-\arabic{question} } + } + } + } + } + +\cs_new:Npn \__exsheets_restore_number_from_and_do:Nnn #1#2#3 + { + \prop_get:NnN #1 { #2 } \l__exsheets_tmpc_tl + \tl_if_eq:NNF \l__exsheets_tmpc_tl \q_no_value + { + \exp_after:wN + \__exsheets_read_number:w \l__exsheets_tmpc_tl \q_stop + #3 + } + % use \exsheets_read_counter_settings:V \l__exsheets_qu_counter_format_tl + % afterwards to print the number + } +\cs_generate_variant:Nn \__exsheets_restore_number_from_and_do:Nnn { NV } + +\NewDocumentCommand \QuestionNumber { m } + { \exsheets_question_number:c { exsheets@question@#1 } } + +\cs_new:Npn \exsheets_question_number:N #1 + { + \cs_if_exist:NTF #1 + { + \exp_after:wN \__exsheets_get_question_number:w #1 \q_stop + \ReadCounterPatternFrom [ exsheets ] \l__exsheets_qu_counter_pattern_tl + } + { \textbf{??} } + } +\cs_generate_variant:Nn \exsheets_question_number:N { c } + +\cs_new:Npn \__exsheets_get_question_number:w #1-#2-#3 \q_stop + { + \cs_if_exist:NT \thechapter + { \int_set:Nn \l__exsheets_counter_ch_int { #1 } } + \int_set:Nn \l__exsheets_counter_sec_int { #2 } + \int_set:Nn \l__exsheets_counter_qu_int { #3 } + } + +% ---------------------------------------------------------------------------- +% title of a question: +\input { exsheets_headings.def } +\bool_if:NT \l__exsheets_load_headings_bool + { + \RequirePackage { amssymb } + \input { exsheets_headings.cfg } + } +% #1: instance +% #2: title +% #3: number +% #4: points +% #5: bonus +\cs_new_nopar:Npn \__exsheets_use_heading:nnnnn #1#2#3#4#5 + { + \IfInstanceExistTF { exsheets-heading } { #1 } + { \UseInstance { exsheets-heading } { #1 } } + { + \msg_warning:nnx { exsheets} { headings } { #1 } + \UseInstance { exsheets-heading } { block } + } + { #2 } { #3 } { #4 } { #5 } + } +\cs_generate_variant:Nn \__exsheets_use_heading:nnnnn { V , VV , VVV } + +\bool_new:N \l__exsheets_exam_bool +\bool_set_false:N \l__exsheets_exam_bool +\bool_new:N \l__exsheets_questions_runin_bool +\bool_set_false:N \l__exsheets_questions_runin_bool + +% options for the questions: +\keys_define:nn { exsheets / question } + { + type .choice: , + type / exam .code:n = + \bool_set_true:N \l__exsheets_exam_bool , + type / exercise .code:n = + \bool_set_false:N \l__exsheets_exam_bool , + name .code:n = + \tl_set:Nn \l__exsheets_exsheets_name_tl { #1 } + \tl_set:Nn \l__exsheets_questions_name_tl { #1 } , + print .bool_set:N = \l__exsheets_questions_print_bool , + print .default:n = true , + ID .tl_set:N = \l__exsheets_questions_id_tl , + class .code:n = + \bool_set_true:N \l__exsheets_questions_class_bool + \tl_set:Nn \l__exsheets_questions_class_tl { #1 } , + topic .code:n = + \bool_set_true:N \l__exsheets_questions_topic_bool + \tl_set:Nn \l__exsheets_questions_topic_tl { #1 } , + use .choice: , + use / true .code:n = + \bool_gset_true:N \g__exsheets_questions_use_bool + \bool_set_true:N \l__exsheets_questions_use_bool , + use / false .code:n = + \bool_gset_false:N \g__exsheets_questions_use_bool + \bool_set_false:N \l__exsheets_questions_use_bool , + use .default:n = true , + skip-below .dim_set:N = \l__exsheets_questions_skip_below_dim + } + +% ---------------------------------------------------------------------------- +% using ``metadata'': +\cs_new:Npn \__exsheets_declare_question_property:n #1 + { + \prop_new:c { g__exsheets_question_property_#1_prop } + \keys_define:nn { question / meta } + { #1 .code:n = \__exsheets_question_set_property:nn { #1 } { ##1 } } + } + +\cs_new_eq:NN \exsheets_declare_question_property:n + \__exsheets_declare_question_property:n + +\NewDocumentCommand \DeclareQuestionProperty { m } + { \exsheets_declare_question_property:n { #1 } } +\@onlypreamble\DeclareQuestionProperty + +\NewDocumentCommand \SetQuestionProperties { m } + { \exsheets_set_question_properties:n { #1 } } + +\cs_new:Npn \__exsheets_set_question_properties:n #1 + { + \@bsphack + \bool_if:NTF \l__exsheets_inside_question_bool + { \keys_set:nn { question / meta } { #1 } } + { + \msg_error:nnn { exsheets } { only-inside-question } + { \SetQuestionProperties } + } + \@esphack + } + +\cs_new_eq:NN \exsheets_set_question_properties:n + \__exsheets_set_question_properties:n + +\cs_new:Npn \__exsheets_question_set_property:nn #1#2 + { + \prop_gput:cVn { g__exsheets_question_property_#1_prop } + \g__exsheets_questions_current_id_tl { #2 } + } + +\NewDocumentCommand \GetQuestionProperty { mm } + { \exsheets_get_question_property:nn { #1 } { #2 } } + +\cs_new:Npn \exsheets_get_question_property:nn #1#2 + { + \prop_if_in:cnT { g__exsheets_question_property_#1_prop } { #2 } + { \prop_get:cn { g__exsheets_question_property_#1_prop } { #2 } } + } + +% ---------------------------------------------------------------------------- +% debug-Info: +\bool_new:N \l__exsheets_questions_debug_bool +\bool_set_false:N \l__exsheets_questions_debug_bool + +\colorlet { exsheetsdebugcolor } { yellow } + +\cs_new_nopar:Npn \exsheets_questions_debug: + { + \bool_if:nT { \l__exsheets_questions_debug_bool && \l__exsheets_inside_question_bool } + { + \colorbox { exsheetsdebugcolor } + { + \group_begin: + \normalfont\normalsize\normalcolor + ID:~ + \tl_if_blank:VTF \l__exsheets_questions_id_tl + { \int_use:N \g__exsheets_questions_id_int } + { \tl_use:N \l__exsheets_questions_id_tl } + \bool_if:NT \l__exsheets_questions_class_bool + { ,~CLASS:~ \tl_use:N \l__exsheets_questions_class_tl } + \bool_if:NT \l__exsheets_questions_topic_bool + { ,~TOPIC:~ \tl_use:N \l__exsheets_questions_topic_tl } + \group_end: + } + } + } + +\NewDocumentCommand \DebugExSheets { G{true} } + { \use:c { bool_set_#1:N } \l__exsheets_questions_debug_bool } + +% ---------------------------------------------------------------------------- +% include random/selected questions from a file: +\bool_new:N \l__exsheets_select_questions_bool +\bool_new:N \l__exsheets_include_all_bool +\bool_new:N \l__exsheets_include_random_bool +\bool_set_true:N \l__exsheets_include_all_bool +\prop_new:N \g__exsheets_selected_questions_prop +\clist_new:N \l__exsheets_include_id_clist +\int_new:N \l__exsheets_include_random_int +\int_zero:N \l__exsheets_include_random_int +\tl_new:N \l__exsheets_random_seed_tl +\tl_set:Nn \l__exsheets_random_seed_tl { -1 } +\newcounter {exsheets@include@random} + +\cs_new:Npn \file_input_if_exist:n #1 + { \file_if_exist:nT { #1 } { \file_input:n { #1 } } } + +\cs_if_exist:NF \prop_length:N + { + \cs_new:Npn \prop_length:N #1 + { + \prop_length:NN #1 \l__exsheets_tmpa_int + \int_use:N \l__exsheets_tmpa_int + } + } + +\cs_new:Npn \prop_length:NN #1#2 + { + \int_zero:N #2 + \prop_map_inline:Nn #1 + { \int_incr:N #2 } + } + +\NewDocumentCommand \includequestions { om } + { + \group_begin: + \IfNoValueF { #1 } + { \keys_set:nn { exsheets / include } { #1 } } + \exsheets_include_questions:n { #2 } + \group_end: + } + +\cs_new:Npn \exsheets_include_questions:n #1 + { + \seq_set_split:Nnn \l__exsheets_tmpa_seq { , } { #1 } + \seq_map_inline:Nn \l__exsheets_tmpa_seq + { + \bool_set_true:N \l__exsheets_questions_deactivate_bool + \file_input_if_exist:n { ##1 } + \bool_if:NT \l__exsheets_questions_debug_bool + { + \colorbox { exsheetsdebugcolor } + { + The~file~ ` \texttt { \tl_to_str:n { ##1 } } ' ~contains~ + \prop_length:N \g__exsheets_selected_questions_prop \c_space_tl + questions. + } + \par + } + \bool_set_false:N \l__exsheets_questions_deactivate_bool + \__exsheets_select_question_random:n { ##1 } + \file_input_if_exist:n { ##1 } + \prop_gclear:N \g__exsheets_selected_questions_prop + \clist_clear:N \l__exsheets_include_id_clist + } + } + +% options: +% - IDs=<list of IDs> +% - all=true|false % default when no option is given +% - random=<num> +% - seed=<num> % set the seed for the random selection +\keys_define:nn { exsheets / include } + { + all .bool_set:N = \l__exsheets_include_all_bool , + IDs .code:n = + \bool_set_false:N \l__exsheets_include_all_bool + \bool_set_false:N \l__exsheets_include_random_bool + \clist_set:Nn \l__exsheets_include_id_clist { #1 } , + random .code:n = + \bool_set_false:N \l__exsheets_include_all_bool + \bool_set_true:N \l__exsheets_include_random_bool + \int_set:Nn \l__exsheets_include_random_int { #1 } , + seed .tl_set:N = \l__exsheets_random_seed_tl + } + +\cs_new:Npn \__exsheets_select_question:n #1 + { + \bool_if:NTF \l__exsheets_questions_deactivate_bool + { + \prop_gput:Nnn \g__exsheets_selected_questions_prop + { #1 } { \__exsheets_dummy: } + } + { + \bool_if:NF \l__exsheets_include_all_bool + { \__exsheets_select_question_by_id:n { #1 } } + } + } +\cs_generate_variant:Nn \__exsheets_select_question:n { V } + +\cs_new:Npn \__exsheets_select_question_by_id:n #1 + { +% \clist_show:N \l__exsheets_include_id_clist + \clist_if_in:NnTF + \l__exsheets_include_id_clist + { #1 } + { \bool_gset_true:N \g__exsheets_questions_use_bool } + { \bool_gset_false:N \g__exsheets_questions_use_bool } + } + +\cs_new:Npn \__exsheets_select_question_random:n #1 + { + \bool_if:NT \l__exsheets_include_random_bool + { + \prop_length:NN \g__exsheets_selected_questions_prop \l__exsheets_tmpa_int + \int_compare:nTF { \l__exsheets_include_random_int > \l__exsheets_tmpa_int } + { + \msg_warning:nnxxx { exsheets } { random } + { \int_use:N \l__exsheets_include_random_int } + { #1 } + { \int_use:N \l__exsheets_tmpa_int } + \bool_set_true:N \l__exsheets_include_all_bool + } + { + \group_begin: + \WarningsOff[lcg] + \tl_set:Nx \l__exsheets_tmpa_tl { \int_use:N \l__exsheets_tmpa_int } + \reinitrand + [ + first = 1 , + last = \l__exsheets_tmpa_tl , + counter = exsheets@include@random , + seed = \l__exsheets_random_seed_tl , + quiet = y + ] + \int_zero:N \l__exsheets_tmpa_int + \int_do_while:nNnn \l__exsheets_tmpa_int < \l__exsheets_include_random_int + { + \rand + \int_zero:N \l__exsheets_tmpb_int + \prop_map_inline:Nn \g__exsheets_selected_questions_prop + { + \int_incr:N \l__exsheets_tmpb_int + \int_compare:nT + { \l__exsheets_tmpb_int = \value{exsheets@include@random} } + { + \tl_set_rescan:Nnn \l__exsheets_tmpa_tl {} { ##1 } + \clist_if_in:NVTF \l__exsheets_include_id_clist \l__exsheets_tmpa_tl + { \int_decr:N \l__exsheets_tmpb_int } + { + \clist_gput_right:NV \l__exsheets_include_id_clist + \l__exsheets_tmpa_tl + \prop_map_break: + } + } + } + \clist_remove_duplicates:N \l__exsheets_include_id_clist + \int_set:Nn \l__exsheets_tmpa_int + { \clist_count:N \l__exsheets_include_id_clist } + } + \WarningsOn[lcg] + \group_end: + } + } + } + +\NewDocumentCommand \PrintIfIncludeActiveTF { mm } + { \bool_if:NTF \l__exsheets_questions_deactivate_bool { #2 } { #1 } } + +\NewDocumentCommand \PrintIfIncludeActiveT { } + { \bool_if:NF \l__exsheets_questions_deactivate_bool } + +\NewDocumentCommand \PrintIfIncludeActiveF { } + { \bool_if:NT \l__exsheets_questions_deactivate_bool } + +% ---------------------------------------------------------------------------- +% die 'solution' Umgebung: +\bool_new:N \l__exsheets_solutions_print_bool +\bool_set_false:N \l__exsheets_solutions_print_bool +\bool_new:N \l__exsheets_solutions_print_here_bool +\bool_set_false:N \l__exsheets_solutions_print_here_bool +\bool_new:N \l__exsheets_solutions_print_section_bool +\bool_set_false:N \l__exsheets_solutions_print_section_bool +\bool_new:N \l__exsheets_solutions_print_chapter_bool +\bool_set_false:N \l__exsheets_solutions_print_chapter_bool +\bool_new:N \l__exsheets_solutions_print_all_bool +\bool_set_false:N \l__exsheets_solutions_print_all_bool + +% \prop_new:N \g__exsheets_question_number_prop +\prop_new:N \g__exsheets_solutions_content_prop +\prop_new:N \g__exsheets_solutions_questions_id_prop +\prop_new:N \g__exsheets_solutions_names_prop + +\tl_new:N \l__exsheets_solutions_name_tl +\tl_set:Nn \l__exsheets_solutions_name_tl { Solution } + +\cs_new:Npn \__exsheets_save_solution:n #1 + { + % save for later use + \prop_gput:Nff \g__exsheets_solutions_content_prop + { \int_use:N \g__exsheets_questions_id_int } + { #1 } + \prop_gput:Nff \g__exsheets_solutions_questions_id_prop + { \int_use:N \g__exsheets_questions_id_int } + { \tl_use:N \g__exsheets_questions_current_id_tl } + \prop_gput:Nff \g__exsheets_solutions_names_prop + { \int_use:N \g__exsheets_questions_id_int } + { \tl_use:N \l__exsheets_solutions_name_tl } + % print here + \bool_if:NT \l__exsheets_solutions_print_here_bool + { + \int_set:Nn \l__exsheets_counter_qu_int { \arabic{question} } + \__exsheets_solutions_name:VV + \l__exsheets_qu_counter_interpretation_tl + \l__exsheets_solutions_name_tl + \use:n { #1 } \par + \dim_compare:nNnT { \parskip } = { 0pt } + { \exsheets_glue:N \l__exsheets_solutions_skip_below_dim } + } + } +\cs_generate_variant:Nn \prop_gput:Nnn { Nff,Nfx,Nfn,Nxx } +\cs_generate_variant:Nn \__exsheets_save_solution:n { V } + +\NewEnviron { __exsheets_solution_int: } + { + \bool_if:nT { \g__exsheets_questions_use_bool && \l__exsheets_solutions_use_bool } + { + \cspreto { BODY } { \ifhmode \fi }% what's that good for? + \__exsheets_save_solution:V \BODY + } + } + +\bool_new:N \l__exsheets_inside_solution_bool +\bool_set_false:N \l__exsheets_inside_solution_bool + +\NewDocumentEnvironment { solution } { o } + { + \__exsheets_solutions_use_classes: + \__exsheets_solutions_use_topics: + \bool_if:NT \l__exsheets_questions_deactivate_bool + { \bool_set_false:N \l__exsheets_solutions_use_bool } + \bool_if:NT \l__exsheets_solutions_use_bool + { + \bool_set_true:N \l__exsheets_inside_solution_bool + \IfNoValueF { #1 } { \keys_set:nn { exsheets / solution } { #1 } } + } + \__exsheets_solution_int: + } + { \end__exsheets_solution_int: } + +\bool_new:N \l__exsheets_solutions_runin_bool +\bool_set_false:N \l__exsheets_solutions_runin_bool + +\cs_new_nopar:Npn \__exsheets_solutions_name:nn #1#2 + { + \__exsheets_use_heading:Vnnnn + \l__exsheets_heading_instance_tl + { #2 } { #1 } { 0 } { 0 } + } +\cs_generate_variant:Nn \__exsheets_solutions_name:nn { VV } + +\tl_new:N \l__exsheets_solutions_name_style_tl +\tl_set:Nn \l__exsheets_solutions_name_style_tl { \normalsize \bfseries } + +\cs_new:Npn \exsheets_solutions_name_style:n #1 + { \l__exsheets_solutions_name_style_tl #1 } + +% ---------------------------------------------------------------------------- +% print solutions: +% save section / chapter counter: +\cs_new:Npn \__exsheets_exlabel:n #1 + { + \@bsphack + \iow_now:Nx \@auxout + { + \token_to_str:N \newlabel { exse:#1 } + { { \arabic { section } } { \thepage } } + } + \cs_if_exist:NT \thechapter + { + \iow_now:Nx \@auxout + { + \token_to_str:N \newlabel { exch:#1 } + { { \arabic { chapter } } { \thepage } } + } + } + \@esphack + } + +% user command: +\cs_new_eq:NN \exlabel \__exsheets_exlabel:n + +% adapt \label, maybe do this _after_ BeginDocument: +\bool_if:NT \l__exsheets_solutions_by_ref_bool + { + \cs_new_eq:NN \__exsheets_saved_label:n \label + \cs_set:Npn \label #1 + { \__exsheets_saved_label:n { #1 } \__exsheets_exlabel:n { #1 } } + } + +% this is like \ref from latex.ltx +\cs_new:Npn \__exsheets_ref:n #1 + { + \cs_if_exist:cTF { r@#1 } + { \__exsheets_ref_aux:n { #1 } } + { + \protect\G@refundefinedtrue + 1 + \@latex@warning{exlabel `#1' on page \thepage \space undefined}% + } + } + +\cs_new:Npn \__exsheets_ref_aux:n #1 + { \exp_after:wN \exp_after:wN \exp_after:wN \use_i:nn \cs:w r@#1 \cs_end: } + +\cs_new_eq:NN \exref \__exsheets_ref:n + +% user command: +\NewDocumentCommand \printsolutions { O{all} } + { \exsheets_print_solutions:n { #1 } } + +% internal command: +\cs_new:Npn \exsheets_print_solutions:n #1 + { + \group_begin: + \bool_set_true:N \l__exsheets_solutions_print_bool + \bool_set_true:N \l__exsheets_inside_solution_bool + \cs_set:Npn \S ##1 { \exref { exse:##1 } } + \cs_set:Npn \C ##1 { \exref { exch:##1 } } + \keys_set:nn { exsheets / exsheets_print_solutions } { #1 } + \group_end: + } + +\keys_define:nn { exsheets } + { + exsheets_print_solutions .choice: , + exsheets_print_solutions / section .code:n = + { \exsheets_print_solutions_section:n { #1 } } , + exsheets_print_solutions / chapter .code:n = + { \exsheets_print_solutions_chapter:n { #1 } } , + exsheets_print_solutions / all .code:n = + { \exsheets_print_solutions_all: } , + exsheets_print_solutions / byID .code:n = + { \exsheets_print_solutions_byID:n { #1 } } + } + +\int_new:N \l__exsheets_counter_ch_int +\int_new:N \l__exsheets_counter_sec_int +\int_new:N \l__exsheets_counter_qu_int + +\cs_new:Npn \__exsheets_print_solution_if:nn #1#2 + { + \exp_args:No \int_compare:nT { #2 } + { + \prop_get:NnN \g__exsheets_solutions_names_prop + { #1 } \l__exsheets_tmpa_tl + \prop_get:NnN \g__exsheets_solutions_content_prop + { #1 } \l__exsheets_tmpb_tl + \eSaveCounterPatternFrom [ exsheets ] + \l__exsheets_current_pattern_interpretation_tl + \l__exsheets_current_pattern_tl + \l__exsheets_qu_counter_pattern_tl + \exsheets_solutions_print_name:VV + \l__exsheets_current_pattern_tl + \l__exsheets_tmpa_tl + \tl_use:N \l__exsheets_tmpb_tl \par + \dim_compare:nNnT { \parskip } = { 0pt } + { \exsheets_glue:N \l__exsheets_solutions_skip_below_dim } + } + } + +% print by section: +\cs_new:Npn \exsheets_print_solutions_section:n #1 + { + \tl_if_blank:nTF { #1 } + { + \prop_map_inline:Nn \g__exsheets_question_number_prop + { + \prop_if_in:NnT \g__exsheets_solutions_names_prop { ##1 } + { + \__exsheets_print_solutions_section:nnn { ##1 } { ##2 } + { \arabic{section} } + } + } + } + { + \clist_map_inline:nn { #1 } + { \__exsheets_print_solutions_by_section:w ##1-- \q_stop } + } + } + +\cs_new:Npn \__exsheets_print_solutions_by_section:w #1-#2-#3 \q_stop + { + % wenn #3=-, dann range-Input + \tl_if_eq:nnTF { #3 } { - } + { + \int_zero:N \l__exsheets_tmpa_int + \int_set_eq:NN \l__exsheets_tmpb_int \c_ten_thousand + \tl_if_blank:nF { #1 } { \int_set:Nn \l__exsheets_tmpa_int { #1 } } + \tl_if_blank:nF { #2 } { \int_set:Nn \l__exsheets_tmpb_int { #2 } } + \int_do_while:nn { \l__exsheets_tmpa_int <= \l__exsheets_tmpb_int } + { + \prop_map_inline:Nn \g__exsheets_question_number_prop + { + \prop_if_in:NnT \g__exsheets_solutions_names_prop { ##1 } + { + \__exsheets_print_solutions_section:nnn + { ##1 } { ##2 } { \l__exsheets_tmpa_int } + } + } + \int_incr:N \l__exsheets_tmpa_int + } + } + { + \prop_map_inline:Nn \g__exsheets_question_number_prop + { + \prop_if_in:NnT \g__exsheets_solutions_names_prop { ##1 } + { \__exsheets_print_solutions_section:nnn { ##1 } { ##2 } { #1 } } + } + } + } + +\cs_new:Npn \__exsheets_print_solutions_section:nnn #1#2#3 + { + \__exsheets_read_number:w #2 \q_stop + \__exsheets_print_solution_if:nn { #1 } + { \l__exsheets_counter_sec_int = #3 } + } + +% print by chapter: +\cs_new:Npn \exsheets_print_solutions_chapter:n #1 + { + \tl_if_blank:nTF { #1 } + { + \prop_map_inline:Nn \g__exsheets_question_number_prop + { + \prop_if_in:NnT \g__exsheets_solutions_names_prop { ##1 } + { + \__exsheets_print_solutions_chapter:nnn { ##1 } { ##2 } + { \arabic{chapter} } + } + } + } + { + \clist_map_inline:nn { #1 } + { \__exsheets_print_solutions_by_chapter:w ##1-- \q_stop } + } + } + +\cs_new:Npn \__exsheets_print_solutions_by_chapter:w #1-#2-#3 \q_stop + { + % wenn #3=-, dann range-Input + \tl_if_eq:nnTF { #3 } { - } + { + \int_zero:N \l__exsheets_tmpa_int + \int_set_eq:NN \l__exsheets_tmpb_int \c_ten_thousand + \tl_if_blank:nF { #1 } { \int_set:Nn \l__exsheets_tmpa_int { #1 } } + \tl_if_blank:nF { #2 } { \int_set:Nn \l__exsheets_tmpb_int { #2 } } + \int_do_while:nn { \l__exsheets_tmpa_int <= \l__exsheets_tmpb_int } + { + \prop_map_inline:Nn \g__exsheets_question_number_prop + { + \prop_if_in:NnT \g__exsheets_solutions_names_prop { ##1 } + { + \__exsheets_print_solutions_chapter:nnn + { ##1 } { ##2 } { \l__exsheets_tmpa_int } + } + } + \int_incr:N \l__exsheets_tmpa_int + } + } + { + \prop_map_inline:Nn \g__exsheets_question_number_prop + { + \prop_if_in:NnT \g__exsheets_solutions_names_prop { ##1 } + { \__exsheets_print_solutions_chapter:nnn { ##1 } { ##2 } { #1 } } + } + } + } + +\cs_new:Npn \__exsheets_print_solutions_chapter:nnn #1#2#3 + { + \__exsheets_read_number:w #2 \q_stop + \__exsheets_print_solution_if:nn { #1 } + { \l__exsheets_counter_ch_int = #3 } + } + +% print all: +\cs_new:Npn \exsheets_print_solutions_all: + { + \prop_map_function:NN \g__exsheets_question_number_prop + \__exsheets_print_solutions_all:nn + } + +\cs_new:Npn \__exsheets_print_solutions_all:nn #1#2 + { + \__exsheets_read_number:w #2 \q_stop + \prop_get:NnNT \g__exsheets_solutions_names_prop + { #1 } \l__exsheets_tmpa_tl + { + \tl_set_eq:NN \l__exsheets_solutions_name_tl \l__exsheets_tmpa_tl + \prop_get:NnN \g__exsheets_solutions_content_prop + { #1 } \l__exsheets_tmpb_tl + \eSaveCounterPatternFrom [ exsheets ] + \l__exsheets_current_pattern_interpretation_tl + \l__exsheets_current_pattern_tl + \l__exsheets_qu_counter_pattern_tl + \exsheets_solutions_print_name:VV + \l__exsheets_current_pattern_tl + \l__exsheets_tmpa_tl + \tl_use:N \l__exsheets_tmpb_tl \par + \dim_compare:nNnT { \parskip } = { 0pt } + { \exsheets_glue:N \l__exsheets_solutions_skip_below_dim } + } + } + +% print by ID: +\seq_new:N \l__exsheets_solutions_byID_seq +\cs_new:Npn \exsheets_print_solutions_byID:n #1 + { + \seq_set_split:Nnn \l__exsheets_solutions_byID_seq { , } { #1 } + \seq_clear:N \l__exsheets_tmpa_seq + \seq_map_inline:Nn \l__exsheets_solutions_byID_seq + { + \prop_get:NnN \g__exsheets_questions_id_prop + { ##1 } \l__exsheets_tmpa_tl + \seq_put_right:NV \l__exsheets_tmpa_seq \l__exsheets_tmpa_tl + } + \bool_if:NT \l__exsheets_print_byID_sorted_bool + { + \seq_sort:Nn \l__exsheets_tmpa_seq + { + \int_compare:nNnTF { ##1 } > { ##2 } + { \sort_reversed: } + { \sort_ordered: } + } + } + \seq_map_inline:Nn \l__exsheets_tmpa_seq + { + \group_begin: + \tl_if_eq:nnF { ##1 } { \q_no_value } + { + \prop_get:NnNT \g__exsheets_solutions_names_prop + { ##1 } \l__exsheets_tmpa_tl + { + \prop_get:NnN \g__exsheets_solutions_content_prop + { ##1 } \l__exsheets_tmpb_tl + \__exsheets_restore_number_from_and_do:Nnn + \g__exsheets_question_number_prop + { ##1 } + { + \eSaveCounterPatternFrom [ exsheets ] + \l__exsheets_current_pattern_interpretation_tl + \l__exsheets_current_pattern_tl + \l__exsheets_qu_counter_pattern_tl + \exsheets_solutions_print_name:VV + \l__exsheets_current_pattern_tl + \l__exsheets_tmpa_tl + \tl_use:N \l__exsheets_tmpb_tl \par + \dim_compare:nNnT { \parskip } = { 0pt } + { \exsheets_glue:N \l__exsheets_solutions_skip_below_dim } + } + } + } + \group_end: + } + } + +\cs_new_nopar:Npn \__exsheets_read_number:w #1-#2-#3 \q_stop + { + \int_zero:N \l__exsheets_counter_ch_int + \int_zero:N \l__exsheets_counter_sec_int + \int_zero:N \l__exsheets_counter_qu_int + \tl_if_in:nnF { #1 } { @@@ } + { + \tl_if_blank:nF { #1 } + { \int_set:Nn \l__exsheets_counter_ch_int { #1 } } + } + \int_set:Nn \l__exsheets_counter_sec_int { #2 } + \int_set:Nn \l__exsheets_counter_qu_int { #3 } + } + +\cs_new_nopar:Npn \exsheets_solutions_print_name:nn #1#2 + { + \tl_set_rescan:Nnn \l__exsheets_tmpa_tl + { \char_set_catcode_letter:N \@ } { #1 } + \tl_if_in:nnTF { #1 } { @@@ } + { \__exsheets_solutions_name:nn { } { #2 } } + { \__exsheets_solutions_name:nn { #1 } { #2 } } + \tex_penalty:D \c_ten_thousand + } +\cs_generate_variant:Nn \exsheets_solutions_print_name:nn { VV } + +\cs_new:Npn \PrintSolutionsTF + { \bool_if:NTF \l__exsheets_solutions_print_bool } +\cs_new:Npn \PrintSolutionsT + { \bool_if:NT \l__exsheets_solutions_print_bool } +\cs_new:Npn \PrintSolutionsF + { \bool_if:NF \l__exsheets_solutions_print_bool } + +\bool_new:N \l__exsheets_print_byID_sorted_bool +\bool_set_true:N \l__exsheets_print_byID_sorted_bool + +\keys_define:nn { exsheets / solution } + { + print .choice: , + print / true .code:n = + { + \bool_set_true:N \l__exsheets_solutions_print_bool + \bool_set_true:N \l__exsheets_solutions_print_here_bool + \bool_set_false:N \l__exsheets_solutions_print_section_bool + \bool_set_false:N \l__exsheets_solutions_print_chapter_bool + \bool_set_false:N \l__exsheets_solutions_print_all_bool + } , + print / false .code:n = + { + \bool_set_false:N \l__exsheets_solutions_print_bool + } , + print .default:n = true , + name .tl_set:N = \l__exsheets_solutions_name_tl , + sorted .bool_set:N = \l__exsheets_print_byID_sorted_bool , + skip-below .dim_set:N = \l__exsheets_solutions_skip_below_dim + } + +% ---------------------------------------------------------------------------- +% the `tasks' list +\input { exsheets_tasks.def } +\bool_if:NT \l__exsheets_load_tasks_bool + { + \RequirePackage { amssymb } + \input { exsheets_tasks.cfg } + } + +% ---------------------------------------------------------------------------- +% the \blank{<words>} command +\RequirePackage { ulem } \normalem +\dim_new:N \l__exsheets_blank_dim +\box_new:N \l__exsheets_blank_box +\bool_new:N \l__exsheets_blank_width_bool + +\cs_new_nopar:Npn \exsheets_write_blank:n #1 { #1 } +\cs_set_eq:NN \exsheets_write_blank:n \uline + +\keys_define:nn { exsheets / blank } + { + style .choice: , + style / line .code:n = + { \cs_set_eq:NN \exsheets_write_blank:n \uline } , + style / wave .code:n = + { \cs_set_eq:NN \exsheets_write_blank:n \uwave } , + style / dline .code:n = + { \cs_set_eq:NN \exsheets_write_blank:n \uuline } , + style / dotted .code:n = + { \cs_set_eq:NN \exsheets_write_blank:n \dotuline } , + style / dashed .code:n = + { \cs_set_eq:NN \exsheets_write_blank:n \dashuline } , + width .code:n = + { + \bool_set_true:N \l__exsheets_blank_width_bool + \dim_set:Nn \l__exsheets_blank_dim { #1 } + } + } + +\NewDocumentCommand \blank { o m } + { + \group_begin: + \IfNoValueF { #1 } { \keys_set:nn { exsheets / blank } { #1 } } + \exsheets_blank:n { #2 } + \group_end: + } + +\cs_new:Npn \exsheets_blank:n #1 + { + \box_clear:N \l__exsheets_blank_box + \hbox_set:Nn \l__exsheets_blank_box { #1 } + \bool_if:NTF \l__exsheets_inside_solution_bool + { \exsheets_write_blank:n { #1 } } + { + \bool_if:NTF \l__exsheets_blank_width_bool + { \__exsheets_blank_skip:N \l__exsheets_blank_dim } + { \__exsheets_blank_skip:n { \box_wd:N \l__exsheets_blank_box } } + } + } + +\cs_new:Npn \__exsheets_blank_skip:N #1 + { + \dim_set:Nn \l__exsheets_tmpa_dim { #1 } + \dim_compare:nTF { \l__exsheets_tmpa_dim > 2em } + { + \exsheets_write_blank:n { \skip_horizontal:n { 1em } } + \dim_sub:Nn \l__exsheets_tmpa_dim { 2em } + \dim_do_while:nn { \l__exsheets_tmpa_dim > \c_zero_dim } + { + \tex_penalty:D \hyphenpenalty + \dim_compare:nTF { \l__exsheets_tmpa_dim < 1pt } + { \exsheets_write_blank:n { \skip_horizontal:N \l__exsheets_tmpa_dim } } + { \exsheets_write_blank:n { \skip_horizontal:n { 1pt } } } + \dim_sub:Nn \l__exsheets_tmpa_dim { 1pt } + } + \exsheets_write_blank:n { \skip_horizontal:n { 1em } } + } + { \exsheets_write_blank:n { \skip_horizontal:N \l__exsheets_tmpa_dim } } + } +\cs_generate_variant:Nn \__exsheets_blank_skip:N { n } + +% the following code from Heiko Oberdieck in d.c.t.t served as inspiration +% and basis for the \blank command: +% +% \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 + +% ---------------------------------------------------------------------------- +% SETUP +\NewDocumentCommand \SetupExSheets { o m } + { + \IfNoValueTF { #1 } + { \keys_set:nn { exsheets } { #2 } } + { \keys_set:nn { exsheets / #1 } { #2 } } + } + +% ---------------------------------------------------------------------------- +% Sprachanpassungen +\file_if_exist:nT { translations.sty } + { + \RequirePackage { translations } + % translation for the exercises + \DeclareTranslation { English } { exsheets-exercise-name } { Exercise } + \DeclareTranslation { British } { exsheets-exercise-name } { Exercise } + \DeclareTranslation { American } { exsheets-exercise-name } { Exercise } + \DeclareTranslation { French } { exsheets-exercise-name } { Exercise } + \DeclareTranslation { German } { exsheets-exercise-name } { \"Ubung } + \DeclareTranslation { Italian } { exsheets-exercise-name } { Esercizio } + \DeclareTranslation { Spanish } { exsheets-exercise-name } { Ejercicio } + \DeclareTranslation { Catalan } { exsheets-exercise-name } { Exercir } + \DeclareTranslation { Turkish } { exsheets-exercise-name } { Egzersiz } + % translation for the question + \DeclareTranslation { English } { exsheets-question-name } { Question } + \DeclareTranslation { British } { exsheets-question-name } { Question } + \DeclareTranslation { American } { exsheets-question-name } { Question } + \DeclareTranslation { French } { exsheets-question-name } { Question } + \DeclareTranslation { German } { exsheets-question-name } { Aufgabe } + \DeclareTranslation { Italian } { exsheets-question-name } { Questione } + \DeclareTranslation { Spanish } { exsheets-question-name } { Pregunta } + \DeclareTranslation { Catalan } { exsheets-question-name } { Q\"uesti\'o } + \DeclareTranslation { Turkish } { exsheets-question-name } { Soru } + % translation for the solutions + \DeclareTranslation { English } { exsheets-solution-name } { Solution } + \DeclareTranslation { British } { exsheets-solution-name } { Solution } + \DeclareTranslation { American } { exsheets-solution-name } { Solution } + \DeclareTranslation { French } { exsheets-solution-name } { Solution } + \DeclareTranslation { German } { exsheets-solution-name } { L\"osung } + \DeclareTranslation { Italian } { exsheets-solution-name } { Soluzione } + \DeclareTranslation { Spanish } { exsheets-solution-name } { Soluci\'on } + \DeclareTranslation { Catalan } { exsheets-solution-name } { Soluci\'o } + \DeclareTranslation { Turkish } { exsheets-solution-name } { \c C\"oz\"um } + % the actual translating + \tl_set:Nn \l__exsheets_exsheets_name_tl + { \GetTranslation { exsheets-exercise-name } } + \tl_set:Nn \l__exsheets_questions_name_tl + { \GetTranslation { exsheets-question-name } } + \tl_set:Nn \l__exsheets_solutions_name_tl + { \GetTranslation { exsheets-solution-name } } + } + +% ---------------------------------------------------------------------------- +% save total points in .aux file to make it available for \allpoints anywhere +\AtEndDocument + { + \iow_now:Nx \@auxout + { + \exp_not:N \exsheets@sum@of@points + { \fp_eval:n { \g__exsheets_points_sum_fp } } + \exp_not:N \exsheets@sum@of@bonus + { \fp_eval:n { \g__exsheets_bonus_sum_fp } } + } + } + +% ---------------------------------------------------------------------------- +% load custom configuration +\file_if_exist:nT { exsheets_configurations.cfg } + { + \AtBeginDocument + { + \msg_info:nn { exsheets } { loading-configurations } + \file_input:n { exsheets_configurations.cfg } + } + } + +\tex_endinput:D + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +HISTORY: +2011/11/23 v0.1pre - first upload to bitbucket and all changes until + considered stable enough/ready to be called 0.1alpha. + There'll be no further descriptions until then. +2012/06/08 v0.1alpha - first hopefully stable version +2012/06/11 v0.1alpha-a - added headings instances, slightly rewritten + `exercises-tasks' object and `tasks' environment +2012/06/11 v0.1alpha-b - added `multiplechoice' instance and `load-tasks' option +2012/06/12 v0.1alpha-c - renamed from `exercises' into `ExSheets' +2012/06/15 v0.1alpha-d - added more flexible solution printing method +2012/06/15 v0.1beta - filled in some blanks in the documentation, now we need + some testing! +2012/09/07 v0.1beta-a - adjustments to the updated l3kernel +2012/09/08 v0.1beta-b - sort solutions printed with the `byID' key +2012/09/16 v0.1beta-c - renamed option `questions-counter-format' into + `counter-format' +2012/09/19 v0.1beta-d - added `topic' key, provide \includequestions with options + `all' and `IDs' +2012/09/24 v0.1beta-e - added question properties and improved random question + selection +2012/09/27 v0.1 - added two headings instances, new option `headings-format' + - small changes in the definition of the `exsheets-headings' + object + - preliminary version of totoc options. Unfortunatly + \exsheets@recover@number is not expandable => no + hyperref support +2012/09/30 v0.2beta - version numbering gone crazy! this will now stay 0.2beta + until upload to CTAN (v0.2) + - integrated packages `translations' and `cntformats': + trnslt: provide expandable version of `translator's + \translate + cntfmts: outsourced previous counter formatting commands; + should now be usable in other packages, too, and + simplified definitions in `ExSheets' + - thanks to `translations' and `cntformats' the `totoc' + option now works with `hyperref' +2012/10/05 v0.2 - removed \sumpoints and moved the functionality to + \totalpoints* + - changed meaning of \addpoints* and moved former + functionality to \points + - added bonus point functionality including \addbonus, + \bonus, \bonussum, \pointssum, \currentpointssum, + \currentbonussum + - added grades distribution + - `translations' got \LoadDictionary and \LoadDictionaryFor + added and loads of languages defined. +2012/10/05 v0.2a - resolved bug in saving and recovering question number + using \exsheets@save@number and \QuestionNumber +2012/10/08 v0.2b - improved the reference to chapter/solution numbers + in \printsolutions + - resolved bug in \printsolutions introduced in the last + update + - upload to CTAN + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% TODO: +- points/decimal-marker, points/frac (?), points/format (?,im interface)
\ No newline at end of file diff --git a/Master/texmf-dist/tex/latex/exsheets/exsheets_configurations.cfg b/Master/texmf-dist/tex/latex/exsheets/exsheets_configurations.cfg new file mode 100644 index 00000000000..3c64153c7ca --- /dev/null +++ b/Master/texmf-dist/tex/latex/exsheets/exsheets_configurations.cfg @@ -0,0 +1,5 @@ +\ProvidesFile{exsheets_configurations.cfg} + +% Put your definitions and configurations here. + +\endinput
\ No newline at end of file diff --git a/Master/texmf-dist/tex/latex/exsheets/exsheets_headings.cfg b/Master/texmf-dist/tex/latex/exsheets/exsheets_headings.cfg new file mode 100644 index 00000000000..3ec2ae06bf5 --- /dev/null +++ b/Master/texmf-dist/tex/latex/exsheets/exsheets_headings.cfg @@ -0,0 +1,302 @@ +% -------------------------------------------------------------------------- +% the EXSHEETS package +% +% Yet another package for the creation of exercise sheets +% +% -------------------------------------------------------------------------- +% Clemens Niederberger +% Web: https://bitbucket.org/cgnieder/exsheets/ +% E-Mail: contact@mychemistry.eu +% -------------------------------------------------------------------------- +% Copyright 2011-2012 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 exsheets package consists of the files +% - exsheets.sty, exsheets_headings.def, exsheets_headings.cfg, +% exsheets_tasks.def, exsheets_tasks.cfg, exsheets_configurations.cfg, +% - exsheets_en.tex, exsheets_en.pdf, +% - README +% -------------------------------------------------------------------------- +% If you have any ideas, questions, suggestions or bugs to report, please +% feel free to contact me. +% -------------------------------------------------------------------------- +% HEADINGS FOR QUESTIONS AND SOLUTIONS +\ProvidesFile{exsheets_headings.cfg} + [\exsheets@date\space v\exsheets@version\space ExSheets headings instances] + +% SIMPLE: +\DeclareInstance { exsheets-heading } { simple } { default } + { + title-format = \normalsize , + points-pre-code = ( , + points-post-code = ) , + attach = { main[l,t] number[l,t] (0pt,0pt) } , + join = + { + number[r,b] title[l,b] (1ex,0pt) ; + main[l,b] points[l,t] (1em,0pt) + } + } + +% BLOCK, REVERSED: +\DeclareInstance { exsheets-heading } { block-rev } { default } + { + toc-reversed = true , + join = { number[r,B] title[l,B] (1ex,0pt) } , + attach = + { + main[l,vc] number[l,vc] (0pt,0pt) ; + main[r,vc] points[l,vc] (\marginparsep,0pt) + } + } + +% BLOCK, POINTS WITH THE TITLE: +\DeclareInstance { exsheets-heading } { block-wp } { default } + { + points-pre-code = ( , + points-post-code = ) , + join = + { + title[r,B] number[l,B] (1ex,0pt) ; + title[r,B] points[l,B] (1ex,0pt) + } , + attach = { main[l,vc] title[l,vc] (0pt,0pt) } + } + +% BLOCK, POINTS WITH THE TITLE, REVERSED: +\DeclareInstance { exsheets-heading } { block-wp-rev } { default } + { + toc-reversed = true , + points-pre-code = ( , + points-post-code = ) , + join = + { + number[r,B] title[l,B] (1ex,0pt) ; + number[r,B] points[l,B] (1ex,0pt) + } , + attach = { main[l,vc] number[l,vc] (0pt,0pt) } + } + +% BLOCK WITH NO TITLE: +\DeclareInstance { exsheets-heading } { block-nr } { default } + { + attach = + { + main[l,vc] number[l,vc] (0pt,0pt) ; + main[r,vc] points[l,vc] (\marginparsep,0pt) + } + } + +% BLOCK WITH NO TITLE, NUMBER WITH THE TITLE: +\DeclareInstance { exsheets-heading } { block-nr-wp } { default } + { + points-pre-code = ( , + points-post-code = ) , + join = { number[r,vc] points[l,vc] (1ex,0pt) } , + attach = { main[l,vc] number[l,vc] (0pt,0pt) } + } + +% RUNIN, REVERSED: +\DeclareInstance { exsheets-heading } { runin-rev } { default } + { + toc-reversed = true , + runin = true , + title-post-code = \c_space_tl , + attach = + { main[l,vc] points[l,vc] (\linewidth + \marginparsep,0pt) } , + join = + { + main[r,vc] number[r,vc] (0pt,0pt) ; + main[r,vc] title[l,vc] (1ex,0pt) + } + } + +% RUNIN, POINTS WITH THE TITLE: +\DeclareInstance { exsheets-heading } { runin-wp } { default } + { + runin = true , + points-pre-code = ( , + points-post-code = ) \c_space_tl , + join = + { + main[r,vc] title[r,vc] (0pt,0pt) ; + main[r,vc] number[l,vc] (1ex,0pt) ; + main[r,vc] points[l,vc] (1ex,0pt) + } + } + +% RUNIN, POINTS WITH THE TITLE, REVERSED: +\DeclareInstance { exsheets-heading } { runin-wp-rev } { default } + { + toc-reversed = true , + runin = true , + points-pre-code = ( , + points-post-code = ) \c_space_tl , + join = + { + main[r,vc] number[r,vc] (0pt,0pt) ; + main[r,vc] title[l,vc] (1ex,0pt) ; + main[r,vc] points[l,vc] (1ex,0pt) + } + } + +% RUNIN WITH NO TITLE: +\DeclareInstance { exsheets-heading } { runin-nr } { default } + { + runin = true , + number-post-code = \c_space_tl , + attach = + { main[l,vc] points[l,vc] (\linewidth + \marginparsep,0pt) } , + join = { main[r,vc] number[l,vc] (0pt,0pt) } + } + +% RUNIN WITH NO TITLE, POINTS WITH THE TITLE: +\DeclareInstance { exsheets-heading } { runin-nr-wp } { default } + { + runin = true , + points-pre-code = ( , + points-post-code = ) \c_space_tl , + join = + { + main[r,vc] number[l,vc] (0pt,0pt) ; + main[r,vc] points[l,vc] (1ex,0pt) + } + } + +% RUNIN WITH NO TITLE, FIXED WIDTH OF NUMBER +\DeclareInstance { exsheets-heading } { runin-fixed-nr } { default } + { + runin = true , + number-pre-code = \hbox to 2em \bgroup , + number-post-code = \hfil\egroup , + attach = + { main[l,vc]points[l,vc](\linewidth+\marginparsep,0pt) } , + join = { main[r,vc]number[l,vc](0pt,0pt) } + } + +% CENTERED: +\DeclareInstance { exsheets-heading } { centered } { default } + { + join = { title[r,B] number[l,B] (1ex,0pt) } , + attach = + { + main[hc,vc] title[hc,vc] (0pt,0pt) ; + main[r,vc] points[l,vc] (\marginparsep,0pt) + } + } + +% CENTERED, POINTS WITH THE TITLE: +\DeclareInstance { exsheets-heading } { centered-wp } { default } + { + points-pre-code = ( , + points-post-code = ) , + join = + { + title[r,B] number[l,B] (1ex,0pt) ; + title[r,B] points[l,B] (1ex,0pt) + } , + attach = { main[hc,vc] title[hc,vc] (0pt,0pt) } + } + +% MARGIN: +\DeclareInstance { exsheets-heading } { margin } { default } + { + runin = true , + number-post-code = \c_space_tl , + points-pre-code = ( , + points-post-code = ) \c_space_tl , + join = { title[r,b] number[l,b] (1ex,0pt) } , + attach = + { + main[l,vc] title[r,vc] (0pt,0pt) ; + main[l,b] points[r,t] (0pt,0pt) + } + } + +% MARGIN WITH NO TITLE +\DeclareInstance { exsheets-heading } { margin-nr } { default } + { + runin = true , + attach = + { + main[l,vc]number[r,vc](-1ex,0pt) ; + main[r,vc]points[l,vc](\linewidth+\marginparsep,0pt) + } + } + +% RIGHT-ALIGNED: +\DeclareInstance { exsheets-heading } { raggedleft } { default } + { + join = { title[r,B] number[l,B] (1ex,0pt) } , + attach = + { + main[r,vc] title[r,vc] (0pt,0pt) ; + main[r,vc] points[l,vc] (\marginparsep,0pt) + } + } + +% MIMICKING KOMA-SECTION: +\DeclareInstance { exsheets-heading } { koma-section } { default } + { + vscale = 2 , + title-format = \Large\bfseries\sffamily , + join = { title[r,B] number[l,B] (1ex,0pt) } , + attach = + { + main[l,vc] title[l,vc] (0pt,0pt) ; + main[r,vc] points[l,vc] (\marginparsep,0pt) + } + } + +% FANCY: +\DeclareInstance { exsheets-heading } { fancy } { default } + { + toc-reversed = true , + indent-first = true , + vscale = 2 , + pre-code = \rule{\linewidth}{1pt} , + post-code = \rule{\linewidth}{1pt} , + title-format = \large\scshape\color{exsheetsred} , + number-format = \large\bfseries\color{exsheetsblue} , + points-format = \itshape , + join = { number[r,B] title[l,B] (1ex,0pt) } , + attach = + { + main[hc,vc] number[hc,vc] (0pt,0pt) ; + main[l,vc] points[r,vc] (-\marginparsep,0pt) + } + } + +% FANCY, POINTS WITH THE TITLE: +\DeclareInstance { exsheets-heading } { fancy-wp } { default } + { + toc-reversed = true , + indent-first = true , + vscale = 2 , + pre-code = \rule{\linewidth}{1pt} , + post-code = \rule{\linewidth}{1pt} , + title-format = \large\scshape\color{exsheetsred} , + number-format = \large\bfseries\color{exsheetsblue} , + points-format = \itshape , + points-pre-code = ( , + points-post-code = ) , + join = + { + number[r,B] title[l,B] (1ex,0pt) ; + number[r,B] points[l,B] (1ex,0pt) + } , + attach = { main[hc,vc] number[hc,vc] (0pt,0pt) } + } + +\tex_endinput:D
\ No newline at end of file diff --git a/Master/texmf-dist/tex/latex/exsheets/exsheets_headings.def b/Master/texmf-dist/tex/latex/exsheets/exsheets_headings.def new file mode 100644 index 00000000000..c5e9eeebe4d --- /dev/null +++ b/Master/texmf-dist/tex/latex/exsheets/exsheets_headings.def @@ -0,0 +1,371 @@ +% -------------------------------------------------------------------------- +% the EXSHEETS package +% +% Yet another package for the creation of exercise sheets +% +% -------------------------------------------------------------------------- +% Clemens Niederberger +% Web: https://bitbucket.org/cgnieder/exsheets/ +% E-Mail: contact@mychemistry.eu +% -------------------------------------------------------------------------- +% Copyright 2011-2012 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 exsheets package consists of the files +% - exsheets.sty, exsheets_headings.def, exsheets_headings.cfg, +% exsheets_tasks.def, exsheets_tasks.cfg, exsheets_configurations.cfg, +% - exsheets_en.tex, exsheets_en.pdf, +% - README +% -------------------------------------------------------------------------- +% If you have any ideas, questions, suggestions or bugs to report, please +% feel free to contact me. +% -------------------------------------------------------------------------- +% HEADINGS FOR QUESTIONS AND SOLUTIONS +% the 6 base coffins: +\ProvidesFile{exsheets_headings.def} + [\exsheets@date\space v\exsheets@version\space ExSheets headings object] + +\coffin_new:N \l__exsheets_heading_main_coffin +\coffin_new:N \l__exsheets_heading_pre_coffin +\coffin_new:N \l__exsheets_heading_post_coffin +\coffin_new:N \l__exsheets_heading_title_coffin +\coffin_new:N \l__exsheets_heading_number_coffin +\coffin_new:N \l__exsheets_heading_points_coffin + +% the object varaibles: +\bool_new:N \l__exsheets_heading_runin_bool +\bool_new:N \l__exsheets_heading_indent_first_bool +\bool_new:N \l__exsheets_heading_toc_reversed_bool + +\dim_new:N \l__exsheets_heading_above_dim +\dim_new:N \l__exsheets_heading_below_dim +\fp_new:N \l__exsheets_heading_scale_fp + +\tl_new:N \l__exsheets_heading_main_tl +\tl_new:N \l__exsheets_heading_pre_code_tl +\tl_new:N \l__exsheets_heading_post_code_tl + +\tl_new:N \l__exsheets_heading_title_format_tl +\tl_new:N \l__exsheets_heading_title_pre_code_tl +\tl_new:N \l__exsheets_heading_title_post_code_tl + +\tl_new:N \l__exsheets_heading_number_format_tl +\tl_new:N \l__exsheets_heading_number_pre_code_tl +\tl_new:N \l__exsheets_heading_number_post_code_tl + +\tl_new:N \l__exsheets_heading_points_format_tl +\tl_new:N \l__exsheets_heading_points_pre_code_tl +\tl_new:N \l__exsheets_heading_points_post_code_tl + +\tl_new:N \l__exsheets_heading_joined_coffins_tl +\tl_new:N \l__exsheets_heading_attached_coffins_tl +\seq_new:N \l__exsheets_heading_joined_coffins_seq +\seq_new:N \l__exsheets_heading_attached_coffins_seq + +% internal object functions: +% the following is shamelessly adapted from the `needspace' package by +% Peter Wilson and Herries Press +\cs_new:Npn \exsheets_needspace:n #1 + { + \group_begin: + \dim_set:Nn \l__exsheets_tmpa_dim { #1 } + \skip_vertical:n { \c_zero_dim + \l__exsheets_tmpa_dim } + \tex_penalty:D -100 + \skip_vertical:n { \c_zero_dim - \l__exsheets_tmpa_dim } + \skip_vertical:N \l__exsheets_tmpa_dim + \tex_penalty:D 9999 + \skip_vertical:n { - \l__exsheets_tmpa_dim } + \skip_vertical:N \c_zero_dim + \group_end: + } + +\AtBeginDocument + { + \cs_if_exist:NF \needspace + { \cs_set_eq:NN \needspace \exsheets_needspace:n } + } + +\cs_generate_variant:Nn \seq_set_split:Nnn { NnV } + +\cs_new:Npn \__exsheets_join:N #1 + { + \seq_map_inline:Nn #1 + { + \tl_if_blank:nF { ##1 } + { \exp_after:wN \__exsheets_join_coffin_sequence:w ##1 } + } + } +\cs_new:Npn \__exsheets_join_coffin_sequence:w #1[#2,#3] #4[#5,#6] (#7,#8) + { \__exsheets_join_coffins:nnnnnnnn {#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8} } + +\cs_new:Npn \__exsheets_join_coffins:nnnnnnnn #1#2#3#4#5#6#7#8 + { + \coffin_join:cnncnnnn + { l__exsheets_heading_#1_coffin } { #2 } { #3 } + { l__exsheets_heading_#4_coffin } { #5 } { #6 } + { #7 } { #8 } + } +\cs_new:Npn \__exsheets_attach:N #1 + { + \seq_map_inline:Nn #1 + { + \tl_if_blank:nF { ##1 } + { \exp_after:wN \__exsheets_attach_coffin_sequence:w ##1 } + } + } +\cs_new:Npn \__exsheets_attach_coffin_sequence:w #1[#2,#3]#4[#5,#6](#7,#8) + { \__exsheets_attach_coffins:nnnnnnnn {#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8} } + +\cs_new:Npn \__exsheets_attach_coffins:nnnnnnnn #1#2#3#4#5#6#7#8 + { + \coffin_attach:cnncnnnn + { l__exsheets_heading_#1_coffin } { #2 } { #3 } + { l__exsheets_heading_#4_coffin } { #5 } { #6 } + { #7 } { #8 } + } + +% the `exsheets-heading' object: +% #1 = title, +% #2 = number, +% #3 = points +% #4 = bonus +\DeclareObjectType { exsheets-heading } { 4 } + +% the `default' template interface: +\DeclareTemplateInterface { exsheets-heading } { default } { 4 } + { + runin : boolean = false , + indent-first : boolean = false , + toc-reversed : boolean = false , + vscale : real = 1 , + above : length = 2pt , + below : length = 2pt , + main : tokenlist = , + pre-code : tokenlist = , + post-code : tokenlist = , + title-format : tokenlist = , + title-pre-code : tokenlist = , + title-post-code : tokenlist = , + number-format : tokenlist = , + number-pre-code : tokenlist = , + number-post-code : tokenlist = , + points-format : tokenlist = , + points-pre-code : tokenlist = , + points-post-code : tokenlist = , + join : tokenlist = , + attach : tokenlist = + } + +% the `default' template code: +\DeclareTemplateCode { exsheets-heading } { default } { 4 } + { + runin = \l__exsheets_heading_runin_bool , + indent-first = \l__exsheets_heading_indent_first_bool , + toc-reversed = \l__exsheets_heading_toc_reversed_bool , + vscale = \l__exsheets_heading_scale_fp , + above = \l__exsheets_heading_above_dim , + below = \l__exsheets_heading_below_dim , + main = \l__exsheets_heading_main_tl , + pre-code = \l__exsheets_heading_pre_code_tl , + post-code = \l__exsheets_heading_post_code_tl , + title-format = \l__exsheets_heading_title_format_tl , + title-pre-code = \l__exsheets_heading_title_pre_code_tl , + title-post-code = \l__exsheets_heading_title_post_code_tl , + number-format = \l__exsheets_heading_number_format_tl , + number-pre-code = \l__exsheets_heading_number_pre_code_tl , + number-post-code = \l__exsheets_heading_number_post_code_tl , + points-format = \l__exsheets_heading_points_format_tl , + points-pre-code = \l__exsheets_heading_points_pre_code_tl , + points-post-code = \l__exsheets_heading_points_post_code_tl , + join = \l__exsheets_heading_joined_coffins_tl , + attach = \l__exsheets_heading_attached_coffins_tl + } + { + \AssignTemplateKeys + \bool_if:nT + { \l__exsheets_questions_totoc_bool && \l__exsheets_inside_question_bool } + { + \phantomsection + \addcontentsline { toc } { \l__exsheets_questions_toclevel_tl } + { + \bool_if:NTF \l__exsheets_heading_toc_reversed_bool + { #2 \ #1 } + { #1\ #2 } + } + } + \bool_if:nT + { \l__exsheets_solutions_totoc_bool && !\l__exsheets_inside_question_bool } + { + \phantomsection + \addcontentsline { toc } { \l__exsheets_solutions_toclevel_tl } + { + \bool_if:NTF \l__exsheets_heading_toc_reversed_bool + { #2 \ #1 } + { #1\ #2 } + } + } + \seq_set_split:NnV \l__exsheets_heading_joined_coffins_seq { ; } + \l__exsheets_heading_joined_coffins_tl + \seq_set_split:NnV \l__exsheets_heading_attached_coffins_seq { ; } + \l__exsheets_heading_attached_coffins_tl + \bool_if:NTF \l__exsheets_heading_runin_bool + { + \hcoffin_set:Nn \l__exsheets_heading_main_coffin + { + \tl_if_blank:VTF \l__exsheets_heading_main_tl + { \tl_use:N \l__exsheets_heading_title_format_tl \strut } + { \tl_use:N \l__exsheets_heading_main_tl } + } + } + { + \hcoffin_set:Nn \l__exsheets_heading_main_coffin + { + \parbox { \linewidth } + { + \tl_if_blank:VTF \l__exsheets_heading_main_tl + { \tl_use:N \l__exsheets_heading_title_format_tl \strut } + { \tl_use:N \l__exsheets_heading_main_tl } + } + } + } + \hcoffin_set:Nn \l__exsheets_heading_pre_coffin + { \tl_use:N \l__exsheets_heading_pre_code_tl } + \hcoffin_set:Nn \l__exsheets_heading_post_coffin + { \tl_use:N \l__exsheets_heading_post_code_tl } + \coffin_join:NnnNnnnn + \l__exsheets_heading_main_coffin { l } { t } + \l__exsheets_heading_pre_coffin { l } { b } { 0pt } { 0pt } + \coffin_join:NnnNnnnn + \l__exsheets_heading_main_coffin { l } { b } + \l__exsheets_heading_post_coffin { l } { t } { 0pt } { 0pt } + \hcoffin_set:Nn \l__exsheets_heading_title_coffin + { + \tl_use:N \l__exsheets_heading_title_format_tl + \strut + \exsheets_questions_debug: + \tl_use:N \l__exsheets_heading_title_pre_code_tl + { \tl_use:N \l__exsheets_heading_title_user_format_tl #1 } + \tl_use:N \l__exsheets_heading_title_post_code_tl + } + \hcoffin_set:Nn \l__exsheets_heading_number_coffin + { + \tl_if_blank:VTF \l__exsheets_heading_number_format_tl + { \tl_use:N \l__exsheets_heading_title_format_tl } + { \tl_use:N \l__exsheets_heading_number_format_tl } + \strut + \tl_use:N \l__exsheets_heading_number_pre_code_tl + { \tl_use:N \l__exsheets_heading_title_user_format_tl #2 } + \tl_use:N \l__exsheets_heading_number_post_code_tl + } + \hcoffin_set:Nn \l__exsheets_heading_points_coffin + { + \bool_if:nF { \fp_compare_p:n { #3 = 0 } && \fp_compare_p:n { #4 = 0 } } + { + \tl_use:N \l__exsheets_heading_points_format_tl + \group_begin: + \tl_use:N \l__exsheets_heading_title_format_tl \strut + \group_end: + \tl_use:N \l__exsheets_heading_points_pre_code_tl + { + % TODO: \l__exsheets_points_separate_bonus_bool beachten + \fp_compare:nF { #3 = 0 } + { + \bool_if:nTF + { + \l__exsheets_points_separate_bonus_bool || + \fp_compare_p:n { #4 = 0 } + } + { \exsheets_print_points:n { #3 } } + { \exsheets_parse_points:n { #3 } } + } + \bool_if:nT { !\fp_compare_p:n { #3 = 0 } && !\fp_compare_p:n { #4 = 0 } } + { ~ } + \fp_compare:nF { #4 = 0 } + { + \tl_use:N \l__exsheets_points_pre_bonus_marker_tl + \bool_if:nTF + { + \l__exsheets_points_separate_bonus_bool || + \fp_compare_p:n { #3 = 0 } + } + { + \exsheets_print_bonus:n { #4 } + \tl_use:N \l__exsheets_points_post_bonus_marker_tl + } + { + \exsheets_parse_bonus:n { #4 } + \tl_use:N \l__exsheets_points_post_bonus_marker_tl + \exsheets_points_name:n { #3 + #4 } + } + } + } + \tl_use:N \l__exsheets_heading_points_post_code_tl + } + } + \bool_if:NF \l__exsheets_heading_runin_bool + { + \coffin_resize:Nnn \l__exsheets_heading_main_coffin { \linewidth } + { + \fp_to_decimal:N \l__exsheets_heading_scale_fp + \coffin_ht:N \l__exsheets_heading_main_coffin + + \l__exsheets_heading_below_dim + } + } + \__exsheets_join:N \l__exsheets_heading_joined_coffins_seq + \__exsheets_attach:N \l__exsheets_heading_attached_coffins_seq + \skip_vertical:N \l__exsheets_heading_above_dim + \exsheets_needspace:n + { + \coffin_ht:N \l__exsheets_heading_main_coffin + + \coffin_dp:N \l__exsheets_heading_main_coffin + + \l__exsheets_heading_below_dim + + \baselineskip + } + \noindent + \coffin_typeset:Nnnnn \l__exsheets_heading_main_coffin + { H } { l } { 0pt }{ 0pt } + \bool_if:NF \l__exsheets_heading_runin_bool + { + \skip_vertical:N \l__exsheets_heading_below_dim + \bool_if:NF \l__exsheets_heading_indent_first_bool { \noindent } + } + } + +% the two basic instances: +% BLOCK: +\DeclareInstance { exsheets-heading } { block } { default } + { + join = { title[r,B] number[l,B] (1ex,0pt) } , + attach = + { + main[l,vc] title[l,vc] (0pt,0pt) ; + main[r,vc] points[l,vc] (\marginparsep,0pt) + } + } + +% RUNIN: +\DeclareInstance { exsheets-heading } { runin } { default } + { + runin = true , + number-post-code = \c_space_tl , + attach = + { main[l,vc] points[l,vc] (\linewidth + \marginparsep,0pt) } , + join = + { + main[r,vc] title[r,vc] (0pt,0pt) ; + main[r,vc] number[l,vc] (1ex,0pt) + } + } + +\tex_endinput:D
\ No newline at end of file diff --git a/Master/texmf-dist/tex/latex/exsheets/exsheets_tasks.cfg b/Master/texmf-dist/tex/latex/exsheets/exsheets_tasks.cfg new file mode 100644 index 00000000000..54de030795b --- /dev/null +++ b/Master/texmf-dist/tex/latex/exsheets/exsheets_tasks.cfg @@ -0,0 +1,56 @@ +% -------------------------------------------------------------------------- +% the EXSHEETS package +% +% Yet another package for the creation of exercise sheets +% +% -------------------------------------------------------------------------- +% Clemens Niederberger +% Web: https://bitbucket.org/cgnieder/exsheets/ +% E-Mail: contact@mychemistry.eu +% -------------------------------------------------------------------------- +% Copyright 2011-2012 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 exsheets package consists of the files +% - exsheets.sty, exsheets_headings.def, exsheets_headings.cfg, +% exsheets_tasks.def, exsheets_tasks.cfg, exsheets_configurations.cfg, +% - exsheets_en.tex, exsheets_en.pdf, +% - README +% -------------------------------------------------------------------------- +% If you have any ideas, questions, suggestions or bugs to report, please +% feel free to contact me. +% -------------------------------------------------------------------------- +% further instances for the `tasks' environment +\ProvidesFile{exsheets_tasks.cfg} + [\exsheets@date\space v\exsheets@version\space ExSheets tasks instances] + +% ITEMIZE: +\DeclareInstance { exsheets-tasks } { itemize } { default } + { + enumerate = false , + label-width = 2.25ex + } + +% ENUMERATE: +\DeclareInstance { exsheets-tasks } { enumerate } { default } + { label-format = tsk. } + +% MULTIPLECHOICE +\DeclareInstance { exsheets-tasks } { multiplechoice } { default } + { + enumerate = false , + label = \choicebox + } + +\tex_endinput:D
\ No newline at end of file diff --git a/Master/texmf-dist/tex/latex/exsheets/exsheets_tasks.def b/Master/texmf-dist/tex/latex/exsheets/exsheets_tasks.def new file mode 100644 index 00000000000..8ff8c581753 --- /dev/null +++ b/Master/texmf-dist/tex/latex/exsheets/exsheets_tasks.def @@ -0,0 +1,334 @@ +% -------------------------------------------------------------------------- +% the EXSHEETS package +% +% Yet another package for the creation of exercise sheets +% +% -------------------------------------------------------------------------- +% Clemens Niederberger +% Web: https://bitbucket.org/cgnieder/exsheets/ +% E-Mail: contact@mychemistry.eu +% -------------------------------------------------------------------------- +% Copyright 2011-2012 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 exsheets package consists of the files +% - exsheets.sty, exsheets_headings.def, exsheets_headings.cfg, +% exsheets_tasks.def, exsheets_tasks.cfg, exsheets_configurations.cfg, +% - exsheets_en.tex, exsheets_en.pdf, +% - README +% -------------------------------------------------------------------------- +% If you have any ideas, questions, suggestions or bugs to report, please +% feel free to contact me. +% -------------------------------------------------------------------------- +% TASKS: LIST-LIKE ENVIRONMENT +\ProvidesFile{exsheets_tasks.def} + [\exsheets@date\space v\exsheets@version\space ExSheets tasks object] + +\RequirePackage { epic } + +% variables: +\seq_new:N \l__exsheets_tasks_seq +\int_new:N \l__exsheets_tasks_depth_int +\int_new:N \l__exsheets_tasks_int +\int_new:N \l__exsheets_tasks_total_items_int +\int_new:N \l__exsheets_tasks_columns_int +\int_new:N \l__exsheets_tasks_rows_int +\bool_new:N \l__exsheets_tasks_enumerate_bool +\tl_new:N \l__exsheets_tasks_instance_tl +\tl_new:N \l__exsheets_tasks_label_tl +\tl_new:N \l__exsheets_tasks_label_pattern_tl +\tl_new:N \l__exsheets_tasks_custom_label_format_tl +\dim_new:N \l__exsheets_tasks_item_indent_dim +\dim_new:N \l__exsheets_tasks_after_item_skip_dim +\dim_new:N \l__exsheets_tasks_item_width_dim +\dim_new:N \l__exsheets_tasks_label_width_dim +\dim_new:N \l__exsheets_tasks_default_label_width_dim +\skip_new:N \l__exsheets_tasks_before_list_skip +\skip_set:Nn \l__exsheets_tasks_before_list_skip { .33\baselineskip } +\skip_new:N \l__exsheets_tasks_after_list_skip +\skip_new:N \l__exsheets_tasks_after_list_default_skip +\skip_set:Nn \l__exsheets_tasks_after_list_default_skip { .33\baselineskip } + +\NewCounterPattern* [ exsheets ] { task } { tsk } +\ReadCounterFrom [ exsheets ] { task } \l__exsheets_tasks_int + +% scratch coffins: +\cs_if_exist:NF \l__exsheets_tmpa_coffin { \coffin_new:N \l__exsheets_tmpa_coffin } +\cs_if_exist:NF \l__exsheets_tmpb_coffin { \coffin_new:N \l__exsheets_tmpb_coffin } +\cs_if_exist:NF \l__exsheets_tmpc_coffin { \coffin_new:N \l__exsheets_tmpc_coffin } + +% collect the tasks: +% #1: instance +% #2: number of columns +% #3: environment body +\cs_new:Npn \__exsheets_tasks:nnw #1#2#3 \end + { + \par \addvspace { \l__exsheets_tasks_before_list_skip } + \seq_set_split:Nnn \l__exsheets_tasks_seq { ; } { #3 } + % remove the last (empty) item: + \seq_pop_right:NN \l__exsheets_tasks_seq \l__exsheets_tmpa_tl + \tl_if_blank:VF \l__exsheets_tmpa_tl + { % TODO ERROR + } + \int_set:Nn \l__exsheets_tasks_total_items_int + { \seq_length:N \l__exsheets_tasks_seq } + \UseInstance { exsheets-tasks } { #1 } + { \l__exsheets_tasks_total_items_int } + { #2 } + { \l__exsheets_tasks_custom_label_format_tl } + % just to be sure: + \seq_clear:N \l__exsheets_tasks_seq + \par \skip_vertical:N \l__exsheets_tasks_after_list_skip + % we gobbled this from the input stream, let's put it back: + \end + } +\cs_generate_variant:Nn \__exsheets_tasks:nnw { V } + +\cs_new:Npn \__exsheets_task:nnw #1#2[#3,#4][#5,#6](#7,#8) + { + \dim_set:Nn \l__exsheets_tasks_item_width_dim + { + \linewidth / \l__exsheets_tasks_columns_int - + \l__exsheets_tasks_depth_int\l__exsheets_tasks_item_indent_dim + } + \int_incr:N \l__exsheets_tmpa_int + \__exsheets_tasks_set_rows_num:NN + \l__exsheets_tasks_total_items_int + \l__exsheets_tasks_columns_int + \int_compare:nT { \l__exsheets_tmpa_int > \l__exsheets_tasks_columns_int } + { \int_set:Nn \l__exsheets_tmpa_int { 1 } } + % the item: + \hcoffin_set:Nn \l__exsheets_tmpa_coffin + { + \vcoffin_set:Nnn \l__exsheets_tmpc_coffin + { \l__exsheets_tasks_item_width_dim } + { \__exsheets_tasks_setup: #2 } + \coffin_typeset:Nnnnn \l__exsheets_tmpc_coffin + { l } { b } { 0pt } { 0pt } + } + % the label: + \hcoffin_set:Nn \l__exsheets_tmpb_coffin { \strut #1 } + \coffin_attach:NnnNnnnn + \l__exsheets_tmpa_coffin { l } { t } + \l__exsheets_tmpb_coffin { l } { t } { -\l__exsheets_tasks_label_width_dim } { 0pt } + % typeset label & item: + % need this when a new row starts: + \int_compare:nT { \l__exsheets_tmpa_int = 1 } { \par\noindent } + \skip_horizontal:N \l__exsheets_tasks_item_indent_dim + \coffin_typeset:Nnnnn \l__exsheets_tmpa_coffin { l } { T } { 0pt } { 0pt } + % need this before a new row starts: + \int_compare:nT { \l__exsheets_tmpa_int = \l__exsheets_tasks_columns_int } + { \skip_vertical:N \l__exsheets_tasks_after_item_skip_dim } + \coffin_clear:N \l__exsheets_tmpa_coffin + \coffin_clear:N \l__exsheets_tmpb_coffin + \coffin_clear:N \l__exsheets_tmpc_coffin + } +\cs_generate_variant:Nn \__exsheets_task:nnw { VV } + +\cs_new:Npn \__exsheets_tasks_setup: + { + \dim_set:Nn \parskip { 0pt } + \noindent + \dim_set_eq:NN \parskip \parsep + \dim_set_eq:NN \parindent \listparindent + \strut + } + +\cs_new:Npn \__exsheets_tasks_set_rows_num:NN #1#2 + { + \int_set:Nn \l__exsheets_tasks_rows_int { \int_div_truncate:nn { #1 } { #2 } } + \int_compare:nNnT { \int_mod:nn { #1 } { #2 } } > { 0 } + { \int_incr:N \l__exsheets_tasks_rows_int } + } + +% the `exsheets-tasks' object: +% #1: number of items +% #2: number of columns +% #3: label-format +\DeclareObjectType { exsheets-tasks } { 3 } +% the `default' template interface: +\DeclareTemplateInterface { exsheets-tasks } { default } { 3 } + { + enumerate : boolean = true , + label : tokenlist , + indent : length = 2.5em , + label-format : tokenlist = tsk[a]) , + label-width : length = 3ex , + after-item-skip : length = 2ex + } +% the `default' template code: +\DeclareTemplateCode { exsheets-tasks } { default } { 3 } + { + enumerate = \l__exsheets_tasks_enumerate_bool , + label = \l__exsheets_tasks_label_tl , + indent = \l__exsheets_tasks_item_indent_dim , + label-format = \l__exsheets_tasks_label_pattern_tl , + label-width = \l__exsheets_tasks_default_label_width_dim , + after-item-skip = \l__exsheets_tasks_after_item_skip_dim + } + { + \AssignTemplateKeys + \skip_set:Nn \l__exsheets_tasks_after_list_skip + { + \l__exsheets_tasks_after_list_default_skip - + \l__exsheets_tasks_after_item_skip_dim + } + \dim_compare:nT { \l__exsheets_tasks_label_width_dim = 0pt } + { + \dim_set_eq:NN + \l__exsheets_tasks_label_width_dim + \l__exsheets_tasks_default_label_width_dim + } + % need this for enumerate list: + \int_zero:N \l__exsheets_tasks_int + \int_set:Nn \l__exsheets_tasks_columns_int { #2 } + % set all the items in their own coffins and join with the ground: + \int_zero:N \l__exsheets_tmpa_int + \tl_if_blank:VF \l__exsheets_tasks_custom_label_format_tl + { + \tl_set_eq:NN + \l__exsheets_tasks_label_pattern_tl + \l__exsheets_tasks_custom_label_format_tl + } + \seq_map_inline:Nn \l__exsheets_tasks_seq + { + \__exsheets_read_item:w ##1\task{}{}\q_stop + \bool_if:NTF \l__exsheets_tasks_enumerate_bool + { + \int_incr:N \l__exsheets_tasks_int + \tl_if_blank:VT \l__exsheets_tasks_label_tl + { + \tl_set:Nn \l__exsheets_tasks_label_tl + { + \ReadCounterPatternFrom [ exsheets ] + \l__exsheets_tasks_label_pattern_tl + } + } + } + { + \tl_if_blank:VT \l__exsheets_tasks_label_tl + { \tl_set_eq:NN \l__exsheets_tasks_label_tl \labelitemi } + } + \tl_if_blank:VTF \l__exsheets_tasks_tmp_label_tl + { + \__exsheets_task:VVw + \l__exsheets_tasks_label_tl + \l__exsheets_tasks_item_tl + [ l , b ] [ l , t ] ( 0pt , 0pt ) + } + { + \__exsheets_task:VVw + \l__exsheets_tasks_tmp_label_tl + \l__exsheets_tasks_item_tl + [ l , b ] [ l , t ] ( 0pt , 0pt ) + \tl_clear:N \l__exsheets_tasks_tmp_label_tl + } + } + } + +\tl_new:N \task +\tl_new:N \l__exsheets_tasks_item_tl +\tl_new:N \l__exsheets_tasks_tmp_label_tl + +\cs_new:Npn \__exsheets_read_item:w #1 \task #2#3 \q_stop + { + \tl_set:Nn \l__exsheets_tmpa_tl { #1 } + \tl_set:Nn \l__exsheets_tmpb_tl { #2 } + \tl_set:Nn \l__exsheets_tmpc_tl { #3 } + \tl_if_blank:VTF \l__exsheets_tmpa_tl + { + \tl_set_eq:NN \l__exsheets_tasks_item_tl \l__exsheets_tmpc_tl + \tl_set_eq:NN \l__exsheets_tasks_tmp_label_tl \l__exsheets_tmpb_tl + } + { \tl_set_eq:NN \l__exsheets_tasks_item_tl \l__exsheets_tmpa_tl } + } + +% choice box: +\bool_new:N \l__exsheets_choice_checked_bool +\dim_new:N \l__exsheets_choice_width_dim +\dim_set:Nn \l__exsheets_choice_width_dim { 1.25ex } +\dim_new:N \l__exsheets_choice_linewidth_dim +\dim_set:Nn \l__exsheets_choice_linewidth_dim { .3pt } +\dim_new:N \l__exsheets_choice_checkwidth_dim +\dim_set:Nn \l__exsheets_choice_checkwidth_dim { .5pt } +\dim_new:N \l__exsheets_choice_raise_dim +\dim_set:Nn \l__exsheets_choice_raise_dim { .1ex } + +\cs_new:Npn \exsheets_choice: + { + \leavevmode + \bool_set_false:N \l__exsheets_choice_checked_bool + \box_move_up:nn + { \l__exsheets_choice_raise_dim } + { \hbox:n { \__exsheets_choice: } } + } + +\cs_new:Npn \exsheets_choice_checked: + { + \leavevmode + \bool_set_true:N \l__exsheets_choice_checked_bool + \box_move_up:nn + { \l__exsheets_choice_raise_dim } + { \hbox:n { \__exsheets_choice: } } + } + +\cs_new:Npn \__exsheets_choice: + {% + \dim_set:Nn \unitlength { .1\l__exsheets_choice_width_dim } + \begin{picture}(10,0) + \linethickness \l__exsheets_choice_linewidth_dim + \drawline(0,0)(0,10)(10,10)(10,0)(0,0) + \linethickness \l__exsheets_choice_checkwidth_dim + \bool_if:NT \l__exsheets_choice_checked_bool + { + \drawline(2,2)(8,8) + \drawline(2,8)(8,2) + } + \end{picture}% + } + +\cs_if_exist:NF \choicebox + { \cs_new:Npn \choicebox { \exsheets_choice: } } +\cs_if_exist:NF \ckeckedchoicebox + { \cs_new:Npn \ckeckedchoicebox { \exsheets_choice_checked: } } + +% base instance: +% ALPHABETIZE: a) b) c) +\DeclareInstance { exsheets-tasks } { alphabetize } { default } { } + +\keys_define:nn { exsheets / tasks } + { + style .tl_set:N = \l__exsheets_tasks_instance_tl , + label .tl_set:N = \l__exsheets_tasks_custom_label_format_tl , + label-width .dim_set:N = \l__exsheets_tasks_label_width_dim , + before-skip .skip_set:N = \l__exsheets_tasks_before_list_skip , + after-skip .skip_set:N = \l__exsheets_tasks_after_list_skip + } + +% the user environment: +\NewDocumentEnvironment { tasks } { oG{1} } + { + \IfNoValueTF { #1 } + { \keys_set:nn { exsheets / tasks } { style = alphabetize } } + { + \keys_set:nn { exsheets / tasks } { #1 } + \tl_if_blank:VT \l__exsheets_tasks_instance_tl + { \keys_set:nn { exsheets / tasks } { style = alphabetize } } + } + \int_incr:N \l__exsheets_tasks_depth_int + \__exsheets_tasks:Vnw \l__exsheets_tasks_instance_tl { #2 } + } + { } + +\tex_endinput:D
\ No newline at end of file diff --git a/Master/texmf-dist/tex/latex/exsheets/translations.sty b/Master/texmf-dist/tex/latex/exsheets/translations.sty new file mode 100644 index 00000000000..208bc7295c1 --- /dev/null +++ b/Master/texmf-dist/tex/latex/exsheets/translations.sty @@ -0,0 +1,311 @@ +% -------------------------------------------------------------------------- +% the TRANSLATIONS package +% +% a simple translator +% +% This package is part of the exsheets bundle +% -------------------------------------------------------------------------- +% Clemens Niederberger +% Web: https://bitbucket.org/cgnieder/exsheets/ +% E-Mail: contact@mychemistry.eu +% -------------------------------------------------------------------------- +% Copyright 2012 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 translations package consists of the files +% - translations.sty +% -------------------------------------------------------------------------- +% If you have any ideas, questions, suggestions or bugs to report, please +% feel free to contact me. +% -------------------------------------------------------------------------- +\def\@trnslt@date{2012/10/08} +\def\@trnslt@version{v0.2b} + +\ProvidesPackage{translations}[\@trnslt@date\space \@trnslt@version\space a simple translator] +\RequirePackage{etoolbox} + +% -------------------------------------------------------------------------- +% message handling +\def\@trnslt@error@message{% + For details have a look at the `exsheets' manual.} + +\def\@trnslt@create@message#1{% + \ifstrequal{#1}{Error} + {% + \lowercase{\csdef{@trnslt@#1}}##1{% + \csuse{Package#1}{translations}{##1}{\@trnslt@error@message}}% + }{% + \lowercase{\csdef{@trnslt@#1}}##1{% + \csuse{Package#1}{translations}{##1}}% + }} +\@trnslt@create@message{Error} +\@trnslt@create@message{Warning} +\@trnslt@create@message{WarningNoLine} +\@trnslt@create@message{Info} + +\def\@trnslt@err@unknown@lang#1{% + \@trnslt@error{Unknown language `#1'}} + +\def\@trnslt@warn@unknown@lang#1{% + \@trnslt@warning{Unknown language `#1'}} + +\def\@trnslt@err@already@defined#1#2{% + \@trnslt@error{The #2 translation for `#1' is already defined.}} + +\def\@trnslt@err@not@defined#1#2{% + \@trnslt@error{The \@trnslt@language{#2} translation for `#1' is not defined yet.}} + +% -------------------------------------------------------------------------- +% check if babel or polyglossia is used +\AtEndPreamble{ + \@ifpackageloaded{babel}{}{ + \@ifpackageloaded{polyglossia}{} + {\@trnslt@warning{No language package found. I am going to use `english' + as default language.}} + } + \ifdef\languagename{} + {\def\languagename{english}} + \def\@trnslt@current@language{\languagename} + \ifdef\bbl@afterfi{} + {\long\def\bbl@afterfi#1\fi{\fi#1}} +} + +% -------------------------------------------------------------------------- +% \DeclareLanguage and \DeclareLanguageAlias +% #1: language +\newrobustcmd*\DeclareLanguage[1]{% + \@trnslt@declare@language{#1}} +\@onlypreamble\DeclareLanguage + +\def\@trnslt@declare@language#1{% + \csdef{@trnslt@language@#1}{#1}} + +% #1: alias +% #2: language +\newrobustcmd*\DeclareLanguageAlias[2]{% + \@trnslt@declare@languagealias{#1}{#2}} +\@onlypreamble\DeclareLanguageAlias + +\def\@trnslt@declare@languagealias#1#2{% + \ifcsdef{@trnslt@language@#2} + {}{% + \@trnslt@warn@unknown@lang{#2}% + \@trnslt@declare@language{#2}% + }% + \csletcs{@trnslt@language@#1}{@trnslt@language@#2}} + +\def\@trnslt@language#1{% + \csuse{@trnslt@language@#1}} + +% -------------------------------------------------------------------------- +% \DeclareTranslation, \NewTranslation and \RenewTranslation +% #1: language +% #2: word +% #3: replacement +\newrobustcmd*\DeclareTranslation[3]{% + \@trnslt@declare@translation{#2}{#1}{#3}} +\@onlypreamble\DeclareTranslation + +\def\@trnslt@declare@translation#1#2#3{% + \ifcsdef{@trnslt@language@#2} + {% + \csdef{@trnslt@word@#1@\@trnslt@language{#2}}{#3}% + \csdef{@trnslt@word@#1@literal}{#1}% + } + {\@trnslt@err@unknown@lang{#2}}} + +\def\@trnslt@if@translation#1#2{% + \ifcsdef{@trnslt@word@#1@\@trnslt@language{#2}} + {\expandafter\@firstoftwo} + {\expandafter\@secondoftwo}} + +\newrobustcmd*\NewTranslation[3]{% + \@trnslt@new@translation{#2}{#1}{#3}} +\@onlypreamble\NewTranslation + +\def\@trnslt@new@translation#1#2#3{% + \@trnslt@if@translation{#1}{#2} + {\@trnslt@err@already@defined{#1}{#2}} + {\@trnslt@declare@translation{#1}{#2}{#3}}} + +\newrobustcmd*\RenewTranslation[3]{% + \@trnslt@renew@translation{#2}{#1}{#3}} +\@onlypreamble\RenewTranslation + +\def\@trnslt@renew@translation#1#2#3{% + \@trnslt@if@translation{#1}{#2} + {\@trnslt@declare@translation{#1}{#2}{#3}} + {\@trnslt@err@not@defined{#1}{#2}}} + +% -------------------------------------------------------------------------- +% \GetTranslationFor and \GetTranslation +% these need to be expandable! +% #1: language +% #2: word +\newcommand*\GetTranslationFor[2]{% + \@trnslt@get@translation@for{#2}{#1}} + +\newcommand*\GetTranslation[1]{% + \@trnslt@get@translation@for{#1}{\@trnslt@current@language}} + +% #1: word #2: language +\def\@trnslt@get@translation@for#1#2{% + \@trnslt@if@translation{#1}{#2} + {\csuse{@trnslt@word@#1@\@trnslt@language{#2}}} + {% + \@trnslt@warning{Translation for `#1' in #2 unknown.}% + \csuse{@trnslt@word@#1@literal}% + }} + +% -------------------------------------------------------------------------- +% \SaveTranslationFor and \SaveTranslation +\newrobustcmd*\SaveTranslationFor[3]{% + \@trnslt@save@translation@for{#1}{#3}{#2}} + +\newrobustcmd*\SaveTranslation[2]{% + \@trnslt@save@translation@for{#1}{#2}{\@trnslt@current@language}} + +\def\@trnslt@save@translation@for#1#2#3{% + \edef#1{% + \@trnslt@if@translation{#2}{#3} + {\csuse{@trnslt@word@#2@\@trnslt@language{#3}}} + {}% + }} + +% -------------------------------------------------------------------------- +% \LoadDictionary and \LoadDictionaryFor +\newrobustcmd*\LoadDictionary[1]{% + \@trnslt@load@dictionary@for{#1}{\@trnslt@current@language}} +\@onlypreamble\LoadDictionary + +\newrobustcmd*\LoadDictionaryFor[2]{% + \@trnslt@load@dictionary@for{#1}{#2}} +\@onlypreamble\LoadDictionaryFor + +\def\@trnslt@load@dictionary@for#1#2{% + \AtBeginDocument{% + \InputIfFileExists{#1-\@trnslt@language{#2}.trsl} + {\@trnslt@info{loading dictionary `#1' for `#2'.}} + {\@trnslt@warning{File `#1-\@trnslt@language{#2}.trsl' not found.}}% + }} + +\newrobustcmd*\ProvideDictionaryFor[2]{% + \@trnslt@provide@dictionary@for{#1}{#2}} +\@onlypreamble\ProvideDictionaryFor + +\def\@trnslt@provide@dictionary@for#1#2{% + \def\@trnslt@dictionary@name{#2}% + \def\@trnslt@dictionary@lang{#1}% + \@ifnextchar[ + {\@trnslt@provide@dictionary@version} + {\ProvidesFile{#2-#1.trsl}[(#1 translation file `#2')]}} + +\def\@trnslt@provide@dictionary@version[#1]{% + \ProvidesFile + {\@trnslt@dictionary@name-\@trnslt@dictionary@lang.trsl}% + [(\@trnslt@dictionary@lang\space translation file `\@trnslt@dictionary@name') #1]} + +% -------------------------------------------------------------------------- +% predefined languages +\DeclareLanguage{albanian} +\DeclareLanguage{bulgarian} +\DeclareLanguage{catalan} +\DeclareLanguage{croatian} +\DeclareLanguage{czech} +\DeclareLanguage{danish} +\DeclareLanguage{dutch} +\DeclareLanguage{english} +\DeclareLanguage{finnish} +\DeclareLanguage{french} +\DeclareLanguage{german} +\DeclareLanguage{greek} +\DeclareLanguage{hebrew} +\DeclareLanguage{hungarian} +\DeclareLanguage{icelandic} +\DeclareLanguage{italian} +\DeclareLanguage{norwegian} +\DeclareLanguage{polish} +\DeclareLanguage{portuges} +\DeclareLanguage{romanian} +\DeclareLanguage{russian} +\DeclareLanguage{serbocroatian} +\DeclareLanguage{slovak} +\DeclareLanguage{slovenian} +\DeclareLanguage{spanish} +\DeclareLanguage{swedish} +\DeclareLanguage{turkish} +\DeclareLanguage{ukrainian} + +\DeclareLanguageAlias{Albanian}{albanian} +\DeclareLanguageAlias{Bulgarian}{bulgarian} +\DeclareLanguageAlias{Catalan}{catalan} +\DeclareLanguageAlias{Croatian}{croatian} +\DeclareLanguageAlias{Czech}{czech} +\DeclareLanguageAlias{Danish}{danish} +\DeclareLanguageAlias{Dutch}{dutch} +\DeclareLanguageAlias{Finnish}{finnish} +\DeclareLanguageAlias{francais}{french} +\DeclareLanguageAlias{Francais}{francais} +\DeclareLanguageAlias{canadien}{french} +\DeclareLanguageAlias{Canadien}{canadien} +\DeclareLanguageAlias{French}{french} +\DeclareLanguageAlias{american}{english} +\DeclareLanguageAlias{American}{american} +\DeclareLanguageAlias{australian}{english} +\DeclareLanguageAlias{Australian}{australian} +\DeclareLanguageAlias{british}{english} +\DeclareLanguageAlias{British}{british} +\DeclareLanguageAlias{canadian}{english} +\DeclareLanguageAlias{Canadian}{canadian} +\DeclareLanguageAlias{English}{english} +\DeclareLanguageAlias{UKenglish}{english} +\DeclareLanguageAlias{USenglish}{english} +\DeclareLanguageAlias{austrian}{german} +\DeclareLanguageAlias{Austrian}{austrian} +\DeclareLanguageAlias{German}{german} +\DeclareLanguageAlias{germanb}{german} +\DeclareLanguageAlias{naustrian}{austrian} +\DeclareLanguageAlias{ngerman}{german} +\DeclareLanguageAlias{Greek}{greek} +\DeclareLanguageAlias{polutonikogreek}{greek} +\DeclareLanguageAlias{Hebrew}{hebrew} +\DeclareLanguageAlias{Hungarian}{hungarian} +\DeclareLanguageAlias{magyar}{hungarian} +\DeclareLanguageAlias{Magyar}{magyar} +\DeclareLanguageAlias{Icelandic}{icelandic} +\DeclareLanguageAlias{Italian}{italian} +\DeclareLanguageAlias{norsk}{norwegian} +\DeclareLanguageAlias{Norsk}{norsk} +\DeclareLanguageAlias{Norwegian}{norwegian} +\DeclareLanguageAlias{nynorsk}{norwegian} +\DeclareLanguageAlias{Nynorsk}{nynorsk} +\DeclareLanguageAlias{Polish}{polish} +\DeclareLanguageAlias{brazil}{portuges} +\DeclareLanguageAlias{Brazil}{brazil} +\DeclareLanguageAlias{brazilian}{portuges} +\DeclareLanguageAlias{Brazilian}{brazilian} +\DeclareLanguageAlias{Portuges}{portuges} +\DeclareLanguageAlias{portuguese}{portuges} +\DeclareLanguageAlias{Portuguese}{portuguese} +\DeclareLanguageAlias{Romanian}{romanian} +\DeclareLanguageAlias{Russian}{russian} +\DeclareLanguageAlias{Serbocroatian}{serbocroatian} +\DeclareLanguageAlias{Slovak}{slovak} +\DeclareLanguageAlias{Slovenian}{slovenian} +\DeclareLanguageAlias{Spanish}{spanish} +\DeclareLanguageAlias{Swedish}{swedish} +\DeclareLanguageAlias{Turkish}{turkish} +\DeclareLanguageAlias{Ukrainian}{ukrainian} + +\endinput
\ No newline at end of file diff --git a/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc b/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc index bacfa596b7a..9a410e1d1bf 100644 --- a/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc +++ b/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc @@ -250,6 +250,7 @@ depend exercise depend exp-testopt depend expdlist depend export +depend exsheets depend extract depend facsimile depend fancynum diff --git a/Master/tlpkg/tlpsrc/exsheets.tlpsrc b/Master/tlpkg/tlpsrc/exsheets.tlpsrc new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/Master/tlpkg/tlpsrc/exsheets.tlpsrc |