# Spacing after \vtop

There is insufficient spacing between the lines in the MWE, made using an \hbox filled with two \vtop boxes.

\parindent=0pt

\newdimen\linewidth
\linewidth=4in

\newdimen\colsep
\colsep=1em

\newdimen\colwidth
\colwidth=0.5\linewidth

\def\twocols#1#2{%
\hbox to \linewidth{%
\vtop{\hsize=\colwidth
\hangindent=1em \hangafter=1 #1\par}\hfill
\vtop{\hsize=\colwidth
\hangindent=1em \hangafter=1 #2\par}\hss
}\par
}

\twocols
{This is a very long line that will run over}
{What is wrong with the spacing?}
\twocols
{What is wrong with the spacing?}
{This is a very long line that will run over}

\bye


-
– egreg Feb 21 at 23:52

If you turn on logging you see the dreaded

..\glue(\lineskip) 1.0


a vtop box has large depth, and the following vtop tries to maintain \baselineskip spacing to the reference point of the previous box which is the baseline of the first line. As that can not be achieved, TeX gives up on baseline spacing and just inserts \lineskip glue.

You can use a strut at the start and the end, and suppress lineskip glue then spacing will be preserved as long as there is no abnormally large text

\tracingonline1
\tracingoutput1

\showboxdepth=4

\parindent=0pt

\newdimen\linewidth
\linewidth=4in

\newdimen\colsep
\colsep=1em

\newdimen\colwidth
\colwidth=0.5\linewidth

\def\twocols#1#2{%
\hbox to \linewidth{%
\vtop{\hsize=\colwidth
\hangindent=1em \hangafter=1 \strut#1\nobreak\strut\par}\hfill
\vtop{\hsize=\colwidth
\hangindent=1em \hangafter=1 \strut#2\nobreak\strut\par}\hss
}\par
}

\twocols
{This is a very long line that will run over}
{What is wrong with the spacing?}
\nointerlineskip
\twocols
{What is wrong with the spacing?}
{This is a very long line that will run over}

\bye

-
Could you give an example? (I tried \vtop spread \baselineskip but it added too much space.) Also, is this the right way to make such boxes at all? – Andrew Cashner Feb 21 at 23:40
see update..... – David Carlisle Feb 21 at 23:41
@AndrewCashner no you should be using latex:-) – David Carlisle Feb 21 at 23:42

You can carry over the depth of the last line in the \vtop:

\parindent=0pt

\newdimen\linewidth
\linewidth=4in

\newdimen\colsep
\colsep=1em

\newdimen\colwidth
\colwidth=0.5\linewidth

\def\twocols#1#2{%
\par
\setbox0=\vtop{\hsize=\colwidth
\hangindent=1em \hangafter=1 #1\par
\xdef\tpdA{\the\prevdepth}
}%
\setbox2=\vtop{\hsize=\colwidth
\hangindent=1em \hangafter=1 #2\par
\xdef\tpdB{\the\prevdepth}
}%
\edef\tpd{\ifdim\dp0>\dp2 \tpdA \else \tpdB\fi}%
\hbox to \linewidth{\box0 \hfill \box2}
\prevdepth=\tpd
}

\twocols
{This is a very long line that will run over over over over over over over}
{What is wrong with the spacing?}
\twocols
{What is wrong with the spacing?}
{This is a very long line that will run over}

\bye


-

Update handles the lineskip. Don't use this too close to bottom of page.

\parindent=0pt

\newdimen\linewidth
\linewidth=4in

\newdimen\colsep
\colsep=1em

\newdimen\colwidth
\colwidth=0.5\linewidth

