public FormattedString Format(EcmaValue value) { EnsureInitialized(); NumberFormatInfo formatter = formatProvider.FormatProvider; value = value.ToNumber(); if (value.IsNaN || !value.IsFinite) { string str = value.ToDouble().ToString(formatter); return(new FormattedString(new[] { new FormattedPart(value.IsNaN ? FormattedPartType.NaN : FormattedPartType.Infinity, str) })); } double doubleValue = value.ToDouble(); if (this.SignDisplay == SignDisplayFormat.Never) { doubleValue = Math.Abs(doubleValue); } if (this.Style == NumberStyle.Percent) { doubleValue *= 100; } PluralCategories pluralCount = pluralRules.Match(doubleValue); NumberFormatPattern notationFormats = this.Notation == NumberNotation.Compact ? GetCompactNotationPattern(doubleValue, pluralCount, out doubleValue) : this.notationFormats; NumberFormatPattern styleFormats = this.styleFormats.Count == 1 ? this.styleFormats[PluralCategories.Other] : this.styleFormats[pluralCount]; FormattedString notationFormat = null; FormattedString styleFormat = null; switch (doubleValue.CompareTo(0)) { case -1: notationFormat = notationFormats.NegativePattern; styleFormat = styleFormats.NegativePattern; break; case 0: notationFormat = notationFormats.ZeroPattern; styleFormat = styleFormats.ZeroPattern; break; case 1: notationFormat = notationFormats.PositivePattern; styleFormat = styleFormats.PositivePattern; break; } if (this.Digits.RoundingType == RoundingType.SignificantDigits) { doubleValue = RoundToSignificantDigits(doubleValue, this.Digits.MaximumSignificantDigits); } // format double value with corresponding notation (scienific, compact, ...) List <FormattedPart> numParts = new List <FormattedPart>(notationFormat); List <FormattedPart> subParts = new List <FormattedPart>(); int index = numParts.FindIndex(v => v.Type == FormattedPartType.Placeholder); string formatted = doubleValue.ToString(numParts[index].Value, formatter); FormattedPartType integerType = FormattedPartType.Integer; RoundingType roundingType = this.Digits.RoundingType; int maxDigits = roundingType == RoundingType.SignificantDigits ? this.Digits.MaximumSignificantDigits : -1; int numOfDigits = 0; foreach (Match m in Regex.Matches(formatted, "([0-9]+)|.")) { FormattedPartType type = FormattedPartType.Literal; string str = m.Value; if (m.Groups[1].Success) { type = integerType; if (roundingType == RoundingType.SignificantDigits) { if (type != FormattedPartType.ExponentInteger) { numOfDigits += numOfDigits == 0 ? str.TrimStart('0').Length : str.Length; } if (type == FormattedPartType.Fraction && numOfDigits > maxDigits) { str = str.Substring(0, str.Length - numOfDigits + maxDigits); } } } else if (symbolType.TryGetValue(str, out type)) { if (type == FormattedPartType.Decimal) { integerType = FormattedPartType.Fraction; } else if (type == FormattedPartType.ExponentSeparator) { integerType = FormattedPartType.ExponentInteger; } } subParts.Add(new FormattedPart(type, str)); } numParts.RemoveAt(index); numParts.InsertRange(index, subParts); // format as curreny or unit with the formatted number List <FormattedPart> finalParts = new List <FormattedPart>(styleFormat); index = finalParts.FindIndex(v => v.Type == FormattedPartType.Placeholder); finalParts.RemoveAt(index); finalParts.InsertRange(index, numParts); return(new FormattedString(finalParts)); }
public PluralCategories ResolveCategory(double number) { EnsureInitialized(); return(resolver.Match(number)); }