August 26, 2010 - Tagged as: python, django, tr.
Daha önceden burada Django’ya Markdown desteği eklenmesinden bahsetmiştim(Django’nun Markdown eklentisi olduğunu farkettim çok sonradan). Bu sefer de syntax renklendirme için Pygments desteği ekledim. Pygments’den önce syntaxhighlighter kullanıyordum benim amacım için biraz fazla gelişmiş ve kompleks kaçıyordu.
Öncelikle django’ya pygments desteği için 2 tane çok iyi kaynak var(1, 2), fakat bu kaynaklardaki yöntemlerden ilki, veritabanına gerekli html tagları eklenmiş bir şekilde yazıyor, dolayısıyla bir daha düzenlemek istediğinizde kodunuz okunmaz bir halde oluyor. Benim yapmak istediğim şey, daha önceden markdown için de yaptığım gibi, bir template filter oluşturup istediğim yerde kullanabilmek. Hem bu şekilde daha esnek olabilirim. İkinci yöntem ise, açıkçası ne yaptığını anlamaya çalışmadım, markdown ve pygments’i beraber uyguluyor. Bu da benim istediğim şey değil. Benim amacım, istediğim yere markdown, istediğim yere pygments, istediğim yere de ikisini beraber uygulamak.
Bunun için verdiğim ilk kaynaktaki kodu kullandım aslında. Tek farkı, sonucu veritabanına yazdırmak yerine, fonksiyonu template filter haline getirdim.
# pygmentsf.py
from django import template
from BeautifulSoup.BeautifulSoup import BeautifulSoup #saka gibi
from pygments import lexers, highlight, formatters
from django.template.defaultfilters import stringfilter
= template.Library()
register @register.filter
@stringfilter
def pygmentsf(html):
"String'i Pygments'den gecirir. BeautifulSoup ile pre taglarini ayristirir."
= BeautifulSoup(html)
soup = soup.findAll('pre')
preblocks for pre in preblocks:
if pre.has_key('class'):
try:
= ''.join([unicode(item) for item in pre.contents])
code = unescape_html(code)
code = pre['class']
preclass # syntaxhighlighter icin yazilmis kodlar icin
if preclass == 'brush: python' or preclass == 'brush; python':
= 'python'
preclass = lexers.get_lexer_by_name(preclass)
lexer = formatters.HtmlFormatter()
formatter = highlight(code, lexer, formatter)
code_hl
pre.replaceWith(BeautifulSoup(code_hl))except:
pass
return unicode(soup)
def unescape_html(html):
= html.replace('<', '<')
html = html.replace('>', '>')
html = html.replace('&', '&')
html return html
Ayrıca küçük bir düzenlemeyle daha önceden syntaxhighlighter için yazdığım yazılarla da uyumlu olmasını sağladım. Bu dosyayı uygulamanız altında eğer templatetags klasörüne attıktan sonra template dosyanızdan {% load pygmentsf %}
dedikten sonra, istediğiniz değişkene uygulayabilirsiniz. {{ blog.body|pygmentsf|safe|escape }}
gibi. Ya da isterseniz markdown yazımdaki template filter ile beraber {{ blog.body|markdown|pygmentsf|safe|escape }}
şeklinde kullanabilirsiniz.
Unutmadan, HTML’i ayrıştırmak için BeautifulSoup kullanılıyor. Mükemmel bir kütüphane.