4 ms·
Does it handle the "x of y" in Slavic languages correctly? For example in Polish: "Page 3 of 4" is "Strona 3 z 4" "Page 3 of 100" is "Strona 3 ze 100"
by ajuc 8y ago
Does it handle the "x of y" in Slavic languages correctly?
For example in Polish:
"Page 3 of 4" is "Strona 3 z 4"
"Page 3 of 100" is "Strona 3 ze 100"
- lifthrasiir 8y agoAs far as I can tell Fluent has no builtin support for tagging a phonemic information to messages or arguments (it only supports plural rules and number formatting largely derived from the CLDR). You can probably specify special cases with selectors (but it will quickly go absurd, for Polish I guess that applies to 6, 7, 16, 17, 60..79, 100..199, 600..699 and so on?) or have an external function. Context: Polish preposition "z(e)" is spelled "z" if the following word starts with s and z and alikes (problematically enough, the exact rule is not systematic) and "ze" otherwise. Korean has a similar case with postpositions "은(는)" and "이(가)" where the former is for words ending with a consonant and the latter is for words ending with a vowel, and the ko-KR localization of Firefox seems to completely ignore and/or sidestep this; the last letter is assumed (e.g. "{-brand-name}는") or a static word is inserted (e.g. "{$user} 사용자는" instead of "{$user}은(는)").
- ajuc 8y agoFunnily enough "Strona 3 z 6" and "Strona 3 z 7" sounds correct but "Strona 3 z 100" doesn't. So I think it's only words starting with "s", not "sz" nor "si". And only 0 starts with "z" so it's not a problem (you never have "X out of 0"). So the only special case is for 100-199, 100 000-199 999, etc.
- lifthrasiir 8y agoYeah, it is clear that I don't speak Polish ;-) What is a common workaround there? "Strona X z(e) Y"?
- ajuc 8y ago> What is a common workaround there? Ignoring the issue altogether :) Or, if you're pedantic - implementing the special cases in the source code. But that's unmaintenable if you have lots of languages.
- chungleong 8y agoA filler vowel is needed with certain consonant clusters. 100 is "stu" and "st" requires it, whereas "dwustu" (200), "trzystu" (300), "czterystu" (400) don't. I don't remember the list. "mn" is another combo that needs the vowel: "ze mnóstwa".
- stasm 8y agoThis is an excellent question and a very good use-case. I'm a Polish speaker myself, so I can definitely relate. It's also a good excuse for me to talk a little bit more about the advanced features of Fluent. The Fluent Syntax is a simple declarative DSL. By design, it doesn't allow translators to build complex conditionals or use arithmetic. There is, however, an escape hatch. The problem you described can be solved in Fluent with a little bit of one-time help from the developer of the source code, through a feature of Fluent called custom functions. Translations in Fluent can use functions to format values or decide between variants. There exist built-in functions like NUMBER and DATETIME. They are rarely used because the Fluent runtime calls them on numeric and temporal values implicitly, but they can be helpful when localizers wish to use custom formatting options. weekday-today = Today is {DATETIME($today, weekday: "long")}. See https://projectfluent.org/play/?id=a3540d4f02c104a634adbfc0e57f927a https://projectfluent.org/play/?id=a3540d4f02c104a634adbfc0e... for a live example of DATETIME. There can also be custom functions, defined during the initialization of the runtime. In Firefox, we use one such function called PLATFORM: https://searchfox.org/mozilla-central/rev/d33d470140ce3f9426af523eaa8ecfa83476c806/intl/l10n/L10nRegistry.jsm#404-422 https://searchfox.org/mozilla-central/rev/d33d470140ce3f9426.... It can be used as follows: open-preferences = {PLATFORM() -> [windows] Open Options *[other] Open Preferences } The logic of custom functions is entirely up to developers and the localization needs of the UI. In https://github.com/projectfluent/fluent/issues/228#issuecomment-456372627 https://github.com/projectfluent/fluent/issues/228#issuecomm..., for instance, I suggested using a custom function to handle negative and positive floor numbers. A custom function can also cater to the use-case you described. A simple and possibly naive implementation in JavaScript could look like the following one: function NUMBER_HEAD(num) { while (num > 999) { num /= 1e3; } let first = num.toString()[0]; return num < 10 ? first : num < 100 ? first + "x" : first + "xx"; } I wrote this with Polish in mind, but it could be useful to other languages in which numerals are named after the first thousand-triple, in a left to right order. Depending on the exact product requirements, the function could be called NUMBER_HEAD_POLISH, or perhaps NUMBER_HEAD_TRIPLE_FIRST_DIGIT :) Once defined, the function can be used as follows: # The Polish copy can take advantage of the custom function. page-of = {NUMBER_HEAD($pageTotal) -> [1xx] Strona {$pageCurrent} ze {$pageTotal} *[other] Strona {$pageCurrent} z {$pageTotal} } This method still requires some work from developers, but it only needs to happen once and in a single palce in code: where the Fluent runtime is initialized. Because they are code, custom functions can be reviewed and tested just as any other code in the code base, to help ensure that they do what they claim to :) Importantly, the use of the custom function is completely opt-in. # The English copy doesn't need any special handling. page-of = Page {$pageCurrent} of {$pageTotal} All localization callsites remain unchanged, and all existing translations remain functional.