#!/usr/bin/perl
# ASCII chart generator.
# First argument is the base, hexadecimal by default.
# oatcookies.sdf.org / 2014
#
# Run with perl -CS
use strict;
use warnings;
use utf8;
use feature 'unicode_strings';
use POSIX;

my $base = $ARGV[0];
if (!$base) {
  $base = 16;
}
print("Base is $base\n");

my $row;
my $column;
my $code;

print "    ";

# The header row.
for (my $i = 0; $i < $base; $i++) {
  if ($base == 16) {
    printf(" %x ", $i);
  } else {
    printf(" %d ", $i);
  }
}
print "\n";

# The rows.
my $num_rows = ceil(127 / $base);
for ($row = 0; $row < $num_rows; $row++) {
  my $rowstring;
  if ($base == 16) {
    $rowstring = sprintf(" %x ", $row);
  } else {
    $rowstring = sprintf(" %2d ", $row);
  }
  # The columns in the row.
  for ($column = 0; $column < $base; $column++) {
    $code = ($row * $base) + $column;
    # Old, base16-dependent bit magic
    #$code = (($row<<4)|0b0001111) & ($column|0b1110000);
    if ($code < 32 or $code > 126) {
      # Use Unicode's "Control Pictures" block, U+2400 to U+243F.
      if ($code == 127) {
        $code = 0x2421;
      } elsif ($code > 127) {
        $code = $code;
      } else {
        $code += 0x2400;
      }
      $rowstring .= (' '.chr($code).' ');
    } else {
      $rowstring .= (' '.chr($code).' ');
    }
  }
  print("$rowstring\n");
}

# Posted 2014-11-23
# Syntax coloured Perl-in-HTML by Vim.