使用 Knuth-Liang 算法实现高效且灵活的自动断字。
请参阅完整文档:https://john-mueller.github.io/Hyphenation。
此库的主要目的是自动在文本中插入软连字符,以改善其布局流程。请参考 Butterick's Practical Typography 中的以下示例。
随着行长的缩短,对齐的文本通常会在单词之间显示较大的间隙,而左对齐或右对齐的文本则显示越来越不均匀的边距。通过在单词中插入软连字符(仅在单词位于行尾时显示),可以将文本更自然地拆分为多行,从而改善文本的美观性。
这在 HTML 中非常有用(因为 hyphens
CSS 属性 并非普遍支持),甚至可以在 UIKit 和 SwiftUI 文本组件中使用。
通过 Swift Package Manager 安装断字。首先,将其添加到您的依赖项中。
let package = Package(
...
dependencies: [
.package(url: "https://github.com/john-mueller/Hyphenation.git", from: "0.2.0")
],
...
)
然后在需要的地方导入 Hyphenation 模块。
import Hyphenation
基本用法只需要创建一个 Hyphenator
实例并调用其 hyphenate(text:)
方法。
let hyphenator = Hyphenator()
hyphenator.separator = "-"
let text = "This algorithm identifies likely hyphenation points."
print(hyphenator.hyphenate(text: text))
// This al-go-rithm iden-ti-fies like-ly hy-phen-ation points.
您还可以通过调用 unhyphenate(text:)
从字符串中删除 separator
字符。
let hyphenatedText = "This al-go-rithm iden-ti-fies like-ly hy-phen-ation points."
print(hyphenator.unhyphenate(text: hyphenatedText))
// This algorithm identifies likely hyphenation points.
请注意,如果原始字符串包含 separator
字符,则 unhyphenate(text:)
方法也会删除这些实例,因此断字和取消断字字符串可能无法恢复原始字符串。
该算法旨在优先防止不正确的断字,而不是找到每一个正确的断字——错过一个断字很少对文本流程产生有意义的影响,但是错误的断字可能相当明显。由于模式是从英语字典中派生的,因此它可以对许多未出现在字典中的单词做出很好的猜测。
let hyphenator = Hyphenator()
hyphenator.separator = "-"
print(hyphenator.hyphenate(text: "swiftlang supercalifragilisticexpialidocious"))
// swift-lang su-per-cal-ifrag-ilis-tic-ex-pi-ali-do-cious
尽管如此,该算法有时可能会对品牌名称或其他不寻常的单词产生意外的结果。在这种情况下,您可以手动使用例外指定所需的断字。
print(hyphenator.hyphenate(text: "Microsoft sesquipedalian"))
// Mi-crosoft sesquipedalian
hyphenator.addCustomExceptions(["Micro-soft", "ses-qui-pe-da-li-an"])
print(hyphenator.hyphenate(text: "Microsoft sesquipedalian"))
// Micro-soft ses-qui-pe-da-li-an
要删除自定义例外,请使用以下方法。
hyphenator.removeCustomExceptions(["sesquipedalian"])
hyphenator.removeAllCustomExceptions()
您可以修改几个属性来调整单词的断字方式。
separator
属性设置在断字点插入的字符。 默认情况下,这是 U+00AD(软连字符)。
minLength
、minLeading
和 minTrailing
属性调整分隔符字符可以插入到单词中的位置。
minLength
的单词将不会被断字。minLeading
个字符内。minTrailing
个字符内。此库默认包含美式英语的断字模式,但您可以轻松地使用其他语言的模式初始化 Hyphenator
实例。模式可以通过 String
或 URL
传递。
let hyphenator1 = Hyphenator(patterns: patternsString, exceptions: exceptionsString)
let hyphenator2 = Hyphenator(patternFile: patternsURL, exceptions: exceptionsURL)
可以在 TeX 断字仓库中找到各种语言的模式。请在 TeX 断字模式网站上检查每组模式发布的许可。此页面还列出了每种语言的正确 minLeading
和 minTrailing
。
在初始化新的 Hyphenator
实例时,假定模式由换行符或空格分隔。
Hyphenator 类是线程安全的,可以用于在多个线程上同时进行断字(尽管使用两个实例的性能优势可以忽略不计)。
copy()
方法提供了一种有效的方法来创建一个新的 Hyphenator
实例,该实例具有与现有实例相同的属性和模式。
您不应将 hyphenate(text:)
方法直接应用于包含 HTML 或代码的字符串,因为代码元素可能会被错误地断字。更安全的方法是使用另一种能够识别 HTML 或代码元素并将断字仅应用于标记中的纯文本内容的工具。
有关使用 SwiftSoup 断字 HTML 的示例,请参见 HyphenationPublishPlugin。
如果您在使用 Hyphenation 时遇到问题,请通过提交问题或提交 pull request 告诉我!
提交问题时,请尽最大努力提供可重现的步骤和对预期行为的解释。
如果是 pull request,请注意以下步骤:
swiftlint
不应产生任何警告。 这是由 CI 检查的,但我也建议尽可能在本地进行 lint(有关安装说明,请参见 SwiftLint 仓库)。make test
不会导致任何错误。 这将在 CorrectnessTests
和 ThreadSafetyTests
文件中运行测试。make bench
,以检查是否存在任何速度回归。 这将在 PerformanceTests
文件中运行测试。Hyphenation 在 MIT 许可下提供(请参见 LICENSE.md)。
英语断字模式在 原始自定义许可下提供,并且来自 TeX 断字仓库。
用于性能测试的文本位于公共领域,并在其标头中注明。
简介中的示例段落来自 Butterick's Practical Typography,并经许可使用。
该库的灵感来自 Butterick's Practical Typography 中关于对齐文本和可选连字符的页面,以及作者在 Racket 中的实现。 值得一读!