% 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>
%% -------------------------------------------------------------------------------------------
%% This work may be distributed and/or modified under the
%% conditions of the LaTeX Project Public License, either version 1.3c
%% of this license or (at your option) any later version.
%% The latest version of this license is in
%%   http://www.latex-project.org/lppl.txt
%% and version 1.3c or later is part of all distributions of LaTeX
%% 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/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
}
\@ifundefined{exercisesDir}{\gdef\@exercisesDir{.}
}{}
\global\let\incl = \input
\usepackage{xstring}
\usepackage{pgffor}
\usepackage{scrextend}
\usepackage{comment}
\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,
  problem header={\normalfont\Large\bfseries\@tr{Problem}~\theproblemcounter},
  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,
part problems/.style = {switches/#1/.get = \exbank@opt@partProblems},
tighten paragraphs/.style = {switches/#1/.get = \exbank@opt@tightenparagraphs},
switches/.cd,
  On/.initial = \@isTrue,
  on/.initial = \@isTrue,
  T/.initial =  \@isTrue
  Off/.initial = \@isFalse,
  off/.initial = \@isFalse,
  F/.initial = \@isFalse,
}
\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,
  Solution/.estore in = \@tr@Solution
}
\newcommand{\translateExBank}[1]{  \pgfkeys{/exbanki18n, default, #1}%
}
\translateExBank{}
\gdef\@tr#1{\@ifundefined{@tr@#1}{#1}{  \csname @tr@#1\endcsname
}
}
\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
}
  \fi
}
\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}
\newlength{\pMarginAbove}
\newlength{\pMarginLeft}
\newlength{\ppMarginBelow}
\newlength{\ppMarginAbove}
\newlength{\ppMargin}
\newlength{\ppPullback}
\setlength{\ppLeading}{4em}
\setlength{\pMarginBelow}{1em}
\setlength{\pMarginAbove}{1em}
\setlength{\pMarginLeft}{-1.5em}
\setlength{\ppMarginBelow}{2em}
\setlength{\ppMarginAbove}{2em}
\setlength{\ppMargin}{2em}
\setlength{\ppPullback}{3.5em}
\def\solMargin{\dimexpr\ppMargin\relax}
\def\vsSize{1em}
\def\vs{\vspace{\vsSize}}
\newcounter{problemcounter}
\setcounter{problemcounter}{0}
\newcounter{partproblemcounter}
\At\VeryBeginProblem{	\stepcounter{problemcounter}
	\setcounter{partproblemcounter}{0}
	\vspace*{\pMarginAbove}
	\begin{addmargin}{\pMarginLeft}
		{\exbank@opt@problemHeader}
	\end{addmargin}
	\vspace*{\pMarginBelow}
}
\At\EndProblem{\tighten@paragraph
}
\At\VeryBeginPartproblem{%
	\stepcounter{partproblemcounter}%
	\bgroup
	\if\@displayMetaCounter\isTrue\relax%
		\ex@before\exbank@opt@partProblemHeader{{\Large\themetacounter}:}
	\fi
	\begin{addmargin}{\ppMargin}
		\begin{itemize}
			\item[\exbank@opt@partProblemHeader]
}
\At\EndPartproblem{		\end{itemize}
	\end{addmargin}
	\egroup\tighten@paragraph
	\vspace*{\pMarginBelow}%
}
\At\BeginSolution{	\vspace*{1em}
	\begin{addmargin}{\solMargin}
		\begin{itemize}
			\item[\exbank@opt@solutionHeader]
}
\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}
\AtBeginDocument{  \if\@DisplaySolutions\isFalse
    \@latex@warning{Hiding solutions. Show them with \string\DisplaySolutions}
  \fi
}
\global\let\do@ProcessCutFile = \ProcessCutFile
\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
     \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
      \else
        \Trigger\EndProblem
      \fi
    \fi
  \endgroup
}
\generalcomment{solution}
{\Trigger\AtBeginSolutionHard
\begingroup
  \if\@DisplaySolutions\isTrue
    \if\DisplayProblem\isFalse
      \xdef\DisplaySolution{\isFalse}
    \fi
  \fi
  \if\DisplaySolution\isTrue
    \Trigger\BeginSolution
  \else
    \def\ProcessCutFile{}
  \fi
}{\if\DisplaySolution\isTrue
\Trigger\EndSolution
\tighten@paragraph@solutions
\vspace*{0.5em}
\fi
\endgroup
\Trigger\EndSolutionHard%
}
\generalcomment{intro}{  \if\@countIntros\isTrue
    \stepcounter{metacounter}
    \Trigger\DecideProblemDisplay
    \begingroup
    \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
    \endgroup
  \fi
  \vspace*{1em}
}
\def\squeeze{  \newlength{\marginw}
  \setlength{\marginw}{1.5cm}
  \newgeometry{margin=\marginw}
  \renewcommand{\topfraction}{0.85}
  \renewcommand{\bottomfraction}{0.85}
  \renewcommand{\textfraction}{0.1}
  \renewcommand{\floatpagefraction}{0.85}
  \renewcommand{\dbltopfraction}{0.85}
  \renewcommand{\dblfloatpagefraction}{.85}
  \setcounter{topnumber}{25}
  \setcounter{bottomnumber}{25}
  \setcounter{totalnumber}{25}
  \setcounter{dbltopnumber}{25}
  \renewcommand{\baselinestretch}{0.9}
  \let\markeverypar\everypar
  \newtoks\everypar
  \everypar\markeverypar
  \markeverypar{\the\everypar\looseness=-1\relax}
  \g@addto@macro\define@newfont{%
    \fontdimen2\font@name=0.8\fontdimen2\font@name
}%
  \fontdimen2\font@name=0.8\fontdimen2\font@name
    \thinmuskip=0mu plus 3mu
    \medmuskip=1mu plus 4mu
    \thickmuskip=2mu plus 5mu
    \abovedisplayskip=0pt plus 3pt
    \belowdisplayskip=0pt plus 3pt
    \abovedisplayshortskip=0pt plus 3pt
    \belowdisplayshortskip=0pt plus 3pt
}
\let\ea = \expandafter
\newcounter{metacounter}
\setcounter{metacounter}{0}
\gdef\emptyList{0}
\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\@ifppMode#1{%
\ifnum\pdfstrcmp{\exbank@macroname{#1}}{\ppMode}=\z@%
\expandafter\@firstofone%
\else%
\expandafter\@noneofone%
\fi%
}%
\def\pm@Exclude{exclude}
\def\pm@Select{select}
\def\pm@Normal{normal}
\let\ipm\@ifppMode
\let\T@\isTrue
\let\F@\isFalse
\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
}
\pgfkeys{ /makeset/.is family, /makeset,
 default/.style = {noheadarg=\isFalse, introarg=\isFalse},
 intro/.style = {introarg=\isTrue},
 nohead/.style = {noheadarg=\isTrue},
 introarg/.estore in = \introarg,
 noheadarg/.estore in = \noheadarg
}
\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{\exlist@protect{#3}}
  \def\setmacro{\unexpanded\expandafter{\csname setlist@#2\endcsname}}
  \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]
\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{\exbank@setEnv}[3][{-1}]{  \if\@spriteMode\isFalse%
    \gdef\ppList{#1}
    \gdef\exerciseFile{#2}
    \gdef\ppMode{#3}
  \else
    \gdef\ppList{\emptyList}
    \gdef\exerciseFile{#2}
    \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}
\newcommand\buildset[2][]{  \def\oarg{#1}
  \@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
}{}
  \let\exlist@protect\unexpanded
  \edef\exbank@setlist{\csname setlist@#2\endcsname}
  \let\exlist@protect\noexpand
  \if\@spriteMode\isFalse
    \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}%
    \@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
      \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%
}
  \if\@spriteMode\isFalse
    \Trigger\EndBuildset
  \fi
}
\newcommand\refcounter[1]{\edef\@currentlabel{#1}%
}
\DeclareRobustCommand{\pplabel}[1]{	\refcounter{\theproblemcounter}\label{pr:\exerciseFile:#1}
	\refcounter{\alph{partproblemcounter}}\label{pp:\exerciseFile:#1}
}
\let\pptag = \pplabel
\newcommand\pppref[1]{%
(\ea\@alph\ref{pp:\exerciseFile:#1})\relax%
}
\newcommand\ppref[1]{%
(\ref{pr:\exerciseFile:#1}\ref{pp:\exerciseFile:#1})\relax%
}
\newcommand\pref[1]{%
\ref{pr:\exerciseFile:#1}\relax%
}
