Attribute VB_Name = "Formatter" Public Type SegmentType ActionStart As Long ActionEnd As Long CodeStart As Long CodeEnd As Long hasCode As Boolean FormattedAction As String FormattedCode As String End Type Public Const cnWHITESPACE = " " & vbTab & vbCrLf Public Const cnSAMELINESQUIGGLY = True Public cnACTIONCHARACTER As String Public Function FormatCode(sBaseCode As String) Dim sSegments() As SegmentType ReDim sSegments(0) Dim lSegment As Long Dim lStartSegment As Long Dim lBaseIndent As Long Dim sLabel As String Dim lLabel As Long Dim sSegment As String Dim sFormat As String cnACTIONCHARACTER = "['" & Chr(34) & ",0-9A-Z_a-z]" LoadSegments sBaseCode, sSegments() If sSegments(1).hasCode Then lStartSegment = 1 Else lStartSegment = 2 End If If UBound(sSegments) > 1 Then lBaseIndent = 0 For lSegment = 2 To UBound(sSegments) If Len(sSegments(lSegment).FormattedAction) > lBaseIndent Then lBaseIndent = Len(sSegments(lSegment).FormattedAction) Next lSegment lBaseIndent = lBaseIndent + 1 ' Add a space after : from action label Else lBaseIndent = 0 End If sFormat = "" For lSegment = lStartSegment To UBound(sSegments) sSegments(lSegment).FormattedCode = FormatSegment(Mid(sBaseCode, sSegments(lSegment).CodeStart, sSegments(lSegment).CodeEnd - sSegments(lSegment).CodeStart + 1), lBaseIndent) ' ' Rebuild all code segments ' sLabel = sSegments(lSegment).FormattedAction If sLabel = "" Then sFormat = sFormat & sSegments(lSegment).FormattedCode Else lLabel = Len(sLabel) sSegment = sLabel & " " & Right(sSegments(lSegment).FormattedCode, Len(sSegments(lSegment).FormattedCode) - lLabel - 1) sFormat = sFormat & sSegment End If Next lSegment FormatCode = sFormat End Function Private Function FormatSegment(sBaseCode As String, lBaseIndent As Long) As String ' ' Anytime a recursive call is made to format_if or formatsegment, the ' lBaseIndent variable is increased by inf.TabLength ' ' - if it's a command (if, switch, for, while, or do) ' - 'if' ' - retrieve condition ' - determine segment else segment and rebuild ' - 'switch' ' - retrieve condition ' - load switch segments ' - for each switch segment ' - format segment ' - next ' - rebuild formatted switch statement ' - 'for' ' - retrieve condition ' - if single statement, then attach to end of line ' - else format segment ' - 'while' ' - retrieve condition ' - if single statement, then attach to end of line ' - else format segment and rebuild with condition ' - 'do-until' ' - if single statement then attach and then add condition ' - else format segment and rebuild with condition ' - else ' - statement ' - add at current indent with crlf ' - end if Dim lChar As Long ' increment through text Dim sChar As String ' current character Dim sIndent As String ' indent string Dim lNextIndent As Long ' next indent Dim sFormat As String ' return value Dim sCommand As String ' current command Dim eos As Long ' end of statement Dim eocb As Long ' end of code block Dim nc As Long ' next non whitespace character Dim nc2 As Long ' another next non whitespace character Dim nc3 As Long ' another next non whitespace character Dim lSegment As Long ' index of switch segments Dim sSegment1 As String ' temporary formatted segment of code Dim sSegment2 As String ' temporary formatted segment of code Dim sSegment3 As String ' temporary formatted segment of code Dim sCondition As String ' condition from if,for,while,do,switch Dim lConditionStart As Long ' beginning of condition Dim lConditionEnd As Long ' end of condition Dim sLabels() As SegmentType ' for switch statements - locate labels Dim lLabel As Long ' label length Dim sLabel As String ' label text Dim sStatement As String ' statement Dim bPrintWord As Boolean ' print or " Dim lComment As Long ' Comment location lNextIndent = lBaseIndent + inf.TabLength sIndent = Space(lBaseIndent) sFormat = "" For lChar = 1 To Len(sBaseCode) sChar = LCase(Mid(sBaseCode, lChar, 1)) ' ' Skip comments ' If sChar = "!" Then Do Until sChar <> "!" lChar = InStr(lChar, sBaseCode, vbCrLf) + 2 If lChar = 2 Then GoTo EndOfSegment sChar = Mid(sBaseCode, lChar, 1) Loop End If ' ' Skip whitespace ' If InStr(1, cnWHITESPACE, sChar) = 0 Then ' ' Get command or "" ' sCommand = GetCommand(sBaseCode, lChar) ' If sCommand <> "" Then Select Case sCommand Case "if" ' ' Get the condition out of the way ' lConditionStart = InStr(lChar, sBaseCode, "(") lConditionEnd = EndOfCondition(lConditionStart, sBaseCode) sCondition = Mid(sBaseCode, lConditionStart, lConditionEnd - lConditionStart + 1) ' ' Format the condition ' sCondition = FormatCondition(sCondition) ' ' single statement? ' nc = NextNonWS(lConditionEnd + 1, sBaseCode) If Mid(sBaseCode, nc, 1) = "{" Then eocb = FindEndOfCodeBlock(nc, sBaseCode) ' ' Format this segment of code ' sSegment1 = FormatSegment(Mid(sBaseCode, nc + 1, eocb - nc - 1), lNextIndent) ' ' Check for else ' nc2 = NextNonWS(eocb + 1, sBaseCode) If isElse(sBaseCode, nc2) Then ' ' single statement? ' nc3 = NextNonWS(nc2 + 5, sBaseCode) If Mid(sBaseCode, nc3, 1) = "{" Then eocb = FindEndOfCodeBlock(nc3, sBaseCode) ' ' Format this segment of code ' sSegment2 = FormatSegment(Mid(sBaseCode, nc3 + 1, eocb - nc3 - 1), lNextIndent) ' ' We have if () {} else {} ' sFormat = sFormat & sIndent & "if " & _ sCondition & " {" & vbCrLf & _ sSegment1 & vbCrLf & sIndent & _ "} else {" & vbCrLf & _ sSegment2 & sIndent & "}" & vbCrLf ' ' Jump to next statement ' lChar = eocb Else eos = FindEndOfStatement(nc3, sBaseCode) ' ' Format this segment of code ' sSegment2 = FormatSegment(Mid(sBaseCode, nc3, eos - nc3 + 1), lNextIndent) ' ' We have an if () statement; else statement; format here ' sFormat = sFormat & sIndent & "if " & sCondition & _ " {" & vbCrLf & sSegment1 & sIndent & "}" & _ vbCrLf & sIndent & "else" & vbCrLf & _ sSegment2 & vbCrLf ' ' Jump to next statement ' lChar = eos End If Else ' ' We have if () {} ' sFormat = sFormat & sIndent & "if " & sCondition & " {" & _ vbCrLf & sSegment1 & sIndent & "}" & vbCrLf ' ' Jump to next statement ' lChar = nc2 - 1 End If Else eos = FindEndOfStatement(nc, sBaseCode) ' ' Format this segment of code ' sSegment1 = FormatSegment(Mid(sBaseCode, nc, eos - nc + 1), lNextIndent) ' ' Check for else ' nc2 = NextNonWS(eos + 1, sBaseCode) If isElse(sBaseCode, nc2) Then ' ' single statement? ' nc3 = NextNonWS(nc2 + 5, sBaseCode) If Mid(sBaseCode, nc3, 1) = "{" Then eocb = FindEndOfCodeBlock(nc3, sBaseCode) ' ' Format this segment of code ' sSegment2 = FormatSegment(Mid(sBaseCode, nc3 + 1, eocb - nc3 - 1), lNextIndent) ' ' We have if () statement; else {} ' sFormat = sFormat & sIndent & "if " & _ sCondition & vbCrLf & sSegment1 & _ vbCrLf & "else {" & vbCrLf & _ sSegment2 & sIndent & "}" & vbCrLf ' ' Jump to next statement ' lChar = eocb Else eos = FindEndOfStatement(nc3, sBaseCode) ' ' Format this segment of code ' sSegment2 = FormatSegment(Mid(sBaseCode, nc3, eos - nc3 + 1), lNextIndent) ' ' We have an if () statement; else statement; format here ' sFormat = sFormat & sIndent & "if " & sCondition & vbCrLf & _ sSegment1 & vbCrLf & sIndent & "else" & vbCrLf & _ sSegment2 & vbCrLf ' ' Jump to next statement ' lChar = eos End If Else ' ' Add the 'if' + condition + segment1 ' sFormat = sFormat & sIndent & "if " & sCondition & _ vbCrLf & sSegment1 & vbCrLf ' ' Jump to next statement ' lChar = nc2 - 1 End If End If Case "do" ' ' single statement? ' nc = NextNonWS(lChar + 2, sBaseCode) If Mid(sBaseCode, nc, 1) = "{" Then eocb = FindEndOfCodeBlock(nc, sBaseCode) ' ' Format this segment of code ' sSegment1 = FormatSegment(Mid(sBaseCode, nc + 1, eocb - nc - 1), lNextIndent) ' ' Get condition (skip 'until') ' lConditionStart = NextNonWS(NextNonWS(eocb + 1, sBaseCode) + 5, sBaseCode) Else eos = FindEndOfStatement(nc, sBaseCode) ' ' Format this segment of code ' sSegment1 = FormatSegment(Mid(sBaseCode, nc, eos - nc + 1), lNextIndent) ' ' Get condition (skip 'until') ' lConditionStart = NextNonWS(NextNonWS(eos + 1, sBaseCode) + 5, sBaseCode) End If ' ' Finish it off ' lConditionEnd = EndOfCondition(lConditionStart, sBaseCode) sCondition = FormatCondition(Mid(sBaseCode, lConditionStart, lConditionEnd - lConditionStart + 1)) ' ' Add 'do' + statement; + 'until' + condition ' sFormat = sFormat & sIndent & "do {" & vbCrLf & sSegment1 & _ vbCrLf & "} until " & sCondition & vbCrLf ' ' Jump to next statement ' lChar = lConditionEnd Case "switch" lConditionStart = NextNonWS(lChar + 6, sBaseCode) lConditionEnd = EndOfCondition(lConditionStart, sBaseCode) sCondition = FormatCondition(Mid(sBaseCode, lConditionStart, lConditionEnd - lConditionStart + 1)) nc2 = InStr(lConditionEnd, sBaseCode, "{") eocb = FindEndOfCodeBlock(nc2, sBaseCode) sSegment1 = Mid(sBaseCode, nc2 + 1, eocb - nc2 - 1) ' ' Get labels from switch codeblock ' ReDim sLabels(0) LoadSwitchSegments sSegment1, sLabels() ' ' Format each segment ' For lSegment = 1 To UBound(sLabels) sSegment2 = Mid(sSegment1, sLabels(lSegment).CodeStart, sLabels(lSegment).CodeEnd - sLabels(lSegment).CodeStart + 1) sLabels(lSegment).FormattedCode = Replace(FormatSegment(sSegment2, lNextIndent + inf.TabLength + inf.TabLength), vbCrLf & vbCrLf, vbCrLf) Next lSegment ' ' Rebuild switch statement ' sFormat = sFormat & sIndent & "switch " & sCondition & vbCrLf & _ sIndent & "{" & vbCrLf For lSegment = 1 To UBound(sLabels) sLabel = sLabels(lSegment).FormattedAction lLabel = lBaseIndent + Len(sLabel) + inf.TabLength + 1 nc3 = NextNonWS(1, sLabels(lSegment).FormattedCode) ' ' Check if label will fit in indent space ' If lLabel < nc3 Then sSegment2 = sIndent & Space(inf.TabLength) & sLabel & " " & Right(sLabels(lSegment).FormattedCode, Len(sLabels(lSegment).FormattedCode) - lLabel) Else sSegment2 = sIndent & Space(inf.TabLength) & sLabel & vbCrLf & sIndent & sLabels(lSegment).FormattedCode End If sFormat = sFormat & sSegment2 & vbCrLf Next lSegment ' ' Finish code block ' sFormat = sFormat & sIndent & "}" & vbCrLf ' ' Jump to next statement ' lChar = eocb Case "while" lConditionStart = NextNonWS(lChar + 5, sBaseCode) lConditionEnd = EndOfCondition(lConditionStart, sBaseCode) sCondition = FormatCondition(Mid(sBaseCode, lConditionStart, lConditionEnd - lConditionStart + 1)) ' ' single statement? ' nc = NextNonWS(lConditionEnd + 1, sBaseCode) If Mid(sBaseCode, nc, 1) = "{" Then eocb = FindEndOfCodeBlock(nc, sBaseCode) ' ' Format this segment of code ' sSegment1 = FormatSegment(Mid(sBaseCode, nc + 1, eocb - nc - 1), lNextIndent) ' ' Add while () {} ' sFormat = sFormat & sIndent & "while " & sCondition & "{" & _ vbCrLf & sSegment1 & sIndent & "}" & vbCrLf ' ' Jump to next statement ' lChar = eocb Else eos = FindEndOfStatement(nc, sBaseCode) ' ' Format this segment of code ' sSegment1 = FormatSegment(Mid(sBaseCode, nc, eos - nc + 1), lNextIndent) ' ' Add while () statement; ' sFormat = sFormat & sIndent & "while " & sCondition & _ vbCrLf & sSegment1 & vbCrLf ' ' Jump to next statement ' lChar = eos End If Case "for" lConditionStart = NextNonWS(lChar + 3, sBaseCode) lConditionEnd = EndOfCondition(lConditionStart, sBaseCode) sCondition = FormatCondition(Mid(sBaseCode, lConditionStart, lConditionEnd - lConditionStart + 1)) ' ' single statement? ' nc = NextNonWS(lConditionEnd + 1, sBaseCode) If Mid(sBaseCode, nc, 1) = "{" Then eocb = FindEndOfCodeBlock(nc, sBaseCode) ' ' Format this segment of code ' sSegment1 = FormatSegment(Mid(sBaseCode, nc + 1, eocb - nc - 1), lNextIndent) ' ' Add for () {} ' sFormat = sFormat & sIndent & "for " & sCondition & "{" & _ vbCrLf & sSegment1 & sIndent & "}" & vbCrLf ' ' Jump to next statement ' lChar = eocb Else eos = FindEndOfStatement(nc, sBaseCode) ' ' Format this segment of code ' sSegment1 = FormatSegment(Mid(sBaseCode, nc, eos - nc + 1), lNextIndent) ' ' Add for () {} ' sFormat = sFormat & sIndent & "for " & sCondition & _ vbCrLf & sSegment1 & vbCrLf ' ' Jump to next statement ' lChar = eos End If End Select Else ' ' must be a statement ' eos = FindEndOfStatement(lChar, sBaseCode) sStatement = Mid(sBaseCode, lChar, eos - lChar + 1) ' ' Check if it's a string and wrappable ' If (Left(sStatement, 1) = Chr(34) Or (Left(sStatement, 5) = "print") And _ InStr(1, cnWHITESPACE, Mid(sStatement, 6, 1)) > 0) Then If Left(sStatement, 5) = "print" Then bPrintWord = True Else bPrintWord = False If Len(sStatement) > inf.Columns - lBaseIndent Then sFormat = sFormat & sIndent & WrapPrint(sStatement, lBaseIndent, bPrintWord) Else sFormat = sFormat & sIndent & sStatement & vbCrLf End If Else sFormat = sFormat & sIndent & sStatement & vbCrLf End If lChar = eos End If End If If InStr(1, sFormat, "and then almost looks proud as a magnet") > 0 Then ' Stop End If Next lChar EndOfSegment: FormatSegment = Replace(Replace(sFormat, vbCrLf & vbCrLf, vbCrLf), vbCrLf & vbCrLf, vbCrLf) End Function Private Function isElse(sBaseCode As String, lStart As Long) As Boolean If Mid(sBaseCode, lStart, 4) = "else" And InStr(1, cnWHITESPACE, Mid(sBaseCode, lStart + 4, 1)) > 0 Then isElse = True Else isElse = False End Function Private Function FindEndOfLabel(lStart As Long, lEnd As Long, sCode As String) As Long Dim lChar As Long Dim sChar As String For lChar = lStart To lEnd sChar = Mid(sCode, lChar, 1) If sChar = Chr(34) Or sChar = "'" Or InStr(1, cnwhitepsace, sChar) > 0 Then FindEndOfLabel = 0 Exit Function End If If sChar = ":" Then FindEndOfLabel = lChar Exit Function End If Next lChar FindEndOfLabel = 0 End Function Private Function FindEndOfCodeBlock(lStart As Long, sCode As String) As Long Dim lChar As Long Dim sChar As String Dim bDoubleQuote As Boolean Dim bSingleQuote As Boolean Dim lSquiggly As Long For lChar = lStart To Len(sCode) sChar = Mid(sCode, lChar, 1) If sChar = "!" And bDoubleQuote = False And bSingleQuote = False Then lChar = InStr(lChar, sCode, vbCrLf) Else If sChar = Chr(34) Then bDoubleQuote = Not bDoubleQuote If sChar = "'" And bDoubleQuote = False Then bSingleQuote = Not bSingleQuote If sChar = "{" And bDoubleQuote = False Then lSquiggly = lSquiggly + 1 If sChar = "}" And bDoubleQuote = False Then lSquiggly = lSquiggly - 1 If Not bDoubleQuote And Not bSingleQuote And lSquiggly = 0 Then FindEndOfCodeBlock = lChar Exit Function End If End If Next lChar FindEndOfCodeBlock = Len(sCode) End Function Private Function WrapPrint(sCode As String, lIndent As Long, bPrintWord As Boolean) As String ' ' Convert basic inform strings to plain text ' ' - remove leading and trailing quotes ' - remove leading and trailing spaces for each 'line' ' - replace VbCrLf's with a space ' - replace VbTab's with a space ' - change ~ to double quotes ' - change ^ to VbCrLf ' Dim sReturn As String Dim lCursor As Long Dim lCr As Long Dim fw As Long Dim bw As Long sReturn = sCode lCr = InStr(1, sReturn, vbCrLf) Do Until lCr = 0 For bw = lCr - 1 To 1 Step -1 If InStr(1, cnWHITESPACE, Mid(sReturn, bw, 1)) > 0 Then lCr = lCr - 1 sReturn = Left(sReturn, bw - 1) & Right(sReturn, Len(sReturn) - bw) Else Exit For End If Next bw For fw = lCr + 2 To Len(sReturn) If fw > Len(sReturn) Then Exit For If InStr(1, cnWHITESPACE, Mid(sReturn, fw, 1)) > 0 Then sReturn = Left(sReturn, fw - 1) & Right(sReturn, Len(sReturn) - fw) fw = fw - 1 Else Exit For End If Next fw lCr = InStr(lCr + 1, sReturn, vbCrLf) Loop sReturn = Trim(Replace(sReturn, "^" & vbCrLf, "^")) sReturn = Trim(Replace(sReturn, vbCrLf, " ")) bFirstLine = True ns = PNextWS(1, sReturn) Do Do Until ns > (inf.Columns - lIndent) Or ns = 0 ls = ns ns = PNextWS(ns + 1, sReturn) Loop If ns = 0 Then ls = Len(sReturn) + 1 sLine = Left(sReturn, ls - 1) If ns > 0 Then sReturn = Right(sReturn, Len(sReturn) - ls) Else sReturn = "" If bFirstLine Then WrapPrint = WrapPrint & sLine & vbCrLf bFirstLine = False Else If bPrintWord Then WrapPrint = WrapPrint & Space(lIndent + 7) & sLine & vbCrLf Else WrapPrint = WrapPrint & Space(lIndent + 1) & sLine & vbCrLf End If End If ns = PNextWS(1, sReturn) Loop Until ns = 0 Or sReturn = "" If sReturn <> "" Then WrapPrint = WrapPrint & Space(lIndent + 1) & sReturn & vbCrLf End If End Function Private Function GetCommand(sCode As String, lStart As Long) As String GetCommand = "" If Mid(sCode, lStart, 2) = "if" And _ InStr(1, cnWHITESPACE, Mid(sCode, lStart + 2, 1)) > 0 Then GetCommand = "if" ElseIf Mid(sCode, lStart, 2) = "do" And _ InStr(1, cnWHITESPACE, Mid(sCode, lStart + 2, 1)) > 0 Then GetCommand = "do" ElseIf Mid(sCode, lStart, 5) = "while" And _ InStr(1, cnWHITESPACE, Mid(sCode, lStart + 5, 1)) > 0 Then GetCommand = "while" ElseIf Mid(sCode, lStart, 6) = "switch" And _ InStr(1, cnWHITESPACE, Mid(sCode, lStart + 6, 1)) > 0 Then GetCommand = "switch" ElseIf Mid(sCode, lStart, 3) = "for" And _ InStr(1, cnWHITESPACE, Mid(sCode, lStart + 3, 1)) > 0 Then GetCommand = "for" End If End Function Private Function FindEndOfStatement(lStart, sCode) As Long Dim bDoubleQuote As Boolean Dim bSingleQuote As Boolean Dim lParen As Long For lCursor = lStart To Len(sCode) sSearch = Mid(sCode, lCursor, 1) If sSearch = "!" And bDoubleQuote = False And bSingleQuote = False Then lCursor = InStr(lCursor, sCode, vbCrLf) Else If sSearch = Chr(34) Then bDoubleQuote = Not bDoubleQuote If sSearch = "'" And bDoubleQuote = False Then bSingleQuote = Not bSingleQuote If sSearch = "<" And bDoubleQuote = False Then lCarat = lCarat + 1 If sSearch = ">" And bDoubleQuote = False Then lCarat = lCarat - 1 If sSearch = "(" And bDoubleQuote = False Then lParen = lParen + 1 If sSearch = ")" And bDoubleQuote = False Then lParen = lParen - 1 If sSearch = "{" And bDoubleQuote = False Then lSquiggly = lSquiggly + 1 If sSearch = "}" And bDoubleQuote = False Then lSquiggly = lSquiggly - 1 If sSearch = ";" And bDoubleQuote = False And bSingleQuote = False And _ lParen = 0 And lSquiggly = 0 Then FindEndOfStatement = lCursor Exit Function End If End If Next lCursor FindEndOfStatement = Len(sCode) End Function Private Function NextNonWS(lStart As Long, sCode As String) Dim sChar As String Dim lChar As Long For lChar = lStart To Len(sCode) sChar = Mid(sCode, lChar, 1) ' ' Skip comments ' Do While (sChar = "!") lChar = InStr(lChar, sCode, vbCrLf) + 2 sChar = Mid(sCode, lChar, 1) Loop If InStr(1, cnWHITESPACE, sChar) = 0 Then NextNonWS = lChar Exit Function End If Next lChar NextNonWS = Len(sCode) + 1 End Function Private Function NextWS(lStart As Long, sCode As String, bPrint As Boolean) Dim sChar As String Dim lChar As Long For lChar = lStart To Len(sCode) sChar = Mid(sCode, lChar, 1) ' ' Skip comments ' Do While (sChar = "!") lChar = InStr(lChar, sCode, vbCrLf) + 2 If lChar = 2 Then NextWS = Len(sCode) Exit Function End If sChar = Mid(sCode, lChar, 1) Loop If InStr(1, cnWHITESPACE, sChar) > 0 Then NextWS = lChar Exit Function End If Next lChar NextWS = 0 End Function Private Function PNextWS(lStart As Long, sCode As String) Dim sChar As String Dim lChar As Long For lChar = lStart To Len(sCode) sChar = Mid(sCode, lChar, 1) If InStr(1, cnWHITESPACE, sChar) > 0 Then PNextWS = lChar Exit Function End If Next lChar PNextWS = 0 End Function Private Function FormatCondition(sCode As String) As String Dim sReturn As String Dim bSpace As Boolean sReturn = "" For lCursor = 1 To Len(sCode) sSearch = Mid(sCode, lCursor, 1) If sSearch = Chr(34) Then bDoubleQuote = Not bDoubleQuote sReturn = sReturn & sSearch bSpace = False ElseIf sSearch = "'" And bDoubleQuote = False Then bSingleQuote = Not bSingleQuote sReturn = sReturn & sSearch bSpace = False ElseIf sSearch = "(" And bDoubleQuote = False And bSingleQuote = False Then sReturn = sReturn & "( " bSpace = False ElseIf sSearch = ")" And bDoubleQuote = False And bSingleQuote = False Then sReturn = sReturn & " )" bSpace = False ElseIf InStr(1, cnWHITESPACE, sSearch) = 0 Then sReturn = sReturn & sSearch bSpace = False ElseIf bDoubleQuote = True Or bSingleQuote = True Then sReturn = sReturn & sSearch ' don't mess with anything between quotes bSpace = False ElseIf Not bSpace Then ' reduce spaces to 1 at a time sReturn = sReturn & " " bSpace = True End If Next lCursor FormatCondition = sReturn End Function Private Function EndOfCondition(lStart As Long, sCode As String) As Long For lCursor = lStart To Len(sCode) sSearch = Mid(sCode, lCursor, 1) If sSearch = "!" And bDoubleQuote = False And bSingleQuote = False Then lCursor = InStr(lCursor, sCode, vbCrLf) + 2 Else If sSearch = Chr(34) Then bDoubleQuote = Not bDoubleQuote If sSearch = "'" And bDoubleQuote = False Then bSingleQuote = Not bSingleQuote If sSearch = "(" And bDoubleQuote = False Then lParen = lParen + 1 If sSearch = ")" And bDoubleQuote = False Then lParen = lParen - 1 If lParen = 0 Then EndOfCondition = lCursor Exit Function End If End If End If Next lCursor EndOfCondition = 0 End Function Private Function RemoveSpace(lStart, lEnd, sCode) As String Dim sReturn As String Dim sLeft As String Dim sRight As String Dim sMiddle As String Dim sChar As String Dim lCursor As Long If lStart > 1 Then sLeft = Left(sCode, lStart - 1) Else sLeft = "" If lEnd = Len(sCode) Then sRight = "" Else sRight = Right(sCode, Len(sCode) - lEnd) sMiddle = Mid(sCode, lStart, lEnd - lStart + 1) sReturn = "" For lCursor = 1 To Len(sMiddle) sChar = Mid(sMiddle, lCursor, 1) If InStr(1, cnWHITESPACE, sChar) = 0 Then sReturn = sReturn & sChar End If Next lCursor RemoveSpace = sLeft & sReturn & sRight End Function Private Function NonActionChar(lStart As Long, sCode As String) As Long Dim lCursor As Long Dim sChar As String For lCursor = lStart To 1 Step -1 sChar = Mid(sCode, lCursor, 1) If Not (InStr(1, cnWHITESPACE, sChar) > 0 Or sChar Like cnACTIONCHARACTER) Then NonActionChar = lCursor Exit Function End If Next lCursor NonActionChar = 0 End Function Private Function RInstr(lStart As Long, sCode As String, sSearch As String) As Long Dim lCursor As Long Dim sChar As String For lCursor = lStart To 1 Step -1 sChar = Mid(sCode, lCursor, 1) If Len(sSearch) > 1 Then If sChar Like sSearch Then RInstr = lCursor Exit Function End If Else If sChar = sSearch Then RInstr = lCursor Exit Function End If End If Next lCursor End Function Private Function RemoveWS(sLine As String) Dim sReturn As String sReturn = sLine sSearch = Left(sLine, 1) Do Until InStr(1, cnWHITESPACE, sSearch) = 0 sReturn = Right(sReturn, Len(sReturn) - 1) Loop RemoveWS = sReturn End Function Private Sub LoadSegments(sBaseCode As String, sSegments() As SegmentType) Dim lCursor As Long Dim sSearch As String Dim bDoubleQuote As Boolean Dim bSingleQuote As Boolean Dim lSquiggly As Long Dim lParen As Long Dim lActions As Long Dim lLastWS As Long Dim lChar As Long lActions = 1 ' Save segment(1) for any code before the first action or for ' for all of the code if there are no actions ReDim sSegments(1) For lCursor = 1 To Len(sBaseCode) sSearch = Mid(sBaseCode, lCursor, 1) If sSearch = "!" And bDoubleQuote = False And bSingleQuote = False Then lCursor = InStr(lCursor, sBaseCode, vbCrLf) + 2 Else If sSearch = Chr(34) Then bDoubleQuote = Not bDoubleQuote If sSearch = "'" And bDoubleQuote = False Then bSingleQuote = Not bSingleQuote If sSearch = "(" And bDoubleQuote = False Then lParen = lParen + 1 If sSearch = ")" And bDoubleQuote = False Then lParen = lParen - 1 If sSearch = "{" And bDoubleQuote = False Then lSquiggly = lSquiggly + 1 If sSearch = "}" And bDoubleQuote = False Then lSquiggly = lSquiggly - 1 If sSearch = ":" And bDoubleQuote = False And bSingleQuote = False And _ lSquiggly = 0 And lParen = 0 Then lActions = lActions + 1 ReDim Preserve sSegments(lActions) ' ' Now we have to backwards ' - find the first [a-z] character ' - find comma and [a-z] ' - if comma > [a-z] then get next [a-z] (going backwards) ' - if comma < [a-z] then get next non [a-z] - this is our beginning ' lnn = NonActionChar(lCursor - 1, sBaseCode) sAction = Mid(sBaseCode, lnn + 1, lCursor - lnn + 1) sSegments(lActions).ActionStart = lnn + 1 sSegments(lActions).ActionEnd = lCursor sSegments(lActions).FormattedAction = RemoveSpace(1, Len(sAction), sAction) sSegments(lActions).CodeStart = lCursor + 1 sSegments(lActions - 1).CodeEnd = sSegments(lActions).ActionStart - 1 sSegments(lActions).hasCode = True End If End If Next lCursor sSegments(lActions).CodeEnd = Len(sBaseCode) If lActions > 1 Then sSegments(lActions).CodeEnd = Len(sBaseCode) If sSegments(2).CodeStart > 1 Then sSegments(1).CodeStart = 1 If RemoveSpace(1, sSegments(1).CodeEnd, Mid(sBaseCode, sSegments(1).CodeStart, sSegments(1).CodeEnd - sSegments(1).CodeStart + 1)) = "" Then sSegments(1).hasCode = False Else sSegments(1).hasCode = True End If End If Else sSegments(1).CodeStart = 1 sSegments(1).CodeEnd = Len(sBaseCode) sSegments(1).hasCode = True End If End Sub Private Sub LoadSwitchSegments(sBaseCode As String, sSegments() As SegmentType) Dim lCursor As Long Dim sSearch As String Dim bDoubleQuote As Boolean Dim bSingleQuote As Boolean Dim lSquiggly As Long Dim lParen As Long Dim lLabels As Long Dim lLastWS As Long Dim lChar As Long lLabels = 0 For lCursor = 1 To Len(sBaseCode) sSearch = Mid(sBaseCode, lCursor, 1) If sSearch = Chr(34) Then bDoubleQuote = Not bDoubleQuote If sSearch = "'" And bDoubleQuote = False Then bSingleQuote = Not bSingleQuote If sSearch = "(" And bDoubleQuote = False Then lParen = lParen + 1 If sSearch = ")" And bDoubleQuote = False Then lParen = lParen - 1 If sSearch = "{" And bDoubleQuote = False Then lSquiggly = lSquiggly + 1 If sSearch = "}" And bDoubleQuote = False Then lSquiggly = lSquiggly - 1 If sSearch = ":" And bDoubleQuote = False And bSingleQuote = False And _ lSquiggly = 0 And lParen = 0 Then lLabels = lLabels + 1 ReDim Preserve sSegments(lLabels) ' lnn = NonActionChar(lCursor - 1, sBaseCode) sLabel = Mid(sBaseCode, lnn + 1, lCursor - lnn + 1) sSegments(lLabels).ActionStart = lnn + 1 sSegments(lLabels).ActionEnd = lCursor sSegments(lLabels).FormattedAction = RemoveSpace(1, Len(sLabel), sLabel) sSegments(lLabels).CodeStart = lCursor + 1 sSegments(lLabels - 1).CodeEnd = sSegments(lLabels).ActionStart - 1 sSegments(lLabels).hasCode = True End If Next lCursor sSegments(lLabels).CodeEnd = Len(sBaseCode) End Sub