# Why is \baselineskip not inserted before an \unvbox?

It seems that \setbox0=\vbox{\hbox{abc}}\unvbox0 is not equivalent to \hbox{abc}: the former does not insert a \baselineskip in the following situation.

\vbox{%
\hbox{XY}%
\hbox{abc}%
\hbox{def}
}

\vbox{% missing baselineskip before \unvbox0
\hbox{XY}%
\setbox0=\vbox{\hbox{abc}}%
\unvbox0
\hbox{def}
}


A solution might be

\vbox{% the baselineskip is inserted when we write \box0, then remove it.
\hbox{XY}%
\setbox0=\vbox{\hbox{abc}}%
\box0
\setbox2=\lastbox
\unvbox2
\hbox{def}
}


but is it really the right way to do it?

For information, I am trying to emulate the behaviour of \halign with hand-made boxes, and I don't think that I will be able to put the \hbox{abc} (corresponding to rows) directly on the current vertical list since the rows need to all be read and the glue left unset, until the end of the tabular is reached and we can know the width of each column. Resetting the glue requires me to go through the list of row boxes, \unhbox them, \unhbox and re-\hbox each cell, etc.

\bye

-
I like the \bye there. =) egreg answered your question, but one possibility might be setting \baselineskip=0pt \lineskip=0pt and the inserting a \strut similar to what array does. –  TH. Apr 14 '11 at 22:07
@TH. I am trying to be as general as possible, so using \prevdepth is probably the way to go. –  Bruno Le Floch Apr 15 '11 at 1:50

At the start of a \vbox the parameter \prevdepth is set to -1000pt and, when you do \unvbox, this value inhibits the interline glue. You must reinstate the correct \prevdepth in the \vbox:

\showboxbreadth=1000
\tracingonline=1

\setbox0=\vbox{
\hbox{XY}
\hbox{abc}
\hbox{def}
}

\showbox0 \box0

\setbox0=\vbox{
\hbox{XY}\dimen255=\prevdepth
\setbox0=\vbox{\prevdepth=\dimen255 \hbox{abc}}
\unvbox0
\hbox{def}
}

\showbox0 \box0

-
Thank you for pointing me to \prevdepth. –  Bruno Le Floch Apr 15 '11 at 1:50

A different solution than keeping track explicitly of \prevdepth is to use \lastbox: this primitive removes the last box (here \hbox{abc}) from the current list, and, since we are not doing anything with it, puts it back in the list. TeX then inserts the baselineskip, using the correct value of \prevdepth (even in weird cases where I manually alter \prevdepth after \hbox{XY}).

Of course, this solution is less general than egreg's answer, because that only works if the saved box contains a single box (this was true in my case).

\showboxbreadth=1000
\tracingonline=1

\setbox0=\vbox{
\hbox{XY}
\hbox{abc}
\hbox{def}
}

\showbox0 \box0

\setbox0=\vbox{
\hbox{XY}
\setbox0=\vbox{\hbox{abc}}
\unvbox0
\lastbox % <= this
\hbox{def}
}

\showbox0 \box0

-