本文共 6117 字,大约阅读时间需要 20 分钟。
由于CSDN这个博客不知道怎么搞,语法高亮,好像又不能够支持了,同时最近也学习正则,所以也就顺便写下了这个代码,练练手,同时也熟悉一下 Python,由于对正则还不熟悉,所以写的有点冗余,嘿嘿,有兴趣的参考参考修补修补,如有已经做好的,希望也能发给俺参考参考!
刚刚搞定,本博客中有几篇文章也用本代码转了一些Delphi代码的语法高亮格式过来。废话不多说了,
全部代码如下:
# -*- coding: gbk -*-
import reclass PaserDelphi(): """Delphi代码生成HTML代码""" #关键字定义 DelphiKeyWords = 'abs addr and ansichar ansistring array as asm begin boolean byte cardinal case char class comp const constructor currency destructor div do double downto else end except exports extended false file finalization finally for function goto if implementation in inherited int64 initialization integer interface is label library longint longword mod nil not object of on or packed pansichar pansistring pchar pcurrency pdatetime pextended pint64 pointer private procedure program property pshortstring pstring pvariant pwidechar pwidestring protected public published raise real real48 record repeat set shl shortint shortstring shr single smallint string then threadvar to true try type unit until uses val var varirnt while widechar widestring with word write writeln xor absolute abstract assembler automated cdecl contains default dispid dynamic export external far forward implements index message name near nodefault overload override package pascal readonly register reintroduce requires resident safecall stdcall stored virtual writeonly' #正则 DelphiKeyWordList = r'/b'.join(['',DelphiKeyWords.replace(' ',r'/b|/b')]).join(['',r'/b']) tempstr1 = r"'[/s/w]*".join(['',DelphiKeyWords.replace(' ',r"|'[/s/w]*")]) tempstr2 = r'/{[/s/w]*'.join(['',DelphiKeyWords.replace(' ',r'|/{[/s/w]*')]) tempstr3 = r"/(/*[/s/w]*".join(['',DelphiKeyWords.replace(' ',r"|/(/*[/s/w]*")]) tempstr4 = r"//[//s/w]*".join(['',DelphiKeyWords.replace(' ',r"|//[//s/w]*")]) ParserList = {'CodeStart': {'begin': """<style type="text/css">.textBackGround {background-color: #F0F5FD;}</style><table cellspacing=0 cellpadding=0 width="100%" height=20 border=1 align="center" bordercolor="#9DA7AC" bgcolor="#E3DFE3"><font color=#0000A0 face="Courier New"><b>DelphiCode: </b></font><tr><Td> <div class="textBackGround" style="font-family:Courier New;font-size:10pt;"><pre>""", 'end': '</pre></div></td></Tr></table>'}, 'KeyWords':{'begin': "<font color = blue><b>", 'end': '</b></font>'}, 'ToCompile':{'begin': "<font color=#008080>",'end':"</font>"}, 'Comit':{'begin':"<font color=green><i>", 'end':'</i></font>'}, 'String':{'begin':"<font color=#FF44A2>", 'end':'</font>'}, 'Num':{'begin':'<font color=#FF00FF>','end':'</font>'}, 'Asm':{'begin':'<font color=#AF8000>','end':'</font>'}, 'Symbol':{'begin':'<font color=#00572C','end':'</font>'} } def __init__(self): self.Comit = 0 self.Asm = 0 self.IsCompileComit = False #判断字符串CodeLine是否有符合正则列表ReList的字符串 def __ifCodeInReList__(self,ReList,codeLine): tempstr = '|'.join(ReList) return re.search(tempstr,codeLine,re.IGNORECASE) def __Parser__(self,CodeLine): MatchState = '' def convert(matobj): if MatchState == '': return '%s%s%s'%(self.ParserList[CodeStyle]['begin'],matobj.group(),self.ParserList[CodeStyle]['end']) elif MatchState == 'begin': return '%s%s'%(self.ParserList[CodeStyle]['begin'],matobj.group()) else: return '%s%s'%(matobj.group(),self.ParserList[CodeStyle]['end']) StrMatchObj = re.search("'.*'",CodeLine,re.IGNORECASE) if StrMatchObj: CodeStyle = 'String' MatchState = '' #字符串是否在注释中begin,不在注释中则替换生成HTML代码 if not self.__ifCodeInReList__([r"/{[/s/w]*'",r"/(/*[/s/w]*'",r"//[//s/w]*'"],CodeLine): CodeLine = re.sub("'.*'",convert,CodeLine) p = re.compile(self.DelphiKeyWordList,re.IGNORECASE) KeyMatchobj = p.search(CodeLine) if KeyMatchobj: CodeStyle = 'KeyWords' #判断关键字是否在字符串中#在判断关键字是否在注释中 if (self.Comit == 0): if not self.__ifCodeInReList__([self.tempstr1,self.tempstr2,self.tempstr3,self.tempstr4],CodeLine): #然后在判断关键字是否为汇编指令 if self.__ifCodeInReList__([r'/basm/b'],CodeLine): self.Asm += 1 CodeLine = p.sub(convert,CodeLine).join(['',self.ParserList['Asm']['begin']]) if self.Asm == 0: CodeLine = p.sub(convert,CodeLine) elif self.__ifCodeInReList__(['end'],CodeLine): if self.Asm > 0: self.Asm -= 1 CodeLine = p.sub(convert,CodeLine).join(['',self.ParserList['Asm']['end']]) CommitMatchobj = re.search(r'[/s/*]*//.*',CodeLine,re.IGNORECASE) BegMatchObj = CommitMatchobj CodeStyle = 'Comit' if CommitMatchobj: CodeLine = re.sub(r'[/s/*]*//.*',convert,CodeLine) else: CommitMatchobj = re.search(r'/s*/(/*|/{[^/$].*',CodeLine,re.IGNORECASE) if CommitMatchobj: if self.Comit == 0:#为0则表示前面没有注释,然后进行下面的注释 MatchState = 'begin' CodeLine = re.sub(r'/s*/(/*|/{[^/$].*',convert,CodeLine) self.IsCompileComit = False self.Comit += 1 else: CommitMatchobj = re.search(r'/{/$.*',CodeLine,re.IGNORECASE) if CommitMatchobj: self.IsCompileComit = True CodeStyle = 'ToCompile' MatchState = 'begin' CodeLine = re.sub(r'/{/$',convert,CodeLine) self.Comit += 1 print CodeLine CommitMatchobj = re.search(r'/*/)|/}',CodeLine,re.IGNORECASE) MatchState = 'end' if CommitMatchobj: self.Comit -= 1 CodeLine = re.sub(r'/*/)|/}',convert,CodeLine) print CodeLine NumMatchObj = re.search(r'/b[/d]+/.?[/d]*/b',CodeLine) HtmlBjObj = re.search(r'<.*>',CodeLine,re.IGNORECASE) if NumMatchObj and (self.Comit == 0):#数字匹配 CodeStyle = 'Num' MatchState = '' if HtmlBjObj and (HtmlBjObj.start()>NumMatchObj.start()): if (not BegMatchObj) and (not StrMatchObj): CodeLine = re.sub(r'/b[/d]+/.?[/d]*/b',convert,CodeLine) else: if self.Comit == 0: if BegMatchObj and (BegMatchObj.start() > NumMatchObj.start()):#不在注释中 CodeLine = re.sub(r'/b[/d]+/.?[/d]*/b',convert,CodeLine) elif StrMatchObj and (StrMatchObj.start() > NumMatchObj.start()):#不在注释中 CodeLine = re.sub(r'/b[/d]+/.?[/d]*/b',convert,CodeLine) return CodeLine def getHtml(self,code): self.codeList = code.split('/n')#分割成列表 self.Comit = 0 self.Asm = 0 self.IsCompileComit = False s = '' for i in range(len(self.codeList)): s = '%s/n%s'%(s,self.__Parser__(self.codeList[i])) s = '%s%s%s'%(self.ParserList['CodeStart']['begin'],s,self.ParserList['CodeStart']['end']) return sdef main(): s1="""{$R *.dfm}""" mm = DelphiPaser.PaserDelphi() print mm.getHtml(s1)if __name__=='__main__' : main()
如果需要界面的,俺也做了个简单的界面,是对着wxPython边弄边写的一个界面!所以丑陋,而且也就提供了一个转换功能而已界面如下:
转换后的结构如图: