使用Sphinx与Markdown而非reST
我不喜欢reST,但我喜欢Sphinx。有没有办法让Sphinx用Markdown而不是reStructuredText来读取呢?
12 个回答
这个不使用Sphinx,不过MkDocs可以用Markdown来生成你的文档。我也不喜欢rst,至今为止我对MkDocs的体验非常好。
要做到这一点的“正确”方法是为markdown写一个docutils解析器。(还需要一个Sphinx选项来选择解析器。)这样做的好处是可以立即支持所有docutils输出格式(不过你可能不太在意,因为类似的markdown工具已经存在于大多数情况下)。如果不从头开发解析器,可以考虑以下几种方法:
你可以“作弊”,写一个“解析器”,利用Pandoc将markdown转换为RST,然后把结果传给RST解析器 :-).
你可以使用现有的markdown到XML的解析器,然后将结果转换(使用XSLT?)为docutils的格式。
你可以使用一些现有的Python markdown解析器,让你定义一个自定义的渲染器,并让它构建docutils节点树。
你可以分叉现有的RST读取器,去掉所有与markdown无关的部分,并修改不同的语法(这个对比可能会有帮助)...
编辑:我不推荐这种方法,除非你准备进行大量测试。markdown已经有太多微妙不同的方言,这可能会导致又一个新的方言...
更新: https://github.com/sgenoud/remarkdown是一个用于docutils的markdown读取器。它没有采用上述任何捷径,而是使用了Parsley PEG语法,灵感来自peg-markdown。
- 尚不支持指令。
更新: https://github.com/readthedocs/recommonmark是另一个docutils读取器,在ReadTheDocs上原生支持。 它源自remarkdown,但使用了CommonMark-py解析器。
- 它可以转换特定的相对自然的Markdown语法为适当的结构,例如将链接列表转换为toctree。* 不支持角色的通用原生语法。
- 支持嵌入任何 rST内容,包括指令,使用
```eval_rst
围栏块以及指令的简写DIRECTIVE_NAME:: ...
。
更新: MyST是另一个docutils/Sphinx读取器。基于markdown-it-py,兼容CommonMark。
- 有一个通用的
{ROLE_NAME}`...`
语法用于角色。 - 有一个通用的指令语法,使用
```{DIRECTIVE_NAME} ...
围栏块。
在所有情况下,你需要发明Markdown的扩展来表示Sphinx指令和角色。虽然你可能不需要所有的指令,但像.. toctree::
这样的指令是必不可少的。
我认为这是最难的部分。在Sphinx扩展之前,reStructuredText已经比markdown丰富得多。即使是像pandoc这样的大幅扩展markdown,仍然主要是rST功能集的一个子集。这需要覆盖很多内容!
从实现的角度来看,最简单的事情是添加一个通用的构造来表达任何docutils角色/指令。语法灵感的明显候选者有:
- 属性语法,pandoc和其他一些实现已经允许在许多内联和块构造中使用。例如
`foo`{.method}
->`foo`:method:
。 - HTML/XML。从
<span class="method">foo</span>
到最笨拙的方法,直接插入docutils内部XML! - 某种YAML用于指令?
但这样的通用映射可能不是最markdown风格的解决方案... 目前讨论markdown扩展的最活跃地方是https://groups.google.com/forum/#!topic/pandoc-discuss,https://github.com/scholmd/scholmd/
这也意味着你不能仅仅重用一个markdown解析器,而不以某种方式扩展它。Pandoc再次证明了它作为文档转换瑞士军刀的声誉,支持自定义过滤器。(实际上,如果我来处理这个问题,我会尝试在docutils读取器/转换器/写入器和pandoc读取器/过滤器/写入器之间建立一个通用桥梁。这比你需要的要多,但收益将远远超过仅仅是sphinx/markdown。)
另一个疯狂的想法:与其扩展markdown来处理Sphinx,不如扩展reStructuredText以支持(主要)markdown的超集!这样做的好处是你可以直接使用任何Sphinx功能,同时能够用markdown编写大部分内容。
已经有相当大的语法重叠;最显著的是链接语法不兼容。我认为如果你为RST添加对markdown链接的支持,以及###
样式的标题,并将默认的`backticks`
角色改为字面量,可能还要将缩进块改为字面量(RST现在支持> ...
用于引用),你将得到一个可用的东西,支持大部分markdown。
你可以在同一个 Sphinx 项目中同时使用 Markdown 和 reStructuredText。这方面的具体操作可以在 Sphinx 的文档 中找到简单明了的说明。
首先,你需要安装 myst-parser
(可以通过命令 pip install myst-parser
来安装),然后编辑 conf.py
文件:
# simply add the extension to your list of extensions
extensions = ['myst_parser']
source_suffix = ['.rst', '.md']
我在 Github 上创建了一个小示例项目 (serra/sphinx-with-markdown),展示了如何使用这个功能。这个项目使用的是 Sphinx 版本 3.5.4 和 myst-parser 版本 0.14.0。
实际上,MyST parser 让你可以用 Markdown 写整个 Sphinx 文档。它支持一些指令,并且你可以通过在 conf.py 中的配置启用多个扩展功能。
需要注意的是,MyST parser 要求 Sphinx 版本在 2.1 或更高。如果你使用的是更早版本的 Sphinx,可以通过 recommonmark 来在 Sphinx 中使用 Markdown。你可以查看这个回答的 早期版本 来了解具体操作。