From 0c9f0e3c20d7b39baa0fdbdc1563c13349ad108a Mon Sep 17 00:00:00 2001
From: Karl Berry <karl@freefriends.org>
Date: Sun, 29 Apr 2018 21:46:58 +0000
Subject: exercisebank (29apr18)

git-svn-id: svn://tug.org/texlive/trunk@47483 c570f23f-e606-0410-a88d-b1316a301751
---
 .../tex/latex/exercisebank/exercisebank.sty        | 350 +++++++++++++++------
 1 file changed, 254 insertions(+), 96 deletions(-)

(limited to 'Master/texmf-dist/tex/latex/exercisebank/exercisebank.sty')

diff --git a/Master/texmf-dist/tex/latex/exercisebank/exercisebank.sty b/Master/texmf-dist/tex/latex/exercisebank/exercisebank.sty
index 059c4e1973b..6d32887e413 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.1.0 (2018/04/08) - build 55
+% Source (with comments) can be found at https://github.com/Strauman/exercisebank/
+%% The LaTeX package exercisebank - version v0.1.4 (2018/04/28) - build 74
 %% 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/04/08 v0.1.0 Creates a setup that gives freedom in making sets and exercises.]
-\PackageWarningNoLine{exercisebank-v0.1.0}{This package is in the alpha 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{exbank}}
+\ProvidesPackage{exercisebank}[2018/04/28 v0.1.4 Creates a setup that gives freedom in making sets and exercises.]
+\xdef\exbank@quiet{1}
+\PackageWarningNoLine{exercisebank-v0.1.4}{This package is in the alpha 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
 }
@@ -29,8 +30,59 @@
 \usepackage{calc}
 \usepackage{pgfpages}
 \usepackage{geometry}
+\usepackage{listofitems}
+\usepackage{trimspaces}
 \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\strif#1#2{%
