After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 353235 - Overloaded plural strings
Overloaded plural strings
Status: RESOLVED FIXED
Product: gedit
Classification: Applications
Component: general
git master
Other All
: Normal normal
: ---
Assigned To: Gedit maintainers
Gedit maintainers
Depends on:
Blocks:
 
 
Reported: 2006-08-28 13:08 UTC by Theppitak Karoonboonyanan
Modified: 2006-12-07 23:25 UTC
See Also:
GNOME target: ---
GNOME version: 2.15/2.16


Attachments
Proposed patch (1.58 KB, patch)
2006-08-28 17:15 UTC, Theppitak Karoonboonyanan
none Details | Review
Proposed patch using distinguished singular form in ngettext (1.44 KB, patch)
2006-08-29 10:50 UTC, Theppitak Karoonboonyanan
none Details | Review

Description Theppitak Karoonboonyanan 2006-08-28 13:08:06 UTC
Two msgid's in gedit has plural forms with both c-format and non-c-format, and the non-c-format one is unfortunately shared with some other non-c-format string. This causes trouble in translation for languages that have no plural form, such as Thai, Vietnamese, CJK, etc.:

(1)
#: ../gedit/dialogs/gedit-close-confirmation-dialog.c:451
#: ../gedit/dialogs/gedit-close-confirmation-dialog.c:472
#, c-format
msgid "If you don't save, changes from the last hour will be permanently lost."
msgid_plural ""
"If you don't save, changes from the last %d hours will be permanently lost."

(2)
#: ../gedit/gedit-commands-file.c:1184 ../gedit/gedit-commands-file.c:1205
#, c-format
msgid "Changes made to the document in the last hour will be permanently lost."
msgid_plural ""
"Changes made to the document in the last %d hours will be permanently lost."

The singular form of string (1), for example, is from two places:

#: ../gedit/dialogs/gedit-close-confirmation-dialog.c:451
secondary_msg = g_strdup (_("If you don't save, changes from the last hour "
                            "will be permanently lost."));

#: ../gedit/dialogs/gedit-close-confirmation-dialog.c:472
secondary_msg = g_strdup_printf (
                  ngettext ("If you don't save, changes from the last hour "                                  
                            "will be permanently lost.",
                            "If you don't save, changes from the last %d hours "
                            "will be permanently lost.",
                            hours),
                  hours);

For languages with nplurals=1, translating this using a single msgstr[0] entry is impossible. With "%d" in translation, the raw placeholder will show up to user in the former. Without "%d", the latter just loose the number information.
Comment 1 Theppitak Karoonboonyanan 2006-08-28 13:10:44 UTC
Add I18N keyword.
Comment 2 Paolo Maggi 2006-08-28 15:41:18 UTC
Thanks for the bug report.

It is not clear to me what kind of problems could this cause.

What is your suggestion to solve this problem? 

