Unverified Commit fae84f67 authored by Tarekk Mohamed Abdalla's avatar Tarekk Mohamed Abdalla Committed by GitHub

[gen_l10n] Add support for adding placeholders inside select (#92753)

parent 31ee09f6
......@@ -177,6 +177,59 @@ String generateNumberFormattingLogic(Message message) {
return formatStatements.isEmpty ? '@(none)' : formatStatements.join();
}
/// To make it easier to parse plurals or select messages, temporarily replace
/// each "{placeholder}" parameter with "#placeholder#" for example.
String _replacePlaceholdersBraces(
String translationForMessage,
Iterable<Placeholder> placeholders,
String replacementBraces,
) {
assert(replacementBraces.length == 2);
String easyMessage = translationForMessage;
for (final Placeholder placeholder in placeholders) {
easyMessage = easyMessage.replaceAll(
'{${placeholder.name}}',
'${replacementBraces[0]}${placeholder.name}${replacementBraces[1]}',
);
}
return easyMessage;
}
/// Replaces message with the interpolated variable name of the given placeholders
/// with the ability to change braces to something other than {...}.
///
/// Examples:
///
/// * Replacing `{userName}`.
/// ```dart
/// final message = 'Hello my name is {userName}';
/// final transformed = _replacePlaceholdersWithVariables(message, placeholders);
/// // transformed == 'Hello my name is $userName'
/// ```
/// * Replacing `#choice#`.
/// ```dart
/// final message = 'I would like to have some #choice#';
/// final transformed = _replacePlaceholdersWithVariables(message, placeholders, '##');
/// transformed == 'I would like to have some $choice'
/// ```
String _replacePlaceholdersWithVariables(String message, Iterable<Placeholder> placeholders, [String braces = '{}']) {
assert(braces.length == 2);
String messageWithValues = message;
for (final Placeholder placeholder in placeholders) {
String variable = placeholder.name;
if (placeholder.requiresFormatting) {
variable += 'String';
}
messageWithValues = messageWithValues.replaceAll(
'${braces[0]}${placeholder.name}${braces[1]}',
_needsCurlyBracketStringInterpolation(messageWithValues, placeholder.name)
? '\${$variable}'
: '\$$variable'
);
}
return messageWithValues;
}
String _generatePluralMethod(Message message, String translationForMessage) {
if (message.placeholders.isEmpty) {
throw L10nException(
......@@ -186,12 +239,7 @@ String _generatePluralMethod(Message message, String translationForMessage) {
);
}
// To make it easier to parse the plurals message, temporarily replace each
// "{placeholder}" parameter with "#placeholder#".
String easyMessage = translationForMessage;
for (final Placeholder placeholder in message.placeholders) {
easyMessage = easyMessage.replaceAll('{${placeholder.name}}', '#${placeholder.name}#');
}
final String easyMessage = _replacePlaceholdersBraces(translationForMessage, message.placeholders, '##');
final Placeholder countPlaceholder = message.getCountPlaceholder();
const Map<String, String> pluralIds = <String, String>{
......@@ -208,19 +256,7 @@ String _generatePluralMethod(Message message, String translationForMessage) {
final RegExp expRE = RegExp('($pluralKey)\\s*{([^}]+)}');
final RegExpMatch? match = expRE.firstMatch(easyMessage);
if (match != null && match.groupCount == 2) {
String argValue = generateString(match.group(2)!);
for (final Placeholder placeholder in message.placeholders) {
String variable = placeholder.name;
if (placeholder.requiresFormatting) {
variable += 'String';
}
argValue = argValue.replaceAll(
'#${placeholder.name}#',
_needsCurlyBracketStringInterpolation(argValue, placeholder.name)
? '\${$variable}'
: '\$$variable'
);
}
final String argValue = _replacePlaceholdersWithVariables(generateString(match.group(2)!), message.placeholders, '##');
pluralLogicArgs.add(' ${pluralIds[pluralKey]}: $argValue');
}
}
......@@ -281,10 +317,11 @@ String _generateSelectMethod(Message message, String translationForMessage) {
);
}
final String easyMessage = _replacePlaceholdersBraces(translationForMessage, message.placeholders, '##');
final List<String> cases = <String>[];
final RegExpMatch? selectMatch =
LocalizationsGenerator._selectRE.firstMatch(translationForMessage);
final RegExpMatch? selectMatch = LocalizationsGenerator._selectRE.firstMatch(easyMessage);
String? choice;
if (selectMatch != null && selectMatch.groupCount == 2) {
choice = selectMatch.group(1);
......@@ -292,9 +329,10 @@ String _generateSelectMethod(Message message, String translationForMessage) {
final RegExp patternRE = RegExp(r'\s*([\w\d]+)\s*\{(.*?)\}');
for (final RegExpMatch patternMatch in patternRE.allMatches(pattern)) {
if (patternMatch.groupCount == 2) {
final String value = patternMatch.group(2)!
String value = patternMatch.group(2)!
.replaceAll("'", r"\'")
.replaceAll('"', r'\"');
value = _replacePlaceholdersWithVariables(value, message.placeholders, '##');
cases.add(
" '${patternMatch.group(1)}': '$value'",
);
......@@ -374,21 +412,7 @@ bool _needsCurlyBracketStringInterpolation(String messageString, String placehol
String _generateMethod(Message message, String translationForMessage) {
String generateMessage() {
String messageValue = generateString(translationForMessage);
for (final Placeholder placeholder in message.placeholders) {
String variable = placeholder.name;
if (placeholder.requiresFormatting) {
variable += 'String';
}
messageValue = messageValue.replaceAll(
'{${placeholder.name}}',
_needsCurlyBracketStringInterpolation(messageValue, placeholder.name)
? '\${$variable}'
: '\$$variable'
);
}
return messageValue;
return _replacePlaceholdersWithVariables(generateString(translationForMessage), message.placeholders);
}
if (message.isPlural) {
......
......@@ -123,45 +123,47 @@ void main() {
'#l10n 68 (Cabriolet has "acceleration")\n'
'#l10n 69 (Oh, she found 1 item!)\n'
'#l10n 70 (Indeed, they like Flutter!)\n'
'#l10n 71 (--- es ---)\n'
'#l10n 72 (ES - Hello world)\n'
'#l10n 73 (ES - Hello _NEWLINE_ World)\n'
'#l10n 74 (ES - Hola \$ Mundo)\n'
'#l10n 75 (ES - Hello Mundo)\n'
'#l10n 76 (ES - Hola Mundo)\n'
'#l10n 77 (ES - Hello World on viernes, 1 de enero de 1960)\n'
'#l10n 78 (ES - Hello world argument on 1/1/1960 at 0:00)\n'
'#l10n 79 (ES - Hello World from 1960 to 2020)\n'
'#l10n 80 (ES - Hello for 123)\n'
'#l10n 81 (ES - Hello)\n'
'#l10n 82 (ES - Hello World)\n'
'#l10n 83 (ES - Hello two worlds)\n'
'#l10n 84 (ES - Hello)\n'
'#l10n 85 (ES - Hello nuevo World)\n'
'#l10n 86 (ES - Hello two nuevo worlds)\n'
'#l10n 87 (ES - Hello on viernes, 1 de enero de 1960)\n'
'#l10n 88 (ES - Hello World, on viernes, 1 de enero de 1960)\n'
'#l10n 89 (ES - Hello two worlds, on viernes, 1 de enero de 1960)\n'
'#l10n 90 (ES - Hello other 0 worlds, with a total of 100 citizens)\n'
'#l10n 91 (ES - Hello World of 101 citizens)\n'
'#l10n 92 (ES - Hello two worlds with 102 total citizens)\n'
'#l10n 93 (ES - [Hola] -Mundo- #123#)\n'
'#l10n 94 (ES - \$!)\n'
'#l10n 95 (ES - One \$)\n'
"#l10n 96 (ES - Flutter's amazing!)\n"
"#l10n 97 (ES - Flutter's amazing, times 2!)\n"
'#l10n 98 (ES - Flutter is "amazing"!)\n'
'#l10n 99 (ES - Flutter is "amazing", times 2!)\n'
'#l10n 100 (ES - 16 wheel truck)\n'
"#l10n 101 (ES - Sedan's elegance)\n"
'#l10n 102 (ES - Cabriolet has "acceleration")\n'
'#l10n 103 (ES - Oh, she found ES - 1 itemES - !)\n'
'#l10n 104 (ES - Indeed, ES - they like ES - Flutter!)\n'
'#l10n 105 (--- es_419 ---)\n'
'#l10n 106 (ES 419 - Hello World)\n'
'#l10n 107 (ES 419 - Hello)\n'
'#l10n 71 (Indeed, he likes ice cream!)\n'
'#l10n 72 (Indeed, she likes chocolate!)\n'
'#l10n 73 (--- es ---)\n'
'#l10n 74 (ES - Hello world)\n'
'#l10n 75 (ES - Hello _NEWLINE_ World)\n'
'#l10n 76 (ES - Hola \$ Mundo)\n'
'#l10n 77 (ES - Hello Mundo)\n'
'#l10n 78 (ES - Hola Mundo)\n'
'#l10n 79 (ES - Hello World on viernes, 1 de enero de 1960)\n'
'#l10n 80 (ES - Hello world argument on 1/1/1960 at 0:00)\n'
'#l10n 81 (ES - Hello World from 1960 to 2020)\n'
'#l10n 82 (ES - Hello for 123)\n'
'#l10n 83 (ES - Hello)\n'
'#l10n 84 (ES - Hello World)\n'
'#l10n 85 (ES - Hello two worlds)\n'
'#l10n 86 (ES - Hello)\n'
'#l10n 87 (ES - Hello nuevo World)\n'
'#l10n 88 (ES - Hello two nuevo worlds)\n'
'#l10n 89 (ES - Hello on viernes, 1 de enero de 1960)\n'
'#l10n 90 (ES - Hello World, on viernes, 1 de enero de 1960)\n'
'#l10n 91 (ES - Hello two worlds, on viernes, 1 de enero de 1960)\n'
'#l10n 92 (ES - Hello other 0 worlds, with a total of 100 citizens)\n'
'#l10n 93 (ES - Hello World of 101 citizens)\n'
'#l10n 94 (ES - Hello two worlds with 102 total citizens)\n'
'#l10n 95 (ES - [Hola] -Mundo- #123#)\n'
'#l10n 96 (ES - \$!)\n'
'#l10n 97 (ES - One \$)\n'
"#l10n 98 (ES - Flutter's amazing!)\n"
"#l10n 99 (ES - Flutter's amazing, times 2!)\n"
'#l10n 100 (ES - Flutter is "amazing"!)\n'
'#l10n 101 (ES - Flutter is "amazing", times 2!)\n'
'#l10n 102 (ES - 16 wheel truck)\n'
"#l10n 103 (ES - Sedan's elegance)\n"
'#l10n 104 (ES - Cabriolet has "acceleration")\n'
'#l10n 105 (ES - Oh, she found ES - 1 itemES - !)\n'
'#l10n 106 (ES - Indeed, ES - they like ES - Flutter!)\n'
'#l10n 107 (--- es_419 ---)\n'
'#l10n 108 (ES 419 - Hello World)\n'
'#l10n 109 (ES 419 - Hello two worlds)\n'
'#l10n 109 (ES 419 - Hello)\n'
'#l10n 110 (ES 419 - Hello World)\n'
'#l10n 111 (ES 419 - Hello two worlds)\n'
'#l10n END\n'
);
}
......
......@@ -227,6 +227,8 @@ class Home extends StatelessWidget {
"${localizations.doubleQuoteSelect('cabriolet')}",
"${localizations.pluralInString(1)}",
"${localizations.selectInString('he')}",
"${localizations.selectWithPlaceholder('male', 'ice cream')}",
"${localizations.selectWithPlaceholder('female', 'chocolate')}",
]);
},
),
......@@ -655,6 +657,15 @@ void main() {
"placeholders": {
"gender": {}
}
},
"selectWithPlaceholder": "Indeed, {gender, select, male {he likes {preference}} female {she likes {preference}} other {they like {preference}}}!",
"@selectWithPlaceholder": {
"description": "A select message with prefix, suffix strings, and a placeholder.",
"placeholders": {
"gender": {},
"preference": {}
}
}
}
''';
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment