PoshCode Logo PowerShell Code Repository

Difference between
modified post 6671 by CAIRO AG on Sat 7th Jan 04:28 and
original post 4792 by bogdan on Tue 14th Jan 16:18
Showold version | new version | both versions

    
11
#
22
#.SYNOPSIS
33
# Svendsen Tech's PowerShell ASCII art script creates ASCII art characters
44
# from a subset of common letters, numbers and punctuation characters.
55
# You can add new characters by editing the XML and updating the
66
# $AcceptedChars regexp.
77
#
88
# Author: Joakim Svendsen, Svendsen Tech
99
#
1010
#.DESCRIPTION
1111
# This script reads characters (it started out as letters so the variable
1212
# names are not precise) from an XML file. If you include new characters
1313
# in the XML, you will need to add them to the regular expression assigned
1414
# to the variable $AcceptedChars.
1515
#
1616
# It was written to be used in conjunction with a modified version of
1717
# PowerBot (http://poshcode.org/2510), a simple IRC bot framework written
1818
# using SmartIrc4Net; that's why it prepends an apostrophe by default
1919
# because somewhere along the way the leading spaces get lost before it
2020
# hits the IRC channel.
2121
#
2222
# Currently the XML only contains lowercase letters.
2323
#
2424
# Example:
2525
# PS E:\ASCII-letters> .\Write-ASCII-Letters.ps1 -NoPrependChar "ASCII!"
2626
#                    _  _  _
2727
#   __ _  ___   ___ (_)(_)| |
2828
#  / _` |/ __| / __|| || || |
2929
# | (_| |\__ \| (__ | || ||_|
3030
#  \__,_||___/ \___||_||_|(_)
3131
# PS E:\ASCII-letters>
3232
#
3333
#.PARAMETER InputText
3434
# String(s) to convert to ASCII.
3535
#.PARAMETER NoPrependChar
3636
# Makes the script not prepend an apostrophe.
3737
#.PARAMETER TextColor
3838
# Optional. Console only. Changes color of output.
3939
#>
4141
param(
4242
    [string[]] $InputText,
4343
    [switch] $NoPrependChar,
4444
    [string] $TextColor = 'Default'
4545
    #[int] $MaxChars = '25'
4646
    )
