首页 > 解决方案 > 如何使用 Python 的 docutils 解析像树一样的 RST 文档?

问题描述

从这个站点上的不同答案,我编写/复制了以下代码来解析 RST 文档。

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

def myparse():
    s = ''
    with open('test.rst') as f:
        s = f.read()
    doc = parse_rst(s)
    visitor = MyVisitor(doc)
    return doc, visitor

此代码有效并且能够解析 RST 文档。如果我有如下的 RST 文件

heading1
========
and some
multi line text

subheading1
-----------

afjafjafjfjajf

heading2
========
other text

我希望得到一个树状结构,其中主标题在一个级别上,每个都是一个节点,我可以用它来递归树到它的子文本和子标题。相反,我得到了一个完全线性的结构,其中子标题似乎与更高级别的标题处于同一级别。这是 doc.ids 的输出

>>> doc, vis = myparse()
>>> doc.ids
{'heading1': <section "heading1": <title...><paragraph...><section "subheading1"...>>,
'subheading1': <section "subheading1": <title...><paragraph...>>,
'heading2': <section "heading2": <title...><paragraph...>>}

所以,我有点茫然如何以编程方式迭代顶级标题。docutils 的正确方法是什么(如果有的话)像树一样导航文档,以便我可以轻松确定哪些子标题属于适当的标题,并避免在尝试查找我的主要顶级标题时迭代子标题?

标签: pythonpython-3.xdocutils

解决方案


推荐阅读