' PsToHtml.vbs ' VBScript program to read PowerShell code from a text file and convert ' into HTML, with colorization. For use in a Microsoft Forum message. ' A new file is created with the same name as the input file, but with ' *.htm extension. The contents of the new file can be pasted into a ' forum message using the "Edit HTML Source" feature. This ensures that ' the code snippet maintains spacing and uses a fixed-width font. ' ' ---------------------------------------------------------------------- ' Copyright (c) 2011-2012 Richard L. Mueller ' Hilltop Lab web site - http://www.rlmueller.net ' Version 1.0 - October 15, 2011 ' Version 1.1 - February 7, 2012 - Add border around the code. ' Version 1.2 - February 8, 2012 - Preserve all embedded spacing. ' Version 1.3 - February 11, 2012 - Recognize more cmdlets. Improve parsing. ' Version 1.4 - February 18, 2012 - Remove border, add horizontal line. ' Version 1.5 - February 23, 2012 - Replace horizontal line with gray border. ' Version 1.6 - April 27, 2012 - Add switch to omit gray border. ' ' You have a royalty-free right to use, modify, reproduce, and ' distribute this script file in any way you find useful, provided that ' you agree that the copyright owner above has no warranty, obligations, ' or liability for such use. Option Explicit Dim strInputFile, objFSO, objInput, strLine Dim strFilePath, strNewFile, objOutput, objList, k Dim strWord, strChar, strNewLine Dim blnQuote2, strQuote, strComment, blnQuote1 Dim objRE, blnHere, strHere, blnBorder Const ForReading = 1 Const ForWriting = 2 Const OpenAsASCII = 0 Const CreateIfNotExist = True ' One parameter required. If (Wscript.Arguments.Count <> 1) And (Wscript.Arguments.Count <> 2) Then Wscript.Echo "File name required" Wscript.Echo "Syntax:" Wscript.Echo "cscript //nologo PsToHtml.vbs Example.ps1" Wscript.Echo "This program will create file Example.htm" Wscript.Echo "You can also specify the optional parameter ""/nb"" to omit the gray border" Wscript.Quit End If Set objList = CreateObject("Scripting.Dictionary") objList.CompareMode = vbTextCompare ' Open the specified file of code for reading. strInputFile = Wscript.Arguments(0) Set objFSO = CreateObject("Scripting.FileSystemObject") Set objInput = objFSO.OpenTextFile(strInputFile, ForReading) blnBorder = True If (Wscript.Arguments.Count = 2) Then If (LCase(Wscript.Arguments(1)) = "/nb") Then blnBorder = False Else Wscript.Echo "If included, the second paramter must be ""/nb"", to omit the gray border" Wscript.Echo "Syntax:" Wscript.Echo "cscript //nologo PsToHtml.vbs Example.ps1 /nb" Wscript.Echo "This program will create file Example.htm" Wscript.Quit End If End If ' Determine new file name. strFilePath = objFSO.GetAbsolutePathName(strInputFile) strNewFile = objFSO.GetBaseName(strFilePath) & ".htm" ' Regular expression to recognize variables, operators, and square brackets. Set objRE = New RegExp objRE.Global = True ' Open new *.htm file for HTML. Set objOutput = objFSO.OpenTextFile(strNewFile, _ ForWriting, CreateIfNotExist, OpenAsASCII) ' Output opening paragraph tag, using fixed width font. If (blnBorder = True) Then objOutput.WriteLine "
" Else ' Output horizontal line. objOutput.WriteLine "
"
End If
' PowerShell keywords and cmdlets, to be colored blue.
objList.Add "Do", True
objList.Add "If", True
objList.Add "While", True
objList.Add "Function", True
objList.Add "Try", True
objList.Add "Catch", True
objList.Add "Finally", True
objList.Add "In", True
objList.Add "Else", True
objList.Add "For", True
objList.Add "ForEach", True
objList.Add "ForEach-Object", True
objList.Add "Where-Object", True
objList.Add "Where", True
objList.Add "Switch", True
objList.Add "Break", True
objList.Add "Continue", True
objList.Add "Param", True
objList.Add "Throw", True
objList.Add "Return", True
objList.Add "Out-Null", True
objList.Add "Out-Default", True
objList.Add "Out-Host", True
objList.Add "Out-File", True
objList.Add "Out-Printer", True
objList.Add "Out-String", True
objList.Add "Out-GridView", True
objList.Add "Invoke-WSManAction", True
objList.Add "Invoke-History", True
objList.Add "Invoke-Command", True
objList.Add "Invoke-Expression", True
objList.Add "Invoke-WmiMethod", True
objList.Add "Invoke-Item", True
objList.Add "Get-WinEvent", True
objList.Add "Get-Counter", True
objList.Add "Get-WSManCredSSP", True
objList.Add "Get-WSManInstance", True
objList.Add "Get-Command", True
objList.Add "Get-Help", True
objList.Add "Get-History", True
objList.Add "Get-PSSessionConfiguration", True
objList.Add "Get-PSSession", True
objList.Add "Get-Job", True
objList.Add "Get-Module", True
objList.Add "Get-PSSnapin", True
objList.Add "Get-FormatData", True
objList.Add "Get-Event", True
objList.Add "Get-EventSubscriber", True
objList.Add "Get-Alias", True
objList.Add "Get-Culture", True
objList.Add "Get-Date", True
objList.Add "Get-Host", True
objList.Add "Get-Member", True
objList.Add "Get-Random", True
objList.Add "Get-UICulture", True
objList.Add "Get-Unique", True
objList.Add "Get-Variable", True
objList.Add "Get-PSBreakpoint", True
objList.Add "Get-PSCallStack", True
objList.Add "Get-TraceSource", True
objList.Add "Get-EventLog", True
objList.Add "Get-ChildItem", True
objList.Add "Get-Content", True
objList.Add "Get-ItemProperty", True
objList.Add "Get-WmiObject", True
objList.Add "Get-Location", True
objList.Add "Get-PSDrive", True
objList.Add "Get-Item", True
objList.Add "Get-PSProvider", True
objList.Add "Get-Process", True
objList.Add "Get-Service", True
objList.Add "Get-Transaction", True
objList.Add "Get-HotFix", True
objList.Add "Get-ComputerRestorePoint", True
objList.Add "Get-Acl", True
objList.Add "Get-PfxCertificate", True
objList.Add "Get-Credential", True
objList.Add "Get-ExecutionPolicy", True
objList.Add "Get-AuthenticodeSignature", True
objList.Add "Get-ADAccountAuthorizationGroup", True
objList.Add "Get-ADAccountResultantPasswordReplicationPolicy", True
objList.Add "Get-ADComputer", True
objList.Add "Get-ADComputerServiceAccount", True
objList.Add "Get-ADDefaultDomainPasswordPolicy", True
objList.Add "Get-ADDomain", True
objList.Add "Get-ADDomainController", True
objList.Add "Get-ADDomainControllerPasswordReplicationPolicy", True
objList.Add "Get-ADDomainControllerPasswordReplicationPolicyUsage", True
objList.Add "Get-ADFineGrainedPasswordPolicy", True
objList.Add "Get-ADFineGrainedPasswordPolicySubject", True
objList.Add "Get-ADForest", True
objList.Add "Get-ADGroup", True
objList.Add "Get-ADGroupMember", True
objList.Add "Get-ADObject", True
objList.Add "Get-ADOptionalFeature", True
objList.Add "Get-ADOrganizationalUnit", True
objList.Add "Get-ADPrincipalGroupMembership", True
objList.Add "Get-ADRootDSE", True
objList.Add "Get-ADServiceAccount", True
objList.Add "Get-ADUser", True
objList.Add "Get-ADUserResultantPasswordPolicy", True
objList.Add "set", True
objList.Add "Set-WSManQuickConfig", True
objList.Add "Set-WSManInstance", True
objList.Add "Set-PSSessionConfiguration", True
objList.Add "Set-PSDebug", True
objList.Add "Set-StrictMode", True
objList.Add "Set-Alias", True
objList.Add "Set-Date", True
objList.Add "Set-Variable", True
objList.Add "Set-PSBreakpoint", True
objList.Add "Set-TraceSource", True
objList.Add "Set-Location", True
objList.Add "Set-Item", True
objList.Add "Set-Service", True
objList.Add "Set-Content", True
objList.Add "Set-ItemProperty", True
objList.Add "Set-WmiInstance", True
objList.Add "Set-Acl", True
objList.Add "Set-ExecutionPolicy", True
objList.Add "Set-AuthenticodeSignature", True
objList.Add "Set-ADAccountControl", True
objList.Add "Set-ADAccountExpiration", True
objList.Add "Set-ADAccountPassword", True
objList.Add "Set-ADComputer", True
objList.Add "Set-ADDefaultDomainPasswordPolicy", True
objList.Add "Set-ADDomain", True
objList.Add "Set-ADDomainMode", True
objList.Add "Set-ADFineGrainedPasswordPolicy", True
objList.Add "Set-ADForest", True
objList.Add "Set-ADForestMode", True
objList.Add "Set-ADGroup", True
objList.Add "Set-ADObject", True
objList.Add "Set-ADOrganizationalUnit", True
objList.Add "Set-ADServiceAccount", True
objList.Add "Set-ADUser", True
objList.Add "ConvertTo-Html", True
objList.Add "ConvertFrom-StringData", True
objList.Add "ConvertTo-CSV", True
objList.Add "ConvertFrom-CSV", True
objList.Add "ConvertTo-XML", True
objList.Add "Convert-Path", True
objList.Add "ConvertFrom-SecureString", True
objList.Add "ConvertTo-SecureString", True
objList.Add "select", True
objList.Add "Select-String", True
objList.Add "Select-Object", True
objList.Add "Select-XML", True
objList.Add "Read-Host", True
objList.Add "clear", True
objList.Add "Clear-History", True
objList.Add "Clear-Variable", True
objList.Add "Clear-Content", True
objList.Add "Clear-ItemProperty", True
objList.Add "Clear-EventLog", True
objList.Add "Clear-Item", True
objList.Add "Clear-ADAccountExpiration", True
objList.Add "write", True
objList.Add "Write-Host", True
objList.Add "Write-Progress", True
objList.Add "Write-Debug", True
objList.Add "Write-Verbose", True
objList.Add "Write-Warning", True
objList.Add "Write-Error", True
objList.Add "Write-Output", True
objList.Add "Write-EventLog", True
objList.Add "move", True
objList.Add "Move-ItemProperty", True
objList.Add "Move-Item", True
objList.Add "Move-ADDirectoryServer", True
objList.Add "Move-ADDirectoryServerOperationMasterRole", True
objList.Add "Move-ADObject", True
objList.Add "New-WSManInstance", True
objList.Add "New-WSManSessionOption", True
objList.Add "New-PSSession", True
objList.Add "New-PSSessionOption", True
objList.Add "New-Module", True
objList.Add "New-ModuleManifest", True
objList.Add "New-Event", True
objList.Add "New-Alias", True
objList.Add "New-TimeSpan", True
objList.Add "New-Object", True
objList.Add "New-Variable", True
objList.Add "New-EventLog", True
objList.Add "New-PSDrive", True
objList.Add "New-Item", True
objList.Add "New-ItemProperty", True
objList.Add "New-Service", True
objList.Add "New-WebServiceProxy", True
objList.Add "New-ADComputer", True
objList.Add "New-ADFineGrainedPasswordPolicy", True
objList.Add "New-ADGroup", True
objList.Add "New-ADObject", True
objList.Add "New-ADOrganizationalUnit", True
objList.Add "New-ADServiceAccount", True
objList.Add "New-ADUser", True
objList.Add "Format-List", True
objList.Add "Format-Custom", True
objList.Add "Format-Table", True
objList.Add "Format-Wide", True
objList.Add "Import-Counter", True
objList.Add "Import-Module", True
objList.Add "Import-CSV", True
objList.Add "Import-PSSession", True
objList.Add "Import-Alias", True
objList.Add "Import-LocalizedData", True
objList.Add "Import-Clixml", True
objList.Add "Export-Counter", True
objList.Add "Export-ModuleMember", True
objList.Add "Export-Console", True
objList.Add "Export-FormatData", True
objList.Add "Export-CSV", True
objList.Add "Export-Alias", True
objList.Add "Export-PSSession", True
objList.Add "Export-Clixml", True
objList.Add "compare", True
objList.Add "Compare-Object", True
objList.Add "Remove-WSManInstance", True
objList.Add "Remove-PSSession", True
objList.Add "Remove-Job", True
objList.Add "Remove-Module", True
objList.Add "Remove-PSSnapin", True
objList.Add "Remove-Event", True
objList.Add "Remove-Variable", True
objList.Add "Remove-PSBreakpoint", True
objList.Add "Remove-EventLog", True
objList.Add "Remove-PSDrive", True
objList.Add "Remove-Item", True
objList.Add "Remove-ItemProperty", True
objList.Add "Remove-WmiObject", True
objList.Add "Remove-Computer", True
objList.Add "Remove-ADComputer", True
objList.Add "Remove-ADComputerServiceAccount", True
objList.Add "Remove-ADDomainControllerPasswordReplicationPolicy", True
objList.Add "Remove-ADFineGrainedPasswordPolicy", True
objList.Add "Remove-ADFineGrainedPasswordPolicySubject", True
objList.Add "Remove-ADGroup", True
objList.Add "Remove-ADGroupMember", True
objList.Add "Remove-ADObject", True
objList.Add "Remove-ADOrganizationalUnit", True
objList.Add "Remove-ADPrincipalGroupMembership", True
objList.Add "Remove-ADServiceAccount", True
objList.Add "Remove-ADUser", True
objList.Add "copy", True
objList.Add "Copy-ItemProperty", True
objList.Add "Copy-Item", True
objList.Add "Add-History", True
objList.Add "Add-PSSnapin", True
objList.Add "Add-Member", True
objList.Add "Add-Type", True
objList.Add "Add-Content", True
objList.Add "Add-Computer", True
objList.Add "Add-ADComputerServiceAccount", True
objList.Add "Add-ADDomainControllerPasswordReplicationPolicy", True
objList.Add "Add-ADFineGrainedPasswordPolicySubject", True
objList.Add "Add-ADGroupMember", True
objList.Add "Add-ADPrincipalGroupMembership", True
objList.Add "start", True
objList.Add "Start-Job", True
objList.Add "Start-Sleep", True
objList.Add "Start-Transcript", True
objList.Add "Start-Process", True
objList.Add "Start-Service", True
objList.Add "Start-Transaction", True
objList.Add "Stop-Job", True
objList.Add "Stop-Transcript", True
objList.Add "Stop-Process", True
objList.Add "Stop-Service", True
objList.Add "Stop-Computer", True
objList.Add "Test-WSMan", True
objList.Add "Test-ModuleManifest", True
objList.Add "Test-Path", True
objList.Add "Test-Connection", True
objList.Add "Test-ComputerSecureChannel", True
objList.Add "Search-ADAccount", True
objList.Add "sort", True
objList.Add "Sort-Object", True
objList.Add "Rename-Item", True
objList.Add "Rename-ItemProperty", True
objList.Add "Rename-ADObject", True
objList.Add "Restart-Service", True
objList.Add "Restart-Computer", True
objList.Add "Register-PSSessionConfiguration", True
objList.Add "Register-ObjectEvent", True
objList.Add "Register-EngineEvent", True
objList.Add "Register-WmiEvent", True
objList.Add "Disconnect-WSMan", True
objList.Add "Connect-WSMan", True
objList.Add "Limit-EventLog", True
objList.Add "Enter-PSSession", True
objList.Add "Receive-Job", True
objList.Add "Show-EventLog", True
objList.Add "measure", True
objList.Add "Measure-Object", True
objList.Add "Measure-Command", True
objList.Add "Send-MailMessage", True
objList.Add "Tee-Object", True
objList.Add "Install-ADServiceAccount", True
' Read the code from the file.
blnHere = False
strHere = ""
Do Until objInput.AtEndOfStream
strLine = objInput.ReadLine
' Replace symbols.
strLine = Replace(strLine, "&", "&")
strLine = Replace(strLine, "<", "<")
strLine = Replace(strLine, ">", ">")
' Check for comments, quoted strings, here-strings, and keywords.
strNewLine = ""
strWord = ""
blnQuote1 = False
blnQuote2 = False
strQuote = ""
For k = 1 To Len(strLine)
strChar = Mid(strLine, k, 1)
Select Case strChar
Case "#"
' Pound sign character.
If (blnQuote2 = False) And (blnQuote1 = False) And (blnHere = False) Then
' A pound sign not in a quoted string or here-string
' indicates a comment.
' Comments always continue to the end of the line.
strComment = Mid(strLine, k)
' Replace symbols.
strComment = Replace(strComment, """", """)
strComment = Replace(strComment, "'", "'")
' Words in comments are not colorized.
If (strWord <> "") Then
strNewLine = strNewLine & strWord
End If
' Comments are colored green.
strNewLine = strNewLine & "" _
& Trim(strComment) & ""
' Ignore everything that follows on this line.
strWord = ""
Exit For
End If
If (blnHere = True) Then
' Pound sign character in here-string.
strHere = strHere & strChar
Else
' Pound sign character in quoted string.
strQuote = strQuote & strChar
End If
Case "'"
' Single quote character.
If (blnHere = True) Then
' Part of a here-string.
strHere = strHere & strChar
ElseIf (blnQuote2 = False) And (blnQuote1 = False) Then
' Start of a quoted string.
blnQuote1 = True
strQuote = strQuote & "'"
If (strWord <> "") Then
strWord = ParseTokens(strWord)
strNewLine = strNewLine & strWord
strWord = ""
End If
ElseIf (blnQuote2 = True) Then
' Single quote is part of a double quoted string.
' Treat like any other character.
strQuote = strQuote & "'"
ElseIf (blnQuote1 = True) Then
' Single quote in a single quoted string.
If (k < Len(strLine)) Then
' Check if the next character is a single quote.
If (Mid(strLine, k + 1, 1) = "'") Then
' Two single quote characters in a row.
strQuote = strQuote & "'"
' Next character, a quote, will be treated as the start
' of a quoted string, except strQuote will not be blank.
blnQuote1 = False
Else
' This terminates a string. Strings are colored red.
strQuote = strQuote & "'"
strNewLine = strNewLine & "" _
& strQuote & ""
strQuote = ""
blnQuote1 = False
strWord = ""
End If
Else
' This terminates a string. Strings are colored red.
strQuote = strQuote & "'"
strNewLine = strNewLine & "" _
& strQuote & ""
strQuote = ""
blnQuote1 = False
strWord = ""
End If
Else
' Cannot have both blnQuote1 and blnQuote2 be True.
End If
Case """"
' Double quote character.
If (blnHere = True) Then
' Part of a here-string.
strHere = strHere & strChar
ElseIf (blnQuote2 = False) And (blnQuote1 = False) Then
' Start of a quoted string.
blnQuote2 = True
strQuote = strQuote & """
If (strWord <> "") Then
strWord = ParseTokens(strWord)
strNewLine = strNewLine & strWord
strWord = ""
End If
ElseIf (blnQuote1 = True) Then
' Double quote is part of a singe quoted string.
' Treat like any other character.
strQuote = strQuote & """"
ElseIf (blnQuote2 = True) Then
' Double quote in a double quoted string.
If (k < Len(strLine)) Then
' Check if the next character is a double quote.
If (Mid(strLine, k + 1, 1) = """") Then
' Two double quote characters in a row.
strQuote = strQuote & """
' Next character, a quote, will be treated as the start
' of a quoted string, except strQuote will not be blank.
blnQuote2 = False
Else
' This terminates a string. Strings are colored red.
strQuote = strQuote & """
strNewLine = strNewLine & "" _
& strQuote & ""
strQuote = ""
blnQuote2 = False
strWord = ""
End If
Else
' This terminates a string. Strings are colored red.
strQuote = strQuote & """
strNewLine = strNewLine & "" _
& strQuote & ""
strQuote = ""
blnQuote2 = False
strWord = ""
End If
Else
' Cannot have both blnQuote1 and blnQuote2 be True.
End If
Case " ", vbTab
' Space or tab character.
If (blnHere = True) Then
' Part of a here-string.
strHere = strHere & strChar
ElseIf (blnQuote2 = True) Or (blnQuote1 = True) Then
' Space is part of the quoted string.
strQuote = strQuote & strChar
Else
' Space delimits a word. Check for keyword.
If (objList.Exists(strWord) = True) Then
' Keywords are colored blue.
strWord = "" & strWord & ""
End If
strWord = ParseTokens(strWord)
strNewLine = strNewLine & strWord & strChar
strWord = ""
End If
Case "(", "{", "|"
' Open parentheses, open brace, or pipe symbol.
If (blnHere = True) Then
' Part of a here-string.
strHere = strHere & strChar
ElseIf (blnQuote2 = True) Or (blnQuote1 = True) Then
' Part of the quoted string.
strQuote = strQuote & strChar
Else
' A keyword could start at the next character.
strWord = ParseTokens(strWord)
strNewLine = strNewLine & strWord & strChar
strWord = ""
End If
Case Else
' Any character other than single quote, double quote,
' pound sign, or space.
If (blnQuote2 = True) Or (blnQuote1 = True) Then
strQuote = strQuote & strChar
ElseIf (blnHere = True) Then
strHere = strHere & strChar
If (strChar = "@") Then
If (k > 1) Then
' Check if the previous character was a double quote.
If (Mid(strLine, k - 1, 1) = """") Then
' End of a here-string.
blnHere = False
' Here-strings are colored red.
strNewLine = strHere & ""
strHere = ""
End If
End If
End If
ElseIf (strChar = "@") Then
If (k < Len(strLine)) Then
' Check if the next character is a double quote.
If (Mid(strLine, k + 1, 1) = """") Then
' Start of a here-string.
blnHere = True
' Here-strings are colored red.
strHere = strNewLine & "" & strChar
End If
End If
If (blnHere = False) Then
strWord = strWord & strChar
End If
Else
strWord = strWord & strChar
End If
End Select
Next
If (strWord <> "") Then
If (objList.Exists(strWord) = True) Then
' Keywords are colored blue.
strWord = "" & strWord & ""
End If
strWord = ParseTokens(strWord)
strNewLine = strNewLine & strWord
End If
' Replace any tab characters with four space characters.
strNewLine = Replace(strNewLine, vbTab, " ")
' Preserve all spacing.
strNewLine = Replace(strNewLine, " ", " ")
' Preserve leading single space.
If (Left(strNewLine, 1) = " ") Then
strNewLine = " " & Mid(strNewLine, 2)
End If
If (blnHere = False) Then
' Output the line with a trailing carriage return.
objOutput.WriteLine strNewLine & "
"
Else
' Here-string continues on the next line.
strHere = strHere & "
"
End If
Loop
objInput.Close
' Output closing paragraph tag.
objOutput.WriteLine "
tag to flag this as code. objOutput.WriteLine "-----" objOutput.WriteLine "" ' Close output file. objOutput.Close ' Alert user about the new file. Wscript.Echo "File " & strNewFile & " with HTML created in the current folder" Function ParseTokens(ByVal strToken) ' Function to parse tokens. ' Variable objRE must have global scope and be Set in the main program. Dim objMatches, intStart, intLen, strLeft, strVar, strRight, j ' Equal and plus signs are colored gray. If ((strToken = "=") Or (strToken = "+")) Then strToken = "" & strToken & "" End If ' Search for variables. objRE.Pattern = "[$][a-zA-Z_:0-9]+" Set objMatches = objRE.Execute(strToken) For j = objMatches.Count To 1 Step -1 intStart = objMatches(j - 1).FirstIndex + 1 intLen = objMatches(j - 1).Length If (intStart > 1) Then strLeft = Left(strToken, intStart - 1) Else strLeft = "" End If strVar = Mid(strToken, intStart, intLen) If (Len(strToken) > intStart + intLen - 1) Then strRight = Mid(strToken, intStart + intLen) Else strRight = "" End If ' Variables are colored orange-red. strToken = strLeft & "" _ & strVar & "" & strRight Next ' Search for operators. objRE.Pattern = "^[-][a-zA-Z]+" Set objMatches = objRE.Execute(strToken) For j = objMatches.Count To 1 Step -1 intStart = objMatches(j - 1).FirstIndex + 1 intLen = objMatches(j - 1).Length If (intStart > 1) Then strLeft = Left(strToken, intStart - 1) Else strLeft = "" End If strVar = Mid(strToken, intStart, intLen) If (Len(strToken) > intStart + intLen - 1) Then strRight = Mid(strToken, intStart + intLen) Else strRight = "" End If ' Operators are colored gray. strToken = strLeft & "" _ & strVar & "" & strRight Next ' Search For text within square brackets. objRE.Pattern = "[\[][a-zA-Z]+[\]]" Set objMatches = objRE.Execute(strToken) For j = objMatches.Count To 1 Step -1 intStart = objMatches(j - 1).FirstIndex + 1 intLen = objMatches(j - 1).Length If (intStart > 1) Then strLeft = Left(strToken, intStart - 1) Else strLeft = "" End If strVar = Mid(strToken, intStart + 1, intLen - 2) If (Len(strToken) > intStart + intLen - 1) Then strRight = Mid(strToken, intStart + intLen) Else strRight = "" End If ' Text in square brackets is colored teal. ' The brackets are colored gray. strToken = strLeft & "" & "[" & "" _ & "" & strVar & "" _ & "" & "]" & "" & strRight Next ParseTokens = strToken End Function