osa1 feed

Eski arşiv için düzenlemeler

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 value

Aslı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 s

Birkaç sorun var, birincisi, wordpressde yazdığım bu yazılar veritabanına hep ’ " gibi karakterler kaçılarak(ne desem bilemedim, &amp; gibi karakterlere dönüştürülerek işte) kaydedilmiş. Fakat codehilite kullandığımda onlar ekrana &amp; ş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>'