3

I'm trying to determine the vertical distance between boxes and a line of text in the immediately following paragraph. Depending on the content of the top box I'm getting a discrepancy of \lineskip.

Here's my not so minimal MWE. I put a lot of colored lines in to help illustrate baselines (blue), struts (orange), depths (purple), and distances between lines (black).

\documentclass{article}
\usepackage{xcolor}
%% set `\parskip` to non-trivial value
\setlength{\parskip}{2ex}
%% --- CREATING A STRUT ---
%% strut to equalize line heights of the two boxes designed to be variable
%% if `\aestrutht` is set to `0.7\baselineskip` there's a `\lineskip` discrepency
%% if `\aestrutht` is set to `0.8\baselineskip` there's no apparent discrpency
\newlength{\aestrutht}
\setlength{\aestrutht}{0.7\baselineskip}
\newlength{\aestrutdp}
\setlength{\aestrutdp}{0.3\baselineskip}
%% first rule is to prevent `\color` from screwing things up!
\newcommand{\aestrut}{%%'
  \rule{0pt}{0pt}%%'
  {%%'
    \color{orange}%%'
    \rule[-\aestrutdp]{2pt}{\dimexpr\aestrutdp+\aestrutht\relax}%%'
  }}
%% --- MAKING THE BASELINES VISIBLE ---
\newcommand{\aeshowbaseline}
  {%%'
    \bgroup
      \color{blue}%%'
      \raisebox{0pt}[0pt][0pt]{%%'
        \makebox[0pt][l]{%%'
          \rule{0.1pt}{\aestrutht}%%'
          \rule{2in}{0.1pt}%%'
        }%%'
      }%%'
    \egroup
  }
%% --- CREATING BOX FOR TOP MATTER ---
%% placed in a box so I can measure its height and depth
\newsavebox{\aebox}
\newcommand{\aeTopMatter}[1]{%%'
  \begin{lrbox}{\aebox}
    \begin{minipage}[t]{1in}
      \raggedright
      \aestrut
      \aeshowbaseline #1
      %%\par\rule{0pt}{0pt}
    \end{minipage}
  \end{lrbox}\usebox{\aebox}}%%'
%%---------------------------------------------------------------------------------
%% --- CREATING BOTTOM MATTER ---
\newcommand{\aeBottomMatter}{%%'
  \hspace*{0.95in}%%'
  \aestrut
  \aeshowbaseline
  \hspace*{1em}%%'
  More text}
%% --- MACRO TO SHOW DEPTH OF TOP BOX ---
\newcommand{\aeShowDepthOfTopMatter}{%%'
  \llap{\color{purple}%%'
    \rule[-\dp\aebox]{1in}{0.1pt}%%'
    \rule[-\dp\aebox]{0.1pt}{\dp\aebox}}}
%% --- MACRO TO SHOW DISTANCE BETWEEN TWO LINES ---
\newcommand{\aeShowDistanceBetweenLines}{%%'
  \raisebox{0pt}[0pt][0pt]{%%'
    \rule{2pt}{\dimexpr\parskip+\dp\aebox+\lineskip+\aestrutht}}}
\begin{document}

\aeTopMatter{Hello World}\aeShowDepthOfTopMatter

\aeBottomMatter\aeShowDistanceBetweenLines

\vspace{0.25cm}

\aeTopMatter{Hello My World}\aeShowDepthOfTopMatter

\aeBottomMatter\aeShowDistanceBetweenLines

\vspace{0.25cm}

\aeTopMatter{Hello World to this hardy world}\aeShowDepthOfTopMatter

\aeBottomMatter\aeShowDistanceBetweenLines

\end{document}

enter image description here

I know two possible ways of fixing thing:

  1. I could set the height of \aestrutht a bit bigger
  2. I could uncomment the line \par\rule{0pt}{0pt}

I don't understand why either of these work. In the case of the first, my difficulty revolves around the fact that, given how the height of my strut is already set, it is well above the height of any content on the line. So it seems to me I shouldn't need any more boost.

What I would appreciate knowing is why these two fixes work and why there's only a \lineskip in the third case but not the first two.

For a while I thought this might be related to measuring \prevdepth such as using

\par\xdef\tpd{\theprevdepth}

But that gets convoluted with the depth of the top box and generally doesn't seem useful.

  • Since your minipages have the t specifier, the depth for the box in the third case makes \lineskip to be inserted; in the first two cases this glue isn't inserted since the depth of the minipages is too little. – Gonzalo Medina Aug 4 '13 at 2:22
  • @GonzaloMedina That's kind of what I was thinking, but then again shouldn't \lineskip already be part of the calculation for the depth of the box? – A.Ellett Aug 4 '13 at 2:24
  • @GonzaloMedina Oh wait! Are you saying that because the first two cases have a small or zero depth, after the box is formed and the new line is generated, there's no \lineskip inserted? What are the rules governing when \lineskip is inserted? I thought it always was inserted. – A.Ellett Aug 4 '13 at 2:29
  • @GonzaloMedina If that is as you say, then why does increasing the height (but not the depth) of the strut correct for the \lineskip? – A.Ellett Aug 4 '13 at 2:31
  • Yes, that's exactly what happens. I've provided a simple explanation in my answer, but most importantly, a link to one of egreg's answers about this same phenomenon; in his answer, egreg explains the calculations involved and when the glue is inserted. – Gonzalo Medina Aug 4 '13 at 2:32
3

This is a case of the same situation that was asked in How to keep a constant baselineskip when using minipages (or \parboxes)? and answered by egreg:

Basically, since minipages with t alignment are used, in the third case, the value of the sum of the depth and the height of the box is responsible for the insertion of the \lineskip glue; in the first two cases, the value of the sum doesn't force the insertion of the glue (for the details of the calculations involved, refer to egreg's excellent answer).

Let's have a look at the height and depth of the boxes involved and let's kill \lineskip:

\documentclass{article}
\usepackage{xcolor}


\newlength\BoxDp
\newlength\BoxHt
%% set `\parskip` to non-trivial value
\setlength{\parskip}{2ex}
%% --- CREATING A STRUT ---
%% strut to equalize line heights of the two boxes designed to be variable
%% if `\aestrutht` is set to `0.7\baselineskip` there's a `\lineskip` discrepency
%% if `\aestrutht` is set to `0.8\baselineskip` there's no apparent discrpency
\newlength{\aestrutht}
\setlength{\aestrutht}{0.7\baselineskip}
\newlength{\aestrutdp}
\setlength{\aestrutdp}{0.3\baselineskip}
%% first rule is to prevent `\color` from screwing things up!
\newcommand{\aestrut}{%%'
  \rule{0pt}{0pt}%%'
  {%%'
    \color{orange}%%'
    \rule[-\aestrutdp]{2pt}{\dimexpr\aestrutdp+\aestrutht\relax}%%'
  }}
%% --- MAKING THE BASELINES VISIBLE ---
\newcommand{\aeshowbaseline}
  {%%'
    \bgroup
      \color{blue}%%'
      \raisebox{0pt}[0pt][0pt]{%%'
        \makebox[0pt][l]{%%'
          \rule{0.1pt}{\aestrutht}%%'
          \rule{2in}{0.1pt}%%'
        }%%'
      }%%'
    \egroup
  }
%% --- CREATING BOX FOR TOP MATTER ---
%% placed in a box so I can measure its height and depth
\newsavebox{\aebox}
\newcommand{\aeTopMatter}[1]{%%'
  \begin{lrbox}{\aebox}
    \begin{minipage}[t]{1in}
      \raggedright
      \aestrut
      \aeshowbaseline #1
      %%\par\rule{0pt}{0pt}
    \end{minipage}
  \end{lrbox}\usebox{\aebox}%
\settoheight\BoxHt{\usebox{\aebox}}%
\settodepth\BoxDp{\usebox{\aebox}}%
Box ht: \the\BoxHt~%
Box dt: \the\BoxDp%
}%%'
%%---------------------------------------------------------------------------------
%% --- CREATING BOTTOM MATTER ---
\newcommand{\aeBottomMatter}{%%'
  \hspace*{0.95in}%%'
  \aestrut
  \aeshowbaseline
  \hspace*{1em}%%'
  More text}
%% --- MACRO TO SHOW DEPTH OF TOP BOX ---
\newcommand{\aeShowDepthOfTopMatter}{%%'
  \llap{\color{purple}%%'
    \rule[-\dp\aebox]{1in}{0.1pt}%%'
    \rule[-\dp\aebox]{0.1pt}{\dp\aebox}}}
%% --- MACRO TO SHOW DISTANCE BETWEEN TWO LINES ---
\newcommand{\aeShowDistanceBetweenLines}{%%'
  \raisebox{0pt}[0pt][0pt]{%%'
    \rule{2pt}{\dimexpr\parskip+\dp\aebox+\lineskip+\aestrutht}}}
\begin{document}

\offinterlineskip
\aeTopMatter{Hello World}\aeShowDepthOfTopMatter

\aeBottomMatter\aeShowDistanceBetweenLines

\vspace{0.25cm}

\aeTopMatter{Hello My World}\aeShowDepthOfTopMatter

\aeBottomMatter\aeShowDistanceBetweenLines

\vspace{0.25cm}

\aeTopMatter{Hello World to this hardy world}\aeShowDepthOfTopMatter

\aeBottomMatter\aeShowDistanceBetweenLines

\end{document}

enter image description here

In the example I used \offinterlineskip to prevent interline glue globally, but one could use \nointerlineskip instead, where appropriate, to prevent interline glue insertion once.

  • Thank you for the link. That was most helpful along with your suggestion to zilch out \lineskip. – A.Ellett Aug 4 '13 at 2:42
  • \offinterlineskip pointed me in the right direction of what I wanted! But instead of going whole-hog with it, I can just add \par\nointerlineskip after the top box and kill the \lineskip for just that line. I would not have found this were it not for your answer. Thank you. – A.Ellett Aug 4 '13 at 3:04
  • @A.Ellett You're welcome! Yes, \nointerlineskip can be used locally; I used \offinterlineskip in my example just for illustrative purposes. Perhaps I'll edit my answer to use \nonterlineskip instead. – Gonzalo Medina Aug 4 '13 at 3:05
  • That would be great. My ultimate objective is to improve an earlier answer I gave where I couldn't get a list to line up properly with a box. So with your answer suggesting \nointerlineskip, I can now improve that previous answer and understand why it's working and also point the OP to the appropriate places for fuller explanations. – A.Ellett Aug 4 '13 at 3:11
  • 1
    @A.Ellett I added a little remark about \nointerlineskip. – Gonzalo Medina Aug 4 '13 at 4:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.