Write-ScriptHTML.ps1
function Write-ScriptHTML { <# .Synopsis Writes Windows PowerShell as colorized HTML .Description Outputs a Windows PowerShell script as colorized HTML. The script is wrapped in HTML PRE tags with SPAN tags defining color regions. .Example Write-ScriptHTML {Get-Process} .Link ConvertFrom-Markdown #> [CmdletBinding(DefaultParameterSetName="Text")] [OutputType([string])] param( # The Text to colorize [Parameter(Mandatory=$true, ParameterSetName="Text", Position=0, ValueFromPipeline=$true)] [Alias('ScriptContents')] [ScriptBlock]$Text, # The script as a string. [Parameter(Mandatory=$true, ParameterSetName="ScriptString", Position=0, ValueFromPipelineByPropertyName=$true)] [string]$Script, # The start within the string to colorize [Int]$Start = -1, # the end within the string to colorize [Int]$End = -1, # The palette of colors to use. # By default, the colors will be the current palette for the # Windows PowerShell Integrated Scripting Environment $Palette = $Psise.Options.TokenColors, # If set, will include the script within a span instead of a pre tag [Switch]$NoNewline, # If set, will treat help within the script as markdown [Switch]$HelpAsMarkdown, # If set, will not put a white background and padding around the script [Switch]$NoBackground ) begin { #region Color Palettes function New-ScriptPalette { param( $Attribute = "#FFADD8E6", $Command = "#FF0000FF", $CommandArgument = "#FF8A2BE2", $CommandParameter = "#FF000080", $Comment = "#FF006400", $GroupEnd = "#FF000000", $GroupStart = "#FF000000", $Keyword = "#FF00008B", $LineContinuation = "#FF000000", $LoopLabel = "#FF00008B", $Member = "#FF000000", $NewLine = "#FF000000", $Number = "#FF800080", $Operator = "#FFA9A9A9", $Position = "#FF000000", $StatementSeparator = "#FF000000", $String = "#FF8B0000", $Type = "#FF008080", $Unknown = "#FF000000", $Variable = "#FFFF4500" ) process { $NewScriptPalette= @{} foreach ($parameterName in $myInvocation.MyCommand.Parameters.Keys) { $var = Get-Variable -Name $parameterName -ErrorAction SilentlyContinue if ($var -ne $null -and $var.Value) { if ($var.Value -is [Collections.Generic.KeyValuePair[System.Management.Automation.PSTokenType,System.Windows.Media.Color]]) { $NewScriptPalette[$parameterName] = $var.Value.Value } elseif ($var.Value -as [Windows.Media.Color]) { $NewScriptPalette[$parameterName] = $var.Value -as [Windows.Media.Color] } } } $NewScriptPalette } } #endregion Color Palettes Set-StrictMode -Off Add-Type -AssemblyName PresentationCore, PresentationFramework, System.Web } process { if (-not $Palette) { $palette = @{} } if ($psCmdlet.ParameterSetName -eq 'ScriptString') { $text = [ScriptBLock]::Create($script) } if ($Text) { # # Now parse the text and report any errors... # $parse_errs = $null $tokens = [Management.Automation.PsParser]::Tokenize($text, [ref] $parse_errs) if ($parse_errs) { $parse_errs | Write-Error return } $stringBuilder = New-Object Text.StringBuilder $backgroundAndPadding = if (-not $NoBackground) { "background-color:#fefefe;padding:5px" } else { "" } $null = $stringBuilder.Append("<$(if (-not $NoNewline) {'pre'} else {'span'}) class='PowerShellColorizedScript' style='font-family:Consolas;$($backgroundAndPadding)'>") # iterate over the tokens an set the colors appropriately... $lastToken = $null $ColorPalette = New-ScriptPalette @Palette $scriptText = "$text" $c = 0 $tc = $tokens.Count foreach ($t in $tokens) { $C++ if ($c -eq $tc) { break } if ($lastToken) { $spaces = " " * ($t.Start - ($lastToken.Start + $lastToken.Length)) $null = $stringBuilder.Append($spaces) } if ($t.Type -eq "NewLine") { $null = $stringBuilder.Append(" ") } else { $chunk = $scriptText.SubString($t.start, $t.length).Trim() if ($t.Type -eq 'Comment' -and $HelpAsMarkdown) { if ($chunk -like "#*") { $chunk = $chunk.Substring(1) } $chunk = "<p>" + (ConvertFrom-Markdown -Markdown $chunk) + "</p>" } $color = $ColorPalette[$t.Type.ToString()] $redChunk = "{0:x2}" -f $color.R $greenChunk = "{0:x2}" -f $color.G $blueChunk = "{0:x2}" -f $color.B $colorChunk = "#$redChunk$greenChunk$blueChunk" $null = $stringBuilder.Append("<span style='color:$colorChunk'>$([Web.HttpUtility]::HtmlEncode($chunk).Replace('&','&').Replace('"','`"'))</span>") } $lastToken = $t } $null = $stringBuilder.Append("</$(if (-not $NoNewline) {'pre'} else {'span'})>") $stringBuilder.ToString() } } } |