Jan 15

Syntax highlighting for Django using Pygments

The wonderful django-mingus includes a few separate syntax highlighters, including one from django-sugar. However, the pygmentize template filter only works on <code> blocks and tries to guess the language.

A better syntax would be to include the language in the class of the code block, like so:

<code class="python"> 
    import this 
    print [r for r in range(0,10,2)] 

You can use this template filter, which is adapted from the Pygments Rendering Template Filter at Django Snippets.

import re 
import pygments 
from django import template 
from pygments import lexers 
from pygments import formatters 
register = template.Library() 
regex = re.compile(r'<code(.*?)>(.*?)</code>', re.DOTALL) 
def pygmentize(value): 
    last_end = 0 
    to_return = '' 
    found = 0 
    for match_obj in regex.finditer(value): 
        code_class = match_obj.group(1) 
        code_string = match_obj.group(2) 
        if code_class.find('class'): 
            language = re.split(r'"|\'', code_class)[1] 
            lexer = lexers.get_lexer_by_name(language) 
                lexer = lexers.guess_lexer(str(code_string)) 
            except ValueError: 
                lexer = lexers.PythonLexer() 
        pygmented_string = pygments.highlight(code_string, lexer, formatters.HtmlFormatter()) 
        to_return = to_return + value[last_end:match_obj.start(0)] + pygmented_string 
        last_end = match_obj.end(2) 
        found = found + 1 
    to_return = to_return + value[last_end:] 
    return to_return 

This is a template filter, which can be applied like so:

{{ code|pygmentize }} You can read more about custom tempalte filters at the Django Project: Writing Custom Template Filters.


6:57 p.m. on January 15th, 2010
1 Kevin says...
Mingus is getting another codehighlighting option in .9 version - google code's prettify js solution. But yea, I need to update the django-sugar template tag (which is actually the ericflo templatetag you referred to) as it's not completely without error. I'll look into your code as the fix.
3:14 a.m. on March 3rd, 2010
2 Kévin Gomez says...
You should improve your filter so that it doesn't parse and highlight the code each time a user displays the page =)
12:38 p.m. on March 3rd, 2010
3 Samuel Clay says...
@Kévin, That caching logic should be applied to the template, not the pygmentize parser. You could cache the snippet around the code: {% cache %} {{ code|pygmentize }} {% endcache %}

Comments are closed.

That's all the comments I'm taking for this post. Email me your thoughts: blog+comments@ofbrooklyn.com.

Samuel Clay is the founder of NewsBlur, a trainable and social news reader for web, iOS, and Android. He is also the founder of Turn Touch, a startup building hardware automation devices for the home. He lives in San Francisco, CA, but misses Brooklyn terribly. In another life in New York, he worked at the New York Times on DocumentCloud, an open-source repository of primary source documents contributed by journalists.

Apart from NewsBlur, his latest projects are Hacker Smacker, a friend/foe system for Hacker News, and New York Field Guide, a photo-blog documenting New York City's 90 historic districts. You can read about his past and present projects at samuelclay.com.

Follow @samuelclay on Twitter.

You can email Samuel at samuel@ofbrooklyn.com. He loves receiving email from new people. Who doesn't?