日本語bannerコマンド

bannerコマンドの日本語版を作ってみました。

(永遠の)やっつけ版なんで細かい突っ込みは受け付けません!

[mikeda@cent banner]$ ./banner_jp.pl 
    ./banner_jp.pl [options] string

     Options:
       -h,--help        brief help message
       -c,--char        use given char for drawing (default:"*")
       -m,--mimcho      use mincho (default:gothic)
       -y,--yoko        tate-gaki
[mikeda@cent banner]$ ./banner_jp.pl -y -c @ "暑いですね"
 @@@@@              @@@     @     @     
 @   @  @   @    @@@ @  @@@@@@@   @ @@  
 @@@@@  @    @      @ @    @@   @@@@  @ 
  @@@   @     @    @      @ @     @   @ 
@@@@@@@ @     @    @       @@    @@  @@ 
  @@ @   @ @        @       @   @ @ @ @ 
@@ @@@    @          @@    @      @  @  

読みづらいwwwwww

ソースコード

フォントは8*8のビットマップフォント、「美咲フォント」を使わせてもらいました。
http://www.geocities.jp/littlimi/misaki.htm
スクリプトと同じディレクトリに展開してください。

# wget http://www.geocities.jp/littlimi/arc/misaki/misaki_bdf_b11a.tar.gz
# tar xvzf misaki_bdf_b11a.tar.gz


ソースコードはこんな感じです。

#!/usr/bin/perl
use strict;
use warnings;
use utf8;
use Encode;
use Getopt::Long;
use File::Basename qw(dirname);
use Data::Dumper;

my %opts;
GetOptions(\%opts, 'mincho', 'yoko', 'char=s', 'help');

my $str = shift;
if(!$str || $opts{help}){
  die << "END";
    $0 [options] string

     Options:
       -h,--help        brief help message
       -c,--char        use given char for drawing (default:"*")
       -m,--mimcho      use mincho (default:gothic)
       -y,--yoko        tate-gaki
END
}
utf8::decode $str;

my $font_file =  $opts{mincho} ? 'misaki_mincho.bdf' : 'misaki_gothic.bdf';
$font_file = dirname($0)."/$font_file";

my @codes  = get_jis_codes($str);
my $banner = get_banner($font_file, \@codes, $opts{char});
print_banner(\@codes, $banner, $opts{yoko});

exit;


sub get_jis_codes {
  my $str = shift;
  my $jis  = encode('iso-2022-jp', $str);
  # メタ文字消去
  $jis =~ s/\x1B..//g;
  # とりあえずのエンディアン対応、リトルはだめよ
  unpack("n*", $jis);
}

sub get_banner {
  my ($font_file, $codes, $char) = @_;
  $char ||= "*";

  open my $fh, "<", $font_file;
  local $/;
  my $bdf = <$fh>;
  close $fh;

  my %banner;
  while($bdf =~ /ENCODING (\d+).*?BITMAP\n((?:\w+\n){8})/msg){
    my $code = $1;
    next unless grep {$_ == $code} @$codes;

    my @bitmap = map {hex $_} split /\n/, $2;
    my @banner;
    for my $line (@bitmap){
      push @banner, join "", map {$line & (128>>$_) ? $char : " "} 0..7;
    }
    $banner{$code} = \@banner;
  }
  \%banner;
}

sub print_banner {
  my ($codes, $banner, $yoko) = @_;

  if($yoko){
    for my $line (0..7){
      print $banner->{$_}->[$line] for @$codes;
      print "\n";
    }
  }else{
    for my $code (@$codes){
      print "$_\n" for @{$banner->{$code}};
    }
  }
}