syntax colorizer - ponyatov/orth GitHub Wiki
Any programmers editor must have two minimal functions:
- syntax coloring
- language element completion
We will do syntax coloring using ORTH syntax parser written with PLY library.
## word name or undefined
t_ANY = r'[a-zA-Z0-9_]+'
## compiler words
t_COMPILER = r'[\:\;]{1}'
## lexer error callback
def t_error(t): raise SyntaxError(t)
## FORTH coloring lexer
lexer = lex.lex()
wx.stc
styling.
## get monospace font from system
font = wx.Font(14, wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD)
editor.StyleSetSpec(wx.stc.STC_STYLE_DEFAULT,
"face:%s,size:%d" % (font.GetFaceName(), font.GetPointSize()))
## default style
style_DEFAULT = wx.stc.STC_STYLE_DEFAULT
editor.StyleSetSpec(style_DEFAULT,'fore:#000000')
## comment
style_COMMENT = 1
editor.StyleSetSpec(style_COMMENT,'fore:#0000FF,normal')
## number
style_NUMBER = 2
editor.StyleSetSpec(style_NUMBER,'fore:#008800')
## colon definition
style_COMPILER = 3
editor.StyleSetSpec(style_COMPILER,'fore:#FF0000,bold')
## colorer callback
def onStyle(event):
# feed lexer
text = editor.GetValue() ; lexer.input(text)
# restart styles
# editor.StartStyling(0,0xFF) ; editor.SetStyling(len(text),style_DEFAULT)
# process source code via coloring lexer
while True:
token = lexer.token()
if not token: break
editor.StartStyling(token.lexpos,0xFF)
if token.type == 'COMMENT':
editor.SetStyling(len(token.value),style_COMMENT)
elif token.type in ['NUMBER','INT','HEX','BIN']:
editor.SetStyling(token.length,self.style_NUMBER)
elif token.type == 'COMPILER':
editor.SetStyling(len(token.value),style_COMPILER)
else:
editor.SetStyling(0,0)
editor.Bind(wx.stc.EVT_STC_STYLENEEDED,onStyle)
GUI Editor class
Variant of colorizer embedded intoclass Editor(wx.Frame):
def initEditor(self):
self.initColorizer()
## init colorizer styles & lexer
def initColorizer(self):
## get monospace font from system
self.font = wx.Font(14, wx.FONTFAMILY_MODERN,
wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD)
## load default editor style
self.editor.StyleSetSpec(wx.stc.STC_STYLE_DEFAULT,
"face:%s,size:%d" % (
self.font.GetFaceName(), self.font.GetPointSize()))
# configure styles
## default style
self.style_DEFAULT = wx.stc.STC_STYLE_DEFAULT
self.editor.StyleSetSpec(self.style_DEFAULT,'fore:#000000')
## comment
self.style_COMMENT = 1
self.editor.StyleSetSpec(self.style_COMMENT,'fore:#0000FF,normal')
## number
self.style_NUMBER = 2
self.editor.StyleSetSpec(self.style_NUMBER,'fore:#008800')
## colon definition
self.style_COMPILER = 3
self.editor.StyleSetSpec(self.style_COMPILER,'fore:#FF0000,bold')
# bind colorizer event
self.editor.Bind(wx.stc.EVT_STC_STYLENEEDED,self.onStyle)
## colorizer callback
def onStyle(self,event):
# feed lexer
text = self.editor.GetValue() ; lexer.input(text)
# restart styles
# editor.StartStyling(0,0xFF) ; editor.SetStyling(len(text),style_DEFAULT)
# process source code via coloring lexer
while True:
token = lexer.token()
if not token: break
self.editor.StartStyling(token.lexpos,0xFF)
if token.type == 'COMMENT':
self.editor.SetStyling(len(token.value),self.style_COMMENT)
elif token.type in ['NUMBER','INT','HEX','BIN']:
self.editor.SetStyling(token.length,self.style_NUMBER)
elif token.type == 'COMPILER':
self.editor.SetStyling(len(token.value),self.style_COMPILER)
else:
self.editor.SetStyling(0,0)