Private/ColorNames.ps1
|
# Helpers for the color name and style profile commands function Get-ColorRegisterRgb { <# .SYNOPSIS The RGB color Register-ColorName takes a value as, or $null for a value that is not a color: a hex code, rgb(), hsl(), three numbers 0-255, or a name in the color table. #> param([object]$Value, [hashtable]$Table) if ($Value -is [array]) { if ($Value.Count -ne 3) { return $null } $rgb = [System.Collections.Generic.List[object]]::new() foreach ($channel in $Value) { if (-not ($channel -is [int] -or $channel -is [long] -or $channel -is [int16] -or $channel -is [byte]) -or $channel -lt 0 -or $channel -gt 255) { return $null } $rgb.Add([int]$channel) } return ,$rgb.ToArray() } if ($Value -isnot [string]) { return $null } $entry = $Table[$Value] if ($entry) { return ,@($entry[4][0], $entry[4][1], $entry[4][2]) } $form = ConvertTo-ColorForm -Value $Value return ,[ColorCode]::HexToRgb($form) } function Get-ColorNameOrder { <# .SYNOPSIS Color names in family order: by the name without Dark or Light, then Dark, the name, Light. Names compare by their letters in upper case, ordinal, so the order is the same everywhere. #> param([string[]]$Names) if ($null -eq $Names -or $Names.Count -eq 0) { return } $keys = [string[]]::new($Names.Count) for ($i = 0; $i -lt $Names.Count; $i++) { $name = $Names[$i] $variant = 1 $family = $name if ($name -match '^(?i)dark(.+)$') { $variant = 0 $family = $Matches[1] } elseif ($name -match '^(?i)light(.+)$') { $variant = 2 $family = $Matches[1] } $keys[$i] = '{0}|{1}|{2}' -f $family.ToUpperInvariant(), $variant, $name.ToUpperInvariant() } $sorted = [string[]]$Names.Clone() [Array]::Sort($keys, $sorted, [System.StringComparer]::Ordinal) $sorted } function ConvertTo-ColorJson { <# .SYNOPSIS A value as JSON, indented two spaces: an ordered dictionary as an object, an array as an array, and strings, integers, booleans and $null. Written here rather than with ConvertTo-Json, whose layout differs between Windows PowerShell 5.1 and PowerShell 7, so a profile file has the same bytes everywhere. #> param([object]$Value, [int]$Depth = 0) $indent = ' ' * ($Depth + 1) $close = ' ' * $Depth if ($null -eq $Value) { return 'null' } if ($Value -is [bool]) { return $(if ($Value) { 'true' } else { 'false' }) } if ($Value -is [int] -or $Value -is [long]) { return $Value.ToString([System.Globalization.CultureInfo]::InvariantCulture) } if ($Value -is [string] -or $Value -is [char]) { $builder = [System.Text.StringBuilder]::new('"') foreach ($character in ([string]$Value).ToCharArray()) { switch ($character) { '"' { [void]$builder.Append('\"'); continue } '\' { [void]$builder.Append('\\'); continue } "`n" { [void]$builder.Append('\n'); continue } "`r" { [void]$builder.Append('\r'); continue } "`t" { [void]$builder.Append('\t'); continue } default { if ([int]$character -lt 0x20) { [void]$builder.Append(('\u{0:x4}' -f [int]$character)) } else { [void]$builder.Append($character) } } } } return $builder.Append('"').ToString() } if ($Value -is [System.Collections.IDictionary]) { if ($Value.Count -eq 0) { return '{}' } $members = foreach ($key in $Value.Keys) { $indent + (ConvertTo-ColorJson -Value ([string]$key)) + ': ' + (ConvertTo-ColorJson -Value $Value[$key] -Depth ($Depth + 1)) } return "{`n" + ($members -join ",`n") + "`n$close}" } if ($Value -is [System.Collections.IEnumerable]) { $items = @($Value) if ($items.Count -eq 0) { return '[]' } # A list of numbers, such as an RGB color, stays on one line $simple = $true foreach ($item in $items) { if ($item -isnot [int] -and $item -isnot [long]) { $simple = $false } } if ($simple) { return '[' + (@(foreach ($item in $items) { ConvertTo-ColorJson -Value $item }) -join ', ') + ']' } $members = foreach ($item in $items) { $indent + (ConvertTo-ColorJson -Value $item -Depth ($Depth + 1)) } return "[`n" + ($members -join ",`n") + "`n$close]" } return ConvertTo-ColorJson -Value ([string]$Value) -Depth $Depth } function ConvertFrom-ColorJsonValue { <# .SYNOPSIS A value ConvertFrom-Json read, with whole numbers as [int] as Write-ColorEX takes them, and arrays as object arrays. PowerShell 7 reads whole numbers as [long]. #> param([object]$Value) if ($Value -is [long] -and $Value -ge [int]::MinValue -and $Value -le [int]::MaxValue) { return [int]$Value } if ($Value -is [array]) { $items = [System.Collections.Generic.List[object]]::new() foreach ($item in $Value) { $items.Add((ConvertFrom-ColorJsonValue -Value $item)) } return ,$items.ToArray() } return $Value } # The PSColorStyle properties a profile file holds, in the order it holds them $script:ColorProfileProperties = @( 'ForegroundColor', 'BackgroundColor', 'Gradient', 'BackgroundGradient', 'GradientSpace', 'Style', 'Bold', 'Italic', 'Underline', 'Blink', 'Faint', 'CrossedOut', 'DoubleUnderline', 'Overline', 'Reverse', 'UnderlineColor', 'UnderlineStyle', 'StartTab', 'StartSpaces', 'LinesBefore', 'LinesAfter', 'ShowTime', 'NoNewLine', 'HorizontalCenter', 'AutoPad', 'PadLeft', 'PadCenter', 'PadChar', 'Truncate', 'Wrap' ) |