Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I am trying to measure the height of a few lines while the lines are set. I thought the 'real' height of a line is the baselineskip, e.g. 14.5pt for a 12p document. However, when I set the text in vbox to measure its height I get 10.7pt for one line and 25pt for two lines. But should it not be 14.5pt and 29pt, respectively? The MWE below clarifies what I mean.

How do I measure the height of a row as multiples of the height of baselineskip? What I want to achieve is a clear measure of the amount of the number of lines in a box. I thought a clever strategy was to measure the total height and divide over the baselineskip.

\documentclass[12pt]{scrartcl}

\usepackage{lipsum,lmodern,xspace}

\newcommand{\boxheight}[1]{%
 \newdimen\height
 \setbox0=\vbox{#1}
 \height=\ht0 \advance\height by \dp0
 #1
}

\begin{document}

\boxheight{\noindent A box with one line is \the\height\xspace high}

\vspace{3ex}

\boxheight{\noindent A box with \\ two lines is \the\height\xspace high}

\vspace{3ex}

\noindent The `real' height of one line is \the\baselineskip.

\end{document}

enter image description here

share|improve this question
    
BTW, \newdimen should be only used once in the preamble, not inside the macro call. Also, the use of \xspace is not required. Simply use \space or \ here. –  Martin Scharrer Oct 19 '12 at 14:20
add comment

2 Answers

up vote 3 down vote accepted

The height of the vbox is the distance from the depth of the last line and the height of the first line. There is no extra baselineskip for the first line, so all you get is the total height (height + depth) for a single line and for two lines you only get the one baselineskip between them, etc. You should be able to fix this by adding a \strut at the beginning of the first and end of the last line.
This won't work properly if you change the font size in between, however. For this the internal font size macro could be changed to automatically add \struts before and after any size change.

\documentclass[12pt]{scrartcl}

\usepackage{lipsum,lmodern}

\newdimen\height

\newcommand{\boxheight}[1]{%
 \setbox0=\vbox{\strut#1\strut}%
 \height=\ht0 \advance\height by \dp0
 #1%
}

\begin{document}

\boxheight{\noindent A box with one line is \the\height\space high}

\vspace{3ex}

\boxheight{\noindent A box with \\ two lines is \the\height\space high}

\vspace{3ex}

\noindent The `real' height of one line is \the\baselineskip.

\end{document}

Gives:

A box with one line is 14.49998pt high

A box with two lines is 28.99998pt high

The ‘real’ height of one line is 14.5pt.

The small difference is due to rounding errors, I guess.

share|improve this answer
add comment

The height of a line is not the baselineskip, in general. Baselines are \baselineskip apart from each other because TeX adds vertical space between lines. Adding the depth is not sufficient to get \baselineskip.

Let's see your first example: the line contains

 A box with one line is \the\height{} high

The height of the constructed \vbox is the maximum height of the ascenders in the line, the depth is the maximum descender. In this particular case, you're adding the height of "A" to the depth of "p" (or "g"), which are, respectively 8.38399pt and 2.33331pt, for a total of 10.7173pt, which is exactly as reported.

You ensure multiples of the baseline (unless the \lineskiplimit mechanism enters into action) by adding a \strut at the beginning and end of the box:

\documentclass[12pt]{scrartcl}

\usepackage{lmodern}

\newdimen\myheight
\newcommand{\boxheight}[1]{%
 \setbox0=\vbox{\strut#1\strut}
 \myheight=\ht0 \advance\myheight by \dp0
 #1}

\begin{document}

\boxheight{\noindent A box with one line is \the\height{} high}

\vspace{3ex}

\boxheight{\noindent A box with \\ two lines is \the\height{} high}

\vspace{3ex}

\noindent The `real' height of one line is \the\baselineskip.

\end{document}

Here's the result (the deviation from the expected value is due to how the binary internal arithmetic of TeX works)

enter image description here

Note that \newdimen\myheight (don't use \height that's reserved in LaTeX) should go outside the definition of \boxheight.

share|improve this answer
    
Perfect explanation, thank you and now it gives me the expected result. However, if I set the text in a parbox, e.g. \parbox[t]{4cm}{\boxheight{Test}} I cannot use \myheight outside the parbox (the height is 0.0pt). Why does it not get stored and how can I store it? –  Jörg Oct 19 '12 at 15:46
    
@Jörg The contents of a \parbox is processed in a group; so you need \global\myheight=\ht0 \global\advance\myheight by \dp0 –  egreg Oct 19 '12 at 15:49
    
both your and Martin's answer are perfect, I just accepted his because he was first to answer. –  Jörg Oct 20 '12 at 17:25
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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