Автор вопроса: Павел | Web-сайт:www.vbnet.ru | ICQ: 326066673
Товарищ Commanche предоставил мне код подсветки кода Visual Basic с
результатом в HTML... Все вроде нормально: больше тысячи ключевых слов
для VB6 и VB .NET, подсветка ключевых слов, комментариев, строковых
констант, обрисовка кода рамкой... Но! Работает возмутительно медленно
(на моем P4-2.66 файл объемом в рабочих условиях (под ASP .NET)
обрабатывался 14 секунд!). Поэтому может знатоки оптимизации помогут
сделать что-нибудь с этим кодом? Или дадут ссылку на другой хороший
вариант подсветки кода в HTML...
Public Class HighLight
' Константы HTML-цветов:
Private Const KEYWORD_COLOR As String = "#000099" ' << тёмно-синий - подсветка ключевых слов
Private Const COMMENT_COLOR As String = "#339933" ' << тёмно-зелёный - подсветка комментариев
Private Const STRINGS_COLOR As String = "#666666" ' << тёмно-серый - подсветка строковых констант
Private Const CODE_BG_COLOR As String = "#FFFFCC" ' << светло-жёлтый - цвет фона области кода
Private Const CODE_BR_COLOR As String = "#993300" ' << тёмно-бордовый - цвет рамки области кода
Private vbWordList As String = "Abs Array Asc AscB AscW Atn Avg CBool CByte CCur CDate CDbl Cdec Choose Chr ChrB ChrW CInt CLng Command Cos Count CreateObject CSng CStr CurDir CVar CVDate CVErr Date DateAdd DateDiff DatePart DateSerial DateValue Day DDB Dir DoEvents Environ EOF Error Exp FileAttr FileDateTime FileLen Fix Format FreeFile FV GetAllStrings GetAttr GetAutoServerSettings GetObject GetSetting Hex Hour IIf IMEStatus Input InputB InputBox InStr InstB Int IPmt IsArray IsDate IsEmpty IsError IsMissing IsNull IsNumeric IsObject LBound LCase Left LeftB Len LenB LoadPicture Loc LOF Log LTrim Max Mid MidB Min Minute MIRR Month MsgBox Now NPer NPV Oct Partition Pmt PPmt PV QBColor Rate RGB Right RightB Rnd RTrim Second Seek Sgn Shell Sin SLN Space Spc Sqr StDev StDevP Str StrComp StrConv String Switch Sum SYD Tab Tan Time Timer TimeSerial TimeValue Trim TypeName UBound UCase Val Var VarP VarType Weekday Year Accept Activate Add AddCustom AddFile AddFromFile AddFromTemplate AddItem AddNew AddToAddInToolbar AddToolboxProgID Append AppendChunk Arrange Assert AsyncRead BatchUpdate BeginTrans Bind Cancel CancelAsyncRead CancelBatch CancelUpdate CanPropertyChange CaptureImage CellText CellValue Circle Clear ClearFields ClearSel ClearSelCols Clone Close Cls ColContaining ColumnSize CommitTrans CompactDatabase Compose Connect Copy CopyQueryDef CreateDatabase CreateDragImage CreateEmbed CreateField CreateGroup CreateIndex CreateLink CreatePreparedStatement CreatePropery CreateQuery CreateQueryDef CreateRelation CreateTableDef CreateUser CreateWorkspace Customize Delete DeleteColumnLabels DeleteColumns DeleteRowLabels DeleteRows DoVerb Drag Draw Edit EditCopy EditPaste EndDoc EnsureVisible EstablishConnection Execute ExtractIcon Fetch FetchVerbs Files FillCache Find FindFirst FindItem FindLast FindNext FindPrevious Forward GetBookmark GetChunk GetClipString GetData GetFirstVisible GetFormat GetHeader GetLineFromChar GetNumTicks GetRows GetSelectedPart GetText GetVisibleCount GoBack GoForward Hide HitTest HoldFields Idle InitializeLabels InsertColumnLabels InsertColumns InsertObjDlg InsertRowLabels InsertRows Item KillDoc Layout Line LinkExecute LinkPoke LinkRequest LinkSend Listen LoadFile LoadResData LoadResPicture LoadResString LogEvent MakeCompileFile MakeReplica MoreResults Move MoveData MoveFirst MoveLast MoveNext MovePrevious NavigateTo NewPage NewPassword NextRecordset OLEDrag OnAddinsUpdate OnConnection OnDisconnection OnStartupComplete Open OpenConnection OpenDatabase OpenQueryDef OpenRecordset OpenResultset OpenURL Overlay PaintPicture Paste PastSpecialDlg PeekData Play Point PopulatePartial PopupMenu Print PrintForm PropertyChanged PSet Quit Raise RandomDataFill RandomFillColumns RandomFillRows rdoCreateEnvironment rdoRegisterDataSource ReadFromFile ReadProperty Rebind ReFill Refresh RefreshLink RegisterDatabase Reload Remove RemoveAddInFromToolbar RemoveItem Render RepairDatabase Reply ReplyAll Requery ResetCustom ResetCustomLabel ResolveName RestoreToolbar Resync Rollback RollbackTrans RowBookmark RowContaining RowTop Save SaveAs SaveFile SaveToFile SaveToolbar SaveToOle1File Scale ScaleX ScaleY Scroll Select SelectAll SelectPart SelPrint Send SendData Set SetAutoServerSettings SetData SetFocus SetOption SetSize SetText SetViewport Show ShowColor ShowFont ShowHelp ShowOpen ShowPrinter ShowSave ShowWhatsThis SignOff SignOn Size Span SplitContaining StartLabelEdit StartLogging Stop Synchronize TextHeight TextWidth ToDefaults TwipsToChartPart TypeByChartType Update UpdateControls UpdateRecord UpdateRow Upto WhatsThisMode WriteProperty ZOrder AccessKeyPress AfterAddFile AfterChangeFileName AfterCloseFile AfterColEdit AfterColUpdate AfterDelete AfterInsert AfterLabelEdit AfterRemoveFile AfterUpdate AfterWriteFile AmbienChanged ApplyChanges Associate AsyncReadComplete AxisActivated AxisLabelActivated AxisLabelSelected AxisLabelUpdated AxisSelected AxisTitleActivated AxisTitleSelected AxisTitleUpdated AxisUpdated BeforeClick BeforeColEdit BeforeColUpdate BeforeConnect BeforeDelete BeforeInsert BeforeLabelEdit BeforeLoadFile BeforeUpdate ButtonClick ButtonCompleted ButtonGotFocus ButtonLostFocus Change ChartActivated ChartSelected ChartUpdated Click ColEdit Collapse ColResize ColumnClick Compare ConfigChageCancelled ConfigChanged ConnectionRequest DataArrival DataChanged DataUpdated DblClick Deactivate DeviceArrival DeviceOtherEvent DeviceQueryRemove DeviceQueryRemoveFailed DeviceRemoveComplete DeviceRemovePending DevModeChange Disconnect DisplayChanged Dissociate DoGetNewFileName Done DonePainting DownClick DragDrop DragOver DropDown EditProperty EnterCell EnterFocus Event ExitFocus Expand FootnoteActivated FootnoteSelected FootnoteUpdated GotFocus HeadClick InfoMessage Initialize IniProperties ItemActivated ItemAdded ItemCheck ItemClick ItemReloaded ItemRemoved ItemRenamed ItemSeletected KeyDown KeyPress KeyUp LeaveCell LegendActivated LegendSelected LegendUpdated LinkClose LinkError LinkNotify LinkOpen Load LostFocus MouseDown MouseMove MouseUp NodeClick ObjectMove OLECompleteDrag OLEDragDrop OLEDragOver OLEGiveFeedback OLESetData OLEStartDrag OnAddNew OnComm Paint PanelClick PanelDblClick PathChange PatternChange PlotActivated PlotSelected PlotUpdated PointActivated PointLabelActivated PointLabelSelected PointLabelUpdated PointSelected PointUpdated PowerQuerySuspend PowerResume PowerStatusChanged PowerSuspend QueryChangeConfig QueryComplete QueryCompleted QueryTimeout QueryUnload ReadProperties Reposition RequestChangeFileName RequestWriteFile Resize ResultsChanged RowColChange RowCurrencyChange RowResize RowStatusChanged SelChange SelectionChanged SendComplete SendProgress SeriesActivated SeriesSelected SeriesUpdated SettingChanged SplitChange StateChanged StatusUpdate SysColorsChanged Terminate TimeChanged TitleActivated TitleSelected TitleActivated UnboundAddData UnboundDeleteRow UnboundGetRelativeBookmark UnboundReadData UnboundWriteData Unload UpClick Updated Validate ValidationError WillAssociate WillChangeData WillDissociate WillExecute WillUpdateRows WithEvents WriteProperties AppActivate Base Beep Call Case ChDir ChDrive Const Declare DefBool DefByte DefCur DefDate DefDbl DefDec DefInt DefLng DefObj DefSng DefStr Deftype DefVar DeleteSetting Dim Do Else ElseIf End Enum Erase Event Exit Explicit False FileCopy For ForEach Friend Function Get GoSub GoTo If Implements Kill Let LineInput Lock Loop LSet MkDir Name Next Not OnError On Option Private Property Public Put RaiseEvent Randomize ReDim Rem Reset Resume Return RmDir RSet SavePicture SaveSetting SendKeys SetAttr Static Sub Then True Type Unlock Wend While Width With Write Debug.Print Debug.Assert Print Exit New RaiseEvent AddressOf Type Compare Alias Lib Call Do Preserve Redim Erase Global Byte Base On Error Resume GoTo Until Open Input Output Random Binary Access Read Write Put Close Stop Set Is Nothing Property Let Get ElseIf Null And Or If Then Sub Declare Function Option Dim As End Loop Private Public While Not Wend Next Explicit LBound UBound Const Static True False String Boolean Integer Long Single Currency Select Case With Else ByVal ByRef For Mod Xor Imp To Module"" _"
Private vbnetWordList As String = "3DDKSHADOW 3DHIGHLIGHT 3DLIGHT ABORT ABORTRETRYIGNORE ACTIVEBORDER ACTIVETITLEBAR ALIAS APPLICATIONMODAL APPLICATIONWORKSPACE ARCHIVE BACK BINARYCOMPARE BLACK BLUE BUTTONFACE BUTTONSHADOW BUTTONTEXT CANCEL CDROM CR CRITICAL CRLF CYAN DEFAULT DEFAULTBUTTON1 DEFAULTBUTTON2 DEFAULTBUTTON3 DESKTOP DIRECTORY EXCLAMATION FALSE FIXED FORAPPENDING FORMFEED FORREADING FORWRITING FROMUNICODE GRAYTEXT GREEN HIDDEN HIDE HIGHLIGHT HIGHLIGHTTEXT HIRAGANA IGNORE INACTIVEBORDER INACTIVECAPTIONTEXT INACTIVETITLEBAR INFOBACKGROUND INFORMATION INFOTEXT KATAKANA LF LOWERCASE MAGENTA MAXIMIZEDFOCUS MENUBAR MENUTEXT METHOD MINIMIZEDFOCUS MINIMIZEDNOFOCUS MSGBOXRIGHT MSGBOXRTLREADING MSGBOXSETFOREGROUND NARROW NEWLINE NO NORMAL NORMALFOCUS NORMALNOFOCUS NULLSTRING OBJECTERROR OK OKCANCEL OKONLY PROPERCASE QUESTION RAMDISK READONLY RED REMOTE REMOVABLE RETRY RETRYCANCEL SCROLLBARS SYSTEMFOLDER SYSTEMMODAL TAB TEMPORARYFOLDER TEXTCOMPARE TITLEBARTEXT TRUE UNICODE UNKNOWN UPPERCASE VERTICALTAB VOLUME WHITE WIDE WIN16 WIN32 WINDOWBACKGROUND WINDOWFRAME WINDOWSFOLDER WINDOWTEXT YELLOW YES YESNO YESNOCANCEL BOOLEAN BYTE DATE DECIMIAL DOUBLE INTEGER LONG OBJECT SINGLE STRING As ADDHANDLER ASSEMBLY AUTO Binary ByRef ByVal BEGINEPILOGUE Else Empty Error ENDPROLOGUE EXTERNALSOURCE ENVIRON For Friend GET HANDLES Input Is Len Lock Me Mid MUSTINHERIT MYBASE MYCLASS New Next Nothing Null NOTINHERITABLE NOTOVERRIDABLE OFF On Option Optional OVERRIDABLE ParamArray Print Private Property Public Resume Seek Static Step String SHELL SENDKEYS SET Then Time To THROW WithEvents COLLECTION DEBUG DICTIONARY DRIVE DRIVES ERR FILE FILES FILESYSTEMOBJECT FOLDER FOLDERS TEXTSTREAM ADDRESSOF AND BITAND BITNOT BITOR BITXOR GETTYPE LIKE MOD NOT OR XOR APPACTIVATE BEEP CALL CHDIR CHDRIVE CLASS CASE CATCH DECLARE DELEGATE DELETESETTING DIM DO DOEVENTS END ENUM EVENT EXIT EACH FUNCTION FINALLY IF IMPORTS INHERITS INTERFACE IMPLEMENTS KILL LOOP MIDB NAMESPACE OPEN PUT RAISEEVENT RANDOMIZE REDIM REM RESET SAVESETTING SELECT SETATTR STOP SUB SYNCLOCK STRUCTURE SHADOWS SWITCH TIMEOFDAY TODAY TRY WIDTH WITH WRITE WHILE ABS ARRAY ASC ASCB ASCW CALLBYNAME CBOOL CBYTE CCHAR CCHR CDATE CDBL CDEC CHOOSE CHR CHR CHRB CHRB CHRW CINT CLNG CLNG8 CLOSE COBJ COMMAND COMMAND CONVERSION COS CREATEOBJECT CSHORT CSTR CURDIR CTYPE CVDATE DATEADD DATEDIFF DATEPART DATESERIAL DATEVALUE DAY DDB DIR DIR EOF ERROR EXP FILEATTR FILECOPY FILEDATATIME FILELEN FILTER FIX FORMAT FORMAT FORMATCURRENCY FORMATDATETIME FORMATNUMBER FORMATPERCENT FREEFILE FV GETALLSETTINGS GETATTRGETOBJECT GETSETTING HEX HEX HOUR IIF IMESTATUS INPUT INPUTB INPUTB INPUTBOX INSTR INSTRB INSTRREV INT IPMT IRR ISARRAY ISDATE ISEMPTY ISERROR ISNULL ISNUMERIC ISOBJECT JOIN LBOUND LCASE LCASE LEFT LEFT LEFTB LEFTB LENB LINEINPUT LOC LOF LOG LTRIM LTRIM MID MIDB MIDB MINUTE MIRR MKDIR MONTH MONTHNAME MSGBOX NOW NPER NPV OCT OCT PARTITION PMT PPMT PV RATE REPLACE RIGHT RIGHT RIGHTB RIGHTB RMDIR RND RTRIM RTRIM SECOND SIN SLN SPACE SPACE SPC SPLIT STR STR STRCOMP STRCONV STRING STRREVERSE SYD TAB TAN TIMEOFDAY TIMER TIMESERIAL TIMEVALUE TODAY TRIM TRIM TYPENAME UBOUND UCASE UCASE VAL WEEKDAY WEEKDAYNAME YEAR ANY ATN CALENDAR CIRCLE CURRENCY DEFBOOL DEFBYTE DEFCUR DEFDATE DEFDBL DEFDEC DEFINT DEFLNG DEFOBJ DEFSNG DEFSTR DEFVAR EQV GOSUB IMP INITIALIZE ISMISSING LET LINE LSET RSET SGN SQR TERMINATE VARIANT VARTYPE WEND"
Private strWords As String
Private vbCode As String
Dim lngPos As Int32 = 1
Dim strRight As String
Dim strLeft As String
Dim arrWords() As String
Dim lngIndex As Int32
Public Function HighLight(ByVal Code As String) As String
Dim vbSelStart As Integer, vbSelLength As Integer
Dim part1 As String, part2 As String, newPart As String
Dim i As Integer, j As Integer, st As String
Dim t As Single
Dim arrWords As String() = Split(strWords, " ")
' Сортируем его по убыванию длины слов - это ОБЯЗАТЕЛЬНО!!!:
For j = LBound(arrWords) To UBound(arrWords) - 1
For i = j To UBound(arrWords)
If Len(arrWords(j)) < Len(arrWords(i)) Then
st = arrWords(j)
arrWords(j) = arrWords(i)
arrWords(i) = st
End If
Next i
Next j
vbSelStart = 0
vbSelLength = Len(vbCode)
For lngIndex As Int32 = LBound(arrWords) To UBound(arrWords)
While Not InStr(lngPos, LCase(vbCode), LCase(arrWords(lngIndex))) = 0
lngPos = InStr(lngPos, LCase(vbCode), LCase(arrWords(lngIndex)))
vbSelStart = lngPos - 1
vbSelLength = Len(arrWords(lngIndex))
strRight = Mid(vbCode, lngPos + Len(arrWords(lngIndex)), 1)
If lngPos = 1 Then strLeft = " " Else strLeft = Mid(vbCode, lngPos - 1, 1)
If (strRight = " " Or strRight = "," Or strRight = "" Or strRight = "(" Or strRight = Chr(13)) And _
(strLeft = " " Or strLeft = "" Or strLeft = "(" Or strLeft = Chr(32) Or strLeft = Chr(10)) _
And ((Not InsideString()) And (Not InsideComment(lngPos))) Then
part1 = Mid(vbCode, 1, vbSelStart)
part2 = Mid(vbCode, vbSelStart + vbSelLength + 1, Len(vbCode) - vbSelStart - vbSelLength)
newPart = "<font color=" + KEYWORD_COLOR + ">" & arrWords(lngIndex) & "</font>"
vbCode = part1 + newPart + part2
lngPos = lngPos + Len(newPart) + 1
Else
lngPos = lngPos + 1
End If
End While
lngPos = 1
Next
lngPos = 1
While Not InStr(lngPos, vbCode, "'") = 0
lngPos = InStr(lngPos, vbCode, "'")
vbSelStart = lngPos - 1
If Not InStr(lngPos, vbCode, vbCrLf) = 0 Then vbSelLength = InStr(lngPos, vbCode, vbCrLf) - lngPos Else vbSelLength = Len(vbCode)
If lngPos = 1 Then strLeft = " " Else strLeft = Mid(vbCode, lngPos - 1, 1)
If (Not strLeft = Chr(34)) And (Not InsideString()) Then
part1 = Mid(vbCode, 1, vbSelStart)
part2 = Mid(vbCode, vbSelStart + vbSelLength + 1, Len(vbCode) - vbSelStart - vbSelLength)
newPart = "<font color=" + COMMENT_COLOR + ">" & Mid(vbCode, vbSelStart + 1, vbSelLength) & "</font>"
vbCode = part1 + newPart + part2
lngPos = lngPos + Len(newPart) + 1
Else
lngPos = lngPos + 1
End If
End While
vbSelStart = 0
Private Function InsideString() As Boolean
Dim cnt As Integer, i As Integer
i = lngPos
cnt = 0
While Mid(vbCode, i, 1) <> Chr(10) And i > 1
i = i - 1
If Mid(vbCode, i, 1) = Chr(34) Then
cnt = cnt + 1
End If
End While
InsideString = ((cnt Mod 2) = 1)
End Function
Private Function InsideComment(ByVal x As Long) As Boolean
Dim cnt As Integer, i As Long
i = x
cnt = 0
While Mid(vbCode, i, 1) <> Chr(10) And i > 1
i = i - 1
If Mid(vbCode, i, 1) = "'" Then
cnt = cnt + 1
End If
End While
InsideComment = (cnt > 0)
End Function
Private Sub HighLightStrings()
Dim arr() As String, i As Integer, pos As Long, flag As Boolean
arr = Split(vbCode, Chr(34))
pos = 0
For i = LBound(arr) To UBound(arr)
If i > LBound(arr) Then pos = pos + Len(arr(i - 1)) + 1 : flag = InsideComment(pos) Else flag = False
If (i Mod 2 = 1) And (Not flag) Then
arr(i) = "<font color=" + STRINGS_COLOR + ">" + Chr(34) + arr(i) + Chr(34) + "</font>"
ElseIf (i Mod 2 = 1) And (flag) Then
arr(i) = Chr(34) + arr(i) + Chr(34)
End If
Next i
vbCode = Join(arr, "")
End Sub
End Class