![使标点符号组几乎牢不可破,避免出现孤儿和寡妇](https://linux22.com/image/450775/%E4%BD%BF%E6%A0%87%E7%82%B9%E7%AC%A6%E5%8F%B7%E7%BB%84%E5%87%A0%E4%B9%8E%E7%89%A2%E4%B8%8D%E5%8F%AF%E7%A0%B4%EF%BC%8C%E9%81%BF%E5%85%8D%E5%87%BA%E7%8E%B0%E5%AD%A4%E5%84%BF%E5%92%8C%E5%AF%A1%E5%A6%87.png)
我有一个脚本,可以从富文本生成 PDF。我想确保没有只包含标点符号或标点符号前有换行符(如果标点符号后面有单词)的孤行和寡行。假设我们有这个句子:
“Oh. Wow.” He frowned. “What? I thought you were teaching…”
,但我希望它呈现得更像这样:
“Oh. Wow.” He frowned. “What? I thought you were
teaching…”
或者
“Oh. Wow.” He frowned. “What? I thought you were teach-
ing…”
我实际上做了一个正则表达式来找到标点符号并在它们周围加上惩罚,就像这样
“Oh. Wow.” He frowned. “What? I thought you were teaching\penalty900{}…\penalty900{}”\penalty900{}
这是相当高的惩罚,但它仍然拒绝提前打破这条线,结果与上图相同。如果我将惩罚增加到10000
相当于\nobreak
它实际上是有效的,但是我遇到了这样的问题
- 带有大量标点符号的行
Lorem…Ipsum…Lorem…Ipsum…Lorem…Ipsum…Lorem…Ipsum…Lorem…Ipsum…Lorem…Ipsum…Lorem…Ipsum…Lorem…Ipsum…Lorem…Ipsum…Lorem…Ipsum…Lorem…Ipsum…Lorem…Ipsum…Lorem…Ipsum…Lorem…Ipsum…Lorem…Ipsum…Lorem…Ipsum…Lorem…Ipsum…Lorem…Ipsum…Lorem…Ipsum…Lorem…Ipsum…Lorem…Ipsum…Lorem…Ipsum…Lorem…Ipsum…Lorem…Ipsum…Lorem…Ipsum…Lorem…Ipsum…Lorem…Ipsum…Lorem…Ipsum…Lorem…Ipsum…Lorem…Ipsum…
- 只有点
.................................................................................................................................................................................
为了解决这个问题,我使用正则表达式将这些长标点符号拆分为 5 个组,然后在组之间添加惩罚301
,从而得到此结果
.\penalty10000.\penalty10000.\penalty10000.\penalty10000.\penalty301.\penalty10000.\penalty10000.\penalty10000.\penalty10000.
我还编写了正则表达式来查找所有未被其他标点符号所取代的省略号,并将惩罚设置为301
,这样它就可以在省略号之后中断
Lorem…Ipsum…
会成为
Lorem…\penalty301{}Ipsum…\penalty301{}
现在它可以工作了,但是整个正则表达式字符串感觉非常脆弱,所以最后的问题是:
是否有可能以更接近 LaTeX 的方式实现它,而无需所有正则表达式,例如设置一些全局标点符号列表和惩罚?我也不明白为什么惩罚900
没有强制 latex 在单词前真正断行,因为\hyphenpenalty=50
理论上 LaTeX 应该更喜欢对单词进行连字符处理,而不是在单词后断行。