\def\twocols#1#2{%
\par
\hbox to\linewidth
{%
\vtop{\hsize=\colwidth
\hangindent=1em \hangafter=1 #1\par\indent}\hfill
\vtop{\hsize=\colwidth
\hangindent=1em \hangafter=1 #2\par\indent}%
}\kern-\baselineskip\hrule height0pt
\indent\par
}

\lineskip\maxdimen

\twocols
{This is a very long line that will run over over over over over over over ppppp}
{Nothing wrong with
the spacing !}
\twocols
{Nothing \smash{\vrule height \baselineskip depth 0pt  width 1pt} wrong with
the spacing! YYYYYY ppppppp}
{This is a very long line that will run over}

AAAAAA\smash{\vrule height \baselineskip depth 0pt  width 1pt}

\tracingoutput1
\bye


Here is a a third approach. Does not use \prevdepth neither \strut's (the latter forces its use also if you follow the thing with something else than \twocols itself).

\parindent=0pt

\newdimen\linewidth
\linewidth=4in

\newdimen\colsep
\colsep=1em

\newdimen\colwidth
\colwidth=0.5\linewidth

\def\twocols#1#2{%
\par
\hbox to\linewidth
{%
\vtop{\hsize=\colwidth
\hangindent=1em \hangafter=1 #1\par\indent}\hfill
\vtop{\hsize=\colwidth
\hangindent=1em \hangafter=1 #2\par\indent}%
}\par\kern-\baselineskip\indent\par
}

\twocols
{This is a very long line that will run over over over over over over jjjjj over}
{What is wrong with the spacing?}
\twocols
{What is wrong with the spacing?}
{This is a very long line that will run over}

\bye


-
you have an additional 1pt (\lineskip) between the boxes still: ..\kern -12.0 ..\glue(\parskip) 0.0 plus 1.0 ..\glue(\lineskip) 1.0 – David Carlisle Feb 22 at 9:25
The same as for Gustavo applies here: try $\Bigg|$ at the end of the very first box. – egreg Feb 22 at 10:11
@egreg there is an approval vote of your comment, but the $\Bigg|$ elicits no surprise for me, to the contrary, this is was it aimed at here. – jfbu Feb 22 at 11:11
@GustavoMezzetti yes, oversight from copying David's answer as starting point ;-) although I had removed the unneeded \hss... ;-) – jfbu Feb 22 at 11:14
@jfbu The result is clearly unacceptable; is this what you were trying to say? So the answer serves no purpose, doesn't it? – egreg Feb 22 at 11:14

Well, why not just the following, then?

\parindent=0pt

\newdimen\linewidth
\linewidth=4in

\newdimen\colsep
\colsep=1em

\newdimen\colwidth
\colwidth=0.5\linewidth

\def\singlebox#1{%
\vtop{%
\hsize=\colwidth
\hangindent=1em \hangafter=1
\leavevmode #1\par
\kern -\prevdepth
}%
}
\def\twocols#1#2{%
\par
\hbox to\linewidth
{%
\singlebox{#1}\hfill\singlebox{#2}%
}%
\prevdepth = 0pt
}

\twocols
{This is a very long line that will run over over over over over over jjjjj over}
{What is wrong with the spacing?}
\twocols
{What is wrong with the spacing?}
{This is a very long line that will run over}

More text.

% {\tracingall\showlists}

\bye


Quite obviously, since it “kills” the depth of the bottom line inside the \twocols construction, this solution is not adequate when the text contains unusual descenders (as egreg has immediately noticed). This answer was intended just as a streamlining of jfbu’s idea.

A possible refinement is:

\parindent=0pt

\newdimen\linewidth
\linewidth=4in

\newdimen\colsep
\colsep=1em

\newdimen\colwidth
\colwidth=0.5\linewidth

\def\singlebox#1{%
\vtop{%
\hsize=\colwidth
\hangindent=1em \hangafter=1
\leavevmode #1\par
\kern -%
\ifdim\prevdepth<\maxdepth
\prevdepth
\else
\maxdepth
\fi
}%
}
\def\twocols#1#2{%
\par
\hbox to\linewidth
{%
\singlebox{#1}\hfill\singlebox{#2}%
}%
\prevdepth = 0pt
}

\twocols
{This is a very long line that will run over over over over over over jjjjj over}
{What is wrong with the spacing?}
\twocols
{What is wrong with the spacing?}
{This is a very long line that will run over}

More text.

\twocols
{This is a very long line that will run over over over over over over jjjjj
over $\Bigg|$}
{What is wrong with the spacing?}
\twocols
{What is wrong with the spacing?}
{This is a very long line that will run over}

Still more text.

% {\tracingall\showlists}

\bye


The output produced by this amended code is

Please note that this does work at the bottom of pages too. Moreover, since the OP didn’t insert the \parskip glue above the \twocols construction, I did not too; if desired, an explicit \vskip\parskip can be added just before the \hbox command in the definition of \twocols.

-
Try with $\Bigg|$ at the end of the very first box and you'll have a surprise. – egreg Feb 22 at 9:56
@egreg: Ah, yes, of course: I was not even trying to cope with a situation like that. Mine was just an elaboration over jfbu’s answer. – Gustavo Mezzetti Feb 22 at 10:09
Good approach with \prevdepth. Solves the issue of behaviour at page bottom from my imaginative proposal. I think egreg is taking a nap. Else he would be asking about why your method does not inserted \parskip glue as it arguably should between two \twocols. Ah yes, his answer does not either. Nobody is perfect. Especially when the world is open ended and answers matter more than questions. – jfbu Feb 22 at 13:35
@jfbu: I think egreg has been silenced by the \maxdepth trick… ;-) – Gustavo Mezzetti Feb 22 at 22:42