Pygments and highlight_code for Django Python Syntax Highlighting


Pygments highlight_code Django Python Syntax Highlighting

Published on by nick

Tags: django, pygments, syntax-highlighting

A short time ago, I decided to implement syntax highlighting for this blog. I thought this should be a somewhat trivial task, but it ended up being trickier than I thought. Of course, I'm no Django or Python expert; I'm just starting out. Still, sometimes tasks like using third-party packages or plugins are easy and sometimes they are hard.

To start out, here are some useful links I found very valuable during this exploration:

Additionally, you will need to fulfill some dependencies on your system. I'm using Python 2.7, Django 1.5.1, Pygments 1.6 and Beautiful Soup 4. If you've made it this far in your Python and Django exploration, you should already know how to install these tools. So do so now, if you haven't already. Also, this article assumes you have a working Django project with at least one application with which you want to use syntax highlighting. The Django documentation is a great place to start to get moving in the right direction.

For Python syntax highlighting, I'm using the highlight_code script from Robert Tagg's blog:

# encoding: utf-8

"""
Desc: A filter to highlight code blocks in html with Pygments and BeautifulSoup.
Usage:  {% load highlight_code %}
        {{ text|formatCode|safe }}
"""

from bs4 import BeautifulSoup
from django import template
from django.template.defaultfilters import stringfilter

from pygments import highlight
from pygments.lexers import get_lexer_by_name
from pygments.formatters.html import HtmlFormatter

register = template.Library()


@register.filter
@stringfilter
def formatCode(html):

    soup = BeautifulSoup(unicode(html))
    preblocks = soup.findAll('pre')

    for pre in preblocks:

        if pre.has_key('class'):

            try:
                code = ''.join([unicode(item) for item in pre.contents])
                lexer = get_lexer_by_name(pre['class'][0])
                formatter = HtmlFormatter()
                code_hl = highlight(code, lexer, formatter)
                pre.contents = [BeautifulSoup(code_hl)]
                pre.name = 'code'

            except:
                raise

    return unicode(soup)

To use this script, you must do a few things. I found it confusing to get it working since I'm a beginner, so here I will add a bit more detail for others on the web looking for instructions on how to set this up.

First, you should read up on templatetags in the Django documentation. This concept took me a while to figure out. Once you are ready, in the Django application you want to add syntax highlighting to, in my case blog, add a directory called templatetags. In that directory, create a file called highlight_code.py with the contents of the above script inside.

Also, be sure to add an empty __init__.py file inside, as well, so Python knows this is a tag library. Some of the documentation out there doesn't mention this, maybe because the authors assume we know, or maybe because they forgot. At any rate, I'm reminding you know so you can get this app to work.

The next step is to set up your Django template so that you can get some syntax highlighting working for real. This article assumes you already have a working blog or a working application that you want to add syntax highlighting to. If not, please re-read the Django documentation and get your project and an application built.

The basic idea is to use the function in the highlight_code library, formatCode (which uses Beautiful Soup) to filter your code and spit it out looking good. The tags to do this in your Django template will look something like this:

{{ post.content|formatCode|safe }}

Remember to add the load mechanism as well, so Django knows to use this library:

{% load highlight_code %}

After this, you still need one final ingredient in order tog et your syntax highlighting to work: the CSS styles from the Pygments library. Robert Tagg provides a nice script to create these files for you and can be found here. Basically, from the command line, you will run something like this:

python pygments_styles.py pygments.css

This creates a pygments.css stylesheet with the specified styles. I actually went a step further and generated all of the styles from the Pygments library so I would have them on hand. You can download this here.

Comments

Comments powered by Disqus

 Blog Search

  Popular Tags

django, ubuntu, mod_wsgi, apache, authentication, python, tls, linux, forms, ssl, virtualenv, dell, uwsgi, bash, nginx, raid, customer-service, centurylink, ux, software-companies, rais, form, centos, password, certificates, tinymce, mdadm, dual-boot, file-server, virtualhost, gluster, IT, blog, get, networking, piplight, distributed-file-system, big companies, bitnami, cygwin, windows, samba, scripting, pygments, post, programming-language, ui, lampstack, outsourcing, isp, security, usabillity, provision, php, shared-hosting, netflix, git, flatpages, syntax-highlighting, virtualbox, hg, redirect, usability, prg, acls, change-password, complex, view tags...

 Questions/Comments?

Drop me a line... [email protected]
Follow me on Twitter... @nicorellius
Share on Facebook...