欢迎使用 Ink,这是一个使用 Swift 编写的快速且灵活的 Markdown 解析器。它可用于将 Markdown 格式的字符串转换为 HTML,并且还支持元数据解析,以及用于细粒度后期处理的强大自定义选项。它的构建重点是基于 Swift 的 Web 开发和其他以 HTML 为中心的工作流程。
Ink 用于渲染 swiftbysundell.com 上的所有文章。
要开始使用 Ink,您只需导入它,并使用其 MarkdownParser
类型将任何 Markdown 字符串转换为高效渲染的 HTML。
import Ink
let markdown: String = ...
let parser = MarkdownParser()
let html = parser.html(from: markdown)
就是这样!生成的 HTML 可以按原样显示,也可以嵌入到其他上下文中——如果这就是您对 Ink 的全部需求,则不需要更多代码。
Ink 还内置了元数据支持,这意味着您可以在任何 Markdown 文档的顶部定义键/值对,这些键/值对将自动解析为 Swift 字典。
要利用此功能,请在 MarkdownParser
上调用 parse
方法,该方法为您提供一个 Markdown
值,该值既包含已解析 Markdown 字符串中的任何元数据,也包含其 HTML 表示形式。
let markdown: String = ...
let parser = MarkdownParser()
let result = parser.parse(markdown)
let dateString = result.metadata["date"]
let html = result.html
要在 Markdown 文档中定义元数据值,请使用以下语法:
---
keyA: valueA
keyB: valueB
---
Markdown text...
即使以上格式不是 原始 Markdown 规范的一部分,许多不同的 Markdown 编辑器和其他工具也支持它。
除了它的 内置解析规则(旨在涵盖各种 Markdown 风格中最常见的功能)之外,您还可以通过使用修饰符来自定义 Ink 执行解析的方式。
修饰符使用 Modifier
类型定义,并与给定的 Target
相关联,该 Target
确定将用于哪种 Markdown 片段。例如,以下是如何在每个代码块之前添加 H3 标签:
var parser = MarkdownParser()
let modifier = Modifier(target: .codeBlocks) { html, markdown in
return "<h3>This is a code block:</h3>" + html
}
parser.addModifier(modifier)
let markdown: String = ...
let html = parser.html(from: markdown)
修饰符传递给 Ink 为给定片段生成的 HTML,以及它的原始 Markdown 表示形式——两者都可用于确定应如何自定义每个片段。
Ink 的设计目标是尽可能快速高效,以在几秒钟内解析数百篇完整的 Markdown 文章,同时仍然提供完全可定制的 API。以下两个关键特性使这成为可能:
O(N)
复杂度,方法是最大限度地减少读取传递给它的 Markdown 字符串的次数,并优化其 HTML 渲染以使其完全线性。虽然由于 Markdown 极其灵活的语法,真正的 O(N)
复杂度在 Markdown 解析方面是不可能实现的,但目标是尽可能接近该目标。String
API,Ink 充分利用了它——通过使用字符串索引、范围和子字符串,而不是在其各种操作之间执行不必要的字符串复制。要成功使用 Ink,请确保您的系统已安装 Swift 5.2(或更高版本)。如果您使用的是 Mac,还请确保 xcode-select
指向包含所需 Swift 版本的 Xcode 安装,并且您运行的是 macOS Catalina (10.15) 或更高版本。
请注意,Ink 不正式支持任何形式的 Beta 软件,包括 Xcode 和 macOS 的 Beta 版本,或未发布的 Swift 版本。
Ink 使用 Swift Package Manager 分发。 要将其安装到项目中,只需将其添加为 Package.swift
清单中的依赖项:
let package = Package(
...
dependencies: [
.package(url: "https://github.com/johnsundell/ink.git", from: "0.1.0")
],
...
)
然后在您想要使用它的任何地方导入 Ink:
import Ink
有关如何使用 Swift Package Manager 的更多信息,请查看 这篇文章,或 其官方文档。
Ink 还附带一个简单但有用的命令行工具,可让您直接从命令行将 Markdown 转换为 HTML。
要安装它,请克隆项目并运行 make
:
$ git clone https://github.com/johnsundell/Ink.git
$ cd Ink
$ make
命令行工具将安装为 ink
,并且可以通过多种方式传递 Markdown 文本以转换为 HTML。
不带参数调用它将开始从 stdin
读取,直到以 Ctrl+D
终止:
$ ink
当不带参数调用 ink
时,可以管道输入 Markdown 文本:
$ echo "*Hello World*" | ink
单个参数被视为文件名,并将解析相应的文件:
$ ink file.md
可以使用 -m
或 --markdown
标志直接传递 Markdown 字符串:
$ ink -m "*Hello World*"
当然,您也可以构建自己的命令行工具,通过将其作为包导入,以更高级的方式利用 Ink。
Ink 支持以下 Markdown 功能:
## H2
。*
) 或下划线 (_
) 包围一段文本。 例如 *斜体文本*
。**
) 或两个下划线 (__
) 包围一段文本。 例如 **粗体文本**
。~~
) 包围一段文本,例如 ~~删除线文本~~
。[标题](url)
。
。[referenceName]: url
。.
) 或右括号 ()
) 的数字作为项目符号)和无序列表(使用短划线 (-
)、加号 (+
) 或星号 (*
) 作为项目符号)。***
) 或三个破折号 (---
) 放置水平线。> 这是一个块引用
。-
) 组成的行以创建没有标题行的表格):| Header | Header 2 |
| ------ | -------- |
| Row 1 | Cell 1 |
| Row 2 | Cell 2 |
请注意,作为一个非常年轻的实现,Ink 并不完全支持所有 Markdown 规范,例如 CommonMark。 Ink 肯定旨在尽可能多地涵盖,并包含对最常用的 Markdown 功能的支持,但如果完整的 CommonMark 兼容性是您所需要的,那么您可能需要查看像 CMark 这样的工具。
Ink 使用高度模块化的 基于规则的内部架构,以使添加新规则和格式选项成为可能,而不会影响整个系统。
每个 Markdown 片段都由符合内部 Readable
和 HTMLConvertible
协议的类型单独解析和渲染——例如 FormattedText
、List
和 Image
。
要解析 Markdown 文档的一部分,每种片段类型都使用一个 Reader
实例来读取 Markdown 字符串并断言其结构。错误 用作控制流,以指示解析操作是否成功,这反过来使父上下文可以决定是前进当前的 Reader
实例还是将其回退。
开始探索 Ink 实现的一个好地方是查看主 MarkdownParser
类型的 parse
方法,然后更深入地研究各种 Fragment
实现和 Reader
类型。
Ink 最初由 John Sundell 编写,作为静态站点生成工具 Publish 套件的一部分,该套件用于构建和生成 Swift by Sundell。构成 Publish 套件的其他工具也将很快开源。
Markdown 格式由 John Gruber 创建。 您可以在 此处找到更多相关信息。
Ink 完全以开放方式开发,非常欢迎您的贡献。
在开始在您的任何项目中使用 Ink 之前,强烈建议您花几分钟时间熟悉其文档和内部实现,以便您准备好解决可能遇到的任何问题或极端情况。
由于这是一个非常年轻的项目,它可能有很多局限性和缺失的功能,只有当更多的人开始使用它时,才能真正发现和解决这些问题。 虽然 Ink 在生产中用于渲染所有 Swift by Sundell 的内容,但建议您首先针对您的特定用例进行尝试,以确保它支持您需要的功能。
本项目不提供基于 GitHub Issues 的支持。我们鼓励用户积极参与项目的持续开发,包括修复遇到的任何错误,或改进任何需要完善的文档。
如果您希望进行更改,请发起 Pull Request——即使只是包含您计划的更改草案,或者重现问题的测试用例——我们可以在那里进一步讨论。
希望您喜欢使用 Ink!