# How to avoid the enlarging of a \vbox by \vbox\unvbox?

The \vbox{\unvbox ...} operation should remove obsolete vertical space. In the following case, additional vertical space appears somewhere inside the resulting box. The resulting \vbox grows from a total height of 45.0pt to 46.94444pt.

I played around with \baselineskip, \lineskip, etc. but I could not find the recipe to avoid the enlargement. In my application, it is crucial that the resulting box never grows larger than the dimension given in the \vsplit operation.

\documentclass{article}

\begin{document}

\newbox\mybox
\setbox\mybox=\vbox%
{%
Bla 1
\begin{itemize}
\item bla
\item bla
\end{itemize}
Bla 2.
\begin{itemize}
\item bla
\item bla
\end{itemize}
}

\splittopskip=0pt%
\splitmaxdepth=0pt%
\setbox\mybox=\vsplit\mybox to 45pt%

Before \verb+\vbox\unvbox+ :

{\fboxsep0pt\fbox{\copy\mybox}}\par
\edef\myboxheight{\the\dimexpr\ht\mybox+\dp\mybox\relax}%
Total height: \myboxheight

\bigskip

After \verb+\vbox\unvbox+ :

\setbox\mybox=\vbox{\unvbox\mybox}

{\fboxsep0pt\fbox{\copy\mybox}}\par
\edef\myboxheight{\the\dimexpr\ht\mybox+\dp\mybox\relax}%
Total height: \myboxheight

\end{document}


To give a 'positive' example why I use \unvbox, see the following. Here, the splitting produces a lot of space which is removed by unboxing and boxing again.

\documentclass{article}
\usepackage{amsmath}

\begin{document}

\newbox\mybox
\setbox\mybox=\vbox%
{%
\begin{enumerate}
\item
\! \begin{aligned}[t] -2x &>4\\ x &< \frac{4}{-2} \\ x &< -2 \end{aligned}
\item
\! \begin{aligned}[t] 7x -1 &< 13\\ 7x &< 13 +1\\ 7x &< 14\\ x &< \frac{14}{7}\\ x &< 2 \end{aligned}
\end{enumerate}}

\splittopskip=0pt%
\splitmaxdepth=0pt%
\setbox\mybox=\vsplit\mybox to 90pt%

{\fboxsep0pt\fbox{\copy\mybox}}

\setbox\mybox=\vbox{\unvbox\mybox}

{\fboxsep0pt\fbox{\copy\mybox}}\par
\edef\myboxheight{\the\dimexpr\ht\mybox+\dp\mybox\relax}%

\end{document}


-
\unvboxing unfreezes any glue. If you want to retain the size, why not just use the \vbox as it is? – Andrew Swann May 14 '13 at 10:13
There are many cases where I get a positive effect using the unfreezing and boxing again, e.g. in this example – Thomas F. Sturm May 14 '13 at 11:08
What example do you refer to? – Andrew Swann May 14 '13 at 11:14
I realized too late that I cannot insert code in a comment (sorry, I am new here). I added my example to the question part now. – Thomas F. Sturm May 14 '13 at 11:17
The example you give is the same as your original, in both cases you are just setting glue to its natural length, this can be more or less than the setting in the original box, depending on whether that glue was stretched or shrunk. In neither case is any glue removed. (In addition to re-setting glue you also discard any explicit settings of the box dimensions which are recalculated from the box contents. – David Carlisle May 14 '13 at 11:34

After \vsplit\mybox to 45pt the box is forced to the total height 45pt:

\showboxdepth=\maxdimen
\showbox\mybox


The .log file shows:

> \box26=
\vbox(45.0+0.0)x345.0, glue set - 0.32408
.\hbox(6.94444+0.0)x345.0, glue set 306.8055fil
..\hbox(0.0+0.0)x15.0
..\OT1/cmr/m/n/10 B
..\OT1/cmr/m/n/10 l
..\OT1/cmr/m/n/10 a
..\glue 3.33333 plus 1.66666 minus 1.11111
..\OT1/cmr/m/n/10 1
..\penalty 10000
..\glue(\parfillskip) 0.0 plus 1.0fil
..\glue(\rightskip) 0.0
.\penalty -51
.\glue 8.0 plus 3.0 minus 4.0
.\glue -8.0 plus -3.0 minus -4.0
.\glue 4.0 plus 1.0 minus 3.0
.\glue(\parskip) 4.0 plus 2.0 minus 1.0
.\glue(\baselineskip) 5.05556
[...]


The outmost box is not set with its natural height, its glue components (the shrinkable parts) is reduced by factor - 0.32408. The sum of the shrinkable parts (after minus in the \glue lines of the .log file) is 6pt. Multiplied with 0.32408 the result is 1.9248. Thats the difference to the second case (modulo rounding issues).

In the latter case, after \vbox{\unvbox\mybox}, the box contents is the same, the difference is the glue setting in the topmost \vbox:

> \box26=
\vbox(46.94444+0.0)x345.0


Here the box is set with its natural width that is slightly larger than 45pt of the forced first case. The plus and minus parts of the \glue components are not needed.

The height can be forced by using \vbox to:

\setbox\mybox=\vbox to 45pt{\unvbox\mybox}


But I do not see the point for this exercise. What do you want to achieve? \vbox + \unvbox does not remove "obsolete vertical space". And in your case there is no vertical space at the beginning and end that have an effect. The vertical box starts and ends with an \hbox.

## Second example

Also the second example does not remove any white space elements (glue, kern). The effect of reduced white space at the beginning is also the effect of a different glue setting. The box is forced to a box with height 90pt. The natural height of the box is 18.39996pt. Therefore the stretchable components are used and enlarged by the huge factor 6.77441.

At the end of a box the white space can sometimes be removed by \unskip and \unkern. But this will not work, if there is something invisible afterwards like \special or \write. And this trick will not work for the first part of a vertical box. Only LuaTeX allows the full inspection and modification of boxes.

If a vertical box contains glue, then its height can be set differently to its natural height. However this works both ways, the box can be made smaller or larger in height. Thus the reverse process, setting the box again in its natural height makes the box smaller or larger.

-
The point is that I my vboxes may contain 'anything' not only the example given. I have added a 'positive' example which shows what I want to achieve, i.e. removing space from the begin and/or end of the splitted box. I've seen the \vbox + \unvbox recommended for this task but obviously they work in many but not all cases. What would be a better idea? – Thomas F. Sturm May 14 '13 at 11:25

I am thankful to all given answers and explanations. They lighten what really happens. Now, I try to answer myself - hopefully, not too silly.

In the following code, the \vbox+\unvbox operation is replaced by a macro \rebox. It resets the glue with \vbox+\unvbox but forces the height of the resulting box not to grow beyond a limit (taken from the splitting).

Now, example 1 stays at 45.0pt and example 2 is allowed to reduce the visible space above.

\documentclass{article}
\usepackage{amsmath}

\def\rebox#1#2{%
\setbox#2=\vbox{\unvbox#2}%
\ifdim\dimexpr\ht#2+\dp#2>#1%
\setbox#2=\vbox to \the\dimexpr#1-\dp#2\relax{\unvbox#2}%
\fi%
}

\def\testmybox#1{%
\par%
{\fboxsep0pt\fbox{\copy#1}}\par%
\edef\myboxheight{\the\dimexpr\ht#1+\dp#1\relax}%
Total height: \myboxheight%
}

\begin{document}

\newbox\mybox
\setbox\mybox=\vbox%
{%
Bla 1
\begin{itemize}
\item bla
\item bla
\end{itemize}
Bla 2.
\begin{itemize}
\item bla
\item bla
\end{itemize}
}

\splittopskip=0pt%
\splitmaxdepth=0pt%
\setbox\mybox=\vsplit\mybox to 45pt%

\textbf{Example 1:}

Before \verb+\rebox+ :

{\fboxsep0pt\fbox{\copy\mybox}}\par
\edef\myboxheight{\the\dimexpr\ht\mybox+\dp\mybox\relax}%
Total height: \myboxheight

\bigskip

After \verb+\rebox+ :

\rebox{45pt}{\mybox}
\testmybox{\mybox}

\setbox\mybox=\vbox%
{%
\begin{enumerate}
\item
\! \begin{aligned}[t] -2x &>4\ x &< \frac{4}{-2} \ x &< -2 \end{aligned}
\item
\! \begin{aligned}[t] 7x -1 &< 13\ 7x &< 13 +1\ 7x &< 14\ x &< \frac{14}{7}\ x &< 2 \end{aligned}
\end{enumerate}}

\bigskip

\splittopskip=0pt%
\splitmaxdepth=0pt%
\setbox\mybox=\vsplit\mybox to 90pt

\textbf{Example 2:}

Before \verb+\rebox+ :

{\fboxsep0pt\fbox{\copy\mybox}}\par
\edef\myboxheight{\the\dimexpr\ht\mybox+\dp\mybox\relax}%
Total height: \myboxheight

\bigskip

After \verb+\rebox+ :

\rebox{90pt}{\mybox}
\testmybox{\mybox}

\end{document}


-
David said the same in the chat: chat.stackexchange.com/transcript/message/9416695#9416695 – Marco Daniel May 14 '13 at 14:50
That eases me that my own answer is not silly ;-) – Thomas F. Sturm May 14 '13 at 14:55