人为地改进默认的 TeX 算法结果以平衡单词间距

人为地改进默认的 TeX 算法结果以平衡单词间距

我正在尝试创建矩形段落。也就是说,段落既左对齐又右对齐。对于较大的段落,我可以告诉 TeX 我想要一个矩形的最终结果。

考虑下面的例子,

\documentclass{article}
\usepackage{microtype}
\usepackage[numbers]{kantlipsum}

\begin{document}

\parindent=0pt
\parfillskip=0pt
\parskip=6pt % to show paragraph breaks

\kant[1-160]

\end{document}

正如 egreg 所指出的,这个(简单的)示例文档生成了所需的矩形段落(只有第 154 段不是完美的矩形,可以使用更高的 进行调整\tolerance)并使用\parfillskip=0pt完成。对于较小的段落,会出现问题,并且大部分段落的最后一行可能会产生不美观的结果。

我想探索如何改进这一点,首先可以选择人为地增加或减少单词间距,可能以段落为单位。Steven B. Segletes 提到可能有一些可能性可以实现这一点,但我一般都愿意听取建议。当然,例如,对每个段落进行极端微调将是一种选择,即逐段调整跟踪。更普遍适用和/或自动化的解决方案显然会受到青睐。

答案1

如果允许使用字母间距和单词间距的解决方案,请参阅附录。

在这个阶段,这个结果是手动的,因为需要插入或删除每个单词空间的 pt 值来优化结果。此外,这个简单的算法无法处理文本中的宏,不过我想如果有人想走这条路,它可以变得更健壮。

该方法是对输入逐词进行解析,并在每个单词后,在额外的(手动指定的)空格中进行字距调整,然后是\hfill,最后是常规\空格。

在这个 MWE 中,我采用了完整的葛底斯堡演说,或者逐句截取。我展示了两种结果:一种是将其向右扩展以对齐最后一行,另一种是将其压缩以删除最后一部分行。正如聊天室中指出的那样,短句很难看起来好看。我使用的语法是\comparepars{expansion}{compression}{text}

希望您能使用这种手动方法来确定它是否值得推广以满足您的需求。如果将段落矩形化的结果不是您所期望的,那么您以很小的成本确定了这一点。

