functions/convert-fscpstexttoascii.ps1
<# .SYNOPSIS Converts a given text to ASCII art using a specified font and optional border style with color support. .DESCRIPTION The Convert-FSCPSTextToAscii function takes a string input and converts it into ASCII art using the specified font. Optionally, a border style and colors for the text and border can be applied. The function supports various fonts and border styles, allowing for customization of the output. The text and border colors can also be specified to enhance the visual appearance of the ASCII art. This function is ideal for creating visually appealing text banners or decorations in scripts, logs, or console outputs. .PARAMETER Text The text to be converted into ASCII art. This parameter is mandatory. .PARAMETER Font The font to be used for generating the ASCII art. This parameter is mandatory. .PARAMETER BorderType The type of border to apply around the ASCII art. This parameter is optional and defaults to 'None'. .PARAMETER TextColor The color to use for the ASCII art text. This parameter is optional and defaults to 'White'. .PARAMETER BorderColor The color to use for the border. This parameter is optional and defaults to 'Gray'. .PARAMETER Timestamp Enables or disables detailed information (timestamp) in the output. Defaults to `$false`. .EXAMPLE PS C:\> Convert-FSCPSTextToAscii -Text "Hello" -Font "Standard" -BorderType Asterisk -TextColor Yellow -BorderColor Green -DetailedInfo $true Converts the text "Hello" into ASCII art using the "Standard" font, surrounds it with an asterisk border, and applies yellow text with a green border. Detailed information (timestamp and function name) is enabled. .NOTES Author: Oleksandr Nikolaiev (@onikolaiev) #> function Convert-FSCPSTextToAscii { [CmdletBinding()] [OutputType()] param( [Parameter(Mandatory=$true)] [string]$Text, [Parameter(Mandatory=$true)] [FontType]$Font, [Parameter(Mandatory=$false)] [BorderType]$BorderType = [BorderType]::None, [Parameter(Mandatory=$false)] [ValidateSet("Black", "DarkBlue", "DarkGreen", "DarkCyan", "DarkRed", "DarkMagenta", "DarkYellow", "Gray", "DarkGray", "Blue", "Green", "Cyan", "Red", "Magenta", "Yellow", "White")] [string]$TextColor = "White", [Parameter(Mandatory=$false)] [ValidateSet("Black", "DarkBlue", "DarkGreen", "DarkCyan", "DarkRed", "DarkMagenta", "DarkYellow", "Gray", "DarkGray", "Blue", "Green", "Cyan", "Red", "Magenta", "Yellow", "White")] [string]$BorderColor = "Gray", [Parameter(Mandatory=$false)] [switch]$Timestamp = $false ) begin { Invoke-TimeSignal -Start # Save the current state of the PSFramework message style settings $originalTimestampSetting = (Get-PSFConfig -Module PSFramework -Name 'Message.Style.Timestamp').Value $originalFunctionNameSetting = (Get-PSFConfig -Module PSFramework -Name 'Message.Style.FunctionName').Value # Apply the detailed info setting if ($Timestamp) { Set-PSFConfig -Module PSFramework -Name 'Message.Style.Timestamp' -Value $true Set-PSFConfig -Module PSFramework -Name 'Message.Style.FunctionName' -Value $false } else { Set-PSFConfig -Module PSFramework -Name 'Message.Style.Timestamp' -Value $false Set-PSFConfig -Module PSFramework -Name 'Message.Style.FunctionName' -Value $false } $border = Get-BorderSymbol -BorderType $BorderType $fontDirectory = "$ModuleRoot\internal\misc\Fonts" $fontFilePath = Join-Path $fontDirectory "$Font.flf" # Load .flf file lines $flfLines = (Get-Content -Path $fontFilePath -Raw -ErrorAction Stop -Encoding UTF8) -split "`r?`n" # Parse metadata from the first line $headerParts = $flfLines[0].Split(' ') $charHeight = [int]$headerParts[1] $commentLines= [int]$headerParts[5] # Skip header + comment lines $startIndex = 1 + $commentLines # Build a dictionary of ASCII art for each printable character $charMap = @{ } $asciiCode = 32 # Start from space (ASCII 32) } PROCESS { $linePos = $startIndex while ($linePos -lt $flfLines.Count) { $charLines = @() for ($i = 0; $i -lt $charHeight; $i++) { if ($linePos -ge $flfLines.Count) { break } $charLines += $flfLines[$linePos] $linePos++ } $charMap[$asciiCode] = $charLines $asciiCode++ # Stop if we've passed typical ASCII printable range if ($asciiCode -gt 126) { break } } # Generate ASCII art lines for input text $outputLines = New-Object System.Collections.Generic.List[string] for ($row = 0; $row -lt $charHeight; $row++) { $rowBuilder = " " foreach ($c in $Text.ToCharArray()) { $charCode = [int][char]$c if ($charMap.ContainsKey($charCode)) { $rowText = $charMap[$charCode][$row] # Logic to handle '@' replacements if ($rowText -eq "@") { $rowText = " " } elseif ($rowText.EndsWith("@")) { $rowText = $rowText.TrimEnd("@") } # Logic to handle '$' replacements if ($rowText -eq "$") { $rowText = " " } elseif ($rowText.EndsWith("$")) { $rowText = $rowText.TrimEnd("$") } $rowBuilder += $rowText } else { $rowBuilder += "?" # fallback if not in font map } } $rowBuilder += " " $outputLines.Add($rowBuilder) } if ($outputLines[-1].Replace(" ", "").Length -eq 0) { $outputLines.RemoveAt($outputLines.Count - 1) # Remove last line of whitespace } # Determine max line length $maxLen = ($outputLines | ForEach-Object { $_.Length } | Measure-Object -Maximum).Maximum # Calculate the total width of the content including side borders $totalWidth = $maxLen if ($BorderType -ne [BorderType]::None) { # Repeat spacer patterns to match the required total width $topBorder = $border.TopSpacer * ([math]::Ceiling($totalWidth / $border.TopSpacer.Length)) $topBorder = $topBorder.Substring(0, $topBorder.Length) # Trim to exact length $bottomBorder = $border.BottomSpacer * [math]::Ceiling($totalWidth / $border.BottomSpacer.Length) $bottomBorder = $bottomBorder.Substring(0, $bottomBorder.Length) # Trim to exact length # Draw top border $topBorderLine = $border.TopLeft + $topBorder + $border.TopRight Write-PSFMessage -Level Important -Message ('<c="'+$BorderColor.ToLower()+'">' + $topBorderLine + "</c>") # Draw lines, padding each to the max length foreach ($line in $outputLines) { $curLineLength = $line.Length + $border.LeftSpacer.Length + $border.RightSpacer.Length $curAdvDifference = ($topBorderLine.Length - ($curLineLength)) $padded = $line.PadRight($maxLen + $curAdvDifference) Write-PSFMessage -Level Important -Message ('<c="'+$BorderColor.ToLower()+'">' + "$($border.LeftSpacer)" + "</c>" + '<c="'+$TextColor.ToLower()+'">' + $padded +"</c>" + '<c="'+$BorderColor.ToLower()+'">' + "$($border.RightSpacer)" + "</c>") } # Draw bottom border Write-PSFMessage -Level Host -Message ('<c="'+$BorderColor.ToLower()+'">' + $border.BottomLeft + $bottomBorder + $border.BottomRight + "</c>") } else { # Draw lines without borders foreach ($line in $outputLines) { Write-PSFMessage -Level Host -Message ('<c="'+$TextColor.ToLower()+'">' + $line + "</c>") } } } END { # Restore the original state of the PSFramework message style settings Set-PSFConfig -Module PSFramework -Name 'Message.Style.Timestamp' -Value $originalTimestampSetting Set-PSFConfig -Module PSFramework -Name 'Message.Style.FunctionName' -Value $originalFunctionNameSetting Invoke-TimeSignal -End } } |