CGI-Kwiki

 view release on metacpan or  search on metacpan

lib/CGI/Kwiki/I18N.pm  view on Meta::CPAN

	next unless UNIVERSAL::isa($src, $type);

	my $method = 'lexicon_get_' . lc($type);
	die "cannot handle source $type for $src: no $method defined"
	    unless $class->can($method);

	return $class->$method($src, $caller, $lang);
    }

    # default handler
    return $class->lexicon_get_($src, $caller, $lang);
}

# assume filename - search path, open and return its contents
sub lexicon_get_ {
    my ($class, $src, $caller, $lang) = @_;

    require FileHandle;
    require File::Spec;

    my $fh = FileHandle->new;
    my @path = split('::', $caller);
    push @path, $lang if length $lang;

    $src = (grep { -e } map {
	my @subpath = @path[0..$_];
	map { File::Spec->catfile($_, @subpath, $src) } @INC;
    } -1 .. $#path)[-1] unless -e $src;

    die "cannot find $_[1] (called by $_[2]) in \@INC" unless -e $src;
    $fh->open($src) or die $!;
    binmode($fh);
    return <$fh>;
}

package CGI::Kwiki::I18N::Lexicon::Gettext;
use strict;

my ($InputEncoding, $OutputEncoding, $DoEncoding);

sub input_encoding { $InputEncoding };
sub output_encoding { $OutputEncoding };

sub parse {
    my $self = shift;
    my (%var, $key, @ret);
    my @metadata;

    $InputEncoding = $OutputEncoding = $DoEncoding = undef;

    # Check for magic string of MO files
    return parse_mo(join('', @_))
	if ($_[0] =~ /^\x95\x04\x12\xde/ or $_[0] =~ /^\xde\x12\x04\x95/);

    local $^W;	# no 'uninitialized' warnings, please.

    my $UseFuzzy = CGI::Kwiki::I18N::Lexicon::option('use_fuzzy');

    # Parse PO files
    foreach (@_) {
	/^(msgid|msgstr) +"(.*)" *$/	? do {	# leading strings
	    $var{$1} = $2;
	    $key = $1;
	} :

	/^"(.*)" *$/			? do {	# continued strings
	    $var{$key} .= $1;
	} :

	/^#, +(.*) *$/			? do {	# control variables
	    $var{$_} = 1 for split(/,\s+/, $1);
	} :

	/^ *$/ && %var			? do {	# interpolate string escapes
	    push @ret, (map transform($_), @var{'msgid', 'msgstr'})
		if length $var{msgstr} and !$var{fuzzy} or $UseFuzzy;
	    push @metadata, parse_metadata($var{msgstr})
		if $var{msgid} eq '';
	    %var = ();
	} : ();
    }

    push @ret, map { transform($_) } @var{'msgid', 'msgstr'}
	if length $var{msgstr};
    push @metadata, parse_metadata($var{msgstr})
	if $var{msgid} eq '';

    return {@metadata, @ret};
}

sub parse_metadata {
    return map {
	(/^([^\x00-\x1f\x80-\xff :=]+):\s*(.*)$/) ?
	    ($1 eq 'Content-Type') ? do {
		my $enc = $2;
		if ($enc =~ /\bcharset=\s*([-\w]+)/i) {
		    $InputEncoding = $1;
		    $OutputEncoding = CGI::Kwiki::I18N::Lexicon::option('encoding');
		    if ( CGI::Kwiki::I18N::Lexicon::option('decode') and
			(!$OutputEncoding or $InputEncoding ne $OutputEncoding)) {
			require Encode::compat if $] < 5.007001;
			require Encode;
			$DoEncoding = 1;
		    }
		}
		("__Content-Type", $enc);
	    } : ("__$1", $2)
	: ();
    } split(/\r*\n+\r*/, transform(pop));
}

sub transform {
    my $str = shift;

    $str = Encode::decode($InputEncoding, $str) if $DoEncoding and $InputEncoding;
    $str =~ s/\\([0x]..|c?.)/qq{"\\$1"}/eeg;
    $str =~ s/[\~\[\]]/~$&/g;
    $str =~ s/(?<![%\\])%([A-Za-z#*]\w*)\(([^\)]*)\)/"\[$1,".unescape($2)."]"/eg;
    $str =~ s/(?<![%\\])%(\d+|\*)/\[_$1]/g;
    $str = Encode::encode($OutputEncoding, $str) if $DoEncoding and $OutputEncoding;

    return $str;
}

sub unescape {
    my $str = shift;
    $str =~ s/(^|,)%(\d+|\*)(,|$)/$1_$2$3/g;
    return $str;
}

1;


### Assorted non-loc()ed localizable strings ###
# loc('HomePage')
# loc('RecentChanges')
# loc('Preferences')
# loc('Blog')
# loc('New Page Name')
# loc('BrianIngerson')
# loc('HomePage')
# loc('???')

# loc('KwikiAbout')
# loc('KwikiBackup')
# loc('KwikiBlog')



( run in 0.794 second using v1.01-cache-2.11-cpan-acf6aa7dc9e )