October 25, 2010 - Tagged as: python, tr.
Eski wordpress arşivimi daha okunabilir bir hale getirmek için küçük bir parser yazma niyetindeydim ama beceremedim. Şimdilik aşağıdaki template filter ile işimi görüyorum:
def wpcodegen(value):
value = value.replace('[code lang="python"]', '<pre class="wp">')
value = value.replace('[/code]', '</pre>')
value = value.replace('[coolcode]', '<pre class="wp">')
value = value.replace('[/coolcode]', '</pre>')
return valueAslında syntax renklendirme için uğraşıyordum. Python kodlarını markdown ve codehilite ile renklendirecektim. Bunun için yazıyı parçalara ayırık, [code] ... [/code] arasını gerekli fonksiyona gönderip(fonksiyona göndermeden önce markdown’a göre biçimlendirmem gerekiyordu, dolayısıyla [code] ... [/code] arasını önce satır satır parçalayıp gerekli biçimlendirmeleri yapmam gerekri) çıktıyı o parçayı yazının neresinden söktüysem oraya yerleştirecektim. Kodlamaya başladıktan sonra biraz daha esnek bir yapı için fantastik işlere giriştim. Son hali duruma göre güzel çalışabiliyor aslında.
class Parser:
def __init__(self, metin, baslangic, bitis):
self.metin = metin
self.devam = metin
self.pos = [[0, 0]]
self.baslangic = baslangic
self.bitis = bitis
self.__setPos()
def __setPos(self, index = 0):
try:
bas = self.devam.index(self.baslangic) + \
len(self.baslangic) + index
son = self.devam.index(self.bitis) + index
except ValueError:
return self.pos
self.pos.append([bas, son])
self.devam = self.devam[son+len(self.bitis):]
return self.__setPos(index = son+len(self.bitis))
def codehilite(self, lang=""):
if self.pos == [[0, 0]]:
return self.metin
s = ''
for i in range(len(self.pos)):
if i == range(len(self.pos))[-1]:
break
i += 1
kod = ''
basladi = False
s += self.metin[self.pos[i-1][^1]: self.pos[i][^0]len(self.baslangic)]
for satir in self.metin[self.pos[i][^0]: self.pos[i][^1].split('\n'):
if not basladi:
if not lang == "":
kod += '\t:::%s\n' % lang
basladi = True
kod += '\t%s\n' % satir
s += Markdown(kod, ['codehilite'])
return sBirkaç sorun var, birincisi, wordpressde yazdığım bu yazılar veritabanına hep ’ " gibi karakterler kaçılarak(ne desem bilemedim, & gibi karakterlere dönüştürülerek işte) kaydedilmiş. Fakat codehilite kullandığımda onlar ekrana & şeklinde yazdırılıyor. Onun dışında, iki ayrı tagı ayrıştırmak istiyorsanız 2 ayrı parser oluşturmalı ve aynı işlemi iki parser ile de uygulamalısınız. Hoş olmadı.
Kullanımı şu şekilde olacaktı:
>>> ornekMetin = u'Buraya [test]bazı etiketler [/test]gelecek'
>>> parser = Parser(ornekMetin, '[test]', '[/test]')
>>> parser.codehilite()
u'Buraya <pre><code>baz\xc4\xb1 etiketler\n</code></pre>'