使用Python标记树处理器包装etree元素

使用Python标记树处理器包装etree元素,python,markdown,Python,Markdown,我正在尝试编写一个Python标记树处理器扩展,它将span标记封装在div标记中;所以如果我有(降价)- 如果我用索引值0运行它,我会得到以下结果- from markdown.extensions import Extension from markdown.treeprocessors import Treeprocessor import markdown class MyTreeProcessor(Treeprocessor): def run(self, doc):

我正在尝试编写一个Python标记树处理器扩展,它将
span
标记封装在
div
标记中;所以如果我有(降价)-

如果我用索引值
0运行它,我会得到以下结果-

from markdown.extensions import Extension

from markdown.treeprocessors import Treeprocessor

import markdown

class MyTreeProcessor(Treeprocessor):

    def run(self, doc):
        def iterate(parent):
            print ("%s %s :: %s" % (parent.tag, parent.attrib, parent.text))
            for child in parent.getchildren():
                iterate(child)
        iterate(doc)

class MyTreeExtension(Extension):

    def extendMarkdown(self,
                       md,
                       key="my_extension",
                       index=1e8):
        md.registerExtension(self)
        md.treeprocessors.register(MyTreeProcessor(md.parser),
                                   key, index)

if __name__=="__main__":
    md=markdown.Markdown(extensions=[MyTreeExtension()])
    md.convert("before <span>hello world</span> after")
div {} :: None
p {} :: before <span>hello world</span> after
div {} :: 

p {} :: before wzxhzdk:0hello worldwzxhzdk:1 after
这两个都不是我想要的-在第一种情况下,
span
没有被处理,在第二种情况下,它以某种奇怪的格式被处理:-/

查找markdown扩展文档对于看似简单的任务来说非常复杂-有人能确认我在这里使用Treeprocessor(或没有)是正确的树吗?如果是这样,我在无法将这个
span
解析为
etree.Element
时做错了什么


TIA

您可能不想在这里使用树处理器,因为您正在处理原始HTML

Python Markdown通过将标记转换为
etree
对象来解析标记。但是,它不解析HTML(至少不完全解析),并且
etree
对象不能保存原始HTML字符串。当然,它们可以保存它们,但是当
etree
对象呈现为HTML字符串时,它们将被转义。因此,原始HTML被标识并替换为占位符(
wzxhzdk:0
)。将
etree
对象呈现为HTML字符串后,后处理器将查找所有占位符,并将它们替换为原始HTML,原始HTML是使用占位符作为键存储的

两个索引之间行为不同的原因是,其中一个在运行inlinepatterns之前运行(第一个treeprocessor实际上是所有inlinepatterns的包装器),另一个在之后运行,但在占位符被交换回之前。当然,由于占位符被后处理器交换回,您无法从TreeProcessor访问该状态

总之:

  • 块级原始HTML由预处理器处理,并且永远无法从treeprocessor获得
  • 内联原始HTML由内联模式处理,因此内联原始HTML将在
    inlineProcessor
    treeprocessor运行之前不被处理,但在运行之后treeprocessor将不可用
  • 一个可能的解决方案是使用inlinepattern。但是,您需要自己解析HTML标记

    此外,所需的输出不是有效的HTML。请注意,hello world之后的
    将被包装在
    标记中,并且
    标记不能包含任何其他块级元素,包括
    标记。当然,没有什么强迫您不将
    标记包装在
    标记中,但是浏览器永远不会以这种方式解释HTML。根据HTML规范,块级标记会自动关闭
    标记。因此,浏览器(可能)会这样解释您的输出:

    之前

    之后的hello world

    请注意,
    之后没有
    包装
    。是的,结束标记将出现,但如果没有开始标记(紧接着结束
    ,浏览器将不知道它是否启动,并且您将得到一个空的
    窗口结束标记的位置


    现在,如果您对所有这些都满意,那么为什么不在降价中首先使用
    。或者
    只是问题中实际标记的占位符?如果是这样,它们是内联的还是块级的可能会改变答案。

    好奇为什么您使用
    1e8
    的优先级?如果我不是mistaken,这等于
    100000000.0
    。然而,只有两个内置的树处理器,优先级分别为
    10
    20
    。你可以轻松地使用高于
    20
    的任何数字。不需要使用1000亿。这是一个非常好的答案,谢谢。我只是使用
    作为代理事实上,我正在尝试修复Twitter嵌入的边缘,它使用
    啊,这更有意义。注意
    是一个块级标记,所以只要它本身在一行上,它的行为就不同于
    标记。
    div {} :: None
    p {} :: before <span>hello world</span> after
    
    div {} :: 
    
    p {} :: before wzxhzdk:0hello worldwzxhzdk:1 after