Подсветка синтаксиса Django, вызывающая проблемы с экранированием символов
Вопрос
Я работал над своим собственным блогом на основе 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 escape в коде, извлеченном из body моим фильтром, но, похоже, у меня никогда не получается сделать это правильно.Я думаю, что мое понимание ускользающего контента просто недостаточно полное.Я также попытался написать экранированную версию в теле сообщения (например <), но это просто выводится в виде текста.
Каков наилучший способ пометить HTML-код для отображения?Неужели я все делаю неправильно?
Спасибо.
Решение
Наконец-то я нашел немного времени, чтобы разобраться в этом.Когда beautiful soup извлекает содержимое, содержащее тег, тег отображается в качестве вложенного узла списка.Эта строка является виновником:
new_content = pygments.highlight(code.contents[0], lexer, formatter)
[0] отсекает другую часть кода, она не декодируется неправильно.Плохое обнаружение ошибок с моей стороны.Эту строку необходимо заменить на:
new_content = pygments.highlight(code.decodeContents(), lexer, formatter)
Приведенные здесь уроки направлены на то, чтобы убедиться, что вы знаете, в чем проблема, и знаете, как работают ваши библиотеки.