package Locale::TextDomain::OO::Lexicon::Role::ExtractHeader; ## no critic (TidyCode)
use strict;
use warnings;
use Carp qw(confess);
use English qw(-no_match_vars $EVAL_ERROR);
use Moo::Role;
require Safe;
use namespace::autoclean;
our $VERSION = '1.0010';
with qw(
Locale::TextDomain::OO::Lexicon::Role::Constants
);
sub _perlify_plural_forms_ref {
my ($self, $plural_forms_ref) = @_;
${$plural_forms_ref} =~ s{ \b ( nplurals | plural | n ) \b }{\$$1}xmsg;
return;
}
sub _nplurals {
my ($self, $plural_forms) = @_;
$self->_perlify_plural_forms_ref(\$plural_forms);
my $code = <<"EOC";
my \$n = 0;
my (\$nplurals, \$plural);
$plural_forms;
\$nplurals;
EOC
my $nplurals = Safe->new->reval($code)
or confess "Code of Plural-Forms $plural_forms is not safe, $EVAL_ERROR";
return $nplurals;
}
sub _plural {
my ($self, $plural_forms) = @_;
return $plural_forms =~ m{ \b plural= ( [^;\n]+ ) }xms;
}
sub _plural_code {
my ($self, $plural_forms) = @_;
$self->_perlify_plural_forms_ref(\$plural_forms);
my $code = <<"EOC";
sub {
my \$n = shift;
my (\$nplurals, \$plural);
$plural_forms;
return 0 + \$plural;
}
EOC
my $code_ref = Safe->new->reval($code)
or confess "Code $plural_forms is not safe, $EVAL_ERROR";
return $code_ref;
}
sub extract_header_msgstr {
my ($self, $header_msgstr) = @_;
## no critic (ComplexRegexes)
my ( $plural_forms ) = $header_msgstr =~ m{
^
Plural-Forms:
[ ]*
(
nplurals [ ]* [=] [ ]* \d+ [ ]* [;]
[ ]*
plural [ ]* [=] [ ]* [^;\n]+ [ ]* [;]?
[ ]*
)
$
}xms
or confess 'Plural-Forms not found in header';
## use critic (ComplexRegexes)
my ( $charset ) = $header_msgstr =~ m{
^
Content-Type:
[^;]+ [;] [ ]*
charset [ ]* = [ ]*
( [^ ]+ )
[ ]*
$
}xms
or confess 'Content-Type with charset not found in header';
my ( $multiplural_nplurals ) = $header_msgstr =~ m{
^ X-Multiplural-Nplurals: [ ]* ( \d+ ) [ ]* $
}xms;
return {(
nplurals => $self->_nplurals($plural_forms),
plural => $self->_plural($plural_forms),
plural_code => $self->_plural_code($plural_forms),
charset => $charset,
(
$multiplural_nplurals
? ( multiplural_nplurals => $multiplural_nplurals )
: ()
),
)};
}
sub message_array_to_hash {
my ($self, $messages_ref) = @_;
my $length_or_empty_list = sub {
my $item = shift;
defined $item or return;
length $item or return;
return $item;
};
return {
map { ## no critic (ComplexMappings)
my ( $msgctxt, $msgid, $msgid_plural )
= delete @{$_}{ qw( msgctxt msgid msgid_plural ) };
my $msg_key = join $self->msg_key_separator,
$length_or_empty_list->($msgctxt),
join $self->plural_separator,
$length_or_empty_list->($msgid),
$length_or_empty_list->($msgid_plural);
( $msg_key => $_ );
} @{$messages_ref}
};
}
1;
__END__
=head1 NAME
Locale::TextDomain::OO::Lexicon::Role::ExtractHeader - Gettext header extractor
$Id: ExtractHeader.pm 490 2014-05-03 16:23:46Z steffenw $
$HeadURL: svn+ssh://steffenw@svn.code.sf.net/p/perl-gettext-oo/code/module/trunk/lib/Locale/TextDomain/OO/Lexicon/Role/ExtractHeader.pm $
=head1 VERSION
1.010
=head1 DESCRIPTION
This module is extracting charset and plural date from gettext header.
=head1 SYNOPSIS
with qw(
Locale::TextDomain::OO::Lexicon::Role::ExtractHeader
);
=head1 SUBROUTINES/METHODS
=head2 method extract_header_msgstr
$hash_ref = $self->extract_header_msgstr($header_msgstr);
That hash_ref contains:
nplurals => $count_of_plural_forms,
plural => $the_original_formula,
plural_code => $code_ref_to_select_the_right_plural_form,
charset => $charset,
=head2 method message_array_to_hash
Transformation the array of messages to a faster accessable hash
$message_ref = $self->message_array_to_hash($messages_ref);
=head1 EXAMPLE
Inside of this distribution is a directory named example.
Run this *.pl files.
=head1 DIAGNOSTICS
confess
=head1 CONFIGURATION AND ENVIRONMENT
none
=head1 DEPENDENCIES
L<Carp|Carp>
L<English|English>
L<Moo::Role|Moo::Role>
L<Safe|Safe>
L<namespace::autoclean|namespace::autoclean>
L<Locale::TextDomain::OO::Lexicon::Role::Constants|Locale::TextDomain::OO::Lexicon::Role::Constants>
=head1 INCOMPATIBILITIES
not known
=head1 BUGS AND LIMITATIONS
none
=head1 SEE ALSO
L<Locale::TextDoamin::OO|Locale::TextDoamin::OO>
=head1 AUTHOR
Steffen Winkler
=head1 LICENSE AND COPYRIGHT
Copyright (c) 2013 - 2014,
Steffen Winkler
C<< <steffenw at cpan.org> >>.
All rights reserved.
This module is free software;
you can redistribute it and/or modify it
under the same terms as Perl itself.