
При наличии нескольких абзацев в 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
— это простые vbox
es с высотой последнего абзаца. height
Значение берется из двухпроходного набора данных. Это lastparagraph
также vbox
, высота которого измеряется и сохраняется в .tuc
файле. \framed
Последующие \starttext
просто добавлены для иллюстрации. Заполните его своим содержимым.