# Dynamic Spacing in exam Package

I'm using the exam package for creating exercise questions of a class and trying to leave empty spaces dynamically according to the length of the solution, instead of setting a static value.

The exam package provides an option to print the solutions or leave an empty space for students to answer when solutions not printed. This option is set by the following commands:

\printanswers


or

\noprintanswers


A question and a solution is formatted as follows:

\begin{questions}
\question This is a question text
\begin{solution}[2in]
\begin{itemize}
\item A hundred answers maybe
\end{itemize}
\end{solution}
\end{questions}


Here the solution space is defined in this line:

\begin{solution}[2in]


What I'm currently doing is to set a variable called \solspace and use it for each solution across the document. I can manually set a proper value for the solution space depending on the length of the solution as well, but that's not the best way.

What I want to do is to (ideally) calculate how much space the solution would take (when \printanswers) and use this value in \solution[2in] instead of the static value of 2in. It could also be possible to somehow estimate the length of the solution and use a proper length for the space. Note that solutions are not limited to items or text, could be formulas or images.

Any ideas on how to approach this problem?

Example:

• if you distribute the exam on paper you could simply print the solutions in white. (This is not a good plan if the students can access the PDF :-) Mar 31 '19 at 16:13
• What about wrapping a vphantom around the whole solution? Apr 1 '19 at 0:00
• @grendelsdad doesn't work well as the solution contains itemize env or other envs, the structure of the solutions varies from images to formulas Apr 3 '19 at 9:58
• Note that solution and solutionbox use totally different approaches. Apr 3 '19 at 15:27
• @JohnKormylo right, edited the sample image accordingly Apr 3 '19 at 19:47

The problem is that you really don't know how wide \linewidth is until you are in the solution environment, at which point is too late. Besides, handwriting uses more space than typesetting, although I suppose you could just multiply by some factor.

The assumes that all solutions are the same width, which is found using \the\linewidth in a previous run. I also measured the height of an empty solution so that versions with \printanswers and \noprintanswers would line up.

\documentclass{exam}
\usepackage{showframe}

\newsavebox\tempbox% note: \solutionbox already used (environment)
\newlength\solutionwidth
\setlength{\solutionwidth}{433.1772pt}
\newlength{\emptyheight}
\setlength{\emptyheight}{41.74443pt}% height of empty solution (printed)

\begin{document}
\begin{questions}
\question This is a question text
\savebox\tempbox{\parbox[t]{\solutionwidth}{%
\begin{itemize}
\item A hundred answers maybe
\end{itemize}}}%
\begin{solution}[\dimexpr \emptyheight+\ht\tempbox+\dp\tempbox]%
%\the\linewidth% used to set \solutionwidth
\usebox\tempbox
\end{solution}
\question Next question.
\end{questions}
\end{document}


This is a two-pass solution. It stores the height in the aux file using \saveheight, then in the next pass stores the height in \tempheight using \getheight.

\documentclass{exam}
\usepackage{showframe}% debugging tool

\newcounter{tempcount}
\newsavebox\tempbox% note: \solutionbox already used (environment)
\newlength{\tempheight}% reserve global register
\newlength{\emptyheight}
\setlength{\emptyheight}{41.74443pt}% height of empty solution (printed)

\makeatletter
\newcommand{\saveheight}[1]{% text for solution environment
\setbox\tempbox=\vbox{#1}%
\tempheight=\dimexpr \ht\tempbox+\dp\tempbox\relax
\immediate\write\@auxout{\string\newheight{\the\tempheight}}%
\unvbox\tempbox}

\newcommand{\newheight}[1]{% called automatically from aux file
\stepcounter{tempcount}%
\expandafter\gdef\csname height\thetempcount\endcsname{#1}}%

\newcommand{\getheight}{\stepcounter{tempcount}%
\@ifundefined{height\thetempcount}{\tempheight=1in}%
{\tempheight=\csname height\thetempcount\endcsname\relax}%
}
\makeatother
\AtBeginDocument{\setcounter{tempcount}{0}}% reset

\begin{document}
\begin{questions}
\question This is a question text
\getheight%
\begin{solution}[\dimexpr \emptyheight+\tempheight]
\saveheight{%
\begin{itemize}
\item A hundred answers maybe
\end{itemize}}%
\end{solution}
\question Next question.
\end{questions}
\end{document}

• Solutions are the same width that's not a big issue. However, my apologies, I didn't understand the structure of the answer. Are these two separate files? Do I run them both? Or two different solutions? Apr 3 '19 at 9:56
• These are two separate solutions. I didn't think of the second one until after the first was done. Apr 3 '19 at 15:08
• Works great with the first approach! One little thing: I need to add an empty line before the solution so \\  is necessary as: \\ \usebox\tempbox  otherwise the parbox overflows Apr 3 '19 at 20:05

Never be to strict with space for answering the question. :) Some children write big, others write small. The solution of could be extended by some kids, are reduced by others. If my kids are complaining about layout of exams, they mostly complain that they didn't had enough space to answer the questions.

You could work like this:

\documentclass{exam}
\begin{questions}
\question blablabla
\begin{itemize}
\item \dotfill
\item \dotfill
\item \dotfill
\end{itemize}
\else
\begin{itemize}