Textile&Pygments实现代码高亮

环境:

Blog:django-articles
Web-framework:django

实现思路:

利用django的filter加上pygments实现代码高亮

为什么选择Textile:

markdown&ReStructured对代码块的语法不太符合我的胃口,在每段代码前加上tab或4个以上的空格符对我来说并不好用,虽然可以通过其他的方法来避免,但我依然觉得不是最佳的办法。特别是我之前是使用了JSPWiki的语法我觉得”{{{ code }}}“这种只需要考虑开始和结束的语法更加方便和简洁。

具体实现:

在templatetags中创建一个pygdecorator.py的文件,其中的代码如下所示:

import re
import pygments
import HTMLParser
from django import template
from pygments import lexers
from pygments import formatters
register = template.Library()
regex = re.compile(r'<code(.*?)>(.*?)</code>',re.DOTALL);
@register.filter
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)
        code_string = HTMLParser.HTMLParser().unescape(code_string)
        if code_class.find('class') > 0 :
            language = re.split(r'"|\'', code_class)[1]
            lexer = lexers.get_lexer_by_name(language)
        else:
            try:
                lexer = lexers.guess_lexer(str(code_string))
            except ValueError:
                lexer = lexers.TextLexer()
        py_string = pygments.highlight(code_string, lexer, formatters.HtmlFormatter())
        to_return = to_return + value[last_end:match_obj.start(0)] + py_string
        last_end = match_obj.end(2)
        found = found + 1
    to_return = to_return + value[last_end:]
    return to_return;

上面的代码做了两件事

  • 将代码块的代码反转义。因为在DB中存储的文章是已经转义过了的Html,如果直接拿这个内容进行pygments高亮转化会出现将转义符两次转义的问题,比如说你编辑了”&“在后台保存之后为”&amp;“如果直接进行高亮转化最终会得到”&amp;amp;“,那么在页面上就会显示”&amp;“,所以在进行高亮处理之前将代码反转义是非常必要的。
  • pygments高亮处理。高亮处理很简单拿到要转化的内容转化之后在将其结果返回,在这里利用了code块的css样式来确定需要转化代码的语言。 如何使用filter
    加载filter代码

{% load pygdecorator %}

使用filter

{{ article.render_content|pygmentize|safe }}

至于样式文件,则可以通过pygment工具生存css文件并添加到页面中。
bc. pygmentize -S default -f html > style.css

如果你想为代码添加LineNumber可以将highlight修改成如下内容:

py_string = pygments.highlight(code_string, lexer, formatters.HtmlFormatter(
noclasses=False, linenos=True))

注意:修改filter的内容是需要重启web应用的

Meta

Published: March 4, 2012 Author: ivan Comments:   Word Count: 264
Bookmark and Share

Next: 利用xl2tpd搭建l2tp VPN服务

Previous: :() { :|:& }; :

Tags

pygments python textile web

Comments powered by Disqus