On Thu, Aug 17, 2006 at 08:01:54PM +0200, Bruno Haible wrote: Hi,
> + In the English singular case, the number -- always 1 -- can be replaced with > + "one": > + > + @smallexample > + printf (ngettext ("One file removed", "%d files removed", n), n); > + @end smallexample Please don't do so, please don't mention this in the manual! It is quite brain-damaged, for at least two reasons: - "One file", "2 files", "3 files" is really inconsistent and really ugly. If "One" is written as text, then it should continue as "Two files", "Three files" so it's time to implement a localized number-to-text converter :-) Or if numbers are used then "1" should be a number, too. - This approach might easily break scripts that parse the output of the command, e.g. cut the number and use it for arithmetic processing. If the author of the script notices that "One" is a special case, he can write ugly workaround for it. It he doesn't notice it, his script will be buggy and it might need intensive wide-spread usage for this bug to appear. Let's not risk these kind of bugs to appear in front-ends and other wrapper software. The original code in coreutils which I mentioned in http://lists.gnu.org/archive/html/bug-coreutils/2006-08/msg00082.html looked analogous to this one: printf (ngettext ("1 file removed", "%d files removed", n), n); So "1" was also presented as a number, not as a word. Here I requested the coreutils team and Paul agreed to change this to printf (ngettext ("%d file removed", "%d files removed", n), n); The result produced by the program remains the same with some negligible performance overhead, but it helps translators create good translations. As far as I see, translators are usually not programmers and sometimes they don't even fully understand the logic behind ngettext. And they use software which do not help them and create trivially bad .po files. For example quoting from hu.po in coreutils 5.97: "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: KBabel 1.11.1\n" [...] msgid "1 truncated record\n" msgid_plural "%<PRIuMAX> truncated records\n" msgstr[0] "1 levágott rekord\n" msgstr[1] "%<PRIuMAX> levágott rekord\n" Now I just wonder why kbabel allows both "nplurals=1" and "msgstr[1]" which clearly does not make any sense. The translation above is clearly wrong since it always reports "1" truncated record in Hungarian. If the English singular string is converted to use the same format specifier, i.e. msgid "%<PRIuMAX> truncated record\n" msgid_plural "%<PRIuMAX> truncated records\n" in this case, then translators cannot make this mistake, even if they don't really know how ngettext works. That's why Paul and I recommend to mention in gettext's manual to use the same format specifier even in the singular case, e.g. "%d file removed" instead of "1 file removed". So, based on Paul's patch sent on 16 Aug, I recommend to apply this slightly modified patch: --- gettext-0.15/gettext-tools/doc/gettext.texi 2006-06-30 07:25:39.000000000 -0700 +++ gettext-0.15-plural/gettext-tools/doc/gettext.texi 2006-08-16 12:20:25.000000000 -0700 @@ -5198,6 +5198,18 @@ printf (ngettext ("%d file removed", "%d Please note that the numeric value @var{n} has to be passed to the @code{printf} function as well. It is not sufficient to pass it only to @code{ngettext}. + +When translating format strings, it is usually better to use the same +conversion specifications, and use wordings as similar as possible in [EMAIL PROTECTED] and @var{msgid2}, as this simplifies the translator's job. +For example: + [EMAIL PROTECTED] +/* Avoid usages like this one. */ +printf (ngettext ("1 file removed", "%d files removed", n), n); +/* Use this one instead. */ +printf (ngettext ("%d file removed", "%d files removed", n), n); [EMAIL PROTECTED] smallexample @end deftypefun @deftypefun {char *} dngettext (const char [EMAIL PROTECTED], const char [EMAIL PROTECTED], const char [EMAIL PROTECTED], unsigned long int @var{n}) -- Egmont _______________________________________________ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils