GNOME Bugzilla – Bug 353235
Overloaded plural strings
Last modified: 2006-12-07 23:25:22 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.
Add I18N keyword.
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?
(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
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.
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);
(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.
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.
Created attachment 71822 [details] [review] Proposed patch using distinguished singular form in ngettext
(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.
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.