PoshCode Logo PowerShell Code Repository

Highlight-Syntax 2.0 by Jeff Hillman 4 years ago (modification of post by Jeff Hillman view diff)
View followups from Chris | diff | embed code: <script type="text/javascript" src="http://PoshCode.org/embed/101"></script>download | new post

This script uses the System.Management.Automation.PsParser class to highlight PowerShell syntax with HTML.

  1. #requires -version 2.0
  2.  
  3. # Highlight-Syntax.ps1
  4. # version 2.0
  5. # by Jeff Hillman
  6. #
  7. # this script uses the System.Management.Automation.PsParser class
  8. # to highlight PowerShell syntax with HTML.
  9.  
  10. param( [string] $code, [switch] $LineNumbers )
  11.  
  12. if ( Test-Path $code -ErrorAction SilentlyContinue )
  13. {
  14.     $code = Get-Content $code | Out-String
  15. }
  16.  
  17. $backgroundColor = "#DDDDDD"
  18. $foregroundColor = "#000000"
  19. $lineNumberColor = "#404040"
  20.  
  21. $PSTokenType = [System.Management.Automation.PSTokenType]
  22.  
  23. $colorHash = @{
  24. #    $PSTokenType::Unknown            = $foregroundColor;
  25.     $PSTokenType::Command            = "#C86400";
  26. #    $PSTokenType::CommandParameter   = $foregroundColor;
  27. #    $PSTokenType::CommandArgument    = $foregroundColor;
  28.     $PSTokenType::Number             = "#800000";
  29.     $PSTokenType::String             = "#800000";
  30.     $PSTokenType::Variable           = "#000080";
  31. #    $PSTokenType::Member             = $foregroundColor;
  32. #    $PSTokenType::LoopLabel          = $foregroundColor;
  33. #    $PSTokenType::Attribute          = $foregroundColor;
  34.     $PSTokenType::Type               = "#404040";
  35.     $PSTokenType::Operator           = "#C86400";
  36. #    $PSTokenType::GroupStart         = $foregroundColor;
  37. #    $PSTokenType::GroupEnd           = $foregroundColor;
  38.     $PSTokenType::Keyword            = "#C86400";
  39.     $PSTokenType::Comment            = "#008000";
  40.     $PSTokenType::StatementSeparator = "#C86400";
  41. #    $PSTokenType::NewLine            = $foregroundColor;
  42.     $PSTokenType::LineContinuation   = "#C86400";
  43. #    $PSTokenType::Position           = $foregroundColor;
  44.    
  45. }
  46.  
  47. filter Html-Encode
  48. {
  49.     $_ = $_ -replace "&", "&amp;"
  50.     $_ = $_ -replace " ", "&nbsp;"
  51.     $_ = $_ -replace "<", "&lt;"
  52.     $_ = $_ -replace ">", "&gt;"
  53.  
  54.     $_
  55. }
  56.  
  57. # replace the tabs with spaces
  58. $code = $code -replace "\t", ( " " * 4 )
  59.  
  60. if ( $LineNumbers )
  61. {
  62.     $highlightedCode = "<li style='color: $lineNumberColor; padding-left: 5px'>"
  63. }
  64. else
  65. {
  66.     $highlightedCode = ""
  67. }
  68.  
  69. $parser = [System.Management.Automation.PsParser]
  70. $lastColumn = 1
  71. $lineCount = 1
  72.  
  73. foreach ( $token in $parser::Tokenize( $code, [ref] $null ) | Sort-Object StartLine, StartColumn )
  74. {
  75.     # get the color based on the type of the token
  76.     $color = $colorHash[ $token.Type ]
  77.    
  78.     if ( $color -eq $null )
  79.     {
  80.         $color = $foregroundColor
  81.     }
  82.  
  83.     # add whitespace
  84.     if ( $lastColumn -lt $token.StartColumn )
  85.     {
  86.         $highlightedCode += ( "&nbsp;" * ( $token.StartColumn - $lastColumn ) )
  87.     }
  88.  
  89.     switch ( $token.Type )
  90.     {
  91.         $PSTokenType::String {
  92.             $string = "<span style='color: {0}'>{1}</span>" -f $color,
  93.                 ( $code.SubString( $token.Start, $token.Length ) | Html-Encode )
  94.  
  95.             # we have to highlight each piece of multi-line strings
  96.             if ( $string -match "\r\n" )
  97.             {
  98.                 # highlight any line continuation characters as operators
  99.                 $string = $string -replace "(``)(?=\r\n)",
  100.                     ( "<span style='color: {0}'>``</span>" -f $colorHash[ $PSTokenType::Operator ] )
  101.  
  102.                 $stringHtml = "</span><br />`r`n"
  103.                
  104.                 if ( $LineNumbers )
  105.                 {
  106.                      $stringHtml += "<li style='color: $lineNumberColor; padding-left: 5px'>"
  107.                 }
  108.  
  109.                 $stringHtml += "<span style='color: $color'>"
  110.  
  111.                 $string = $string -replace "\r\n", $stringHtml
  112.             }
  113.  
  114.             $highlightedCode += $string
  115.             break
  116.         }
  117.  
  118.         $PSTokenType::NewLine {
  119.             $highlightedCode += "<br />`r`n"
  120.            
  121.             if ( $LineNumbers )
  122.             {
  123.                 $highlightedCode += "<li style='color: $lineNumberColor; padding-left: 5px'>"
  124.             }
  125.            
  126.             $lastColumn = 1
  127.             ++$lineCount
  128.             break
  129.         }
  130.  
  131.         default {
  132.             if ( $token.Type -eq $PSTokenType::LineContinuation )
  133.             {
  134.                 $lastColumn = 1
  135.                 ++$lineCount
  136.             }
  137.  
  138.             $highlightedCode += "<span style='color: {0}'>{1}</span>" -f $color,
  139.                 ( $code.SubString( $token.Start, $token.Length ) | Html-Encode )
  140.         }
  141.     }
  142.  
  143.     $lastColumn = $token.EndColumn
  144. }
  145.  
  146. # put the highlighted code in the pipeline
  147. "<div style='width: 100%; " +
  148.             "/*height: 100%;*/ " +
  149.             "overflow: auto; " +
  150.             "font-family: Consolas, `"Courier New`", Courier, mono; " +
  151.             "font-size: 12px; " +
  152.             "background-color: $backgroundColor; " +
  153.             "color: $foregroundColor; " +
  154.             "padding: 2px 2px 2px 2px; white-space: nowrap'>"
  155.  
  156. if ( $LineNumbers )
  157. {
  158.     $digitCount =  $lineCount.ToString().Length
  159.  
  160.     "<ol start='1' style='border-left: " +
  161.                          "solid 1px $lineNumberColor; " +
  162.                          "margin-left: $( ( $digitCount * 10 ) + 15 )px; " +
  163.                          "padding: 0px;'>"
  164. }
  165.  
  166. $highlightedCode
  167.  
  168. if ( $LineNumbers )
  169. {
  170.     "</ol>"
  171. }
  172.  
  173. "</div>"

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