nickcolor.pl 的に着色してみた

昨日の続き.
例の sed.txt を

s/:[0-9]\{2\} <#twitter@atig\.rb:/ /
s/> / /
s/^C10\([^^O]*\)^O/^[[36m\1^[[m/g
s/@YourNick/^G^[[31m@YourNick^[[m/g

このように変更する.例によって ^C ^O ^[ ^G は制御文字. @YourNick というキーワードで visual bell を鳴らすようにしてみた.
次に, return_colored_line.pl として以下のようなスクリプトを用意.

#!/usr/bin/perl
use strict;
use warnings;
use utf8;

my %saved_colors;
my $color;
my @colors = qw/2 3 4 5 6 7 9 10 11 12 13/;
my %esc_seq = (
  "2"  => "\x1b[34m",
  "3"  => "\x1b[32m",
  "4"  => "\x1b[31m\x1b[1m",
  "5"  => "\x1b[31m",
  "6"  => "\x1b[35m",
  "7"  => "\x1b[33m",
  "8"  => "\x1b[33m\x1b[1m",
  "9"  => "\x1b[32m\x1b[1m",
  "10" => "\x1b[36m",
  "11" => "\x1b[36m\x1b[1m",
  "12" => "\x1b[34m\x1b[1m",
  "13" => "\x1b[35m\x1b[1m",
  "14" => "\x1b[37m",
    );

load_colors();

while( my $line = <STDIN> ){
  my @parts = split(/ /, $line);
  my $nick = $parts[1];
  if( $saved_colors{$nick} ){
    $color = $saved_colors{$nick};
  }
  else {
    $color = simple_hash($nick);
  }
  $parts[1] = "$esc_seq{$color}".$nick."\x1b[m";
  $| = 1; # Avoid buffering
  print "@parts";
}
exit 0;

sub load_colors {
  if( open COLORS, "$ENV{HOME}/.irssi/saved_colors" ){
    while (<COLORS>) {
      # I don't know why this is necessary only inside of irssi
      my @lines = split "\n";
      foreach my $line (@lines) {
        my($nick, $color) = split ":", $line;
        $saved_colors{$nick} = $color;
      }
    }
    close COLORS;
  }
}
sub simple_hash {
  my ($string) = @_;
  chomp $string;
  my @chars = split //, $string;
  my $counter;

  foreach my $char (@chars) {
    $counter += ord $char;
  }

  $counter = $colors[$counter % 11];

  return $counter;
}

nickcolor.pl は Public Domain らしいので,色の計算をしているところをごっそり拝借.

% tail -n 100000 -f `date +%Y.%m.%d.txt` \
  | cat `date +%Y.%m.%d.txt -d '1 days ago'` - \
  | sed -u -f sed.txt \
  | perl return_colored_line.pl

などとすれば, irssi で見慣れた色がついて表示される.

ログを直接参照する形式にしてしまえば,後はパイプでやりたい放題.たとえば keywords.txt, ngwords.txt, footers.txt として

keyword1
keyword2
keyword3
...
ngword1
ngword2
ngword3
...
footer1
footer2
footer3
...

こんなファイルを用意しておいて,

% tail -n 100000 -f `date +%Y.%m.%d.txt` \
  | cat `date +%Y.%m.%d.txt -d '1 days ago'` - \
  | grep --line-buffered -f keywords.txt \
  | grep --line-buffered -v -f ngwords.txt \
  | sed -u -f <(awk '{if($1!="") print "s/" $1 "//g"}' footers.txt) \
  | sed -u -f sed.txt \
  | perl return_colored_line.pl

と叩くと, keywords を含み ngwords を含まない発言を抽出して,そこから footers をカットして出力できる.正規表現が使えるので, twitter 公式のリストより圧倒的に柔軟に TL を快適に出来る.

しかし

Perl を使ってしまったのは失敗だった.中里一日記: 少女まんがにおける暴力のようなもので.