Python 使用docutils从restructuredtext的代码指令中提取代码

Python 使用docutils从restructuredtext的代码指令中提取代码,python,restructuredtext,docutils,Python,Restructuredtext,Docutils,我想以一个重新构造的文本字符串从代码指令中逐字提取源代码 下面是我第一次尝试这样做,但我想知道是否有更好的方法(即更健壮、更通用或更直接的方法) 假设我将以下rst文本作为python中的字符串: s = ''' My title ======== Use this to square a number. .. code:: python def square(x): return x**2 and here is some javascript too. ..

我想以一个重新构造的文本字符串从代码指令中逐字提取源代码

下面是我第一次尝试这样做,但我想知道是否有更好的方法(即更健壮、更通用或更直接的方法)

假设我将以下rst文本作为python中的字符串:

s = '''

My title
========

Use this to square a number.

.. code:: python

   def square(x):
       return x**2

and here is some javascript too.

.. code:: javascript

    foo = function() {
        console.log('foo');
    }

'''
为了得到这两个代码块,我可以

from docutils.core import publish_doctree

doctree = publish_doctree(s)
source_code = [child.astext() for child in doctree.children 
if 'code' in child.attributes['classes']]
现在源代码是一个列表,其中只包含两个代码块中的逐字源代码。如有必要,我还可以使用child的attributes属性来查找代码类型


它确实起作用,但是有更好的方法吗

您的解决方案只会在文档的顶层找到代码块,如果类“code”用于其他元素(不太可能,但可能),则可能会返回误报。我还将检查元素/节点的类型,在其.tagname属性中指定

节点上有一个“遍历”方法(文档/doctree只是一个特殊的节点),它对文档树进行完整遍历。它将查看文档中的所有元素,并仅返回与用户指定条件匹配的元素(返回布尔值的函数)。以下是方法:

def is_code_block(node):
    return (node.tagname == 'literal_block'
            and 'code' in node.attributes['classes'])

code_blocks = doctree.traverse(condition=is_code_block)
source_code = [block.astext() for block in code_blocks]

这可以进一步简化为:

source_code = [block.astext() for block in doctree.traverse(nodes.literal_block)
               if 'code' in block.attributes['classes']]
如何(我可以?)修改代码块,然后将更改写回原始文件?