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.

Is there a way to get the size of \vfill? I want to do some math with the spacing, and I already tried to do:

\newlength{\newtest}
\settowidth{\newtest}{\vfill}

I got an error.

Any sugestions?

share|improve this question
    
We would need little more information than this. For a start, \vfill is a vertical length, not horizontal. Using \settowidth is usually for horizontal measurements. Also, what kind of calculations are you after or where will it be used? Are you limited in terms of using latex or would pdflatex also be an option? –  Werner Aug 1 '12 at 23:35
    
I want to adjust this blocks of text all with the same vertical space. –  user13596 Aug 1 '12 at 23:49
    
@user13596 --- sorry, your comment does not make sense to me. Perhaps you could edit your question and add an example that shows the results you want to achieve. –  Ian Thompson Aug 1 '12 at 23:53
4  
The answer to your question as posed is "No." but if you actually said what spacing calculation you wanted, then someone could probably help. –  David Carlisle Aug 2 '12 at 0:15
1  
The macro \vfill is not a length parameter, but a command that inserts a vertical amount of whitespace of length (or height, if you will) \fill. Hence, your command \settolength\newlength{\vfill} has to generate an error message. The rubber length \fill is not constant but "infinitely stretchable" (in TeX jargon). AFAICT, there's no point in assigning \fill to a new length variable; you might as well use \fill directly, right? –  Mico Aug 2 '12 at 1:20

2 Answers 2

up vote 16 down vote accepted

\vfill is infinite glue. The amount is not a fixed value, but a "rubber length" that can span from 0pt to "infinity". Its real length is known, when TeX constructs its parental vertical box. Experts can inspect the box and determine the exact settings that TeX has chosen. However, there is also an easier way. Many TeX compilers support a feature that tells the position: pdfTeX (the inventor of the feature) in both modes PDF and DVI, XeTeX, LuaTeX). The position is known at the time, when the page is shipped out. Module savepos of package zref provides a wrapper that deals with the internals. It records the positions in the auxiliary file (.aux) as references and makes them available in the next LaTeX run.

\documentclass{article}
\usepackage{zref-savepos}
\usepackage{printlen}
\usepackage{lipsum}

\newcommand*{\posdiff}[2]{%
  \zifrefundefined{#1}{\textbf{??}}{%
    \zifrefundefined{#2}{\textbf{??}}{%
      \printlength{\dimexpr\zposy{#1}sp-\zposy{#2}sp\relax}%
    }%
  }%
}
\uselengthunit{mm}

\begin{document}
\section{Hello World}
\lipsum[1-2]

\hrule
\zsavepos{top}
\vfill
\zsavepos{bottom}
\hrule
\newpage
Vertical space on the previous page
between the lines: \posdiff{top}{bottom}
\end{document}

For the experts that want to debug TeX boxes:

  • \showbox expects a box handle and shows the box with its node contents in the .log file.
  • \showlists without parameters displays the current vertical main list.
  • \showboxbreadth and \showboxdepth are integer registers that control how much of the box contents is shown (boxes can be very huge). Their default values are -1 in LaTeX that suppresses the output.
  • The output is printed in the .log file only unless \tracingonline (also an integer register) is set to a positive value.
share|improve this answer
    
@Mico \vfill is equivalent to \vskip 0pt plus 1fill\relax, i.e., using LaTeX's \fill, \vskip\fill. –  Bruno Le Floch Aug 2 '12 at 8:13

The following is perhaps a use-case of Heiko's answer. I assume the motivation here is that you have some fixed-height block (of text) at the top of the pages and some variable-height block (of text) at the bottom of the pages. Using \vfill on the largest bottom block, you wish to extract that information and use that as the vertical space between the blocks on other pages as well.

You can calculate the length inserted by \vfill and store it in a length (say) \vfilllength, as is done in the example below:

enter image description here

\documentclass{article}
\usepackage[paperheight=5in]{geometry}% http://ctan.org/pkg/geometry
\usepackage[savepos]{zref}% http://ctan.org/pkg/zref
\usepackage{lipsum}% http://ctan.org/pkg/lipsum
\newlength{\vfilllength}
\AtBeginDocument{%
  \setlength{\vfilllength}{\dimexpr\zposy{thetop}sp-\zposy{thebottom}sp}% Calculate \vfill
}
\begin{document}
\lipsum[1]
\par\zsaveposy{thetop}
\vfill
\zsaveposy{thebottom}\par
\noindent\rule{\linewidth}{1in}%
\clearpage
\lipsum[1]
\par\vspace*{\vfilllength}\par
\noindent\rule{\linewidth}{1cm}%
\end{document}

In the above MWE the labels thetop and thebottom are placed around a \vfill to record the vertical position (in scaled points/sps) of the labels; increasing from bottom to top on the page. They are subsequently extracted using \zposy with the distance calculated via \dimexpr.

Note that length setting is not possible within the document preamble, since the .aux file (containing the PDF label positions) is only read after the preamble is finished. Hence the use of \AtBeginDocument.

geometry was used in this example to minimize the page layout only, while lipsum provided some dummy text, Lorem Ipsum style.

share|improve this answer
    
+1, and congratulations on rank 3! –  lockstep Aug 2 '12 at 10:57
    
@lockstep: Thanks! ...yet the jostling continues. :) –  Werner Aug 2 '12 at 17:23

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.