4848
Set-StrictMode -Version Latest
4949
$ErrorActionPreference = 'Stop'
5151
# Populate the $Letters hashtable with character data from the XML.
5252
Function Parse-LetterXML {
5454
    $LetterFile = '.\letters.xml'
5555
    $Xml = [xml] (Get-Content $LetterFile)
5757
    $Xml.Letters.Letter | ForEach-Object {
5959
        $Letters.($_.Name) = New-Object PSObject -Property @{
6161
            'Lines' = $_.Lines
6262
            'ASCII' = $_.Data
6363
            'Width' = $_.Width
6464
        }
6666
    }
6868
}
7070
# Algorithm from hell... This was painful. I hope there's a better way.
7171
function Create-ASCII-Text {
7373
    param([string] $Text)
7575
    $LetterArray = [char[]] $Text.ToLower()
7777
    #Write-Host -fore green $LetterArray
7979
    # Find the letter with the most lines.
8080
    $MaxLines = 0
8181
    $LetterArray | ForEach-Object { if ($Letters.([string] $_).Lines -gt $MaxLines ) { $MaxLines = $Letters.([string] $_).Lines } }
8383
    $LetterWidthArray = $LetterArray | ForEach-Object { $Letter = [string] $_; $Letters.$Letter.Width }
8484
    $LetterLinesArray = $LetterArray | ForEach-Object { $Letter = [string] $_; $Letters.$Letter.Lines }
8686
    #$LetterLinesArray
8888
    $Lines = @{
8989
        '1' = ''
9090
        '2' = ''
9191
        '3' = ''
9292
        '4' = ''
9393
        '5' = ''
9494
        '6' = ''
9595
    }
9797
    #$LineLengths = @(0, 0, 0, 0, 0, 0)
9999
    $LetterPos = 0
100100
    foreach ($Letter in $LetterArray) {
102102
        # We need to work with strings for indexing the hash by letter
103103
        $Letter = [string] $Letter
105105
        # Each ASCII letter can be from 4 to 6 lines.
107107
        # If the letter has the maximum of 6 lines, populate hash with all lines.
108108
        if ($LetterLinesArray[$LetterPos] -eq 6) {
110110
            foreach ($Num in 1..6) {
112112
                $StringNum = [string] $Num
114114
                $LineFragment = [string](($Letters.$Letter.ASCII).Split("`n"))[$Num-1]
116116
                if ($LineFragment.Length -lt $Letters.$Letter.Width) {
117117
                    $LineFragment += ' ' * ($Letters.$Letter.Width - $LineFragment.Length)
118118
                }
120120
                $Lines.$StringNum += $LineFragment
122122
            }
124124
        }
126126
        # Add padding for line 6 for letters with 5 lines and populate lines 2-6.
127127
        elseif ($LetterLinesArray[$LetterPos] -eq 5) {
129129
            $Padding = ' ' * $LetterWidthArray[$LetterPos]
130130
            $Lines.'1' += $Padding
132132
            foreach ($Num in 2..6) {
134134
                $StringNum = [string] $Num
136136
                $LineFragment = [string](($Letters.$Letter.ASCII).Split("`n"))[$Num-2]
138138
                if ($LineFragment.Length -lt $Letters.$Letter.Width) {
139139
                    $LineFragment += ' ' * ($Letters.$Letter.Width - $LineFragment.Length)
140140
                }
142142
                $Lines.$StringNum += $LineFragment
144144
            }
147147
        }
149149
        # Here we deal with letters with four lines.
150150
        # Dynamic algorithm that places four-line letters on the bottom line if there are
151151
        # 4 or 5 lines only in the letter with the most lines.
152152
        else {
154154
            # Default to putting the 4-liners at line 3-6
155155
            $StartRange, $EndRange, $IndexSubtract = 3, 6, 3
156156
            $Padding = ' ' * $LetterWidthArray[$LetterPos]
158158
            # If there are 4 or 5 lines...
159159
            if ($MaxLines -lt 6) {
161161
                $Lines.'2' += $Padding
163163
            }
165165
            # There are 6 lines maximum, put 4-line letters in the middle.
166166
            else {
168168
                $Lines.'1' += $Padding
169169
                $Lines.'6' += $Padding
170170
                $StartRange, $EndRange, $IndexSubtract = 2, 5, 2
172172
            }
174174
            # There will always be at least four lines. Populate lines 2-5 or 3-6 in the hash.
175175
            foreach ($Num in $StartRange..$EndRange) {
177177
                $StringNum = [string] $Num
179179
                $LineFragment = [string](($Letters.$Letter.ASCII).Split("`n"))[$Num-$IndexSubtract]
181181
                if ($LineFragment.Length -lt $Letters.$Letter.Width) {
182182
                    $LineFragment += ' ' * ($Letters.$Letter.Width - $LineFragment.Length)
183183
                }
185185
                $Lines.$StringNum += $LineFragment
187187
            }
189189
        }
191191
        $LetterPos++
193193
    } # end of LetterArray foreach
195195
    # Return stuff
196196
    $Lines.GetEnumerator() | Sort Name | Select -ExpandProperty Value | ?{ $_ -match '\S' } | %{ if ($NoPrependChar) { $_ } else { "'" + $_ } }
198198
}
200200
# Get ASCII art letters/characters and data from XML.
201201
$Letters = @{}
202202
Parse-LetterXML
204204
# Turn the [string[]] into a [string] the only way I could figure out how... wtf
205205
$Text = ''
206206
$InputText | ForEach-Object { $Text += "$_ " }
208208
# Limit to 30 characters
209209
$MaxChars = 30
210210
if ($Text.Length -gt $MaxChars) { "Too long text. There's a maximum of $MaxChars characters."; exit }
212212
# Replace spaces with underscores.
213213
$Text = $Text -replace ' ', '_'
215215
# Define accepted characters (which are found in XML).
216216
217217
if ($Text -match $AcceptedChars) { "Unsupported character, using this 'accepted chars' regex: $AcceptedChars."; exit }
219219
# Filthy workaround (now worked around in the foreach creating the string).
220220
#if ($Text.Length -eq 1) { $Text += '_' }
222222
$Lines = @()
223223
$ASCII = Create-ASCII-Text $Text
225225
if ($TextColor -ne 'Default') { Write-Host -ForegroundColor $TextColor ($ASCII -join "`n") }
226226
else { $ASCII }

ContributeMost Recent Contributions (feed)

Contribute ... Next Page