将Sphinx与Markdown而不是RST一起使用

问题:将Sphinx与Markdown而不是RST一起使用

我讨厌RST,但喜欢狮身人面像。有没有一种方法可以让狮身人面像读取markdown而不是reStructuredText?

I hate RST but love sphinx. Is there a way that sphinx reads markdown instead of reStructuredText?


回答 0

做到这一点的“正确”方法是为降价编写docutils解析器。(加上一个Sphinx选项来选择解析器。)它的优点是可以立即支持所有docutils输出格式(但是您可能并不在意,因为大多数降价工具已经存在)。无需从头开发解析器的方法:

  • 您可以作弊并编写一个“解析器”,该解析器使用Pandoc将markdown转换为RST并将其传递给RST解析器:-)。

  • 您可以使用现有的markdown-> XML解析器,并将结果(使用XSLT?)转换为docutils模式。

  • 您可以使用一些现有的python markdown解析器,使您可以定义自定义渲染器,并使其构建docutils节点树。

  • 您可以分叉现有的RST阅读器,删除与降价无关的所有内容并更改不同的语法(此比较可能会有所帮助)…
    编辑:除非您准备好对其进行大量测试,否则我不建议您使用此路由。Markdown已经有太多不同的方言,这很可能会导致另一方言……

更新: https : //github.com/sgenoud/remarkdown是docutils的降价阅读器。它没有采用上述任何快捷方式,而是使用了受peg-markdown启发的Parsley PEG语法。尚不支持指令。

更新:https : //github.com/rtfd/recommonmark,这是另一个docutils阅读器,ReadTheDocs本身支持。 源自remarkdown,但使用CommonMark-py解析器。不支持指令,但可以将或多或少的自然Markdown语法转换为适当的结构,例如toctree的链接列表。对于其他需求,带```eval_rst围栏的块可让您嵌入任何rST指令。


所有情况下,您都需要发明Markdown的扩展来表示Sphinx指令和角色。虽然您可能不需要全部,但有些.. toctree::是必不可少的。
我认为这是最困难的部分。Sphinx扩展之前的reStructuredText已经比markdown丰富。即使是大幅扩展的降价促销(例如pandoc),也大多是rST功能集的子集。有很多方面需要解决!

在实现方面,最简单的方法是添加泛型构造以表达任何docutils角色/指令。语法启发的显而易见的候选人是:

  • pandoc和其他一些实现已允许在许多内联和块构造中使用属性语法。例如`foo`{.method}-> `foo`:method:
  • HTML / XML。从<span class="method">foo</span>只是插入docutils内部XML的kludgiest方法开始!
  • 某种针对指令的YAML?

但是这样的通用映射不会是最降价十岁上下的解决方案。目前最活跃的地方,讨论降价扩展是https://groups.google.com/forum/#!topic/pandoc-discusshttps://开头github.com/scholmd/scholmd/

这也意味着您不能只使用markdown解析器而不以某种方式扩展它。潘多克(Pandoc)通过支持定制过滤器(fils),再次履行其作为瑞士转换文件的军刀的声誉。(实际上,如果我要采用这种方法,我会尝试在docutils读取器/变压器/编写器与pandoc读取器/过滤器/编写器之间建立通用的桥梁。这超出了您的需求,但收益将远远超过狮身人面像/降价。)


另一个疯狂的主意:扩展reStructuredText而不是扩展markdown来处理Sphinx,以(主要)支持markdown的超集!这样做的好处是,您可以按原样使用任何Sphinx功能,但可以在markdown中编写大多数内容。

已经有相当多的语法重叠 ; 最明显的是链接语法不兼容。我认为,如果您为markdown链接和###-style标头添加了对RST的支持,并将默认`backticks`角色更改为文字,并且可能将缩进的块更改为文字(现在的RST支持> ...引号),那么您将获得支持大多数markdown的有用信息。

The “proper” way to do that would be to write a docutils parser for markdown. (Plus a Sphinx option to choose the parser.) The beauty of this would be instant support for all docutils output formats (but you might not care about that, as similar markdown tools already exist for most). Ways to approach that without developing a parser from scratch:

  1. You could cheat and write a “parser” that uses Pandoc to convert markdown to RST and pass that to the RST parser :-).

  2. You can use an existing markdown->XML parser and transform the result (using XSLT?) to the docutils schema.

  3. You could take some existing python markdown parser that lets you define a custom renderer and make it build docutils node tree.

  4. You could fork the existing RST reader, ripping out everything irrelevant to markdown and changing the different syntaxes (this comparison might help)…
    EDIT: I don’t recommend this route unless you’re prepared to heavily test it. Markdown already has too many subtly different dialects and this will likely result in yet-another-one…

UPDATE: https://github.com/sgenoud/remarkdown is a markdown reader for docutils. It didn’t take any of the above shortcuts but uses a Parsley PEG grammar inspired by peg-markdown.

