Подсветка синтаксиса Django, вызывающая проблемы с экранированием символов

StackOverflow https://stackoverflow.com/questions/1607979

Вопрос

Я работал над своим собственным блогом на основе 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)

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top