避免在连续的行中出现“河流”

避免在连续的行中出现“河流”

这个问题引出了包中的一个新功能:
impnattypo

以下引述自 James Felici,排版完整手册(2003),第 161 页:

字间距在连续的字行中堆叠在一起时,就会出现“长条”,从而产生贯穿文本的裂缝效果 [...]。长条是构图的意外,软件还不够智能,无法检测到它们,更不用说对它们采取任何措施了。

在下一页中,Felici 展示了一条贯穿段落的“大河”的示例。下面,您将看到 LaTeX 代码和我对 Felicis 示例的重新制作(略有删节)的图片输出。(布局的选择使得当使用microtype包及其默认设置。

\documentclass{article}

\usepackage{mathptmx}
\usepackage{microtype}

\textwidth 247pt
\parindent 23pt
\frenchspacing

\begin{document}

Though the Pearl measures less than 50~miles in total length from its
modest source as a cool mountain spring to the screaming cascades and
steaming estuary of its downstream reaches, over those miles, the
river has in one place or another everything you could possibly ask
for. You can roam among lush temperate rain forests, turgid white
water canyons, contemplative meanders among aisles of staid aspens
(with trout leaping to slurp all the afternoon insects from its calm
surface), and forbidding swamp land as formidable as any that Humphrey
Bogart muddled through in \emph{The African Queen}.

\end{document}

替代文本

那么,Felici 说“软件还不够智能”来处理河流,这是对的吗?或者 TeX 可以处理这个问题?如果 TeX 不能处理,那么 LuaTeX 可以处理吗?

编辑:正如 rassie 指出的那样,TeX 是图灵完备的,让我澄清一下,我对已经存在或可以用合理的时间和精力实现的解决方案感兴趣。

答案1

我已经将使用 Lua 检测河流的算法的第一个版本添加到impnattypo包中在 github 上。要使用它,只需使用以下rivers选项:

\usepackage[draft,rivers]{impnattypo}

以下是示例结果:

利普萨姆河

请注意可能仍然存在一些错误;-)

答案2

稍微扩展一下已经给出的答案:这不仅仅是添加一种新的惩罚并让 TeX 神奇地针对新惩罚进行优化的问题。问题在于 TeX 的段落优化算法利用了给定问题的特殊结构:该问题被重新表述为图中的最短路径算法(其节点是可能的断点),并使用Dijkstra 算法...任何新类型的惩罚都必须符合这一框架,而河流惩罚在某种意义上对这一框​​架来说“太全球化了”。

检测另一方面,这应该是可行的。如果我们有办法检测河流,那么就可以手动调整有问题的段落,让河流消失。

答案3

我不确定问题是否可解,并且可能需要新一代非常快的计算机(使用不同算法的试验可能需要六个多小时才能完成)。下面的例子可以产生比 Felici 的例子更强大的河流。

\documentclass[11pt]{article} 
\begin{document}


\def\samplerivers{%
\hskip1em Repeated repeated repeated repeated
repeated repeated repeated repeated
repeated repeated repeated repeated
repeated repeated repeated repeated
repeated repeated repeated repeated
repeated repeated repeated repeated
repeated repeated repeated repeated
repeated repeated repeated repeated
repeated repeated repeated repeated
repeated repeated repeated repeated
repeated repeated repeated repeated
repeated repeated repeated repeated
repeated.}


\begin{minipage}{1.9in}
 \looseness=-1 \hyphenpenalty=0\samplerivers
\end{minipage}\hspace{.8cm}
\begin{minipage}{1.9in}
  \hyphenpenalty=100\samplerivers
\end{minipage}\hspace{.8cm}
\begin{minipage}{1.9in}
 \hyphenpenalty=100000 \samplerivers
\end{minipage}

\end{document}

解决这个问题的一个尝试是霍尔克纳他尝试优化多个目标,但正如他所写:

... 性能下降非常严重,以至于一些测试不得不停止,因为它们需要六个多小时才能完成。

TeX 的算法不包含任何用于最小化河流的参数。

答案4

我认为这更像是一个算法问题,而不是 TeX 的问题。TeX 和 Lua 都是图灵完备的编程语言,因此只要有足够的时间,就可以在其中实现任何算法。

因此,让我们假设您有一个算法,可以判断一段文本中是否有河流,例如,通过在段落上方以图形方式放置垂直线并检查下方的所有点是否为白色。然后可以定义一个\riverpenalty绑定到该算法输出的变量,如果设置得足够高,它将强制 TeX 选择该特定段落的另一种渲染方式。

但是,如果我没有记错的话,经典 TeX 首先构建行,然后构建段落,即段落绑定惩罚不会导致特定行的不同渲染。这意味着使用经典 TeX 可以进行河流检测,但不能进行河流校正。

另一方面,许多 PDFTeX 和 XeTeX 算法,尤其是处理微排版的算法,可能需要基于段落惩罚来纠正线条渲染的方法。在这种情况下,应该可以使用这些高级引擎之一来实现河流校正,无论是在引擎本身中还是使用其 API —— 此时,无论你使用哪种语言,无论是纯 TeX 还是 Lua 还是完全不同的语言,都无关紧要。

相关内容