假设我有一些多种语言的文本,并且想要并行显示,如下所示。该文本可能跨越多页。
我怎样才能使较短文本的行高自动调整,以使其占用与最长文本相同的空间,如上所示?
编辑:这是一个使用 Malipivo 方法的示例这很接近我想要的,只是它不处理跨多页文本的分页。文本换行也有点丑陋,但我可能可以设法解决这个问题。
答案1
我的解决方案引入了\langs{text1}{text2}{text3}
具有所需输出的宏。该实现计算所有三列的系数,\vsplit
如果文本跨越多页,则使用这些系数。
当然,我的解决方案是纯 TeX,但如果您需要以其他格式使用它,我相信这不会有问题。
\newdimen\colhsize
\newcount\tmpnum \newdimen\tmpdim
\newdimen\pagesize \newdimen \maxht \newdimen\coef
\newif\ifrepeat
{\lccode`\?=`\p \lccode`\!=`\t \lowercase{\gdef\ignorept#1?!{#1}}}
\def\langs#1#2#3{\setbox1=\vbox{\setbaselines #1}\setbox0=\vsplit1 to0pt
\setbox2=\vbox{\setbaselines #2}\setbox0=\vsplit2 to0pt
\setbox3=\vbox{\setbaselines #3}\setbox0=\vsplit3 to0pt \printlangs
}
\def\setbaselines{\penalty0
\advance\baselineskip by 0pt plus1em \relax
\advance\hsize by-4em \divide\hsize by3
}
\def\printlangs{\par \repeattrue
\loop \maxht=\ht1
\ifdim\maxht<\ht2 \maxht=\ht2 \fi \ifdim\maxht<\ht3 \maxht=\ht3 \fi
\pagesize=\pagegoal
\ifdim\pagesize=\maxdimen \pagesize=\vsize
\else \advance\pagesize by-\baselineskip \fi
\advance\pagesize by-\pagetotal
\ifdim\maxht>\pagesize
\tmpnum=\maxht \divide\tmpnum by256
\splitlang1 \splitlang2 \splitlang3
\putlangboxes\pagesize{11}{12}{13}\vfil\break
\else \putlangboxes\maxht123 \repeatfalse \fi
\ifrepeat \repeat
}
\def\splitlang#1 {\coef=\ht#1 \divide\coef by\tmpnum \multiply\coef by256
\tmpdim=\pagesize
\ifdim\ht#1=\maxht \else \advance\tmpdim by-\baselineskip \fi
\setbox 1#1=\vsplit #1 to \expandafter\ignorept\the\coef \tmpdim
}
\def\putlangboxes#1#2#3#4{\hbox{\vbox to#1{\unvbox#2}\kern2em
\vbox to#1{\unvbox#3}\kern2em \vbox to#1{\unvbox#4}}}
%%% The test:
\def\text{Rr eiewb ei s sd fuz dhg fg zd jd ffj xds c sg xv fxdz xvv zhx cdfg.}
\def\textA{\text\par\text\text\par\text}
\def\textB{\text\text\text\par\text\text\par\text\text}
\def\textC{\text\text\par\text\text\text}
This text is before language columns. \text\text
\langs{Language one: \textA\textA\textA\textA\textA\textA\textA\textA}
{Language two: \textB\textB\textB\textB\textB\textB\textB\textB}
{Language three: \textC\textC\textC\textC\textC\textC\textC\textC}
This text follows. \text\text
\bye
实施细节说明。 将text1
设置为 box1,与\vbox
一样\baselineskip=\baselineskip plus\vsize
。这使得 的潜在拉伸\baselineskip
。text2
将 设置为 box2 和text3
box3,类似地。所有框的第一个元素是\penalty0
。\vsplit
此时将 应用于所有三个框的第一个元素\penalty0
,以便将 设置在所有框中的第一行上方。这确保当我们执行等\splittopskip
操作时,第一行在所有三个框中都位于同一位置。\vbox to something{\unvbox1}
宏\printlangs
测量页面上的空间\pagesize
并循环分割文本。\maxht
是框的最大高度。如果是,\maxht>\pagesize
则我们需要分割框并重复循环。否则,我们需要打印框并结束循环。宏\splitlang
将给\vsplit
定框的给定大小乘以\pagesize
系数。分割结果从框 1 存储到框 11,从框 2 存储到框 12,从框 3 存储到框 13。宏打印,即三列,并将所有给定的框重新装箱为给定的大小。\ht-of current box
\maxht
\putlangboxes
\hbox{\vbox{}\vbox{}\vbox{}}
#1
Edid:我在 中发现了一个错误\setbaselines
:\advance\baselineskip by 0pt plus\vsize
。该\vsize
值每行递增一次,结果在第 49 行时值溢出,而下一行的plus
值是负值。解决方案:我写入plus1em
。该值永远不会溢出。另一个解决方案:写入plus1fil
。
答案2
也许我理解不正确,但有一个建议是以下 MWE。我通过 pdflatex 进行编译。
\documentclass{scrreprt}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
% http://uucode.com/blog/2010/12/06/multi-page-tables-with-inter-row-page-breaks/
\usepackage{lipsum}
\usepackage{cals}
\usepackage[latin]{babel}
\showboxbreadth=100
\showboxdepth=100
\makeatletter
\let\oldDispatch=\cals@row@dispatch
\newbox\rowBefore
\newbox\rowAfter
\newbox\decorationCopy
\newdimen\splitHeight
\def\cals@row@dispatch{%
\cals@ifbreak\iftrue % detect that a break is required
\splitHeight=\pagegoal \advance\splitHeight -\pagetotal
\ifdim \splitHeight>50pt % break inrow only if at least 100pt left
\advance\splitHeight -5pt % avoid pagebreak due to overflows
%
% Split the current row on two: before and after the break
%
\setbox\rowBefore=\hbox{}
\setbox\rowAfter=\hbox{}
\def\next{%
\setbox0=\lastbox
\ifvoid0
\def\next{\global\setbox\rowBefore=\box\rowBefore
\global\setbox\rowAfter=\box\rowAfter }%
\else
\setbox2=\vsplit0 to\splitHeight
\setbox\rowBefore=\hbox{\box2 \unhbox\rowBefore}%
\setbox\rowAfter=\hbox{\box0 \unhbox\rowAfter}%
\fi
\next}
\setbox0=\hbox{\unhbox\cals@current@row \next}
%
% Decoration backup, typeset the first row,
% restore context, typeset the second at the end of macro
%
\setbox\decorationCopy=\copy\cals@current@cs
\setbox\cals@current@row=\box\rowBefore
\ht\cals@current@cs=\ht\cals@current@row
\oldDispatch
\cals@issue@break
\cals@thead@tokens
\setbox\cals@current@row=\box\rowAfter
\cals@reheight@cells\cals@current@row
\setbox\cals@current@cs=\box\decorationCopy
\ht\cals@current@cs=\ht\cals@current@row
\let\cals@current@context=b
\fi
\fi
\oldDispatch}
\makeatother
\makeatletter
\def\cals@rs@width{0pt}
\def\cals@cs@width{0pt}
\def\cals@rs@color{red}
\makeatother
\begin{document}
\begin{calstable}
\colwidths{{150pt}{150pt}{150pt}}
% \thead{\brow \bfseries \cell{header1}\cell{header2}\cell{header3}
% \mdseries \erow}
\brow \cell{\lipsum[ 1]}\cell{\lipsum[ 2]}\cell{\lipsum[ 3]} \erow
\brow \cell{\lipsum[16]}\cell{\lipsum[17]}\cell{\lipsum[18]} \erow
\end{calstable}
\end{document}
大部分来自 http://uucode.com/blog/2010/12/06/multi-page-tables-with-inter-row-page-breaks/
我已将线宽重置为零,以避免出现黑线。我还删除了页眉,这样分页符就可以沿着单元格移动。您必须在每列的一个单元格中输入文本。
此致
彼得·埃贝尔塞格