sphinx-js¶
为什么¶
编写JavaScript库时, 如何向人们解释? 如果它是用户熟悉的域中的一个小项目, 那么JSDoc按字母顺序排列的例程列表就足够了. 但是在一个更大的项目中, 散布散文与API文档是有用的, 而无需复制和粘贴内容.
sphinx-js允许您使用业界领先的 Sphinx 文档工具和JS项目. 它提供了一些指令, 在以Python为中心的 autodoc 之后, 用于将JSDoc格式的文档拉入reStructuredText页面. 而且, 因为您可以在代码中继续使用JSDoc, 所以您仍然可以与其他JS工具兼容, 例如Google的Closure Compiler.
配置¶
使用npm安装JSDoc.
jsdoc
必须在你的$PATH
上, 所以你可能想要全局安装它:npm install -g jsdoc
我们使用jsdoc 3.4.3,3.5.4, 很可能还有其他版本.
安装sphinx-js, 它会将Sphinx本身作为一个依赖项:
pip install sphinx-js
通过运行
sphinx-quickstart
并回答问题, 在项目中创建一个文档文件夹:cd my-project sphinx-quickstart > Root path for the documentation [.]: docs > Separate source and build directories (y/n) [n]: > Name prefix for templates and static dir [_]: > Project name: My Project > Author name(s): Fred Fredson > Project version []: 1.0 > Project release [1.0]: > Project language [en]: > Source file suffix [.rst]: > Name of your master document (without suffix) [index]: > Do you want to use the epub builder (y/n) [n]: > autodoc: automatically insert docstrings from modules (y/n) [n]: > doctest: automatically test code snippets in doctest blocks (y/n) [n]: > intersphinx: link between Sphinx documentation of different projects (y/n) [n]: > todo: write "todo" entries that can be shown or hidden on build (y/n) [n]: > coverage: checks for documentation coverage (y/n) [n]: > imgmath: include math, rendered as PNG or SVG images (y/n) [n]: > mathjax: include math, rendered in the browser by MathJax (y/n) [n]: > ifconfig: conditional inclusion of content based on config values (y/n) [n]: > viewcode: include links to the source code of documented Python objects (y/n) [n]: > githubpages: create .nojekyll file to publish the document on GitHub pages (y/n) [n]: > Create Makefile? (y/n) [y]: > Create Windows command file? (y/n) [y]:
在生成的 Sphinx conf.py 文件中, 将
sphinx_js
添加到extensions
:extensions = ['sphinx_js']
如果您的JS源代码在项目的根目录中的任何位置, 请在 conf.py 中自行添加
js_source_path = '../somewhere/else'
. JS源代码树的根目录应该是相对于 conf.py 文件的设置指向的位置. (当项目的根目录下有一个docs
文件夹并且你的源代码直接存在于根目录中时, 默认的../
效果很好. )如果您有特殊的jsdoc配置, 请将
jsdoc_config_path = '../conf.json'
(例如)添加到 conf.py 中.如果您只记录JS而没有其他语言, 则可以在conf.py中将“主域”设置为JS:
primary_domain = 'js'
然后你可以省略下面指令中的所有 “js:” 前缀.
使用¶
简而言之, 编写一个充满reStructuredText文件的文件夹, 使用以下指令来获取JSDoc文档, 然后告诉Sphinx通过在docs目录中运行 make html
来渲染它. 如果您之前从未使用过Sphinx或编写过reStructuredText, 那么这里是 我们在其教程中停止的地方 . 为了快速入门, 现在只需向index.rst添加内容即可.
自动功能¶
首先, 使用标准JSDoc格式记录您的JS代码:
/**
* Return the ratio of the inline text length of the links in an element to
* the inline text length of the entire element.
*
* @param {Node} node - Types or not: either works.
* @throws {PartyError|Hearty} Multiple types work fine.
* @returns {Number} Types and descriptions are both supported.
*/
function linkDensity(node) {
const length = node.flavors.get('paragraphish').inlineLength;
const lengthWithoutLinks = inlineTextLength(node.element,
element => element.tagName !== 'A');
return (length - lengthWithoutLinks) / length;
}
然后, 使用sphinx-js指令引用您的文档. 我们的指令与Sphinx标准的autodoc指令非常相似. 你只能指定一个函数的名字……
.. js:autofunction:: someFunction
…一个格式很好的文档块将显示在您的文档中.
如果要记录可选参数, 也可以输入自己的显式参数列表:
.. js:autofunction:: someFunction(foo, bar[, baz])
参数属性和解构参数也可以使用 标准JSDoc语法:
/**
* Export an image from the given canvas and save it to the disk.
*
* @param {Object} options Output options
* @param {string} options.format The output format (``jpeg``, ``png``, or
* ``webp``)
* @param {number} options.quality The output quality when format is
* ``jpeg`` or ``webp`` (from ``0.00`` to ``1.00``)
*/
function saveCanvas({ format, quality }) {
// ...
}
提取默认参数值也很有效. 这些行为符合预期, 但有一些注意事项:
/**
* You must declare the params, even if you have nothing else to say, so
* JSDoc will extract the default values.
*
* @param [num]
* @param [str]
* @param [bool]
* @param [nil]
*/
function defaultsDocumentedInCode(num=5, str="true", bool=true, nil=null) {}
/**
* JSDoc guesses types for things like "42". If you have a string-typed
* default value that looks like a number or boolean, you'll need to
* specify its type explicitly. Conversely, if you have a more complex
* value like an arrow function, specify a non-string type on it so it
* isn't interpreted as a string. Finally, if you have a disjoint type like
* {string|Array} specify string first if you want your default to be
* interpreted as a string.
*
* @param {function} [func=() => 5]
* @param [str=some string]
* @param {string} [strNum=42]
* @param {string|Array} [strBool=true]
* @param [num=5]
* @param [nil=null]
*/
function defaultsDocumentedInDoclet(func, strNum, strBool, num, nil) {}
您甚至可以添加其他内容. 如果这样做, 它将出现在任何提取的文档下面:
.. js:autofunction:: someFunction
Here are some things that will appear...
* Below
* The
* Extracted
* Docs
Enjoy!
js:autofunction
有一个选项, :short-name:
, 它对于链接的API很方便, 它们的实现细节你想要看不见. 当你在类方法上使用它时, 文档中不会提到包含类, 函数将在其索引中的短名称下出现, 并且交叉引用也必须使用短名称(:func:`someFunction `
):
.. js:autofunction:: someClass#someFunction
:short-name:
autofunction
也可用于使用 @callback标签 定义的回调.
有一些实验支持滥用 autofunction
来记录 @typedef tags, 虽然结果将被设计为一个函数, 并且 @property
标签会在 “Arguments” 标题下误导. 不过, 在我们能够做到正确之前, 它总比没有好.
autoclass¶
我们提供了一个 js:autoclass
指令, 它使用类注释和构造函数注释的连接来记录一个类. 它共享 js:autofunction
的所有功能, 甚至采用相同的 :short-name:
标志, 这对于内部类可以派上用场. 使用它的最简单方法是调用它的 :members:
选项, 它自动记录你所有类的所有公共方法和属性:
.. js:autoclass:: SomeEs6Class(constructor, args, if, you[, wish])
:members:
您可以通过说…添加私人会员:
.. js:autoclass:: SomeEs6Class
:members:
:private-members:
隐私由JSDoc @private
标签决定.
用 :exclude-members:
按名称排除某些成员:
.. js:autoclass:: SomeEs6Class
:members:
:exclude-members: Foo, bar, baz
或者明确列出您想要的成员. 我们会尊重您的订购.
.. js:autoclass:: SomeEs6Class
:members: Qux, qum
显式列出成员时, 可以包含 *
以包含所有未提及的成员. 这对于控制某些元素的排序很有用, 而不必包含详尽的列表.
.. js:autoclass:: SomeEs6Class
:members: importMethod, *, uncommonlyUsedMethod
最后, 如果你想要完全控制, 可以通过嵌入 js:autofunction
或 js:autoattribute
来一次拉一个类成员.
.. js:autoclass:: SomeEs6Class
.. js:autofunction:: SomeEs6Class#someMethod
Additional content can go here and appears below the in-code comments,
allowing you to intersperse long prose passages and examples that you
don't want in your code.
autoattribute¶
这对于记录公共属性很有用:
class Fnode {
constructor(element) {
/**
* The raw DOM element this wrapper describes
*/
this.element = element;
}
}
然后, 在文档中……:
.. autoclass:: Fnode
.. autoattribute:: Fnode#element
这也是记录ES6风格的getter和setter的方法, 因为它省略了函数的尾随 ()
. 假定的做法是通常的JSDoc:只记录你的 getter/setter 对中的一个:
class Bing {
/** The bong of the bing */
get bong() {
return this._bong;
}
set bong(newBong) {
this._bong = newBong * 2;
}
}
然后, 在文档中……:
.. autoattribute:: Bing#bong
用路径名避免歧义¶
如果在不同文件中有相同名称的对象, 请使用路径名来消除它们的歧义. 这是一个特别长的例子:
.. js:autofunction:: ./some/dir/some/file.SomeClass#someInstanceMethod.staticMethod~innerMember
您可以从 JSDoc namepaths 中识别分隔符 #. 〜
. 他们在这里工作相同.
为简明起见, 您可以使用任何唯一的后缀, 只要它包含完整的路径段即可. 假设它们在源树中是唯一的, 这些都将等同于上述内容:
innerMember
staticMethod~innerMember
SomeClass#someInstanceMethod.staticMethod~innerMember
some/file.SomeClass#someInstanceMethod.staticMethod~innerMember
注意事项:
我们使用简单的文件路径而不是JSDoc的
module:
前缀.我们使用简单的反斜杠转义, 而不是在路径中途切换转义方案; JSDoc本身 也是如此. 需要转义的字符是
#.~(/
, 虽然你不需要在前导.
或../
中逃脱点. 一条非常可怕的路径可能是…::some/path\ with\ spaces/file.topLevelObject#instanceMember.staticMember\(with\(parens
相对路径相对于config中指定的
js_source_path
. 绝对路径是不允许的.
在幕后, sphinx-js 会将所有分隔符更改为点, 以便……
Sphinx的“缩短”语法有效:
:func:`~InwardRhs.atMost`
只打印atMost()
. (现在, 你应该总是使用点而不是其他名称路径分隔符:#〜
. )Sphinx索引信息更多, 称方法属于他们的类.
通过设置主域来保存击键¶
要保存一些击键, 你可以在conf.py中设置 primary_domain ='js'
然后说(例如) autofunction
而不是 js:autofunction
.
TypeScript支持¶
sphinx-js中有实验性的TypeScript支持. 通过设置配置变量 js_language ='typescript'
来启用它. 然后, 安装TypeDoc(版本0.11.1已知可以工作), 而不是安装JSDoc:
npm install -g typedoc
您将注意到的主要区别是函数文档中的其他 type 字段.
配置参考¶
js_language
根据您使用的语言, 使用 ‘javascript’ 或 ‘typescript’. 默认为 ‘javascript’.
js_source_path
扫描(非递归)JS文件的目录列表, 相对于Sphinx的conf.py文件. 如果只有一个字符串, 则可以是字符串. 如果有多个, 则必须指定
root_for_relative_js_paths
.jsdoc_config_path
jsdoc或typedoc配置文件的conf.py相对路径, 如果要指定自己的jsdoc选项(如递归和自定义文件名匹配), 这将非常有用.
root_for_relative_js_paths
如果要指定自己的jsdoc选项(例如递归和自定义文件名匹配), 则jsdoc或typedoc配置文件的conf.py相对路径很有用.
示例¶
使用大多数sphinx-js功能的一个很好的例子是Fathom文档. 一个特别多汁的页面是 https://mozilla.github.io/fathom/ruleset.html. 单击 “查看页面源” 链接以查看原始指令.
ReadTheDocs 是Sphinx文档的规范托管平台, 现在支持sphinx-js作为选择加入测试版. 把它放在你的repo根目录下的 .readthedocs.yml
文件中:
requirements_file: docs/requirements.txt
build:
image: latest
然后把你想要的sphinx-js版本放在 docs/requirements.txt
中. 例如…:
sphinx-js==2.5
或者, 如果您愿意, Fathom repo带有 Travis CI配置 和 部署脚本 用于使用sphinx-js构建文档并将它们发布到GitHub Pages. 随意借用它们.
注意事项¶
我们不理解内联JSDoc结构, 如
{@link foo}
;你现在必须使用Sphinx风格的等价物, 比如:js:func:`foo`
(或者只是:func:`foo`
如果你设置primary_domain ='js'
在conf.py.到目前为止, 我们理解并转换JSDoc块标签
@param
,@returns
,throws
,@example
(没有可选的<caption>
) ,@deprecated
,@see
和他们的同义词. 其他人将 噗 进入以太.
测试¶
运行 python setup.py test
. 运行 tox
来测试Python版本.
版本历史¶
- 2.7.1
修复Windows上UTF-8有时会发生的崩溃. #67.
始终对jsdoc的工作目录使用conf.py的目录. #78. (Thomas Khyn)
- 2.7
添加实验性TypeScript支持. (Wim Yedema)
- 2.6
添加对
@deprecated
和@see
的支持. (David Li)注意并记录JS variadic params很好. (David Li)
将linter添加到代码库.
- 2.5
使用记录的
@params
来帮助填写函数的正式参数列表. 这使我们不会错过使用解构的params. (flozz)缺少jsdoc时改进错误报告.
将提取的默认值添加到生成的正式参数列表中. (flozz and erikrose)
- 2.4
支持
@example
标签. (lidavidm)在Windows下工作. 以前, 我们几乎找不到任何文件. (flozz)
正确展开多行JSDoc标记, 即使它们具有Windows行结尾. (Wim Yedema)
删除对Python 3.3的支持, 因为Sphinx也已经这样做了.
在Sphinx> = 1.7.1下使用Recommonmark(用于Markdown支持)时修复构建时崩溃. (jamrizzi)
- 2.3.1
在Windows上找到jsdoc命令, 它具有不同的名称. 然后修补进程通信, 使其不挂起.
- 2.3
添加在
autoclass:members:
选项中说 “*” 的能力, 意思是 “和我没有明确列出的所有成员”.
- 2.2
为
@callback
标签添加autofunction
支持. (krassowski)为
@typedef
标签添加实验autofunction
支持. (KRASSOWSKI)为jsdoc找不到任何JS文件时添加一条很好的错误消息.
更紧密地固定六个, 以便
python_2_unicode_compatible
肯定会出现.
- 2.1
在
js_source_path
中允许多个文件夹. 这对于逐步将大型项目(一次一个文件夹)迁移到jsdoc非常有用. 引入root_for_relative_js_paths
以在多个源路径面前保持相对路径的明确性.聚合PathTaken错误, 并立即报告所有错误. 这意味着您在清理大型项目时不必重复运行JSDoc.
修复了在3.6之前的Python 3版本上崩溃的字节vs字符串问题. (jhkennedy)
容忍文件扩展名不是 “. js” 的JS文件. 之前, 当与摄取此类文件的自定义jsdoc配置结合使用时, 会生成不正确的对象路径名, 从而导致虚假的“找不到对象…的错误的JSDoc文档”.
- 2.0.1
通过首先将大型JSDoc输出写入临时文件来修复虚假语法错误. (jhkennedy)
- 2.0
处理模棱两可的对象路径. 具有相同JSDoc长名称的符号(例如在不同文件中称为 “foo” 的两个顶级事物)将不再具有另一个阴影. 引入用于引用对象的明确路径约定. 添加一个真正的解析器来解析它们, 而不是我们之前使用的肮脏技巧. 向后兼容性稍微破坏, 因为模糊引用现在是一个致命的错误, 而不是悄悄地引用JSDoc碰巧遇到的最后一个定义.
将所有内容索引到后缀树中, 以便您可以使用任何唯一的路径后缀来引用对象.
有一个真正的解析器的其他后果:
停止支持 “-” 作为名称路径分隔符.
不再虚假地将名称路径中的转义分隔符转换为点.
否则正确处理路径和逃逸. 例如, 我们现在可以处理包含 “(” 的符号.
在尝试收集标记为
@class
的普通旧对象的构造函数params时修复KeyError.
- 1.5.2
修复crasher, 同时警告未找到指定的长名称.
- 1.5.1
将
:members:
选项添加到autoclass
中.
- 1.5
在
autoclass
中添加:members:
选项.添加
:private-members:
和:exclude-members:
选项.重要的重构允许指令类相互通信.
- 1.4
添加
jsdoc_config_path
选项.
- 1.3.1
容忍包含在源代码中的@args和其他信息字段行.
在Sphinx发出的警告和错误中引用源注释的文件和行.
- 1.3
添加
autoattribute
指令.
- 1.2
始终做完全重建;当JS代码发生变化但RST没有变更时, 不要让页面过时.
使Python-3兼容.
添加基本的
autoclass
指令.
- 1.1
添加
:short-name:
选项.
- 1.0
初始版本, 只有
js:autofunction