使用Sphinx与Markdown而非reST

260 投票
12 回答
71493 浏览
提问于 2025-04-15 20:34

我不喜欢reST,但我喜欢Sphinx。有没有办法让Sphinx用Markdown而不是reStructuredText来读取呢?

12 个回答

35

这个不使用Sphinx,不过MkDocs可以用Markdown来生成你的文档。我也不喜欢rst,至今为止我对MkDocs的体验非常好。

106

要做到这一点的“正确”方法是为markdown写一个docutils解析器。(还需要一个Sphinx选项来选择解析器。)这样做的好处是可以立即支持所有docutils输出格式(不过你可能不太在意,因为类似的markdown工具已经存在于大多数情况下)。如果不从头开发解析器,可以考虑以下几种方法:

  1. 你可以“作弊”,写一个“解析器”,利用Pandoc将markdown转换为RST,然后把结果传给RST解析器 :-).

  2. 你可以使用现有的markdown到XML的解析器,然后将结果转换(使用XSLT?)为docutils的格式。

  3. 你可以使用一些现有的Python markdown解析器,让你定义一个自定义的渲染器,并让它构建docutils节点树。

  4. 你可以分叉现有的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-discusshttps://github.com/scholmd/scholmd/

这也意味着你不能仅仅重用一个markdown解析器,而不以某种方式扩展它。Pandoc再次证明了它作为文档转换瑞士军刀的声誉,支持自定义过滤器。(实际上,如果我来处理这个问题,我会尝试在docutils读取器/转换器/写入器和pandoc读取器/过滤器/写入器之间建立一个通用桥梁。这比你需要的要多,但收益将远远超过仅仅是sphinx/markdown。)


另一个疯狂的想法:与其扩展markdown来处理Sphinx,不如扩展reStructuredText以支持(主要)markdown的超集!这样做的好处是你可以直接使用任何Sphinx功能,同时能够用markdown编写大部分内容。

已经有相当大的语法重叠;最显著的是链接语法不兼容。我认为如果你为RST添加对markdown链接的支持,以及###样式的标题,并将默认的`backticks`角色改为字面量,可能还要将缩进块改为字面量(RST现在支持> ...用于引用),你将得到一个可用的东西,支持大部分markdown。

130

你可以在同一个 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。你可以查看这个回答的 早期版本 来了解具体操作。

撰写回答