1

私は自分のdjangoベースのブログ(みんなのように)でPythonを研ぎ澄ましてきましたが、構文のハイライトを追加するとかなり素晴らしいと思いました。私はそこにあるスニペットのいくつかを見て、いくつかを組み合わせて、BeautifulSoupと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エスケープ関数を使用して遊んでいますが、それを正しく理解することはできません。コンテンツのエスケープについての私の理解は十分ではないと思います。エスケープされたバージョンを投稿の本文(例:<)に書き込んでみましたが、テキストとして出力されます。

表示用にhtmlをマークする最良の方法は何ですか?私はこれについてすべて間違っていますか?

ありがとう。

4

1 に答える 1

1

私はついにそれを理解するための時間を見つけました。美しいスープがコンテンツを取り込み、タグが含まれている場合、タグはリストのサブノードとしてリストされます。この行が原因です:

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

[0]はコードの他の部分を切り取り、正しくデコードされていません。私の側の悪いバグ発見。その行は次のように置き換える必要があります。

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

ここでのレッスンは、問題が何であるかを確実に理解し、ライブラリがどのように機能するかを理解することです。

于 2009-11-01T18:07:06.553 に答える