PoshCode Logo PowerShell Code Repository

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

  1. ##############################################################################
  2. ##
  3. ## Show-ColorizedContent
  4. ##
  5. ## From Windows PowerShell Cookbook (O'Reilly)
  6. ## by Lee Holmes (http://www.leeholmes.com/guide)
  7. ##
  8. ##############################################################################
  9.  
  10. <#
  11.  
  12. .SYNOPSIS
  13.  
  14. Displays syntax highlighting, line numbering, and range highlighting for
  15. PowerShell scripts.
  16.  
  17. .EXAMPLE
  18.  
  19. PS >Show-ColorizedContent Invoke-MyScript.ps1
  20.  
  21. 001 | function Write-Greeting
  22. 002 | {
  23. 003 |     param($greeting)
  24. 004 |     Write-Host "$greeting World"
  25. 005 | }
  26. 006 |
  27. 007 | Write-Greeting "Hello"
  28.  
  29. .EXAMPLE
  30.  
  31. PS >Show-ColorizedContent Invoke-MyScript.ps1 -highlightRange (1..3+7)
  32.  
  33. 001 > function Write-Greeting
  34. 002 > {
  35. 003 >     param($greeting)
  36. 004 |     Write-Host "$greeting World"
  37. 005 | }
  38. 006 |
  39. 007 > Write-Greeting "Hello"
  40.  
  41. #>
  42.  
  43. param(
  44.     ## The path to colorize
  45.     [Parameter(Mandatory = $true)]
  46.     $Path,
  47.  
  48.     ## The range of lines to highlight
  49.     $HighlightRange = @(),
  50.  
  51.     ## Switch to exclude line numbers
  52.     [Switch] $ExcludeLineNumbers
  53. )
  54.  
  55. Set-StrictMode -Version Latest
  56.  
  57. ## Colors to use for the different script tokens.
  58. ## To pick your own colors:
  59. ## [Enum]::GetValues($host.UI.RawUI.ForegroundColor.GetType()) |
  60. ##     Foreach-Object { Write-Host -Fore $_ "$_" }
  61. $replacementColours = @{
  62.     'Attribute' = 'DarkCyan'
  63.     'Command' = 'Blue'
  64.     'CommandArgument' = 'Magenta'
  65.     'CommandParameter' = 'DarkBlue'
  66.     'Comment' = 'DarkGreen'
  67.     'GroupEnd' = 'Black'
  68.     'GroupStart' = 'Black'
  69.     'Keyword' = 'DarkBlue'
  70.     'LineContinuation' = 'Black'
  71.     'LoopLabel' = 'DarkBlue'
  72.     'Member' = 'Black'
  73.     'NewLine' = 'Black'
  74.     'Number' = 'Magenta'
  75.     'Operator' = 'DarkGray'
  76.     'Position' = 'Black'
  77.     'StatementSeparator' = 'Black'
  78.     'String' = 'DarkRed'
  79.     'Type' = 'DarkCyan'
  80.     'Unknown' = 'Black'
  81.     'Variable' = 'Red'
  82. }
  83.  
  84. $highlightColor = "Red"
  85. $highlightCharacter = ">"
  86. $highlightWidth = 6
  87. if($excludeLineNumbers) { $highlightWidth = 0 }
  88.  
  89. ## Read the text of the file, and tokenize it
  90. $file = (Resolve-Path $Path).Path
  91. $content = [IO.File]::ReadAllText($file)
  92. $parsed = [System.Management.Automation.PsParser]::Tokenize(
  93.     $content, [ref] $null) | Sort StartLine,StartColumn
  94.  
  95. ## Write a formatted line -- in the format of:
  96. ## <Line Number> <Separator Character> <Text>
  97. function WriteFormattedLine($formatString, [int] $line)
  98. {
  99.     if($excludeLineNumbers) { return }
  100.  
  101.     ## By default, write the line number in gray, and use
  102.     ## a simple pipe as the separator
  103.     $hColor = "DarkGray"
  104.     $separator = "|"
  105.  
  106.     ## If we need to highlight the line, use the highlight
  107.     ## color and highlight separator as the separator
  108.     if($highlightRange -contains $line)
  109.     {
  110.         $hColor = $highlightColor
  111.         $separator = $highlightCharacter
  112.     }
  113.  
  114.     ## Write the formatted line
  115.     $text = $formatString -f $line,$separator
  116.     Write-Host -NoNewLine -Fore $hColor -Back White $text
  117. }
  118.  
  119. ## Complete the current line with filler cells
  120. function CompleteLine($column)
  121. {
  122.     ## Figure how much space is remaining
  123.     $lineRemaining = $host.UI.RawUI.WindowSize.Width -
  124.         $column - $highlightWidth + 1
  125.  
  126.     ## If we have less than 0 remaining, we've wrapped onto the
  127.     ## next line. Add another buffer width worth of filler
  128.     if($lineRemaining -lt 0)
  129.     {
  130.         $lineRemaining += $host.UI.RawUI.WindowSize.Width
  131.     }
  132.  
  133.     Write-Host -NoNewLine -Back White (" " * $lineRemaining)
  134. }
  135.  
  136.  
  137. ## Write the first line of context information (line number,
  138. ## highlight character.)
  139. Write-Host
  140. WriteFormattedLine "{0:D3} {1} " 1
  141.  
  142. ## Now, go through each of the tokens in the input
  143. ## script
  144. $column = 1
  145. foreach($token in $parsed)
  146. {
  147.     $color = "Gray"
  148.  
  149.     ## Determine the highlighting colour for that token by looking
  150.     ## in the hashtable that maps token types to their color
  151.     $color = $replacementColours[[string]$token.Type]
  152.     if(-not $color) { $color = "Gray" }
  153.  
  154.     ## If it's a newline token, write the next line of context
  155.     ## information
  156.     if(($token.Type -eq "NewLine") -or ($token.Type -eq "LineContinuation"))
  157.     {
  158.         CompleteLine $column
  159.         WriteFormattedLine "{0:D3} {1} " ($token.StartLine + 1)
  160.         $column = 1
  161.     }
  162.     else
  163.     {
  164.         ## Do any indenting
  165.         if($column -lt $token.StartColumn)
  166.         {
  167.             $text = " " * ($token.StartColumn - $column)
  168.             Write-Host -Back White -NoNewLine $text
  169.             $column = $token.StartColumn
  170.         }
  171.  
  172.         ## See where the token ends
  173.         $tokenEnd = $token.Start + $token.Length - 1
  174.  
  175.         ## Handle the line numbering for multi-line strings and comments
  176.         if(
  177.             (($token.Type -eq "String") -or
  178.             ($token.Type -eq "Comment")) -and
  179.             ($token.EndLine -gt $token.StartLine))
  180.         {
  181.             ## Store which line we've started at
  182.             $lineCounter = $token.StartLine
  183.  
  184.             ## Split the content of this token into its lines
  185.             ## We use the start and end of the tokens to determine
  186.             ## the position of the content, but use the content
  187.             ## itself (rather than the token values) for manipulation.
  188.             $stringLines = $(
  189.                 -join $content[$token.Start..$tokenEnd] -split "`n")
  190.  
  191.             ## Go through each of the lines in the content
  192.             foreach($stringLine in $stringLines)
  193.             {
  194.                 $stringLine = $stringLine.Trim()
  195.  
  196.                 ## If we're on a new line, fill the right hand
  197.                 ## side of the line with spaces, and write the header
  198.                 ## for the new line.
  199.                 if($lineCounter -gt $token.StartLine)
  200.                 {
  201.                     CompleteLine $column
  202.                     WriteFormattedLine "{0:D3} {1} " $lineCounter
  203.                     $column = 1
  204.                 }
  205.  
  206.                 ## Now write the text of the current line
  207.                 Write-Host -NoNewLine -Fore $color -Back White $stringLine
  208.                 $column += $stringLine.Length
  209.                 $lineCounter++
  210.             }
  211.         }
  212.         ## Write out a regular token
  213.         else
  214.         {
  215.             ## We use the start and end of the tokens to determine
  216.             ## the position of the content, but use the content
  217.             ## itself (rather than the token values) for manipulation.
  218.             $text = (-join $content[$token.Start..$tokenEnd])
  219.             Write-Host -NoNewLine -Fore $color -Back White $text
  220.         }
  221.  
  222.         ## Update our position in the column
  223.         $column = $token.EndColumn
  224.     }
  225. }
  226.  
  227. CompleteLine $column
  228. 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.

Syntax highlighting:


Remember me