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.

Given several paragraphs in ConTeXt or plain TeX, how can I ensure that all paragraphs use the same amount of vertical space, by adding white space to the end, as the longest paragraph in the set? E.g.:

    This is a paragraph
with only two lines.
    This paragraph is a
little bit longer and it
has three lines.
    This is the longest
paragraph, as it has
a second, third, and
fourth line.

The above paragraphs would get added white space afterward, such that they all occupy the same amount of vertical space as the last paragraph, because it is longest, e.g.:

    This is a paragraph
with only two lines.


    This paragraph is a
little bit longer and it
has three lines.

    This is the longest
paragraph, as it has
a second, third, and
fourth line.
share|improve this question
add comment

3 Answers

up vote 3 down vote accepted

Another ConTeXt based solution, but this one works in a single pass. It requires you to store the content in buffers, then measures all the buffers and sets the height to maximum height (not necessarily the height of the last paragraph).

\newdimen\maxbufferheight

\def\placebuffertomaximumheight[#1]%
    {\maxbufferheight\zeropoint
     \processcommalist[#1]\domeasurebuffermaxheight
     \processcommalist[#1]\doplacebuffertomaxheight}


\def\domeasurebuffermaxheight#1%
    {\setbox\scratchbox\vbox{\getbuffer[#1]}%
     \scratchdimen\ht\scratchbox
     \ifdim\scratchdimen>\maxbufferheight
        \maxbufferheight=\scratchdimen
     \fi}

\def\doplacebuffertomaxheight#1%
     {\ruledvbox to \maxbufferheight
        {\getbuffer[#1]}%
        \blank[none]} %change \blank[..] to \par to get regular inter-para space


\starttext
\startbuffer[one]
Single line
\stopbuffer

\startbuffer[two]
\input tufte
\stopbuffer

\startbuffer[three]
\input ward
\stopbuffer

\placebuffertomaximumheight[one,two,three]

\stoptext

Once you have the basic mechanism, it is straight-forward to wrap this around a macro.

\newcount\nofmeasuredparagraphs

\def\startparagraph
    {\increment\nofmeasuredparagraphs
     \grabbufferdata[measuredparagraph-\nofmeasuredparagraphs][startparagraph][stopparagraph]}

\def\stopparagraph{}

\def\startmeasuredparagraph
    {\nofmeasuredparagraphs\zeropoint}

\def\stopmeasuredparagraph
    {\maxbufferheight\zeropoint
    \dorecurse\nofmeasuredparagraphs
        {\domeasurebuffermaxheight{measuredparagraph-\recurselevel}}%
    \dorecurse\nofmeasuredparagraphs
        {\doplacebuffertomaxheight{measuredparagraph-\recurselevel}}}

\starttext
\startmeasuredparagraph
\startparagraph
Single line
\stopparagraph

\startparagraph
\input tufte
\stopparagraph

\startparagraph
\input ward
\stopparagraph
\stopmeasuredparagraph


\stoptext

This gives

enter image description here

I am using \ruledvbox so that you can see the box. Change that to \vbox if you don't want to see the box.

share|improve this answer
    
\grabbufferdata was introduced around Feb 2011. If you are using an older version add \let\grabbufferdata=\dostartbuffer. –  Aditya Apr 25 '12 at 16:36
add comment

you can use

\vbox to 5cm{stuff.......\vfill}

To force a box of the right vertical size, padded with space at the end.

instead of 5cm you can measure one of the boxes first so

 \setbox0\vbox{longest stuff....}

then for each paragraph you can do

\vbox to \ht0{stuff.......\vfill}
share|improve this answer
add comment

Here I provide a more ConTeXtish solution based on the same idea as Davids solution. It incorporates the now two-pass data mechanism.

\defineframedtext [normalparagraph]
  [
      frame=off,
     offset=overlay,
      width=\textwidth,
     height=\datasetvariable{lastparagraph}{last}{height},
  ]

\definedataset [lastparagraph]
\newbox\mylastbox

\definestartstop [lastparagraph]
  [
    before=\setups{last:before},
     after=\setups{last:after},
  ]

\startsetups last:before
  \setbox\mylastbox\vbox\bgroup
\stopsetups

\startsetups last:after
  \egroup
  \setdataset [lastparagraph] [last] [height=\the\ht\mylastbox]
  \box\mylastbox
\stopsetups

\starttext

  \startnormalparagraph
    \framed[align=normal]{\input knuth\par}
  \stopnormalparagraph

  \startnormalparagraph
    \framed[align=normal]{\input ward\par}
  \stopnormalparagraph

  \startlastparagraph
    \input knuth
  \stoplastparagraph

\stoptext

Result:

result

The normalparagraphs are simple vboxes with the height of the last paragraph. The height value is picked up from the two-pass data set. The lastparagraph is also a vbox, which height is measured and saved in the .tuc file. The \framed after \starttext are just added for illustration. Fill it with your content.

share|improve this answer
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.