27

I'm trying to format the title of the table of contents using the tocloft package. It inserts code that looks like the following.

\par
\vspace*{\cftbeforetoctitleskip}%
% code to typeset \contentsname

The \vspace* is adding unwanted space. Here's a minimal example demonstrating the problem.

\documentclass{article}
\usepackage{showframe}
\begin{document}
\vspace*{0pt}%
ASDF
\end{document}

Compare that to \vspace{0pt} (or simply omitting the \vspace line altogether).

The difference between \vspace and \vspace* is clear. With the star, it expands to

\dimen@\prevdepth
\hrule \@height\z@
\nobreak
\vskip#1%
\vskip\z@skip
\prevdepth\dimen@

and without the star, it expands to just the two \vskips.

Why is there the extra space? (And bonus question: Doesn't this make \vspace* sort of worthless since the star only has a use when TeX is discarding items?)

Edit:
I was able to fix my real problem (with the table of contents) by using \patchcmd from etoolbox.

lockstep
  • 250,273
TH.
  • 62,639
  • I am not sure whether it is related to \topskip as explained here http://tex.stackexchange.com/questions/7286/how-to-make-an-exact-vertically-centered-object-in-a-page – Display Name Dec 24 '10 at 05:01

1 Answers1

21

To ensure that white space is produced even at points in the document where page breaking takes place or at the top or bottom of a page one should replace \vspace by \vspace*.

At the beginning of a page \topskip is inserted, normally \topskip=10pt. Setting topskip=0pt and \offinterlineskip will produce identical results both for vspace and vscpace*.

\documentclass{article}
\usepackage{showframe}
\begin{document}
\topskip=0pt  \offinterlineskip 
\vspace*{0pt}%
ASDF

\end{document}

\offinterlineskip is macro to prevent interline glue globally. Try running both examples to see the difference.

\documentclass{article}
\usepackage{showframe}
\begin{document}
\topskip=0pt  %\offinterlineskip 
\vspace*{0pt}%
ASDF
\end{document}
yannisl
  • 117,160
  • 1
    @Yiannis, I already gave @TH the link where you explained almost the same answer. – Display Name Dec 24 '10 at 06:01
  • 1
    \offinterlineskip doesn't seem to be needed. And \prevdepth wasn't contributing anything in my example since it was 0pt. \topskip is really the culprit. As TeX by Topic points out, if you want to really start at the top of the page, you should use \hbox{}\kern-\topskip. – TH. Dec 24 '10 at 06:02
  • @TH I think it does (at least for my example), if you comment it out it will still have an effect. See TeXbook exercise 12.10. Why do you say in your example \topskip was zero? – yannisl Dec 24 '10 at 06:08
  • @xport yes thanks, I saw it but just wanted to clear all these in my mind as well and I thought you went for lunch, while I am having breakfast:) – yannisl Dec 24 '10 at 06:10
  • @Yiannis: I didn't. I said that \prevdepth is zero. – TH. Dec 24 '10 at 06:12
  • @TH Interesting stuff, how do you know prevdepth was zero? – yannisl Dec 24 '10 at 06:17
  • @Yiannis: I used \showthe\prevdepth. – TH. Dec 24 '10 at 06:31
  • 1
    @TH Doesn't it shows zero because there was no last box yet? – yannisl Dec 24 '10 at 06:37
  • @Yiannis: Yes. For the first box on the page, TeX doesn't look at \baselineskip, \lineskiplimit, or \lineskip. "Before the first box on each page some glue is inserted. This glue has the same stretch and shrink as \topskip but the natural size is the natural size of \topskip minus the height of the first box, or zero if this would be negative." – TeX by Topic, Section 26.2. \topskip0pt is the key. – TH. Dec 24 '10 at 10:29
  • @Yiannis: If you comment out \offinterlineskip in your example, the top of the first line (namely \the\dimen@) is still at the very top of the text area. Exercise 12.10 in The TeXbook doesn't have anything to do about this particular issue. It's just talking about \nointerlineskip. I want to accept an answer for this question but I think the only part of yours that is correct and relevant is "At the beginning of the page \topskip is inserted, normally \topskip=10pt." If you remove the other stuff, I'll accept it. – TH. Dec 26 '10 at 10:48
  • @TH I had a good look at the whole issue and I will give it a good edit in the morning as it is getting a bit late here. We are both partly right here. I was wrong with prevdepth. However, if you do a tracingall TeX inserts a baselineskip after a rule, hence the need for interlineskip. However, the major culprit is topskip. – yannisl Dec 26 '10 at 16:27
  • @Yiannis: Please don't forget the good edit. It wouldn't be good to leave the answer as is. – Hendrik Vogt Dec 30 '10 at 15:08
  • @Hendrik I did a couple of changes to incorporate your suggestions. Please feel free to edit the answer further if you wish. – yannisl Jan 03 '11 at 23:29
  • @Yiannis: \offinterlineskip is a bit extreme. I think it'd be better to use \nointerlineskip there which just sets \prevdepth to -1000 pt just like \hrule does. \offinterlineskip sets \baselineskip to -1000 pt, \lineskip to 0 pt, and \lineskiplimit to \maxdimen. – TH. Jan 04 '11 at 01:50