我一直在研究我自己的基于django的博客(就像每个人一样,我知道)来加强我的python,我想添加一些语法高亮会非常棒。我查看了那里的一些片段,并决定结合使用Beautiful Soup和Pygments编写我自己的语法突出显示模板过滤器。它看起来像这样:

from django import template
from BeautifulSoup import BeautifulSoup
import pygments
import pygments.lexers as lexers
import pygments.formatters as formatters

register = template.Library()

@register.filter(name='pygmentize')
def pygmentize(value):
    try:
        formatter = formatters.HtmlFormatter(style='trac')
        tree = BeautifulSoup(value)
        for code in tree.findAll('code'):
            if not code['class']: code['class'] = 'text'
            lexer = lexers.get_lexer_by_name(code['class'])
            new_content = pygments.highlight(code.contents[0], lexer, formatter)
            new_content += u"<style>%s</style>" % formatter.get_style_defs('.highlight')
            code.replaceWith ( "%s\n" % new_content )
        content = str(tree)
        return content
    except KeyError:
        return value

它会查找这样的代码块,并突出显示相关样式的广告:

<code class="python">
    print "Hello World"
</code>

这一切都正常,直到我包含的代码块中有一些html。现在,我知道我需要的所有html,所以我直接在其中写博客帖子,当渲染到模板时,只需将帖子正文标记为安全:

{{ post.body|pygmentize|safe }}

这种方法导致代码块中的任何html只是呈现为html(即,不显示)。我一直在玩我的过滤器在从身体中提取的代码上使用django转义函数,但我似乎永远无法正确使用它。我认为我对逃避内容的理解还不够完整。我也尝试在帖子体中编写转义版本(例如<!> lt;),但它只是作为文本出现。

将html标记为显示的最佳方法是什么?我错了吗?

感谢。

有帮助吗?

解决方案

我终于找到了一些时间来弄明白。当美丽的汤拉入内容并且它包含标签时,标签被列为列表的子节点。这条线是罪魁祸首:

new_content = pygments.highlight(code.contents[0], lexer, formatter)

[0]切断了代码的其他部分,它没有被错误地解码。我身上发现的臭虫很少。该行需要替换为:

new_content = pygments.highlight(code.decodeContents(), lexer, formatter)

这里的课程是确保您知道问题所在,并了解您的图书馆如何运作。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top