CC: | unrtst [...] gmail.com |
Subject: | New feature support - strings marked #| from fuzzy |
Current version of Locale::PO does not recognize nor retain lines marked
with #| or #~| (old values that caused the message to be fuzzy, and
obsolete versions of those respectively).
The attached patch adds support, and adds tests for these as well.
I've used this when calculating the translation cost impact of minor
updates to messages and the addition of context (msgctxt) by comparing
the old string marked with "#| msgid" to the new one.
For example:
#: cgi-bin/employeeProfile.pl:824
#, fuzzy
#| msgctxt "Date as in the noun, the time at which an event occcurs"
#| msgid "Date"
msgctxt "Date as in the noun, the time at which an event occurred"
msgid "Date"
msgstr ""
The attached patch also includes the fix from bug # 40009, which fixes
multi-line obsolete entries.
Subject: | Locale-PO-0.21.patch |
diff -Nrup Locale-PO-0.21/Changes Locale-PO-0.21.patched/Changes
--- Locale-PO-0.21/Changes 2008-05-19 12:17:52.000000000 -0400
+++ Locale-PO-0.21.patched/Changes 2011-02-28 12:40:50.000000000 -0500
@@ -1,5 +1,9 @@
Revision history for Perl extension Locale::PO.
+0.21 Feb 28 2011
+ - Bug #40009 for Locale-PO: Incorrect handling of multi-line obsolete entries
+ - Added support for fuzzy string prefix "#|" and "#~|".
+ (patch provided by Joshua Miller)
0.21 May 19 2008
- BUG #35939 - Locale::PO is now correctly subclassable
(patch provided by Cosimo Streppone)
diff -Nrup Locale-PO-0.21/MANIFEST Locale-PO-0.21.patched/MANIFEST
--- Locale-PO-0.21/MANIFEST 2008-05-19 12:29:16.000000000 -0400
+++ Locale-PO-0.21.patched/MANIFEST 2011-02-28 14:59:41.000000000 -0500
@@ -4,6 +4,8 @@ META.yml
Makefile.PL
PO.pm
README
+t/fuzzy.pot
+t/fuzzy.t
t/plurals.pot
t/plurals.t
t/singular.t
diff -Nrup Locale-PO-0.21/PO.pm Locale-PO-0.21.patched/PO.pm
--- Locale-PO-0.21/PO.pm 2008-05-19 12:21:50.000000000 -0400
+++ Locale-PO-0.21.patched/PO.pm 2011-02-28 14:58:37.000000000 -0500
@@ -1,7 +1,7 @@
package Locale::PO;
use strict;
use warnings;
-our $VERSION = '0.21';
+our $VERSION = '0.22';
use Carp;
@@ -12,6 +12,9 @@ sub new {
my $self = {};
bless $self, $class;
$self->_flags([]);
+ $self->fuzzy_msgid( $options{'-fuzzy_msgid'} ) if defined( $options{'-fuzzy_msgid'} );
+ $self->fuzzy_msgid_plural( $options{'-fuzzy_msgid_plural'} )
+ if defined( $options{'-fuzzy_msgid_plural'} );
$self->msgid( $options{'-msgid'} ) if defined( $options{'-msgid'} );
$self->msgid_plural( $options{'-msgid_plural'} )
if defined( $options{'-msgid_plural'} );
@@ -19,6 +22,7 @@ sub new {
$self->msgstr_n( $options{'-msgstr_n'} )
if defined( $options{'-msgstr_n'} );
$self->msgctxt( $options{'-msgctxt'} ) if defined( $options{'-msgctxt'} );
+ $self->fuzzy_msgctxt( $options{'-fuzzy_msgctxt'} ) if defined( $options{'-fuzzy_msgctxt'} );
$self->comment( $options{'-comment'} ) if defined( $options{'-comment'} );
$self->fuzzy( $options{'-fuzzy'} ) if defined( $options{'-fuzzy'} );
$self->automatic( $options{'-automatic'} )
@@ -33,6 +37,24 @@ sub new {
return $self;
}
+sub fuzzy_msgctxt {
+ my $self = shift;
+ @_ ? $self->{'fuzzy_msgctxt'} = $self->quote(shift) : $self->{'fuzzy_msgctxt'};
+}
+
+sub fuzzy_msgid {
+ my $self = shift;
+ @_ ? $self->{'fuzzy_msgid'} = $self->quote(shift) : $self->{'fuzzy_msgid'};
+}
+
+sub fuzzy_msgid_plural {
+ my $self = shift;
+ @_
+ ? $self->{'fuzzy_msgid_plural'} =
+ $self->quote(shift)
+ : $self->{'fuzzy_msgid_plural'};
+}
+
sub msgctxt {
my $self = shift;
@_ ? $self->{'msgctxt'} = $self->quote(shift) : $self->{'msgctxt'};
@@ -207,9 +229,23 @@ sub _normalize_str {
}
}
+sub _fuzzy_normalize_str {
+ my $self = shift;
+ my $string = shift;
+ my $prefix = shift;
+
+ my $normalized = $self->_normalize_str($string);
+
+ # on newlines, start them with "#| " or "#~| "
+ $normalized =~ s/\n"/\n$prefix"/g;
+
+ return $normalized;
+}
+
sub dump {
my $self = shift;
my $obsolete = $self->obsolete? '#~ ' : '';
+ my $fuzzy_prefix = $self->obsolete? '#~| ' : '#| ';
my $dump;
$dump = $self->_dump_multi_comment( $self->comment, "# " )
if ( $self->comment );
@@ -225,6 +261,16 @@ sub dump {
}
$dump .= "#$flags\n" if length $flags;
+ $dump .= "${fuzzy_prefix}msgctxt "
+ . $self->_fuzzy_normalize_str( $self->fuzzy_msgctxt, $fuzzy_prefix )
+ if $self->fuzzy_msgctxt;
+ $dump .= "${fuzzy_prefix}msgid "
+ . $self->_fuzzy_normalize_str( $self->fuzzy_msgid, $fuzzy_prefix )
+ if $self->fuzzy_msgid;
+ $dump .= "${fuzzy_prefix}msgid_plural "
+ . $self->_fuzzy_normalize_str( $self->fuzzy_msgid_plural, $fuzzy_prefix )
+ if $self->fuzzy_msgid_plural;
+
$dump .= "${obsolete}msgctxt " . $self->_normalize_str( $self->msgctxt )
if $self->msgctxt;
$dump .= "${obsolete}msgid " . $self->_normalize_str( $self->msgid );
@@ -331,6 +377,9 @@ sub _load_file {
if ( defined($po) ) {
+ $po->fuzzy_msgctxt( $buffer{fuzzy_msgctxt} ) if defined $buffer{fuzzy_msgctxt};
+ $po->fuzzy_msgid( $buffer{fuzzy_msgid} ) if defined $buffer{fuzzy_msgid};
+ $po->fuzzy_msgid_plural( $buffer{fuzzy_msgid_plural} ) if defined $buffer{fuzzy_msgid_plural};
$po->msgctxt( $buffer{msgctxt} ) if defined $buffer{msgctxt};
$po->msgid( $buffer{msgid} ) if defined $buffer{msgid};
$po->msgid_plural( $buffer{msgid_plural} ) if defined $buffer{msgid_plural};
@@ -396,6 +445,24 @@ sub _load_file {
$po->add_flag($flag);
}
}
+ elsif (/^#(~)?\|\s+msgctxt\s+(.*)/) {
+ $po = $class->new( -loaded_line_number => $line_number ) unless defined($po);
+ $buffer{fuzzy_msgctxt} = $self->dequote($2);
+ $last_buffer = \$buffer{fuzzy_msgctxt};
+ $po->obsolete(1) if $1;
+ }
+ elsif (/^#(~)?\|\s+msgid\s+(.*)/) {
+ $po = $class->new( -loaded_line_number => $line_number ) unless defined($po);
+ $buffer{fuzzy_msgid} = $self->dequote($2);
+ $last_buffer = \$buffer{fuzzy_msgid};
+ $po->obsolete(1) if $1;
+ }
+ elsif (/^#(~)?\|\s+msgid_plural\s+(.*)/) {
+ $po = $class->new( -loaded_line_number => $line_number ) unless defined($po);
+ $buffer{fuzzy_msgid_plural} = $self->dequote($2);
+ $last_buffer = \$buffer{fuzzy_msgid_plural};
+ $po->obsolete(1) if $1;
+ }
elsif (/^(#~\s+)?msgctxt\s+(.*)/) {
$po = $class->new( -loaded_line_number => $line_number ) unless defined($po);
$buffer{msgctxt} = $self->dequote($2);
@@ -426,10 +493,14 @@ sub _load_file {
$buffer{msgstr_n}{$1} = $self->dequote($2);
$last_buffer = \$buffer{msgstr_n}{$1};
}
- elsif (/^(?:#~\s+)?"/) {
+ elsif (/^(?:#(?:~|~\||\|)\s+)?(".*)/) {
- # contined string
- $$last_buffer .= $self->dequote($_);
+ # continued string. Accounts for:
+ # normal : "string"
+ # obsolete : #~ "string"
+ # fuzzy : #| "string"
+ # fuzzy+obsolete : #~| "string"
+ $$last_buffer .= $self->dequote($1);
}
else {
warn "Strange line at $file line $line_number: $_\n";
@@ -529,7 +600,8 @@ a list/hash of the form:
-option=>value, -option=>value, etc.
-Where options are msgid, msgstr, msgctxt, comment, automatic, reference,
+Where options are msgid, msgid_plural, msgstr, msgctxt, comment, automatic,
+reference, fuzzy_msgctxt, fuzzy_msgid, fuzzy_msgid_plural,
fuzzy, and c-format. See accessor methods below.
To generate a po file header, add an entry with an empty
@@ -583,6 +655,24 @@ Set or get the translation context strin
This method expects the new string in unquoted form but returns the current string in quoted form.
+=item fuzzy_msgid
+
+Set or get the outdated untranslated string from the object.
+
+This method expects the new string in unquoted form but returns the current string in quoted form.
+
+=item fuzzy_msgid_plural
+
+Set or get the outdated untranslated plural string from the object.
+
+This method expects the new string in unquoted form but returns the current string in quoted form.
+
+=item fuzzy_msgctxt
+
+Set or get the outdated translation context string from the object.
+
+This method expects the new string in unquoted form but returns the current string in quoted form.
+
=item obsolete
Returns 1 if the entry is obsolete.
diff -Nrup Locale-PO-0.21/t/fuzzy.pot Locale-PO-0.21.patched/t/fuzzy.pot
--- Locale-PO-0.21/t/fuzzy.pot 1969-12-31 19:00:00.000000000 -0500
+++ Locale-PO-0.21.patched/t/fuzzy.pot 2011-02-28 14:58:32.000000000 -0500
@@ -0,0 +1,68 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI +ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: ENCODING\n"
+
+# tests for handline fuzzy / old strings
+#, fuzzy
+#| msgid "Click Ok to continue."
+msgid "Click OK to continue."
+msgstr ""
+
+#: cgi-bin/test.pl:6505
+#, fuzzy
+#| msgid "Response"
+msgid "Add Response"
+msgstr ""
+
+#: cgi-bin/programGoals.pl:1200
+#, fuzzy
+#| msgid ""
+#| "There are no bindings for the the Goal Group filter you chose. \n"
+#| "If you need a binding added contact %1. All Goal Groups, \n"
+#| "will still be displayed below."
+msgid ""
+"There are no bindings for the the Goal Group or GoalType Sets you chose.\n"
+"If you need a binding added contact %1. All Goal Groups and GoalType Sets\n"
+"will still be displayed below."
+msgstr ""
+
+#: cgi-bin/employeeProfile.pl:824
+#, fuzzy
+#| msgctxt "Date as in the noun, the time at which an event occcurs"
+#| msgid "Date"
+msgctxt "Date as in the noun, the time at which an event occurred"
+msgid "Date"
+msgstr ""
+
+#, fuzzy
+#| msgid "1 day"
+#| msgid_plural "%n days"
+msgctxt "Number of Days"
+msgid "1 day"
+msgid_plural "%n days"
+msgstr[0] ""
+msgstr[1] ""
+
+#, fuzzy
+#~| msgid "Other Fields"
+#~ msgid "Other Skills"
+#~ msgstr ""
+
+#, fuzzy
+#~| msgid ""
+#~| "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do \n"
+#~| "eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim \n"
+#~| "ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut \n"
+#~| "aliquip ex ea commodo consequat. Duis aute irure dolor in \n"
+#~| "reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla \n"
+#~| "pariatur. Excepteur sint occaecat cupidatat non proident, sunt in \n"
+#~| "culpa qui officia deserunt mollit anim id est laborum."
+#~ msgid "Lorem ipsum"
+#~ msgstr ""
+
diff -Nrup Locale-PO-0.21/t/fuzzy.t Locale-PO-0.21.patched/t/fuzzy.t
--- Locale-PO-0.21/t/fuzzy.t 1969-12-31 19:00:00.000000000 -0500
+++ Locale-PO-0.21.patched/t/fuzzy.t 2011-02-28 14:58:32.000000000 -0500
@@ -0,0 +1,54 @@
+# $Id: fuzzy.t,v 1.1 2011/02/28 14:33:10 evdb Exp $
+# Copyright 2005. Distributed under the same licence as Perl itself.
+# Author: Joshua Miller <unrtst@cpan.org>
+
+use strict;
+use warnings;
+
+use Test::More 'no_plan';
+use File::Slurp;
+
+use_ok 'Locale::PO';
+
+my $pos = Locale::PO->load_file_asarray("t/fuzzy.pot");
+ok $pos, "loaded fuzzy.pot file";
+
+my $out = $pos->[0]->dump;
+ok $out, "dumped po object";
+
+ok Locale::PO->save_file_fromarray( "t/fuzzy.pot.out", $pos ), "save to file";
+ok -e "t/fuzzy.pot.out", "the file now exists";
+
+is(
+ read_file('t/fuzzy.pot'),
+ read_file('t/fuzzy.pot.out'),
+ "found no matches - good"
+ )
+ && unlink 't/fuzzy.pot.out';
+
+{ # Check that the fuzzy can be created in code.
+
+ my $po = Locale::PO->new(
+ -fuzzy_msgid => 'one test',
+ -fuzzy_msgid_plural => '%d tests',
+ -msgid => '%d test',
+ -msgid_plural => '%d tests',
+ -msgstr_n => { 0 => '%d TEST', 1 => '%d TESTS' },
+ );
+ ok $po, "object created.";
+
+ my $expected = join "\n", '#| msgid "one test"', '#| msgid_plural "%d tests"',
+ 'msgid "%d test"', 'msgid_plural "%d tests"',
+ 'msgstr[0] "%d TEST"', 'msgstr[1] "%d TESTS"', '', '';
+
+ is $po->dump, $expected, "check the output";
+
+ # try to edit the fuzzy in the code.
+
+ ok $po->fuzzy_msgid( 'one TeSt' ),
+ "change the value of a fuzzy msgid";
+
+ $expected =~ s/one test/one TeSt/;
+ is $po->dump, $expected, "check the output";
+
+}