How to create python syntax highlighting function for Python Tkinter Text Widget- Python MagicStick Text Editor - Last Part

Namaste Friends,




For Programmers, Syntax highlighting Feature is plus point in writing programming code's fastly. Syntax highlighting Feature In text Editor, Helps Programmer To Write Programming Syntax Correctly By highlighting programming syntax, comments, functions, class in various Colours. So, Today In this post, i am going to show you how to make complete set of functions that can highlight programming syntax, comments, strings, class, functions and other things in various colours.


Friends, This Is our last Tutorial Of Python MagicStick Project But,  if you are a new visitor, Then I will suggest you to read our tutorials number wise. because in these tutorial series i am showing how to use python tkinter module to create a real life application.

Links For Tutorials

MagicStick Text Editor Part 3
MagicStick Text Editor Part 4
MagicStick Text Editor Part 5
MagicStick Text Editor Part 6
MagicStick Text Editor Part 7
MagicStick Text Editor Part 8
MagicStick Text Editor Part 9
Or You Can Also Download Our Example Codes Of Python MagicStick Text Editor Project For Understanding This Project More Clearly.

Check Here Our Github Repo


Now, let's focus to our main topic.


For this purpose we will use re module. The re module is one of the best module in python for finding any text data in fastest way. This Module provide us special abilities and features for finding any specified data, line, word or content from raw data. So, with the help of re module, we will identity our programming syntax, function and other things. 



If you don't know about re module.

And To make this script easy to understand we will create a separate empty script "ColorLight.py" in "magicsticklibs/" folder and write our codes  in it. Friends, here for tutorial purpose, i am writing this function for highlighting python related syntax only, but with the help of re tutorial, you can modify these code's according to your needs.


So, let's do some practical coding's.

1. ColorLight.py



  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
##
##
## ################################################
## ###### Please Don't Remove Author Name #########
## ############# Thanks ###########################
## ################################################
##
##
__author__='''

######################################################
                By S.S.B Group                          
######################################################

    Suraj Singh
    Admin
    S.S.B Group
    surajsinghbisht054@gmail.com
    http://bitforestinfo.blogspot.com/

    Note: We Feel Proud To Be Indian
######################################################
'''

import __builtin__
import re
import keyword
from Graphics import Tkinter


def any(name, alternates):
    "Return a named group pattern matching list of alternates."
    return "(?P<%s>" % name + "|".join(alternates) + ")"


def ty():
    kw = r"\b" + any("KEYWORD", keyword.kwlist) + r"\b"
    builtinlist = [str(name) for name in dir(__builtin__)
                                        if not name.startswith('_')]
    builtinlist.remove('print')
    builtin = r"([^.'\"\\#]\b|^)" + any("BUILTIN", builtinlist) + r"\b"
    comment = any("COMMENT", [r"#[^\n]*"])
    stringprefix = r"(\br|u|ur|R|U|UR|Ur|uR|b|B|br|Br|bR|BR)?"
    sqstring = stringprefix + r"'[^'\\\n]*(\\.[^'\\\n]*)*'?"
    dqstring = stringprefix + r'"[^"\\\n]*(\\.[^"\\\n]*)*"?'
    sq3string = stringprefix + r"'''[^'\\]*((\\.|'(?!''))[^'\\]*)*(''')?"
    dq3string = stringprefix + r'"""[^"\\]*((\\.|"(?!""))[^"\\]*)*(""")?'
    string = any("STRING", [sq3string, dq3string, sqstring, dqstring])
    return kw + "|" + builtin + "|" + comment + "|" + string +\
           "|" + any("SYNC", [r"\n"])

def _coordinate(start,end,string):
    srow=string[:start].count('\n')+1 # starting row
    scolsplitlines=string[:start].split('\n')
    if len(scolsplitlines)!=0:
        scolsplitlines=scolsplitlines[len(scolsplitlines)-1]
    scol=len(scolsplitlines)# Ending Column
    lrow=string[:end+1].count('\n')+1
    lcolsplitlines=string[:end].split('\n')
    if len(lcolsplitlines)!=0:
        lcolsplitlines=lcolsplitlines[len(lcolsplitlines)-1]
    lcol=len(lcolsplitlines)+1# Ending Column
    return '{}.{}'.format(srow, scol),'{}.{}'.format(lrow, lcol)#, (lrow, lcol)

def coordinate(pattern, string,txt):
    line=string.splitlines()
    start=string.find(pattern)  # Here Pattern Word Start
    end=start+len(pattern) # Here Pattern word End
    srow=string[:start].count('\n')+1 # starting row
    scolsplitlines=string[:start].split('\n')
    if len(scolsplitlines)!=0:
        scolsplitlines=scolsplitlines[len(scolsplitlines)-1]
    scol=len(scolsplitlines)# Ending Column
    lrow=string[:end+1].count('\n')+1
    lcolsplitlines=string[:end].split('\n')
    if len(lcolsplitlines)!=0:
        lcolsplitlines=lcolsplitlines[len(lcolsplitlines)-1]
    lcol=len(lcolsplitlines)# Ending Column
    return '{}.{}'.format(srow, scol),'{}.{}'.format(lrow, lcol)#, (lrow, lcol)

