Pregunta

He estado trabajando en mi propio blog basado en django (como todos, lo sé) para mejorar mi python, y pensé que agregar algo de resaltado de sintaxis sería bastante bueno. Observé algunos fragmentos y decidí combinar algunos y escribir mi propio filtro de plantilla de resaltado de sintaxis usando Beautiful Soup and Pygments. Se ve así:

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

Busca un bloque de código como este y resalta y publicita los estilos relevantes:

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

Todo esto funcionaba bien hasta que un bloque de código que estaba incluido tenía algo de HTML. Ahora, conozco todo el html que necesito, así que escribo las publicaciones de mi blog directamente en él y, cuando renderizo en la plantilla, marco el cuerpo de la publicación como seguro:

{{ post.body|pygmentize|safe }}

Este enfoque da como resultado que cualquier html en un bloque de código simplemente se represente como html (es decir, no se muestra). He estado jugando con el uso de la función de escape django en el código extraído del cuerpo por mi filtro, pero parece que nunca puedo hacerlo bien. Creo que mi comprensión del contenido que se escapa no es lo suficientemente completa. También he intentado escribir la versión escapada en el cuerpo de la publicación (por ejemplo, & Lt;), pero solo sale como texto.

¿Cuál es la mejor manera de marcar el html para su visualización? ¿Voy a hacer todo esto mal?

Gracias.

¿Fue útil?

Solución

Finalmente encontré algo de tiempo para resolverlo. Cuando una sopa hermosa tira del contenido y contiene una etiqueta, la etiqueta aparece como un subnodo de una lista. Esta línea es la culpable:

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

El [0] corta la otra parte del código, no se decodifica incorrectamente. Pobre error manchado de mi parte. Esa línea debe ser reemplazada por:

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

Las lecciones aquí son para asegurarse de saber cuál es el problema y saber cómo funcionan sus bibliotecas.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top