[gen_l10n] Add support for adding placeholders inside select (#92753)
This commit is contained in:
parent
31ee09f6bf
commit
fae84f6714
@ -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": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
''';
|
||||
|
Loading…
x
Reference in New Issue
Block a user