Как сделать так, чтобы два или более абзацев использовали одинаковое количество вертикального пространства?

Как сделать так, чтобы два или более абзацев использовали одинаковое количество вертикального пространства?

При наличии нескольких абзацев в ConTeXt или простом TeX, как можно гарантировать, что все абзацы используют одинаковое количество вертикального пространства, добавив пробел в конце, как самый длинный абзац в наборе? Например:

    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.

Вышеуказанные абзацы будут впоследствии дополнены пробелами, так что все они будут занимать такое же количество вертикального пространства, как и последний абзац, поскольку он самый длинный, например:

    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.

решение1

Еще одно решение на основе ConTeXt, но это работает за один проход. Оно требует, чтобы вы сохранили содержимое в буферах, затем измеряете все буферы и устанавливает высоту на максимальную высоту (не обязательно высоту последнего абзаца).

\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

Как только вы освоите базовый механизм, его будет легко реализовать в виде макроса.

\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

Это дает

введите описание изображения здесь

Я использую \ruledvbox, чтобы вы могли видеть коробку. Измените это на , \vboxесли вы не хотите видеть коробку.

решение2

вы можете использовать

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

Создать коробку нужного вертикального размера, дополненную пробелом в конце.

вместо 5 см вы можете сначала измерить одну из коробок, чтобы

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

затем для каждого абзаца вы можете сделать

\vbox to \ht0{stuff.......\vfill}

решение3

Здесь я предлагаю более ConTeXtish решение, основанное на той же идее, что и решение Дэвида. Оно включает в себя теперьдвухпроходные данныемеханизм.

\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

Результат:

результат

S normalparagraph— это простые vboxes с высотой последнего абзаца. heightЗначение берется из двухпроходного набора данных. Это lastparagraphтакже vbox, высота которого измеряется и сохраняется в .tucфайле. \framedПоследующие \starttextпросто добавлены для иллюстрации. Заполните его своим содержимым.

Связанный контент