+ \ifnum\pdfstrcmp{#1}{#2}=\z@\relax%
+}
+\let\ea = \expandafter
+\begingroup\lccode`\|=`\\
+\lowercase{\endgroup\def\removebs#1{\if#1|\else#1\fi}}
+\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
+}
+\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
+}%
+}
+}
+\edef\@isTrue{1}
+\edef\@isFalse{0}
+\gdef\ShowNumbers{\gdef\@displayMetaCounter{\isTrue}}
+\gdef\@DisplaySolutions{\@isFalse}
+\gdef\DisplaySolutions{\xdef\@DisplaySolutions{\isTrue}\@latex@warning{Showing solutions}}
+\gdef\@SolutionsOnly{\@isFalse}
+\gdef\SolutionsOnly{\xdef\@SolutionsOnly{\@isTrue}\DisplaySolutions}
 \pgfkeys{/exbanksetup/.is family, /exbanksetup,
 default/.style = {  part problems = On,
   tighten paragraphs = True,
@@ -38,8 +90,10 @@ default/.style = {  part problems = On,
   part problem header={\large\textbf{(\theproblemcounter\alph{partproblemcounter})}},
   solution header={\large{\textbf{\@tr{Solution}:}}},
   exercise directory=.,
+  figure root directory=\@exercisesDir,
 },
 exercise directory/.estore in = \@exercisesDir, %
+figure root directory/.estore in = \@figrootDir, %
 problem header/.store in = \exbank@opt@problemHeader,
 part problem header/.store in = \exbank@opt@partProblemHeader,
 solution header/.store in = \exbank@opt@solutionHeader,
@@ -56,6 +110,30 @@ switches/.cd,
 \newcommand\exercisebanksetup[1]{  \pgfkeys{/exbanksetup, #1}%
 }
 \exercisebanksetup{default}
+\AtBeginDocument{\xdef\tpd{\the\prevdepth}}
+\gdef\tighten@paragraph{%
+\if\exbank@opt@tightenparagraphs\@isTrue\relax%
+  \if\@SolutionsOnly\@isFalse
+    \if\@DisplaySolutions\@isFalse
+      \filbreak%
+    \fi
+  \fi
+\fi%
+}
+\gdef\tighten@paragraph@solutions{%
+\if\exbank@opt@tightenparagraphs\@isTrue\relax%
+  \if\@SolutionsOnly\@isFalse
+    \if\@DisplaySolutions\@isTrue
+      \filbreak%
+    \fi
+  \fi
+\fi%
+}
+\gdef\tighten@paragraph@always{%
+\if\exbank@opt@tightenparagraphs\@isTrue\relax%
+\filbreak%
+\fi%
+}
 \pgfkeys{ /exbanki18n/.is family, /exbanki18n,
   default/.style = {Problem = Problem, Solution = Solution},
   Problem/.estore in = \@tr@Problem,
@@ -68,18 +146,35 @@ switches/.cd,
 }
 }
 \let\ea = \expandafter
-\def\removebs#1{\if#1\@backslashchar\else#1\fi}
-\newcommand{\At}[2]{  \def\macname{\expandafter\removebs\detokenize{#1}}
-  \let\mname = \macname
+\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
+}
   \fi
 }
-\newcommand{\Trigger}[1]{  \def\macname{\expandafter\removebs\detokenize{#1}}
-  \let\mname = \macname
-  \@ifundefined{At@\mname}{}{\csname At@\mname\endcsname}
+\newcommand{\Trigger}[1]{  \edef\mname{\exbank@macroname{#1}}
+  \ea\@ifundefined{At@\mname}{}{%
+  \csname At@\mname\endcsname%
+}%
+}
+\xdef\figuresPath{\@figrootDir/}
+\gdef\fileInputPath{}
+\gdef\fileInputBase{}
+\providecommand*{\input@path}{}
+\g@addto@macro\input@path{{\fileInputBase}{\fileInputPath}}
+\At\PathControl{  \xdef\figuresPath{\@figrootDir/}
+  \edef\exfile{\exerciseFile}
+  \expandafter\filename@parse{\exfile}
+  \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{\ppLeading}
 \newlength{\pMarginBelow}
@@ -111,17 +206,21 @@ switches/.cd,
 	\end{addmargin}
 	\vspace*{\pMarginBelow}
 }
-\At\EndProblem{	\if\exbank@opt@tightenparagraphs\isTrue\filbreak\fi
+\At\EndProblem{\tighten@paragraph
 }
 \At\VeryBeginPartproblem{%
 	\stepcounter{partproblemcounter}%
+	\bgroup
+	\if\@displayMetaCounter\isTrue\relax%
+		\ex@before\exbank@opt@partProblemHeader{{\Large\themetacounter}:}
+	\fi
 	\begin{addmargin}{\ppMargin}
-		\if\exbank@opt@tightenparagraphs\isTrue\filbreak\fi
 		\begin{itemize}
 			\item[\exbank@opt@partProblemHeader]
 }
 \At\EndPartproblem{		\end{itemize}
 	\end{addmargin}
+	\egroup\tighten@paragraph
 	\vspace*{\pMarginBelow}%
 }
 \At\BeginSolution{	\vspace*{1em}
@@ -132,36 +231,43 @@ switches/.cd,
 \At\EndSolution{		\end{itemize}
 	\end{addmargin}
 }
+\At\EndProblem{%
+\if\exbank@opt@tightenparagraphs\@isTrue\relax%
+  \if\@SolutionsOnly\@isFalse%
+    \if\@DisplaySolutions\@isTrue%
+      \penalty-300%
+    \fi%
+  \fi%
+\fi%
+}
+\@ifundefined{figure}{}{\edef\figure{\unexpanded{\tighten@paragraph@always}\unexpanded\expandafter{\figure}}
+}
+\@ifundefined{endfigure}{}{\g@addto@macro\endfigure{\tighten@paragraph@always}
+}
 \gdef\isFalse{0}
 \gdef\isTrue{1}
 \gdef\DisplayProblem{\isTrue}
 \gdef\@displayMetaCounter{\isFalse}
-\gdef\ShowNumbers{\gdef\@displayMetaCounter{\isTrue}}
-\gdef\@DisplaySolutions{\isFalse}
-\gdef\DisplaySolutions{\xdef\@DisplaySolutions{\isTrue}\@latex@warning{Showing solutions}}
 \AtBeginDocument{  \if\@DisplaySolutions\isFalse
     \@latex@warning{Hiding solutions. Show them with \string\DisplaySolutions}
   \fi
 }
 \global\let\do@ProcessCutFile = \ProcessCutFile
 \gdef\showhideproblem#1{%
-  \if\@displayMetaCounter\isTrue%
-    {P:\Large\themetacounter}
-    \Trigger\BeginPartproblem
-    \Trigger\VeryBeginPartproblem
-    \gdef\DisplayProblem{\isTrue}
+  \if\DisplayProblem\isFalse
+    \def\ProcessCutFile{}
   \else
-    \if\DisplayProblem\isFalse
-      \def\ProcessCutFile{}
-    \else
-      #1
-    \fi
+    \if\@SolutionsOnly\@isTrue\relax%
+    \def\ProcessCutFile{}\fi%
+    #1
   \fi
 }
 \generalcomment{problem}{  \edef\DisplaySolution{\@DisplaySolutions}
+  \stepcounter{metacounter}
   \Trigger\DecideProblemDisplay
   \begingroup
-     \showhideproblem{        \if\exbank@opt@partProblems\isTrue
+     \showhideproblem{%
+        \if\exbank@opt@partProblems\isTrue
             \Trigger\BeginPartproblem
             \Trigger\VeryBeginPartproblem
         \else
@@ -169,9 +275,10 @@ switches/.cd,
             \Trigger\VeryBeginProblem
         \fi
 }
-}{    \if\DisplayProblem\isFalse\else
+}{    \if\DisplayProblem\@isFalse\relax\else
       \if\exbank@opt@partProblems\isTrue
         \Trigger\EndPartproblem
+        \tighten@paragraph
       \else
         \Trigger\EndProblem
       \fi
@@ -193,14 +300,28 @@ switches/.cd,
   \fi
 }{\if\DisplaySolution\isTrue
 \Trigger\EndSolution
+\tighten@paragraph@solutions
+\vspace*{0.5em}
 \fi
-\Trigger\EndSolutionHard
 \endgroup
+\Trigger\EndSolutionHard%
 }
 \generalcomment{intro}{  \if\@countIntros\isTrue
+    \stepcounter{metacounter}
     \Trigger\DecideProblemDisplay
     \begingroup
-    \showhideproblem{\Trigger\BeginIntro}
+    \if\@displayMetaCounter\isTrue\relax%
+    {\exb@lmargin{{\Large\themetacounter}}{\pMarginLeft}}
+    \fi
+    \if\@spriteMode\isTrue
+      \if\introarg\isTrue
+        \stepcounter{partproblemcounter}
+      \fi
+    \fi
+    \showhideproblem{%
+      \tighten@paragraph%
+      \Trigger\BeginIntro%
+}
   \fi
 }{  \if\@countIntros\isTrue
     \Trigger\EndIntro
@@ -208,25 +329,6 @@ switches/.cd,
   \fi
   \vspace*{1em}
 }
-\gdef\isin#1#2#3#4{  \def\needle{#2}
-  \def\haystack{#1}
-  \def\isFalse{0}
-  \let\isInList = \isFalse
-  \IfInteger{\haystack}{    \if\haystack\needle
-    #3
-    \else
-    #4
-    \fi
-}{  \foreach\pp in #1{    \if\pp\needle
-      \gdef\isInList{1}
-      #3
-    \fi
-}
-  \if\isInList\isFalse
-    #4
-  \fi
-}
-}
 \def\squeeze{  \newlength{\marginw}
   \setlength{\marginw}{1.5cm}
   \newgeometry{margin=\marginw}
@@ -259,20 +361,16 @@ switches/.cd,
 }
 \let\ea = \expandafter
 \newcounter{metacounter}
-\def\emptyList{-1}
-\begingroup\lccode`\|=`\\
-\lowercase{\endgroup\def\removebs#1{\if#1|\else#1\fi}}
-\newcommand{\macroname}[1]{\expandafter\removebs\string#1}
-\gdef\ifppMode#1{  \def\mname{\macroname{#1}}
-  \if\mname\ppMode
+\setcounter{metacounter}{0}
+\gdef\emptyList{0}
+\gdef\ifppMode#1{  \def\mname{\exbank@macroname{#1}}
+  \strif\mname\ppMode
 }
-\gdef\isppMode#1#2{  \edef\mname{\macroname{#1}}
-  \if{\macroname{#1}}\ppMode#2\fi
+\gdef\isppMode#1#2{  \edef\mname{\exbank@macroname{#1}}
+  \strif{\exbank@macroname{#1}}{\ppMode}\relax#2\fi
 }
-\gdef\@noneofone#1{}
-\gdef\@noneOfTwo#1#2{}
 \gdef\@ifppMode#1{%
-\ifnum\pdfstrcmp{\macroname{#1}}{\ppMode}=\z@%
+\ifnum\pdfstrcmp{\exbank@macroname{#1}}{\ppMode}=\z@%
 \expandafter\@firstofone%
 \else%
 \expandafter\@noneofone%
@@ -280,17 +378,18 @@ switches/.cd,
 }%
 \def\pm@Exclude{exclude}
 \def\pm@Select{select}
+\def\pm@Normal{normal}
 \let\ipm\@ifppMode
 \let\T@\isTrue
 \let\F@\isFalse
-\At\DecideProblemDisplay{  \if\ppList\emptyList
-    \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@}
+\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
-  \stepcounter{metacounter}
+    \fi
 }
 \pgfkeys{ /makeset/.is family, /makeset,
  default/.style = {noheadarg=\isFalse, introarg=\isFalse},
@@ -301,69 +400,125 @@ switches/.cd,
 }
 \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][]{  \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{#3}
+  \ea\gdef\csname setlist@#2\endcsname{\exlist@protect{#3}}
   \def\setmacro{\unexpanded\expandafter{\csname setlist@#2\endcsname}}
-  \g@addto@macro\@listOfSets{#2}
+  \g@addto@macro\@listOfSets{,#2}
 }
 \long\gdef\about#1{}
 \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]
-  \foreach\set in \@listOfSets{    \buildset{\set}
+\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%
+}
+\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%
 }
+\fi
+}
+\gdef\exbank@setEnv@normal#1{\exbank@setEnv{#1}{normal}
 }
-\newcommand{\redef}[3][{-1}]{  \if\@spriteMode\isFalse%
+\newcommand{\exbank@setEnv}[3][{-1}]{  \if\@spriteMode\isFalse%
     \gdef\ppList{#1}
     \gdef\exerciseFile{#2}
     \gdef\ppMode{#3}
   \else
-    \gdef\ppList{}
+    \gdef\ppList{\emptyList}
     \gdef\exerciseFile{#2}
-    \gdef\ppMode{exclude}
-\fi
+    \gdef\ppMode{\pm@Normal}
+  \fi
 }
 \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}%
+}
+\let\exbank@isFirstProblem\isTrue
+\exbank@def@makeset@command{\phead}{  \if\exbank@isFirstProblem\isTrue%
+    \let\exbank@isFirstProblem\isFalse%
+  \else%
+    \Trigger\EndProblem%
+  \fi%
+  \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}}
 \gdef\@countIntros{\isFalse}
-\gdef\phead{?\noexpand\Trigger\noexpand\VeryBeginProblem}
 \newcommand\buildset[2][]{  \def\oarg{#1}
-  \@ifundefined{setlist@#2@intro}{\gdef\@countIntros{\isFalse}}{\gdef\@countIntros{\isTrue}\@latex@warning{Counting intros}}
+  \@ifundefined{setlist@#2@intro}{\gdef\@countIntros{\isFalse}}{\gdef\@countIntros{\isTrue}\@dlog{Counting intros}}
   \@ifundefined{setlist@#2@nohead}{\gdef\nohead{\isFalse}}{\gdef\nohead{\isTrue}}
   \xdef\setName{#2}
   \@ifundefined{setlist@#2}{    \@latex@error{Couldn't find set #2. Did you remember to do \string\makeset{#2}{}?}
     \stop\bye
 }{}
-  \edef\setlist{\csname setlist@#2\endcsname}
+  \let\exlist@protect\unexpanded
+  \edef\exbank@setlist{\csname setlist@#2\endcsname}
+  \let\exlist@protect\noexpand
   \if\@spriteMode\isFalse
     \Trigger\StartBuildset
   \fi
-  \foreach\exerciseFileInfo in \setlist{    \def\continueLoop{\isTrue}
-    \gdef\ppList{-1}
-    \setcounter{metacounter}{1}
-    \StrLeft{\exerciseFileInfo}{1}[\firstchar]%
-    \if[\firstchar
-      \ea\redef\exerciseFileInfo\relax
-      \def\continueLoop{\isTrue}
-    \else\if?\firstchar
-        \expandafter\@secondoftwo\exerciseFileInfo
-      \def\continueLoop{\isFalse}
-    \else
-        \redef{\exerciseFileInfo}{normal}
-        \def\continueLoop{\isTrue}
-    \fi\fi
-    \if\continueLoop\isTrue
+  \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}%
+    \@dlog{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}
+    \@dlog{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
+}
+  \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
@@ -372,11 +527,14 @@ switches/.cd,
     \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
+    \fi%
 }
   \if\@spriteMode\isFalse
     \Trigger\EndBuildset
@@ -385,14 +543,14 @@ switches/.cd,
 \newcommand\refcounter[1]{\edef\@currentlabel{#1}%
 }
 \DeclareRobustCommand{\pplabel}[1]{	\refcounter{\theproblemcounter}\label{pr:\exerciseFile:#1}
-	\refcounter{\thepartproblemcounter}\label{pp:\exerciseFile:#1}
+	\refcounter{\alph{partproblemcounter}}\label{pp:\exerciseFile:#1}
 }
 \let\pptag = \pplabel
 \newcommand\pppref[1]{%
-(\ref{pp:\exerciseFile:#1})\relax%
+(\ea\@alph\ref{pp:\exerciseFile:#1})\relax%
 }
 \newcommand\ppref[1]{%
-\ref{pr:\exerciseFile:#1}\ref{pp:\exerciseFile:#1}\relax%
+(\ref{pr:\exerciseFile:#1}\ref{pp:\exerciseFile:#1})\relax%
 }
 \newcommand\pref[1]{%
 \ref{pr:\exerciseFile:#1}\relax%
-- 
cgit v1.2.3

