sub2 = extractSubstitution(owner, predecessor);
}
ruleText = this.ruleText;
- if (ruleText.startsWith("$(") && ruleText.endsWith(")")) {
+ int pluralRuleStart = ruleText.indexOf("$(");
+ int pluralRuleEnd = (pluralRuleStart >= 0 ? ruleText.indexOf(')', pluralRuleStart) : -1);
+ if (pluralRuleEnd >= 0) {
int endType = ruleText.indexOf(',');
if (endType < 0) {
throw new IllegalArgumentException("Rule \"" + ruleText + "\" does not have a defined type");
}
- String type = this.ruleText.substring(2, endType);
+ String type = this.ruleText.substring(pluralRuleStart + 2, endType);
PluralRules.PluralType pluralType;
if ("cardinal".equals(type)) {
pluralType = PluralRules.PluralType.CARDINAL;
throw new IllegalArgumentException(type + " is an unknown type");
}
rulePatternFormat = formatter.createPluralFormat(pluralType,
- ruleText.substring(endType + 1, ruleText.length() - 1));
+ ruleText.substring(endType + 1, pluralRuleEnd));
}
}
// into the right places in toInsertInto (notice we do the
// substitutions in reverse order so that the offsets don't get
// messed up)
+ int pluralRuleStart = ruleText.length();
+ int lengthOffset = 0;
if (rulePatternFormat == null) {
toInsertInto.insert(pos, ruleText);
}
else {
- toInsertInto.insert(pos, rulePatternFormat.format(baseValue == 0 ? number : number/baseValue));
+ pluralRuleStart = ruleText.indexOf("$(");
+ int pluralRuleEnd = ruleText.indexOf(')', pluralRuleStart);
+ int initialLength = toInsertInto.length();
+ if (pluralRuleEnd < ruleText.length() - 1) {
+ toInsertInto.insert(pos, ruleText.substring(pluralRuleEnd + 1));
+ }
+ toInsertInto.insert(pos, rulePatternFormat.format((long)(number/Math.pow(radix, exponent))));
+ if (pluralRuleStart > 0) {
+ toInsertInto.insert(pos, ruleText.substring(0, pluralRuleStart));
+ }
+ lengthOffset = ruleText.length() - (toInsertInto.length() - initialLength);
}
if (!sub2.isNullSubstitution()) {
- sub2.doSubstitution(number, toInsertInto, pos);
+ sub2.doSubstitution(number, toInsertInto, pos - (sub2.getPos() > pluralRuleStart ? lengthOffset : 0));
}
if (!sub1.isNullSubstitution()) {
- sub1.doSubstitution(number, toInsertInto, pos);
+ sub1.doSubstitution(number, toInsertInto, pos - (sub1.getPos() > pluralRuleStart ? lengthOffset : 0));
}
}
// [again, we have two copies of this routine that do the same thing
// so that we don't sacrifice precision in a long by casting it
// to a double]
+ int pluralRuleStart = ruleText.length();
+ int lengthOffset = 0;
if (rulePatternFormat == null) {
toInsertInto.insert(pos, ruleText);
}
else {
- toInsertInto.insert(pos, rulePatternFormat.format(number));
+ pluralRuleStart = ruleText.indexOf("$(");
+ int pluralRuleEnd = ruleText.indexOf(')', pluralRuleStart);
+ int initialLength = toInsertInto.length();
+ if (pluralRuleEnd < ruleText.length() - 1) {
+ toInsertInto.insert(pos, ruleText.substring(pluralRuleEnd + 1));
+ }
+ toInsertInto.insert(pos, rulePatternFormat.format((long)(number/Math.pow(radix, exponent))));
+ if (pluralRuleStart > 0) {
+ toInsertInto.insert(pos, ruleText.substring(0, pluralRuleStart));
+ }
+ lengthOffset = ruleText.length() - (toInsertInto.length() - initialLength);
}
if (!sub2.isNullSubstitution()) {
- sub2.doSubstitution(number, toInsertInto, pos);
+ sub2.doSubstitution(number, toInsertInto, pos - (sub2.getPos() > pluralRuleStart ? lengthOffset : 0));
}
if (!sub1.isNullSubstitution()) {
- sub1.doSubstitution(number, toInsertInto, pos);
+ sub1.doSubstitution(number, toInsertInto, pos - (sub1.getPos() > pluralRuleStart ? lengthOffset : 0));
}
}
pluralFormatKey.parseType(str, scanner, position);
int start = position.getBeginIndex();
if (start >= 0) {
- return new int[]{start, position.getEndIndex() - start};
+ int pluralRuleStart = ruleText.indexOf("$(");
+ int pluralRuleSuffix = ruleText.indexOf(')', pluralRuleStart) + 1;
+ int matchLen = position.getEndIndex() - start;
+ String prefix = ruleText.substring(0, pluralRuleStart);
+ String suffix = ruleText.substring(pluralRuleSuffix);
+ if (str.regionMatches(start - prefix.length(), prefix, 0, prefix.length())
+ && str.regionMatches(start + matchLen, suffix, 0, suffix.length()))
+ {
+ return new int[]{start - prefix.length(), matchLen + prefix.length() + suffix.length()};
+ }
}
return new int[]{-1, 0};
}
+ "200: <<сти[ >>];"
+ "300: <<ста[ >>];"
+ "500: <<сот[ >>];"
- + "1000: <<$(cardinal,one{ тысяча}few{ тысячи}other{ тысяч})[ >>];";
+ + "1000: << $(cardinal,one{тысяча}few{тысячи}other{тысяч})[ >>];"
+ + "1000000: << $(cardinal,one{миллион}few{миллионы}other{миллионов})[ >>];";
RuleBasedNumberFormat ruFormatter = new RuleBasedNumberFormat(ruRules, new ULocale("ru"));
String[][] ruTestData = {
{ "1", "один" },
{ "125", "сто двадцать пять" },
{ "399", "триста девяносто девять" },
{ "1,000", "один тысяча" },
+ { "1,001", "один тысяча один" },
{ "2,000", "два тысячи" },
+ { "2,001", "два тысячи один" },
+ { "2,002", "два тысячи два" },
+ { "3,333", "три тысячи триста тридцать три" },
{ "5,000", "пять тысяч" },
+ { "11,000", "одиннадцать тысяч" },
{ "21,000", "двадцать один тысяча" },
{ "22,000", "двадцать два тысячи" },
};