# Breakable vboxes

In Plain TeX how can I make vboxes breakable, and can I handle/measure them separately? What I'm trying to do, is that I have a portion of text, that is treated separately (no indention, narrower, coloured background, with the use of \hrule/\vrule) and make it breakable.

Additionally I'm interested in how to brake automatically hboxes

-
hboxes cannot break - that is rather the point of them! – Joseph Wright Jun 16 '11 at 12:34
You can't break the content of \vbox or \hbox because they force restricted mode. – Martin Scharrer Jun 16 '11 at 12:34
In a sense it is possible to break. OK, to be more precise: It is possible to split boxes, and in this case this was the solution I needed. – Adam L. S. Jun 20 '11 at 20:38

A \vbox is by itself not breakable. But assigning it to a box register allows TeX to split it with the \vsplit operation.

\newbox\totalbox
\newbox\partialbox
\newdimen\partialboxdim
\setbox\totalbox=\vbox{<settings><text>}
<measurements setting \partialboxdim to the available space>
\setbox\partialbox=\vsplit\totalbox to \partialdim
<measurements setting \partialboxdim to the available space>
...


This is the scheme, you have to provide the \addcoloredbackground macro and the measurements, probably based on \pagegoal and \pagetotal. The TeXbook and TeX by Topic have examples about \vsplit.

Let's expand a bit; I assume you have a \colorthisbox macro that adds a colored background to a box and requirese 3pt of extra space above and below it. The strategy is first to gather the text to be boxed:

\newbox\totalbox
\newbox\partialbox
\newdimen\partialboxdim
\def\startcoloredbox{\par\bigskip
\def\endcoloredbox{\egroup\splitcoloredbox}


At this point we have all the text; now we start the splitting:

\def\splitcoloredbox{\ifvoid\totalbox\finishcoloredbox
\else\continuesplitting\fi}
\def\finishcoloredbox{\bigskip}


The macro \finishcoloredbox should provide the finishing touches, I've only put a \bigskip. The macro \continuesplitting is the heart of the process: it first measures the available space, but first of all it places a \null box in the main vertical list, because when the current page is empty, \pagetotal equals \maxdimen. The 6pt is the extra space reserved for printing the colored box. If the (remaining) part of box \totalbox is less high than the available space, we simply set box \partialbox to it, otherwise we split off from \totalbox what is necessary to fill the available space; then we pass the control to \colorthisbox, but we add \eject in the second case, since we are sure that we have reached the bottom of a page and we want to start at a fresh one with \pagetotal=0pt. After processing we call \splitcoloredbox again.

\def\continuesplitting{\null % In case this starts a new page
\dimen255=\dimexpr\pagegoal-\pagetotal-\pageshrink-6pt\relax
\ifdim\ht\totalbox<\dimen255
\setbox\partialbox=\box\totalbox
\colorthisbox
\else
\setbox\partialbox=\vsplit\totalbox to\dimen255
\colorthisbox\eject
\fi
\splitcoloredbox}


Here is the definition of \colorthisbox I used for testing; it's important that it encloses everything in a box (\hbox or \vbox) in order not to start horizontal mode.

\def\colorthisbox{\hbox{\fbox{\vbox{\unvbox\partialbox}}}}


(yes, the testing was done in LaTeX, because of \lipsum). The \vbox{\unvbox\partialbox} part is important because it avoids underfull boxes.

-
 @egreg: Am I correct in thinking that this approach means that splitting has to come before adding background colour? – Joseph Wright♦ Jun 16 '11 at 14:01 @Joseph: I think this is the easiest way, but I'm no expert in pdfTeX color management. – egreg Jun 16 '11 at 14:07 @egreg: neither am I. A quick look at color.sty shows me that \colorbox is implemented using a rule the size of the box, which of course can't then be split. So if the colour goes in before splitting it would have to be done some other way. – Joseph Wright♦ Jun 16 '11 at 14:37 @Joseph: so it's better to delay the coloring – egreg Jun 16 '11 at 14:45 Well that does not solve the underfull boxes, and also seems awkward, when it splits at the first line, but it does the trick. Thanks. – Adam L. S. Jun 18 '11 at 10:54
show 1 more comment