Category: Utility Scripts
Author/Contact Info runrig
Description: Display an ascii chart similar to the ascii man page, in a variety of formats.
# Display ascii table
# (Some unix systems have an 'ascii' man page which displays
#  an ascii table; mine doesn't, so I cooked this up)
# takes optional format string
# Usage: ascii [D|a|k|d|b|h]...
# D=Description a=abbreviation k=Keyboard d=Decimal b=Binary h=Hex
# e.g.: ascii hD
# (Default is "ha")

use strict;
use warnings;

my $display = @ARGV ? join('', @ARGV) : "ha";
$display =~ tr/-//d;

my @names = qw(Description Abbr Keybd Dec Binary Hex);
my @lengths=qw(-21           -3    -7   3      8   2);
my %lengths; @lengths{@names} = @lengths;
my %show;
my @show = qw(D a k d b h);
@show{@show} = @names;
my $show_str = join("|", @show);

my $usage_str = <<EOT;
Usage: ascii [$show_str]...
D = description
a = abbreviation
k = keybd
d = decimal
b = binary
h = hex
(Default: ha)

my @display = map { $show{$_} || die "Bad field $_\n$usage_str"
                  } split '', $display;
die "No fields to display\n" unless @display;

my @ascii;
while (<DATA>) {
 next if /^#/ or /^\s*$/;
 my @fields;
 # Read in pipe delimited file (pipes are escaped)
 push @fields, $1 while /((?:\\.|[^|])+)/g;
 s/\\(.)/$1/g for @fields;
 my %fields; @fields{@names} = @fields;
 push @ascii, \%fields;

my $max = 70;
my $spaces = 3;
my $hdr = ' ' x $spaces;
my $hdr_txt = sprintf
       map { "%-" . (abs($lengths{$_})+$spaces) ."s" } @display
$hdr .= $hdr_txt while length($hdr.$hdr_txt)-$spaces <= $max;
print "$hdr\n";

my $line = '';
for my $asc (@ascii) {
  my $tmp_line = '';
  for my $fld (@display) {
    $tmp_line .= " - " if $tmp_line;
    $tmp_line .= sprintf("%$lengths{$fld}s", $asc->{$fld});
  if ((length($line) + length($tmp_line) + 3) > $max) {
    print "$line\n";
    $line = "   $tmp_line";
  } else {
    $line .= "   $tmp_line";
print "$line\n" if $line;
# Description|Abbrev|Keybd|Decimal|Binary|Hex
Null|NUL|Ctrl @|0|00000000|00
Start of Heading|SOH|Ctrl A|1|00000001|01
Start of Text|STX|Ctrl B|2|00000010|02
End of Text|ETX|Ctrl C|3|00000011|03
End of Transmit|EOT|Ctrl D|4|00000100|04
Enquiry|ENQ|Ctrl E|5|00000101|05
Acknowledge|ACK|Ctrl F|6|00000110|06
Bell|BEL|Ctrl G|7|00000111|07
Back Space|BS|Ctrl H|8|00001000|08
Horizontal Tab|TAB|Ctrl I|9|00001001|09
Line Feed|LF|Ctrl J|10|00001010|0A
Vertical Tab|VT|Ctrl K|11|00001011|0B
Form Feed|FF|Ctrl L|12|00001100|0C
Carriage Return|CR|Ctrl M|13|00001101|0D
Shift Out|SO|Ctrl N|14|00001110|0E
Shift In|SI|Ctrl O|15|00001111|0F
Data Line Escape|DLE|Ctrl P|16|00010000|10
Device Control 1|DC1|Ctrl Q|17|00010001|11
Device Control 2|DC2|Ctrl R|18|00010010|12
Device Control 3|DC3|Ctrl S|19|00010011|13
Device Control 4|DC4|Ctrl T|20|00010100|14
Negative Acknowledge|NAK|Ctrl U|21|00010101|15
Synchronous Idle|SYN|Ctrl V|22|00010110|16
End of Transmit Block|ETB|Ctrl W|23|00010111|17
Cancel|CAN|Ctrl X|24|00011000|18
End of Medium|EM|Ctrl Y|25|00011001|19
Substitute|SUB|Ctrl Z|26|00011010|1A
Escape|ESC|Ctrl [|27|00011011|1B
File Separator|FS|Ctrl \\|28|00011100|1C
Group Separator|GS|Ctrl ]|29|00011101|1D
Record Separator|RS|Ctrl ^|30|00011110|1E
Unit Separator|US|Ctrl _|31|00011111|1F
Space| | |32|00100000|20
Exclamation Point|!|Shift 1|33|00100001|21
Double Quote|"|Shift `|34|00100010|22
Pound/Number Sign|#|Shift 3|35|00100011|23
Dollar Sign|$|Shift 4|36|00100100|24
Percent Sign|%|Shift 5|37|00100101|25
Ampersand|&|Shift 7|38|00100110|26
Single Quote|'|'|39|00100111|27
Left Parenthesis|(|(|40|00101000|28
Right Parenthesis|)|)|41|00101001|29
Hyphen / Minus Sign|-|-|45|00101101|2D
Forward Slash|/|/|47|00101111|2F
Zero Digit|0|0|48|00110000|30
One Digit|1|1|49|00110001|31
Two Digit|2|2|50|00110010|32
Three Digit|3|3|51|00110011|33
Four Digit|4|4|52|00110100|34
Five Digit|5|5|53|00110101|35
Six Digit|6|6|54|00110110|36
Seven Digit|7|7|55|00110111|37
Eight Digit|8|8|56|00111000|38
Nine Digit|9|9|57|00111001|39
Colon|:|Shift ;|58|00111010|3A
Less-Than Sign|<|Shift ,|60|00111100|3C
Equals Sign|=|=|61|00111101|3D
Greater-Than Sign|>|Shift .|62|00111110|3E
Question Mark|?|Shift /|63|00111111|3F
At Sign|@|Shift 2|64|01000000|40
Capital A|A|Shift A|65|01000001|41
Capital B|B|Shift B|66|01000010|42
Capital C|C|Shift C|67|01000011|43
Capital D|D|Shift D|68|01000100|44
Capital E|E|Shift E|69|01000101|45
Capital F|F|Shift F|70|01000110|46
Capital G|G|Shift G|71|01000111|47
Capital H|H|Shift H|72|01001000|48
Capital I|I|Shift I|73|01001001|49
Capital J|J|Shift J|74|01001010|4A
Capital K|K|Shift K|75|01001011|4B
Capital L|L|Shift L|76|01001100|4C
Capital M|M|Shift M|77|01001101|4D
Capital N|N|Shift N|78|01001110|4E
Capital O|O|Shift O|79|01001111|4F
Capital P|P|Shift P|80|01010000|50
Capital Q|Q|Shift Q|81|01010001|51
Capital R|R|Shift R|82|01010010|52
Capital S|S|Shift S|83|01010011|53
Capital T|T|Shift T|84|01010100|54
Capital U|U|Shift U|85|01010101|55
Capital V|V|Shift V|86|01010110|56
Capital W|W|Shift W|87|01010111|57
Capital X|X|Shift X|88|01011000|58
Capital Y|Y|Shift Y|89|01011001|59
Capital Z|Z|Shift Z|90|01011010|5A
Left Bracket|[|[|91|01011011|5B
Backward Slash|\\|\\|92|01011100|5C
Right Bracket|]|]|93|01011101|5D
Caret|^|Shift 6|94|01011110|5E
Underscore|_|Shift -|95|01011111|5F
Back Quote|`|`|96|01100000|60
Lower-case A|a|A|97|01100001|61
Lower-case B|b|B|98|01100010|62
Lower-case C|c|C|99|01100011|63
Lower-case D|d|D|100|01100100|64
Lower-case E|e|E|101|01100101|65
Lower-case F|f|F|102|01100110|66
Lower-case G|g|G|103|01100111|67
Lower-case H|h|H|104|01101000|68
Lower-case I|I|I|105|01101001|69
Lower-case J|j|J|106|01101010|6A
Lower-case K|k|K|107|01101011|6B
Lower-case L|l|L|108|01101100|6C
Lower-case M|m|M|109|01101101|6D
Lower-case N|n|N|110|01101110|6E
Lower-case O|o|O|111|01101111|6F
Lower-case P|p|P|112|01110000|70
Lower-case Q|q|Q|113|01110001|71
Lower-case R|r|R|114|01110010|72
Lower-case S|s|S|115|01110011|73
Lower-case T|t|T|116|01110100|74
Lower-case U|u|U|117|01110101|75
Lower-case V|v|V|118|01110110|76
Lower-case W|w|W|119|01110111|77
Lower-case X|x|X|120|01111000|78
Lower-case Y|y|Y|121|01111001|79
Lower-case Z|z|Z|122|01111010|7A
Left Brace|{|Shift [|123|01111011|7B
Vertical Bar|\||Shift \\|124|01111100|7C
Right Brace|}|Shift ]|125|01111101|7D
Tilde|~|Shift `|126|01111110|7E
Replies are listed 'Best First'.
Re: Ascii Chart
by steves (Curate) on Feb 25, 2003 at 03:07 UTC

    Hmmmm ... no octal. Now I feel old.

Re: Ascii Chart
by belg4mit (Prior) on Feb 25, 2003 at 17:35 UTC
    At the author's behest, a somehwat exhaustive list of nits.
    • The need is not apparent
    • Storing the ord, instead of using $./the index
    • Storing the ord in so many formats when perl provides conversion functions
    • Maybe use format and write?
    • UPDATE: Since it's a line per entry anyways, the ability to customize the output is overkill
    • Extensibility? ie; support for EBDIC, locale specific code pages, or unicode?
    • "n Digit" would look better and be more consistent as as "Digit n"
    • Lower-case vs. Capital

    I'm not belgian but I play one on TV.

      The data already existed, so when I wrote the program I tried to do as little work as possible to format it. I disagree with the 'apparent need', though, since if there was no need there wouldn't be an ascii man page on the systems that have one (of course, on those systems with an ascii man page, I agree that there is no apparent need for this script).

      I thought about using printf to format the numbers rather than leaving them hard coded, but at the time I liked the idea of leaving it hard-coded for easy viewing and re-usability of the data (and it required less work on my part). And using $. is a good idea, but likewise I'd rather be able to look at the data and see which line is which.

      If I were to use formats, format and write would probably have to be formline and $^A since the format is dynamic, but that and EBCDIC and locale specific code pages and unicode are left as projects for those with more time than I have :-)

      Taking out the hard coding of the hex and binary numbers wasn't too hard though, so here's my first pass at that (I may add octal later)(Update: Added octal - didn't want to do it until I tested it, and zentara is right, it was easy enough):

Re: Ascii Chart
by zentara (Archbishop) on Feb 25, 2003 at 19:26 UTC
    Well it was easy enough to add octal to your code, I won't post it because, it's a big program. I will say that this makes a nice cheat-sheet wall hanging. If you are using linux, do:
    ./abovescript -Dakdbh > ascii.txt a2ps -P display ascii.txt
    Then print from gv.