有没有模块可以将restructuredtext解析成树模型?
docutils 或 sphinx 可以这样做吗?
我想扩展 Gareth Latty 的回答。 “您可能想要的是
docutils.parsers.rst
处的解析器”是一个很好的答案起点,但下一步是什么?即:
如何在 python 中解析重组文本?
以下是 Python 3.6 和 docutils 0.14 的确切答案:
import docutils.nodes
import docutils.parsers.rst
import docutils.utils
import docutils.frontend
def parse_rst(text: str) -> docutils.nodes.document:
parser = docutils.parsers.rst.Parser()
components = (docutils.parsers.rst.Parser,)
settings = docutils.frontend.OptionParser(components=components).get_default_values()
document = docutils.utils.new_document('<rst-doc>', settings=settings)
parser.parse(text, document)
return document
并且可以使用例如下面的方法处理生成的文档,它将打印文档中的所有引用:
class MyVisitor(docutils.nodes.NodeVisitor):
def visit_reference(self, node: docutils.nodes.reference) -> None:
"""Called for "reference" nodes."""
print(node)
def unknown_visit(self, node: docutils.nodes.Node) -> None:
"""Called for all other node types."""
pass
运行方法如下:
doc = parse_rst('spam spam lovely spam')
visitor = MyVisitor(doc)
doc.walk(visitor)
Docutils 确实包含执行此操作的工具。
您可能想要的是
docutils.parsers.rst
处的解析器
有关所涉及内容的详细信息,请参阅本页。
docutils/examples.py
也有一些示例 - 特别是查看 internals()
函数,这可能很有趣。
根据 Gareth Latty 和 mbdevpl 的回答,此处更新了较新版本的 docutils。
从docutils 0.18(2021-10-26)开始,
docutils.frontend.OptionParser
已经被弃用(git mirror commit,upstream SVN HISTORY.txt),会打印如下警告(source):
DeprecationWarning: The frontend.OptionParser class will be replaced by a subclass of argparse.ArgumentParser in Docutils 0.21 or later.
可以使用
docutils.frontend.get_default_settings()
函数代替,但它只在docutils 0.18中添加,所以要兼容所有版本而不会收到警告,您可以使用:
import docutils.parsers.rst
import docutils.utils
import docutils.frontend
def parse_rst(text: str) -> docutils.nodes.document:
parser = docutils.parsers.rst.Parser()
if hasattr(docutils.frontend, 'get_default_settings'):
# docutils >= 0.18
settings = docutils.frontend.get_default_settings(docutils.parsers.rst.Parser)
else:
# docutils < 0.18
settings = docutils.frontend.OptionParser(components=(docutils.parsers.rst.Parser,)).get_default_values()
document = docutils.utils.new_document('<rst-doc>', settings=settings)
parser.parse(text, document)
return document
其余代码保持不变,可以在 mbdevpl 的答案中找到。