使用docutils从重组文本中的代码指令中提取代码
extract code from code directive from restructuredtext using docutils
我想从重组文本字符串中的代码指令中逐字提取源代码。
接下来是我第一次尝试这样做,但我想知道是否有更好的(即更强大、更通用或更直接)的方法。
假设我在 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']]
现在 source_code 是一个仅包含来自两个代码块的逐字源代码的列表。如有必要,我还可以使用 child 的 attributes 属性来找出代码类型。
它完成了工作,但有更好的方法吗?
您的解决方案只会在文档的顶层找到代码块,如果 class "code" 用于其他元素(不太可能,但可能)。我还会检查 element/node 的类型,在其 .tagname 属性中指定。
节点上有一个 "traverse" 方法(document/doctree 只是一个特殊节点),它可以对文档树进行完整遍历。它将查看文档中的所有元素,并且 return 仅查看与用户指定条件匹配的元素(return 为布尔值的函数)。方法如下:
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']]
我想从重组文本字符串中的代码指令中逐字提取源代码。
接下来是我第一次尝试这样做,但我想知道是否有更好的(即更强大、更通用或更直接)的方法。
假设我在 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']]
现在 source_code 是一个仅包含来自两个代码块的逐字源代码的列表。如有必要,我还可以使用 child 的 attributes 属性来找出代码类型。
它完成了工作,但有更好的方法吗?
您的解决方案只会在文档的顶层找到代码块,如果 class "code" 用于其他元素(不太可能,但可能)。我还会检查 element/node 的类型,在其 .tagname 属性中指定。
节点上有一个 "traverse" 方法(document/doctree 只是一个特殊节点),它可以对文档树进行完整遍历。它将查看文档中的所有元素,并且 return 仅查看与用户指定条件匹配的元素(return 为布尔值的函数)。方法如下:
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']]