diff options
author | Karl Berry <karl@freefriends.org> | 2018-09-25 20:25:41 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2018-09-25 20:25:41 +0000 |
commit | f357d5402f0a195a92c76d252e4ad5db974f8f9e (patch) | |
tree | 2c5367424fb4d1fe37ff462da8f9167f9a1167d8 /Master | |
parent | ea8edbcb109a90aa4a837df9f9e61ad88fb3ca0a (diff) |
exercisebank (25sep18)
git-svn-id: svn://tug.org/texlive/trunk@48757 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master')
-rw-r--r-- | Master/texmf-dist/doc/latex/exercisebank/README.txt | 2 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/exercisebank/example.zip | bin | 60293 -> 68564 bytes | |||
-rw-r--r-- | Master/texmf-dist/doc/latex/exercisebank/exercisebank-doc.pdf | bin | 223329 -> 241889 bytes | |||
-rw-r--r-- | Master/texmf-dist/doc/latex/exercisebank/exercisebank-doc.tex | 268 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/exercisebank/exercisebank.sty | 449 |
5 files changed, 553 insertions, 166 deletions
diff --git a/Master/texmf-dist/doc/latex/exercisebank/README.txt b/Master/texmf-dist/doc/latex/exercisebank/README.txt index 1f720685498..43f36657408 100644 --- a/Master/texmf-dist/doc/latex/exercisebank/README.txt +++ b/Master/texmf-dist/doc/latex/exercisebank/README.txt @@ -22,7 +22,7 @@ https://github.com/Strauman/exercisebank/ Licence: -The LaTeX package exercisebank - version v0.2.0 (2018/07/21) - build 75 +The LaTeX package exercisebank - version v0.2.1 (2018/09/24) - build 95 exercisebank.sty: Exercise bank ------------------------------------------------------------------------------------------- Copyright (c) 2018 by Andreas Storvik Strauman diff --git a/Master/texmf-dist/doc/latex/exercisebank/example.zip b/Master/texmf-dist/doc/latex/exercisebank/example.zip Binary files differindex 5bda00d48e2..f1920130228 100644 --- a/Master/texmf-dist/doc/latex/exercisebank/example.zip +++ b/Master/texmf-dist/doc/latex/exercisebank/example.zip diff --git a/Master/texmf-dist/doc/latex/exercisebank/exercisebank-doc.pdf b/Master/texmf-dist/doc/latex/exercisebank/exercisebank-doc.pdf Binary files differindex cbf2d7c44b6..3b927d6ca10 100644 --- a/Master/texmf-dist/doc/latex/exercisebank/exercisebank-doc.pdf +++ b/Master/texmf-dist/doc/latex/exercisebank/exercisebank-doc.pdf diff --git a/Master/texmf-dist/doc/latex/exercisebank/exercisebank-doc.tex b/Master/texmf-dist/doc/latex/exercisebank/exercisebank-doc.tex index 8897fb1d927..7208e61fd97 100644 --- a/Master/texmf-dist/doc/latex/exercisebank/exercisebank-doc.tex +++ b/Master/texmf-dist/doc/latex/exercisebank/exercisebank-doc.tex @@ -1,5 +1,5 @@ -%% exercisebank v0.2.0b75 - 2018/07/21 -%% The LaTeX package exercisebank - version v0.2.0 (2018/07/21) build 75 +%% exercisebank v0.2.1b95 - 2018/09/24 +%% The LaTeX package exercisebank - version v0.2.1 (2018/09/24) build 95 %% Manual/Documentation for exercisebank.sty %% ------------------------------------------------------------------------------------------- %% Copyright (c) 2018 by Andreas Storvik Strauman @@ -18,6 +18,7 @@ \usepackage{needspace} \usepackage{tabularx} \usepackage{geometry} +\usepackage{listofitems} \makeatletter \def\input@path{{../../docs/}} \lstdefinestyle{mydocumentation}{style=tcbdocumentation, @@ -45,7 +46,21 @@ drop fuzzy shadow,#1} \def\l@macro#1#2{#1\hfill\newline} \newcommand\macrotable{\hypersetup{linkcolor=black}\@starttoc{mac}\hypersetup{linkcolor=Definition}} -\newcommand\gh[1]{\href{#1}{https://github.com/#1}} +\newcommand\gh[1]{\href{https://github.com/#1}{@#1}} +\newcommand\ghURL[1]{\href{https://github.com/#1}{https://github.com/#1}} + +\providecommand\thankyous{\relax} +\def\print@thankyous{\readlist*\lst\thankyous\foreachitem\itm\in\lst{\if\itm\relax\else\item[-] \itm\fi}} +\providecommand\@thankyous@content{\relax} +\AtEndDocument{\write\@auxout{\string\gdef\string\thankyous{\@thankyous@content}}} +\gdef\thankyou#1{\g@addto@macro\@thankyous@content{#1,}} + +\providecommand\testers{} +\providecommand\@testers@content{} +\AtEndDocument{\write\@auxout{\string\gdef\string\testers{\@testers@content}}} +\gdef\tester#1{\g@addto@macro\@testers@content{#1\,}} + +\gdef\footxt#1{\protected@xdef\@thefnmark{}\@footnotetext{#1}} % --- CHANGELOG TABLE --- % \newcommand*\l@version[2]{% \ifnum \c@tocdepth >\z@ @@ -76,10 +91,15 @@ \renewcommand\tableofcontents{\hypersetup{linkcolor=black}\oldTOC\hypersetup{linkcolor=Definition}} \reversemarginpar \def\updated#1{\tcbdocmarginnote{\bfseries{\color{blue}U}#1}} -\def\defnew#1{\tcbdocmarginnote{\bfseries{\color{green}N}#1}} +\definecolor{green(munsell)}{rgb}{0.0, 0.70, 0.47} +\def\defnew#1{\tcbdocmarginnote{\bfseries{\color{green(munsell)}New:}#1}} -\let\dac\docAuxCommand -\def\mdac#1{\docAuxCommand{\expandafter\@gobble\string#1}} +\newcommand{\removebs}[1]{\if#1\@backslashchar\else#1\fi} +\begingroup\lccode`\|=`\\ +\lowercase{\endgroup\def\removebs#1{\if#1|\else#1\fi}} +\newcommand{\macroname}[1]{\expandafter\removebs\string#1} +\def\dac#1{\docAuxCommand{\macroname{#1}}} +\let\mdac\dac \makeatother @@ -99,13 +119,15 @@ \setlength{\parindent}{0pt} -\title{{exercisebank - manual\\ v0.2.0{\\[-0.5em]\footnotesize(build 75)}}} +\title{{exercisebank - manual\\ v0.2.1{\\[-0.5em]\footnotesize(build 95)}}} \author{Andreas Strauman} \begin{document} \maketitle -If you found any bugs or want new functionality, to contribute, view the commented source, get latest version of this package or get in touch with me, you can do all of that at\\\url{https://github.com/Strauman/exercisebank/}. If you have questions of functionality, kindly direct them to the community\\ \url{http://tex.stackexchange.com}. The author is active on this site regularly. - +If you found any bugs or want new functionality, to contribute, view the commented source, get latest version of this package or get in touch with me, you can do all of that at \url{https://github.com/Strauman/exercisebank/}. If you have questions of functionality, kindly direct them to the community\\ \url{http://tex.stackexchange.com}. The author is active on this site regularly. +If you feel up for it, you can always find the latest development version online, and I always need people to test -- it saves me a lot of time! +\if\thankyous\relax\else Special thanks to these contributors: \makeatletter\begin{itemize}\print@thankyous\end{itemize}\makeatother\fi +\if\testers\relax\else\footxt{People who helped test and make this package better (github users): \testers}\fi \tableofcontents \clearpage \section{Motivation} @@ -185,18 +207,18 @@ In \dac{makeset} you can just separate exercises with commas! Here is an example Let's say you have two files with exercises. One located in \texttt{exercises/circuits/RLC.tex} and one in \texttt{exercises/ohm/ohmsGeneralLaw.tex}, and you want to include partproblem 1 through 5 from \texttt{RLC.tex} and all of the exercises from \texttt{ohmsGeneralLaw.tex}. \begin{dispListing} -\makeset{\select{circuits/RLC}{1,...,5}, ohmsGeneralLaw} +\makeset{myExerciseSet}{\select{circuits/RLC}{1,...,5}, ohmsGeneralLaw} \end{dispListing} This will divide it up with problem headers. So that what is in the \texttt{RLC.tex}-file will be Problem 1, and \texttt{ohmsGeneralLaw.tex} Problem 2. \subsection{Mixnmatch} What if you want to make both of them the same exercise? Well, then you pass the [nohead] argument to \dac{makeset}: \begin{dispListing} -\makeset[nohead]{\phead, \select{circuits/RLC}{1,...,5}, ohmsGeneralLaw} +\makeset[nohead]{myExerciseSet}{\phead, \select{circuits/RLC}{1,...,5}, ohmsGeneralLaw} \end{dispListing} The \dac{phead} command makes a problem header. You can pass them as much as you want: \begin{dispListing} -\makeset[nohead]{\phead, \select{circuits/RLC}{1,...,5}, +\makeset[nohead]{myExerciseSet}{\phead, \select{circuits/RLC}{1,...,5}, ohmsGeneralLaw, \phead, someOtherExercise, moreExercises} \end{dispListing} @@ -252,6 +274,22 @@ the same as exercise is in. E.g. if you have a declared the option You can change the root dir by doing \\ \dac{exercisebanksetup}\brackets{\refKey{figure root directory}=figures}. See the \refKey{figure root directory} key for more info. +\subsection{Points and tags for exercises} +By default since version v0.2.1 there are now points and tags available through the \refCom{nextproblem} command.% +To assign a points to a part problem you'd do +\begin{dispListing} + \nextproblem{points=3,tag=difficult} + \begin{problem} + This problem is worth 3 points and has the `difficult' tag. + \end{problem} +\end{dispListing} +Then to build all exercises that has the `difficult' and e.g. the `easy' tag one would use the \refCom{buildtags} command. +\begin{dispListing} + \makeset{myExerciseSet}{ohmsGeneralLaw} + \buildtags{dificult,easy}{myExerciseSet} +\end{dispListing} + + That covers the basics. Enjoy \begin{marker} \dac{begin}\{problem\},\dac{end}\{problem\},\\ @@ -280,6 +318,28 @@ Inside the \dac{keyRef}\{exercise directory\}, you keep your exercises. Inside t Sometimes you'd want to introcude your exercises and tell a little bit about it. Maybe have a figure there also. Those things should go inside this environment. This can be treated as a problem in terms of counting. See \refCom{makeset} for more info. \end{docEnvironment} \filbreak\subsection{Making sets} +\begin{docCommand}{makesetdefaults}{\marg{nohead|intro}}\addcontentsline{toc}{subsubsection}{\refCom{makesetdefaults}} +\defnew{v0.2.1\\2018/09/24 } + Sets the default arguments to all makeset-keys. +e.g. +\begin{dispListing} +\makesetdefaults{intro} +\end{dispListing} +Will effectively make all +\begin{dispListing} +\makeset{...}{...} +\end{dispListing} +into +\begin{dispListing} +\makeset[intro]{...}{...} +\end{dispListing} +However, you can override this; +\begin{dispListing} +\makesetdefaults{intro} +\makeset[nointro]{...}{...} +\end{dispListing} +(the \oarg{nointro} overrides the default \meta{intro} setting) +\end{docCommand} \begin{docCommand}{spritesets}{\marg{setlist}}\addcontentsline{toc}{subsubsection}{\refCom{spritesets}} This is a command that is used by sprite to determine what sets are shown in sprite. If this is not given, sprite uses all sets given in \dac{makset} @@ -304,18 +364,25 @@ exercise, explaining short what the exercise is about. It's only visible when us inside one page. Defaults to 4 \begin{marker}If \dac{sprite} is used, it should be the only command in \dac{begin}\{document\}\dac{end}\{document\}\end{marker} \end{docCommand} -\begin{docCommand}{exclude}{\marg{exerciseFileName}\marg{Comma separated numbers}}\addcontentsline{toc}{subsubsection}{\refCom{exclude}} -\updated{v0.2.0\\2018/07/21 } -As you can see in the intro section of the documentation, this is for excluding partproblems -To be used in \refCom{makeset} -\end{docCommand} -\begin{docCommand}{select}{\marg{exerciseFileName}\marg{Comma separated numbers}}\addcontentsline{toc}{subsubsection}{\refCom{select}} -\updated{v0.2.0\\2018/07/21 } -As you can see in the intro section of the documentation, this is for cherry picking partproblems -To be used in \refCom{makeset} +\begin{docCommand}{exec}{\marg{macros}}\addcontentsline{toc}{subsubsection}{\refCom{exec}} +\updated{v0.2.1\\2018/09/24 } +You can use this in \dac{makeset} to execute commands between problems. +E.g. to insert a new page in between two problems when using nohead: +\begin{dispListing} +\makeset[nohead]{2}{\phead,my/exercise,\exec{\clearpage},next/exercise} +\end{dispListing} \end{docCommand} -\begin{docCommand}{DeclareExerciseCommand}{\marg{\dac{command}}\marg{actions}}\addcontentsline{toc}{subsubsection}{\refCom{DeclareExerciseCommand}} -\defnew{v0.2.0\\2018/07/21 } +\begin{docCommand}{DeclareExerciseCommand}{\marg{command}\oarg{numargs}\marg{actions}}\addcontentsline{toc}{subsubsection}{\refCom{DeclareExerciseCommand}} +\updated{v0.2.1\\2018/09/24 } +Now, use similar to newcommand. Does not support default arguments yet, but plans to. +The old way of defining still works: +\begin{dispListing} +\DelcareExerciseCommand{\pbreak}\brackets{\clearpage} +\end{dispListing} +and +\begin{dispListing} +\DelcareExerciseCommand{\ptitle}[1]\brackets{\Large\textbf{#1}} +\end{dispListing} This can be used later in makesets. E.g. \dac{DelcareExerciseCommand}\{\dac{pbreak}\}\brackets{\dac{clearpage}} will make \dac{pbreak} behave like \dac{clearpage} in the set: @@ -328,12 +395,27 @@ This can be used later in makesets. E.g. } \end{dispListing} \end{docCommand} -\begin{docCommand}{exec}{\marg{macros}}\addcontentsline{toc}{subsubsection}{\refCom{exec}} +\begin{docCommand}{exclude}{\marg{exerciseFileName}\marg{Comma separated numbers}}\addcontentsline{toc}{subsubsection}{\refCom{exclude}} \updated{v0.2.0\\2018/07/21 } -You can use this in \dac{makeset} to execute commands between problems. -E.g. to insert a new page in between two problems when using nohead: +As you can see in the intro section of the documentation, this is for excluding partproblems +To be used in \refCom{makeset} +\end{docCommand} +\begin{docCommand}{select}{\marg{exerciseFileName}\marg{Comma separated numbers}}\addcontentsline{toc}{subsubsection}{\refCom{select}} +\updated{v0.2.0\\2018/07/21 } +As you can see in the intro section of the documentation, this is for cherry picking partproblems +To be used in \refCom{makeset} +\end{docCommand} +\begin{docCommand}{orderedselect}{}\addcontentsline{toc}{subsubsection}{\refCom{orderedselect}} +\defnew{v0.2.1\\2018/09/24 } +\end{docCommand} +\begin{docCommand}{buildset}{\oarg{intro|nohead|nointro}\marg{setname}}\addcontentsline{toc}{subsubsection}{\refCom{buildset}} +\updated{v0.2.1\\2018/09/24 } +This command runs the set given. The set has do be defined by \dac{makeset}. E.eg \begin{dispListing} -\makeset[nohead]{2}{\phead,my/exercise,\exec{\clearpage},next/exercise} +\makeset{myExerciseSet}{exercisefile1, \select{exercisefile2}{1,2}} +\!begin{document} + \buildset{myExerciseSet} +\!end{document} \end{dispListing} \end{docCommand} \begin{docCommand}{setName}{}\addcontentsline{toc}{subsubsection}{\refCom{setName}} @@ -351,13 +433,20 @@ The following example prints "Exercise set number 1" and "Exercise set number 2" \end{document} \end{dispListing} \end{docCommand} -\begin{docCommand}{buildsets}{\marg{list}}\addcontentsline{toc}{subsubsection}{\refCom{buildsets}} -\defnew{v0.2.0\\2018/07/21 } +\begin{docCommand}{buildsets}{\oarg{intro|nohead|nointro}\marg{list}}\addcontentsline{toc}{subsubsection}{\refCom{buildsets}} +\updated{v0.2.1\\2018/09/24 } This command will generate multiple sets: \begin{dispListing} \buildsets{set,set2,set3} \end{dispListing} \end{docCommand} +\begin{docCommand}{buildtags}{\marg{tagslist}\marg{setslist}}\addcontentsline{toc}{subsubsection}{\refCom{buildtags}} +\defnew{v0.2.1\\2018/09/24 } +This command will generate multiple sets: +\begin{dispListing} +\buildsets{tag,tag2,tag3}{set,set2,set3} +\end{dispListing} +\end{docCommand} \begin{docCommand}{pplabel}{\marg{label}}\addcontentsline{toc}{subsubsection}{\refCom{pplabel}} Labels a partproblem. You can reference to it later using \dac{ppref}\{\meta{label\}} @@ -370,16 +459,28 @@ Reference a partproblem created by \dac{pplabel}\{\meta{label\}}. This prints e. Reference a partproblem created by \dac{pplabel}\{\meta{label\}}. This prints e.g. 1 \end{docCommand} +\begin{docCommand}{HideTags}{\marg{list}}\addcontentsline{toc}{subsubsection}{\refCom{HideTags}} +\defnew{v0.2.1\\2018/09/24 } +Hide all exercises containing the list of tags when building a set. +\end{docCommand} \filbreak\subsection{Configuration and options} You can do a lot of configurations on this package, and probably even more to come in later versions! \begin{docCommand}{ShowNumbers}{}\addcontentsline{toc}{subsubsection}{\refCom{ShowNumbers}} -\updated{v0.2.0\\2018/07/21 } +\updated{v0.2.1\\2018/09/24 } Shows the numbers in fron of the part problems and intros that should be used with \dac{exclude} and \dac{select} \end{docCommand} -\begin{docCommand}{exercisebanksetup}{\marg{[key/values]}}\addcontentsline{toc}{subsubsection}{\refCom{exercisebanksetup}} -\updated{v0.2.0\\2018/07/21 } +\begin{docCommand}{ShowTags}{}\addcontentsline{toc}{subsubsection}{\refCom{ShowTags}} +\defnew{v0.2.1\\2018/09/24 } + Shows the tags in front of the part problems much like \dac{ShowNumbers} +\end{docCommand} +\begin{docCommand}{ShowFilenames}{}\addcontentsline{toc}{subsubsection}{\refCom{ShowFilenames}} +\defnew{v0.2.1\\2018/09/24 } + Shows the path+filename to the current exercise file +\end{docCommand} +\begin{docCommand}{exercisebanksetup}{\marg{\oarg{key/values}}}\addcontentsline{toc}{subsubsection}{\refCom{exercisebanksetup}} +\updated{v0.2.1\\2018/09/24 } Here is a list of the different keys and their meaning \keyDef{part problems}{On/Off}{On}{ This is whether or not to do part problems. E.g. 1a), 1b) etc. @@ -395,12 +496,23 @@ You can do a lot of configurations on this package, and probably Defaults to\\ \brackets{\dac{normalfont}\dac{Large}\dac{bfseries}\dac{@tr}\{Problem\}~\dac{theproblemcounter}}. } +\keyDef{problem needs space}{dimension}{0.2\dac{pageheight}}{ +How much space has to be left on the page for a problem to start +} +\keyDef{no needspace}{bool}{false}{ +Don't use \dac{needspace} command (only used in \refKey{problem needs space}) +} \keyDef{part problem header}{macro}{see below}{ This sets the problem header. To access the current problem, use \dac{theproblemcounter}, and then the current part problem \dac{thepartproblemcounter}. To make it a letter, as per default use \dac{alph}\{partproblemcounter\}\\ Default is:\\ \dac{large}\dac{textbf}\{(\dac{theproblemcounter}\dac{alph}{partproblemcounter\})} } +\keyDef{part problem header suffix}{macro}{\meta{empty}}{ + This sets the suffix problem header, and defaults to be the number of points + the current exercise is worth. + Default is \meta{empty} +} \keyDef{solution header}{string}{see below}{ \dac{large}\{\dac{textbf}{\dac{@tr}\brackets{Solution:\}}} \dac{@tr} is the translation macro @@ -442,6 +554,16 @@ Where to load the front page. The commands \refCom{setName} is available. Whether or not to put problem headers and part problem headers out in the margins. } \end{docCommand} +\keyDef{current points style}{style}{see below}{ + This is how the points will be shown in the part problem headers. + the default code is by \gh{thorstengrote} + \texttt{~\dac{ifnum}\dac{exb@currentPoints}=\dac{z@}\dac{ifnum}\dac{totalpoints}=\dac{z@}\dac{else}\dac{phantom}\{0p\}\dac{fi}\dac{else}\dac{exb@currentPoints} p\dac{fi}~\dac{ignorespaces}} +} +\keyDef{disable points}{bool}{false}{ + Whether or not to disable the point system. +} + + \filbreak\subsection{Internationalization} \begin{docCommand}{translateExBank}{\marg{Translation key/vals}}\addcontentsline{toc}{subsubsection}{\refCom{translateExBank}} @@ -455,11 +577,58 @@ The Norwegian translation would then be done with \translateExBank{Problem=Oppgave, Solution=Løsning} \end{dispListing} \end{docCommand} +\filbreak\subsection{Problem options and tagging} +\begin{docCommand}{nextproblem}{}\addcontentsline{toc}{subsubsection}{\refCom{nextproblem}} +\defnew{v0.2.1\\2018/09/24 } +Prior to a problem environment in an exercise file you can pass options +using the \dac{nextproblem} command. If you e.g. wanted to hide one regardless +of what set it is you'd do +\begin{dispListing} +\nextproblem{hide} +\begin{problem} + This problem will be hidden because of the \nextproblem command +\end{problem} +\end{dispListing} +you can also tag problems using this: +\begin{dispListing} +\nextproblem{tag=hard} +\begin{problem} + This problem is hard +\end{problem} +\nextproblem{tag=hard} +\begin{problem} + This problem is also hard +\end{problem} +\nextproblem{tag=easy} +\begin{problem} + This problem is easy +\end{problem} +\end{dispListing} + And you could now build, say, only easy problems using +\dac{buildtags}\{hard\}\{SETNAME\}, where SETNAME is chosen by a +\dac{makeset} command. +\end{docCommand} + You can also have multiple tags per exercise +\begin{dispListing} +\nextproblem{tag={tag1,tag2}} +\begin{problem} + This problem is easy +\end{problem} +\end{dispListing} +Here are the \dac{nextproblem} keys: +\keyDef{points}{number}{0}{ + The number of points the next exercise is worth. + you can retrieve the total points using \dac{totalpoints} +} + + \filbreak\subsection{Triggers} \begin{docCommand}{Trigger}{\marg{Any Macro}}\addcontentsline{toc}{subsubsection}{\refCom{Trigger}} -\updated{v0.1.3\\2018/04/20 } +\updated{v0.2.1\\2018/09/24 } See \refCom{At}\\ Available triggers:\\ +\dac{Trigger}\dac{PartProblemHeaderSuffix}:\\ Triggers after the part problem header. + anything added to this trigger will happen within the header \dac{Trigger}\dac{BeginPartproblem}:\\ Triggers before a partproblem is inserted\\ \dac{Trigger}\dac{VeryBeginPartproblem}:\\ Triggers right after \dac{BeginPartproblem}. This is so that the user can do stuff before the actual headers start. The partproblem headers are invoked by \dac{At}\dac{VeryBeginPartproblem}\\ \dac{Trigger}\dac{InputExercise}:\\ Triggers before a file is included\\\ @@ -482,16 +651,16 @@ This is to annoy the user enough to get his attention about the requirements of This is the directory, relative to the file you included the package, where the package should be looking for exercises. Default is the same directory as your main file (the one you build). \end{docCommand} -\begin{docCommand}{isin}{\marg{haystack}\marg{needle}\marg{True}\marg{False}}\addcontentsline{toc}{subsubsection}{\refCom{isin}} +\begin{docCommand}{exb@isin}{\marg{haystack}\marg{needle}\marg{True}\marg{False}}\addcontentsline{toc}{subsubsection}{\refCom{exb@isin}} - \meta{haystack} is a comma separated list of integers\\ + \meta{haystack} is a comma separated list of anything\\ \meta{needle} is an integer\\ Executes \meta{True} if \meta{needle} is found in \meta{haystack} else executes \meta{False} \end{docCommand} This package also includes some extra stuff. For example the \dac{At} and \dac{Trigger} \begin{docCommand}{At}{\marg{AnyMacro}} -\updated{v0.1.3\\2018/04/20 }Here you can send any macro because it isn't evaluated! For example \dac{At}\dac{BeginSomething} is fine and even if \dac{BeginSomething} is not defined. Also and when using \dac{Trigger} it just ignores it if it didn't exist. It's pretty similar in function as to \dac{AtBeginDocument}. +\updated{v0.2.1\\2018/09/24 }Here you can send any macro because it isn't evaluated! For example \dac{At}\dac{BeginSomething} is fine and even if \dac{BeginSomething} is not defined. Also and when using \dac{Trigger} it just ignores it if it didn't exist. It's pretty similar in function as to \dac{AtBeginDocument}. \begin{dispListing} \At\BeginSomething{DoSomething} Which is triggered with @@ -544,17 +713,25 @@ Distance above Problem \# header \addcontentsline{mac}{macro}{\refCom{At}}{} \addcontentsline{mac}{macro}{\refCom{DeclareExerciseCommand}}{} \addcontentsline{mac}{macro}{\refCom{DisplaySolutions}}{} +\addcontentsline{mac}{macro}{\refCom{HideTags}}{} +\addcontentsline{mac}{macro}{\refCom{ShowFilenames}}{} \addcontentsline{mac}{macro}{\refCom{ShowNumbers}}{} +\addcontentsline{mac}{macro}{\refCom{ShowTags}}{} \addcontentsline{mac}{macro}{\refCom{Trigger}}{} \addcontentsline{mac}{macro}{\refCom{about}}{} +\addcontentsline{mac}{macro}{\refCom{buildset}}{} \addcontentsline{mac}{macro}{\refCom{buildsets}}{} +\addcontentsline{mac}{macro}{\refCom{buildtags}}{} +\addcontentsline{mac}{macro}{\refCom{exb@isin}}{} \addcontentsline{mac}{macro}{\refCom{exclude}}{} \addcontentsline{mac}{macro}{\refCom{exec}}{} \addcontentsline{mac}{macro}{\refCom{exerciseFile}}{} \addcontentsline{mac}{macro}{\refCom{exercisebanksetup}}{} \addcontentsline{mac}{macro}{\refCom{introMargin}}{} -\addcontentsline{mac}{macro}{\refCom{isin}}{} \addcontentsline{mac}{macro}{\refCom{makeset}}{} +\addcontentsline{mac}{macro}{\refCom{makesetdefaults}}{} +\addcontentsline{mac}{macro}{\refCom{nextproblem}}{} +\addcontentsline{mac}{macro}{\refCom{orderedselect}}{} \addcontentsline{mac}{macro}{\refCom{ownLineNoSpacesGotIt}}{} \addcontentsline{mac}{macro}{\refCom{pMarginAbove}}{} \addcontentsline{mac}{macro}{\refCom{pMarginBelow}}{} @@ -627,5 +804,22 @@ Distance above Problem \# header \change{Introducing \refCom{buildsets}-command for building more than one set at a time.} \change{Ability to add front page with the \refKey{front page} setup-key.} \change{You can now remove the forced margin setup with \refKey{style margins}.} +\newversion{v0.2.1 2018/09/24} + \change{Added options for individual part problems using the \dac{nextproblem}-command} + \change{Added tagging for part problems using using the \dac{nextproblem}-command and \dac{buildtags}-commands.} + \change{Fixed problems related to \dac{ShowNumbers} not showing correctly.} + \change{Fixed \dac{exec} so that it now can take paragraphs (made it \dac{long})} + \change{Added point system} + \change{Fixed bug where vertical space would remain when intro environment hidden} + \change{\dac\DeclareExerciseCommand~now takes args} + \change{Keys sent to \dac\makeset can now be sent to \dac\buildset~and~\dac\buildsets} + \change{Introducing \dac\makesetdefaults} \chlogtable + + +% Testers and thanks +\thankyou{\gh{tristelune1} -- \ghURL{tristelune1} for help with testing and bug-reporting the current version (0.2.1)} +\thankyou{\gh{thorstengrothe} -- \ghURL{thorstengrothe} for help with testing and bug-reporting the current version (0.2.1)} +% \tester{\gh{thorstengrothe}} +% \tester{\gh{tristelune1}} \end{document} diff --git a/Master/texmf-dist/tex/latex/exercisebank/exercisebank.sty b/Master/texmf-dist/tex/latex/exercisebank/exercisebank.sty index 3ad71d95aff..fec5d392ed3 100644 --- a/Master/texmf-dist/tex/latex/exercisebank/exercisebank.sty +++ b/Master/texmf-dist/tex/latex/exercisebank/exercisebank.sty @@ -1,5 +1,5 @@ % Source (with comments) can be found at https://github.com/Strauman/exercisebank/ -%% The LaTeX package exercisebank - version v0.2.0 (2018/07/21) - build 75 +%% The LaTeX package exercisebank - version v0.2.1 (2018/09/24) - build 95 %% exercisebank.sty: Exercise bank %% ------------------------------------------------------------------------------------------- %% Copyright (c) 2018 by Andreas Storvik Strauman <andreas dot s dot strauman at uit dot no> @@ -13,9 +13,10 @@ %% version 2008/05/04 or later. %% This work has the LPPL maintenance status `author-maintained'. %% This work consists of all files listed in README -\ProvidesPackage{exercisebank}[2018/07/21 v0.2.0 Creates a setup that gives freedom in making sets and exercises.] +\ProvidesPackage{exercisebank}[2018/09/24 v0.2.1 Creates a setup that gives freedom in making sets and exercises.] \xdef\exbank@quiet{1} -\PackageWarningNoLine{exercisebank-v0.2.0}{This package is in the beta stage, and if something unexpected happens please, oh pretty please, report it to https://github.com/Strauman/exercisebank. Thank you!} +\def\exercisebankversion{v0.2.1 - Build 95} +\PackageWarningNoLine{exercisebank-v0.2.1}{This package is in the beta stage, and if something unexpected happens please, oh pretty please, report it to https://github.com/Strauman/exercisebank. Thank you!} \@ifundefined{ownLineNoSpacesGotIt}{\@latex@warning{Compilation wont work unless \string\end{problem} and \string\end{solution} are on their own lines and without any spaces. This warning can be removed by doing \string\def\string\ownLineNoSpacesGotIt{} before \@backslashchar usepackage{exercisebank}} }{} \gdef\setExercisesDir#1{\@latex@error{\string\setExercisesDir is deprecated. Use \string\exercisebanksetup{exercise directory=#1} instead}{}\stop\bye @@ -35,28 +36,52 @@ \usepackage{needspace} \edef\@isTrue{1} \edef\@isFalse{0} -\gdef\isin#1#2#3#4{ \def\needle{#2} - \def\haystack{#1} - \def\isFalse{0} - \let\isInList = \isFalse - \IfInteger{\needle}{}{\@latex@error{ISIN: Can't look for part problem that is not numeric!}{}\bye\stop} - \IfInteger{\haystack}{ \ifnum\haystack=\needle\relax - #3 - \else - #4 - \fi -}{ \foreach\pp in #1{ \ifnum\pp=\needle\relax% - \gdef\isInList{1} - #3 - \fi -} - \if\isInList\isFalse - #4 - \fi -} +\gdef\exb@int@isin#1#2#3#4{% + \def\needle{#1} + \def\haystack{#2} + \ifx\haystack\empty\relax#4\else% + \def\isFalse{0}% + \let\isInList = \isFalse% + \IfInteger{\needle}{}{\@latex@error{ISIN: Can't look for part problem that is not numeric: `\needle' in `\haystack'!}{}\bye\stop}% + \IfInteger{\haystack}{ \ifnum\haystack=\needle\relax% + #3% + \else% + #4% + \fi% +}{ \foreach\pp in #2{% + \ifnum\pp=\needle\relax% + \gdef\isInList{1}% + #3% + \fi% +}% + \if\isInList\isFalse% + #4% + \fi% +}% + \fi} +\gdef\exb@warn{\PackageWarningNoLine{exercisebank-v0.2.1}} +\gdef\exb@err#1{\PackageError{exercisebank}{#1}{}} +\newif\ifexb@isInList +\newcounter{exb@isin@dots} +\gdef\exb@isin#1#2#3#4{\@dinfo{running isin} + \global\exb@isInListfalse + \xdef\needle{#1} + \xdef\haystack{#2} + \def\whenfalse{#4} + \def\whentrue{#3} + \ifx\haystack\empty\relax#4\else% + \readlist*\items\haystack% + \foreachitem\itm\in\items{% + \ifnum\pdfstrcmp{\needle}{\itm}=\z@\relax% + \global\exb@isInListtrue% + #3\fi% +}% + \ifexb@isInList\else% + #4 + \fi\fi% } \gdef\strif#1#2{% - \ifnum\pdfstrcmp{#1}{#2}=\z@\relax% + \ifnum\pdfstrcmp{#1}{#2}=\z@\relax% } \let\ea = \expandafter \begingroup\lccode`\|=`\\ @@ -64,36 +89,86 @@ \gdef\exbank@macroname#1{\expandafter\removebs\string#1} \gdef\@noneofone#1{} \gdef\@noneoftwo#1#2{} -\@ifundefined{exbank@quiet}{ \global\let\@dlog\@latex@warning -}{ \global\let\@dlog\@noneofone +{\globaldefs=1\newcommand\@opt@gobble[2][]{}} +\@ifundefined{exbank@verbose}{ \global\let\@dinfo\@gobble + \global\let\@dinfomode\@opt@gobble +}{ \bgroup + \globaldefs=1\newcommand\@dinfo[2][]{% + \@latex@warning{--INFO:#2}% +}% + \egroup% +} +\@ifundefined{exbank@quiet}{ \gdef\@dlog#1{\@latex@warning{::DEBUG:#1}}% +}{ \global\let\@dlog\@noneofone% } -\newcommand\ex@before[2]{\edef #1{\unexpanded{#2}\unexpanded\expandafter{#1}} +\gdef\shownextchar#1{\@latex@warning{NEXT:\string#1}#1} +\newcommand\ex@before[2]{ \edef #1{\unexpanded{#2}\unexpanded\expandafter{#1}} } \newcommand{\exb@lmargin}[2]{\strut\vadjust{\exb@domark{#1}{#2}}} \newcommand{\exb@domark}[2]{% - \hbox to #2{ \vbox to 0pt{ \kern-\dp\strutbox - \smash{\llap{#1}} - \vss + \hbox to #2{ \vbox to 0pt{ \kern-\dp\strutbox + \smash{\llap{#1}} + \vss }% } } +\newif\ifexb@isintersection +\def\exb@intersection@any#1#2#3#4{% + \global\exb@isintersectionfalse% + \edef\listarg{#1}% + \ifx\listarg\empty\@dlog{RELAX}#4\else% + \readlist*\needlelist{#1}% + \foreachitem\needle\in\needlelist{% + \exb@isin{\needle}{#2}{\global\exb@isintersectiontrue}{}% +}% + \ifexb@isintersection#3\else#4\fi% + \fi% +} +\gdef\@makespacesignored{% +\global\let\@oldtilde~% +\gdef~{}% +\global\catcode`\^^M=9\relax% +\global\catcode`\^^J=9\relax% +\global\catcode`\ =9\relax% +} +\gdef\@makespacesnormal{% +\global\let~\@oldtilde% +\global\catcode`\^^M=5\relax% +\global\catcode`\^^J=12\relax% +\global\catcode`\ =10\relax% +} +\let\nextPar\everypar +\newtoks\everypar +\nextPar{\the\everypar} +\def\AtNextPar#1{\nextPar\expandafter{\the\nextPar\nextPar{\the\everypar}#1}} \edef\@isTrue{1} \edef\@isFalse{0} \gdef\ShowNumbers{\gdef\@displayMetaCounter{\isTrue}} +\gdef\exb@showtags{\isFalse} +\gdef\ShowTags{\gdef\exb@showtags{\isTrue}} +\gdef\exb@printCurrentTags{Tags: \exb@currentTags~} +\gdef\ShowFilenames{\At\VeryBeginProblem{\exerciseFile\\}} \gdef\@DisplaySolutions{\@isFalse} \gdef\DisplaySolutions{\xdef\@DisplaySolutions{\isTrue}\@latex@warning{Showing solutions}} +\gdef\ifDisplaySolutions{\if\@DisplaySolutions\@isTrue} \gdef\@SolutionsOnly{\@isFalse} \gdef\SolutionsOnly{\xdef\@SolutionsOnly{\@isTrue}\DisplaySolutions} +\gdef\exb@currentPoints{0} +\newif\ifexbank@if@needspace +\global\exbank@if@needspacetrue \pgfkeys{/exbanksetup/.is family, /exbanksetup, default/.style = { part problems = On, tighten paragraphs = True, problem header={\normalsize\Large\bfseries\@tr{Problem}~\theproblemcounter}, part problem header={\large\textbf{(\theproblemcounter\alph{partproblemcounter})}}, + part problem header suffix={}, solution header={\large{\textbf{\@tr{Solution}:}}}, exercise directory=., figure root directory=\@exercisesDir, style margins=On, - problem needs space=0.2\paperheight + problem needs space=0.2\paperheight, + no needspace/.is if={exbank@if@needspace}, + no needspace/.default = false }, exercise directory/.estore in = \@exercisesDir, % figure root directory/.estore in = \@figrootDir, % @@ -103,6 +178,7 @@ problem header/.store in = \exbank@opt@problemHeader, part problem header/.store in = \exbank@opt@partProblemHeader, solution header/.store in = \exbank@opt@solutionHeader, problem needs space/.store in = \exbank@opt@problemneedspace, +part problem header suffix/.store in=\exb@partproblem@header@suffix, part problems/.style = {switches/#1/.get = \exbank@opt@partProblems}, tighten paragraphs/.style = {switches/#1/.get = \exbank@opt@tightenparagraphs}, style margins/.style={switches/#1/.get = \exbank@opt@doMargins}, @@ -155,18 +231,25 @@ switches/.cd, \let\ea = \expandafter \begingroup\lccode`\|=`\\ \lowercase{\endgroup\def\removebs#1{\if#1|\else#1\fi}} -\newcommand{\At}[2]{ \edef\mname{\exbank@macroname{#1}} - \ifcsname At@\mname\endcsname - \ea\g@addto@macro\csname At@\mname\endcsname{#2} - \else - \ea\gdef\csname At@\mname\endcsname{#2} - \AtEndDocument{ \expandafter\let\csname At@\mname\endcsname\relax +\ifcsname at@verbose\endcsname +\global\def\@triggerLog#1{\@latex@warning{--\string\TRIGGER: #1}}% +\else +\global\let\@triggerLog\@gobble% +\fi +\newcommand{\At}[2]{ \edef\mname{\exbank@macroname{#1}}% + \ifcsname At@\mname\endcsname% + \ea\g@addto@macro\csname At@\mname\endcsname{#2}% + \else% + \ea\gdef\csname At@\mname\endcsname{#2}% + \AtEndDocument{% + \expandafter\let\csname At@\mname\endcsname\relax% } - \fi + \fi% } -\newcommand{\Trigger}[1]{ \edef\mname{\exbank@macroname{#1}} +\newcommand{\Trigger}[1]{% + \edef\mname{\exbank@macroname{#1}}% \ea\@ifundefined{At@\mname}{}{% - \csname At@\mname\endcsname% + \@triggerLog{\mname}\csname At@\mname\endcsname% }% } \xdef\figuresPath{\@figrootDir/} @@ -180,7 +263,6 @@ switches/.cd, \xdef\fileInputPath{\figuresPath\filename@area} \xdef\fileInputBase{\figuresPath\filename@area\filename@base/} \graphicspath{{\fileInputBase}{\fileInputPath}} - \@dlog{\fileInputBase} \@ifundefined{input@path}{\gdef\input@path{{\fileInputBase}{\fileInputPath}}}{} } \newlength{\pMarginBelow} @@ -214,7 +296,7 @@ switches/.cd, \newcounter{partproblemcounter} \At\VeryBeginProblem{% \if\exbank@opt@tightenparagraphs\@isTrue\relax% - \needspace{\exbank@opt@problemneedspace}% + \ifexbank@if@needspace\needspace{\exbank@opt@problemneedspace}\fi% \vskip-2\baselineskip\relax% \fi% \stepcounter{problemcounter}% @@ -225,24 +307,42 @@ switches/.cd, } \At\EndProblem{% \tighten@paragraph% -} +}% \At\VeryBeginPartproblem{% +\@dinfo{Triggered Beginning Part Problem (\string\VeryBeginPartproblem)}% \stepcounter{partproblemcounter}% - \bgroup% + \@dinfo{Generating title for part problem}% + \gdef\exb@prePPHead{}% + \gdef\exb@postPPHead{}% \if\@displayMetaCounter\@isTrue\relax% - \ex@before\exbank@opt@partProblemHeader{{\Large\themetacounter}:}% + \gdef\exb@prePPHead{{\Large\themetacounter}:}% + \fi% + \if\exb@showtags\isTrue% + \gdef\exb@postPPHead{\exb@printCurrentTags}% \fi% -\if\exbank@opt@doMargins\@isTrue\relax% -\leavevmode\smash{\llap{{\exbank@opt@partProblemHeader}\hskip\ppMargin}}% -\else{\exbank@opt@partProblemHeader}\fi% +\ifnum\pdfstrcmp{\exbank@opt@doMargins}{\@isTrue}=\z@\relax% +\newbox\nobox% +\gdef\exb@pp@lefttag{\leavevmode{\smash{\llap{{\exb@prePPHead\exbank@opt@partProblemHeader\Trigger\PartProblemHeaderSuffix}\hskip\ppMargin}\exb@postPPHead}}}% +\else% +\gdef\exb@pp@lefttag{{\exbank@opt@partProblemHeader\Trigger\PartProblemHeaderSuffix}}% +\fi% +\AtNextPar{\exb@pp@lefttag}% \ignorespaces}% \At\EndPartproblem{% - \egroup% \vspace*{\pMarginBelow}% \tighten@paragraph\par% } \At\BeginSolution{\hfill\break\vspace*{\solutionMarginAbove}{\exbank@opt@solutionHeader}} \At\EndSolution{} +\newif\ifexb@opthides +\providecommand\exb@currentTags{} +\pgfkeys{/exbank/problems/.cd,% +default/.style={hide=false,tag=\relax},% +hide/.is if={exb@opthides},% +tags/.estore in=\exb@currentTags,% +tag/.code={\pgfkeysalso{tags={#1}}}% +} +\def\nextproblem{\pgfqkeys{/exbank/problems}} \At\EndProblem{% \if\exbank@opt@tightenparagraphs\@isTrue\relax% \if\@SolutionsOnly\@isFalse% @@ -265,40 +365,42 @@ switches/.cd, \fi } \global\let\do@ProcessCutFile = \ProcessCutFile +\newif\ifexb@isdisplaying +\newif\ifexb@hidenextsol +\global\exb@hidenextsolfalse +\gdef\exb@ifshowproblem#1#2{\exb@isdisplayingfalse\ifnum\pdfstrcmp{\DisplayProblem}{\@isTrue}=\z@\ifexb@opthides\else\exb@isdisplayingtrue\fi\fi% +\ifexb@isdisplaying#1\else#2\fi} \gdef\showhideproblem#1{% - \if\DisplayProblem\isFalse - \def\ProcessCutFile{} - \else - \if\@SolutionsOnly\@isTrue\relax% - \def\ProcessCutFile{}\fi% - #1 - \fi -} -\generalcomment{problem}{ \edef\DisplaySolution{\@DisplaySolutions} - \stepcounter{metacounter} - \Trigger\DecideProblemDisplay - \begingroup +\exb@ifshowproblem{\let\ProcessCutFile\do@ProcessCutFile#1\global\exb@hidenextsolfalse}{\def\ProcessCutFile{}\global\exb@hidenextsoltrue}% +} +\generalcomment{problem}{% + \edef\DisplaySolution{\@DisplaySolutions}% + \stepcounter{metacounter}% + \@dinfo{problem: Triggering \string\DecideProblemDisplay}% + \Trigger\DecideProblemDisplay% + \@dinfo{problem:Executing - \string\showhideproblem}% \showhideproblem{% \if\exbank@opt@partProblems\isTrue - \Trigger\BeginPartproblem - \Trigger\VeryBeginPartproblem - \else - \Trigger\BeginProblem - \Trigger\VeryBeginProblem - \fi -} -}{ \if\DisplayProblem\@isFalse\relax\else - \if\exbank@opt@partProblems\isTrue - \Trigger\EndPartproblem - \tighten@paragraph + \Trigger\BeginPartproblem% + \Trigger\VeryBeginPartproblem% + \else% + \Trigger\BeginProblem% + \Trigger\VeryBeginProblem% + \fi% +}% +}{\@dinfo{Ending problem env}% + \if\DisplayProblem\@isTrue\relax% + \if\exbank@opt@partProblems\@isTrue\relax% + \Trigger\EndPartproblem% + \tighten@paragraph\fi% \else - \Trigger\EndProblem - \fi - \fi - \endgroup + \Trigger\EndProblem% + \fi% +\@dinfo{Ended problem env}% } -\generalcomment{solution} -{\Trigger\AtBeginSolutionHard +\g@addto@macro\AfterproblemComment{\nextproblem{default}\ignorespaces}% +\generalcomment{solution}{\@dinfo{START solution ENV}% +\Trigger\AtBeginSolutionHard \begingroup \if\@DisplaySolutions\isTrue \if\DisplayProblem\isFalse @@ -306,18 +408,20 @@ switches/.cd, \fi \fi \if\DisplaySolution\isTrue - \Trigger\BeginSolution + \ifexb@hidenextsol\else\Trigger\BeginSolution\fi \else \def\ProcessCutFile{} \fi -}{\if\DisplaySolution\isTrue +}{% +\if\DisplaySolution\isTrue \Trigger\EndSolution \tighten@paragraph@solutions \vspace*{0.5em} \fi \endgroup -\Trigger\EndSolutionHard% +\Trigger\EndSolutionHard\@dinfo{END solution ENV}% } +\g@addto@macro\AftersolutionComment{\ignorespaces} \def\intromargin#1{% \if\exbank@opt@doMargins\@isTrue% \gdef\endintromargin{\endlist\endgroup}% @@ -325,29 +429,42 @@ switches/.cd, \else% \relax\global\let\endintromargin=\relax\fi% } -\generalcomment{intro}{ \if\@countIntros\isTrue - \stepcounter{metacounter} - \Trigger\DecideProblemDisplay - \begingroup +\generalcomment{intro}{\@dinfo{START intro ENV}% + \if\@countIntros\isTrue% + \stepcounter{metacounter}% + \Trigger\DecideProblemDisplay% + \gdef\exb@pre@intro{}% + \gdef\exb@post@intro{}% \if\@displayMetaCounter\isTrue\relax% - {\exb@lmargin{{\Large\themetacounter}}{\pMarginLeft}} - \fi - \if\@spriteMode\@isTrue - \if\introarg\@isTrue - \stepcounter{partproblemcounter} - \fi - \fi + \gdef\exb@pre@intro{{\leavevmode{\llap{{\Large\themetacounter}:\hspace*{-\pMarginLeft}}}}\ignorespaces}% + \fi% + \if\exb@showtags\isTrue% + \xdef\exb@post@intro{\exb@printCurrentTags}% + \fi% + \if\@spriteMode\@isTrue% + \if\introarg\@isTrue% + \stepcounter{partproblemcounter}% + \fi% + \fi% + \gdef\@displayIntro{\@isFalse} \showhideproblem{% \tighten@paragraph% - \Trigger\BeginIntro% -} - \fi% + \Trigger\BeginIntro\exb@pre@intro\exb@post@intro% + \gdef\@displayIntro{\@isTrue} +}% + \exb@ifshowproblem{\intromargin{-1em}}{} + \else% \intromargin{-1em} -}{ \if\@countIntros\isTrue - \Trigger\EndIntro - \endgroup - \fi\par\endintromargin + \fi% +}{ \if\@countIntros\isTrue% + \Trigger\EndIntro% + \exb@ifshowproblem{\endintromargin}{} + \else + \endintromargin + \fi% + \@dinfo{END intro ENV}\ignorespaces% } +\g@addto@macro\AfterintroComment{\nextproblem{default}\ignorespaces} \def\squeeze{ \newlength{\marginw} \setlength{\marginw}{1.5cm} \newgeometry{margin=\marginw} @@ -381,7 +498,11 @@ switches/.cd, \let\ea = \expandafter \newcounter{metacounter} \setcounter{metacounter}{0} -\gdef\emptyList{0} +\gdef\exb@emptyList{0} +\newif\ifexb@tagbuildmode +\global\exb@tagbuildmodefalse +\global\let\emptyList\exb@emptyList +\global\let\exb@tagList\exb@emptyList \gdef\ifppMode#1{ \def\mname{\exbank@macroname{#1}} \strif\mname\ppMode } @@ -404,19 +525,36 @@ switches/.cd, \At\DecideProblemDisplay{% \ifnum\pdfstrcmp{\ppList}{\emptyList}=\z@\relax% \xdef\DisplayProblem{\ipm\exclude\T@\ipm\select\F@} - \else - \isin{\ppList}{\themetacounter}{ \xdef\DisplayProblem{\ipm\exclude\F@\ipm\select\T@\ipm\normal\T@} -}{ \xdef\DisplayProblem{\ipm\exclude\T@\ipm\select\F@\ipm\normal\T@} -} \fi + \exb@int@isin{\themetacounter}{\ppList}{ \xdef\DisplayProblem{\ipm\exclude\F@\ipm\select\T@\ipm\normal\T@} +}{ \xdef\DisplayProblem{\ipm\exclude\T@\ipm\select\F@\ipm\normal\T@} } +\ifexb@tagbuildmode +\ifnum\pdfstrcmp{\DisplayProblem}{\T@}=\z@\relax% +\exb@intersection@any{\exb@currentTags}{\exb@tagList}{\global\exb@opthidesfalse}{\global\exb@opthidestrue}% +\fi +\fi +} +\gdef\introarg{\@isFalse} +\gdef\noheadarg{\@isFalse} \pgfkeys{ /makeset/.is family, /makeset, - default/.style = {noheadarg=\isFalse, introarg=\isFalse}, - intro/.style = {introarg=\isTrue}, - nohead/.style = {noheadarg=\isTrue}, + default/.style = {}, + intro/.style = {introarg=\@isTrue}, + nointro/.style = {introarg=\@isFalse}, + nohead/.style = {noheadarg=\@isTrue}, + head/.style = {noheadarg=\@isFalse}, introarg/.estore in = \introarg, noheadarg/.estore in = \noheadarg } +\gdef\makesetdefaults#1{% +\edef\exb@setpgfkeys{{\unexpanded\expandafter{/makeset/default/.style = {#1}}}}% +\expandafter\pgfkeys\exb@setpgfkeys% +} +\pgfkeys{/makeset/override/.cd, +intro/.code = {\gdef\introarg{\@isTrue}\ea\gdef\csname setlist@\exb@currentSetID @intro\endcsname{\@isTrue}}, +nointro/.code = {\gdef\introarg{\@isFalse}\ea\gdef\csname setlist@\exb@currentSetID @intro\endcsname{\@isFalse}}, +nohead/.code = {\gdef\noheadarg{\@isTrue}\ea\gdef\csname setlist@\exb@currentSetID @nohead\endcsname{\@isTrue}} +} \gdef\@listOfSets{} \gdef\@spriteMode{\isFalse} \gdef\exbank@spriteSets{\emptyList} @@ -472,18 +610,22 @@ switches/.cd, \gdef\ppMode{\pm@Normal} \fi } +\global\let\ex@protect\noexpand +\long\gdef\exec#1{:\ex@protect{#1}} +\gdef\exb@def@makeset@cmd#1{\@ifnextchar[{\@exb@def@makeset@cmd{#1}}{\@exb@def@makeset@cmd{#1}[0]}} +\gdef\@exb@def@makeset@cmd#1[#2]#3{\def\ncArgs{#1[#2]}% +\bgroup\globaldefs=1\ea\newcommand\ncArgs{\exec{#3}}\egroup% +} +\def\exbank@def@makeset@command{\exb@warn{\string\exbank@def@makeset@command\space is deprecated and will be removed in versions >= 0.3.0. Use \string\exb@def@makeset@cmd}\exb@def@makeset@cmd} +\let\DeclareExerciseCommand\exb@def@makeset@cmd \newcommand{\exclude}[2]{[{#2}]{#1}{exclude}} \newcommand{\select}[2]{[{#2}]{#1}{select}} -\gdef\buildex#1{ \makeset{#1}{#1} - \buildset{#1} -} -\gdef\exbank@def@makeset@command#1#2{% - \edef\macroname{\exbank@macroname{#1}}% - \xdef#1{?{@\macroname}}% - \ea\gdef\csname @\macroname\endcsname{#2}% +\newcommand{\orderedselect}[2]{% +\readlist*\thelist\csv@list% +\foreachitem\items\in\thelist{[{\item}]{#1},}% } \let\exbank@isFirstProblem\isTrue -\exbank@def@makeset@command{\phead}{ \if\exbank@isFirstProblem\isTrue% +\exb@def@makeset@cmd{\phead}{ \if\exbank@isFirstProblem\isTrue% \let\exbank@isFirstProblem\isFalse% \else% \Trigger\EndProblem% @@ -491,19 +633,29 @@ switches/.cd, \Trigger\BeginProblem% \Trigger\VeryBeginProblem% } -\exbank@def@makeset@command{\pbreak}{\clearpage} -\let\DeclareExerciseCommand\exbank@def@makeset@command -\global\let\ex@protect\noexpand -\gdef\exec#1{:\ex@protect{#1}} +\exb@def@makeset@cmd{\pheadarg}[1]{ \if\exbank@isFirstProblem\isTrue% + \let\exbank@isFirstProblem\isFalse% + \else% + \Trigger\EndProblem% + \fi% + \Trigger\BeginProblem% + \bgroup\def\theproblemcounter{#1}\Trigger\VeryBeginProblem\egroup% +} +\exb@def@makeset@cmd{\pbreak}{\clearpage} +\gdef\buildex#1{ \makeset{#1}{#1} + \buildset{#1} +} \gdef\@countIntros{\isFalse} \gdef\exb@setpgf#1{% \edef\keystring{{/makeset,default,#1}}% \ea\pgfkeys\keystring} \newcommand\buildset[2][]{% - \def\oarg{#1}% - \@ifundefined{setlist@#2@intro}{\gdef\@countIntros{\isFalse}}{\gdef\@countIntros{\isTrue}\@dlog{Counting intros}}% + \xdef\exb@currentSetID{#2}% + \pgfkeys{/makeset/override/.cd, #1} + \global\let\setName\exb@currentSetID% + \gdef\exb@buildset@oarg{#1} + \@ifundefined{setlist@#2@intro}{\gdef\@countIntros{\isFalse}}{\gdef\@countIntros{\isTrue}}% \@ifundefined{setlist@#2@nohead}{\gdef\nohead{\isFalse}}{\gdef\nohead{\isTrue}}% - \xdef\setName{#2}% \ifcsname setkeys@\setName\endcsname% \xdef\skeys{\csname setkeys@#2\endcsname}% \exb@setpgf\skeys% @@ -524,7 +676,7 @@ switches/.cd, \gdef\@is@file{\@ifnextchar[\exb@setEnv@withOptargs\X@exb@setEnv}% \gdef\X@exb@setEnv##1{% \def\continueLoop{\isTrue}% - \@dlog{Processing normal file "\exerciseFileInfo.tex"}% + \@dinfo{Processing normal file "\exerciseFileInfo.tex"}% \exbank@setEnv@normal{\exerciseFileInfo}\bgroup\nullfont% } \gdef\exb@setEnv@withOptargs{% @@ -532,12 +684,12 @@ switches/.cd, } \gdef\@execute@makeset@command ?##1{% \edef\inner{\@firstofone##1}% - \@dlog{Executing macro \@backslashchar\@gobble##1}% + \@dinfo{Executing macro \@backslashchar\@gobble##1}% \csname\inner\endcsname% #1\def\continueLoop{\isFalse}\ea\bgroup% } \def\@execute@exec:{% - \def\continueLoop{\isFalse}\@dlog{Executing custom command}\bgroup% + \def\continueLoop{\isFalse}\@dinfo{Executing custom command}\bgroup% } \readlist*\setlist\exbank@setlist% \foreachitem\exerciseFileInfo\in\setlist{% @@ -562,7 +714,7 @@ switches/.cd, \incl{\@exercisesDir/\exerciseFile}% \if\@spriteMode\isTrue% \setcounter{partproblemcounter}{0}% - \fi + \fi% }{ \@latex@error{Could not find \@exercisesDir/\exerciseFile. Maybe it is because the default exercise directory is now changed to the same directory that your main file is in. To set default exercise directory to exercises, do \string\exercisebanksetup{exercise directory=exercises}}{} \stop\bye } @@ -571,17 +723,30 @@ switches/.cd, } \if\@spriteMode\isFalse% \Trigger\EndBuildset% - \fi + \fi% \setcounter{problemcounter}{0}% \setcounter{partproblemcounter}{0}% \clearpage% } -\newcommand\buildsets[1]{% - \xdef\csvlist{#1}% +\newcommand\buildsets[2][]{% + \xdef\csvlist{#2}% \readlist*\items\csvlist% \foreachitem\set\in\items{% + \buildset[#1]{\set}% +} +} +\newcommand\buildtags[2]{% + \global\exb@tagbuildmodetrue + \xdef\csvtags{#1}% + \xdef\csvlist{#2} + \xdef\csvsets{#2}% + \readlist*\tagsItems\csvtags% + \readlist*\setsItems\csvsets% + \foreachitem\set\in\setsItems{% + \xdef\exb@tagList{\csvtags} \buildset{\set}% } + \global\exb@tagbuildmodefalse } \newcommand\refcounter[1]{\edef\@currentlabel{#1}% } @@ -598,3 +763,31 @@ switches/.cd, \newcommand\pref[1]{% \ref{pr:\exerciseFile:#1}\relax% } +\gdef\exb@currentPoints{0} +\gdef\exb@currentPointsStyle{} +\newif\ifexb@enablepoints\global\exb@enablepointstrue +\exercisebanksetup{% +current points style/.store in=\exb@currentPointsStyle, +current points style={\ifnum\exb@currentPoints=\z@\ifnum\totalpoints=\z@\else\phantom{0p}\fi\else\exb@currentPoints p\fi\ignorespaces}, +disable points/.is if={exb@enablepoints} +} +\ifexb@enablepoints +\AtEndDocument{% +\immediate\write\@auxout{\string\gdef\string\totalpoints{\the\c@exb@points}}% +} +\At\PartProblemHeaderSuffix{\exb@currentPointsStyle} +\fi +\newcounter{exb@points} +\setcounter{exb@points}{0} +\providecommand\totalpoints{} +\nextproblem{points/.store in=\exb@currentPoints} +\At\BeginPartproblem{\addtocounter{exb@points}\exb@currentPoints} +\At\EndPartproblem{\gdef\exb@currentPoints{0}} +\def\exb@hidetaglist{} +\At\DecideProblemDisplay{\ifnum\pdfstrcmp{\DisplayProblem}{\T@}=\z@\relax% +\ifx\exb@hidetaglist\relax\else +\exb@intersection@any{\exb@currentTags}{\exb@hidetaglist}{\global\exb@opthidestrue}{\global\exb@opthidesfalse}% +\fi +\fi +} +\gdef\HideTags#1{\xdef\exb@hidetaglist{#1}} |