AozoraBunko-Checkerkun

 view release on metacpan or  search on metacpan

lib/AozoraBunko/Checkerkun.pm  view on Meta::CPAN

package AozoraBunko::Checkerkun;
our $VERSION = "0.12";

use 5.008001;
use strict;
use warnings;
use utf8;

use Carp           qw//;
use File::ShareDir qw//;
use YAML::Tiny     qw//;
use Encode         qw//;
use Lingua::JA::Halfwidth::Katakana;

my $YAML_FILE = File::ShareDir::dist_file('AozoraBunko-Checkerkun', 'hiden_no_tare.yml');
my $YAML = YAML::Tiny->read($YAML_FILE)->[0];
my $ENC = Encode::find_encoding("Shift_JIS");

my %VALID_OUTPUT_FORMAT;
@VALID_OUTPUT_FORMAT{qw/plaintext html/} = ();

# [78hosetsu_tekiyo] 78互換包摂の対象となる不要な外字注記をチェックする
our $KUTENMEN_78HOSETSU_TEKIYO = $YAML->{'kutenmen_78hosetsu_tekiyo'};

# [hosetsu_tekiyo] 包摂の対象となる不要な外字注記をチェックする
our $KUTENMEN_HOSETSU_TEKIYO = $YAML->{'kutenmen_hosetsu_tekiyo'};

# 新JIS漢字で包摂基準の適用除外となる104字
our $JYOGAI = $YAML->{'jyogai'};

# 78互換文字
our $J78 = $YAML->{'j78'};

# 間違えやすい文字
# かとうかおりさんの「誤認識されやすい文字リスト」から
# http://plaza.users.to/katokao/digipr/digipr_charlist.html
our $GONIN1 = $YAML->{'gonin1'};

# 誤認2
our $GONIN2 = $YAML->{'gonin2'};

# 誤認3
# (砂場清隆さんの入力による)
our $GONIN3 = $YAML->{'gonin3'};

# 新字体・旧字体対応リスト
our $KYUJI = $YAML->{'kyuji'};

# 異体字
our $ITAIJI = $YAML->{'itaiji'};

sub _default_options
{
    return {
        'gaiji'            => 1, # JIS外字をチェックする
        'hansp'            => 1, # 半角スペースをチェックする
        'hanpar'           => 1, # 半角カッコをチェックする
        'zensp'            => 0, # 全角スペースをチェックする
        'zentilde'         => 1, # 全角チルダをチェックする
        '78hosetsu_tekiyo' => 1, # 78互換包摂の対象となる不要な外字注記をチェックする
        'hosetsu_tekiyo'   => 1, # 包摂の対象となる不要な外字注記をチェックする
        '78'               => 0, # 78互換包摂29字をチェックする
        'jyogai'           => 0, # 新JIS漢字で包摂規準の適用除外となる104字をチェックする
        'gonin1'           => 0, # 誤認しやすい文字をチェックする(1)
        'gonin2'           => 0, # 誤認しやすい文字をチェックする(2)
        'gonin3'           => 0, # 誤認しやすい文字をチェックする(3)
        'simplesp'         => 0, # 半角スペースは「_」で、全角スペースは「□」で出力する
        'kouetsukun'       => 0, # 旧字体置換可能チェッカー「校閲君」を有効にする
        'output_format'    => 'plaintext', # plaintext または html
    };
}

sub new
{
    my $class = shift;
    my %args  = (ref $_[0] eq 'HASH' ? %{$_[0]} : @_);

    my $options = $class->_default_options;

    for my $key (keys %args)
    {
        if ( ! exists $options->{$key} ) { Carp::croak "Unknown option: '$key'"; }
        else
        {
            if ($key eq 'output_format')
            {
                Carp::croak "Output format option must be 'plaintext' or 'html'" unless exists $VALID_OUTPUT_FORMAT{ $args{$key} };
            }

            $options->{$key} = $args{$key};
        }
    }

    bless $options, $class;
}

sub _tag_html
{
    my ($plaintext, $tag_name, $msg) = @_;

    return qq|<span data-checkerkun-tag="$tag_name">$plaintext</span>| unless defined $msg;
    return qq|<span data-checkerkun-tag="$tag_name" data-checkerkun-message="$msg">$plaintext</span>|;
}

# 例:
#
# ※[#「口+亞」、第3水準1-15-8、144-上-9]
# が
# ※[#「口+亞」、第3水準1-15-8、144-上-9]→[78hosetsu_tekiyo]【唖】
# に変換され、
#
# ※[#「にんべん+曾」、第3水準1-14-41、144-上-9]
# が
# ※[#「にんべん+曾」、第3水準1-14-41、144-上-9]→[hosetsu_tekiyo]【僧】
# に変換される。
#
sub _check_all_hosetsu_tekiyo
{
    my ($self, $chars_ref, $index) = @_;

    my ($replace, $usedlen);

    my $rear_index = $index + 80;
    $rear_index = $#{$chars_ref} if $rear_index > $#{$chars_ref};

    if ( join("", @{$chars_ref}[$index .. $rear_index]) =~ /^(※[#.*?水準(\d+\-\d+\-\d+).*?])/ )
    {
        my ($match, $kutenmen) = ($1, $2);

        if ( $self->{'78hosetsu_tekiyo'} && exists $KUTENMEN_78HOSETSU_TEKIYO->{$kutenmen} )
        {
            if ($self->{'output_format'} eq 'plaintext')
            {
                $replace = "$match→[78hosetsu_tekiyo]【$KUTENMEN_78HOSETSU_TEKIYO->{$kutenmen}】";
            }
            elsif ($self->{'output_format'} eq 'html')
            {
                $replace = _tag_html($match, '78hosetsuTekiyo', $KUTENMEN_78HOSETSU_TEKIYO->{$kutenmen});
            }

            $usedlen = length $match;
        }
        elsif ( $self->{'hosetsu_tekiyo'} && exists $KUTENMEN_HOSETSU_TEKIYO->{$kutenmen} )
        {
            if ($self->{'output_format'} eq 'plaintext')
            {
                $replace = "$match→[hosetsu_tekiyo]【$KUTENMEN_HOSETSU_TEKIYO->{$kutenmen}】";



( run in 0.416 second using v1.01-cache-2.11-cpan-7f9471e7e0a )