如何创建自动调整行距的平行列

如何创建自动调整行距的平行列

假设我有一些多种语言的文本,并且想要并行显示,如下所示。该文本可能跨越多页。

例子

我怎样才能使较短文本的行高自动调整,以使其占用与最长文本相同的空间,如上所示?

编辑:这是一个使用 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。这使得 的潜在拉伸\baselineskiptext2将 设置为 box2 和text3box3,类似地。所有框的第一个元素是\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/

我已将线宽重置为零,以避免出现黑线。我还删除了页眉,这样分页符就可以沿着单元格移动。您必须在每列的一个单元格中输入文本。

此致

彼得·埃贝尔塞格

相关内容