I am writing a set of lecture notes for which there should be two versions: one for me with all of the text, and one for the students with certain sections replaced by a grid for them to make their own notes.
To achieve this, I am trying to define a function \gap
which can enclose some object (paragraph/figure/theorem/etc) of my lecture notes, and when a Boolean gaps
is off, it does nothing, and when the Boolean is on, it replaces the object with a grid the width of the text and of an appropriate height.
Taking into account the fact that hand writing is bigger than typeset text, the height of the grid should be some scaled up multiple of the object being replaced. I am defining \heightmultiplier
as that scale factor which I have set to 2.5
.
On the face of it, this is easy to achieve using the \fillwithgrid
function which can be copied from the exam class exam.cls
. This function takes a single numerical argument - the height of the grid to be drawn. The problem is that the grid this produces is not breakable and so the result leaves lots of white space in the lecture notes. Therefore, I am trying to adapt that function to create a breakable grid.
The first function I define is \fillwithgridbreakable
which, like \fillwithgrid
takes as argument the height of the grid to be drawn. First it compares this height to the amount of space left on the current page \remainingspace
, which I define to be \textheight-\pagetotal
. If there is enough space it draws the grid, otherwise it draws as big a grid as it can before calling itself again to draw a grid of whatever size is left:
\newcommand{\fillwithgridbreakable}[1]{
\newlength{\remainingspace}%
\setlength{\remainingspace}{\textheight-\pagetotal}%
\ifdim #1>\remainingspace%
\fillwithgrid{\remainingspace}%
\fillwithgridbreakable{#1-\remainingspace}%
\else%
\fillwithgrid{#1}%
\fi
}
Then I define the function \gap
which takes some LaTeX code as input. If the Boolean gaps
is off it jest runs the code, and otherwise, it measures the height \height
of whatever that code would produce, and then calls \fillwithgridbreakable
with argument \heightmultiplier\height
.
\newcommand{\gap}[1]{%
\ifthenelse{\boolean{gaps}}{%
\newdimen\height
\setbox0=\vbox{#1}
\height=\ht0 \advance\height by \dp0
\fillwithgridbreakable{\heightmultiplier\height}
}
{%
#1
}
}
My problem is that I get errors saying that \gap
is missing a number and units treated as 0, and that the grid it draws is not breakable.
Here is a MWE
\documentclass{exam}
\usepackage{lipsum}
\newboolean{gaps}
\setboolean{gaps}{true}
\newcommand{\heightmultiplier}{2.5}
\newcommand{\fillwithgridbreakable}[1]{
\newlength{\remainingspace}%
\setlength{\remainingspace}{\textheight-\pagetotal}%
\ifdim #1>\remainingspace%
\fillwithgrid{\remainingspace}%
\fillwithgridbreakable{#1-\remainingspace}%
\else%
\fillwithgrid{#1}%
\fi
}
\newcommand{\gap}[1]{%
\ifthenelse{\boolean{gaps}}{%
\newdimen\height
\setbox0=\vbox{#1}
\height=\ht0 \advance\height by \dp0
\fillwithgridbreakable{\heightmultiplier\height}
}
{%
#1
}
}
\begin{document}
\lipsum[1-5]
\gap{\lipsum[1-3]}
\end{document}
The output of this, at the first page break, looks like this:
I would be very grateful for any insight into why this doesn't work and what I can do to fix it. I have searched SE for posts on similar topics. That's how I found out how to measure the height of something as I do in the \gap
function and how to compute \remainingspace
and use \ifdim...\else
. But I couldn't find anything that makes breakable environments from scratch.
This is also my first post on this SE, so let me know if there's anything I can do to improve it.
Solution
Drawing almost entirely on John Kormylo's solution below, I thought I would set out a working solution here with a couple of bugs fixed and more freedom to adjust things like grid size and colour.
\usepackage{xcolor} %to adjust the grid colour
\usepackage{ifthen} %to create the boolean for turning the functionality of \gaps on and off
\newboolean{gaps}
\setboolean{gaps}{true}
\newcommand{\heightmultiplier}{2.5} %how much taller the grid is than the object it is replacing
\newcommand{\mygridsize}{.5cm} %the size of the grid squares
\colorlet{gridcolor}{gray!50} %the colour of the gridlines
\newcommand{\rulewidth}{0.8pt} %the width of the vertical rules
\newsavebox{\row}
\savebox{\row}{\begin{minipage}[b]{\textwidth}
{\color{gridcolor}\hrule}
\dimen9=\mygridsize\relax
\count9=\numexpr \textwidth / \dimen9\relax
{\color{gridcolor}\rule{\rulewidth}{\dimen9}}%
\loop\ifnum\count9>1
\advance\count9 by -1
\hfill{\color{gridcolor}\rule{\rulewidth}{\dimen9}}%
\repeat
{\color{gridcolor}\hrule}
\end{minipage}}
\newcommand{\fillwithgridbreakable}[1]{% #1 = total height
\setstretch{1} %if setstretch is changed elsewhere in the document, this prevents it from messing with the grid row spacing
\setlength{\parskip}{0pt} %If included inside a list environment, the prevents the paragraph spacing from messing up with the grid row spacing
\vfill
\dimen8=#1\relax
\dimen9=\mygridsize\relax
\count8=\numexpr \dimen8 / \dimen9\relax
\loop\ifnum\count8>0
\advance\count8 by -1
\noindent\usebox\row\par\vskip-\lineskip
\repeat}
\newcommand{\gap}[1]{% #1 = text to be replaced
\ifthenelse{\boolean{gaps}}{%
\setbox0=\vbox{#1}%
\fillwithgridbreakable{\dimexpr \heightmultiplier\ht0 + \heightmultiplier\dp0}%
}
{%
#1
}
}
\newlength
in the preamble. Otherwise, every time you expand\fillwithgridbreakable
you will use up another dimen register and assign it to\remainingspace
.\newlength
, I guess the same goes for\newdem
too. Having separate rows is an interesting idea, but a bit of a bodge I think - getting the overlap correct would be fiddly, and if you used\vspace{-?? pt}
you would probably end up with the first now on the new page too high.\hspace*{-\csname @totalleftmargin\endcsname}
at the beginning of each line.