Creating a Jinja Pygments Extension for Code Highlighting

published on Jan. 26, 2011, 2:26 p.m.

If you use Jinja2 for a template engine, one of the things you might want to do is have some custom tags for highlighting code blocks. Since Python has a great library for this, Pygments, it's just a matter of gluing the two together via a Jinja extension.

The documentation for creating extensions is a bit sparse, so I'll go the important bits of the extension I created.

(If you just want the source code to use, you can stop here and pull it from its GitHub page.)

First thing to notice is that I've followed the example extension pretty closely.

First thing I changed was the tag name I wanted the extension to be invoked with, so something like this would work:

{% code 'python' %}
print 'Hello World'
{% endcode %}

You set the start tag for your extension by assigning it to the 'tags' property of the Extension class.

class PygmentsExtension(Extension):
tags = set(['code'])

Then in the parse method, we can specify the stop tag and pull out the content body in between the two tags.

body = parser.parse_statements(['name:endcode'], drop_needle=True)

The last bit, which is important, is in the _pygmentize function, which is called when the built up AST is walked to generate the output of the template.

content = caller()

You now have the content between the start and stop tags, and you can pass it through the Pygments lexer and formatter to generate the highlighted code markup. The processed markup is the return value of the _pygmentize function, and is added into the rendered markup for the template.

To integrate this extension into Jinja, you do this:

from pygments_extension import PygmentsExtension
jinja2_env = Environment(loader=FileSystemLoader(paths['templates']), extensions=[PygmentsExtension])

The above lines are from my environment.py in a Pylons project, but should be fairly similar to most other Python web frameworks.

You now have custom tags for highlighting source code in Jinja.