\documentclass{article}
\usepackage{tabto}
\def\theLetterSpace{0pt}
\newcommand\spaceout[2][\theLetterSpace]{%
  \edef\tmp{#2}%
  \def\LocalLetterSpace{#1}\expandafter\spaceouthelpA#2 \relax\relax}
\def\spaceouthelpA#1 #2\relax{%
  #1\ifx\relax#2\else%
  \kern\LocalLetterSpace\hfill\ \spaceouthelpA#2\relax\fi%
}
\newcommand\comparepar[2]{%
ORIGINAL:\par#2\par 
SPACED OUT:\par\spaceout[#1]{#2}\par
\clearpage%
}
\newcommand\comparepars[3]{%
ORIGINAL:\par#3\par 
SPACED OUT:\par\spaceout[#1]{#3}\par
SPACED IN:\par\spaceout[#2]{#3}\par
\clearpage%
}
\def\sA{Four score and seven years ago our fathers brought forth on this continent a new nation, conceived in liberty, and dedicated to the proposition that all men are created equal.}
\def\sB{Now we are engaged in a great civil war, testing whether that nation, or any nation so conceived and so dedicated, can long endure. We are met on a great battlefield of that war.}
\def\sC{We have come to dedicate a portion of that field, as a final resting place for those who here gave their lives that that nation might live.}
\def\sD{It is altogether fitting and proper that we should do this.}
\def\sE{But, in a larger sense, we can not dedicate, we can not consecrate, we can not hallow this ground.}
\def\sF{The brave men, living and dead, who struggled here, have consecrated it, far above our poor power to add or detract.}
\def\sG{The world will little note, nor long remember what we say here, but it can never forget what they did here.}
\def\sH{It is for us the living, rather, to be dedicated here to the unfinished work which they who fought here have thus far so nobly advanced.}
\def\sI{It is rather for us to be here dedicated to the great task remaining before us—--that from these honored dead we take increased devotion to that cause for which they gave the last full measure of devotion—that we here highly resolve that these dead shall not have died in vain—that this nation, under God, shall have a new birth of freedom—and that government of the people, by the people, for the people, shall not perish from the earth.}
\begin{document}
\parindent 0pt
\noindent\hrulefill

\edef\txt{\sA\ \sB\ \sC\ \sD\ \sE\ \sF\ \sG\ \sH\ \sI}
\comparepars{.3pt}{-1.1pt}{\txt}

\edef\txt{\sA\ \sB\ \sC\ \sD\ \sE\ \sF\ \sG\ \sH}
\comparepar{0pt}{\txt}

\edef\txt{\sA\ \sB\ \sC\ \sD\ \sE\ \sF\ \sG}
\comparepars{1.3pt}{-.8pt}{\txt}

\edef\txt{\sA\ \sB\ \sC\ \sD\ \sE\ \sF}
\comparepars{.05pt}{-2.6pt}{\txt}

\edef\txt{\sA\ \sB\ \sC\ \sD\ \sE}
\comparepars{1.9pt}{-1.2pt}{\txt}

\edef\txt{\sA\ \sB\ \sC\ \sD}
\comparepars{-.04pt}{-.04pt}{\txt}

\edef\txt{\sA\ \sB\ \sC}
\comparepars{2pt}{-1.6pt}{\txt}

\edef\txt{\sA\ \sB}
\comparepars{1.5pt}{-3.1pt}{\txt}

\edef\txt{\sA}
\comparepars{8pt}{-4pt}{\txt}

\end{document}

这是一段较长的段落,将其扩展以填满整行或将其压缩为少一行看起来还不错。

在此处输入图片描述

但这里只有一个句子。如您所见,无论是将其扩展以填充行还是将其压缩以减少一行,结果都不是特别理想。

在此处输入图片描述


附录

这是使用下面描述的修改算法的最终结果(单句输入)。将其与上面仅使用词间间距方法的结果进行比较。

在此处输入图片描述

如果允许字母间距作为解决方案的一部分,这里有一个与上述类似的方法,但它也会在指定的范围内压缩/扩展字母间距

\def\MaxLetterSpace{0.5pt}
\def\MinLetterSpace{-0.5pt}

单词间间距变化可能超过此范围,但字母间距变化受这些参数限制。

在我看来,结果看起来更好,因为它可以用较小的整体变化实现刷新的结果(例如,比较两个版本之间的扩展/挤压参数),并且单词和字母间距之间的对比变得不那么明显。

\documentclass{article}
\usepackage{xcolor}
\def\theLetterSpace{0.0pt}
\def\theWordSpace{1.5\LocalLetterSpace}
\def\MaxLetterSpace{0.5pt}
\def\MinLetterSpace{-0.5pt}
\newlength\LocalLetterSpace
\newcommand\spaceout[2][\theLetterSpace]{%
  \ifdim#1>\MaxLetterSpace\setlength\LocalLetterSpace{\MaxLetterSpace}%
  \else\ifdim#1<\MinLetterSpace\setlength\LocalLetterSpace{\MinLetterSpace}%
    \else\setlength\LocalLetterSpace{#1}\fi%
  \fi
  \expandafter\spaceouthelpA#2 \relax\relax}
\def\spaceouthelpA#1 #2\relax{%
  \spaceouthelpB#1\relax\relax%
  \ifx\relax#2\else\kern\theWordSpace\hfill\ \spaceouthelpA#2\relax\fi
}
\def\spaceouthelpB#1#2\relax{%
  #1%
  \ifx\relax#2\else
    \kern\LocalLetterSpace\spaceouthelpB#2\relax%
  \fi
}

\newcommand\comparepars[3]{%
ORIGINAL:\par#3\par 
\def\theWordSpace{#1}%
SPACED OUT:\par\spaceout[#1]{#3}\par
\def\theWordSpace{#2}%
SPACED IN:\par\spaceout[#2]{#3}\par
\clearpage%
}
\def\sA{Four score and seven years ago our fathers brought forth on this continent a new nation, conceived in liberty, and dedicated to the proposition that all men are created equal.}
\def\sB{Now we are engaged in a great civil war, testing whether that nation, or any nation so conceived and so dedicated, can long endure. We are met on a great battlefield of that war.}
\def\sC{We have come to dedicate a portion of that field, as a final resting place for those who here gave their lives that that nation might live.}
\def\sD{It is altogether fitting and proper that we should do this.}
\def\sE{But, in a larger sense, we can not dedicate, we can not consecrate, we can not hallow this ground.}
\def\sF{The brave men, living and dead, who struggled here, have consecrated it, far above our poor power to add or detract.}
\def\sG{The world will little note, nor long remember what we say here, but it can never forget what they did here.}
\def\sH{It is for us the living, rather, to be dedicated here to the unfinished work which they who fought here have thus far so nobly advanced.}
\def\sI{It is rather for us to be here dedicated to the great task remaining before us—--that from these honored dead we take increased devotion to that cause for which they gave the last full measure of devotion—that we here highly resolve that these dead shall not have died in vain—that this nation, under God, shall have a new birth of freedom—and that government of the people, by the people, for the people, shall not perish from the earth.}

\begin{document}

\parindent 0pt
\noindent\hrulefill

\edef\txt{\sA\ \sB\ \sC\ \sD\ \sE\ \sF\ \sG\ \sH\ \sI}
\comparepars{.04pt}{-.22pt}{\txt}

\edef\txt{\sA\ \sB\ \sC\ \sD\ \sE\ \sF\ \sG\ \sH}
\comparepars{0pt}{-.43pt}{\txt}

\edef\txt{\sA\ \sB\ \sC\ \sD\ \sE\ \sF\ \sG}
\comparepars{0.29pt}{-.16pt}{\txt}

\edef\txt{\sA\ \sB\ \sC\ \sD\ \sE\ \sF}
\comparepars{.03pt}{-0.75pt}{\txt}

\edef\txt{\sA\ \sB\ \sC\ \sD\ \sE}
\comparepars{0.3pt}{-.3pt}{\txt}

\edef\txt{\sA\ \sB\ \sC\ \sD}
\comparepars{-0.03pt}{-1.8pt}{\txt}

\edef\txt{\sA\ \sB\ \sC}
\comparepars{.4pt}{-.28pt}{\txt}

\edef\txt{\sA\ \sB}
\comparepars{.35pt}{-1.4pt}{\txt}

\edef\txt{\sA}
\comparepars{5pt}{-.8pt}{\txt}
\end{document}

随着要操作的段落变得越来越长,结果很快就会变得更好:

在此处输入图片描述

在此处输入图片描述

答案2

从您的问题中无法清楚看出,除了设置为零以删除开始和结束时的空白\parindent之外,您还需要什么效果。\parfillskip

我借用了斯蒂芬的文本以便于比较,每个版本的文本都设置了 4 次,像正常一样对齐,然后再次不使用 parfillskip,然后再次尝试长一行或短一行。

在此处输入图片描述

\documentclass{article}
\parindent=0pt
\emergencystretch\textwidth

\def\x{\clearpage
\bigskip
\textbf{ORIGINAL}\par{\txt\par}
\bigskip
\textbf{A}\par{\parfillskip=0pt \txt\par}
\bigskip
\textbf{B}\par{\looseness=1 \parfillskip=0pt \txt\par}
\bigskip
\textbf{C}\par{\looseness=-1 \parfillskip=0pt \txt\par}
}

\def\sA{Four score and seven years ago our fathers brought forth on this continent a new nation, conceived in liberty, and dedicated to the proposition that all men are created equal.}
\def\sB{Now we are engaged in a great civil war, testing whether that nation, or any nation so conceived and so dedicated, can long endure. We are met on a great battlefield of that war.}
\def\sC{We have come to dedicate a portion of that field, as a final resting place for those who here gave their lives that that nation might live.}
\def\sD{It is altogether fitting and proper that we should do this.}
\def\sE{But, in a larger sense, we can not dedicate, we can not consecrate, we can not hallow this ground.}
\def\sF{The brave men, living and dead, who struggled here, have consecrated it, far above our poor power to add or detract.}
\def\sG{The world will little note, nor long remember what we say here, but it can never forget what they did here.}
\def\sH{It is for us the living, rather, to be dedicated here to the unfinished work which they who fought here have thus far so nobly advanced.}
\def\sI{It is rather for us to be here dedicated to the great task remaining before us―--that from these honored dead we take increased devotion to that cause for which they gave the last full measure of devotion―that we here highly resolve that these dead shall not have died in vain―that this nation, under God, shall have a new birth of freedom―and that government of the people, by the people, for the people, shall not perish from the earth.}
\begin{document}
\parindent 0pt
\noindent\hrulefill

\edef\txt{\sA\ \sB\ \sC\ \sD\ \sE\ \sF\ \sG\ \sH\ \sI}
\x

\edef\txt{\sA\ \sB\ \sC\ \sD\ \sE\ \sF\ \sG\ \sH}
\x

\edef\txt{\sA\ \sB\ \sC\ \sD\ \sE\ \sF\ \sG}
\x

\edef\txt{\sA\ \sB\ \sC\ \sD\ \sE\ \sF}
\x

\edef\txt{\sA\ \sB\ \sC\ \sD\ \sE}
\x

\edef\txt{\sA\ \sB\ \sC\ \sD}
\x

\edef\txt{\sA\ \sB\ \sC}
\x

\edef\txt{\sA\ \sB}
\x

\edef\txt{\sA}
\x

\end{document}

相关内容