UPDATE: https://github.com/readthedocs/recommonmark and is another docutils reader, natively supported on ReadTheDocs. Derived from remarkdown but uses the CommonMark-py parser.

  • It can convert specific more-or-less natural Markdown syntaxes to appropriate structures e.g. list of links to a toctree. * Doesn’t have generic native syntax for roles.
  • Supports embedding any rST content, including directives, with an ```eval_rst fenced block as well as a shorthand for directives DIRECTIVE_NAME:: ....

UPDATE: MyST is yet another docutins/Sphinx reader. Based on markdown-it-py, CommonMark compatible.

  • Has a generic {ROLE_NAME}`...` syntax for roles.
  • Has a generic syntax for directives with ```{DIRECTIVE_NAME} ... fenced blocks.

In all cases, you’ll need to invent extensions of Markdown to represent Sphinx directives and roles. While you may not need all of them, some like .. toctree:: are essential.
This I think is the hardest part. reStructuredText before the Sphinx extensions was already richer than markdown. Even heavily extended markdown, such as pandoc’s, is mostly a subset of rST feature set. That’s a lot of ground to cover!

Implementation-wise, the easiest thing is adding a generic construct to express any docutils role/directive. The obvious candidates for syntax inspiration are:

  • Attribute syntax, which pandoc and some other implementations already allow on many inline and block constructs. For example `foo`{.method} -> `foo`:method:.
  • HTML/XML. From <span class="method">foo</span> to the kludgiest approach of just inserting docutils internal XML!
  • Some kind of YAML for directives?

But such a generic mapping will not be the most markdown-ish solution… Currently most active places to discuss markdown extensions are https://groups.google.com/forum/#!topic/pandoc-discuss, https://github.com/scholmd/scholmd/

This also means you can’t just reuse a markdown parser without extending it somehow. Pandoc again lives up to its reputation as the swiss army knife of document conversion by supporting custom filtes. (In fact, if I were to approach this I’d try to build a generic bridge between docutils readers/transformers/writers and pandoc readers/filters/writers. It’s more than you need but the payoff would be much wider than just sphinx/markdown.)


Alternative crazy idea: instead of extending markdown to handle Sphinx, extend reStructuredText to support (mostly) a superset of markdown! The beauty is you’ll be able to use any Sphinx features as-is, yet be able to write most content in markdown.

There is already considerable syntax overlap; most notably link syntax is incompatible. I think if you add support to RST for markdown links, and ###-style headers, and change default `backticks` role to literal, and maybe change indented blocks to mean literal (RST supports > ... for quotations nowdays), you’ll get something usable that supports most markdown.


回答 1

您可以在同一Sphinx项目中使用Markdown和reStructuredText。如何完成此操作,请参见“ 阅读文档”

安装recommonmark(pip install recommonmark),然后编辑conf.py

from recommonmark.parser import CommonMarkParser

source_parsers = {
    '.md': CommonMarkParser,
}

source_suffix = ['.rst', '.md']

我已经在Github上创建了一个小示例项目(serra / sphinx-with-markdown),展示了它的工作原理。它使用CommonMark 0.5.4和recommonmark 0.4.0。

You can use Markdown and reStructuredText in the same Sphinx project. How to do this is succinctly documented on Read The Docs.

Install recommonmark (pip install recommonmark) and then edit conf.py:

from recommonmark.parser import CommonMarkParser

source_parsers = {
    '.md': CommonMarkParser,
}

source_suffix = ['.rst', '.md']

I’ve created a small example project on Github (serra/sphinx-with-markdown) demonstrating how (and that) it works. It uses CommonMark 0.5.4 and recommonmark 0.4.0.


回答 2

它不使用Sphinx,但是MkDocs将使用Markdown构建您的文档。我也讨厌rst,到目前为止,我非常喜欢MkDocs。

This doesn’t use Sphinx, but MkDocs will build your documentation using Markdown. I also hate rst, and have really enjoyed MkDocs so far.


回答 3

更新:现在已正式支持此功能,并在sphinx docs中进行了记录

看起来,基本的实现方式已将其引入Sphinx,但尚未达成共识。查看github问题评论

安装依赖项:

pip install commonmark recommonmark

调整conf.py

source_parsers = {
    '.md': 'recommonmark.parser.CommonMarkParser',
}
source_suffix = ['.rst', '.md']

Update: this is now officially supported and documented in the sphinx docs.

It looks like a basic implementation has made it’s way into Sphinx but word has not gotten round yet. See github issue comment

install dependencies:

pip install commonmark recommonmark

adjust conf.py:

source_parsers = {
    '.md': 'recommonmark.parser.CommonMarkParser',
}
source_suffix = ['.rst', '.md']

回答 4

Markdown和ReST做不同的事情。

