getStrings method
Converts a string such as
%1N smile%1s at %2 with %1his eyes sparkling in the light of %3.
Returns an object which can be used to send the right string to the right observer.
If no number is provided after a % (per cent) sign, defaultIndex is used.
If no suffix name is provided, defaultSuffix is assumed.
Assuming the defaults haven't been changed, this means %
will be
expanded to 51n
.
Make the suffix names upper case to have the strings rendered with their first letter capitalised.
Implementation
SocialContext<T> getStrings(String socialString, List<T> perspectives) {
final Map<T, String> targetedStrings = <T, String>{
for (final perspective in perspectives) perspective: socialString
};
final String defaultString =
socialString.replaceAllMapped(suffixRegExp, (Match m) {
final fullString = m.group(0);
if (fullString == null) {
throw Exception('RegExp group(0) returned null.');
}
var indexString = m.group(1);
if (indexString == null || indexString.isEmpty) {
indexString = defaultIndex;
}
final int index = int.parse(indexString);
if (index > perspectives.length || index < 1) {
throw NoSuchIndexError(index, perspectives.length);
}
final T perspective = perspectives[index - 1];
var suffixName = m.group(2);
if (suffixName == null || suffixName.isEmpty) {
suffixName = defaultSuffix;
}
final suffix = suffixes[suffixName.toLowerCase()];
if (suffix == null) {
throw NoSuchSuffixError(suffixName.toLowerCase());
}
final SuffixResult result = suffix(perspective);
var filterName = m.group(3);
if (filterName != null) {
filterName = filterName.substring(1);
final filter = filters[filterName];
if (filter == null) {
throw NoSuchFilter(filterName);
}
result.applyFilter(filter);
}
if (startsAsUpperCase(suffixName)) {
result.applyFilter(toTitleCase);
}
for (final entry in targetedStrings.entries) {
final p = entry.key;
final currentValue = targetedStrings[p];
if (currentValue == null) {
throw Exception('Somehow `currentValue` is null.');
}
final String value;
if (p == perspective) {
value = result.firstPerson;
} else {
value = result.secondPerson;
}
targetedStrings[p] = currentValue.replaceFirst(fullString, value);
}
return result.secondPerson;
});
return SocialContext<T>(targetedStrings, defaultString);
}