Why do you set it High/Critical?
Comment 3 Theppitak Karoonboonyanan 2006-08-28 16:53:57 UTC
(In reply to comment #2)
> It is not clear to me what kind of problems could this cause.

Translation problem. As described above, languages which have no
concept of plural form will face difficulty in translation, as
the non-c-format in msgid cannot be translated in separation
from the c-format msgid_plural. For example, supposed that
English had no plural forms, it would be translated like this:

#: ../gedit/dialogs/gedit-close-confirmation-dialog.c:451
#: ../gedit/dialogs/gedit-close-confirmation-dialog.c:472
#, c-format
msgid "If you don't save, changes from the last hour will be permanently lost."
msgid_plural ""
"If you don't save, changes from the last %d hours will be permanently lost."
msgstr[0] ""
"If you don't save, changes from the last %d hours will be permanently lost."

And this line:

secondary_msg = g_strdup (_("If you don't save, changes from the last hour "
                            "will be permanently lost."));

would get translated into:

secondary_msg = g_strdup ("If you don't save, changes from the last %d hours "
                          "will be permanently lost.");

which confuses users.

OTOH, if it's translated like this, to get it right:

#: ../gedit/dialogs/gedit-close-confirmation-dialog.c:451
#: ../gedit/dialogs/gedit-close-confirmation-dialog.c:472
#, c-format
msgid "If you don't save, changes from the last hour will be permanently lost."
msgid_plural ""
"If you don't save, changes from the last %d hours will be permanently lost."
msgstr[0] ""
"If you don't save, changes from the last hour will be permanently lost."

This line:

secondary_msg = g_strdup_printf (
                  ngettext ("If you don't save, changes from the last hour "    
                            "will be permanently lost.",
                            "If you don't save, changes from the last %d hours
"
                            "will be permanently lost.",
                            hours),
                  hours);

would be translated into:

secondary_msg = g_strdup_printf (
                  "If you don't save, changes from the last hour "    
                  "will be permanently lost.",
                  hours);

which is misleading.

So, it's apparently impossible to make it right without interfering
the other. Hope it can illustrate the problem.

> What is your suggestion to solve this problem? 

I think the string with plural form that contains c-format should 
be made different from the non-c-format that appears somewhere else.

For example, this is the relevant code around the ngettext call:

if (seconds < 55)
  ...
else if (seconds < 75)
  ...
else if (seconds < 110)
  ...
else if (seconds < 3600)
  ...
else if (seconds < 7200)
  ...
else
{
  gint hours;

  hours = seconds / 3600;

  secondary_msg = g_strdup_printf (
                    ngettext ("If you don't save, changes from the last hour "
                              "will be permanently lost.",
                              "If you don't save, changes from the last %d hours "
                              "will be permanently lost.",
                              hours),
                    hours);
 
}

It's clear that for this string, seconds >= 7200 always, which means
hours >= 2 always. So, the singular part of ngettext call is never used.
We can change it to any thing, such as making it c-format:

                    ngettext ("If you don't save, changes from the last %d hour "
                              "will be permanently lost.",
                              "If you don't save, changes from the last %d hours "
                              "will be permanently lost.",
                              hours),
or even remove it:

  secondary_msg = g_strdup_printf (
                    "If you don't save, changes from the last %d hours "
                    "will be permanently lost.",
                    hours);

> Why do you set it High/Critical?

Pardon? I remember filing it as Normal/minor. And the mail from
bugzilla daemon just confirms that:

Paolo Maggi changed:

          What    |Removed                     |Added
----------------------------------------------------------------------------
                CC|                            |paolo@gnome.org
          Severity|minor                       |normal
            Status|UNCONFIRMED                 |NEEDINFO
        OS/Version|Linux                       |All
Comment 4 Theppitak Karoonboonyanan 2006-08-28 17:15:13 UTC
Created attachment 71789 [details] [review]
Proposed patch

Proposed patch, by removing unnecessary ngettext calls.

Languages with concept of plural forms just split their msgstr[0]
and msgstr[1] into different places, while languages without
plurals can then translate them separately.
Comment 5 Wouter Bolsterlee (uws) 2006-08-29 09:58:15 UTC
Nautilus uses this construction in file-manager/fm-directory-view.c:


    if (uri_count == 1) {
        file_name = file_name_from_uri ((char *) uris->data);
        prompt = g_strdup_printf (_("Are you sure you want to permanently delete \"%s\"?"),
                      file_name);
        g_free (file_name);
    } else {
        prompt = g_strdup_printf (ngettext("Are you sure you want to permanently delete "
                           "the %d selected item?",
                           "Are you sure you want to permanently delete "
                           "the %d selected items?", uri_count), uri_count);
Comment 6 Theppitak Karoonboonyanan 2006-08-29 10:33:01 UTC
(In reply to comment #5)
> Nautilus uses this construction in file-manager/fm-directory-view.c:

which I think still contains unnecessary ngettext call. Any good reason
for using ngettext() where singular form is known to be never used?

Ah.. Yes, I may miss those languages with nplurals > 2 !!

So, I'll get back to the other choice of dummy singular form.
Comment 7 Wouter Bolsterlee (uws) 2006-08-29 10:48:56 UTC
Some languages (eg. slavic languages, iirc) use the singular form for count ∈ {11, 21, 31, 41, ...}. Even though it is never used in English (nor most other West-European languages), it's still needed.
Comment 8 Theppitak Karoonboonyanan 2006-08-29 10:50:51 UTC
Created attachment 71822 [details] [review]
Proposed patch using distinguished singular form in ngettext
Comment 9 Theppitak Karoonboonyanan 2006-08-29 10:56:11 UTC
(In reply to comment #7)
> Some languages (eg. slavic languages, iirc) use the singular form for count ∈
> {11, 21, 31, 41, ...}. Even though it is never used in English (nor most other
> West-European languages), it's still needed.

I see. So, there are still chances that it get selected by plural expression
for those languages. I've switched to nautilus' approach in recent patch,
anyway. Thanks for pointing out.
Comment 10 Paolo Maggi 2006-12-07 23:25:22 UTC
Sorry for the late reply.
Fixed in the development version. The fix will be available in the next major release. Thank you for your patch.