def check(k={}):
    if k['COMMENT']!=None:
     return 'comment','red'
    elif k['BUILTIN']!=None:
     return 'builtin','VioletRed'
    elif k['STRING']!=None:
     return 'string','green'
    elif k['KEYWORD']!=None:
     return 'keyword','orange'
    else:
     return 'ss','NILL'

txtfilter=re.compile(ty(),re.S)


class ColorLight:
    def __init__(self, txtbox=None):
        self.txt=txtbox
        self.txt.bind("<Any-KeyPress>", self.trigger)

    def binding_functions_configuration(self):
        self.txt.storeobj['ColorLight']=self.trigger
        return

    def trigger(self, event=None):
        val=self.txt.get('1.0','end')
        if len(val)==1:
            return
        for i in ['comment','builtin','string','keyword']:
            self.txt.tag_remove(i,'1.0','end')
        for i in txtfilter.finditer(val):
            start=i.start()
            end=i.end()-1
            #print start,end
            tagtype,color=check(k=i.groupdict())
            if color!='NILL':
                ind1,ind2=_coordinate(start,end,val)
                #print ind1, ind2
                self.txt.tag_add(tagtype,ind1, ind2)
                self.txt.tag_config(tagtype,foreground=color)
                #Tkinter.Text.tag_configure
#        for i in idprog.finditer(val):
#            start=i.start()
#            end=i.end()-1
#            ind1,ind2=_coordinate(start,end,val)
#            self.txt.tag_add('BLUE',ind1, ind2)
#            self.txt.tag_config("BLUE",foreground='grey')
#            #Tkinter.Text.tag_configure

if __name__ == '__main__':
    root=Tkinter.Tk()
    txt=Tkinter.Text(root)
    txt.pack(expand='yes')
    txt.storeobj={}
    store=ColorLight(txtbox=txt)
    Tkinter.Button(root, text='Click me', command=lambda:store.trigger()).pack()
    root.mainloop()

To Run These Script Codes alone, Just Change line 28 from

"from Graphics import Tkinter"

To

"import Tkinter"  

Or

To Run This Codes as MagicStick Script. Don't Do Any Changes in this codes.

Now, let's join this script in MagicStick Text Editor Project ( Follow Below Steps only, when you have not Connected this script with MagicScript Main Stream).

To Connect This Script With MagicStick project, we need to do only two steps.


1. first, Place This Script In Our "MagicStick/magicsticklibs" Project Directory.


2. Add Function Of This Script in Our "ConfigSettings.py".


Let me explain you these steps in more details.



Step 1.
 Place "ColorLight.py" In Our "MagicStick/magicsticklibs" Project Directory.


Then Our MagicStick Project Directory Structure will look like this.



MagicStick_Editor_Part_12
 |
 |---> About.txt  
 |
 |---> magicsticklibs
 |  |
 |  |---> __init__.py
 |  |     
 |  |---> Main.py
 |  |            
 |  |---> TextPad.py
 |  |
 |  |---> Graphics.py
 |  |
 |  |---> ConfigSettings.py 
 |  |
 |  |---> ScrollBar.py
 |  |
 |  |---> LineNumber.py
 |  |
 |  |---> StationeryFunctions.py
 |  |
 |  |---> PopupMenu.py
 |  |
 |  |---> FindAndReplace.py
 |  |
 |  |---> FileHandler.py
 |  |
 |  |---> FontChooser.py
 |  |
 |  |---> ColorLight.py
 |  
 |  
 |
 |---> main.py


Step 2.
          Add "ColorLight.py" Function in Our "ConfigSettings.py" because in this project, "ConfigSettings.py" is responsible for joining libs in main stream.


ConfigSettings.py Modified Codes



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
##
##
## ################################################
## ###### Please Don't Remove Author Name #########
## ############# Thanks ###########################
## ################################################
##
##
__author__='''

######################################################
                By S.S.B Group                          
######################################################

    Suraj Singh
    Admin
    S.S.B Group
    surajsinghbisht054@gmail.com
    http://bitforestinfo.blogspot.com/

    Note: We Feel Proud To Be Indian
######################################################
'''

from LineNumber import LineMain
from ScrollBar import Scrollbar
from StationeryFunctions import StationeryFunctions
from PopupMenu import Popup
from FIndAndReplace import FindReplaceFunctions
from FileHandler import FileHandler
from FontChooser import FontChooser
from Settings import Configuration
from ColorLight import ColorLight
from MenuBarHandler import MenuBar

class Connect:
 def __init__(self, pad):
  self.pad = pad
  self.modules_connections()


 def modules_connections(self):
  LineMain(self.pad)
  Scrollbar(self.pad)
  StationeryFunctions(self.pad)
  Popup(self.pad)
  FindReplaceFunctions(self.pad)
  FileHandler(self.pad)
  FontChooser(self.pad)
  Configuration(self.pad)
  ColorLight(self.pad)
  MenuBar(self.pad)
  return


                   Boom! Our ColorLight.py script is now ready to use and also, this script is now connected with MagicStick Project Main stream. To run this script in main stream of project. just run "main.py" script or you can also run this script alone and parallel without touching project main stream just run "ColorLight.py".


This Tutorial Ends Here,


In My Next Tutorial, We will Continue This project.


Written By
        SSB

Share this

Related Posts

Previous
Next Post »