# encoding: utf-8 # api: powershell # title: Write-ASCII-Letters # description: I initially wrote this ASCII art character script to be used with a modified version of PowerBot 2.0 (ID 2510 on poshcode). It outputs ASCII art letters from what you supply as a parameter (if the characters are supported). Either to STDOUT with Write-Host (colors are supported) or to the pipeline. It’s useless without the XML that’s found at powershelladmin.com. The full article is in my wiki: http://www.powershelladmin.com/wiki/Ascii_art_characters_powershell_script # version: 0.1 # type: script # author: Joakim Svendsen, Svendsen Tech # license: CC0 # function: Parse-LetterXML # x-poshcode-id: 4792 # x-derived-from-id: 6217 # x-archived: 2016-05-20T09:59:45 # x-published: 2016-01-14T16:18:00 # # # #.SYNOPSIS # Svendsen Tech's PowerShell ASCII art script creates ASCII art characters # from a subset of common letters, numbers and punctuation characters. # You can add new characters by editing the XML and updating the # $AcceptedChars regexp. # # Author: Joakim Svendsen, Svendsen Tech # #.DESCRIPTION # This script reads characters (it started out as letters so the variable # names are not precise) from an XML file. If you include new characters # in the XML, you will need to add them to the regular expression assigned # to the variable $AcceptedChars. # # It was written to be used in conjunction with a modified version of # PowerBot (http://poshcode.org/2510), a simple IRC bot framework written # using SmartIrc4Net; that's why it prepends an apostrophe by default # because somewhere along the way the leading spaces get lost before it # hits the IRC channel. # # Currently the XML only contains lowercase letters. # # Example: # PS E:\ASCII-letters> .\Write-ASCII-Letters.ps1 -NoPrependChar "ASCII!" # _ _ _ # __ _ ___ ___ (_)(_)| | # / _` |/ __| / __|| || || | # | (_| |\__ \| (__ | || ||_| # \__,_||___/ \___||_||_|(_) # PS E:\ASCII-letters> # #.PARAMETER InputText # String(s) to convert to ASCII. #.PARAMETER NoPrependChar # Makes the script not prepend an apostrophe. #.PARAMETER TextColor # Optional. Console only. Changes color of output. #> param( [string[]] $InputText, [switch] $NoPrependChar, [string] $TextColor = 'Default' #[int] $MaxChars = '25' ) Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' # Populate the $Letters hashtable with character data from the XML. Function Parse-LetterXML { $LetterFile = '.\letters.xml' $Xml = [xml] (Get-Content $LetterFile) $Xml.Letters.Letter | ForEach-Object { $Letters.($_.Name) = New-Object PSObject -Property @{ 'Lines' = $_.Lines 'ASCII' = $_.Data 'Width' = $_.Width } } } # Algorithm from hell... This was painful. I hope there's a better way. function Create-ASCII-Text { param([string] $Text) $LetterArray = [char[]] $Text.ToLower() #Write-Host -fore green $LetterArray # Find the letter with the most lines. $MaxLines = 0 $LetterArray | ForEach-Object { if ($Letters.([string] $_).Lines -gt $MaxLines ) { $MaxLines = $Letters.([string] $_).Lines } } $LetterWidthArray = $LetterArray | ForEach-Object { $Letter = [string] $_; $Letters.$Letter.Width } $LetterLinesArray = $LetterArray | ForEach-Object { $Letter = [string] $_; $Letters.$Letter.Lines } #$LetterLinesArray $Lines = @{ '1' = '' '2' = '' '3' = '' '4' = '' '5' = '' '6' = '' } #$LineLengths = @(0, 0, 0, 0, 0, 0) $LetterPos = 0 foreach ($Letter in $LetterArray) { # We need to work with strings for indexing the hash by letter $Letter = [string] $Letter # Each ASCII letter can be from 4 to 6 lines. # If the letter has the maximum of 6 lines, populate hash with all lines. if ($LetterLinesArray[$LetterPos] -eq 6) { foreach ($Num in 1..6) { $StringNum = [string] $Num $LineFragment = [string](($Letters.$Letter.ASCII).Split("`n"))[$Num-1] if ($LineFragment.Length -lt $Letters.$Letter.Width) { $LineFragment += ' ' * ($Letters.$Letter.Width - $LineFragment.Length) } $Lines.$StringNum += $LineFragment } } # Add padding for line 6 for letters with 5 lines and populate lines 2-6. elseif ($LetterLinesArray[$LetterPos] -eq 5) { $Padding = ' ' * $LetterWidthArray[$LetterPos] $Lines.'1' += $Padding foreach ($Num in 2..6) { $StringNum = [string] $Num $LineFragment = [string](($Letters.$Letter.ASCII).Split("`n"))[$Num-2] if ($LineFragment.Length -lt $Letters.$Letter.Width) { $LineFragment += ' ' * ($Letters.$Letter.Width - $LineFragment.Length) } $Lines.$StringNum += $LineFragment } } # Here we deal with letters with four lines. # Dynamic algorithm that places four-line letters on the bottom line if there are # 4 or 5 lines only in the letter with the most lines. else { # Default to putting the 4-liners at line 3-6 $StartRange, $EndRange, $IndexSubtract = 3, 6, 3 $Padding = ' ' * $LetterWidthArray[$LetterPos] # If there are 4 or 5 lines... if ($MaxLines -lt 6) { $Lines.'2' += $Padding } # There are 6 lines maximum, put 4-line letters in the middle. else { $Lines.'1' += $Padding $Lines.'6' += $Padding $StartRange, $EndRange, $IndexSubtract = 2, 5, 2 } # There will always be at least four lines. Populate lines 2-5 or 3-6 in the hash. foreach ($Num in $StartRange..$EndRange) { $StringNum = [string] $Num $LineFragment = [string](($Letters.$Letter.ASCII).Split("`n"))[$Num-$IndexSubtract] if ($LineFragment.Length -lt $Letters.$Letter.Width) { $LineFragment += ' ' * ($Letters.$Letter.Width - $LineFragment.Length) } $Lines.$StringNum += $LineFragment } } $LetterPos++ } # end of LetterArray foreach # Return stuff $Lines.GetEnumerator() | Sort Name | Select -ExpandProperty Value | ?{ $_ -match '\S' } | %{ if ($NoPrependChar) { $_ } else { "'" + $_ } } } # Get ASCII art letters/characters and data from XML. $Letters = @{} Parse-LetterXML # Turn the [string[]] into a [string] the only way I could figure out how... wtf $Text = '' $InputText | ForEach-Object { $Text += "$_ " } # Limit to 30 characters $MaxChars = 30 if ($Text.Length -gt $MaxChars) { "Too long text. There's a maximum of $MaxChars characters."; exit } # Replace spaces with underscores. $Text = $Text -replace ' ', '_' # Define accepted characters (which are found in XML). $AcceptedChars = '[^a-z0-9 _,!?./;:<>(){}\[\]''\-\\"æøå]' # æøå only works when sent as UTF-8 on IRC if ($Text -match $AcceptedChars) { "Unsupported character, using this 'accepted chars' regex: $AcceptedChars."; exit } # Filthy workaround (now worked around in the foreach creating the string). #if ($Text.Length -eq 1) { $Text += '_' } $Lines = @() $ASCII = Create-ASCII-Text $Text if ($TextColor -ne 'Default') { Write-Host -ForegroundColor $TextColor ($ASCII -join "`n") } else { $ASCII }