PSWriteColorEX.psm1
|
#Requires -Version 5.1 <# .SYNOPSIS PSWriteColorEX - Advanced colored console output module with comprehensive ANSI support .DESCRIPTION PSWriteColorEX is an advanced PowerShell module providing enhanced colored console output with comprehensive ANSI support including TrueColor (24-bit RGB), style profiles, cross-platform compatibility, and extensive logging capabilities. KEY FEATURES: - TrueColor (24-bit RGB) support for 16.7 million colors - Multi-stop gradient colors with smooth transitions - Unicode-aware text padding (AutoPad) for perfect table alignment - Style profiles for consistent output (Error, Warning, Info, Success, Critical, Debug) - Automatic terminal detection with graceful color degradation - Cross-platform: Windows, Linux, macOS - Bold font support detection and automatic color lightening - Comprehensive logging with timestamps and log levels - Performance optimized with caching (1000x-18000x improvements) TERMINAL SUPPORT: - Windows: Windows Terminal, PowerShell Console, ConEmu, VS Code, Git Bash - macOS: iTerm2, Terminal.app, VS Code - Linux: GNOME Terminal, Konsole, xterm, rxvt-unicode, Kitty .NOTES Author: MarkusMcNugen License: MIT Requires: PowerShell 5.1 or later Compatible: PowerShell Desktop and Core editions Module initialization automatically detects terminal capabilities and caches results for optimal performance. .LINK https://github.com/MarkusMcNugen/PSWriteColorEX .EXAMPLE Import-Module PSWriteColorEX Write-ColorEX "Hello World" -Color Green -Bold .EXAMPLE Write-ColorError "Operation failed" Write-ColorSuccess "Completed successfully" .EXAMPLE Write-ColorEX "GRADIENT" -Gradient @('Red','Yellow','Green','Cyan','Blue','Magenta') #> # Module variables $script:ModuleRoot = $PSScriptRoot $script:ModuleVersion = '1.0.0' $script:DebugMode = $false $script:CachedANSISupport = $null # Cached ANSI support level for performance $script:SupportsBoldFonts = $false # Cached bold font support detection $script:CachedColorTable = $null # Cached color table for performance $script:CachedHelperStyles = @{} # Cached helper function style params $script:RGB6LevelLookup = $null # Lookup table for RGB to 6-level conversion # Enable debug mode if requested if ($env:PSWRITECOLOREX_DEBUG -eq 'true') { $script:DebugMode = $true Write-Verbose "PSWriteColorEX Debug Mode Enabled" -Verbose } # Initialize RGB to 6-level lookup table for ANSI8 conversion function Initialize-RGB6LevelLookup { if ($null -eq $script:RGB6LevelLookup) { $script:RGB6LevelLookup = [int[]]::new(256) for ($i = 0; $i -lt 256; $i++) { $script:RGB6LevelLookup[$i] = if ($i -lt 48) { 0 } elseif ($i -lt 115) { 1 } elseif ($i -lt 155) { 2 } elseif ($i -lt 195) { 3 } elseif ($i -lt 235) { 4 } else { 5 } } } } # Initialize the lookup table Initialize-RGB6LevelLookup # Load classes first (they need to be loaded before functions that use them) $ClassFiles = @( "$PSScriptRoot\Classes\PSColorStyle.ps1" ) foreach ($file in $ClassFiles) { if (Test-Path $file) { try { . $file if ($script:DebugMode) { Write-Verbose "Loaded class file: $file" -Verbose } } catch { Write-Error "Failed to load class file: $file. Error: $_" } } } # Load private functions (hardcoded for faster loading) $PrivateFunctions = @( "$PSScriptRoot\Private\New-GradientColorArray.ps1" ) foreach ($file in $PrivateFunctions) { if (Test-Path $file) { try { . $file if ($script:DebugMode) { Write-Verbose "Loaded private function: $(Split-Path $file -Leaf)" -Verbose } } catch { Write-Error "Failed to load private function: $(Split-Path $file -Leaf). Error: $_" } } else { Write-Warning "Private function file not found: $file" } } # Load public functions (hardcoded for faster loading) $PublicFunctions = @( "$PSScriptRoot\Public\Test-AnsiSupport.ps1" "$PSScriptRoot\Public\Convert-ColorValue.ps1" "$PSScriptRoot\Public\Write-ColorEX.ps1" "$PSScriptRoot\Public\Write-ColorHelpers.ps1" "$PSScriptRoot\Public\Measure-DisplayWidth.ps1" ) foreach ($file in $PublicFunctions) { if (Test-Path $file) { try { . $file if ($script:DebugMode) { Write-Verbose "Loaded public function: $(Split-Path $file -Leaf)" -Verbose } } catch { Write-Error "Failed to load public function: $(Split-Path $file -Leaf). Error: $_" } } else { Write-Warning "Public function file not found: $file" } } # Initialize default color profiles try { [PSColorStyle]::InitializeDefaultProfiles() if ($script:DebugMode) { Write-Verbose "Initialized default color profiles" -Verbose } } catch { Write-Warning "Could not initialize default color profiles: $_" } # Module initialization $script:ModuleInitialized = $false function Initialize-PSWriteColorEX { <# .SYNOPSIS Initializes the PSWriteColorEX module .DESCRIPTION Performs module initialization tasks including ANSI support detection #> [CmdletBinding()] param() if ($script:ModuleInitialized) { return } # Detect initial ANSI support and cache it $ansiResult = Test-AnsiSupport -Silent $script:CachedANSISupport = $ansiResult.ColorSupport $script:SupportsBoldFonts = $ansiResult.SupportsBoldFonts if ($script:DebugMode) { Write-Verbose "Module initialized with ANSI support level: $script:CachedANSISupport" -Verbose Write-Verbose "Bold font support: $script:SupportsBoldFonts" -Verbose } # Set module initialization flag $script:ModuleInitialized = $true # Display module banner if in interactive mode and not suppressed if ($Host.UI.RawUI -and -not $env:PSWRITECOLOREX_NO_BANNER) { Write-ColorEX -Text "PSWriteColorEX v$script:ModuleVersion loaded" -Color Cyan -Italic if ($script:CachedANSISupport -eq 'TrueColor') { Write-ColorEX -Text "TrueColor support detected - 16.7 million colors available!" -Color @(0, 255, 128) -TrueColor } elseif ($script:CachedANSISupport -eq 'ANSI8') { Write-ColorEX -Text "256-color support detected" -Color 208 -ANSI8 } elseif ($script:CachedANSISupport -eq 'ANSI4') { Write-ColorEX -Text "16-color ANSI support detected" -Color Yellow -ANSI4 } else { Write-Host "Basic console colors available" -ForegroundColor Gray } } } # Initialize module Initialize-PSWriteColorEX # Export module members $ExportParams = @{ Function = @( 'Write-ColorEX', 'Write-ColorError', 'Write-ColorWarning', 'Write-ColorInfo', 'Write-ColorSuccess', 'Write-ColorCritical', 'Write-ColorDebug', 'Set-ColorDefault', 'Get-ColorProfiles', 'New-ColorStyle', 'Test-AnsiSupport', 'Convert-HexToRGB', 'Convert-RGBToANSI8', 'Convert-RGBToANSI4', 'Get-ColorTableWithRGB', 'Measure-DisplayWidth', 'Lighten-RGBColor', 'Lighten-ColorName', 'Lighten-ANSI8Color' ) Alias = @( # Write-ColorEX aliases 'Write-ColourEX', 'Write-Color', 'Write-Colour', 'WC', 'WCEX', 'wcolor', 'wcolour', # Write-ColorError aliases 'WCE', 'Write-ErrorColor', 'Write-ErrorColour', 'Write-ColourError', 'WError', 'wcerror', # Write-ColorWarning aliases 'WCW', 'Write-WarningColor', 'Write-WarningColour', 'Write-ColourWarning', 'WWarning', 'WCWarn', 'wcwarning', # Write-ColorInfo aliases 'WCI', 'Write-InfoColor', 'Write-InfoColour', 'Write-ColourInfo', 'WInfo', 'wcinfo', # Write-ColorSuccess aliases 'WCS', 'Write-SuccessColor', 'Write-SuccessColour', 'Write-ColourSuccess', 'WSuccess', 'wcok', 'wcsuccess', # Write-ColorCritical aliases 'WCC', 'Write-CriticalColor', 'Write-CriticalColour', 'Write-ColourCritical', 'WCritical', 'wccritical', # Write-ColorDebug aliases 'WCD', 'Write-DebugColor', 'Write-DebugColour', 'Write-ColourDebug', 'WDebug', 'wcdebug', # Set-ColorDefault aliases 'SCD', 'Set-ColourDefault', 'Set-DefaultColor', 'Set-DefaultColour', # Get-ColorProfiles aliases 'GCP', 'Get-ColourProfiles', 'Get-Profiles', 'gcprofiles', # New-ColorStyle aliases 'NCS', 'New-ColourStyle', 'New-Style', 'ncstyle', # Test-AnsiSupport aliases 'TAS', 'Test-ANSI', # Convert-HexToRGB aliases 'CHR', 'Hex2RGB', # Convert-RGBToANSI8 aliases 'CRA8', 'RGB2ANSI8', # Convert-RGBToANSI4 aliases 'CRA4', 'RGB2ANSI4', # Get-ColorTableWithRGB aliases 'GCT', 'Get-ColorTable', 'Get-ColourTable', # Measure-DisplayWidth aliases 'MDW', 'Get-DisplayWidth', # Lighten-ANSI8Color aliases 'LA8', 'Lighten-ANSI8' ) Variable = @() } Export-ModuleMember @ExportParams # Module removal cleanup $MyInvocation.MyCommand.ScriptBlock.Module.OnRemove = { # Clean up any module resources if ($script:DebugMode) { Write-Verbose "PSWriteColorEX module removed" -Verbose } } |