i18n: add--interactive: mark plural strings

Mark plural strings for translation. Unfold each action case in one entire sentence. Pass new keyword for xgettext to extract. Update test to include new subroutine __n() for plural strings handling. Update documentation to include a description of the new __n() subroutine. Signed-off-by: Vasco Almeida <vascomalmeida@sapo.pt> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Vasco Almeida committed Dec 14, 2016 at 11:54 UTC c4a85c3b8eef8c3b37f5103870e82894d9e5e7d0
4 files changed +39 -12
Makefile
+2 -1
@@ -2109,7 +2109,8 @@ XGETTEXT_FLAGS_C = $(XGETTEXT_FLAGS) --language=C \
2109 --keyword=_ --keyword=N_ --keyword="Q_:1,2"
2110 XGETTEXT_FLAGS_SH = $(XGETTEXT_FLAGS) --language=Shell \
2111 --keyword=gettextln --keyword=eval_gettextln
2112 -XGETTEXT_FLAGS_PERL = $(XGETTEXT_FLAGS) --keyword=__ --language=Perl
2112 +XGETTEXT_FLAGS_PERL = $(XGETTEXT_FLAGS) --language=Perl \
2113 + --keyword=__ --keyword="__n:1,2"
2114 LOCALIZED_C = $(C_OBJ:o=c) $(LIB_H) $(GENERATED_H)
2115 LOCALIZED_SH = $(SCRIPT_SH)
2116 LOCALIZED_SH += git-parse-remote.sh
git-add--interactive.perl
+18 -9
@@ -668,12 +668,18 @@ sub status_cmd {
668 sub say_n_paths {
669 my $did = shift @_;
670 my $cnt = scalar @_;
671 - print "$did ";
672 - if (1 < $cnt) {
673 - print "$cnt paths\n";
674 - }
675 - else {
676 - print "one path\n";
671 + if ($did eq 'added') {
672 + printf(__n("added %d path\n", "added %d paths\n",
673 + $cnt), $cnt);
674 + } elsif ($did eq 'updated') {
675 + printf(__n("updated %d path\n", "updated %d paths\n",
676 + $cnt), $cnt);
677 + } elsif ($did eq 'reverted') {
678 + printf(__n("reverted %d path\n", "reverted %d paths\n",
679 + $cnt), $cnt);
680 + } else {
681 + printf(__n("touched %d path\n", "touched %d paths\n",
682 + $cnt), $cnt);
683 }
684 }
685
@@ -1420,7 +1426,8 @@ sub patch_update_file {
1426 } elsif (0 < $response && $response <= $num) {
1427 $ix = $response - 1;
1428 } else {
1423 - error_msg "Sorry, only $num hunks available.\n";
1429 + error_msg sprintf(__n("Sorry, only %d hunk available.\n",
1430 + "Sorry, only %d hunks available.\n", $num), $num);
1431 }
1432 next;
1433 }
@@ -1515,8 +1522,10 @@ sub patch_update_file {
1522 elsif ($other =~ /s/ && $line =~ /^s/) {
1523 my @split = split_hunk($hunk[$ix]{TEXT}, $hunk[$ix]{DISPLAY});
1524 if (1 < @split) {
1518 - print colored $header_color, "Split into ",
1519 - scalar(@split), " hunks.\n";
1525 + print colored $header_color, sprintf(
1526 + __n("Split into %d hunk.\n",
1527 + "Split into %d hunks.\n",
1528 + scalar(@split)), scalar(@split));
1529 }
1530 splice (@hunk, $ix, 1, @split);
1531 $num = scalar @hunk;
perl/Git/I18N.pm
+9 -1
@@ -13,7 +13,7 @@ BEGIN {
13 }
14 }
15
16 -our @EXPORT = qw(__);
16 +our @EXPORT = qw(__ __n);
17 our @EXPORT_OK = @EXPORT;
18
19 sub __bootstrap_locale_messages {
@@ -44,6 +44,7 @@ BEGIN
44 eval {
45 __bootstrap_locale_messages();
46 *__ = \&Locale::Messages::gettext;
47 + *__n = \&Locale::Messages::ngettext;
48 1;
49 } or do {
50 # Tell test.pl that we couldn't load the gettext library.
@@ -51,6 +52,7 @@ BEGIN
52
53 # Just a fall-through no-op
54 *__ = sub ($) { $_[0] };
55 + *__n = sub ($$$) { $_[2] == 1 ? $_[0] : $_[1] };
56 };
57 }
58
@@ -70,6 +72,8 @@ Git::I18N - Perl interface to Git's Gettext localizations
72
73 printf __("The following error occurred: %s\n"), $error;
74
75 + printf __n("commited %d file\n", "commited %d files\n", $files), $files;
76 +
77 =head1 DESCRIPTION
78
79 Git's internal Perl interface to gettext via L<Locale::Messages>. If
@@ -87,6 +91,10 @@ it.
91 L<Locale::Messages>'s gettext function if all goes well, otherwise our
92 passthrough fallback function.
93
94 +=head2 __n($$$)
95 +
96 +L<Locale::Messages>'s ngettext function or passthrough fallback function.
97 +
98 =head1 AUTHOR
99
100 E<AElig>var ArnfjE<ouml>rE<eth> Bjarmason <avarab@gmail.com>
t/t0202/test.pl
+10 -1
@@ -4,7 +4,7 @@ use lib (split(/:/, $ENV{GITPERLLIB}));
4 use strict;
5 use warnings;
6 use POSIX qw(:locale_h);
7 -use Test::More tests => 8;
7 +use Test::More tests => 11;
8 use Git::I18N;
9
10 my $has_gettext_library = $Git::I18N::__HAS_LIBRARY;
@@ -31,6 +31,7 @@ is_deeply(\@Git::I18N::EXPORT, \@Git::I18N::EXPORT_OK, "sanity: Git::I18N export
31 # more gettext wrapper functions.
32 my %prototypes = (qw(
33 __ $
34 + __n $$$
35 ));
36 while (my ($sub, $proto) = each %prototypes) {
37 is(prototype(\&{"Git::I18N::$sub"}), $proto, "sanity: $sub has a $proto prototype");
@@ -46,6 +47,14 @@ is_deeply(\@Git::I18N::EXPORT, \@Git::I18N::EXPORT_OK, "sanity: Git::I18N export
47 my ($got, $expect) = (('TEST: A Perl test string') x 2);
48
49 is(__($got), $expect, "Passing a string through __() in the C locale works");
50 +
51 + my ($got_singular, $got_plural, $expect_singular, $expect_plural) =
52 + (('TEST: 1 file', 'TEST: n files') x 2);
53 +
54 + is(__n($got_singular, $got_plural, 1), $expect_singular,
55 + "Get singular string through __n() in C locale");
56 + is(__n($got_singular, $got_plural, 2), $expect_plural,
57 + "Get plural string through __n() in C locale");
58 }
59
60 # Test a basic message on different locales