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.

Might I please have some help with writing a loop that repeats a block of text as many times as there is remaining space for it on the page?

I would like to produce an notebook in TeX which is divided into a number of sections. Each section would start with some printed records (taken from an existing database) followed by some space to hand-write in new entries.

The space for handwritten records is generated by something along the following lines:

\noindent Type of Widget: \dotfill \break
Observations: \dotfill \break
\null\dotfill

The problem I have is that of vertical alignment: I want each section to start at the top of a new page, followed by the printed records and then enough blocks for handwritten notes to fill up the remaining vertical space on that page. Something like this:


Section: Special Widgets

Type of Widget: ABC123

Observations: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse id orci nunc, sed sollicitudin lectus.

Type of Widget: CDE123

Observations: Etiam lacus sem, pharetra vel eleifend ac, elementum at leo. Ut pulvinar, lorem sit amet feugiat hendrerit, sapien justo accumsan eros, eleifend consectetur nisl urna at nibh.

Type of Widget: ...........

Observations: ...................................................................................................

............................................................................................................................

Type of Widget: ...........

Observations: ...................................................................................................

............................................................................................................................


Since the length of the records can vary, I therefore need to run a loop which does something like the following (in eplain pseudo code):

\for
    \noindent Type of Widget: \dotfill \break
    Observations: \dotfill \break
    \null\dotfill
\if **test to see if there is enough vspace to repeat block**
\repeat

Could anyone point me in the right direction as to how to write a test for "is there enough space left on the page to print this block of text?". I presume I would start by making a \vbox the size of the block and then see if it will fit onto the current page but I can't work out how to make that work.

I hope this is clear enough. If not, please let me know.

Thanks.

-Jacob

share|improve this question
add comment

2 Answers

up vote 6 down vote accepted

This is a place to use vertical leaders. Here is a starting point.

\documentclass{article}
\usepackage{lipsum}
\newsavebox\widgetbox
\begin{document}
\setbox\widgetbox\vbox
  {\vspace*{6pt}\noindent Type of Widget: \dotfill \break
  Observations: \dotfill \break
  \null\dotfill\par}

\lipsum[1]

\cleaders\copy\widgetbox\vskip0pt plus 1fill
\end{document}

With \cleaders the boxes will be put right on top of each other, with space added on top and bottom to fill the page. Use \xleaders instead to have the extra space between the boxes.

You could also use \leaders, which should place these boxes in the same position on every page. But then you need to pay attention to dimensions. Ideally, the page height should be a whole multiple of the height of your \widgetbox.

share|improve this answer
    
Thanks for this. I should have guessed there would be a TeX primitive which would do this for me! –  JacobH Dec 6 '10 at 15:05
add comment

Harald's answer did need to be translated into plain TeX for my purposes. My first effort is the following which seems to work, except that (for reasons I don't quite yet understand), I need to add an extra page following the \cleaders and \eject:

\setbox0=\vbox{\noindent Type of Widget: \dotfill \break
  Observations: \dotfill \break
  \null\dotfill\break
  }

Lorem ipsum dolor etc.

\cleaders\box0\vfill

\eject

Another Page

\bye
share|improve this answer
1  
\bye does its own \vfill, which then gets one half of the remaining space on the last page. If you replace your own \vfill with \vskip 0pt plus 1filll (the triple l is not a misprint), you get what you expect. (Or you can replace the final \bye with \supereject\end.) Also, you need to use \copy, not \box, or your box register is emptied after the first use. –  Harald Hanche-Olsen Dec 6 '10 at 17:15
1  
Oh, and \box0 is not likely to survive very long anyhow. For plain TeX, just replace \newsavebox by \newbox. –  Harald Hanche-Olsen Dec 6 '10 at 17:53
    
Thanks for the explanation; particularly of what was happening with \bye. That's very helpful. –  JacobH Dec 9 '10 at 13:16
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.