diff options
author | Karl Berry <karl@freefriends.org> | 2019-03-18 21:16:17 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2019-03-18 21:16:17 +0000 |
commit | 8c69df7f8b72005b3d333b30388fb69d20ebb22a (patch) | |
tree | 61f70bf10d001fed282c3d5c63d732ba56060678 | |
parent | fdcf5fd90a27314abf7b130fd1e7a7bba0a3fa6a (diff) |
exercisebank (18mar19)
git-svn-id: svn://tug.org/texlive/trunk@50448 c570f23f-e606-0410-a88d-b1316a301751
-rw-r--r-- | Master/texmf-dist/doc/latex/exercisebank/README.txt | 13 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/exercisebank/example.zip | bin | 68924 -> 48229 bytes | |||
-rw-r--r-- | Master/texmf-dist/doc/latex/exercisebank/exercisebank-doc.pdf | bin | 245279 -> 256850 bytes | |||
-rw-r--r-- | Master/texmf-dist/doc/latex/exercisebank/exercisebank-doc.tex | 184 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/exercisebank/exercisebank.sty | 958 |
5 files changed, 767 insertions, 388 deletions
diff --git a/Master/texmf-dist/doc/latex/exercisebank/README.txt b/Master/texmf-dist/doc/latex/exercisebank/README.txt index 864ee8207fa..7efcf7bab8b 100644 --- a/Master/texmf-dist/doc/latex/exercisebank/README.txt +++ b/Master/texmf-dist/doc/latex/exercisebank/README.txt @@ -7,10 +7,13 @@ Files: ├── example.zip │ ├── example.pdf │ ├── example.tex -│ └── exercises -│ ├── firstexercise.tex -│ ├── secondexercise.tex -│ └── thirdexercise.tex +│ ├── exercises +│ │ └── mechanics +│ │ └── center-of-mass.tex +│ ├── figures +│ │ └── mechanics +│ │ └── rod.tex +│ └── mathcommands.tex ├── exercisebank-doc.pdf ├── exercisebank-doc.tex └── exercisebank.sty @@ -22,7 +25,7 @@ https://github.com/Strauman/exercisebank/ Licence: -The LaTeX package exercisebank - version v0.2.2 (2018/10/04) - build 97 +The LaTeX package exercisebank - version v0.3.0 (2019/03/18) - build 137 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 5205e752669..fc1decf7cab 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 ce76dddc471..7bcf0f8af94 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 2465880347b..e270a91e886 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.2b97 - 2018/10/04 -%% The LaTeX package exercisebank - version v0.2.2 (2018/10/04) build 97 +%% exercisebank v0.3.0b137 - 2019/03/18 +%% The LaTeX package exercisebank - version v0.3.0 (2019/03/18) build 137 %% Manual/Documentation for exercisebank.sty %% ------------------------------------------------------------------------------------------- %% Copyright (c) 2018 by Andreas Storvik Strauman @@ -49,6 +49,13 @@ \newcommand\gh[1]{\href{https://github.com/#1}{@#1}} \newcommand\ghURL[1]{\href{https://github.com/#1}{https://github.com/#1}} +\providecommand\onethankyou@tmp@content{\relax} +\providecommand\onethankyou@content{\relax} +\let\dlog\@latex@warning +\dlog{OTYC\onethankyou@content:\the\catcode`\@} +\gdef\onethankyou#1{\dlog{Reg @oty}\gdef\onethankyou@tmp@content{#1}} +\AtEndDocument{\write\@auxout{\string\gdef\string\onethankyou@content{\onethankyou@tmp@content}}} + \providecommand\thankyous{\relax} \def\print@thankyous{\readlist*\lst\thankyous\foreachitem\itm\in\lst{\if\itm\relax\else\item[-] \itm\fi}} \providecommand\@thankyous@content{\relax} @@ -98,6 +105,7 @@ \begingroup\lccode`\|=`\\ \lowercase{\endgroup\def\removebs#1{\if#1|\else#1\fi}} \newcommand{\macroname}[1]{\expandafter\removebs\string#1} +% \def\obeyifnextspace{\ltx@ifnextchar{ }\relax\relax} \def\dac#1{\docAuxCommand{\macroname{#1}}} \let\mdac\dac @@ -119,14 +127,18 @@ \setlength{\parindent}{0pt} -\title{{exercisebank - manual\\ v0.2.2{\\[-0.5em]\footnotesize(build 97)}}} +\title{{exercisebank - manual\\ v0.3.0{\\[-0.5em]\footnotesize(build 137)}}} \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 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 +\makeatletter +\if\onethankyou@content\relax\else\par% +An extra special thanks to \onethankyou@content who really helps out with this package! +\fi +\if\thankyous\relax\else\par Special thanks to the people who helps me with this package: \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 @@ -307,6 +319,10 @@ That covers the basics. Enjoy Turns on the solutions, so they are shown. \end{docCommand} +\begin{docCommand}{SolutionsOnly}{}\addcontentsline{toc}{subsubsection}{\refCom{SolutionsOnly}} +\defnew{v0.3.0\\2019/03/18 } +Displays only solutions (if there are any) to the part problem +\end{docCommand} \begin{docEnvironment}{problem}{} Inside the \dac{keyRef}\{exercise directory\}, you keep your exercises. Inside the exercise file you'd use a problem environment to write your partproblems. It might be a little confusing that you're using \dac{begin}\{problem\} instead of \dac{begin}\{partproblem\} when you're writing a partproblem, but it's less typing. \end{docEnvironment} @@ -358,6 +374,10 @@ However, you can override this; This contains information about an exercise set. It is intended to be on the top of an exercise, explaining short what the exercise is about. It's only visible when using \dac{sprite} \end{docCommand} +\begin{docCommand}{buildall}{}\addcontentsline{toc}{subsubsection}{\refCom{buildall}} +\defnew{v0.3.0\\2019/03/18 } + Build all sets defined with \dac{makeset} +\end{docCommand} \begin{docCommand}{sprite}{\oarg{PiP}}\addcontentsline{toc}{subsubsection}{\refCom{sprite}} \updated{v0.1.1\\2018/04/13 } This is a way to visualize all exercises. It takes one optional argument which is how many pages @@ -405,11 +425,8 @@ To be used in \refCom{makeset} 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 } +\updated{v0.3.0\\2019/03/18 } This command runs the set given. The set has do be defined by \dac{makeset}. E.eg \begin{dispListing} \makeset{myExerciseSet}{exercisefile1, \select{exercisefile2}{1,2}} @@ -447,6 +464,10 @@ This command will generate multiple sets: \buildsets{tag,tag2,tag3}{set,set2,set3} \end{dispListing} \end{docCommand} +\begin{docCommand}{buildsprite}{\marg{setslist}}\addcontentsline{toc}{subsubsection}{\refCom{buildsprite}} +\defnew{v0.3.0\\2019/03/18 } + Builds a sprite from the given comma separated list of sets +\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\}} @@ -455,14 +476,35 @@ Labels a partproblem. You can reference to it later using \dac{ppref}\{\meta{lab \updated{v0.2.0\\2018/07/21 } Reference a partproblem created by \dac{pplabel}\{\meta{label\}}. This prints e.g. 1c) \end{docCommand} +\begin{docCommand}{ppgref}{\marg{label}}\addcontentsline{toc}{subsubsection}{\refCom{ppgref}} +\defnew{v0.3.0\\2019/03/18 } +Reference a partproblem created by \dac{pplabel}\{\meta{label\}}. This can be used for \emph{global} exercises. +\end{docCommand} \begin{docCommand}{pref}{\marg{label}}\addcontentsline{toc}{subsubsection}{\refCom{pref}} Reference a partproblem created by \dac{pplabel}\{\meta{label\}}. This prints e.g. 1 \end{docCommand} +\begin{docCommand}{pgref}{\marg{label}}\addcontentsline{toc}{subsubsection}{\refCom{pgref}} +\defnew{v0.3.0\\2019/03/18 } + Reference a partproblem created by \dac{pplabel}\{\meta{label\}}. This prints e.g. 1, but have global search. +\end{docCommand} \begin{docCommand}{HideTags}{\marg{list}}\addcontentsline{toc}{subsubsection}{\refCom{HideTags}} -\defnew{v0.2.1\\2018/09/24 } +\updated{v0.3.0\\2019/03/18 } Hide all exercises containing the list of tags when building a set. \end{docCommand} +\begin{docCommand}{ShowAllTags}{}\addcontentsline{toc}{subsubsection}{\refCom{ShowAllTags}} +\defnew{v0.3.0\\2019/03/18 } +Reset tags set by \dac{HideTags} +\end{docCommand} +\begin{docCommand}{exercisenote}{}\addcontentsline{toc}{subsubsection}{\refCom{exercisenote}} +\defnew{v0.3.0\\2019/03/18 } + Adds a note below an exercise header. To be used in \dac{makeset} +\begin{dispListing} + \makeset{\exercisenote{This is a pretty hard exercise}, my/hard/exercise} +\end{dispListing} + Here the text inside \dac{exercisenote} (This is a pretty hard exercise) will show + right below the problem header of my/hard/exercise.tex +\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! @@ -472,11 +514,11 @@ You can do a lot of configurations on this package, and probably \dac{exclude} and \dac{select} \end{docCommand} \begin{docCommand}{ShowTags}{}\addcontentsline{toc}{subsubsection}{\refCom{ShowTags}} -\defnew{v0.2.1\\2018/09/24 } +\updated{v0.3.0\\2019/03/18 } 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 } +\updated{v0.3.0\\2019/03/18 } Shows the path+filename to the current exercise file \end{docCommand} \begin{docCommand}{exercisebanksetup}{\marg{\oarg{key/values}}}\addcontentsline{toc}{subsubsection}{\refCom{exercisebanksetup}} @@ -550,15 +592,26 @@ You would use this option in the setup:\\ Path to a front page that will be loaded at every \dac{buildset} Where to load the front page. The commands \refCom{setName} is available. } -\keyDef{style margins}{yes/no}{yes}{ +\keyDef{style margins}{true|false}{true}{ Whether or not to put problem headers and part problem headers out in the margins. } +\keyDef{show lonely part problems}{true|false}{false}{ + Whether or not to show part problems if there is only one part problem within the problem. +} \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}} + the default code is by \gh{thorstengrote} (see example below) } +\begin{dispListing} +~\ifnum\exb@currentPoints=\z@% + \ifnum\totalpoints=\z@\else% + \phantom{0p}% + \fi% + \else% + \exb@currentPoints p% + \fi~\ignorespaces +\end{dispListing} \keyDef{disable points}{bool}{false}{ Whether or not to disable the point system. } @@ -577,9 +630,9 @@ The Norwegian translation would then be done with \translateExBank{Problem=Oppgave, Solution=Løsning} \end{dispListing} \end{docCommand} -\filbreak\subsection{Problem options and tagging} +\filbreak\subsection{Problem options: points and tagging} \begin{docCommand}{nextproblem}{}\addcontentsline{toc}{subsubsection}{\refCom{nextproblem}} -\updated{v0.2.2\\2018/10/04 } +\updated{v0.3.0\\2019/03/18 } 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 @@ -615,6 +668,12 @@ you can also tag problems using this: This problem is easy \end{problem} \end{dispListing} +\keyDef{head}{text}{}{ + Set the part problem header for the next problem. +} +\keyDef{solution only}{true|false}{}{ + hide next problem unless \dac{DisplaySolutions} are on +} Here are the \dac{nextproblem} keys: \keyDef{points}{number}{0}{ The number of points the next exercise is worth. @@ -622,6 +681,14 @@ Here are the \dac{nextproblem} keys: } +\begin{docCommand}{totalpoints}{}\addcontentsline{toc}{subsubsection}{\refCom{totalpoints}} + +Contains the total number of points for all exercises in the current set +\end{docCommand} +\begin{docCommand}{exercisepoints}{}\addcontentsline{toc}{subsubsection}{\refCom{exercisepoints}} +\defnew{v0.3.0\\2019/03/18 } + Contains the total number of points in the current exercise (or "Problem") +\end{docCommand} \filbreak\subsection{Triggers} \begin{docCommand}{Trigger}{\marg{Any Macro}}\addcontentsline{toc}{subsubsection}{\refCom{Trigger}} \updated{v0.2.1\\2018/09/24 } @@ -629,6 +696,8 @@ Here are the \dac{nextproblem} keys: 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{PostPPHeader}:\\ Triggers right after the part problem header +has been printed. It is also triggered after the PP header for SolutionsOnly. \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\\\ @@ -639,6 +708,14 @@ Here are the \dac{nextproblem} keys: \end{docCommand} +\begin{docCommand}{exb@ClearHook}{}\addcontentsline{toc}{subsubsection}{\refCom{exb@ClearHook}} + + Deletes all information from a hook. + Note that if preceded by \dac{rigid}, then the + ENTIRE hook will be cleared. + Note that the necessary hooks might not be + registered as rigid. Thus show caution when deleting hooks +\end{docCommand} \filbreak\subsection{General reference} \begin{docCommand}{ownLineNoSpacesGotIt}{}\addcontentsline{toc}{subsubsection}{\refCom{ownLineNoSpacesGotIt}} @@ -658,6 +735,14 @@ where the package should be looking for exercises. Default is the same directory Executes \meta{True} if \meta{needle} is found in \meta{haystack} else executes \meta{False} \end{docCommand} +\begin{docCommand}{exercisebankversion}{}\addcontentsline{toc}{subsubsection}{\refCom{exercisebankversion}} +\defnew{v0.3.0\\2019/03/18 } + Prints the current version and build to the error log +\end{docCommand} +\begin{docCommand}{exercisebankbuild}{}\addcontentsline{toc}{subsubsection}{\refCom{exercisebankbuild}} +\defnew{v0.3.0\\2019/03/18 } + Prints the current build number to the error log +\end{docCommand} This package also includes some extra stuff. For example the \dac{At} and \dac{Trigger} \begin{docCommand}{At}{\marg{AnyMacro}} \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}. @@ -667,6 +752,17 @@ This package also includes some extra stuff. For example the \dac{At} and \dac{T \Trigger\BeginSomething, this evaluates to DoSomething \end{dispListing} \end{docCommand} +\begin{docCommand}{@rigid}{}\addcontentsline{toc}{subsubsection}{\refCom{@rigid}} +\defnew{v0.3.0\\2019/03/18 } +Used to make \dac{At} so that the contents won't be deleted +with \dac{ClearHook}. Note that the necessary hooks might not be + registered as rigid. Thus show caution when deleting hooks +\end{docCommand} +\begin{docCommand}{thisfilepath}{}\addcontentsline{toc}{subsubsection}{\refCom{thisfilepath}} + + Contains the path to the exercisefile relative to the build file. + Useful for inputing files in the same directory as an exercisefile. +\end{docCommand} \begin{docCommand}{exerciseFile}{}\addcontentsline{toc}{subsubsection}{\refCom{exerciseFile}} This is a `read-only' macro that contains the name of the current exerciseFile @@ -702,43 +798,54 @@ Distance above Problem \# header \end{docCommand} \begin{docCommand}{ppMargin}{}\addcontentsline{toc}{subsubsection}{\refCom{ppMargin}} - Part problem: how far away from the text the part problem labels are. + Part problem: how far away from the text the part problem labels are (horisontally). \end{docCommand} -\begin{docCommand}{introMargin}{}\addcontentsline{toc}{subsubsection}{\refCom{introMargin}} +\begin{docCommand}{introOutdent}{}\addcontentsline{toc}{subsubsection}{\refCom{introOutdent}} The offset of margins for intros \end{docCommand} \filbreak\subsection{Macro definitions} - \addcontentsline{mac}{macro}{\refCom{At}}{} + \addcontentsline{mac}{macro}{\refCom{@rigid}}{} +\addcontentsline{mac}{macro}{\refCom{At}}{} \addcontentsline{mac}{macro}{\refCom{DeclareExerciseCommand}}{} \addcontentsline{mac}{macro}{\refCom{DisplaySolutions}}{} \addcontentsline{mac}{macro}{\refCom{HideTags}}{} +\addcontentsline{mac}{macro}{\refCom{ShowAllTags}}{} \addcontentsline{mac}{macro}{\refCom{ShowFilenames}}{} \addcontentsline{mac}{macro}{\refCom{ShowNumbers}}{} \addcontentsline{mac}{macro}{\refCom{ShowTags}}{} +\addcontentsline{mac}{macro}{\refCom{SolutionsOnly}}{} \addcontentsline{mac}{macro}{\refCom{Trigger}}{} \addcontentsline{mac}{macro}{\refCom{about}}{} +\addcontentsline{mac}{macro}{\refCom{buildall}}{} \addcontentsline{mac}{macro}{\refCom{buildset}}{} \addcontentsline{mac}{macro}{\refCom{buildsets}}{} +\addcontentsline{mac}{macro}{\refCom{buildsprite}}{} \addcontentsline{mac}{macro}{\refCom{buildtags}}{} +\addcontentsline{mac}{macro}{\refCom{exb@ClearHook}}{} \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{exercisebankbuild}}{} \addcontentsline{mac}{macro}{\refCom{exercisebanksetup}}{} -\addcontentsline{mac}{macro}{\refCom{introMargin}}{} +\addcontentsline{mac}{macro}{\refCom{exercisebankversion}}{} +\addcontentsline{mac}{macro}{\refCom{exercisenote}}{} +\addcontentsline{mac}{macro}{\refCom{exercisepoints}}{} +\addcontentsline{mac}{macro}{\refCom{introOutdent}}{} \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}}{} \addcontentsline{mac}{macro}{\refCom{pMarginLeft}}{} +\addcontentsline{mac}{macro}{\refCom{pgref}}{} \addcontentsline{mac}{macro}{\refCom{ppMargin}}{} \addcontentsline{mac}{macro}{\refCom{ppMarginAbove}}{} \addcontentsline{mac}{macro}{\refCom{ppMarginBelow}}{} +\addcontentsline{mac}{macro}{\refCom{ppgref}}{} \addcontentsline{mac}{macro}{\refCom{pplabel}}{} \addcontentsline{mac}{macro}{\refCom{ppref}}{} \addcontentsline{mac}{macro}{\refCom{pref}}{} @@ -747,6 +854,8 @@ Distance above Problem \# header \addcontentsline{mac}{macro}{\refCom{setName}}{} \addcontentsline{mac}{macro}{\refCom{sprite}}{} \addcontentsline{mac}{macro}{\refCom{spritesets}}{} +\addcontentsline{mac}{macro}{\refCom{thisfilepath}}{} +\addcontentsline{mac}{macro}{\refCom{totalpoints}}{} \addcontentsline{mac}{macro}{\refCom{translateExBank}}{} \macrotable @@ -817,10 +926,41 @@ Distance above Problem \# header \newversion{v0.2.2 2018/10/04} \change{Made trailing commas ignored in all lists (\dac\makeset,\dac\buildset,\dac\select,\dac\exclude, etc.)} \change{Fixed bug where tags wouldn't hide.} +\newversion{v0.3.0 2019/03/18} + \change{Added possibility of custom part problem header from \dac\nextproblem} + \change{Added possibility of showing problem only when \dac\DisplaySolutions active} + \change{Corrected use of the length \dac\ppMarginBelow} + \change{Fixed bug where \dac\phead and \dac\ShowFilenames crash} + \change{Introduced \dac\SolutionsOnly} + \change{Fixed bug where part problem header repeats if solution is itemize.} + \change{Introduced the \dac\@rigid command for the \dac\At functionality. Also the \dac\ClearHook for deleting a hook} + \change{\dac\buildset now gives error if set does not exist.} + \change{Made \dac\HideTags cummulative.} + \change{Created \dac\ShowAllTags for clearing tags list} + \change{Raises error when pdfTeX(or pdfLaTeX) is not used} + \change{Allow underscore for files in \dac\makeset} + \change{Added \dac\exercisepoints for getting total number of points in an exercise/problem.} + \change{added \dac\pgref and \dac\ppgref} + \change{Margins now more manageable} + \change{Prevent overwriting of \dac\graphicspath} + \change{Set (append) to \dac\input@path no matter what.} + % \change{Fixed bug where part problem headers showing weird if problem started with envs. like enumerate or a figure.} + \change{Added command \dac\buildall to build all sets} + \change{Moved tag placement for when \dac\ShowTags active} + \change{Adjusted margins.} + \change{Activated \dac\ppMarginAbove (it now does something)} + \change{Added \dac\exercisebankversion and \dac\exercisebankbuild} + \change{Part problem header now showing if only one part problem is displayed} + \change{Possibility to toggle whether part problem header showing if only one part problem is displayed \refKey{show lonely part problems}} + \change{Fixed TeX capacity exceeded error for long exercises.} + \change{Added \dac\thisfilepath for getting path of current exercisefile} + \change{Changed default spacing} + \change{Added \dac\buildsprite} \chlogtable % Testers and thanks \tester{\gh{thorstengrothe}} -\tester{\gh{tristelune1}} +\onethankyou{\gh{tristelune1}} +% \thankyou{} \end{document} diff --git a/Master/texmf-dist/tex/latex/exercisebank/exercisebank.sty b/Master/texmf-dist/tex/latex/exercisebank/exercisebank.sty index 60cf10076d5..9e13d79ea7e 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.2 (2018/10/04) - build 97 +%% The LaTeX package exercisebank - version v0.3.0 (2019/03/18) - build 137 %% exercisebank.sty: Exercise bank %% ------------------------------------------------------------------------------------------- %% Copyright (c) 2018 by Andreas Storvik Strauman <andreas dot s dot strauman at uit dot no> @@ -13,17 +13,78 @@ %% 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/10/04 v0.2.2 Creates a setup that gives freedom in making sets and exercises.] +\ProvidesPackage{exercisebank}[2019/03/18 v0.3.0 Creates a setup that gives freedom in making sets and exercises.] \xdef\exbank@quiet{1} -\def\exercisebankversion{v0.2.2 - Build 97} -\PackageWarningNoLine{exercisebank-v0.2.2}{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.3.0 - Build 137} +\PackageWarningNoLine{exercisebank-v0.3.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!} \@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}} }{} +\ifcsname pdfstrcmp\endcsname\else +\PackageError{exercisebank-v0.3.0}{Exercisebank currently only works with pdfLaTeX}{}\stop +\fi \gdef\setExercisesDir#1{\@latex@error{\string\setExercisesDir is deprecated. Use \string\exercisebanksetup{exercise directory=#1} instead}{}\stop\bye } \@ifundefined{exercisesDir}{\gdef\@exercisesDir{.} }{} \global\let\incl = \input +\def\exb@rememberCC#1{% + \edef\exbtmp@charcode{\the\numexpr#1}% + \expandafter\xdef\csname exb@remcc@\exbtmp@charcode\endcsname{\the\catcode#1}% +} +\def\exb@ignoreCC#1{% + \edef\exbtmp@charcode{\the\numexpr#1} + \exb@rememberCC{\exbtmp@charcode}% + \catcode\exbtmp@charcode=9% +} +\def\exb@resetCC#1{ \catcode#1=\csname exb@remcc@\the\numexpr#1\endcsname +} +\def\ignoreOutlineSpaces{% + \exb@ignoreCC{10}% + \exb@ignoreCC{11}% + \exb@ignoreCC{12}% + \exb@ignoreCC{13}% +} +\def\obeyOutlineSpaces{% + \exb@resetCC{10}% + \exb@resetCC{11}% + \exb@resetCC{12}% + \exb@resetCC{13}\ignorespaces% +} +\let\ignoreOutlineSpaces\relax +\let\obeyOutlineSpaces\relax +\def\g@newif#1{% + \count@\escapechar\escapechar\m@ne + \global\let#1\iffalse% + \g@if#1\iftrue% + \g@if#1\iffalse% +\escapechar\count@} +\def\g@if#1#2{% + \expandafter\def\csname\expandafter\@gobbletwo\string#1% + \expandafter\@gobbletwo\string#2\endcsname% + {\global\let#1#2}% +} +\global\newif\ifexbset@nextprob@header +\global\exbset@nextprob@headertrue +\newif\ifexb@opthides +\g@newif\ifexb@b@nextprob@header +\g@newif\ifexb@solutionsonly +\g@newif\ifexb@isFirstProblem +\g@newif\ifexb@opt@tightenparagraphs +\g@newif\ifexb@DisplaySolutions +\g@newif\ifexb@DisplayCurrentSolution +\g@newif\ifexb@DisplayCurrentProblem +\g@newif\ifexbank@if@needspace +\g@newif\ifexb@opt@partProblems +\g@newif\ifexb@opt@doMargins +\g@newif\ifexb@CountIntros +\g@newif\ifexb@noheadArg +\g@newif\ifexb@showtags +\g@newif\ifexb@showCurrent@PPHeader +\g@newif\ifexb@showLonelyPartProblems +\global\exb@showLonelyPartProblemsfalse +\global\exb@showCurrent@PPHeadertrue +\exb@b@nextprob@headerfalse +\exbank@if@needspacetrue \usepackage{xstring} \usepackage{pgffor} \usepackage{scrextend} @@ -60,7 +121,7 @@ \fi% }% \fi} -\gdef\exb@warn{\PackageWarningNoLine{exercisebank-v0.2.2}} +\gdef\exb@warn{\PackageWarningNoLine{exercisebank-v0.3.0}} \gdef\exb@err#1{\PackageError{exercisebank}{#1}{}} \newif\ifexb@isInList \newcounter{exb@isin@dots} @@ -138,38 +199,39 @@ \global\catcode`\^^J=12\relax% \global\catcode`\ =10\relax% } -\let\nextPar\everypar +\def\@AtNextParHook{} +\let\oldep\everypar +\oldep{\the\everypar} \newtoks\everypar -\nextPar{\the\everypar} -\def\AtNextPar#1{\nextPar\expandafter{\the\nextPar\nextPar{\the\everypar}#1}} +\oldep{\the\everypar\@AtNextParHook\relax\gdef\@AtNextParHook{}} +\def\AtNextPar#1{\g@addto@macro\@AtNextParHook{#1}} +\gdef\exercisebankversion{\PackageWarningNoLine{exercisebank}{Version v0.3.0b137}} +\gdef\exercisebankbuild{\PackageWarningNoLine{exercisebank}{Build 137}} \edef\@isTrue{1} \edef\@isFalse{0} \gdef\ShowNumbers{\gdef\@displayMetaCounter{\isTrue}} -\gdef\exb@showtags{\isFalse} -\gdef\ShowTags{\gdef\exb@showtags{\isTrue}} +\global\exb@showtagsfalse +\gdef\ShowTags{\global\exb@showtagstrue} \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\ShowFilenames{\At\InputExerciseFile{File: {\ttfamily \@exercisesDir/\exerciseFile}\par}} +\global\exb@DisplaySolutionsfalse +\gdef\DisplaySolutions{\global\exb@DisplaySolutionstrue\@latex@warning{Showing solutions}} +\gdef\SolutionsOnly{\DisplaySolutions\global\exb@solutionsonlytrue} \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}, +default/.style = { part problems = true, + tighten paragraphs = true, + problem header={\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, + style margins=true, problem needs space=0.2\paperheight, - no needspace/.is if={exbank@if@needspace}, - no needspace/.default = false + needspace/.is if={exbank@if@needspace}, + no needspace/.code = {\global\ifexbank@if@needspacefalse}, + show lonely part problems/.is if={exb@showLonelyPartProblems} }, exercise directory/.estore in = \@exercisesDir, % figure root directory/.estore in = \@figrootDir, % @@ -180,9 +242,9 @@ 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}, +part problems/.is if = {exb@opt@partProblems}, +tighten paragraphs/.is if = {exb@opt@tightenparagraphs}, +style margins/.is if ={exb@opt@doMargins}, switches/.cd, On/.initial = \@isTrue, on/.initial = \@isTrue, @@ -198,24 +260,59 @@ switches/.cd, \exercisebanksetup{default} \AtBeginDocument{\xdef\tpd{\the\prevdepth}} \gdef\tighten@paragraph{% -\if\exbank@opt@tightenparagraphs\@isTrue\relax% - \filbreak% +\ifexb@opt@tightenparagraphs\relax% + \filbreak% \fi% } \gdef\tighten@paragraph@solutions{% -\if\exbank@opt@tightenparagraphs\@isTrue\relax% - \if\@SolutionsOnly\@isFalse - \if\@DisplaySolutions\@isTrue - \filbreak% - \fi +\ifexb@opt@tightenparagraphs% + \ifexb@DisplaySolutions% + \filbreak% \fi \fi% } \gdef\tighten@paragraph@always{% -\if\exbank@opt@tightenparagraphs\@isTrue\relax% +\ifexb@opt@tightenparagraphs% \filbreak% \fi% } +\@dlog{unfilbreak@exercisebank} +\@ifdefinable\@My@filbreak@counter{\newcount\@My@filbreak@counter} +\global \@My@filbreak@counter = 0 +\@ifdefinable\@My@filbreak@mark{\newmarks\@My@filbreak@mark} +\renewcommand*\filbreak{% + \par + \global\advance \@My@filbreak@counter \@ne + \marks\@My@filbreak@mark{\number\@My@filbreak@counter}% + \vfil + \penalty -200 + \vfilneg +} +\newcommand*\@My@finish@stopfilbreak{} +\newcommand*\stopfilbreak{% + \par + \ifnum\prevdepth >\@m \else\prevdepth \z@ \fi + \nobreak\null + \nobreak\vskip -\baselineskip + \penalty\z@ + \begingroup + \output{% + \typeout{t: \the\pagetotal, g: \the\pagegoal}% + \unvbox\@cclv + \ifnum 0\topmarks\@My@filbreak@mark <\@My@filbreak@counter + \gdef\@My@finish@stopfilbreak{% + \penalty\z@% +}% + \else + \gdef\@My@finish@stopfilbreak{% + \penalty\z@ % +}% + \fi +}% + \break + \endgroup + \@My@finish@stopfilbreak +} \pgfkeys{ /exbanki18n/.is family, /exbanki18n, default/.style = {Problem = Problem, Solution = Solution}, Problem/.estore in = \@tr@Problem, @@ -229,42 +326,63 @@ switches/.cd, \csname @tr@#1\endcsname% }% } +\newif\ifat@isrigid \let\ea = \expandafter \begingroup\lccode`\|=`\\ \lowercase{\endgroup\def\removebs#1{\if#1|\else#1\fi}} \ifcsname at@verbose\endcsname -\global\def\@triggerLog#1{\@latex@warning{--\string\TRIGGER: #1}}% + \global\def\@triggerLog#1{\@latex@warning{--\string\TRIGGER: #1}}% \else -\global\let\@triggerLog\@gobble% + \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% +\newcommand{\At}[2]{% + \edef\mname{\exbank@macroname{#1}}% + \ifcsname At@\mname\endcsname% + \ea\g@addto@macro\csname At@\mname\endcsname{#2}% + \else% + \ifat@isrigid + \ea\gdef\csname Rigid@At@\mname\endcsname{#2}% + \else + \ea\gdef\csname At@\mname\endcsname{#2}% + \fi% + \fi% + \global\at@isrigidfalse% } +\let\@rigid\at@isrigidtrue \newcommand{\Trigger}[1]{% - \edef\mname{\exbank@macroname{#1}}% - \ea\@ifundefined{At@\mname}{}{% - \@triggerLog{\mname}\csname At@\mname\endcsname% + \edef\mname{\exbank@macroname{#1}}% + \ea\@ifundefined{Rigid@At@\mname}{}{% + \@triggerLog{\mname}\csname Rigid@At@\mname\endcsname% +}% + \ea\@ifundefined{At@\mname}{}{% + \@triggerLog{\mname}\csname At@\mname\endcsname% }% } +\newcommand{\exb@ClearHook}[1]{% + \edef\mname{\exbank@macroname{#1}}% + \expandafter\let\csname At@\mname\endcsname\relax% + \ifat@isrigid + \expandafter\let\csname Rigid@At@\mname\endcsname\relax% + \fi + \global\at@isrigidfalse% +} \xdef\figuresPath{\@figrootDir/} \gdef\fileInputPath{} +\gdef\thisfilepath{} % \gdef\fileInputBase{} +\@ifundefined{input@path}{\gdef\input@path{}}{} +\AtBeginDocument{% \providecommand*{\input@path}{} -\g@addto@macro\input@path{{\fileInputBase}{\fileInputPath}} +\providecommand*{\Ginput@path}{} +\g@addto@macro\input@path{{\fileInputBase}{\fileInputPath}}% +\g@addto@macro\Ginput@path{{\fileInputBase}{\fileInputPath}}% +} \At\PathControl{ \xdef\figuresPath{\@figrootDir/} \edef\exfile{\exerciseFile} \expandafter\filename@parse{\exfile} + \xdef\thisfilepath{\@exercisesDir/\filename@area} \xdef\fileInputPath{\figuresPath\filename@area} \xdef\fileInputBase{\figuresPath\filename@area\filename@base/} - \graphicspath{{\fileInputBase}{\fileInputPath}} - \@ifundefined{input@path}{\gdef\input@path{{\fileInputBase}{\fileInputPath}}}{} } \newlength{\pMarginBelow} \newlength{\pMarginAbove} @@ -272,43 +390,36 @@ switches/.cd, \newlength{\ppMarginBelow} \newlength{\ppMarginAbove} \newlength{\ppMargin} -\newlength{\introMargin} -\newlength{\solutionMarginLeft} +\newlength{\introOutdent} \newlength{\solutionMarginAbove} -\edef\defaultLeftMargin{\the\dimexpr1in+\hoffset} -\setlength{\ppMargin}{0.5em} +\setlength\parindent{0pt} \setlength{\pMarginLeft}{-\ppMargin-2.5em} -\setlength{\solutionMarginLeft}{\ppMargin} +\setlength{\pMarginBelow}{1.5em \@plus .5em \@minus .5em} +\setlength{\pMarginAbove}{0pt} +\setlength{\ppMargin}{0.5em} +\setlength{\ppMarginBelow}{0em} +\setlength{\ppMarginAbove}{0.5\baselineskip} +\setlength{\introOutdent}{1em} \setlength{\solutionMarginAbove}{1em} -\setlength{\pMarginBelow}{0em} -\setlength{\pMarginAbove}{\baselineskip} -\setlength{\introMargin}{-1.5em} -\setlength{\ppMarginBelow}{\baselineskip} -\setlength{\ppMarginAbove}{0em} -\setlength\parindent{0pt} -\newbox\ppmarkbox -\newlength\markskip -\setlength\markskip{4\baselineskip} -\def\solMargin{\dimexpr\ppMargin\relax} -\def\vsSize{1em} -\def\vs{\vspace{\vsSize}} \newcounter{problemcounter} \setcounter{problemcounter}{0} \newcounter{partproblemcounter} \At\VeryBeginProblem{% - \if\exbank@opt@tightenparagraphs\@isTrue\relax% + \ifexb@opt@tightenparagraphs% \ifexbank@if@needspace\needspace{\exbank@opt@problemneedspace}\fi% - \vskip-2\baselineskip\relax% \fi% \stepcounter{problemcounter}% \setcounter{partproblemcounter}{0}% - \vspace*{\pMarginAbove}% - \strut\vadjust{\vbox to 0pt{\if\exbank@opt@doMargins\@isTrue\hskip\pMarginLeft\fi{\exbank@opt@problemHeader}\vss}}\par% - \vspace*{\the\dimexpr\baselineskip+\pMarginBelow}% + \vspace\pMarginAbove% + \strut\vadjust{\vbox to 0pt{\ifexb@opt@doMargins\relax\hskip\pMarginLeft\fi{\exbank@opt@problemHeader}\vss}}\par% + \vspace\pMarginBelow\relax% } \At\EndProblem{% \tighten@paragraph% }% +\At\BeginPartproblem{% +\vspace\ppMarginAbove\relax% +} \At\VeryBeginPartproblem{% \@dinfo{Triggered Beginning Part Problem (\string\VeryBeginPartproblem)}% \stepcounter{partproblemcounter}% @@ -318,152 +429,201 @@ switches/.cd, \if\@displayMetaCounter\@isTrue\relax% \gdef\exb@prePPHead{{\Large\themetacounter}:}% \fi% - \if\exb@showtags\isTrue% - \gdef\exb@postPPHead{\exb@printCurrentTags}% + \ifexb@showtags% + \g@addto@macro\exb@postPPHead{\exb@printCurrentTags}% \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}}}% +\ifexb@opt@doMargins% +\let\exb@partProblemHeader\exbank@opt@partProblemHeader% +\ifexb@b@nextprob@header\relax% + \global\exb@b@nextprob@headerfalse% + \addtocounter{partproblemcounter}{-1}% + \let\exb@partProblemHeader\exb@nextprob@header% +\fi% +\gdef\exb@pp@lefttag{\leavevmode{\smash{\llap{{\exb@prePPHead\exb@partProblemHeader\Trigger\PartProblemHeaderSuffix}\hskip\ppMargin}\exb@postPPHead}}}% \else% -\gdef\exb@pp@lefttag{{\exbank@opt@partProblemHeader\Trigger\PartProblemHeaderSuffix}}% +\gdef\exb@pp@lefttag{{\exb@partProblemHeader\Trigger\PartProblemHeaderSuffix}}% \fi% -\AtNextPar{\exb@pp@lefttag}% -\ignorespaces}% +\ifexb@showCurrent@PPHeader% +\AtNextPar{\exb@pp@lefttag\global\let\exb@pp@lefttag\relax\Trigger\AfterPPHeader}\par% +\else% +\par% +\fi\ignorespaces}% \At\EndPartproblem{% - \vspace*{\pMarginBelow}% - \tighten@paragraph\par% + \vspace\ppMarginBelow\relax% + \tighten@paragraph% + \global\exb@showCurrent@PPHeadertrue } -\At\BeginSolution{\hfill\break\vspace*{\solutionMarginAbove}{\exbank@opt@solutionHeader}} +\At\BeginSolution{\ifexb@solutionsonly\else\hfill\break\vspace{\solutionMarginAbove}\fi{\exbank@opt@solutionHeader}} \At\EndSolution{} -\newif\ifexb@opthides +\newcounter{numppInFile} +\At\BeginPartproblem{% + \ifcsname exb@numexercises@\the\numexpr\the\c@problemcounter\endcsname% + \edef\numppex{\csname exb@numexercises@\the\numexpr\the\c@problemcounter\endcsname}% + \ifnum\numppex=\@ne% + \ifexb@showLonelyPartProblems\else% + \global\exb@showCurrent@PPHeaderfalse% + \fi + \fi% + \fi% + \stepcounter{numppInFile}% +} +\At\EndProblem{% + \immediate\write\@auxout{\string\expandafter\string\gdef\string\csname\space exb@numexercises@\the\numexpr\the\c@problemcounter\endcsname{\the\c@numppInFile}}% + \setcounter{numppInFile}{0}% +} \providecommand\exb@currentTags{} +\providecommand\exb@nextprob@header{} \pgfkeys{/exbank/problems/.cd,% -default/.style={hide=false,tag=\relax},% +initial style/.style={hide=false,tag=\relax,reset pp head},% +default/.style={initial style}, hide/.is if={exb@opthides},% tags/.estore in=\exb@currentTags,% -tag/.code={\pgfkeysalso{tags={#1}}}% +tag/.code={\pgfkeysalso{tags={#1}}}, +head/.code={\global\exb@b@nextprob@headertrue\gdef\exb@nextprob@header{#1}},% +reset pp head/.code={\global\exb@b@nextprob@headerfalse}, +solution only/.code={\ifexb@DisplaySolutions\else\pgfkeysalso{/exbank/problems/hide=true}\fi}, +reset to default/.code=\pgfkeysalso{/exbank/problems/default/.style={initial style}} } \def\nextproblem{\pgfqkeys{/exbank/problems}} +\def\resetnextproblems{\nextproblem{reset to default}} +\def\nextproblems#1{% +\edef\nextprobargs{{default/.style={#1}}}% +\expandafter\nextproblem\nextprobargs% +} +\newcounter{exb@cutfilecounter} +\global\let\do@ProcessCutFile = \ProcessCutFile \At\EndProblem{% -\if\exbank@opt@tightenparagraphs\@isTrue\relax% - \if\@SolutionsOnly\@isFalse% - \if\@DisplaySolutions\@isTrue% - \penalty-300% - \fi% - \fi% -\fi% + \ifexb@opt@tightenparagraphs\relax% + \ifexb@DisplaySolutions% + \penalty-300% + \fi% + \fi% } -\@ifundefined{figure}{}{\edef\figure{\unexpanded{\tighten@paragraph@always}\unexpanded\expandafter{\figure}} +\@ifundefined{figure}{}{ \edef\figure{\unexpanded{\tighten@paragraph@always}\unexpanded\expandafter{\figure}} } -\@ifundefined{endfigure}{}{\g@addto@macro\endfigure{\tighten@paragraph@always} +\@ifundefined{endfigure}{}{ \g@addto@macro\endfigure{\tighten@paragraph@always} } \gdef\isFalse{0} \gdef\isTrue{1} -\gdef\DisplayProblem{\isTrue} +\global\exb@DisplayCurrentProblemtrue \gdef\@displayMetaCounter{\isFalse} -\AtBeginDocument{ \if\@DisplaySolutions\isFalse - \@latex@warning{Hiding solutions. Show them with \string\DisplaySolutions} - \fi +\AtBeginDocument{ \ifexb@DisplaySolutions\else + \@latex@warning{Hiding solutions. Show them with \string\DisplaySolutions} + \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{% -\exb@ifshowproblem{\let\ProcessCutFile\do@ProcessCutFile#1\global\exb@hidenextsolfalse}{\def\ProcessCutFile{}\global\exb@hidenextsoltrue}% +\long\gdef\exb@ifshowproblem#1#2{% + \exb@isdisplayingfalse% + \ifexb@DisplayCurrentProblem% + \ifexb@opthides\else\exb@isdisplayingtrue\fi\fi% + \ifexb@isdisplaying#1\else#2\fi% +} +\long\gdef\showhideproblem#1{% + \exb@ifshowproblem{\let\ProcessCutFile\do@ProcessCutFile#1\global\exb@DisplayCurrentSolutiontrue}{\def\ProcessCutFile{}\global\exb@DisplayCurrentSolutionfalse}% } \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% + \ifexb@DisplaySolutions + \global\exb@DisplayCurrentSolutiontrue\else\global\exb@DisplayCurrentSolutionfalse + \fi + \stepcounter{metacounter}% + \@dinfo{problem: Triggering \string\DecideProblemDisplay}% + \Trigger\DecideProblemDisplay% + \@dinfo{problem:Executing - \string\showhideproblem - \the\c@problemcounter}% + \showhideproblem{% + \ifexb@opt@partProblems% + \ifexb@solutionsonly\else + \Trigger\BeginPartproblem% + \Trigger\VeryBeginPartproblem% + \fi + \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% -\@dinfo{Ended problem env}% + \ifexb@solutionsonly\def\ProcessCutFile{}\ifexb@DisplayCurrentProblem\relax\stepcounter{partproblemcounter}\fi\fi +}{% + \@dinfo{Ending problem env \the\c@problemcounter}% + \ifexb@DisplayCurrentProblem\relax% + \ifexb@opt@partProblems\relax% + \Trigger\EndPartproblem% + \tighten@paragraph + \else + \Trigger\EndProblem% + \fi% + \fi% + \@dinfo{Ended problem env}% } \g@addto@macro\AfterproblemComment{\nextproblem{default}\ignorespaces}% -\generalcomment{solution}{\@dinfo{START solution ENV}% -\Trigger\AtBeginSolutionHard -\begingroup - \if\@DisplaySolutions\isTrue - \if\DisplayProblem\isFalse - \xdef\DisplaySolution{\isFalse} - \fi - \fi - \if\DisplaySolution\isTrue - \ifexb@hidenextsol\else\Trigger\BeginSolution\fi - \else - \def\ProcessCutFile{} - \fi +\generalcomment{solution}{% + \@dinfo{START solution ENV}% + \Trigger\AtBeginSolutionHard + \begingroup + \ifexb@DisplaySolutions% + \ifexb@DisplayCurrentProblem\else% + \global\exb@DisplayCurrentSolutionfalse + \fi + \else + \global\exb@DisplayCurrentSolutionfalse + \fi + \ifexb@DisplayCurrentSolution% + \let\ProcessCutFile\do@ProcessCutFile% + \ifexb@solutionsonly\AtNextPar{\leavevmode\smash{\llap{\exbank@opt@partProblemHeader}}\Trigger\AfterPPHeader}\fi% + \ifexb@DisplayCurrentSolution\Trigger\BeginSolution\fi% + \else + \def\ProcessCutFile{}% + \fi }{% -\if\DisplaySolution\isTrue -\Trigger\EndSolution -\tighten@paragraph@solutions -\vspace*{0.5em} -\fi -\endgroup -\Trigger\EndSolutionHard\@dinfo{END solution ENV}% + \ifexb@DisplayCurrentSolution% + \Trigger\EndSolution + \tighten@paragraph@solutions + \vspace{0.5em} + \fi + \endgroup + \Trigger\EndSolutionHard\@dinfo{END solution ENV}% } \g@addto@macro\AftersolutionComment{\ignorespaces} -\def\intromargin#1{% -\if\exbank@opt@doMargins\@isTrue% -\gdef\endintromargin{\endlist\endgroup}% -\begingroup\list{}{\leftmargin#1}\item[]% -\else% -\relax\global\let\endintromargin=\relax\fi% +\def\exb@intromargin{% + \ifexb@opt@doMargins\relax% + \gdef\exb@endintromargin{\endlist\endgroup}% + \begingroup\list{}{\leftmargin-\introOutdent}\item[]% + \else% + \relax\global\let\exb@endintromargin=\relax\fi% } \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% - \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\exb@pre@intro\exb@post@intro% - \gdef\@displayIntro{\@isTrue} + \ifexb@CountIntros% + \stepcounter{metacounter}% + \Trigger\DecideProblemDisplay% + \gdef\exb@pre@intro{}% + \gdef\exb@post@intro{}% + \if\@displayMetaCounter\isTrue\relax% + \gdef\exb@pre@intro{{\leavevmode{\llap{{\Large\themetacounter}:\hspace*{-\pMarginLeft}}}}\ignorespaces}% + \fi% + \ifexb@showtags% + \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\exb@pre@intro\exb@post@intro% + \gdef\@displayIntro{\@isTrue}% }% - \exb@ifshowproblem{\intromargin{-1em}}{} - \else% - \intromargin{-1em} - \fi% -}{ \if\@countIntros\isTrue% - \Trigger\EndIntro% - \exb@ifshowproblem{\endintromargin}{} - \else - \endintromargin - \fi% - \@dinfo{END intro ENV}\ignorespaces% + \exb@ifshowproblem{\exb@intromargin}{}% + \else% + \exb@intromargin% + \fi% + \ifexb@solutionsonly\def\ProcessCutFile{}\fi +}{ \ifexb@CountIntros% + \Trigger\EndIntro% + \exb@ifshowproblem{\exb@endintromargin}{} + \else + \exb@endintromargin + \fi% + \@dinfo{END intro ENV}\ignorespaces% } \g@addto@macro\AfterintroComment{\nextproblem{default}\ignorespaces} \def\squeeze{ \newlength{\marginw} @@ -504,18 +664,18 @@ tag/.code={\pgfkeysalso{tags={#1}}}% \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 +\gdef\ifppMode#1{ \def\mname{\exbank@macroname{#1}} + \strif\mname\ppMode } -\gdef\isppMode#1#2{ \edef\mname{\exbank@macroname{#1}} - \strif{\exbank@macroname{#1}}{\ppMode}\relax#2\fi + \gdef\isppMode#1#2{ \edef\mname{\exbank@macroname{#1}} + \strif{\exbank@macroname{#1}}{\ppMode}\relax#2\fi } \gdef\@ifppMode#1{% -\ifnum\pdfstrcmp{\exbank@macroname{#1}}{\ppMode}=\z@% -\expandafter\@firstofone% -\else% -\expandafter\@noneofone% -\fi% + \ifnum\pdfstrcmp{\exbank@macroname{#1}}{\ppMode}=\z@% + \expandafter\@firstofone% + \else% + \expandafter\@noneofone% + \fi% }% \def\pm@Exclude{exclude} \def\pm@Select{select} @@ -523,84 +683,93 @@ tag/.code={\pgfkeysalso{tags={#1}}}% \let\ipm\@ifppMode \let\T@\isTrue \let\F@\isFalse +\def\exb@DPT{\global\exb@DisplayCurrentProblemtrue} +\def\exb@DPF{\global\exb@DisplayCurrentProblemfalse} \At\DecideProblemDisplay{% - \ifnum\pdfstrcmp{\ppList}{\emptyList}=\z@\relax% - \xdef\DisplayProblem{\ipm\exclude\T@\ipm\select\F@} - \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\xdef\DisplayProblem{0}}% -\fi -\fi + \ifnum\pdfstrcmp{\ppList}{\emptyList}=\z@\relax% + \ipm\exclude\exb@DPT\ipm\select\exb@DPF + \fi + \exb@int@isin{\themetacounter}{\ppList}{ \ipm\exclude\exb@DPF\ipm\select\exb@DPT\ipm\normal\exb@DPT +}{ \ipm\exclude\exb@DPT\ipm\select\exb@DPF\ipm\normal\exb@DPT +} + \ifexb@tagbuildmode + \ifexb@DisplayCurrentProblem\relax% + \exb@intersection@any{\exb@currentTags}{\exb@tagList}{\global\exb@opthidesfalse}{\global\exb@opthidestrue\global\exb@DisplayCurrentProblemfalse}% + \fi + \fi } \gdef\introarg{\@isFalse} -\gdef\noheadarg{\@isFalse} -\pgfkeys{ /makeset/.is family, /makeset, - 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 +\pgfkeys{ /makeset/.is family, /makeset, + default/.style = {noheadarg=false}, + intro/.style = {introarg=\@isTrue}, + nointro/.style = {introarg=\@isFalse}, + nohead/.style = {noheadarg=true}, + head/.style = {noheadarg=false}, + introarg/.estore in = \introarg, + noheadarg/.is if = {exb@noheadArg}, } \gdef\makesetdefaults#1{% -\edef\exb@setpgfkeys{{\unexpanded\expandafter{/makeset/default/.style = {#1}}}}% -\expandafter\pgfkeys\exb@setpgfkeys% + \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}} + 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 = {\exb@noheadArgtrue\ea\gdef\csname setlist@\exb@currentSetID @nohead\endcsname{\@isTrue}} } \gdef\@listOfSets{} \gdef\@spriteMode{\isFalse} \gdef\exbank@spriteSets{\emptyList} -\long\gdef\spritesets#1{ \gdef\exbank@spriteSets{#1} -} -\global\let\exlist@protect\noexpand -\newcommand\makeset[3][]{ \xdef\thissetid{#2} - \ea\xdef\csname setkeys@\thissetid\endcsname{#1} - \pgfkeys{/makeset, default, #1}% - \if\introarg\isTrue% - \gdef\introarg{\isTrue} - \ea\gdef\csname setlist@#2@intro\endcsname{\isTrue} - \fi - \if\noheadarg\isTrue% - \ea\gdef\csname setlist@#2@nohead\endcsname{\isTrue} - \fi - \ea\gdef\csname setlist@#2\endcsname{\exlist@protect{#3}} - \def\setmacro{\unexpanded\expandafter{\csname setlist@#2\endcsname}} - \g@addto@macro\@listOfSets{,#2} +\long\gdef\spritesets#1{ \gdef\exbank@spriteSets{#1} +} +\gdef\exb@listofsetnames{} +\global\let\exlist@protect\unexpanded +\newcommand\makeset[3][]{ \xdef\thissetid{#2} + \xdef\exb@listofsetnames{\unexpanded\expandafter{\exb@listofsetnames}\thissetid,} + \ea\xdef\csname setkeys@\thissetid\endcsname{#1} + \pgfkeys{/makeset, default, #1}% + \if\introarg\isTrue% + \gdef\introarg{\isTrue} + \ea\gdef\csname setlist@#2@intro\endcsname{\isTrue} + \fi + \ifexb@noheadArg% + \ea\gdef\csname setlist@#2@nohead\endcsname{\isTrue} + \fi + \ea\gdef\csname setlist@#2\endcsname{\exlist@protect{#3}} + \def\setmacro{\unexpanded\expandafter{\csname setlist@#2\endcsname}} + \g@addto@macro\@listOfSets{,#2} } \long\gdef\about#1{} +\newcommand\buildall{% +\edef\tmpargs{{\exb@listofsetnames}} +\dlog{\tmpargs} +\expandafter\buildsets\tmpargs +} \newcommand\sprite[1][4]{\squeeze \gdef\@spriteMode{\isTrue} \long\def\about##1{{\Large\textbf{About}:\\[1.1em]##1\\[1.5em]}} \pgfpagesuselayout{#1 on 1}[a4paper,border shrink=5mm] \ifnum\pdfstrcmp{\exbank@spriteSets}{\emptyList}=\z@\relax% - \edef\sprite@setlist{\ea\@secondoftwo\@listOfSets} - \readlist*\list@sprite@setlist\sprite@setlist - \foreachitem\set\in\list@sprite@setlist{ \edef\theset{{\set}} - \if\theset\empty\relax\else% - \buildset{\set}% - \fi% + \edef\sprite@setlist{\ea\@secondoftwo\@listOfSets} + \readlist*\list@sprite@setlist\sprite@setlist + \foreachitem\set\in\list@sprite@setlist{ \edef\theset{{\set}} + \if\theset\empty\relax\else% + \buildset{\set}% + \fi% } \else - \edef\sprite@setlist{\exbank@spriteSets} - \readlist*\list@sprite@setlist\sprite@setlist - \foreachitem\set\in\list@sprite@setlist{ \edef\theset{{\set}} - \if\theset\empty\relax\else% - \buildex{\set}% - \fi% + \edef\sprite@setlist{\exbank@spriteSets} + \readlist*\list@sprite@setlist\sprite@setlist + \foreachitem\set\in\list@sprite@setlist{ \edef\theset{{\set}} + \if\theset\empty\relax\else% + \buildex{\set}% + \fi% } \fi } \gdef\exbank@setEnv@normal#1{\exbank@setEnv{#1}{normal} } +\gdef\exerciseFile{}% \newcommand{\exbank@setEnv}[3][{-1}]{ \if\@spriteMode\isFalse% \gdef\ppList{#1} \gdef\exerciseFile{#2} @@ -611,31 +780,32 @@ nohead/.code = {\gdef\noheadarg{\@isTrue}\ea\gdef\csname setlist@\exb@currentSet \gdef\ppMode{\pm@Normal} \fi } +\global\let\exb@execChar\relax \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]}% +\long\gdef\exec#1{\exb@execChar\ex@protect{#1}} +\long\gdef\exb@def@makeset@cmd#1{\@ifnextchar[{\@exb@def@makeset@cmd{#1}}{\@exb@def@makeset@cmd{#1}[0]}} +\long\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} +\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\space(or \string\DeclareExerciseCommand where applicable)}\exb@def@makeset@cmd} \let\DeclareExerciseCommand\exb@def@makeset@cmd \newcommand{\exclude}[2]{[{#2}]{#1}{exclude}} \newcommand{\select}[2]{[{#2}]{#1}{select}} \newcommand{\orderedselect}[2]{% -\readlist*\thelist\csv@list% -\foreachitem\items\in\thelist{[{\item}]{#1},}% } -\let\exbank@isFirstProblem\isTrue -\exb@def@makeset@cmd{\phead}{ \if\exbank@isFirstProblem\isTrue% - \let\exbank@isFirstProblem\isFalse% +\exb@isFirstProblemtrue +\exb@def@makeset@cmd{\phead}{% + \ifexb@isFirstProblem% + \global\exb@isFirstProblemfalse% \else% \Trigger\EndProblem% \fi% +\par% \Trigger\BeginProblem% \Trigger\VeryBeginProblem% } -\exb@def@makeset@cmd{\pheadarg}[1]{ \if\exbank@isFirstProblem\isTrue% - \let\exbank@isFirstProblem\isFalse% +\exb@def@makeset@cmd{\pheadarg}[1]{ \ifexb@isFirstProblem% + \global\exb@isFirstProblemfalse% \else% \Trigger\EndProblem% \fi% @@ -643,91 +813,109 @@ nohead/.code = {\gdef\noheadarg{\@isTrue}\ea\gdef\csname setlist@\exb@currentSet \bgroup\def\theproblemcounter{#1}\Trigger\VeryBeginProblem\egroup% } \exb@def@makeset@cmd{\pbreak}{\clearpage} -\gdef\buildex#1{ \makeset{#1}{#1} - \buildset{#1} +\gdef\buildex#1{ \makeset{#1}{#1} + \buildset{#1} } -\gdef\@countIntros{\isFalse} +\exb@CountIntrosfalse \gdef\exb@setpgf#1{% -\edef\keystring{{/makeset,default,#1}}% -\ea\pgfkeys\keystring} + \edef\keystring{{/makeset,default,#1}}% + \ea\pgfkeys\keystring} +\long\def\exb@getnextchar#1#2\endstr{\gdef\exb@nextchar{#1}\gdef\exb@restchars{#2}} +\long\gdef\@execute@makeset@command#1{% + \@dinfo{Executing macro \@backslashchar\@gobble##1}% + \csname #1\endcsname% + \def\continueLoop{\isFalse}% +} +\long\def\@execute@exec#1{% + \def\continueLoop{\isFalse}\@dinfo{Executing custom (\string\exec) command}{#1}% +} +\long\gdef\X@exb@setEnv#1{% + \def\continueLoop{\isTrue}% + \@dinfo{Processing normal file "\exerciseFileInfo.tex"}% + \exbank@setEnv@normal{#1}% +} +\long\gdef\exb@setEnv@withOptargs#1{% + \def\continueLoop{\isTrue} + \edef\firstarg{#1} + \expandafter\exbank@setEnv\firstarg% +} +\def\set@charcode#1{\edef\testcode{\unexpanded{\the\numexpr`}#1}} +\long\def\@delegateFileInfo#1{% + \expandafter\exb@getnextchar#1\endstr% + \set@charcode\exb@nextchar\relax + \ifnum\testcode=\the\numexpr`?\relax + \relax\@execute@makeset@command\exb@restchars% + \else\ifnum\testcode = \the\numexpr`:\relax% + \@execute@exec\exb@restchars + \else\ifnum\testcode = \the\numexpr`[\relax% + \exb@setEnv@withOptargs{\exb@nextchar\exb@restchars} + \else% + \X@exb@setEnv{\exb@nextchar\exb@restchars} + \fi + \fi + \fi +} \newcommand\buildset[2][]{% - \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}}% - \ifcsname setkeys@\setName\endcsname% - \xdef\skeys{\csname setkeys@#2\endcsname}% - \exb@setpgf\skeys% - \fi% - \@ifundefined{setlist@#2}{% - \@latex@error{Couldn't find set #2. Did you remember to do \string\makeset{#2}{}?} - \stop\bye + \xdef\exb@currentSetID{#2}% + \pgfkeys{/makeset/override/.cd, #1} + \global\let\setName\exb@currentSetID% + \gdef\exb@buildset@oarg{#1} + \@ifundefined{setlist@#2@intro}{\exb@CountIntrosfalse}{\exb@CountIntrostrue}% + \@ifundefined{setlist@#2@nohead}{\gdef\nohead{\isFalse}}{\gdef\nohead{\isTrue}}% + \ifcsname setkeys@\setName\endcsname% + \xdef\skeys{\csname setkeys@#2\endcsname}% + \exb@setpgf\skeys% + \fi% + \@ifundefined{setlist@#2}{% + \exb@err{Couldn't find set #2. Did you remember to do \string\makeset{#2}{}?} + \stop\bye }{} - \let\exlist@protect\unexpanded% - \edef\exbank@setlist{\csname setlist@#2\endcsname}% - \let\exlist@protect\noexpand% - \if\@spriteMode\isFalse% - \if\exb@frontpage\@isFalse\else\input{\exb@frontpage}\fi - \Trigger\StartBuildset% - \fi% - \gdef\@delegateFileInfo{\@ifnextchar?\@execute@makeset@command\@is@exec}% - \def\@is@exec{\@ifnextchar:\@execute@exec\@is@file}% - \gdef\@is@file{\@ifnextchar[\exb@setEnv@withOptargs\X@exb@setEnv}% - \gdef\X@exb@setEnv##1{% - \def\continueLoop{\isTrue}% - \@dinfo{Processing normal file "\exerciseFileInfo.tex"}% - \exbank@setEnv@normal{\exerciseFileInfo}\bgroup\nullfont% -} - \gdef\exb@setEnv@withOptargs{% - \def\continueLoop{\isTrue}\ea\exbank@setEnv\exerciseFileInfo\bgroup\nullfont% -} - \gdef\@execute@makeset@command ?##1{% - \edef\inner{\@firstofone##1}% - \@dinfo{Executing macro \@backslashchar\@gobble##1}% - \csname\inner\endcsname% - #1\def\continueLoop{\isFalse}\ea\bgroup% -} - \def\@execute@exec:{% - \def\continueLoop{\isFalse}\@dinfo{Executing custom command}\bgroup% -} - \readlist*\setlist\exbank@setlist% - \foreachitem\exerciseFileInfo\in\setlist{% - \def\continueLoop{\isTrue}% - \gdef\ppList{\emptyList}% - \setcounter{metacounter}{0}% - \let\ex@protect\unexpanded% - \edef\exerciseFileInfo{\exerciseFileInfo}% - \ea\@delegateFileInfo\exerciseFileInfo\egroup% - \Trigger\InputExercise% - \if\continueLoop\isTrue% - \let\ex@protect\noexpand% - \Trigger\PathControl% - \if\nohead\isFalse% - \if\@spriteMode\isFalse% - \Trigger\BeginProblem% - \fi% - \fi% - \if\nohead\isFalse\Trigger\VeryBeginProblem\fi% - \if\@spriteMode\isTrue\textbf{\exerciseFile.tex\\}\fi% - \IfFileExists{\@exercisesDir/\exerciseFile}{% - \incl{\@exercisesDir/\exerciseFile}% - \if\@spriteMode\isTrue% - \setcounter{partproblemcounter}{0}% - \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 -} - \if\nohead\isFalse\Trigger\EndProblem\fi% - \fi% + \let\exlist@protect\unexpanded% + \edef\exbank@setlist{\csname setlist@#2\endcsname}% + \let\exlist@protect\unexpanded% + \if\@spriteMode\isFalse% + \if\exb@frontpage\@isFalse\else\input{\exb@frontpage}\fi + \Trigger\StartBuildset% + \fi% + \readlist*\setlist\exbank@setlist% + \foreachitem\exerciseFileInfo\in\setlist{% + \def\continueLoop{\isTrue}% + \gdef\ppList{\emptyList}% + \setcounter{metacounter}{0}% + \let\ex@protect\unexpanded% + \edef\exb@execChar{:}% + \edef\exerciseFileInfo{\exerciseFileInfo}% + \@delegateFileInfo\exerciseFileInfo% + \Trigger\InputExercise% + \if\continueLoop\isTrue% + \let\ex@protect\noexpand% + \Trigger\PathControl% + \if\nohead\isFalse% + \if\@spriteMode\isFalse% + \Trigger\BeginProblem% + \fi% + \fi% + \if\nohead\isFalse\Trigger\VeryBeginProblem\fi% + \if\@spriteMode\isTrue\textbf{\exerciseFile.tex\\}\fi% + \IfFileExists{\@exercisesDir/\exerciseFile}{% + \Trigger\InputExerciseFile + \let\exb@execChar\relax + \incl{\@exercisesDir/\exerciseFile}% + \if\@spriteMode\isTrue% + \setcounter{partproblemcounter}{0}% + \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 +} + \if\nohead\isFalse\Trigger\EndProblem\fi% + \fi% } - \if\@spriteMode\isFalse% - \Trigger\EndBuildset% - \fi% - \setcounter{problemcounter}{0}% - \setcounter{partproblemcounter}{0}% - \clearpage% + \if\@spriteMode\isFalse% + \Trigger\EndBuildset% + \fi% + \setcounter{problemcounter}{0}% + \setcounter{partproblemcounter}{0}% + \clearpage% } \newcommand\buildsets[2][]{% \xdef\csvlist{#2}% @@ -737,22 +925,27 @@ nohead/.code = {\gdef\noheadarg{\@isTrue}\ea\gdef\csname setlist@\exb@currentSet } } \newcommand\buildtags[2]{% - \global\exb@tagbuildmodetrue - \xdef\csvtags{#1}% - \xdef\csvlist{#2} + \global\exb@tagbuildmodetrue + \xdef\csvtags{#1}% + \xdef\csvlist{#2} \xdef\csvsets{#2}% \readlist*\tagsItems\csvtags% - \readlist*\setsItems\csvsets% + \readlist*\setsItems\csvsets% \foreachitem\set\in\setsItems{% - \xdef\exb@tagList{\csvtags} + \xdef\exb@tagList{\csvtags} \buildset{\set}% } - \global\exb@tagbuildmodefalse + \global\exb@tagbuildmodefalse +} +\def\buildsprite#1{\squeeze% +\gdef\@spriteMode{\isTrue} +\pgfpagesuselayout{4 on 1}[a4paper,border shrink=5mm]% +\buildsets{#1}% } -\newcommand\refcounter[1]{\edef\@currentlabel{#1}% +\providecommand\refcounter[1]{\edef\@currentlabel{#1}% } -\DeclareRobustCommand{\pplabel}[1]{ \refcounter{\theproblemcounter}\label{pr:\exerciseFile:#1} - \refcounter{\alph{partproblemcounter}}\label{pp:\exerciseFile:#1} +\DeclareRobustCommand{\pplabel}[1]{ \refcounter{\theproblemcounter}\label{pr:\exerciseFile:#1}\label{pr:global:#1} + \refcounter{\alph{partproblemcounter}}\label{pp:\exerciseFile:#1}\label{pp:global:#1} } \let\pptag = \pplabel \newcommand\pppref[1]{% @@ -761,34 +954,77 @@ nohead/.code = {\gdef\noheadarg{\@isTrue}\ea\gdef\csname setlist@\exb@currentSet \newcommand\ppref[1]{% (\ref{pr:\exerciseFile:#1}\ref{pp:\exerciseFile:#1})\relax% } +\newcommand\ppgref[1]{% +(\ref{pr:global:#1}\ref{pp:global:#1})\relax% +} \newcommand\pref[1]{% \ref{pr:\exerciseFile:#1}\relax% } +\newcommand\pgref[1]{% +\ref{pr:global:#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} + 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}}% + \AtEndDocument{% + \immediate\write\@auxout{\string\gdef\string\totalpoints{\the\c@exb@points}}% } -\At\PartProblemHeaderSuffix{\exb@currentPointsStyle} + \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\BeginPartproblem{% +\addtocounter{exb@points}{\exb@currentPoints}% +} \At\EndPartproblem{\gdef\exb@currentPoints{0}} +\providecommand\exercisepoints{} +\newcounter{exb@tmp@exercisepoints} +\setcounter{exb@tmp@exercisepoints}{0} +\At\VeryBeginProblem{ \xdef\exb@expoints@macname{exb@exercisepoints@\the\c@problemcounter} + \ifcsname\exb@expoints@macname\endcsname% + \xdef\exercisepoints{\csname\exb@expoints@macname\endcsname} + \else% + \gdef\exercisepoints{} + \fi + \setcounter{exb@tmp@exercisepoints}{0} +} +\At\BeginPartproblem{% +\addtocounter{exb@tmp@exercisepoints}{\exb@currentPoints}% +} +\At\EndProblem{% +\immediate\write\@auxout{\string\expandafter\string\gdef\string\csname\space exb@exercisepoints@\the\numexpr\the\c@problemcounter\endcsname{\the\c@exb@tmp@exercisepoints}}% +} \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}% +\At\DecideProblemDisplay{\ifexb@DisplayCurrentProblem\relax% +\ifx\exb@hidetaglist\empty\relax\else +\exb@intersection@any{\exb@currentTags}{\exb@hidetaglist}{\global\exb@opthidestrue}{}% +\fi \fi +} +\gdef\HideTags#1{\xdef\exb@hidetaglist{\unexpanded\expandafter{\exb@hidetaglist},#1}} +\gdef\ShowAllTags{\gdef\exb@hidetaglist{}} +\global\let\@exercisenote\@nil% +\gdef\@addExercisenote#1{% + \ifx\@exercisenote\@@nil% + \gdef\@exercisenote{#1}% + \else + \g@addto@macro{\@exercisenote}{\par#1} \fi } -\gdef\HideTags#1{\xdef\exb@hidetaglist{#1}} +\At\VeryBeginProblem{% +\ifx\@exercisenote\@@nil\else% +\begingroup\list{}{\leftmargin-\introOutdent}\item[]% +\@exercisenote% +\endlist\endgroup% +\global\let\@exercisenote\nil% +\fi% +} +\DeclareExerciseCommand\exercisenote[1]{\@addExercisenote{#1}} |