Show-ColorizedContent.ps by Lee Holmes 17 months ago
embed code: <script type="text/javascript" src="http://PoshCode.org/embed/2223"></script>download | new post
From Windows PowerShell Cookbook (O’Reilly) by Lee Holmes
- ##############################################################################
- ##
- ## Show-ColorizedContent
- ##
- ## From Windows PowerShell Cookbook (O'Reilly)
- ## by Lee Holmes (http://www.leeholmes.com/guide)
- ##
- ##############################################################################
- <#
- .SYNOPSIS
- Displays syntax highlighting, line numbering, and range highlighting for
- PowerShell scripts.
- .EXAMPLE
- PS >Show-ColorizedContent Invoke-MyScript.ps1
- 001 | function Write-Greeting
- 002 | {
- 003 | param($greeting)
- 004 | Write-Host "$greeting World"
- 005 | }
- 006 |
- 007 | Write-Greeting "Hello"
- .EXAMPLE
- PS >Show-ColorizedContent Invoke-MyScript.ps1 -highlightRange (1..3+7)
- 001 > function Write-Greeting
- 002 > {
- 003 > param($greeting)
- 004 | Write-Host "$greeting World"
- 005 | }
- 006 |
- 007 > Write-Greeting "Hello"
- #>
- param(
- ## The path to colorize
- [Parameter(Mandatory = $true)]
- $Path,
- ## The range of lines to highlight
- $HighlightRange = @(),
- ## Switch to exclude line numbers
- [Switch] $ExcludeLineNumbers
- )
- Set-StrictMode -Version Latest
- ## Colors to use for the different script tokens.
- ## To pick your own colors:
- ## [Enum]::GetValues($host.UI.RawUI.ForegroundColor.GetType()) |
- ## Foreach-Object { Write-Host -Fore $_ "$_" }
- $replacementColours = @{
- 'Attribute' = 'DarkCyan'
- 'Command' = 'Blue'
- 'CommandArgument' = 'Magenta'
- 'CommandParameter' = 'DarkBlue'
- 'Comment' = 'DarkGreen'
- 'GroupEnd' = 'Black'
- 'GroupStart' = 'Black'
- 'Keyword' = 'DarkBlue'
- 'LineContinuation' = 'Black'
- 'LoopLabel' = 'DarkBlue'
- 'Member' = 'Black'
- 'NewLine' = 'Black'
- 'Number' = 'Magenta'
- 'Operator' = 'DarkGray'
- 'Position' = 'Black'
- 'StatementSeparator' = 'Black'
- 'String' = 'DarkRed'
- 'Type' = 'DarkCyan'
- 'Unknown' = 'Black'
- 'Variable' = 'Red'
- }
- $highlightColor = "Red"
- $highlightCharacter = ">"
- $highlightWidth = 6
- if($excludeLineNumbers) { $highlightWidth = 0 }
- ## Read the text of the file, and tokenize it
- $file = (Resolve-Path $Path).Path
- $content = [IO.File]::ReadAllText($file)
- $parsed = [System.Management.Automation.PsParser]::Tokenize(
- $content, [ref] $null) | Sort StartLine,StartColumn
- ## Write a formatted line -- in the format of:
- ## <Line Number> <Separator Character> <Text>
- function WriteFormattedLine($formatString, [int] $line)
- {
- if($excludeLineNumbers) { return }
- ## By default, write the line number in gray, and use
- ## a simple pipe as the separator
- $hColor = "DarkGray"
- $separator = "|"
- ## If we need to highlight the line, use the highlight
- ## color and highlight separator as the separator
- if($highlightRange -contains $line)
- {
- $hColor = $highlightColor
- $separator = $highlightCharacter
- }
- ## Write the formatted line
- $text = $formatString -f $line,$separator
- Write-Host -NoNewLine -Fore $hColor -Back White $text
- }
- ## Complete the current line with filler cells
- function CompleteLine($column)
- {
- ## Figure how much space is remaining
- $lineRemaining = $host.UI.RawUI.WindowSize.Width -
- $column - $highlightWidth + 1
- ## If we have less than 0 remaining, we've wrapped onto the
- ## next line. Add another buffer width worth of filler
- if($lineRemaining -lt 0)
- {
- $lineRemaining += $host.UI.RawUI.WindowSize.Width
- }
- Write-Host -NoNewLine -Back White (" " * $lineRemaining)
- }
- ## Write the first line of context information (line number,
- ## highlight character.)
- Write-Host
- WriteFormattedLine "{0:D3} {1} " 1
- ## Now, go through each of the tokens in the input
- ## script
- $column = 1
- foreach($token in $parsed)
- {
- $color = "Gray"
- ## Determine the highlighting colour for that token by looking
- ## in the hashtable that maps token types to their color
- $color = $replacementColours[[string]$token.Type]
- if(-not $color) { $color = "Gray" }
- ## If it's a newline token, write the next line of context
- ## information
- if(($token.Type -eq "NewLine") -or ($token.Type -eq "LineContinuation"))
- {
- CompleteLine $column
- WriteFormattedLine "{0:D3} {1} " ($token.StartLine + 1)
- $column = 1
- }
- else
- {
- ## Do any indenting
- if($column -lt $token.StartColumn)
- {
- $text = " " * ($token.StartColumn - $column)
- Write-Host -Back White -NoNewLine $text
- $column = $token.StartColumn
- }
- ## See where the token ends
- $tokenEnd = $token.Start + $token.Length - 1
- ## Handle the line numbering for multi-line strings and comments
- if(
- (($token.Type -eq "String") -or
- ($token.Type -eq "Comment")) -and
- ($token.EndLine -gt $token.StartLine))
- {
- ## Store which line we've started at
- $lineCounter = $token.StartLine
- ## Split the content of this token into its lines
- ## We use the start and end of the tokens to determine
- ## the position of the content, but use the content
- ## itself (rather than the token values) for manipulation.
- $stringLines = $(
- -join $content[$token.Start..$tokenEnd] -split "`n")
- ## Go through each of the lines in the content
- foreach($stringLine in $stringLines)
- {
- $stringLine = $stringLine.Trim()
- ## If we're on a new line, fill the right hand
- ## side of the line with spaces, and write the header
- ## for the new line.
- if($lineCounter -gt $token.StartLine)
- {
- CompleteLine $column
- WriteFormattedLine "{0:D3} {1} " $lineCounter
- $column = 1
- }
- ## Now write the text of the current line
- Write-Host -NoNewLine -Fore $color -Back White $stringLine
- $column += $stringLine.Length
- $lineCounter++
- }
- }
- ## Write out a regular token
- else
- {
- ## We use the start and end of the tokens to determine
- ## the position of the content, but use the content
- ## itself (rather than the token values) for manipulation.
- $text = (-join $content[$token.Start..$tokenEnd])
- Write-Host -NoNewLine -Fore $color -Back White $text
- }
- ## Update our position in the column
- $column = $token.EndColumn
- }
- }
- CompleteLine $column
- Write-Host
Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.
PowerShell Code Repository