Haddock#
简介#
Haddock:根据 Haskell 源码和注释生成文档的工具,是 Haskell 事实上的文档生成器;
Haddock 使用特殊注释生成文档,没有特殊注释 Haddock 也可从签名和类型声明生成文档;
Haddock 支持 HTML、LaTeX 格式和 hoogle 后端;
下载:官网,通常已整合到 GHC 中;
使用:
$ haddock [OPTION...] file...
参数
生成文档的目标文件,接受
.hs
和.lhs
文件。选项
-
--odir
<dir>
,
-o
<dir>
# 生成文档于指定目录,默认为当前目录。
-
--html
,
-h
#
生成 HTML 格式的文档。目录结构:
MODULE-NAME.html
:各模块的文档;mini_module.html
:各模块梗概文档;index.html
:顶级页面;doc-index-X.html
:按字母表排序的文档;SOME.css
:使用到的 CSS;haddock-util.js
:使用到的 JavaScript 文件;
-
--latex
#
生成 LaTeX 格式的文档。目录结构:
pacakge.tex
:顶级 LaTeX 源文件;haddock.sty
:默认样式;MODULE.tex
:各模块的文档;
-
--hoogle
#
生成用于 Hoogle 引擎后端的索引文件,必须设置
--package-name
选项。
-
--mathjax
<url>
# 指定 MathJax 地址。
-
--pretty-html
#
生成 HTML 文件时使用换行和缩进。
-
--use-unicode
#
生成 HTML 文件时使用 Unicode 字符集。
-
--package-name
<name>
# 设置包名。
-
--package-version
<version>
# 设置包版本。
-
--help
,
-?
#
帮助信息。
-
语法#
顶级声明#
-- |<annotation>
-- ...
<top-level declaration>
顶级声明:函数类型签名、类型声明、
class
声明、data
声明、pattern
声明、newtype
声明、type
声明、instance
声明等;-- |
:- 在顶级声明的上一行添加该特殊注释,对该声明进行文档注释;
- 也可将注释置于声明的下一行,类似于 Python 的 Docstring;
- 支持多行文档注释,文档注释持续到第一个非注释行;
-- | 函数 'square' 对一个整数求平方根。 -- 接受一个 'Int' 类型的参数。 square :: Int -> Int -- 顶级函数声明 square x = x * x
{-|<annotation>-}
:多行注释也支持文档注释;{-| 函数 'square' 对一个整数求平方根。 接受一个 'Int' 类型的参数。 -} square :: Int -> Int square x = x * x
部分声明#
-- ^<annotation>
部分声明:对声明中的一部分进行文档注释;
-- ^
:用于一行末尾,对当前行起作用;- 当值构造器和其参数位于同一行时,文档注释作用于值构造器;
data
声明后的deriving
关键字只能使用-- ^
;
1data T a b 2 = C1 -- ^ 'C1' 构造器说明 3 a -- ^ 'C1' 参数 'a' 说明 4 b -- ^ 'C1' 参数 'b' 说明 5 | C2 a b -- ^ 'C2' 构造器说明 6 deriving ( Eq -- ^ 类型类 'Eq' 说明 7 , Ord -- ^ 类型类 'Ord' 说明 8 ) 9 10data R a b = 11 C { a :: a -- ^ 'a' 字段说明 12 , b :: b -- ^ 'b' 字段说明 13 } 14 15f :: Int -- ^ 'Int' 参数说明 16 -> Float -- ^ 'Float' 参数说明 17 -> IO () -- ^ 返回值说明
-- |
也可对部分种类的声明的一部分进行文档注释,但需要置于对象的上一行;1data T a b 2 -- | 'C1' 构造器说明 3 = C1 a b 4 -- | 'C2' 构造器说明 5 | C2 a b 6 7data R a b = 8 C { -- | 'a' 字段说明 9 a :: a, 10 -- | 'b' 字段说明 11 b :: b 12 }
模块描述#
{-|
<label> : <description>
...
<long-description>
-}
可对整个模块本身进行文档注释;
单行和多行注释均可;
标签:对文档进行说明的字段;
可选,但使用时必须按顺序出现;
{-| Copyright : (c) J. Random, 2077 License : GPL-3 -}
支持多行说明,但连续行的缩进必须大于标签所在行的缩进;
-- | Copyright : (c) J. Random, 2077 -- F. Foobar, 2077
字段:
Module
:模块名;Description
:对模块功能的简短描述;Copyright
:版权信息;License
(Licence
):模块使用许可证;Maintainer
:模块维护者邮箱;Stability
:模块稳定性(stable
、experimental
等);Portability
:操作系统或 GHC 版本,因人而异;
说明:在字段之后,可对模块进行整体性说明,所有 Haddock 标记语法在该部分均有效;
1{-|
2 Module : Sample
3 Description : 对模块的简短描述
4 Copyright : (c) J. Random, 2077
5 F. Foobar, 2077
6 License : MIT
7 Maintainer : random@email.com
8 Stability : experimental
9 Portability : POSIX
10
11 此处为模块的详细说明,可包含其他@标记语法@。
12-}
13module Sample where
文档结构#
排版顺序#
- 文档排版的顺序与导出的顺序相同;
1module Image
2 ( -- * 图像导入函数
3 -- 此处为描述 ...
4 readImage
5 , readPngImage
6 , readGifImage
7 ...
8 ) where
9
10-- 代码实现的顺序可以和导出的顺序不同。
11-- 最终生成的文档顺序以导出时定义的顺序为准。
12
13readImage :: FilePath -> IO Image
14readImage = ...
15
16readGifImage :: FilePath -> IO Image
17readGifImage = ...
18
19readPngImage :: FilePath -> IO Image
20readPngImage = ...
模块重导出#
当重新在导出列表中导出另一个模块时,若模块完全导入,则 Haddock 会生成链接到该模块的链接;
module A (module B, module C) where import B import C -- 生成跳转到模块 'B' 和 'C' 的联链接
若模块不完全导入(
hiding
等),则 Haddock 会生成导入部分对象的文档;module A (module B, module C) where import B hiding (f) import C (a, b) -- 生成模块 'B' 中除 'f' 外所有对象的文档 -- 模块 'C' 中只生成 'a' 和 'b' 的文档
章节标题#
-- * <heading>
-- ** <heading>
-- *
:定义一个章节标题,星号越多标题层级越低;1module Image 2 ( -- * 函数 3 -- ** 图像导入函数 4 readImage 5 , readPngImage 6 , readGifImage 7 -- ** 图像导出函数 8 , writeImage 9 , writePngImage 10 , writeGifImage 11 ) where
若定义了标题,则 Haddock 会自动在模块文档的顶部生成目录;
若定义了导出列表,则标题必须在导出列表中定义;若未定义导出列表,则可直接定义在模块体中;
module Image where -- * 函数 -- ** 图像导入函数 readImage :: ... ... -- ** 图像导出函数 writeImage :: ... ...
命名文档块#
-- $<name>
-- ...
文档块:和任何声明都无关联的文档说明,可置于模块描述中,或与标题相关联;
关联方式:
用
-- |
直接书写在导出列表中(无命名);module Sample ( -- * 章节标题 -- | 和特定实体无关联的文档说明 ... ) where
将文档块置于模块体中,使用
-- $<name>
命名并引用文档块,此时命名文档块必须位于所有导入语句之后;module Sample ( -- * 章节标题 -- $doc ... ) where import ... -- $doc -- 一大段文档说明。 -- 用名称 $doc 关联。
直接置于模块体中,使用
-- $<name>
命名并引用文档块,自动与前一个标题相关联(若不命名,而是直接使用-- |
,则自动与同一标题下的下一个声明相关联);module Sample where -- * 章节标题 -- $doc -- 一大段文档说明。 -- 用名称 $doc 与前一标题关联。
超链接和重导出#
- 当 Haddock 生成文档时,导入的对象会链接到各自对应的定义处;
- 每个对象都有一个家模块,Haddock 在链接对象时会指向其家模块,除非当前模块重导出了该对象,此时 Haddock 会链接到当前模块;
- 家模块:
1module A (T) where -- 'T' 的家模块
2data T a = C a
3
4module B (f) where
5import A
6f :: T Int -> Int -- 超链接至 A.T
7f (C i) = i
8
9module C (T, f) where -- 本地超链接至 C.T
10import A
11import B
模块属性#
{-# OPTIONS_HADDOCK <attribute>, ... #-}
- 模块属性定义于编译选项中、模块描述之前或之后,多个属性用逗号分隔;
- 属性:
hide
:生成文档时忽略该模块,但其他模块重导出对象时同样生成文档;prune
:生成文档时忽略没有文档注释的对象;ignore-exports
:忽略导出列表;not-home
:对导出的对象来说,当前模块不是家模块,除非没有其他模块能作为对象的家模块;show-extensions
:仅当导出格式支持时,在文档中显示当前模块使用的编译选项;
标记#
段落#
- 一或多个空行分隔段落;
字符实体#
-- &#<decimals>;
-- &#x<hexadecimals>;
- 虽然 Haddock 源文件支持 Unicode 字符集,但只有 ASCII 字符集具有可移植性;
- Haddock 支持 SGML 格式的字符实体引用,可用十进制或十六进制定义字符实体;
-- λ 表示小写 λ。
代码块#
-- @
-- <code>
-- @
-- > <code>
- 使用
@
包围段落可将段落或字符串指定为代码块,@
中其他标记语法均有效; - 在段落所有行前使用
>
可将段落指定为代码块,>
中不能使用其他标记语法;
-- @f x = x + x@ 是一个代码块
-- > g x = x * 42
例子#
-- >>> <code>
>>>
定义一个 REPL 例子;
-- | 以下给出两个例子:
--
-- >>> fib 10
-- 55
--
-- >>> putStrLn "foo\nbar"
-- foo
-- bar
标题#
-- = <heading>
-- == <heading>
-- = __<collapse>__
=
定义标题,=
越多标题级别越低,最多6个=
;- 标题之后可直接后接段落级别的内容,不用另起新行;
= __<collapse>__
定义可折叠区块,改变=
数量可改变级别;- 可折叠区域一直延伸至下一个同级别及以上标题或注释结束;
1-- |
2-- === __例子:__
3-- >>> foo 1 2
4-- 3
5--
6-- ==== 落入折叠区域中
7-- 一些例子
8--
9-- === 不属于折叠区域
10-- 更多内容
链接#
-- '<module>.<identifier>'
-- "<module>"
-- <<url>>
标识符:
- 用单引号
''
、反引号``
或单引号和反引号(`'
或'`
)包围标识符可创建指向该标识符定义的本地链接; - 创建链接时 Haddock 会检查标识符是否存在于本地,不存在则不创建链接;
- 添加模块名可链接至范围外的标识符,生成文档后不会显示模块名;
- 引号中存在特殊字符时不用特意转义,可直接使用;
- 不能直接引用中缀和前缀运算符,可先用
@
包围转换为代码块,再在@
内引用运算符;
-- | 标识符 'M.T' 不在范围内。 -- 不需要对 foo' 进行转义:'foo''。 -- 前缀运算符 @('++')@ 和中缀标识符 @'`elem`'@。
- 用单引号
模块:用双引号
""
包围模块名可创建指向该模块的超链接;- 模块不会检查模块的存在情况,始终创建链接;
-- | 超链接至模块 "Foo"。
URL:用尖括号
<>
包围 URL 可创建链接;- Haddock 会检测
http://
、ssh://
等协议头,并自动将其转换为超链接;
- Haddock 会检测
锚点#
-- #<label>#
-- "<module>#<label>"
##
包围定义一个被引用的锚点,生成文档后不会显示;"<module>#<label>"
创建一个指向锚点的链接,模块名不一定为当前模块;
-- |#anc#这是一个锚点。
-- |点击 "Sample#anc" 跳转锚点。
列表#
-- * <item>
-- (1) <item>
-- 1. <item>
-- [<identifier>]: <description>
- 无序列表:段落前的
*
定义无序列表; - 有序列表:段落前的
(n)
或n.
定义有序列表; - 术语列表:
[]
定义术语项(可使用其他标记语法),分号后定义描述; - 列表项可跨行;
- 列表可嵌套,嵌套列表缩进为 4 个空格;
- 位于同一缩进层次的列表项属于同一列表级别;
1-- | 列表:
2--
3-- * 列表首项。
4-- 该行属于上一列表项。
5--
6-- (1) 嵌套列表。
7-- 缩进列表。
8--
9-- [@foo@]: @foo@ 的说明。
10-- 该实体为函数。
11--
12-- > foo x y = x + y
13--
14-- 2. 同一缩进层级的列表项。
15--
16-- * 顶级列表项。
17-- 缩进列表项。
元数据#
-- @since <version>
@since
注释后只能接模块的版本号,表示对象最早在模块中定义时的版本号;@since
为段落级别;- 多个
@since
只有最后一个有效;
-- | 备注:'elem' 通常用作中缀标识符。
--
-- @since 4.8.0.0