smartnsoft / FlappyTranslator

A tool which automatically generates Flutter localization resources from CSV and Excel files.
MIT License
57 stars 20 forks source link

Can handle plurals? #14

Open expilu opened 4 years ago

expilu commented 4 years ago

First of all, congrats for the idea and the package. I specially like the idea of having the translations available at compile time.

It doesn't seem to be able to handle plurals though. Is it planned?

ThomasEcalle commented 4 years ago

Hi,

Thank you for your feeback :)

Yes it is planned but, to be honest, I can't assure you that I'll have the time to implement it in the next few days..

Feel free to make a pull request if you want to implement it :)

defuncart commented 4 years ago

Localizing plurals is quite tricky as different languages have different grammatical rules. For instance:

Text en de pl
1 + second 1 second 1 Sekunde 1 sekunda
2 + second 2 seconds 2 Sekunden 2 sekundy
5 + second 5 seconds 5 Sekunden 5 sekund

However, these grammar rules are fixed so we could define a list of plural rules as discussed here.

Plurals could be inputted and parsed by using some special character like &: &second;seconds&, &sekunda;sekundy;sekund& etc.

Then a string Time: %seconds$d &second;seconds& could be parsed to the function

static final _pluralRegExp = RegExp(r'&(.*?)&');

String myKey({int seconds}) {
  String text = _getText('myKey');
  if (seconds != null) {
    text = text.replaceAll('%seconds\$s', seconds);
    if(_pluralRegExp.hasMatch(text) {
      List<String> plurals = _generatedListPlurals(text);
      text = text.replaceAll(_pluralRegExp, _determinePlural(plurals, count));
    }
  }
  return text;
}

List<String> _generatedListPlurals(String text) {
  String temp = _pluralRegExp.firstMatch(text).replaceAll('&', '');
  return temp.split(';');
}

where the methods _determinePlural, _rule1 etc. are part of the generated I18n file:

String _determinePlural(List<String> plurals, int count) {
  switch(currentLanguage) {
    case 'en':
      return _rule1(plurals, count);
    case 'pl':
      return _rule9(plurals, count);

  ....

  }
}

String _rule1(List<String> plurals, int count) {
  if(count == 1) {
   return plurals[0];
  } else { 
    return plurals[1];
  }
}

String _rule9(List<String> plurals, int count) {
  if(count == 1) {
   return plurals[0];
  else if((count % 10 == 2 && count != 12) || 
    (count % 10 == 3 && count != 13) ||
    (count % 10 == 4 && count != 14){
    return plurals[1];
  } else { 
    return plurals[2];
  }
}

Pseudo code is off the top of my head so there may be mistakes :) Also it only considers one plural setting per string. This approach seems like it would work, however & is probably not a good character to use, maybe | or something less common would be better. Languages could be implemented as needed.

What do you think @ThomasEcalle @expilu ?

defuncart commented 4 years ago

@expilu @ThomasEcalle @deadsoul44 Here is a potential solution using's intl package: https://github.com/smartnsoft/FlappyTranslator/pull/20

expilu commented 4 years ago

@expilu @ThomasEcalle @deadsoul44 Here is a potential solution using's intl package: #20

I ended using intl package.

As a way to handle plurals in strings, I like how Android does it. It has served me well so far, even for apps in Chinese.

defuncart commented 4 years ago

@expilu Yes I quite like intl too and believe it is a good solution for plurals and gender :)

defuncart commented 3 years ago

TL;DR Plurals and Genders are out of scope of _flappytranslator and won't be worked on.

The goal of _flappytranslator is to automatically generate LocalizationDelegates using the alternative approach. This workflow is best suited to small-scale projects where developers manually add keys, and an Excel/CSV file is suitable for the translation team.

Back when @ThomasEcalle first created this package, there was discussion in the community on how to simplify the localization process. At that time, the ARB workflow was complicated, strings needed to be added manually to messages files, which also needed to be kept in sync with one another. For many, this workflow was overbearing, and flappy_translator was a good alternative. Thus, developers, including myself, adopted this solution for their projects.

Eventually the question of plurals and genders were raised. Last May I proposed a simple POC on generating plurals using intl, however this solution felt contrived. Moreover, around this time, Flutter proposed a simplified approach using l10n.yaml. #20 was left open to see what the community would say.

With _flappytranslator 1.6.0 around the corner (once all dependencies have migrated to null safety), it feels like a good time to ultimately decide on future plurals and genders supports. In short, with a simplified ARB workflow, it makes much more sense to consider CSV to ARB conversion rather than generating LocalizationDelegates and somewhat reinventing the wheel. CSV to ARB conversion is a topic that I'll probably look into, however it would be out of scope of _flappytranslator.

Although this issue wont be worked on, it will remain open for better visibility.

defuncart commented 3 years ago

Happy to announce that arb_generator is presently being worked on. The initial alpha version already supports variables, plurals, genders and select. Feel free to star the repo to receive updates :)