PoshCode Logo PowerShell Code Repository

Write-ASCII-Letters by bogdan 3 years ago (modification of post by Joakim view diff)
View followups from izulthea and CAIRO AG | diff | embed code: <script type="text/javascript" src="http://PoshCode.org/embed/4792"></script>download | new post

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

  1. #
  2. #.SYNOPSIS
  3. # Svendsen Tech's PowerShell ASCII art script creates ASCII art characters
  4. # from a subset of common letters, numbers and punctuation characters.
  5. # You can add new characters by editing the XML and updating the
  6. # $AcceptedChars regexp.
  7. #
  8. # Author: Joakim Svendsen, Svendsen Tech
  9. #
  10. #.DESCRIPTION
  11. # This script reads characters (it started out as letters so the variable
  12. # names are not precise) from an XML file. If you include new characters
  13. # in the XML, you will need to add them to the regular expression assigned
  14. # to the variable $AcceptedChars.
  15. #
  16. # It was written to be used in conjunction with a modified version of
  17. # PowerBot (http://poshcode.org/2510), a simple IRC bot framework written
  18. # using SmartIrc4Net; that's why it prepends an apostrophe by default
  19. # because somewhere along the way the leading spaces get lost before it
  20. # hits the IRC channel.
  21. #
  22. # Currently the XML only contains lowercase letters.
  23. #
  24. # Example:
  25. # PS E:\ASCII-letters> .\Write-ASCII-Letters.ps1 -NoPrependChar "ASCII!"
  26. #                    _  _  _
  27. #   __ _  ___   ___ (_)(_)| |
  28. #  / _` |/ __| / __|| || || |
  29. # | (_| |\__ \| (__ | || ||_|
  30. #  \__,_||___/ \___||_||_|(_)
  31. # PS E:\ASCII-letters>
  32. #
  33. #.PARAMETER InputText
  34. # String(s) to convert to ASCII.
  35. #.PARAMETER NoPrependChar
  36. # Makes the script not prepend an apostrophe.
  37. #.PARAMETER TextColor
  38. # Optional. Console only. Changes color of output.
  39. #>
  40.  
  41. param(
  42.     [string[]] $InputText,
  43.     [switch] $NoPrependChar,
  44.     [string] $TextColor = 'Default'
  45.     #[int] $MaxChars = '25'  
  46.     )
  47.  
  48. Set-StrictMode -Version Latest
  49. $ErrorActionPreference = 'Stop'
  50.  
  51. # Populate the $Letters hashtable with character data from the XML.
  52. Function Parse-LetterXML {
  53.    
  54.     $LetterFile = '.\letters.xml'
  55.     $Xml = [xml] (Get-Content $LetterFile)
  56.    
  57.     $Xml.Letters.Letter | ForEach-Object {
  58.        
  59.         $Letters.($_.Name) = New-Object PSObject -Property @{
  60.            
  61.             'Lines' = $_.Lines
  62.             'ASCII' = $_.Data
  63.             'Width' = $_.Width
  64.         }
  65.        
  66.     }
  67.    
  68. }
  69.  
  70. # Algorithm from hell... This was painful. I hope there's a better way.
  71. function Create-ASCII-Text {
  72.    
  73.     param([string] $Text)
  74.    
  75.     $LetterArray = [char[]] $Text.ToLower()
  76.    
  77.     #Write-Host -fore green $LetterArray
  78.    
  79.     # Find the letter with the most lines.
  80.     $MaxLines = 0
  81.     $LetterArray | ForEach-Object { if ($Letters.([string] $_).Lines -gt $MaxLines ) { $MaxLines = $Letters.([string] $_).Lines } }
  82.    
  83.     $LetterWidthArray = $LetterArray | ForEach-Object { $Letter = [string] $_; $Letters.$Letter.Width }
  84.     $LetterLinesArray = $LetterArray | ForEach-Object { $Letter = [string] $_; $Letters.$Letter.Lines }
  85.    
  86.     #$LetterLinesArray
  87.    
  88.     $Lines = @{
  89.         '1' = ''
  90.         '2' = ''
  91.         '3' = ''
  92.         '4' = ''
  93.         '5' = ''
  94.         '6' = ''
  95.     }
  96.    
  97.     #$LineLengths = @(0, 0, 0, 0, 0, 0)
  98.        
  99.     $LetterPos = 0
  100.     foreach ($Letter in $LetterArray) {
  101.        
  102.         # We need to work with strings for indexing the hash by letter
  103.         $Letter = [string] $Letter
  104.        
  105.         # Each ASCII letter can be from 4 to 6 lines.
  106.        
  107.         # If the letter has the maximum of 6 lines, populate hash with all lines.
  108.         if ($LetterLinesArray[$LetterPos] -eq 6) {
  109.            
  110.             foreach ($Num in 1..6) {
  111.                
  112.                 $StringNum = [string] $Num
  113.                
  114.                 $LineFragment = [string](($Letters.$Letter.ASCII).Split("`n"))[$Num-1]
  115.                
  116.                 if ($LineFragment.Length -lt $Letters.$Letter.Width) {
  117.                     $LineFragment += ' ' * ($Letters.$Letter.Width - $LineFragment.Length)
  118.                 }
  119.                
  120.                 $Lines.$StringNum += $LineFragment
  121.                
  122.             }
  123.            
  124.         }
  125.        
  126.         # Add padding for line 6 for letters with 5 lines and populate lines 2-6.
  127.         elseif ($LetterLinesArray[$LetterPos] -eq 5) {
  128.            
  129.             $Padding = ' ' * $LetterWidthArray[$LetterPos]
  130.             $Lines.'1' += $Padding
  131.            
  132.             foreach ($Num in 2..6) {
  133.                
  134.                 $StringNum = [string] $Num
  135.                
  136.                 $LineFragment = [string](($Letters.$Letter.ASCII).Split("`n"))[$Num-2]
  137.                
  138.                 if ($LineFragment.Length -lt $Letters.$Letter.Width) {
  139.                     $LineFragment += ' ' * ($Letters.$Letter.Width - $LineFragment.Length)
  140.                 }
  141.                    
  142.                 $Lines.$StringNum += $LineFragment
  143.                
  144.             }
  145.        
  146.            
  147.         }
  148.        
  149.         # Here we deal with letters with four lines.
  150.         # Dynamic algorithm that places four-line letters on the bottom line if there are
  151.         # 4 or 5 lines only in the letter with the most lines.
  152.         else {
  153.            
  154.             # Default to putting the 4-liners at line 3-6
  155.             $StartRange, $EndRange, $IndexSubtract = 3, 6, 3
  156.             $Padding = ' ' * $LetterWidthArray[$LetterPos]
  157.            
  158.             # If there are 4 or 5 lines...
  159.             if ($MaxLines -lt 6) {
  160.                
  161.                 $Lines.'2' += $Padding
  162.                
  163.             }
  164.            
  165.             # There are 6 lines maximum, put 4-line letters in the middle.
  166.             else {
  167.                
  168.                 $Lines.'1' += $Padding
  169.                 $Lines.'6' += $Padding
  170.                 $StartRange, $EndRange, $IndexSubtract = 2, 5, 2
  171.                
  172.             }
  173.            
  174.             # There will always be at least four lines. Populate lines 2-5 or 3-6 in the hash.
  175.             foreach ($Num in $StartRange..$EndRange) {
  176.                
  177.                 $StringNum = [string] $Num
  178.                
  179.                 $LineFragment = [string](($Letters.$Letter.ASCII).Split("`n"))[$Num-$IndexSubtract]
  180.                
  181.                 if ($LineFragment.Length -lt $Letters.$Letter.Width) {
  182.                     $LineFragment += ' ' * ($Letters.$Letter.Width - $LineFragment.Length)
  183.                 }
  184.                
  185.                 $Lines.$StringNum += $LineFragment
  186.                
  187.             }
  188.                
  189.         }
  190.                    
  191.         $LetterPos++
  192.        
  193.     } # end of LetterArray foreach
  194.    
  195.     # Return stuff
  196.     $Lines.GetEnumerator() | Sort Name | Select -ExpandProperty Value | ?{ $_ -match '\S' } | %{ if ($NoPrependChar) { $_ } else { "'" + $_ } }
  197.    
  198. }
  199.  
  200. # Get ASCII art letters/characters and data from XML.
  201. $Letters = @{}
  202. Parse-LetterXML
  203.  
  204. # Turn the [string[]] into a [string] the only way I could figure out how... wtf
  205. $Text = ''
  206. $InputText | ForEach-Object { $Text += "$_ " }
  207.  
  208. # Limit to 30 characters
  209. $MaxChars = 30
  210. if ($Text.Length -gt $MaxChars) { "Too long text. There's a maximum of $MaxChars characters."; exit }
  211.  
  212. # Replace spaces with underscores.
  213. $Text = $Text -replace ' ', '_'
  214.  
  215. # Define accepted characters (which are found in XML).
  216. $AcceptedChars = '[^a-z0-9 _,!?./;:<>(){}\[\]''\-\\"זרו]' # זרו only works when sent as UTF-8 on IRC
  217. if ($Text -match $AcceptedChars) { "Unsupported character, using this 'accepted chars' regex: $AcceptedChars."; exit }
  218.  
  219. # Filthy workaround (now worked around in the foreach creating the string).
  220. #if ($Text.Length -eq 1) { $Text += '_' }
  221.  
  222. $Lines = @()
  223. $ASCII = Create-ASCII-Text $Text
  224.  
  225. if ($TextColor -ne 'Default') { Write-Host -ForegroundColor $TextColor ($ASCII -join "`n") }
  226. else { $ASCII }

Submit a correction or amendment below (
click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:


Remember me