W dniu 26.09.2016 o 20:15, Vasco Almeida pisze:
> A Qua, 31-08-2016 às 12:31 +0000, Vasco Almeida escreveu:
>>
>> 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 subrotine Q__() for plural strings handling.

Why use Q__() as the name of the subroutine? [looks further]. Oh, I see
that you are following the example of C shortcut functions (_, Q_ and N_).

But this is Perl, not C.  The standard shortcut functions are those
defined in Locale::TextDomain, even if we can't use this module directly.
Those that deal with plural strings handling are __n and __nx / __xn.

The Perl equivalent of Q_ shorthand function in C, C++, etc. is __n.
There is also a function __nx for combining handling plural strings
together with variable interpolation.

  __n MSGID, MSGID_PLURAL, COUNT
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  That is the reason for the existance of the function ngettext(),
  that __n() is a short-cut for:

    print __n"One file has been deleted.\n", 
             "All files have been deleted.\n",
             $files_deleted;

  Alternatively:

    print __n ("One file has been deleted.\n",
               "All files have been deleted.\n",
               $files_deleted);


  __nx MSGID, MSGID_PLURAL, COUNT, VAR1 => VAL1, VAR2 => VAL2, ...
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  Bringing it all together:

    print __nx ("One file has been deleted.\n",
                "{count} files have been deleted.\n",
                $num_files,
                count => $num_files);

  The function __nx() [and its alias __xn()] picks the correct plural
  form (also for English!) and it is capable of interpolating variables
  into strings.


>>
>> Signed-off-by: Vasco Almeida <vascomalme...@sapo.pt>
>> ---
>>  Makefile                  |  3 ++-
>>  git-add--interactive.perl | 24 ++++++++++++++++--------
>>  perl/Git/I18N.pm          |  4 +++-
>>  t/t0202/test.pl           | 11 ++++++++++-
>>  4 files changed, 31 insertions(+), 11 deletions(-)

>> diff --git a/Makefile b/Makefile
>> index de5a030..eedf1fa 100644
>> --- a/Makefile
>> +++ b/Makefile
>> @@ -2061,7 +2061,8 @@ XGETTEXT_FLAGS_C = $(XGETTEXT_FLAGS) --language=C \
>>      --keyword=_ --keyword=N_ --keyword="Q_:1,2"
>>  XGETTEXT_FLAGS_SH = $(XGETTEXT_FLAGS) --language=Shell \
>>      --keyword=gettextln --keyword=eval_gettextln
>> -XGETTEXT_FLAGS_PERL = $(XGETTEXT_FLAGS) --keyword=__ --language=Perl
>> +XGETTEXT_FLAGS_PERL = $(XGETTEXT_FLAGS) --language=Perl \
>> +    --keyword=__ --keyword="Q__:1,2"

So this would be

   +XGETTEXT_FLAGS_PERL = $(XGETTEXT_FLAGS) --language=Perl \
   +    --keyword=__ --keyword=__x --keyword=__n:1,2 --keyword=__nx:1,2

(assuming that __x was used for interpolation)
 
>>  LOCALIZED_C = $(C_OBJ:o=c) $(LIB_H) $(GENERATED_H)
>>  LOCALIZED_SH = $(SCRIPT_SH) git-parse-remote.sh
>>  LOCALIZED_PERL = $(SCRIPT_PERL)
[...]

>> diff --git a/git-add--interactive.perl b/git-add--interactive.perl
>> index 4e1e857..08badfa 100755
>> --- a/git-add--interactive.perl
>> +++ b/git-add--interactive.perl
>> @@ -666,12 +666,18 @@ sub status_cmd {
>>  sub say_n_paths {
>>      my $did = shift @_;
>>      my $cnt = scalar @_;
>> -    print "$did ";
>> -    if (1 < $cnt) {
>> -            print "$cnt paths\n";
>> -    }
>> -    else {
>> -            print "one path\n";
>> +    if ($did eq 'added') {
>> +            printf(Q__("added one path\n", "added %d paths\n",
>> +                       $cnt), $cnt);
>> +    } elsif ($did eq 'updated') {
>> +            printf(Q__("updated one path\n", "updated %d paths\n",
>> +                       $cnt), $cnt);
>> +    } elsif ($did eq 'reverted') {
>> +            printf(Q__("reverted one path\n", "reverted %d paths\n",
>> +                       $cnt), $cnt);
>> +    } else {
>> +            printf(Q__("touched one path\n", "touched %d paths\n",
>> +                       $cnt), $cnt);
>>      }
>>  }

One one hand side, it is recommended to avoid lego-like construction
of sentences.

  Translatable strings should be entire sentences. It is often not
  possible to translate single verbs or adjectives in a substitutable
  way.

I think however that the action part ($did in original non-i18n code)
is whole part in any language, so something like the following would
be enough:

        # this hash is as much for validation, as for translation
        my %actions = map { $_ => 1 } (N__"added", N__"updated", N__"reverted");
        if (exists $actions{$did}) {
                print __nx("{did} one path\n", "{did} {count} paths\n", $cnt,
                           did => __($did), count => $cnt);
        } else {
                print __nx("touched one path\n", "touched {count} paths\n", 
$cnt,
                           count => $cnt);
        }

Please correct me if I am wrong, and you know language where
"added %d paths", "updated %d paths", "reverted %d paths" etc. must have
different word order.

> When $cnt is 1 I get the following warning:
> Redundant argument in printf at .../libexec/git-core/git-add--interactive 
> line 680.

I wonder what is the case of C code - is similar warning here, or is
gettext smarter in that case...

> The singular form does not have a %d to consume $cnt argument to
> printf(). Either we find a way to suppress that warning or we change
> the singular form to contain %d.

Anyway, with __nx there should be no such problem.

> 
>> @@ -1508,8 +1514,10 @@ sub patch_update_file {
>> ...
>> -                                    print colored $header_color, "Split 
>> into ",
>> -                                    scalar(@split), " hunks.\n";
>> +                                    print colored $header_color, sprintf(
>> +                                            Q__("Split into %d hunk.\n",
>> +                                                "Split into %d hunks.\n",
>> +                                                scalar(@split)), 
>> scalar(@split));
>
> Like we do with this.

Note that it is a bit of change in behavior: previously Git would
say "Split into 0 hunks.\n".


Though this is probably more work that you wanted to do.  The __n would
take place of Q__, while the __nx function might be defined like this
(borrowing from Locale::TextDomain), which needs to be put into Git::I18N:

# Plural with interpolation.
sub __nx ($$$@)
{
    my ($msgid, $msgid_plural, $count, %args) = @_;
    
    return __expand ((__n $msgid, $msgid_plural, $count),
                     %args);
}

Best regards,
-- 
Jakub Narębski

Reply via email to