\vsplit 拆分任何列表

\vsplit 拆分任何列表

我仍然尝试为双语文档制作一个正常的样式。首先我尝试使用\paracol。我发现它在处理大文本时效果很糟糕,过了一会儿就会添加无限多的空白页。其次,我尝试了pdfcolparallel。它也很糟糕,如果我在另一列中使用类似\vspace或 甚至 的内容,它会在列中添加额外的空格\par。第三,我发现这里优雅的解决方案,它似乎工作得很好,而我没有尝试用列表打破阻止。

为了演示这个问题,我创建了一个简单的 MWE:

\documentclass[a4paper,12pt]{extarticle}
\usepackage[T2A]{fontenc}
\usepackage[english]{babel}
\makeatletter
\def\one{Sample piece of text that could fit at least two lines.}
\newcount\ctr
\def\hundred{\ctr=100\loop\item\one\advance\ctr by -1\ifnum\ctr=0\else\repeat}
% omit orphans and widows
\clubpenalty=10000
\widowpenalty=10000
% Bilingual input partially takeh from https://tex.stackexchange.com/a/234139/24224
\newcount\@count   % temporary counter for dimensions dividing
\newdimen\@tmpdim@ % temporary dimension
\newdimen\p@gesize % size of free space on page
\newdimen\maxht    % max and
\newdimen\minht    % min block height
\newdimen\coef     % shrink coefficient
\newif\ifrepeat    % repeat splitting
\newif\ifshort     % block is too short
% remove "pt" from horizontal dimensions to divide one dimension by another
{\lccode`\?=`\p \lccode`\!=`\t  \lowercase{\gdef\ignorept#1?!{#1}}}
%
% main macro that will make bilingual text block
%
\def\c@ldist{2em} % distance between columns
\def\langs#1#2{\vspace{.5em plus .2em minus .2em}
    \setbox1=\vbox{\setb@selines #1}\setbox0=\vsplit1 to0pt
    \setbox2=\vbox{\setb@selines #2}\setbox0=\vsplit2 to0pt
    \printl@ngs}
% let paragraphs to be a little expandable
\def\setblskip{\advance\baselineskip by 0pt plus1pt\relax}
% change baselineskip to expand shorter text block & change text width to 1/2 - `space/2`
\def\setb@selines{\penalty0\setblskip
    \advance\hsize by-\c@ldist\divide\hsize by2
    \advance\linewidth by-\c@ldist\divide\linewidth by2}
% divide dimension 1 by 2, ex: dim1=10pt, dim2=2pt \@divdimens{dim1}{dim2} = 5pt
% the result is in dimension 3 (without leading \)
\def\@divdimens#1#2#3{\@tmpdim@=#1\@count=#2\divide\@count by 256\divide\@tmpdim@ by\@count
    \multiply\@tmpdim@ by256\csname #3\endcsname=\@tmpdim@}
% test blocks' heights: if it differs too much, set \shorttrue to add \vfil at block's end
\def\@testheights#1#2{
    \@divdimens{\ht#1}{\ht#2}{minht}
    \ifdim\minht<0.83pt\relax\shorttrue\fi  % if one block shorter than 83% of another
    \ifdim\minht>1.23pt\relax\shorttrue\fi}   % we will add vfil later
% split bilingual blocks to their end
\def\printl@ngs{\par\repeattrue\loop
    \maxht=\ht1\minht=\ht1\shortfalse
    % max and min heights
    \ifdim\maxht<\ht2\maxht=\ht2\fi\ifdim\minht>\ht2\minht=\ht2\fi
    \p@gesize=\pagegoal 
    \ifdim\p@gesize=\maxdimen\p@gesize=\vsize
    \else\advance\p@gesize by-\baselineskip\fi
    \advance\p@gesize by-\pagetotal
    % skip too short parts
    \ifdim\p@gesize<4\baselineskip\shorttrue\fi% too little free space
    \ifdim\p@gesize<6\baselineskip\ifdim\minht<0.7\maxht\shorttrue\fi\fi% difference too big
    \ifshort\shortfalse\vfill\pagebreak\repeat
    \ifdim\maxht>\p@gesize % block don't fit into page - break it
        \splitlang1\splitlang2
        \@testheights{11}{12}
        \putlangboxes\p@gesize{11}{12}\vfil\break
    \else\@testheights12\putlangboxes\maxht12\repeatfalse\fi % last block
    \ifrepeat\repeat}
\def\splitlang#1{\@divdimens{\ht #1}{\maxht}{coef}
   \@tmpdim@=\p@gesize\ifdim\ht#1=\maxht\fi
   \setbox1#1=\vsplit #1 to \expandafter\ignorept\the\coef\@tmpdim@}
% add \vfil in end of too short blocks
\def\putlangboxes#1#2#3{\hbox{\vbox to#1{\unvbox#2\ifshort\vfil\fi}\kern\c@ldist%
    \vbox to#1{\unvbox#3\ifshort\vfil\fi}}}
\makeatother
\begin{document}
\langs{\begin{itemize}\hundred\end{itemize}}{\begin{itemize}\hundred\end{itemize}}
\end{document}

问题:此文本在第一页后中断。似乎\vsplit“忘记”了其余部分!

我怎样才能用 拆分任何列表\vsplit

答案1

这种奇怪的行为是由于\repeat\p@gesize控制。这是一个最小的真的工作示例:

\documentclass[a4paper,12pt]{extarticle}
\usepackage[T2A]{fontenc}
\usepackage[english]{babel}
\makeatletter
\def\one{Sample piece of text that could fit at least two lines.}
\newcount\ctr
\def\hundred{\ctr=1\loop\item\the\ctr. \one\advance\ctr by 1\ifnum\ctr=100\else\repeat}
\def\fifty{\ctr=1\loop\the\ctr. \one\advance\ctr by 1\ifnum\ctr=50\else\repeat}

% omit orphans and widows
\clubpenalty=10000
\widowpenalty=10000
% Bilingual input partially takeh from http://tex.stackexchange.com/a/234139/24224
\newcount\@count   % temporary counter for dimensions dividing
\newdimen\@tmpdim@ % temporary dimension
\newdimen\p@gesize % size of free space on page
\newdimen\maxht    % max and
\newdimen\minht    % min block height
\newdimen\coef     % shrink coefficient
\newif\ifrepeat    % repeat splitting
\newif\ifshort     % block is too short

% remove "pt" from horizontal dimensions to divide one dimension by another
{\lccode`\?=`\p \lccode`\!=`\t  \lowercase{\gdef\ignorept#1?!{#1}}}
%
% main macro that will make bilingual text block
%
\def\c@ldist{2em} % distance between columns
\def\langs#1#2{\goodbreak\vspace{.5em plus .25em minus .25em}
    \setbox1=\vbox{\setb@selines #1}\setbox0=\vsplit1 to0pt
    \setbox2=\vbox{\setb@selines #2}\setbox0=\vsplit2 to0pt
    \printl@ngs\vspace{.5em plus .25em minus .25em}
}
% change baselineskip to expand shorter text block & change text width to 1/2 - `space/2`
\def\setb@selines{\penalty0
    \advance\baselineskip by 0pt plus1pt\relax
    \advance\hsize by-\c@ldist\divide\hsize by2
    \advance\linewidth by-\c@ldist\divide\linewidth by2
}
% divide dimension 1 by 2, ex: dim1=10pt, dim2=2pt \@divdimens{dim1}{dim2} = 5pt
% the result is in dimension 3 (without leading \)
\def\@divdimens#1#2#3{\@tmpdim@=#1\@count=#2\divide\@count by 256\divide\@tmpdim@ by\@count
    \multiply\@tmpdim@ by256\csname #3\endcsname=\@tmpdim@}
% test blocks' heights: if it differs too much, set \shorttrue to add \vfil at block's end
\def\@testheights#1#2{
    \@divdimens{\ht#1}{\ht#2}{minht}
    \ifdim\minht<0.83pt\relax\shorttrue\fi  % if one block shorter than 83% of another
    \ifdim\minht>1.23pt\relax\shorttrue\fi} % we will add vfil later
% split bilingual blocks to their end
\def\printl@ngs{\par\repeattrue\loop
    \maxht=\ht1\minht=\ht1\shortfalse
    % max and min heights
    \ifdim\maxht<\ht2\maxht=\ht2\fi\ifdim\minht>\ht2\minht=\ht2\fi
    \p@gesize=\pagegoal 
    \ifdim\p@gesize=\maxdimen\p@gesize=\vsize
    \else\advance\p@gesize by-\baselineskip\fi
    \advance\p@gesize by-\pagetotal
    % skip too short parts
    \ifdim\p@gesize<3\baselineskip\shorttrue\fi% too little free space
    \ifdim\p@gesize<6\baselineskip\ifdim\minht<0.7\maxht\shorttrue\fi\fi% difference too big
    \ifshort\shortfalse\break\p@gesize=\vsize\fi
    \ifdim\maxht>\p@gesize % block don't fit into page - break it
        \splitlang1\splitlang2
        \@testheights{11}{12}
        \putlangboxes\p@gesize{11}{12}\vfil\break
    \else\@testheights12\putlangboxes\maxht12\repeatfalse\fi % last block
    \ifrepeat\repeat
}
\def\splitlang#1{\@divdimens{\ht #1}{\maxht}{coef}
   \setbox1#1=\vsplit #1 to \expandafter\ignorept\the\coef\p@gesize}
% add \vfil in end of too short blocks
\def\putlangboxes#1#2#3{\hbox{\vbox to#1{\unvbox#2\ifshort\vfil\fi}\kern\c@ldist%
    \vbox to#1{\unvbox#3\ifshort\vfil\fi}}}
\makeatother
\begin{document}
\langs{\fifty}{\fifty}
\langs{\begin{itemize}\hundred\end{itemize}}{\begin{itemize}\hundred\end{itemize}}
\end{document}

相关内容