API 库的文档体系支持:主流编程语言的文档设计
Posted Phodal
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了API 库的文档体系支持:主流编程语言的文档设计相关的知识,希望对你有一定的参考价值。
去年,我们在那篇《编程语言的 IDE 支持》详细讨论了在不同 IDE、编辑器里,它们是如何提供对于编程语言的支持。在这一篇文章里,我们将不那么详细地讨论一下:不同的编程语言如何提供文档支持?如此一来,也能在未来为 Datum Lang 提供相关的理论体系支持。这里所指的编程语言的文档体系,主要是指语言标准库中的文档。
新一代编程语言的文档体系
作为一个程序员,和诸多人一样,我并不热衷于在代码中写文档/注释。只是呢,诸多的情况下,我们依旧不得不写文档,如编程语言的标准库、API、SDK 等。在各个语言中,它们有各自不同的实践,有各自不同的特点。
起先,我只分析过 Rust 语言中的 rustdoc
,分析它是如何自动化处理相关文档的。后来,联想到了其它语言的文档形式是不是也会类似。接着,便尝试性的整理自 2012 年后“比较”(相对,至少是我听得多的)主流的语言的文档方式。
于是,便花了点时间,从相关的代码库中快速梳理而来。因时间有限,加之不擅长某些语言。所以,结论上的可能并不是这么完整,欢迎各位读者指正。
从文档编写方式上来看,Rust、Julia、Dart、Kotlin、Swift 的文档工具都是相似的:基于 markdown 语法的基础上,进行了一系列的定制。如 Swift 文档中添加的一些特别的标准,如关于复杂度( Complexity
)的特别说明,便使用了类似的方式来实现。而像 Julia 语言里的 DocumenterTools 则做了大量的定制,则可以基于 index.md
对内容进行特别处理,并添加大量的自定义语法。
从文档代码一致性上来看,从我初步阅读代码的情况来看,Rust、Julia 的文档工具都会校验文档中的代码是不是正常的,并能对其进行测试。如 Rustdoc 会编译、运行文档中的代码,可以通过 Rust 自身提供的断言语法(如 assert_eq!
)进行测试。而像 Julia 里的 DocumenterTools 则做了更多的定制,如可以为文档添加 setup
方法,还能进行一系列相关的断言等。
除此,在 R 语言中提供的 R Markdown 也比较有意思,它提供了一种可执行文档的新思路,即让 markdown 与代码有机的结合在一起,结合 pandoc 构建了新的文档可能性。后续,可能会在文档体验设计相关的文章中,进行详细的介绍。
Rust 的文档测试示例
说了那么多,让我们先简单看个示例。如下是一段 Rust 中的注释代码:
# Examples
```rust
assert_eq!(2 + 2, 4);
```
Rust 在遍历了语法树之后,会:
解析 markdown,寻找 Rust 语言的语法块(如果没有标注语言类型,默认是 Rust)
根据语法块,做一些简单的处理,生成可编译的代码
编译上述的测试代码 (如果编译失败,则说明测试失败)
运行这些测试 or 文档
如下是 Rustdoc 中将上述的代码生成测试代码的测试用例:
#![allow(unused)]
fn main() {
#[allow(non_snake_case)]
fn _doctest_main__some_unique_name() {
assert_eq!(2 + 2, 4);
}
_doctest_main__some_unique_name()
}
一旦上述的代码编译并运行通过,则说明文档中的注释是正确的。
详细见 Rustdoc 相关源码:librustdoc
构建文档体系:markdown 即 DSL
基于上述语言的文档体系,我们就能浮现出基本的原型。核心便是:基于 markdown 而扩展,将 markdown 视为可扩展的 DSL。如此以来,便可以按需添加功能,并根据不同需要进行可视化展示。
0. 基于 markdown
这一点倒是没有啥说的,markdown 在今天已经成为了事实上的开发文档标准。
1. 为扩展设计:文档 DSL
从做法上可以分为:
让语法块可运行。让 markdown 中的代码块包含更多的含义,根据不同的代码块来对语言进行特殊处理。如 Julia 的 Documenter.jl 便定义了一系列的如可执行的 eval
、REPL 环境输出的 repl
、文档测试 jldoctest
等。除此,一旦我们使用特定的符号来标记时,我们就可以在代码中添加更多的可能性。
添加自定义符号。添加一些自定义的语法,以支持更多的高级功能。如 KotlinDoc/KDoc 中使用的 Dokka,使用 []
来链接元素,这种方式和 markdown 比较贴进。
文档编排。通过自定义元素,实现在 markdown 对于内容的“编程”(管理、引用等)。如 Julia 的 Documenter.jl 中创建的 @ref
、 @docs
、 @meta
、 @content
等语法。
而除了上述的内容,我们还可以做更多的事,诸如于对于“代码的引用”等。
2. 为准确性设计:文档测试
为了确保文档与代码保持一致,又或者是文档中代码的准确性,我们需要引入文档测试的方式来检查 API。以 Rust 和 Julia 这两个语言来分析的话,主要可以分为多种情况:
代码编译通过。
代码运行不报错。可以在其中支持语言本身的断言。
与输出一致。文档需要输出程序的输出,它可以通过运行对应的测试,并保持两者是一致的。
主要的实现步骤可以参见上述的 Rust 语言实现。
3. 构建开放协作平台:开放协作
作为一个代码库的文档体系,它应该是开源的,能让所有的人为之做贡献,才会吸引到更多的开发者。
其它
人家苦短,让我们用 markdown 编程。
以上是关于API 库的文档体系支持:主流编程语言的文档设计的主要内容,如果未能解决你的问题,请参考以下文章