Подсветка синтаксиса Django, вызывающая проблемы с экранированием символов - PullRequest
1 голос
/ 22 октября 2009

Я работал над своим собственным блогом на основе 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 (то есть не отображается). Я поиграл с использованием функции escape django в коде, извлеченном из тела моим фильтром, но я никак не могу понять, что это правильно. Я думаю, что мое понимание побега контента недостаточно полно. Я также попытался написать экранированную версию в теле поста (например, <), но он просто выходит в виде текста. </p>

Каков наилучший способ пометить HTML для отображения? Я все об этом ошибаюсь?

Спасибо.

1 Ответ

1 голос
/ 01 ноября 2009

Я наконец нашел время, чтобы понять это. Когда красивый суп загружает содержимое и содержит тег, этот тег отображается как подузел списка. Эта линия является виновником:

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

[0] обрезает другую часть кода, она не декодируется неправильно. Плохое выявление ошибок с моей стороны. Эта строка должна быть заменена на:

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

Здесь приведены уроки, чтобы вы знали, в чем проблема, и знаете, как работают ваши библиотеки.

...