Bug 341692 - Need plural form format for real numbers
Summary: Need plural form format for real numbers
Status: RESOLVED FIXED
Alias: None
Product: frameworks-ki18n
Classification: Frameworks and Libraries
Component: general (show other bugs)
Version: unspecified
Platform: Other Other
: NOR normal
Target Milestone: ---
Assignee: Chusslove Illich
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-12-09 11:36 UTC by fios
Modified: 2016-12-27 16:54 UTC (History)
4 users (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description fios 2014-12-09 11:36:02 UTC
The ki18nc function needs the same plural format interface as ki18ncp.

I am localizing into Scottish Gaelic, and real numbers behave like their floors in respect to plural forms.

C.f. this CLDR bug: http://unicode.org/cldr/trac/ticket/7510

I know API changes are a big pain in the butt, but I'm ending up with translations that look like this: %1 m(h)eatair(ean). So, anything you can do will be appreciated :)

Reproducible: Always
Comment 1 Chusslove Illich 2014-12-11 11:47:35 UTC
API is one issue, but not at all the biggest. More serious is the need to retrain all programmers to use plural calls for real numbers too. And much more serious is the need to somehow indicate to translators in other languages (and retrain them to observe that indicator) that a particular plural message is for real number, so that they don't translate it as for integer number. I think this switch is not feasible, so I close the report as "won't fix".

However, Ki18n provides a translation scripting layer[*], which could be used to get real number plurals with modest effort. For example, you could translate a message like this:

  msgctxt "amount in units (real)"
  msgid "%1 meters"
  msgstr ""
  "%1 m(h)eatair(ean)"
  "|/|"
  "%1 $[myplural ^1 mheatair mheatair meatairean meatair]"

Here the part after the special sequence |/| is the scripted translation, and $[myplural ...] is the call of a language-specific function to be defined. Based on the value of the first argument (^1, which is the input number), it would select one of the four subsequent phrases. The part of translation before |/| is still there, in case the scripted translation fails for any reason (should never happen in this example). Note that this would work only in Ki18n-based PO files, and not Qt-based (those with _qt suffix).

If you think this solution is acceptable, I could add what needs to be added where, so that the function myplural becomes available. If yes, also tell me how to actually name the function instead of myplural (I personally prefer something in the language of translation, any Unicode letters possible).

[*] https://techbase.kde.org/Localization/Concepts/Transcript
Comment 2 fios 2014-12-15 12:31:33 UTC
If it's creating problems for everybody else, we won't want that. So, scripted translation is fine. We could call the function "iolra", which is Gaelic for "plural".

After reading the guide, I still have a question - just to make sure I'll get this right. Does the "|/|" need to be on a separate line, or can I do something like this:

msgctxt "amount in units (real)"
msgid "%1 meters"
msgstr "%1 m(h)eatair(ean)|/|%1 $[iolra ^1 mheatair mheatair meatairean meatair]"
Comment 3 Chusslove Illich 2014-12-22 11:30:18 UTC
Yes, it can be all on one line. I wrap it in the examples just for better view.

I have now committed the scripting file to trunk/l10n-kf5/gd/scripts/frameworks/ki18n5/ki18n5.js (there doesn't seem to be branches/stable/l10n-kf5/gd yet). I took the same plural formula as in gd PO files, and tested that the function works on the above example.
Comment 4 Peter Wu 2016-10-24 17:55:24 UTC
The ki18n API appears to support real numbers (of the double type). I intended to use it like this:

    // double val;
    setSuffix(i18np(" second", " seconds", val));

Corresponding autotests:

    // Anything other than 1 is non-singular.
    QCOMPARE(i18np("second", "seconds", 0.0),
             QString("seconds"));
    QCOMPARE(i18np("second", "seconds", 1.0),
             QString("second"));
    QCOMPARE(i18np("second", "seconds", 1.1),
             QString("seconds"));

The problem however is that the internal implementation only supports integer numbers. Is it worth supporting this case? (feel free to close if you think it is not, then the caller will just check val == 1.0 directly).
Comment 5 Alexander Potashev 2016-10-29 13:02:50 UTC
(In reply to Peter Wu from comment #4)
>     QCOMPARE(i18np("second", "seconds", 1.0),
>              QString("second"));
>     QCOMPARE(i18np("second", "seconds", 1.1),
>              QString("seconds"));

This doesn't work for Scottish Gaelic: as mentioned above, translation for a real number X should be the same as for floor(X). Here you have "1.0 second" and "1.1 seconds".

For Russian language, I need
 1. standard plural forms for integer values (0, 1, 2, 3, ...) and
 2. another fixed translation for the case when the real number becomes non-integer, no matter how large is its integer part.
Comment 6 Albert Astals Cid 2016-12-27 16:43:55 UTC
    // Anything other than 1 is non-singular.
    QCOMPARE(i18np("second", "seconds", 0.0),
             QString("seconds"));
    QCOMPARE(i18np("second", "seconds", 1.0),
             QString("second"));
    QCOMPARE(i18np("second", "seconds", 1.1),
             QString("seconds"));

That's what is expected of it, so closing
Comment 7 Albert Astals Cid 2016-12-27 16:54:00 UTC
Actually that unittest doesn't work