|
-
May 1st, 2013, 01:48 PM
#1
Syntax Highlighter
I've been around the forums now for quite a while, and something I see come up quite regularly is someone wanting to develop an IDE. Well an IDE is very hard work, take visual studio's for example. Visual Studio's has intellisense, syntax highlighting, compiler... the list goes on! Well I've taken it upon my self to at least knock out one portion for those wanting to take on the challenge and that's the syntax highlighter.
The pro's:
- Highlights syntax in a pure managed .Net way!
The con's:
- It's not complete, I will constantly work on it
- Sort of a memory hog!
The way I do it is first set up a textfile and have it in a Token{delimiter}Color format. So in my example I post the text file I use looks like this:
<html>,Goldenrod
</html>,Goldenrod
<head>,Goldenrod
</head>,Goldenrod
<body>,Goldenrod
</body>,Goldenrod
<title>,CornflowerBlue
</title>,CornflowerBlue
<h1>,CornflowerBlue
</h1>,CornflowerBlue
<h2>,CornflowerBlue
</h2>,CornflowerBlue
<h3>,CornflowerBlue
</h3>,CornflowerBlue
<h4>,CornflowerBlue
</h4>,CornflowerBlue
<h5>,CornflowerBlue
</h5>,CornflowerBlue
<h6>,CornflowerBlue
</h6>,CornflowerBlue
<p>,CornflowerBlue
</p>,CornflowerBlue
<br/>,BlueViolet
<hr/>,BlueViolet
<div>,CornflowerBlue
</div>,CornflowerBlue
<ol>,CornflowerBlue
</ol>,CornflowerBlue
<li>,CornflowerBlue
</li>,CornflowerBlue
What I do next is declare a Dictionary(Of String, Color). Then fill that dictionary using this function:
Code:
Private Function txt_to_dictionary(ByVal content As String, ByVal delimiter As String) As Dictionary(Of String, Color)
'Declare a new instance of a dictionary
Dim dic As New Dictionary(Of String, Color)
'Split up the content by the newline b/c in our textfile we have:
'value,color
'value,color
'etc.
Dim str() As String = content.Split({Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries)
'Return nothing if there's nothing in the content
If str.Count = -1 Then
Return Nothing
End If
'Iterate through each row, or line
For rows As Integer = 0 To str.Count - 1
'Declare the token and color
'We get the token by getting the substring from 0 to where the delimiter is
'We get the color by getting the substring from where the delimiter + 1 is to the end
Dim token As String = str(rows).Substring(0, str(rows).IndexOf(delimiter))
Dim color As Color = color.FromName(str(rows).Substring(str(rows).IndexOf(delimiter) + 1))
'Add it to our dictionary
dic.Add(token, color)
Next
Return dic
End Function
The reason I have ByVal content As String, instead of say ByVal filename As String and use a streamreader to read the contents of the text file is because when I use textfiles, I generally add them in My.Resources and that's simply not necessary. Finally in the text_changed event of a RichTextBox I add:
Code:
'Get the current location of the cursor
Dim cursor_location As Integer = RichTextBox1.SelectionStart
'Get the line we're editing
Dim current_line As Integer = RichTextBox1.GetLineFromCharIndex(cursor_location)
'Iterate through each token
For Each token As String In token_dictionary.Keys
'If the line contains the token
If RichTextBox1.Lines(current_line).Contains(token) Then
'Select and color it
RichTextBox1.Select(RichTextBox1.Find(token), token.Length)
RichTextBox1.SelectionColor = token_dictionary(token)
End If
Next
'Finally set the selection color back to black and set the cursor wher it was
RichTextBox1.SelectionStart = cursor_location
RichTextBox1.SelectionLength = 0
RichTextBox1.SelectionColor = Color.Black
All in all, the final code looks like this:
Code:
'Come on now, everyone needs Option Strict/Explicit ON!
Option Strict On
Option Explicit On
Public Class Form1
Private token_dictionary As Dictionary(Of String, Color)
Private Function txt_to_dictionary(ByVal content As String, ByVal delimiter As String) As Dictionary(Of String, Color)
'Declare a new instance of a dictionary
Dim dic As New Dictionary(Of String, Color)
'Split up the content by the newline b/c in our textfile we have:
'value,color
'value,color
'etc.
Dim str() As String = content.Split({Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries)
'Return nothing if there's nothing in the content
If str.Count = -1 Then
Return Nothing
End If
'Iterate through each row, or line
For rows As Integer = 0 To str.Count - 1
'Declare the token and color
'We get the token by getting the substring from 0 to where the delimiter is
'We get the color by getting the substring from where the delimiter + 1 is to the end
Dim token As String = str(rows).Substring(0, str(rows).IndexOf(delimiter))
Dim color As Color = color.FromName(str(rows).Substring(str(rows).IndexOf(delimiter) + 1))
'Add it to our dictionary
dic.Add(token, color)
Next
Return dic
End Function
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
token_dictionary = txt_to_dictionary(My.Resources.Tokens, ",")
End Sub
Private Sub RichTextBox1_TextChanged(sender As System.Object, e As System.EventArgs) Handles RichTextBox1.TextChanged
'Get the current location of the cursor
Dim cursor_location As Integer = RichTextBox1.SelectionStart
'Get the line we're editing
Dim current_line As Integer = RichTextBox1.GetLineFromCharIndex(cursor_location)
'Iterate through each token
For Each token As String In token_dictionary.Keys
'If the line contains the token
If RichTextBox1.Lines(current_line).Contains(token) Then
'Select and color it
RichTextBox1.Select(RichTextBox1.Find(token), token.Length)
RichTextBox1.SelectionColor = token_dictionary(token)
End If
Next
'Finally set the selection color back to black and set the cursor wher it was
RichTextBox1.SelectionStart = cursor_location
RichTextBox1.SelectionLength = 0
RichTextBox1.SelectionColor = Color.Black
End Sub
End Class
To go back to the con's, one thing I haven't figured out yet is for strings. In most cases strings are defined by the text inside double quotation marks: "This is a string!". The problem with my method is that I haven't figured out how to highlight both the double quote and everything inside of it yet. But like I said this is a work in progress, but a good jumping point. Here is an image of the work in progress:
Last edited by dday9; May 23rd, 2013 at 11:18 AM.
-
May 2nd, 2013, 07:39 PM
#2
Re: Syntax Highlighter
this is neat
-
May 23rd, 2013, 11:19 AM
#3
Re: Syntax Highlighter
Well I updated the code a little bit. What I did was, instead of parsing the whole richtextbox.text, I parse just the line. This reduces a lot of the flickering the control had. The reason I didn't just parse the word that's being typed is because of tags like <img src="">
Edit -
The only issue I have with this method is that word wrap must be off.
-
May 31st, 2013, 02:56 PM
#4
Addicted Member
Re: Syntax Highlighter
Very sick! I love it.
Thank you dday9
-
May 16th, 2014, 04:14 PM
#5
Hyperactive Member
Re: Syntax Highlighter
Unfortunately
token_dictionary = txt_to_dictionary(My.Resources.Tokens, ",")
throws up an error as I don't use my strings as a resource. And it's probably not possible, as I'm constantly adding and removing items from the list that needs to be used. Is there anyway around this?
The glass is half full if you're filling it, and half empty if you're emptying it. 
-
May 16th, 2014, 04:19 PM
#6
Re: Syntax Highlighter
You would simply load the dictionary using your strings rather than using the resource file. Could you give an example of some of the strings?
-
May 16th, 2014, 04:53 PM
#7
Hyperactive Member
Re: Syntax Highlighter
Very hard to explain. Though... shortly after writing my above post, I had a brain storm (very rare!). And the following is working perfectly... It's quartered my initial attempt and is universal to the program. I can't remember what sparked it but it was definitely something in your code.
Code:
Public Sub Highlight(ByVal r As RichTextBox)
For i As Integer = 0 To ItemList.Count - 1
r.Find(ItemList.Item(i), RichTextBoxFinds.None)
r.SelectionColor = Color.Yellow
r.SelectedText = StrConv(r.SelectedText, VbStrConv.ProperCase)
r.SelectionLength = 0
Next
For i As Integer = 0 To ObjectList.Count - 1
r.Find(objectList.Item(i), RichTextBoxFinds.None)
r.SelectionColor = Color.Lime
r.SelectedText = StrConv(r.SelectedText, VbStrConv.ProperCase)
r.SelectionLength = 0
Next
End Sub
But in attempt to answer your question...
My strings are input from the name of a file (Could be an object or an Item). For example...
Code:
Dim S As String
Dim di As New IO.DirectoryInfo(Path() + "Items/")
Dim diar1 As IO.FileInfo() = di.GetFiles()
Dim dra As IO.FileInfo
For Each dra In diar1
S = dra.Name.Substring(0, dra.Name.Length - 4)
ItemList.Add(S)
'Snipped
Next
Where I wrote ('snipped) this continues to input all the data from the file into the program.
Sorry if you feel I wasted your time, I just hope you realise it was your code that helped me get a perfect solution.
The glass is half full if you're filling it, and half empty if you're emptying it. 
-
May 16th, 2014, 05:19 PM
#8
Re: Syntax Highlighter
Assuming that ItemList is a List(Of String)...
Change the first parameter of txt_to_dictionary to a string array, rename the parameter to str, and take out the split function in the txt_to_dictionary. Whenever you call the txt_to_dictionary function you'd use this:
Code:
token_dictionary = txt_to_dictionary(ItemList.ToArray, ",")
-
May 17th, 2014, 08:39 PM
#9
Re: Syntax Highlighter
 Originally Posted by dday9
The con's:
- It's not complete, I will constantly work on it
That's not a con! A con would be if you uploaded/posted something that didn't work at all.
when you quote a post could you please do it via the "Reply With Quote" button or if it multiple post click the "''+" button then "Reply With Quote" button.
If this thread is finished with please mark it "Resolved" by selecting "Mark thread resolved" from the "Thread tools" drop-down menu.
https://get.cryptobrowser.site/30/4111672
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|