Classes: Part 2 of N Advanced Server Side Script File Parsing
By:Jon M. Gohr
Hang onto your hats, boys and girls, things are going to start
getting more interesting, complex and useful from this point forward! I've decided
to take a bit of a diversion from the article ideas that I listed in part one.
The reason for this, strangely enough, is the articles
themselves. You will often encounter interesting new challenges when you least expect it,
if you're like me the challenge demands resolution before being able to move on. The
only bad part about coming up with an idea outside of the ones that I mentioned
in the previous article was that I had not written so
much as a single line of the code for this one. I'll
try to let my thoughts and ideas just kind of flow so you can get an
idea of the things that go through my head while in
the design process. Hope you don't end up with nightmares!
In part one of this series I spent entirely too much time in
Visual Interdev, cutting and pasting the example code and then setting font attributes. So in this
article we're going to develop a class that can read an .asp file
from the server and perform syntax highlighting as close to what I'm accustomed to seeing
in Visual Interdev as possible (with one or two of my own additions, which you
can change via class properties if you prefer). ASP 101 will hopefully stop using their script for viewing
code online and start using mine! If
they don't, well they're fools! ;-)
The essence of the programming problem is that we need
to read a file from the server, search through it line by line, find VBScript
language keywords and comments and then format them with HTML so that we can
write them to the user's browser. Reading a file proves to be quite easy, we can
use the Scripting.FileSystemObject. You can get reasonably complete
documentation and example code for the FileSystemObject from the help file for
the VBScript 5 script engine. If you don't have the latest html help files for
the scripting engines head on over to Microsoft's Scripting
and download them now.
Searching the text for language keywords and comments
proves to be the tricky part and we'll need to write all of the code for that
operation ourselves. I approached the problem from several different directions
before finally getting it to work the way I wanted it to. The script can read and parse as many code
blocks as there are in the page
with a few hopefully minor conditions.
Scripts need to be delimited with this type of script
Scripts inside of this type of script tag are not
parsed: <script language="vbscript" runat="server"></script>
Scripts can be on a single line like this: <%
option explicit %> or in multiple line script blocks.
If you have multiple line script blocks you should
place the script markers on their own lines.
The conditions listed above don't impact my
style of coding at all so hopefully everyone else can live with them as
Let's get to work!
For those who have previously viewed this
article you may notice that this section has been completely rewritten! The code
in the article has undergone many stages of refinement and the addendum to the
article was starting to get larger than the article itself. In hopes of
alleviating confusion I decided it would best to just clean up the article text
and get rid of the addendum completely. We'll start fresh and pretend that the 5
rounds of code revisions NEVER HAPPENED.
I decided to call the class that was developed for this
article, cBuffer. It should probably have a name more inline with it's function.
My original object model for performing the file reading and parsing had 4
classes, in that context the cBuffer name was more correct. By the time this
article saw the light of day my object model had collapsed down to 2 classes and
some of my name choices had begun to get a little out of context. Now, in the
final revision of the article and the code, the 2 classes have been further
compacted down to a single class. As stated in
part one of this series ... you will mistakes!
One of the naming mistakes that I made along the way
assumed that I would be storing language keywords in an array. To that end I had
a subroutine called BuildKeywordArray, as soon as I
switched over to using a Dictionary object for the keywords, the old subroutine
name became confusing. Changing the subroutine to CreateKeywords doesn't imply any
specific type of data structure while still giving a reasonable explanation
of it's intended purpose. My point? Watch how you name methods
and properties and don't explicitly give them type related names so
they'll still make sense if you change the implementation.
cBuffer has one property that you must set and one
primary method. The cBuffer.PathToFile property needs to be set
to the file that you want to parse prior to calling the
cBuffer.ParseFile method. If you attempt
to call the ParseFile method prior to setting the PathToFile property an error
of type 5, Invalid procedure call or argument, will be raised. ParseFile takes a
true or false parameter to determine whether or not to output the HTML that
is contained within the page as
well as the script code. Pass the method true if you
want the HTML output or false if you don't.
There are several other optional methods and properties
that you can manipulate prior to calling the ParseFile method. They are:
CodeColor, CommentColor, StringColor, TabSpaces, TableBGColor and AddKeyword.
The CodeColor property holds the color for the vbscript language keywords, the
default is Blue. CommentColor holds the color for comments, the default is Green. StringColor holds the color
for quoted strings, the default is Gray. TabSpaces holds a string of
spaces that will be used to replace
all tab characters. TabSpaces by default holds 4 spaces, this gives us tighter code output. TableBGColor holds
the color for the main table, White is the default color. AddKeyword is a public method
that will allow you to add your own keywords to the Dictionary object
contained in the cBuffer class. AddKeyword takes two string parameters, the
first string is the keyword in lowercase and the second parameter
is the replacement text and any other HTML formatting that you
wish to apply. Check the comments in the various files for
usage examples and other text explaining the finer points.
There are two miscellaneous properties that you can access AFTER
calling the ParseFile method. Accessing these properties before calling ParseFile will
return zero. They are: LineCount and ProcessingTime. LineCount is the number
of lines that were in the file and ProcessingTime is how
long, in seconds, it took to process the file.
The actual code is heavily commented as to it's
operation so instead of rehashing what is already there I
will just provided links to the cBuffer code as well
as some example code showing the usage of cBuffer. All the
code that you will view by following the next three links
will use the cBuffer class for color syntax highlighting and output
so you'll get to see the class in action!
to see the cBuffer code. It will
be output using an instance of the cBuffer class.
to see some
example code showing the usage of the cBuffer class.
the output you receive when executing the example code.
The cBuffer code consistently parses
the token.asp file in 2 seconds on my Pentium II 333mHz development machine.
This seems like acceptable performance on a reasonably complex source file so no
further performance optimizations will be done. KeyMin and KeyMax are two very
important private properties of the cBuffer class. They allow us the simple
optimization of only checking keywords that fall within the length boundaries.
If you add large keywords via the cBuffer.AddKeyword method, be aware that the
code performance will
as the gap between KeyMin and KeyMax gets larger.
Getting the Code:Seems like you have
two choices in the matter. You can either retype all of the code from the output
or you can send me an email
and let me know what you're
going to use
and I'll send it the original ASP include file.
NOTE: There is one anomaly with the cBuffer class that has to do with
certain special characters within a quoted string. It will be dealt with in a
future revision of the class ... see if you can find it! It didn't seem like a
big enough issue to warrant holding up the article. Oh yeah, one other
thing ... if you use large comment blocks like I have in my code they come out
with better formatting if you use spaces for alignment within the comment blocks
instead of tabs.
Other Applications and Possible
It would be quite easy to adapt the concepts of
the cBuffer class to use as a "dirty" word filter for a public/family oriented
message board system or guest book. You could also pass in an index reference to
the class so that it would only parse out a particular code block within an asp
page, which could quite handy depending upon the context. Obviously a site like
ASP 101 that presents ASP source
code can make use of this type of script. Another good use might be a group
of programmers working together on a project that might want to use the script or
a modification of it for different languages as an online code
repository. It would be
a nice addition to the class to add an HTML tag parsing routine so that
if you opted to have the HTML from the page output it would
be formatted in an attractive
anyone takes on that challenge, try to use the coloring that Visual Interdev 6 does
as your model and please send me your results so that we can share it with
At this point I'm not sure ... I have many other classes written but each new day
brings exciting new challenges! So either something interesting will come along and inspire
me in some as yet unknown direction or I'll prepare an article around one
of my previously written classes. Either way you can expect new articles to continue
flowing into the ASP 101 site on a
fairly regular basis. Peace ... and happy coding.
About the Author
Not much to tell ... I write code, usually, in exchange for money. ;-) I have my
own company, NetTech Development Inc. (yes it's a real state registered corporation and not just some name I pulled
from a hat), and work as an independent consultant in Minneapolis/St.
Paul, Minnesota. I have done work for MANY companies in
my area, from the biggest to the smallest. The last four
or five years I've been heavily involved in Internet, Intranet and E-Commerce projects
but also have significant project experience in Visual Basic, C/C++, various
database systems as well as multi-tier system architecture, analysis and data
modeling. If you need some serious development work done feel free to contact me!
I welcome your feedback in regards to my articles, just send me an email and if I have the time you might even get a response. Don't
hold your breath though!
This code is free
for non-commercial use as long as the copyright and author contact information contained within it is left intact. Commercial usage or
duplication requires a licensing agreement from the author. The author assumes no responsibility for
any damages incurred through the use and or execution of this
code. Use at your own risk.