package App::Mobirc::Plugin::HTMLFilter::NickGroup; use strict; use MooseX::Plaggerize::Plugin; use List::Util qw/first/; use XML::LibXML; use Encode; has 'map' => ( is => 'ro', isa => 'HashRef', required => 1, ); # nick -> who_class ("nick_" + groupname) has class_for => ( is => 'ro', isa => 'HashRef', lazy => 1, default => sub { my $self = shift; my %groups = %{ $self->map }; my %class_for; while ( my ( $group, $nicks ) = each %groups ) { for my $nick ( @{$nicks} ) { push @{ $class_for{$nick} }, "nick_" . $group; } } \%class_for; }, ); hook 'html_filter' => sub { my ($self, $global_context, $c, $html) = @_; my $doc = eval { XML::LibXML->new->parse_html_string($html); }; if ($@) { warn $@; return ($c, $html); } for my $elem ($doc->findnodes(q{//span[@class='nick_normal']})) { if (my $who = $elem->findvalue('./text()')) { $who =~ s!^\((.+)\)$!$1!; # (who) => who if (my $new_class = $self->_class($who)) { $elem->setAttribute(class => $new_class); } } } $html = $doc->toStringHTML(); $html =~ s{]*>\s*}{}; $html =~ s{(]+)/>}{$1>}gi; return ($c, decode($doc->encoding || "UTF-8", $html)); }; sub _class { my ($self, $nick) = @_; if ($nick = first { $nick =~ /^$_/i } keys %{ $self->class_for }) { return join ' ', @{ $self->class_for->{$nick} }; } else { return; } } 1; =head1 AUTHOR id:hirose31 & id:tokuhirom