PipeScript.format.ps1xml
<?xml version="1.0" encoding="utf-16"?> <!-- Generated with EZOut 1.9.6: Install-Module EZOut or https://github.com/StartAutomating/EZOut --> <Configuration> <Controls> <Control> <Name>PSToken</Name> <CustomControl> <CustomEntries> <CustomEntry> <CustomItem> <ExpressionBinding> <ItemSelectionCondition> <ScriptBlock> $_.PreviousToken -and $_.Text </ScriptBlock> </ItemSelectionCondition> <ScriptBlock> $token = $_ $prevEnd = $_.PreviousToken.Start + $_.PreviousToken.Length $substring = $_.Text.Substring($prevEnd, $token.Start - $prevEnd) if ($substring) { $substring} else { '' } </ScriptBlock> </ExpressionBinding> <ExpressionBinding> <ScriptBlock>$moduleName = 'PipeScript' do { $lm = Get-Module -Name $moduleName -ErrorAction Ignore if (-not $lm) { continue } if ($lm.FormatPartsLoaded) { break } $wholeScript = @(foreach ($formatFilePath in $lm.exportedFormatFiles) { foreach ($partNodeName in Select-Xml -LiteralPath $formatFilePath -XPath "/Configuration/Controls/Control/Name[starts-with(., '$')]") { $ParentNode = $partNodeName.Node.ParentNode "$($ParentNode.Name)={ $($ParentNode.CustomControl.CustomEntries.CustomEntry.CustomItem.ExpressionBinding.ScriptBlock)}" } }) -join [Environment]::NewLine New-Module -Name "${ModuleName}.format.ps1xml" -ScriptBlock ([ScriptBlock]::Create(($wholeScript + ';Export-ModuleMember -Variable *'))) | Import-Module -Global $onRemove = [ScriptBlock]::Create("Remove-Module '${ModuleName}.format.ps1xml'") if (-not $lm.OnRemove) { $lm.OnRemove = $onRemove } else { $lm.OnRemove = [ScriptBlock]::Create($onRemove.ToString() + '' + [Environment]::NewLine + $lm.OnRemove) } $lm | Add-Member NoteProperty FormatPartsLoaded $true -Force } while ($false) @(& ${PipeScript_Format-RichText} -ForegroundColor 'Success' -NoClear) -join ''</ScriptBlock> </ExpressionBinding> <ExpressionBinding> <ItemSelectionCondition> <ScriptBlock> $_.Type -eq 'Comment' </ScriptBlock> </ItemSelectionCondition> <PropertyName>Content</PropertyName> </ExpressionBinding> <ExpressionBinding> <ScriptBlock>@(& ${PipeScript_Format-RichText} -ForegroundColor 'Success' ) -join ''</ScriptBlock> </ExpressionBinding> <ExpressionBinding> <ScriptBlock>@(& ${PipeScript_Format-RichText} -ForegroundColor 'Verbose' -NoClear) -join ''</ScriptBlock> </ExpressionBinding> <ExpressionBinding> <ItemSelectionCondition> <ScriptBlock> $_.Type -in 'Keyword', 'String', 'CommandArgument' </ScriptBlock> </ItemSelectionCondition> <PropertyName>Content</PropertyName> </ExpressionBinding> <ExpressionBinding> <ScriptBlock>@(& ${PipeScript_Format-RichText} -ForegroundColor 'Verbose' ) -join ''</ScriptBlock> </ExpressionBinding> <ExpressionBinding> <ScriptBlock>@(& ${PipeScript_Format-RichText} -ForegroundColor 'Warning' -NoClear) -join ''</ScriptBlock> </ExpressionBinding> <ExpressionBinding> <ItemSelectionCondition> <ScriptBlock> $_.Type -in 'Variable', 'Command' </ScriptBlock> </ItemSelectionCondition> <PropertyName>Content</PropertyName> </ExpressionBinding> <ExpressionBinding> <ScriptBlock>@(& ${PipeScript_Format-RichText} -ForegroundColor 'Warning' ) -join ''</ScriptBlock> </ExpressionBinding> <ExpressionBinding> <ScriptBlock>@(& ${PipeScript_Format-RichText} -ForegroundColor 'Magenta' -NoClear) -join ''</ScriptBlock> </ExpressionBinding> <ExpressionBinding> <ItemSelectionCondition> <ScriptBlock> $_.Type -in 'CommandParameter' </ScriptBlock> </ItemSelectionCondition> <PropertyName>Content</PropertyName> </ExpressionBinding> <ExpressionBinding> <ScriptBlock>@(& ${PipeScript_Format-RichText} -ForegroundColor 'Magenta' ) -join ''</ScriptBlock> </ExpressionBinding> <ExpressionBinding> <ScriptBlock>@(& ${PipeScript_Format-RichText} -ForegroundColor 'Magenta' -NoClear) -join ''</ScriptBlock> </ExpressionBinding> <ExpressionBinding> <ItemSelectionCondition> <ScriptBlock> $_.Type -in 'Operator','GroupStart', 'GroupEnd' </ScriptBlock> </ItemSelectionCondition> <PropertyName>Content</PropertyName> </ExpressionBinding> <ExpressionBinding> <ScriptBlock>@(& ${PipeScript_Format-RichText} -ForegroundColor 'Magenta' ) -join ''</ScriptBlock> </ExpressionBinding> <ExpressionBinding> <ItemSelectionCondition> <ScriptBlock> $_.Type -notin 'Comment', 'Keyword', 'String', 'CommandArgument', 'Variable', 'Command', 'CommandParameter', 'Operator','GroupStart', 'GroupEnd' </ScriptBlock> </ItemSelectionCondition> <PropertyName>Content</PropertyName> </ExpressionBinding> </CustomItem> </CustomEntry> </CustomEntries> </CustomControl> </Control> <Control> <Name>${PipeScript_Format-RichText}</Name> <CustomControl> <CustomEntries> <CustomEntry> <CustomItem> <ExpressionBinding> <ScriptBlock> <# .Synopsis Formats the text color of output .Description Formats the text color of output * ForegroundColor * BackgroundColor * Bold * Underline .Notes Stylized Output works in two contexts at present: * Rich consoles (Windows Terminal, PowerShell.exe, Pwsh.exe) (when $host.UI.SupportsVirtualTerminal) * Web pages (Based off the presence of a $Request variable, or when $host.UI.SupportsHTML (you must add this property to $host.UI)) #> [Management.Automation.Cmdlet("Format","Object")] [ValidateScript({ $canUseANSI = $host.UI.SupportsVirtualTerminal $canUseHTML = $Request -or $host.UI.SupportsHTML -or $OutputMode -eq 'HTML' if (-not ($canUseANSI -or $canUseHTML)) { return $false} return $true })] param( # The input object [Parameter(ValueFromPipeline)] [PSObject] $InputObject, # The foreground color [string]$ForegroundColor, # The background color [string]$BackgroundColor, # If set, will render as bold [switch]$Bold, # If set, will render as italic. [Alias('Italics')] [switch]$Italic, # If set, will render as faint [switch]$Faint, # If set, will render as hidden text. [switch]$Hide, # If set, will render as blinking (not supported in all terminals or HTML) [switch]$Blink, # If set, will render as strikethru [Alias('Strikethrough', 'Crossout')] [switch]$Strikethru, # If set, will underline text [switch]$Underline, # If set, will double underline text. [switch]$DoubleUnderline, # If set, will invert text [switch]$Invert, # If set, will not clear formatting [switch]$NoClear ) begin { $canUseANSI = $host.UI.SupportsVirtualTerminal $canUseHTML = $Request -or $host.UI.SupportsHTML -or $OutputMode -eq 'HTML' $knownStreams = @{ Output='';Error='BrightRed';Warning='BrightYellow'; Verbose='BrightCyan';Debug='Yellow';Progress='Cyan'; Success='BrightGreen';Failure='Red';Default=''} $esc = [char]0x1b $standardColors = 'Black', 'Red', 'Green', 'Yellow', 'Blue','Magenta', 'Cyan', 'White' $brightColors = 'BrightBlack', 'BrightRed', 'BrightGreen', 'BrightYellow', 'BrightBlue','BrightMagenta', 'BrightCyan', 'BrightWhite' $n =0 $cssClasses = @() $styleAttributes = @(:nextColor foreach ($hc in $ForegroundColor,$BackgroundColor) { $n++ if (-not $hc) { continue } if ($hc[0] -eq $esc) { if ($canUseANSI) { $hc; continue } } $ansiStartPoint = if ($n -eq 1) { 30 } else { 40 } if ($knownStreams.ContainsKey($hc)) { $i = $brightColors.IndexOf($knownStreams[$hc]) if ($canUseHTML) { $cssClasses += $hc } else { if ($i -ge 0 -and $canUseANSI) { '' + $esc + "[1;$($ansiStartPoint + $i)m" } else { $i = $standardColors.IndexOf($knownStreams[$hc]) if ($i -ge 0 -and $canUseANSI) { '' + $esc + "[1;$($ansiStartPoint + $i)m" } elseif ($i -le 0 -and $canUseANSI) { '' + $esc + "[$($ansistartpoint + 8):5m" } } } continue nextColor } elseif ($standardColors -contains $hc) { for ($i = 0; $i -lt $standardColors.Count;$i++) { if ($standardColors[$i] -eq $hc) { if ($canUseANSI -and -not $canUseHTML) { '' + $esc + "[$($ansiStartPoint + $i)m" } else { $cssClasses += $standardColors[$i] } continue nextColor } } } elseif ($brightColors -contains $hc) { for ($i = 0; $i -lt $brightColors.Count;$i++) { if ($brightColors[$i] -eq $hc) { if ($canUseANSI -and -not $canUseHTML) { '' + $esc + "[1;$($ansiStartPoint + $i)m" } else { $cssClasses += $standardColors[$i] } continue nextColor } } } elseif ($psStyle -and $psStyle.Formatting.$hc -and $psStyle.Formatting.$hc -match '^\e') { if ($canUseANSI -and -not $canUseHTML) { $psStyle.Formatting.$hc } else { $cssClasses += "formatting-$hc" } } elseif (-not $n -and $psStyle -and $psStyle.Foreground.$hc -and $psStyle.Foreground.$hc -match '^\e' ) { if ($canUseANSI -and -not $canUseHTML) { $psStyle.Foreground.$hc } else { $cssClasses += "foreground-$hc" } } elseif ($n -and $psStyle -and $psStyle.Background.$hc -and $psStyle.Background.$hc -match '^\e') { if ($canUseANSI -and -not $canUseHTML) { $psStyle.Background.$hc } else { $cssClasses += "background-$hc" } } if ($hc -and $hc -notmatch '^[\#\e]') { $placesToLook= @(if ($hc.Contains('.')) { $module, $setting = $hc -split '\.', 2 $theModule = Get-Module $module $theModule.PrivateData.Color, $theModule.PrivateData.Colors, $theModule.PrivateData.Colour, $theModule.PrivateData.Colours, $theModule.PrivateData.EZOut, $global:PSColors, $global:PSColours } else { $setting = $hc $moduleColorSetting = $theModule.PrivateData.PSColors.$setting }) foreach ($place in $placesToLook) { if (-not $place) { continue } foreach ($propName in $setting -split '\.') { $place = $place.$propName if (-not $place) { break } } if ($place -and "$place".StartsWith('#') -and 4,7 -contains "$place".Length) { $hc = $place continue } } if (-not $hc.StartsWith -or -not $hc.StartsWith('#')) { continue } } $r,$g,$b = if ($hc.Length -eq 7) { [int]::Parse($hc[1..2]-join'', 'HexNumber') [int]::Parse($hc[3..4]-join '', 'HexNumber') [int]::Parse($hc[5..6] -join'', 'HexNumber') }elseif ($hc.Length -eq 4) { [int]::Parse($hc[1], 'HexNumber') * 16 [int]::Parse($hc[2], 'HexNumber') * 16 [int]::Parse($hc[3], 'HexNumber') * 16 } if ($canUseHTML) { if ($n -eq 1) { "color:$hc" } elseif ($n -eq 2) { "background-color:$hc"} } elseif ($canUseANSI) { if ($n -eq 1) { $esc+"[38;2;$r;$g;${b}m" } elseif ($n -eq 2) { $esc+"[48;2;$r;$g;${b}m" } } }) $styleAttributes += @( if ($Bold) { if ($canUseHTML) {"font-weight:bold"} elseif ($canUseANSI) { '' + $esc + "[1m" } } if ($Faint) { if ($canUseHTML) { "opacity:.5" } elseif ($canUseANSI) { '' + $esc + "[2m" } } if ($Italic) { if ($canUseHTML) { "font-weight:bold" } elseif ($canUseANSI) {'' + $esc + "[3m" } } if ($Underline -and -not $doubleUnderline) { if ($canUseHTML) { "text-decoration:underline"} elseif ($canUseANSI) {'' +$esc + "[4m" } } if ($Blink) { if ($canUseANSI) { '' +$esc + "[5m" } } if ($invert) { if ($canUseHTML) {"filter:invert(100%)"} elseif ($canUseANSI) { '' + $esc + "[7m"} } if ($hide) { if ($canUseHTML) {"opacity:0"} elseif ($canUseANSI) { '' + $esc + "[8m"} } if ($Strikethru) { if ($canUseHTML) {"text-decoration: line-through"} elseif ($canUseANSI) { '' +$esc + "[9m" } } if ($DoubleUnderline) { if ($canUseHTML) { "border-bottom: 3px double;"} elseif ($canUseANSI) {'' +$esc + "[21m" } } ) $header = if ($canUseHTML) { "<span$( if ($styleAttributes) { " style='$($styleAttributes -join ';')'"} )$( if ($cssClasses) { " class='$($cssClasses -join ' ')'"} )>" } elseif ($canUseANSI) { $styleAttributes -join '' } } process { if ($header) { "$header" + "$(if ($inputObject) { $inputObject | Out-String})".Trim() } elseif ($inputObject) { ($inputObject | Out-String).Trim() } } end { if (-not $NoClear) { if ($canUseHTML) { "</span>" } elseif ($canUseANSI) { if ($Bold -or $Faint) { "$esc[22m" } if ($Italic) { "$esc[23m" } if ($Underline -or $doubleUnderline) { "$esc[24m" } if ($Blink) { "$esc[25m" } if ($Invert) { "$esc[27m" } if ($hide) { "$esc[28m" } if ($Strikethru) { "$esc[29m" } if ($ForegroundColor) { "$esc[39m" } if ($BackgroundColor) { "$esc[49m" } if (-not ($Underline -or $Bold -or $Invert -or $ForegroundColor -or $BackgroundColor)) { '' + $esc + '[0m' } } } } </ScriptBlock> </ExpressionBinding> </CustomItem> </CustomEntry> </CustomEntries> </CustomControl> </Control> <Control> <Name>${PipeScript_Format-Hashtable}</Name> <CustomControl> <CustomEntries> <CustomEntry> <CustomItem> <ExpressionBinding> <ScriptBlock> <# .Synopsis Takes an creates a script to recreate a hashtable .Description Allows you to take a hashtable and create a hashtable you would embed into a script. Handles nested hashtables and indents nested hashtables automatically. .Example # Corrects the presentation of a PowerShell hashtable [Ordered]@{Foo='Bar';Baz='Bing';Boo=@{Bam='Blang'}} | Format-Hashtable .Outputs [string] .Outputs [ScriptBlock] .Link about_hash_tables #> [OutputType([string], [ScriptBlock])] [Management.Automation.Cmdlet("Format", "Object")] [ValidateScript({return $true})] param( # The hashtable or PSObject that will be written as a PowerShell Hashtable [Parameter(Position=0,ValueFromPipeline,ValueFromPipelineByPropertyName)] [PSObject] $InputObject, # Returns the content as a script block, rather than a string [switch]$AsScriptBlock, # If set, will return the hashtable and all nested hashtables as custom objects. [switch]$AsPSObject, # If set, items in the hashtable will be sorted alphabetically [Switch]$Sort, # If set, credentials will be expanded out into a hashtable containing the username and password. [Switch]$ExpandCredential, # If set, the outputted hashtable will not contain any extra whitespace. [switch]$Compress, # If set, will embed ScriptBlocks as literal strings, # so that the resulting hashtable could work in data language mode. [switch]$Safe, # The maximum depth to enumerate. # Beneath this depth, items will simply be returned as $null. [int]$Depth ) begin { $myCmd = $MyInvocation.MyCommand $myScriptBlock = $myCmd.ScriptBlock } process { if (-not $Compress) { $psCallstack = @(Get-PSCallStack) $callstack = @(foreach ($cs in $psCallstack) { if ($cs.InvocationInfo.MyCommand.ScriptBlock -eq $myCmd.ScriptBlock) { $cs } }) } else { $callstack = @() } $myParams = @{} + $PSBoundParameters $myParams.Remove('InputObject') $CurrentDepth = $callStack.Count if ($Depth -and $CurrentDepth -gt $Depth) { return '$null' } if ($inputObject -and $inputObject -isnot [Collections.IDictionary] -and $inputObject -isnot [string] -and (-not $InputObject.GetType().IsPrimitive) -and $InputObject -isnot [Enum] ) { $newInputObject = [Ordered]@{ PSTypeName=@($inputobject.pstypenames)[0] } if ('System.Object', 'System.Management.Automation.PSCustomObject' -contains $newInputObject.pstypename) { $newInputObject.Remove('PSTypeName') } foreach ($prop in $inputObject.psobject.properties) { $newInputObject[$prop.Name] = $prop.Value } $inputObject = $newInputObject } $scriptString = "" if ($inputObject -is [Collections.IDictionary]) { #region Indent $indent = $CurrentDepth * 4 $scriptString+= if ($Compress) { "@{" } else { "@{ " } #endregion Indent #region Include $items = $inputObject.GetEnumerator() if ($Sort) { $items = $items | Sort-Object Key } foreach ($kv in $items) { if (-not $Compress) { $scriptString+=" " * $indent } if ($kv.Key -eq 'keywords') { $null = $null } $keyString = "$($kv.Key)" if ($keyString.IndexOfAny(" _.#-+:;()'!?^@#$%&=|".ToCharArray()) -ne -1) { if ($keyString.IndexOf("'") -ne -1) { $scriptString+="'$($keyString.Replace("'","''"))' = " } else { $scriptString+="'$keyString' = " } } elseif ($keyString) { $scriptString+="$keyString = " } $value = $kv.Value $value = if ($value -is [string]) { "'" + $value.Replace("'","''").Replace("’", "’’").Replace("‘", "‘‘") + "'" } elseif ( $value -is [ScriptBlock] -or $value -is [Management.Automation.Language.Ast] ) { if ($safe) { "@'" + [Environment]::NewLine + $value [Environment]::NewLine + "'@'" } else { "{$value}" } } elseif ($value -is [switch]) { if ($value) { '$true' } else { '$false' } } elseif ($value -is [DateTime]) { "[DateTime]'$($value.ToString("o"))'" } elseif ($value -is [Timespan]) { if ($Safe) { "'$($value.ToString())'" } else { "[Timespan]'$($value.ToString())'" } } elseif ($value -is [bool]) { if ($value) { '$true'} else { '$false' } } elseif ($value -and $value.GetType -and ( $value.GetType().IsArray -or $value -is [Collections.IList] -or ($value -is [Collections.IEnumerable] -and $value -isnot [Collections.IDictionary]) )) { $joiner = if ($Compress) { ',' } else { "," + [Environment]::NewLine + (' ' * ($indent + 4)) } @(foreach ($v in $value) { if ($v -is [Collections.IDictionary]) { & $myScriptBlock -InputObject $v @myParams } elseif ($v -is [ScriptBlock] -or $v -is [Management.Automation.Language.Ast]) { if ($Safe) { } else { "{$v}" } } elseif ($v -is [Object] -and $v -isnot [string]) { & $myScriptBlock -InputObject $v @myParams } elseif ($v -is [bool] -or $v -is [switch]) { "`$$v" } elseif ($null -ne ($v -as [float])) { $v } else { ("'" + "$v".Replace("'","''").Replace("’", "’’").Replace("‘", "‘‘") + "'") } }) -join $joiner } elseif ($value -as [Collections.IDictionary[]]) { @(foreach ($v in $value) { & $myScriptBlock $v @myParams }) -join "," } elseif ($value -is [Collections.IDictionary]) { "$(& $myScriptBlock $value @myParams)" } elseif ($value -as [Double]) { "$value" } elseif ($value -is [Management.Automation.PSCredential] -and $ExpandCredential) { & $myScriptBlock -InputObject ([Ordered]@{ Username = $value.Username Password = $value.GetNetworkCredential().Password }) @myParams } else { $valueString = "'$($value -replace "'", "''")'" if ($valueString[0] -eq "'" -and $valueString[1] -eq "@" -and $valueString[2] -eq "{") { & $myScriptBlock -InputObject $value @myParams } else { $valueString } } $scriptString+= if ($Compress) { "$value;" } else { "$value" + [Environment]::NewLine } } if (-not $Compress) { $scriptString += " " * ($CurrentDepth - 1) * 4 } $scriptString += "}" if ($AsPSObject -and -not $Safe) { $scriptString = "[PSCustomObject][Ordered]$ScriptString" } #endregion Include } elseif ($InputObject -is [string]) { $scriptString = "'" + $InputObject.Replace("'", "''") + "'" } elseif ( $InputObject.GetType -and $InputObject.GetType().IsPrimitive ) { $scriptString += "$inputObject" } elseif ($inputObject -is [Enum]) { $scriptString = if ($safe) { "'" + $InputObject.ToString().Replace("'", "''") + "'" } else { "[$($InputObject.GetType().FullName -replace '^System\.')]" + "'" + $InputObject.ToString().Replace("'", "''") + "'" } } elseif (-not $inputObject) { $scriptString += '$null' } if ($AsScriptBlock) { [ScriptBlock]::Create($scriptString) } else { $scriptString } } </ScriptBlock> </ExpressionBinding> </CustomItem> </CustomEntry> </CustomEntries> </CustomControl> </Control> <Control> <Name>${PipeScript_Format-Markdown}</Name> <CustomControl> <CustomEntries> <CustomEntry> <CustomItem> <ExpressionBinding> <ScriptBlock> <# .SYNOPSIS Formats an object as Markdown .DESCRIPTION Formats an object as Markdown, with many options to work with .EXAMPLE Format-Markdown -ScriptBlock { Get-Process } .EXAMPLE 1..6 | Format-Markdown -HeadingSize { $_ } #> [Management.Automation.Cmdlet("Format","Object")] [ValidateScript({return $true})] param( [Parameter(ValueFromPipeline,ValueFromPipelineByPropertyName)] [PSObject] $InputObject, # If set, will treat the -InputObject as a paragraph. # This is the default for strings, booleans, numbers, and other primitive types. [Parameter(ValueFromPipelineByPropertyName)] [switch] $MarkdownParagraph, # If set, will generate a markdown table. [Parameter(ValueFromPipelineByPropertyName)] [switch] $MarkdownTable, # If provided, will align columnns in a markdown table. [Parameter(ValueFromPipelineByPropertyName)] [ValidateSet("Left","Right","Center", "")] [string[]] $MarkdownTableAlignment, # An array of properties. Providing this implies -MarkdownTable [Parameter(ValueFromPipelineByPropertyName)] [PSObject[]] $Property, # A heading. # If provided without -HeadingSize, -HeadingSize will default to 2. # If provided with -InputObject, -Heading will take priority. [Parameter(ValueFromPipelineByPropertyName)] [string] $Heading, # The heading size (1-6) # If provided without -Heading, the -InputObject will be considered to be a heading. [Parameter(ValueFromPipelineByPropertyName)] [ValidateRange(1,6)] [int] $HeadingSize, # If set, will create a link. The -InputObject will be used as the link content [Parameter(ValueFromPipelineByPropertyName)] [string] $Link, # If set, will create an image link. The -Inputobject will be used as the link content. [Parameter(ValueFromPipelineByPropertyName)] [string] $ImageLink, # If set, will generate a bullet point list. [Parameter(ValueFromPipelineByPropertyName)] [Alias('BulletpointList')] [switch] $BulletPoint, # If set, bullet or numbered list items will have a checkbox. # Each piped -InputObject will be an additional list item. [Parameter(ValueFromPipelineByPropertyName)] [switch] $Checkbox, # If set, bullet or numbered list items will be checked. [Parameter(ValueFromPipelineByPropertyName)] [switch] $Checked, # If set, will generate a numbered list. # Each piped -InputObject will be an additional list item. [Parameter(ValueFromPipelineByPropertyName)] [switch] $NumberedList, # If set, will generate a block quote. # Each line of the -InputObject will be block quoted. [Parameter(ValueFromPipelineByPropertyName)] [switch] $BlockQuote, # If set, will generate a block quote of a particular depth. # Each line of the -InputObject will be block quoted. [Parameter(ValueFromPipelineByPropertyName)] [ValidateRange(1,3)] [int] $BlockQuoteDepth, # If provided, will create a markdown numbered list with this particular item as the number. [Parameter(ValueFromPipelineByPropertyName)] [int] $Number, # If set, will generate a horizontal rule. # If other parameters are provided, the horiztonal rule will be placed after. [Parameter(ValueFromPipelineByPropertyName)] [switch] $HorizontalRule, # If set, will output the -InputObject as a Markdown code block [Parameter(ValueFromPipelineByPropertyName)] [switch] $Code, # If set, will output the -InputObject as a Markdown code block, with a given language # If the -InputObject is a ScriptBlock, -CodeLanguage will be set to PowerShell. [Parameter(ValueFromPipelineByPropertyName)] [string] $CodeLanguage, # If provided, will output a script block as a Markdown code block. [Parameter(ValueFromPipelineByPropertyName)] [ScriptBlock] $ScriptBlock ) begin { $numberedListCounter = 0 $IsFirst = $true filter LinkInput { $in = $_ if ($ImageLink) { "![$in]($imageLink)" } elseif ($link) { "[$in]($link)" } else { "$in" } } $markdownLines = @() } process { if ($ScriptBlock -or $inputObject -is [scriptblock]) { # If a -ScriptBlock was provided $CodeLanguage = 'PowerShell' # use PowerShell as a Code Language. } # If a -HeadingSize or a -Heading were provided, render a heading. if ($HeadingSize -or $Heading) { if (-not $HeadingSize) { $HeadingSize = 2} # If the -HeadingSize was not set, set it to 2. $headingContent = "$(if ($Heading) { $Heading} else { $inputObject | LinkInput})" $markdownLines += if ($HeadingSize -eq 1) { $headingContent '=' * [Math]::Max($headingContent.Length, 3) } elseif ($HeadingSize -eq 2) { $headingContent '-' * [Math]::Max($headingContent.Length, 3) } else { ("#"*$HeadingSize) + " $headingContent" # Output the -Heading or the -InputObject. } } # If -Code or -CodeLanguage was provided, render a Markdown code block. elseif ($Code -or $CodeLanguage) { # If the -InputObject was a [ScriptBlock] or there is a -ScriptBlock if ($InputObject -is [scriptblock] -or $ScriptBlock) { $CodeLanguage = 'PowerShell' # set the code language to PowerShell. } $markdownLines += ( '```' + # Start the code fence, $(if ($CodeLanguage) { $CodeLanguage}) + # add the language, [Environment]::newline + # then a newline, $( $codeContent = $(if ($ScriptBlock) { "$scriptBlock" } else { $inputObject | LinkInput}) # then the -ScriptBlock or -InputObject $codeContent ) + [Environment]::newline + # then a newline '```' # then close the code fence. ) } # If -BulletPoint was passed, render a Bullet Point list. elseif ($BulletPoint) { $markdownLines += "*$(if ($Checkbox) { "[$(if ($Checked) {"x"} else {" "})]"}) $($inputObject | LinkInput)" } # If -NumberedList was passed, render a numbered list. elseif ($NumberedList -or $Number) { $numberedListCounter++ # Increment the counter $markdownLines += "$(if ($number) { $number } else {$numberedListCounter}).$(if ($Checkbox) {" [$(if ($Checked) {"x"} else {" "})]"}) $($inputObject | LinkInput)" } elseif ($BlockQuote -or $BlockQuoteDepth) { if (-not $BlockQuoteDepth) { $BlockQuoteDepth = 1 } $markdownLines += (">" * $BlockQuoteDepth ) + ' ' + ( "$inputObject" -split '(?>\r\n|\n)' -join ( [Environment]::NewLine + (">" * $BlockQuoteDepth) + ' ' ) ) } # Otherwise, we have to determine if -InputObject should be a -MarkdownTable or a -MarkdownParagraph. else { # If the input is a primitive type or a string, it should be a markdown paragraph if (($inputObject.GetType -and $inputObject.GetType().IsPrimitive) -or $inputObject -is [string]) { $MarkdownParagraph = $true } # If it is a dictionary, it should be a markdown table. elseif ($inputObject -is [Collections.IDictionary]) { $MarkdownTable = $true } # If the input is an array, apply the same logic: elseif ($inputObject -is [Object[]] -or $InputObject -is [PSObject[]]) { $allPrimitives = 1 # if the array was all primitives or strings foreach ($in in $InputObject) { $allPrimitives = $allPrimitives -band ( ($in.GetType -and $in.GetType().IsPrimitive) -or $in -is [string] ) } if ($allPrimitives) { # output as a paragraph. $MarkdownParagraph = $true } else { $MarkdownTable = $true } } # If we're still not sure, output as a table. else { $MarkdownTable = $true } } if ($MarkdownParagraph) { # If we're outputting as a paragraph, add the input and link it if needed. $markdownLines += $inputObject | LinkInput } elseif ($MarkdownTable) { # If we're rendering a table, we need to go row-by-row. foreach ($in in $InputObject) { $propertyList = @( # we first need to get a list of properties. # If there was a -Property parameter provided, use it. if ($Property) { foreach ($prop in $Property) { if ($prop -is [string]) { # Strings in -Property should be taken as property names $prop } elseif ($prop.Name -and $prop.Expression -and $prop.Expression -is [scriptblock]) { # and anything with a name and expression script block will run the expression script block. $_ = $psItem = $in @{name=$prop.Name;Value = . $prop.Expression} } } } # Otherwise, if the input was a dictionary elseif ($in -is [Collections.IDictionary]) { foreach ($k in $in.Keys) { # take all keys from the dictionary if ($MyInvocation.MyCommand.Parameters[$k]) { continue } # that are not parameters of this function. $k } } # Otherwise, walk over all properties on the object else { foreach ($psProp in $In.psobject.properties) { # and skip any properties that are parameters of this function. if ($psProp.Name -notin $MyInvocation.MyCommand.Parameters.Keys) { $psProp } } } ) # If we're rendering the first row of a table if ($IsFirst) { # Create the header $markdownLines += '|' + (@(foreach ($prop in $propertyList) { if ($prop -is [string]) { $prop } else { $prop.Name } }) -replace ([Environment]::newline), '<br/>' -replace '\|', '\|' -join '|') + '|' # Then create the alignment row. $markdownLines += '|' + $( $columnNumber =0 @( foreach ($prop in $propertyList) { $colLength = if ($prop -is [string]) { $prop.Length } else { $prop.Name.Length } if ($MarkdownTableAlignment) { if ($MarkdownTableAlignment[$columnNumber] -eq 'Left') { ':' + ("-" * ([Math]::Max($colLength,2) - 1)) } elseif ($MarkdownTableAlignment[$columnNumber] -eq 'Right') { ("-" * ([Math]::Max($colLength,2) - 1)) + ':' } elseif ($MarkdownTableAlignment[$columnNumber] -eq 'Center') { ':' + ("-" * ([Math]::max($colLength, 3) - 2)) + ':' } else { "-" * $colLength } } else { "-" * $colLength } $columnNumber++ } ) -replace ([Environment]::newline), '<br/>' -replace '\|', '\|' -join '|') + '|' $IsFirst = $false } # Now we create the row for this object. $markdownLine = '|' + ( @( foreach ($prop in $propertyList) { if ($prop -is [string]) { $in.$prop | LinkInput } else { $prop.Value | LinkInput } } ) -replace ([Environment]::newline), '<br/>' -replace '\|', '\|' -join '|') + '|' $markdownLines += $markdownLine } } if ( # There are a few combinations of parameters that make us want to write the -InputObject as a paragraph: ($ScriptBlock -and $inputObject) -or # * If -ScriptBlock and -InputObject were both provided. ($Heading -and $inputObject) # * if -Heading and -InputObject were both provided ) { $markdownLines += $InputObject | LinkInput } # If we're going to render a horizontal rule (and -MarkdownTable has not been set) if ($HorizontalRule -and -not $MarkdownTable) { # add the horizontal rule at the end. if ($host.UI.RawUI.BufferSize.Width) { $markdownLines += (([string]$HorizontalRuleCharacter) * ($Host.UI.RawUI.BufferSize.Width - 1)) } else { $markdownLines += "---" } } } end { # Now we need to make one last pass to normalize tables if ($markdownLines -match '^\|') { # (that is, if we have tables to normalize). $maxColumnSize = @{} # To normalize the table, we need to track the maximum size per column foreach ($ml in $markdownLines) { if ($ml -match '\^|') { $columnCount = 0 foreach ($tablePart in $ml -split '(?<!\\)\|' -ne '') { if ((-not $maxColumnSize[$columnCount]) -or $maxColumnSize[$columnCount] -lt $tablePart.Length) { $maxColumnSize[$columnCount] = [Math]::Max($tablePart.Length, 2) } $columnCount++ } } } # One we know the maximum size per column, walk over each line $markdownLines = @(foreach ($ml in $markdownLines) { if ($ml -match '\^|') { $columnCount = 0 # Recreate the line with the right amount of padding. '|' + (@(foreach ($tablePart in $ml -split '(?<!\\)\|' -ne '') { if ($tablePart -match '^[:\-]+$') { if ($tablePart -match '^\:-{0,}\:$') { # If it's an alignment column, make sure to keep the alignment. if ($maxColumnSize[$columnCount] -gt 2) { ':' + ('-' * ($maxColumnSize[$columnCount] - 2)) + ':' } else { '::' } } elseif ($tablePart -match '\:$') { $tablePart.PadLeft($maxColumnSize[$columnCount], '-') } elseif ($tablePart -match '^\:') { $tablePart.PadRight($maxColumnSize[$columnCount], '-') } else { $tablePart.PadRight($maxColumnSize[$columnCount], '-') } } else { $tablePart.PadRight($maxColumnSize[$columnCount], ' ') } $columnCount++ }) -join '|') + '|' } else { $ml } }) } $markdownLines -join [Environment]::NewLine } </ScriptBlock> </ExpressionBinding> </CustomItem> </CustomEntry> </CustomEntries> </CustomControl> </Control> <Control> <Name>${PipeScript_setOutputStyle}</Name> <CustomControl> <CustomEntries> <CustomEntry> <CustomItem> <ExpressionBinding> <ScriptBlock><# .Synopsis Adds style to a format output .Description Adds style information to a format output, including: * ForegroundColor * BackgroundColor * Bold * Underline .Notes Stylized Output works in two contexts at present: * Rich consoles (Windows Terminal, PowerShell.exe, Pwsh.exe) (when $host.UI.SupportsVirtualTerminal) * Web pages (Based off the presence of a $Request variable, or when $host.UI.SupportsHTML (you must add this property to $host.UI)) IsFormatPart: true #> param( [string]$ForegroundColor, [string]$BackgroundColor, [switch]$Bold, [switch]$Underline, [switch]$Invert ) $canUseANSI = $host.UI.SupportsVirtualTerminal $canUseHTML = $Request -or $host.UI.SupportsHTML if (-not ($canUseANSI -or $canUseHTML)) { return } $knownStreams = @{ Output='';Error='BrightRed';Warning='BrightYellow'; Verbose='BrightCyan';Debug='Yellow';Progress='Cyan'; Success='BrightGreen';Failure='Red';Default=''} $standardColors = 'Black', 'Red', 'Green', 'Yellow', 'Blue','Magenta', 'Cyan', 'White' $brightColors = 'BrightBlack', 'BrightRed', 'BrightGreen', 'BrightYellow', 'BrightBlue','BrightMagenta', 'BrightCyan', 'BrightWhite' $n =0 $cssClasses = @() $styleAttributes = @(:nextColor foreach ($hc in $ForegroundColor,$BackgroundColor) { $n++ if (-not $hc) { continue } if ($hc[0] -eq [char]0x1b) { if ($canUseANSI) { $hc; continue } } $ansiStartPoint = if ($n -eq 1) { 30 } else { 40 } if ($knownStreams.ContainsKey($hc)) { $i = $brightColors.IndexOf($knownStreams[$hc]) if ($canUseHTML) { $cssClasses += $hc } else { if ($i -ge 0 -and $canUseANSI) { '' + [char]0x1b + "[1;$($ansiStartPoint + $i)m" } else { $i = $standardColors.IndexOf($knownStreams[$hc]) if ($i -ge 0 -and $canUseANSI) { '' + [char]0x1b + "[1;$($ansiStartPoint + $i)m" } elseif ($i -le 0 -and $canUseANSI) { '' + [char]0x1b + "[$($ansistartpoint + 8):5m" } } } continue nextColor } elseif ($standardColors -contains $hc) { for ($i = 0; $i -lt $standardColors.Count;$i++) { if ($standardColors[$i] -eq $hc) { if ($canUseANSI -and -not $canUseHTML) { '' + [char]0x1b + "[$($ansiStartPoint + $i)m" } else { $cssClasses += $standardColors[$i] } continue nextColor } } } elseif ($brightColors -contains $hc) { for ($i = 0; $i -lt $brightColors.Count;$i++) { if ($brightColors[$i] -eq $hc) { if ($canUseANSI -and -not $canUseHTML) { '' + [char]0x1b + "[1;$($ansiStartPoint + $i)m" } else { $cssClasses += $standardColors[$i] } continue nextColor } } } if ($hc -and -not $hc.StartsWith('#')) { $placesToLook= @(if ($hc.Contains('.')) { $module, $setting = $hc -split '\.', 2 $theModule = Get-Module $module $theModule.PrivateData.Color, $theModule.PrivateData.Colors, $theModule.PrivateData.Colour, $theModule.PrivateData.Colours, $theModule.PrivateData.EZOut, $global:PSColors, $global:PSColours } else { $setting = $hc $moduleColorSetting = $theModule.PrivateData.PSColors.$setting }) foreach ($place in $placesToLook) { if (-not $place) { continue } foreach ($propName in $setting -split '\.') { $place = $place.$propName if (-not $place) { break } } if ($place -and "$place".StartsWith('#') -and 4,7 -contains "$place".Length) { $hc = $place continue } } if (-not $hc.StartsWith -or -not $hc.StartsWith('#')) { continue } } $r,$g,$b = if ($hc.Length -eq 7) { [int]::Parse($hc[1..2]-join'', 'HexNumber') [int]::Parse($hc[3..4]-join '', 'HexNumber') [int]::Parse($hc[5..6] -join'', 'HexNumber') }elseif ($hc.Length -eq 4) { [int]::Parse($hc[1], 'HexNumber') * 16 [int]::Parse($hc[2], 'HexNumber') * 16 [int]::Parse($hc[3], 'HexNumber') * 16 } if ($canUseHTML) { if ($n -eq 1) { "color:$hc" } elseif ($n -eq 2) { "background-color:$hc"} } elseif ($canUseANSI) { if ($n -eq 1) { [char]0x1b+"[38;2;$r;$g;${b}m" } elseif ($n -eq 2) { [char]0x1b+"[48;2;$r;$g;${b}m" } } }) if ($Bold) { $styleAttributes += if ($canUseHTML) { "font-weight:bold" } elseif ($canUseANSI) { [char]0x1b + "[1m" } } if ($Underline) { $styleAttributes += if ($canUseHTML) { "text-decoration:underline" } elseif ($canUseANSI) { [char]0x1b + "[4m" } } if ($Invert) { $styleAttributes += if ($canUseHTML) { "filter:invert(100%)" } elseif ($canUseANSI) { [char]0x1b + "[7m" } } if ($canUseHTML) { "<span$( if ($styleAttributes) { " style='$($styleAttributes -join ';')'"} )$( if ($cssClasses) { " class='$($cssClasses -join ' ')'"} )>" } elseif ($canUseANSI) { $styleAttributes -join '' }</ScriptBlock> </ExpressionBinding> </CustomItem> </CustomEntry> </CustomEntries> </CustomControl> </Control> <Control> <Name>${PipeScript_clearOutputStyle}</Name> <CustomControl> <CustomEntries> <CustomEntry> <CustomItem> <ExpressionBinding> <ScriptBlock><# .Synopsis Clears the output style .Description Clears ANSI output style or closes the most recent span element. ANSI stylization can be toggled off individually (for instance, to stop applying an -Underline but leave the color unchanged) .Notes IsFormatPart: true #> param( # If set, will explicitly clear ANSI Bold [switch] $Bold, # If set, will explicitly clear ANSI Underline [switch] $Underline, # If set, will explicitly clear ANSI Invert [switch] $Invert, # If set, will explicitly clear ANSI Foreground Color [switch] $ForegroundColor, # If set, will explicitly clear ANSI Background Color [switch] $BackgroundColor ) @(if ($request -or $host.UI.SupportsHTML) { "</span>" } elseif ($Host.UI.SupportsVirtualTerminal) { if ($Underline) { [char]0x1b + "[24m" } if ($Bold) { [char]0x1b + "[21m" } if ($Invert) { [char]0x1b + '[27m' } if ($ForegroundColor) { [char]0x1b + '[39m' } if ($BackgroundColor) { [char]0x1b + '[49m' } if (-not ($Underline -or $Bold -or $Invert -or $ForegroundColor -or $BackgroundColor)) { [char]0x1b + '[0m' } }) -join ''</ScriptBlock> </ExpressionBinding> </CustomItem> </CustomEntry> </CustomEntries> </CustomControl> </Control> <Control> <Name>${PipeScript_Format-YAML}</Name> <CustomControl> <CustomEntries> <CustomEntry> <CustomItem> <ExpressionBinding> <ScriptBlock> <# .SYNOPSIS Formats objects as YAML .DESCRIPTION Formats an object as YAML. .EXAMPLE Format-Yaml -InputObject @("a", "b", "c") .EXAMPLE @{a="b";c="d";e=@{f=@('g')}} | Format-Yaml #> [Management.Automation.Cmdlet("Format","Object")] [ValidateScript({return $true})] param( # The InputObject. [Parameter(ValueFromPipeline)] [PSObject] $InputObject, # If set, will make a YAML header by adding a YAML Document tag above and below output. [Alias('YAMLDocument')] [switch] $YamlHeader, [int] $Indent = 0, # The maximum depth of objects to include. # Beyond this depth, an empty string will be returned. [int] $Depth ) begin { $toYaml = { param( [Parameter(ValueFromPipeline,Position=0)]$Object, [Object]$Parent, [Object]$GrandParent, [int]$Indent = 0) begin { $n = 0; $mySelf = $myInvocation.MyCommand.ScriptBlock } process { $n++ if ($Object -eq $null) { return } if ($depth) { $myDepth = $indent / 2 if ($myDepth -gt $depth) { return '' } } if ($Parent -and $Parent -is [Collections.IList]) { if ($Parent.IndexOf($Object) -gt 0) { ' ' * $Indent } '- ' } #region Primitives if ( $Object -is [string] ) { # If it's a string if ($object -match '\n') { # see if it's a multline string. "|" # If it is, emit the multiline indicator $indent +=2 foreach ($l in $object -split '(?>\r\n|\n)') { # and emit each line indented [Environment]::NewLine ' ' * $indent $l } $indent -=2 } elseif ("$object".Contains('*')) { "'$($Object -replace "'","''")'" } else { $object } if ($Parent -is [Collections.IList]) { # If the parent object was a list [Environment]::NewLine # emit a newline. } return # Once the string has been emitted, return. } if ( $Object.GetType().IsPrimitive ) { # If it is a primitive type "$Object".ToLower() # Emit it in lowercase. if ($Parent -is [Collections.IList]) { [Environment]::NewLine } return } #endregion Primitives #region KVP if ( $Object -is [Collections.DictionaryEntry] -or $object -is [Management.Automation.PSPropertyInfo]) { if ($Parent -isnot [Collections.IList] -and ($GrandParent -isnot [Collections.IList] -or $n -gt 1)) { [Environment]::NewLine + (" " * $Indent) } if ($object.Key -and $Object.Key -is [string]) { $Object.Key +": " } elseif ($object.Name -and $object.Name -is [string]) { $Object.Name +": " } } if ( $Object -is [Collections.DictionaryEntry] -or $Object -is [Management.Automation.PSPropertyInfo]) { & $mySelf -Object $Object.Value -Parent $Object -GrandParent $parent -Indent $Indent return } #endregion KVP #region Nested if ($parent -and ($Object -is [Collections.IDictionary] -or $Object -is [PSObject])) { $Indent += 2 } elseif ($object -is [Collections.IList]) { $allPrimitive = 1 foreach ($Obj in $Object) { $allPrimitive = $allPrimitive -band ( $Obj -is [string] -or $obj.GetType().IsPrimitive ) } if ($parent -and -not $allPrimitive) { $Indent += 2 } } if ( $Object -is [Collections.IDictionary] ) { $Object.GetEnumerator() | & $mySelf -Parent $Object -GrandParent $Parent -Indent $Indent } elseif ($Object -is [Collections.IList]) { [Environment]::NewLine + (' ' * $Indent) $Object | & $mySelf -Parent $Object -GrandParent $Parent -Indent $Indent } elseif ($object -is [enum]) { $object.ToString() } elseif ($Object.PSObject.Properties) { $Object.psobject.properties | & $mySelf -Parent $Object -GrandParent $Parent -Indent $Indent } if ($Object -is [Collections.IDictionary] -or $Object -is [PSCustomObject] -or $Object -is [Collections.IList]) { if ($Parent -is [Collections.IList]) { [Environment]::NewLine } $Indent -= 2; } #endregion Nested } } function IndentString([string]$String,[int]$Indent) { @(foreach ($line in @($String -split '(?>\r\n|\n)')) { (' ' * $indent) + $line }) -join [Environment]::NewLine } $inputWasNotPiped = $PSBoundParameters.InputObject -as [bool] $allInputObjects = @() } process { if ($inputWasNotPiped) { IndentString ('' + $(if ($YamlHeader) { '---' + [Environment]::NewLine }) + ( (& $toYaml -object $inputObject) -join '' -replace "$([Environment]::NewLine * 2)", [Environment]::NewLine ) + $(if ($YamlHeader) { [Environment]::NewLine + '---'})) -Indent $Indent } else { $allInputObjects += $inputObject } } end { if (-not $allInputObjects) { return } if ($allInputObjects.Length -eq 1) { IndentString ('' + $(if ($YamlHeader) { '---' + [Environment]::NewLine}) + ( (& $toYaml -object $inputObject) -join '' -replace "$([Environment]::NewLine * 2)", [Environment]::NewLine ) + $(if ($YamlHeader) { [Environment]::NewLine + '---'})) -Indent $Indent } else { IndentString ('' + $(if ($YamlHeader) { '---' + [Environment]::NewLine}) + ( (& $toYaml -object $allInputObjects) -join '' -replace "$([Environment]::NewLine * 2)", [Environment]::NewLine ) + $(if ($YamlHeader) { [Environment]::NewLine + '---'})) -Indent $Indent } } </ScriptBlock> </ExpressionBinding> </CustomItem> </CustomEntry> </CustomEntries> </CustomControl> </Control> </Controls> <ViewDefinitions> <View> <Name>System.Management.Automation.Language.Ast</Name> <ViewSelectedBy> <TypeName>System.Management.Automation.Language.Ast</TypeName> </ViewSelectedBy> <CustomControl> <CustomEntries> <CustomEntry> <CustomItem> <ExpressionBinding> <PropertyName>Tokens</PropertyName> <EnumerateCollection /> <CustomControlName>PSToken</CustomControlName> </ExpressionBinding> </CustomItem> </CustomEntry> </CustomEntries> </CustomControl> </View> <View> <Name>Hashtable</Name> <ViewSelectedBy> <TypeName>Hashtable</TypeName> </ViewSelectedBy> <CustomControl> <CustomEntries> <CustomEntry> <CustomItem> <ExpressionBinding> <ScriptBlock>$moduleName = 'PipeScript' do { $lm = Get-Module -Name $moduleName -ErrorAction Ignore if (-not $lm) { continue } if ($lm.FormatPartsLoaded) { break } $wholeScript = @(foreach ($formatFilePath in $lm.exportedFormatFiles) { foreach ($partNodeName in Select-Xml -LiteralPath $formatFilePath -XPath "/Configuration/Controls/Control/Name[starts-with(., '$')]") { $ParentNode = $partNodeName.Node.ParentNode "$($ParentNode.Name)={ $($ParentNode.CustomControl.CustomEntries.CustomEntry.CustomItem.ExpressionBinding.ScriptBlock)}" } }) -join [Environment]::NewLine New-Module -Name "${ModuleName}.format.ps1xml" -ScriptBlock ([ScriptBlock]::Create(($wholeScript + ';Export-ModuleMember -Variable *'))) | Import-Module -Global $onRemove = [ScriptBlock]::Create("Remove-Module '${ModuleName}.format.ps1xml'") if (-not $lm.OnRemove) { $lm.OnRemove = $onRemove } else { $lm.OnRemove = [ScriptBlock]::Create($onRemove.ToString() + '' + [Environment]::NewLine + $lm.OnRemove) } $lm | Add-Member NoteProperty FormatPartsLoaded $true -Force } while ($false) $_ | & ${PipeScript_Format-Hashtable} -Depth $FormatEnumerationLimit </ScriptBlock> </ExpressionBinding> </CustomItem> </CustomEntry> </CustomEntries> </CustomControl> </View> <View> <Name>Markdown</Name> <ViewSelectedBy> <TypeName>Markdown</TypeName> </ViewSelectedBy> <CustomControl> <CustomEntries> <CustomEntry> <CustomItem> <ExpressionBinding> <ScriptBlock>$moduleName = 'PipeScript' do { $lm = Get-Module -Name $moduleName -ErrorAction Ignore if (-not $lm) { continue } if ($lm.FormatPartsLoaded) { break } $wholeScript = @(foreach ($formatFilePath in $lm.exportedFormatFiles) { foreach ($partNodeName in Select-Xml -LiteralPath $formatFilePath -XPath "/Configuration/Controls/Control/Name[starts-with(., '$')]") { $ParentNode = $partNodeName.Node.ParentNode "$($ParentNode.Name)={ $($ParentNode.CustomControl.CustomEntries.CustomEntry.CustomItem.ExpressionBinding.ScriptBlock)}" } }) -join [Environment]::NewLine New-Module -Name "${ModuleName}.format.ps1xml" -ScriptBlock ([ScriptBlock]::Create(($wholeScript + ';Export-ModuleMember -Variable *'))) | Import-Module -Global $onRemove = [ScriptBlock]::Create("Remove-Module '${ModuleName}.format.ps1xml'") if (-not $lm.OnRemove) { $lm.OnRemove = $onRemove } else { $lm.OnRemove = [ScriptBlock]::Create($onRemove.ToString() + '' + [Environment]::NewLine + $lm.OnRemove) } $lm | Add-Member NoteProperty FormatPartsLoaded $true -Force } while ($false) $thisObject = $_ if ($thisObject -is [string]) { $thisObject } elseif ($thisObject.Table) { $thisObject.Table | & ${PipeScript_Format-Markdown} } elseif ($thisObject.InputObject) { $thisObject | & ${PipeScript_Format-Markdown} -InputObject { $thisObject.InputObject } } elseif ($thisObject.Heading -and ($thisObject.Code -or $this.CodeLanguage)) { $thisObject | & ${PipeScript_Format-Markdown} } elseif ($thisObject.psobject.Properties.Length) { $thisObject | & ${PipeScript_Format-Markdown} } else { "$thisObject" } </ScriptBlock> </ExpressionBinding> </CustomItem> </CustomEntry> </CustomEntries> </CustomControl> </View> <View> <Name>PipeScript</Name> <ViewSelectedBy> <TypeName>PipeScript</TypeName> </ViewSelectedBy> <TableControl> <TableHeaders> <TableColumnHeader> <Label>DisplayName</Label> </TableColumnHeader> <TableColumnHeader> </TableColumnHeader> <TableColumnHeader> <Label>Parameters</Label> </TableColumnHeader> </TableHeaders> <TableRowEntries> <TableRowEntry> <Wrap /> <TableColumnItems> <!-- {ConditionalColor:""Success""}--> <TableColumnItem> <ScriptBlock>$moduleName = 'PipeScript' do { $lm = Get-Module -Name $moduleName -ErrorAction Ignore if (-not $lm) { continue } if ($lm.FormatPartsLoaded) { break } $wholeScript = @(foreach ($formatFilePath in $lm.exportedFormatFiles) { foreach ($partNodeName in Select-Xml -LiteralPath $formatFilePath -XPath "/Configuration/Controls/Control/Name[starts-with(., '$')]") { $ParentNode = $partNodeName.Node.ParentNode "$($ParentNode.Name)={ $($ParentNode.CustomControl.CustomEntries.CustomEntry.CustomItem.ExpressionBinding.ScriptBlock)}" } }) -join [Environment]::NewLine New-Module -Name "${ModuleName}.format.ps1xml" -ScriptBlock ([ScriptBlock]::Create(($wholeScript + ';Export-ModuleMember -Variable *'))) | Import-Module -Global $onRemove = [ScriptBlock]::Create("Remove-Module '${ModuleName}.format.ps1xml'") if (-not $lm.OnRemove) { $lm.OnRemove = $onRemove } else { $lm.OnRemove = [ScriptBlock]::Create($onRemove.ToString() + '' + [Environment]::NewLine + $lm.OnRemove) } $lm | Add-Member NoteProperty FormatPartsLoaded $true -Force } while ($false) $__ = $_ $ci = . {"Success"} $_ = $__ if ($ci -is [string]) { $ci = & ${PipeScript_Format-RichText} -NoClear -ForegroundColor $ci } else { $ci = & ${PipeScript_Format-RichText} -NoClear @ci } $output = . {$_.'DisplayName'} @($ci; $output; & ${PipeScript_Format-RichText}) -join "" </ScriptBlock> </TableColumnItem> <TableColumnItem> <PropertyName>Synopsis</PropertyName> </TableColumnItem> <TableColumnItem> <ScriptBlock> @(foreach ($kv in ([Management.Automation.CommandMetaData]$_).Parameters.GetEnumerator()) { @( . ${PipeScript_setOutputStyle} -ForegroundColor Verbose "[$($kv.Value.ParameterType)]" . ${PipeScript_clearOutputStyle} . ${PipeScript_setOutputStyle} -ForegroundColor Warning "`$$($kv.Key)" . ${PipeScript_clearOutputStyle} ) -join '' }) -join [Environment]::NewLine </ScriptBlock> </TableColumnItem> </TableColumnItems> </TableRowEntry> </TableRowEntries> </TableControl> </View> <View> <Name>PipeScript.Sentence</Name> <ViewSelectedBy> <TypeName>PipeScript.Sentence</TypeName> </ViewSelectedBy> <CustomControl> <CustomEntries> <CustomEntry> <CustomItem> <ExpressionBinding> <ScriptBlock>$moduleName = 'PipeScript' do { $lm = Get-Module -Name $moduleName -ErrorAction Ignore if (-not $lm) { continue } if ($lm.FormatPartsLoaded) { break } $wholeScript = @(foreach ($formatFilePath in $lm.exportedFormatFiles) { foreach ($partNodeName in Select-Xml -LiteralPath $formatFilePath -XPath "/Configuration/Controls/Control/Name[starts-with(., '$')]") { $ParentNode = $partNodeName.Node.ParentNode "$($ParentNode.Name)={ $($ParentNode.CustomControl.CustomEntries.CustomEntry.CustomItem.ExpressionBinding.ScriptBlock)}" } }) -join [Environment]::NewLine New-Module -Name "${ModuleName}.format.ps1xml" -ScriptBlock ([ScriptBlock]::Create(($wholeScript + ';Export-ModuleMember -Variable *'))) | Import-Module -Global $onRemove = [ScriptBlock]::Create("Remove-Module '${ModuleName}.format.ps1xml'") if (-not $lm.OnRemove) { $lm.OnRemove = $onRemove } else { $lm.OnRemove = [ScriptBlock]::Create($onRemove.ToString() + '' + [Environment]::NewLine + $lm.OnRemove) } $lm | Add-Member NoteProperty FormatPartsLoaded $true -Force } while ($false) @(& ${PipeScript_Format-RichText} -ForegroundColor 'Verbose' -NoClear) -join ''</ScriptBlock> </ExpressionBinding> <ExpressionBinding> <ItemSelectionCondition> <ScriptBlock> $_.Command </ScriptBlock> </ItemSelectionCondition> <PropertyName>Keyword</PropertyName> </ExpressionBinding> <ExpressionBinding> <ScriptBlock>@(& ${PipeScript_Format-RichText} -ForegroundColor 'Verbose' ) -join ''</ScriptBlock> </ExpressionBinding> <ExpressionBinding> <ScriptBlock>@(& ${PipeScript_Format-RichText} -ForegroundColor 'Success' -NoClear) -join ''</ScriptBlock> </ExpressionBinding> <ExpressionBinding> <ItemSelectionCondition> <ScriptBlock> $_.Command </ScriptBlock> </ItemSelectionCondition> <ScriptBlock> " <# $($_.Command) #> " </ScriptBlock> </ExpressionBinding> <ExpressionBinding> <ScriptBlock>@(& ${PipeScript_Format-RichText} -ForegroundColor 'Success' ) -join ''</ScriptBlock> </ExpressionBinding> <ExpressionBinding> <ScriptBlock> ' ' </ScriptBlock> </ExpressionBinding> <ExpressionBinding> <ScriptBlock> @(foreach ($clause in $_.Clauses) { $wordNumber = -1 foreach ($word in $clause.Words) { $wordNumber++ if (-not $wordNumber) { & ${PipeScript_Format-RichText} -ForegroundColor Warning -InputObject "$word" } else { & ${PipeScript_Format-RichText} -InputObject "$word" } } }) -join ' ' </ScriptBlock> </ExpressionBinding> <ExpressionBinding> <ScriptBlock>@(& ${PipeScript_Format-RichText} -ForegroundColor 'Magenta' -NoClear) -join ''</ScriptBlock> </ExpressionBinding> <ExpressionBinding> <ItemSelectionCondition> <ScriptBlock> $_.Arguments -and -not $_.Clauses </ScriptBlock> </ItemSelectionCondition> <ScriptBlock> $_.Arguments -join ' ' </ScriptBlock> </ExpressionBinding> <ExpressionBinding> <ScriptBlock>@(& ${PipeScript_Format-RichText} -ForegroundColor 'Magenta' ) -join ''</ScriptBlock> </ExpressionBinding> </CustomItem> </CustomEntry> </CustomEntries> </CustomControl> </View> <View> <Name>PipeScript.Transpiler</Name> <ViewSelectedBy> <TypeName>PipeScript.Transpiler</TypeName> </ViewSelectedBy> <TableControl> <TableHeaders> <TableColumnHeader> <Label>DisplayName</Label> </TableColumnHeader> <TableColumnHeader> </TableColumnHeader> <TableColumnHeader> <Label>Parameters</Label> </TableColumnHeader> </TableHeaders> <TableRowEntries> <TableRowEntry> <Wrap /> <TableColumnItems> <!-- {ConditionalColor:""Success""}--> <TableColumnItem> <ScriptBlock>$moduleName = 'PipeScript' do { $lm = Get-Module -Name $moduleName -ErrorAction Ignore if (-not $lm) { continue } if ($lm.FormatPartsLoaded) { break } $wholeScript = @(foreach ($formatFilePath in $lm.exportedFormatFiles) { foreach ($partNodeName in Select-Xml -LiteralPath $formatFilePath -XPath "/Configuration/Controls/Control/Name[starts-with(., '$')]") { $ParentNode = $partNodeName.Node.ParentNode "$($ParentNode.Name)={ $($ParentNode.CustomControl.CustomEntries.CustomEntry.CustomItem.ExpressionBinding.ScriptBlock)}" } }) -join [Environment]::NewLine New-Module -Name "${ModuleName}.format.ps1xml" -ScriptBlock ([ScriptBlock]::Create(($wholeScript + ';Export-ModuleMember -Variable *'))) | Import-Module -Global $onRemove = [ScriptBlock]::Create("Remove-Module '${ModuleName}.format.ps1xml'") if (-not $lm.OnRemove) { $lm.OnRemove = $onRemove } else { $lm.OnRemove = [ScriptBlock]::Create($onRemove.ToString() + '' + [Environment]::NewLine + $lm.OnRemove) } $lm | Add-Member NoteProperty FormatPartsLoaded $true -Force } while ($false) $__ = $_ $ci = . {"Success"} $_ = $__ if ($ci -is [string]) { $ci = & ${PipeScript_Format-RichText} -NoClear -ForegroundColor $ci } else { $ci = & ${PipeScript_Format-RichText} -NoClear @ci } $output = . {$_.'DisplayName'} @($ci; $output; & ${PipeScript_Format-RichText}) -join "" </ScriptBlock> </TableColumnItem> <TableColumnItem> <PropertyName>Synopsis</PropertyName> </TableColumnItem> <TableColumnItem> <ScriptBlock> @(foreach ($kv in ([Management.Automation.CommandMetaData]$_).Parameters.GetEnumerator()) { @( . ${PipeScript_setOutputStyle} -ForegroundColor Verbose "[$($kv.Value.ParameterType)]" . ${PipeScript_clearOutputStyle} . ${PipeScript_setOutputStyle} -ForegroundColor Warning "`$$($kv.Key)" . ${PipeScript_clearOutputStyle} ) -join '' }) -join [Environment]::NewLine </ScriptBlock> </TableColumnItem> </TableColumnItems> </TableRowEntry> </TableRowEntries> </TableControl> </View> <View> <Name>Search.PipeScript.Result</Name> <ViewSelectedBy> <TypeName>Search.PipeScript.Result</TypeName> </ViewSelectedBy> <GroupBy> <PropertyName>InputObject</PropertyName> </GroupBy> <TableControl> <TableHeaders> <TableColumnHeader> </TableColumnHeader> <TableColumnHeader> </TableColumnHeader> </TableHeaders> <TableRowEntries> <TableRowEntry> <TableColumnItems> <TableColumnItem> <PropertyName>Result</PropertyName> </TableColumnItem> <TableColumnItem> <PropertyName>Expression</PropertyName> </TableColumnItem> </TableColumnItems> </TableRowEntry> </TableRowEntries> </TableControl> </View> <View> <Name>YAML</Name> <ViewSelectedBy> <TypeName>YAML</TypeName> </ViewSelectedBy> <CustomControl> <CustomEntries> <CustomEntry> <CustomItem> <ExpressionBinding> <ScriptBlock>$moduleName = 'PipeScript' do { $lm = Get-Module -Name $moduleName -ErrorAction Ignore if (-not $lm) { continue } if ($lm.FormatPartsLoaded) { break } $wholeScript = @(foreach ($formatFilePath in $lm.exportedFormatFiles) { foreach ($partNodeName in Select-Xml -LiteralPath $formatFilePath -XPath "/Configuration/Controls/Control/Name[starts-with(., '$')]") { $ParentNode = $partNodeName.Node.ParentNode "$($ParentNode.Name)={ $($ParentNode.CustomControl.CustomEntries.CustomEntry.CustomItem.ExpressionBinding.ScriptBlock)}" } }) -join [Environment]::NewLine New-Module -Name "${ModuleName}.format.ps1xml" -ScriptBlock ([ScriptBlock]::Create(($wholeScript + ';Export-ModuleMember -Variable *'))) | Import-Module -Global $onRemove = [ScriptBlock]::Create("Remove-Module '${ModuleName}.format.ps1xml'") if (-not $lm.OnRemove) { $lm.OnRemove = $onRemove } else { $lm.OnRemove = [ScriptBlock]::Create($onRemove.ToString() + '' + [Environment]::NewLine + $lm.OnRemove) } $lm | Add-Member NoteProperty FormatPartsLoaded $true -Force } while ($false) $inputObject = $_ if ($inputObject.psobject.properties['Indent'].Value -as [int]) { $indentLevel = $inputObject.Indent -as [int] $inputCopy = [Ordered]@{} foreach ($prop in $inputObject.psobject.properties) { if ($prop.Name -eq 'indent') { continue } $inputCopy[$prop.Name] = $prop.Value } & ${PipeScript_Format-YAML} -inputObject $inputCopy -Indent $indentLevel } else { & ${PipeScript_Format-YAML} -inputObject $inputObject } </ScriptBlock> </ExpressionBinding> </CustomItem> </CustomEntry> </CustomEntries> </CustomControl> </View> </ViewDefinitions> </Configuration> |