Plex 로 Wiki Page Parser 를 만들던. Plex 는 륭 readability lexical analyzer code 를 만들록 다.
Plex Example : Wiki Parser ¶
{{{~cpp
from Plex import *
import cStringIO, StringIO
class Parser:
def __init__(self, anInterWikiMap={}, aScriptName='', aMacros={}):
self.interWikiMap = anInterWikiMap
self.scriptName = aScriptName
self.macros = aMacros
def makeToStream(self, aText):
return cStringIO.StringIO(aText)
def parse(self, aText):
stream = self.makeToStream(aText)
return WikiParser(stream, self.interWikiMap,self.scriptName, self.macros).linkedLine()
class WikiParser(Scanner):
def repl_bold(self, aText):
self.bold = not self.bold
return ("<B>","</B>")[not self.bold]
def repl_italic(self, aText):
self.italic = not self.italic
return ("<I>","</I>")[not self.italic]
def repl_boldAndItalic(self, aText):
self.italic = not self.italic
return ("<I><B>","</B></I>")[not self.italic]
def repl_ruler(self, aText):
return "<HR>\n"
def repl_enter(self, aText):
return "<BR>\n"
def getLinkStr(self, anUrl):
return "<a href='%(url)s'>%(url)s</a>" % {'url':anUrl}
def getImageStr(self, anUrl):
return "<img src='%(url)s'>" % {'url':anUrl}
def isImage(self, aFileUrl):
imgExtensions = ("jpg", "png", "gif", "jpeg")
extension = aFileUrl[aFileUrl.rfind(".")+1:]
return extension in imgExtensions
def repl_url(self, aText):
if self.isImage(aText):
return self.getImageStr(aText)
return self.getLinkStr(aText)
def repl_interwiki(self, aText):
wikiMapName,pageName = self.text.split(":")
if self.interWikiMap.has_key(wikiMapName):
url = self.interWikiMap[wikiMapName]
imageTag = "<IMG SRC=../intertag.gif BORDER=0>"
formatText = "<A HREF=%(url)s>%(imageTag)s</A><A HREF=%(url)s%(pageName)s>%(pageName)s</A>"
else:
url = self.scriptName+"/InterMap"
imageTag = "<IMG SRC=../intertag.gif BORDER=1 ALT='Bad:%s'>"%(wikiMapName)
formatText="<A HREF=%(url)s>%(imageTag)s</A><A HREF=%(url)s>%(pageName)s</A>"
return formatText % {'url':url, 'pageName':pageName, 'imageTag':imageTag}
def repl_pagelink(self, aText):
if aText == "NonExistPage":
return "<a class=nonexist href='%(scriptName)s/%(pageName)s'>%(pageName)s</a>" % {'scriptName':self.scriptName, 'pageName':aText}
return "<a href='%(scriptName)s/%(pageName)s'>%(pageName)s</a>" \
% {'scriptName':self.scriptName, 'pageName':aText}
def repl_pagelinkUsingUnderbar(self, aText):
pageName = aText[:-1]
return "<a href='%(scriptName)s/%(pageName)s'>%(pageName)s</a>" % {'scriptName':self.scriptName, 'pageName':pageName}
def repl_macro(self, aText):
class NoneMacro:
def execute(self):
return ''
macroName = aText[2:-2]
macro=self.macros.get(macroName) or NoneMacro()
return macro.execute()
def repl_normalString(self, aText):
return aText
# for auto link
urlHeader = Str("http://")
stringUntilSpace = Rep(AnyBut(" "))
url = urlHeader + stringUntilSpace
upperCase = Range('AZ')
lowerCase = Range('az')
upperCaseSequence = Rep1(upperCase)
lowerCaseSequence = Rep1(lowerCase)
alphabetSequence = Rep1(upperCaseSequence | lowerCaseSequence)
interwikiDelim = Str(":")
stringUntilSpaceOrCommaOrRest = Rep1(AnyBut(" .,"))
interwiki = alphabetSequence + interwikiDelim + stringUntilSpaceOrCommaOrRest
pagelinkUsingCamelWord = upperCase + Rep(lowerCase) + Rep1(upperCaseSequence + lowerCaseSequence)
underbarForLink = Str('_')
pagelinkUsingUnderbar = Rep1(AnyBut('{\n_ ')) + underbarForLink
macro = Str('[[') + Rep1(AnyBut(']]')) + Str(']]')
space = Str(" ")
# for tag
bold = Str("'''")
italic = Str("''")
boldanditalic = bold + italic
htmllefttag = Str("<")
htmlrighttag = Str(">")
htmlandtag = Str("&")
enterCode = Str("\n")
ruler = Str("----") + enterCode
rawTextStart=Str("{{{~cpp ")
rawTextEnd=Str("} } }")
def repl_rawTextStart(self, aText):
self.begin("rawtext")
return "<PRE>"
def repl_rawTextEnd(self, aText):
self.begin("")
return "</PRE>"
lexicon = Lexicon([
(rawTextStart, repl_rawTextStart),
State('rawtext', [
(rawTextEnd, repl_rawTextEnd),
(AnyChar, repl_normalString),
]),
(italic, repl_italic),
(bold, repl_bold),
(boldanditalic, repl_boldAndItalic),
(htmllefttag, "<"),
(htmlrighttag, ">"),
(htmlandtag, "&"),
(url, repl_url),
(interwiki, repl_interwiki),
(pagelinkUsingCamelWord, repl_pagelink),
(ruler, repl_ruler),
(enterCode, repl_enter),
(pagelinkUsingUnderbar, repl_pagelinkUsingUnderbar),
(macro, repl_macro),
(AnyChar | space, repl_normalString),])
def __init__(self, aStream, anInterWikiMap={}, aScriptName='pyki.cgi', aMacroList={}):
Scanner.__init__(self, self.lexicon, aStream)
self.interWikiMap=anInterWikiMap
self.scriptName = aScriptName
self.macros = aMacroList
self.bold = False
self.italic = False
def linkedLine(self):
writer = StringIO.StringIO("")
while True:
token = self.read()
if token[0] is None:
break
writer.write(token[0])
return writer.getvalue()
}}}
=== 개발 ===
는 Wiki Tag 대 Tagger 래를 만들고, link 를 는 부 대 AutoLinker 를, Macro 는 MacroApplyer 를 각각 만들다. 그러다가 문가 겼는데, 그 그 력 겹는 부 겨나게 된 것다. , 를 든다면 Macro 경 CamelWord 로 기 는데, 는 AutoLinker apply 를 면 archor 그가 붙리는 것다.
결방법 : 두가데, 나는 AutoLinker Macro 관련 그 무고 나가는 방법고 나는 AutoLinker MacroApplyer를 는 방법다.
경 각각 Class Responsibility 들 다는 만, AutoLinker 래 각 던 가 더 다는 겠다.
경 래가 다는 단 만, lexical 들만 된다는 과 1 pass 로 같 루 다는 다.
결국 를 다. 근데, 그러면 Tagger AutoLinker 력 미 리가 겼는데, 바로 를 그대로 보는 그부다.
그러나......~ 로 는데 40 리다.; 로 본다면 Parser 두개 lexicon 는 구고, 그 보면 parser line 단 르기 부까 다. 매 때다 를 돌리면 기 때문 그 결과가 보 되다. Text Processing 러 부 대 TDD 는 말 다란 각 든다.
----
[Plex]