RST提供了用于处理文档的对象模型。

Markdown提供了一种雕刻文字的方法。

想要从sphinx项目中引用您的Markdown内容似乎是合理的,使用RST存根整个信息结构和较大文档的流程。让markdown做什么,这使作者可以专注于编写文本。

有没有一种方法可以引用降价域名,仅按原样雕刻内容?RST / sphinx似乎已经照顾好功能,例如toctree没有在markdown中复制它们。

Markdown and ReST do different things.

RST provides an object model for working with documents.

Markdown provides a way to engrave bits of text.

It seems reasonable to want to reference your bits of Markdown content from your sphinx project, using RST to stub out the overall information architecture and flow of a larger document. Let markdown do what it does, which is allow writers to focus on writing text.

Is there a way to reference a markdown domain, just to engrave the content as-is? RST/sphinx seems to have taken care of features like toctree without duplicating them in markdown.


回答 5


回答 6

我同意贝尼(Beni)的建议,将pandoc用于此任务。安装后,以下脚本会将源目录中的所有markdown文件转换为rst文件,以便您可以将所有文档写入markdown中。希望这对其他人有用。

#!/usr/bin/env python
import os
import subprocess

DOCUMENTATION_SOURCE_DIR = 'documentation/source/'
SOURCE_EXTENSION = '.md'
OUTPUT_EXTENSION = '.rst'

for _, __, filenames in os.walk(DOCUMENTATION_SOURCE_DIR):
    for filename in filenames:
        if filename.endswith('.md'):
            filename_stem = filename.split('.')[0]
            source_file = DOCUMENTATION_SOURCE_DIR + filename_stem + SOURCE_EXTENSION
            output_file = DOCUMENTATION_SOURCE_DIR + filename_stem + OUTPUT_EXTENSION
            command = 'pandoc -s {0} -o {1}'.format(source_file, output_file)
            print(command)
            subprocess.call(command.split(' '))

I went with Beni’s suggestion of using pandoc for this task. Once installed the following script will convert all markdown files in the source directory to rst files, so that you can just write all your documentation in markdown. Hope this is useful for others.

#!/usr/bin/env python
import os
import subprocess

DOCUMENTATION_SOURCE_DIR = 'documentation/source/'
SOURCE_EXTENSION = '.md'
OUTPUT_EXTENSION = '.rst'

for _, __, filenames in os.walk(DOCUMENTATION_SOURCE_DIR):
    for filename in filenames:
        if filename.endswith('.md'):
            filename_stem = filename.split('.')[0]
            source_file = DOCUMENTATION_SOURCE_DIR + filename_stem + SOURCE_EXTENSION
            output_file = DOCUMENTATION_SOURCE_DIR + filename_stem + OUTPUT_EXTENSION
            command = 'pandoc -s {0} -o {1}'.format(source_file, output_file)
            print(command)
            subprocess.call(command.split(' '))

回答 7

有一种解决方法。
sphinx-quickstart.py脚本生成一个Makefile。
每次您想要生成文档时,都可以轻松地从Makefile中调用Pandoc,以将Markdown转换为reStructuredText。

There is a workaround.
The sphinx-quickstart.py script generates a Makefile.
You can easily invoke Pandoc from the Makefile every time you’d like to generate the documentation in order to convert Markdown to reStructuredText.


回答 8

这是一个新选项。MyST向Markdown添加了一些功能,这些功能使Sphinx可以像rst一样构建文档。 https://myst-parser.readthedocs.io/en/latest/

Here’s a new option. MyST adds some features to Markdown that allow Sphinx to build docs like rst does. https://myst-parser.readthedocs.io/en/latest/


回答 9

请注意,以下maven插件完全支持使用maven和嵌入式Sphinx + MarkDown支持构建文档:

https://trustin.github.io/sphinx-maven-plugin/index.html

<plugin>
  <groupId>kr.motd.maven</groupId>
  <artifactId>sphinx-maven-plugin</artifactId>
  <version>1.6.1</version>
  <configuration>
    <outputDirectory>${project.build.directory}/docs</outputDirectory>
  </configuration>
  <executions>
    <execution>
      <phase>package</phase>
      <goals>
        <goal>generate</goal>
      </goals>
    </execution>
  </executions>
</plugin>

Note that building documentation using maven and embedded Sphinx + MarkDown support is fully supported by following maven plugin :

https://trustin.github.io/sphinx-maven-plugin/index.html

<plugin>
  <groupId>kr.motd.maven</groupId>
  <artifactId>sphinx-maven-plugin</artifactId>
  <version>1.6.1</version>
  <configuration>
    <outputDirectory>${project.build.directory}/docs</outputDirectory>
  </configuration>
  <executions>
    <execution>
      <phase>package</phase>
      <goals>
        <goal>generate</goal>
      </goals>
    </execution>
  </executions>
</plugin>