Put pbuilder.sty
in your LaTeX/Overleaf folder, then in the preamble add
\usepackage{pbuilder}
.
... % other preamble
\usepackage{pbuilder}
\begin{document}
... % intro
% Problem 1
\problem{...}
\solution{...}
% Problem 2
\problem{...}
\solution{...}
... % more problems
\subsection*{Problems}
\buildproblems
\subsection*{Solutions}
\buildsolutions
Hints section
...
% Problem 1
\problem{...}
\solution{...}
% Problem 2
\problem{...}
\solution{...}
\hint{...} % not every problem needs to have a hint!
% Problem 3
\problem{...}
\solution{...}
...
\subsection*{Hints}
\buildhints
Custom formats (e.g. if you want to have the solutions repeat the problem and the solutions)
...
% in preamble
\renewcommand\solutionitemformat{
\textbf{Problem \getproblemnumber.} \getproblem
\textit{Solution.} \getsolution
}{}
}
\renewcommand\solutionoverallformat[1]{
#1
}
...
\subsection*{Solutions}
\buildsolutions % same usage!
New fields - e.g. if you wanted to add sources for some of the problems.
...
% in preamble
\newfield{problemsource}
% and maybe I want to incorporate it into the solutions:
\renewcommand\solutionitemformat{
\ifcsdef{getsolution}{
\textbf{Problem \getproblemnumber.} \ifcsdef{getproblemsource}{(\getproblemsource)}{} \getproblem
\textit{Solution.} \getsolution
}{}
}
...
Multiple sections
... % preamble
\section{Section A}
% Problem A1
\problem{...}
\solution{...}
% Problem A2
\problem{...}
\solution{...}
\hints{...}
...
\subsection*{Problems}
\buildproblems
\saveandreset{sectionA} % resets the problem counter and stores everything so far
\newpage
\section{Section B}
% Problem B1
\problem{...}
\solution{...}
...
\subsection*{Problems}
\buildproblems
\saveandreset{sectionB}
\newpage
\section*{Hints}
\buildallhints
\newpage
\section*{Solutions}
% maybe we only have solutions for Section A...
\load{sectionA}
\buildsolutions
Examples
% in preamble
% format of the examples
\newcommand\exampleitemformat{
\ifcsdef{getproblemsource}{\begin{example}[\getproblemsource]}{\begin{example}}%
\getproblem
\end{example}
\ifcsdef{getsolution}{\textit{Solution.} \getsolution}{}
}
\newcommand\exampleitemoverall[1]{
#1
}
% some commands to reload the "Examples" section each time
\saveandreset{Examples} % init
\newcommand\loadexample{%
\load{Examples}%
}
\newcommand\showexample{
\showonecustom{\exampleitemformat}{\exampleitemoverall}
\saveandreset{Examples}
}
...
% an example in text
\loadexample
\problem{...}
\solution{...}
\showexample
% you might want this, for instance, if you want to let your students try all the examples ahead of the session
\section*{All examples used}
\loadexample
\buildproblems
The rough org structure of data is:
sections problems fields
Section A - Problem 1 - problem
| | solution
| | (hint?)
- Problem 2 - problem
| | solution
| | (hint?)
Section B - Problem 1 - problem
| | solution
| | (hint?)
- Problem 2 - problem
| | solution
| | (hint?)
fields
are things like problem(s)
, solution(s)
and hint(s)
, but you can also define your own in the preamble using
\newfield{<field>}
This makes the command \<field>
.
The package ships with the following by default:
%% standard template
\newfield[key]{problem}
\newfield{solution}
\newfield{hint}
The [key]
option just indicates that we increase the counter whenever we see a new \problem
. This means that the other fields don't have to be in order, as long as it is between the current \problem
and the next \problem
.
% this works
\problem{...}
\solution{...}
\hint{...}
% this also works
\problem{...}
\hint{...}
\solution{...}
status(es)
are basically field(s)
but boolean.
% e.g. if we want to track which problems were used
% preamble
\newstatus{used}
% a problem
\problem{...}
\used
Each <field>
comes with a \build<field>s
command. This compiles all instances of the field given so far "in memory".
\build<field>s
can be customized by changing \<field>itemformat
and \<field>overallformat
:
% output of \build<field>s
\<field>overallformat{
\<field>itemformat
\<field>itemformat
...
\<field>itemformat
}
The defaults are
\newcommand\fieldoverallformat[#1]{
\begin{enumerate}
#1
\end{enumerate}
}
\newcommand\fielditemformat[#1]{
\item[\getproblemnumber.] \get<field>
}
Ok, this is a slight simplification.
In \<field>itemformat
, you are allowed to use any field available via \get<field>
. In addition, you can refer to the problem number (within the section) by \getproblemnumber
.
Useful patterns:
- If you want to check e.g. if there's a solution, you can do
\ifcsdef{getsolution}{%
% if there is a solution
}{%
% if there isn't a solution
}
The default \<field>itemformat
actually skips over problems whose <field>
is blank.
One can store and wipe the memory using \saveandreset{<section-name>}
. This is typically happens after you compile the problems.
To recover a previously stored section, you can do \load{<section-name>}
.
TODO
e.g. \showonecustom{...}{...}
- finish basic docs
- more examples
- statuses
- problem bank