public NumberFormatPattern GetDecimalNotationFormat() { if (decimalNotation == null) { XElement pattern = elements.FirstOrDefault(v => v.Name.LocalName == "decimalFormats"); if (pattern == null) { decimalNotation = this.Parent.GetDecimalNotationFormat(); } else if (CldrUtility.IsAlias(pattern, out string numberSystem)) { decimalNotation = GetFormat(locale, numberSystem).GetDecimalNotationFormat(); } else { pattern = pattern.XPathSelectElement("decimalFormatLength[not(@type)]/decimalFormat/pattern"); if (pattern == null) { decimalNotation = this.Parent.GetDecimalNotationFormat(); } else { decimalNotation = ParseNumberFormatPattern(pattern.Value); } } } return(decimalNotation); }
public FormattedString GetRangePattern(FormattedPartType greatestDifference, ICollection <string> patterns) { Guard.ArgumentNotNull(patterns, "patterns"); if (!partId.ContainsKey(greatestDifference)) { throw new ArgumentOutOfRangeException("greatestDifference"); } if (patterns.Count == 0) { throw new ArgumentException("Collection should contain at least one element", "patternId"); } XElement dateTimeFormats = root.XPathSelectElement("dateTimeFormats"); if (CldrUtility.IsAlias(dateTimeFormats, out string calendar)) { return(Resolve(locale, calendar).GetRangePattern(greatestDifference, patterns)); } foreach (XElement child in dateTimeFormats.XPathSelectElements("intervalFormats/intervalFormatItem")) { string formatId = child.Attribute("id").Value; if (patterns.Contains(formatId)) { return(GetRangePattern(formatId, partId[greatestDifference])); } } if (dateTimeFormats.Attribute("inherits") != null) { return(this.GetGenericOrParent().GetRangePattern(greatestDifference, patterns)); } return(null); }
public NumberFormatPattern GetPercentStyleFormat() { if (percentFormats == null) { XElement pattern = elements.FirstOrDefault(v => v.Name.LocalName == "percentFormats"); if (pattern == null) { percentFormats = this.Parent.GetPercentStyleFormat(); } else if (CldrUtility.IsAlias(pattern, out string numberSystem)) { percentFormats = GetFormat(locale, numberSystem).GetPercentStyleFormat(); } else { pattern = pattern.XPathSelectElement("percentFormatLength/percentFormat/pattern"); if (pattern == null) { percentFormats = this.Parent.GetPercentStyleFormat(); } else { percentFormats = ParseNumberFormatPattern(pattern.Value); } } } return(percentFormats); }
public ReadOnlyDictionary <PluralCategories, ReadOnlyDictionary <int, NumberFormatPattern> > GetCompactNotationFormats(NumberCompactDisplayFormat style) { XElement decimalFormats = elements.FirstOrDefault(v => v.Name.LocalName == "decimalFormats"); if (decimalFormats == null) { return(this.Parent.GetCompactNotationFormats(style)); } if (CldrUtility.IsAlias(decimalFormats, out string numberSystem)) { return(GetFormat(locale, numberSystem).GetCompactNotationFormats(style)); } Dictionary <PluralCategories, Dictionary <int, NumberFormatPattern> > dict = new Dictionary <PluralCategories, Dictionary <int, NumberFormatPattern> >(); foreach (PluralCategories kind in pluralRules.EnumerateCategories()) { dict[kind] = new Dictionary <int, NumberFormatPattern>(); } XElement decimalFormat = decimalFormats.XPathSelectElement(String.Format("decimalFormatLength[@type = '{0}']/decimalFormat", IntlProviderOptions.ToStringValue(style))); foreach (XElement pattern in decimalFormat.XPathSelectElements("pattern")) { PluralCategories count = IntlProviderOptions.ParseEnum <PluralCategories>(pattern.Attribute("count").Value); dict[count][pattern.Attribute("type").Value.Length - 1] = ParseNumberFormatPattern(pattern.Value); } if (decimalFormat.Attribute("inherits") != null) { ReadOnlyDictionary <PluralCategories, ReadOnlyDictionary <int, NumberFormatPattern> > parent = this.Parent.GetCompactNotationFormats(style); foreach (KeyValuePair <PluralCategories, ReadOnlyDictionary <int, NumberFormatPattern> > e in parent) { CldrUtility.CopyPatternFromParent(dict[e.Key], e.Value); } } return(new ReadOnlyDictionary <PluralCategories, ReadOnlyDictionary <int, NumberFormatPattern> >(dict.ToDictionary(v => v.Key, v => new ReadOnlyDictionary <int, NumberFormatPattern>(v.Value)))); }
public static string GetCanonicalRegionName(string value, string lang) { Guard.ArgumentNotNull(value, "value"); Guard.ArgumentNotNull(lang, "lang"); Dictionary <string, string> cached = aliasLookup.GetOrAdd("territory", _ => { Dictionary <string, string> dict = new Dictionary <string, string>(); XDocument supplementalData = CldrUtility.LoadXml("Codeless.Ecma.Intl.Data.supplementalMetadata.xml.gz"); foreach (XElement elm in supplementalData.XPathSelectElements("/supplementalData/metadata/alias/territoryAlias")) { string from = elm.Attribute("type").Value.ToLowerInvariant(); string to = elm.Attribute("replacement").Value; dict[from] = to; } return(dict); }); if (cached.TryGetValue(value.ToLowerInvariant(), out string canonical)) { if (canonical.IndexOf(' ') <= 0) { return(canonical); } Dictionary <string, BcpLanguageTag> likelySubtags = EnsureLikelySubtagData(); string[] candidates = canonical.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); foreach (string candidate in candidates) { if (likelySubtags.TryGetValue(String.Concat("und-", candidate), out BcpLanguageTag tag) && tag.Language == lang) { return(candidate); } } return(candidates[0]); } return(value.ToUpperInvariant()); }
private Dictionary <string, string> GetCombinePatterns() { if (this.combinePatterns == null) { XElement dateTimeFormats = root.XPathSelectElement("dateTimeFormats"); if (CldrUtility.IsAlias(dateTimeFormats, out string calendar)) { this.combinePatterns = Resolve(locale, calendar).GetCombinePatterns(); } else { Dictionary <string, string> combinePatterns = new Dictionary <string, string>(); foreach (XElement child in dateTimeFormats.Elements("dateTimeFormatLength")) { combinePatterns[child.Attribute("type").Value] = Regex.Replace(child.XPathSelectElement("dateTimeFormat/pattern").Value, "'([^']*)'", m => { return(m.Length == 2 ? "'" : m.Groups[1].Value); }); } if (combinePatterns.Count < 4) { CldrUtility.CopyPatternFromParent(combinePatterns, this.Parent.GetCombinePatterns()); } this.combinePatterns = combinePatterns; } } return(this.combinePatterns); }
private static string GetHourFormat(string locale) { XElement hourFormat = timeZones.XPathSelectElement(String.Format("/root/timeZoneNames[@locale = '{0}']/hourFormat", locale)); if (hourFormat != null) { return(hourFormat.Value); } return(CldrUtility.GetParentPatterns(locale, GetHourFormat)); }
private ReadOnlyDictionary <PluralCategories, string> GetUnitSubFormat(string unit, UnitDisplayFormat format, bool perUnit = false) { XDocument units = CldrUtility.LoadXml("Codeless.Ecma.Intl.Data.units.xml.gz"); XElement unitLength = units.XPathSelectElement(String.Format("/root/units[@locale = '{0}']/unitLength[@type = '{1}']", locale, IntlProviderOptions.ToStringValue(format))); if (unitLength == null) { return(this.Parent.GetUnitSubFormat(unit, format)); } if (CldrUtility.IsAlias(unitLength, out string type)) { return(GetUnitSubFormat(unit, IntlProviderOptions.ParseEnum <UnitDisplayFormat>(type), perUnit)); } bool hasInheritedValues = unitLength.Attribute("inherits") != null; if (unit == "per") { XElement perCompountUnit = unitLength.XPathSelectElement("compoundUnit[@type = 'per']/compoundUnitPattern"); if (perCompountUnit == null) { return(hasInheritedValues ? this.Parent.GetUnitSubFormat(unit, format) : null); } return(CreateSingleResult(perCompountUnit.Value)); } XElement unitElm = unitLength.XPathSelectElement(String.Format("unit[substring-after(@type, '-') = '{0}']", unit)); if (unitElm == null) { return(hasInheritedValues ? this.Parent.GetUnitSubFormat(unit, format) : null); } if (perUnit) { XElement perUnitPattern = unitElm.XPathSelectElement("perUnitPattern"); if (perUnitPattern == null) { return(hasInheritedValues ? this.Parent.GetUnitSubFormat(unit, format) : null); } return(CreateSingleResult(perUnitPattern.Value)); } Dictionary <PluralCategories, string> dict = new Dictionary <PluralCategories, string>(); foreach (XElement unitPattern in unitElm.XPathSelectElements("unitPattern")) { dict[IntlProviderOptions.ParseEnum <PluralCategories>(unitPattern.Attribute("count").Value)] = unitPattern.Value; } if (unitElm.Attribute("inherits") != null) { ReadOnlyDictionary <PluralCategories, string> parent = this.Parent.GetUnitSubFormat(unit, format); CldrUtility.CopyPatternFromParent(dict, parent); } return(new ReadOnlyDictionary <PluralCategories, string>(dict)); }
private static Dictionary <string, BcpLanguageTag> EnsureLikelySubtagData() { if (likelySubtags == null) { Dictionary <string, BcpLanguageTag> map = new Dictionary <string, BcpLanguageTag>(); XDocument xDocument = CldrUtility.LoadXml("Codeless.Ecma.Intl.Data.likelySubtags.xml.gz"); foreach (XElement elm in xDocument.XPathSelectElements("/supplementalData/likelySubtags/likelySubtag")) { map[elm.Attribute("from").Value] = Parse(elm.Attribute("to").Value); } likelySubtags = map; } return(likelySubtags); }
private FormattedString GetRangePattern(string formatId, string id) { string key = String.Concat(formatId, "/", id); if (rangeFormats.TryGetValue(key, out FormattedString cached)) { return(cached); } XElement dateTimeFormats = root.XPathSelectElement("dateTimeFormats"); if (CldrUtility.IsAlias(dateTimeFormats, out string use)) { return(rangeFormats.GetOrAdd(key, Resolve(locale, use).GetRangePattern(formatId, id))); } XElement pattern = dateTimeFormats.XPathSelectElement(String.Format("intervalFormats/intervalFormatItem[@id = '{0}']/greatestDifference[@id = '{1}']", formatId, id)); if (pattern == null) { return(null); } string patternValue = pattern.Value; Match m = Regex.Match(patternValue, "(?<p>(?:'[^']*'|\\s|[^a-zA-Z]|(?<d>[yMLdGEcabBhHkKmszv])\\k<d>*)+)((?:'[^']*'|\\s|[^a-zA-Z])+)\\k<p>"); if (!m.Success) { return(new FormattedString(new[] { new FormattedPart(FormattedPartType.Literal, patternValue) })); } List <FormattedPart> parts = new List <FormattedPart>(); Group repeated = m.Groups["p"]; if (repeated.Index > 0) { parts.Add(GetPlaceholderOrLiteral(patternValue.Substring(0, repeated.Index))); } string repeatedFormat = ParseDateTimeFormat(repeated.Value, out _); parts.Add(new FormattedPart(FormattedPartType.StartRangePlaceholder, repeatedFormat)); parts.Add(GetPlaceholderOrLiteral(m.Groups[1].Value)); parts.Add(new FormattedPart(FormattedPartType.EndRangePlaceholder, repeatedFormat)); if (m.Index + m.Length < patternValue.Length) { parts.Add(GetPlaceholderOrLiteral(patternValue.Substring(m.Index + m.Length))); } return(rangeFormats.GetOrAdd(key, new FormattedString(parts))); }
public static string GetCanonicalVariantName(string value) { Guard.ArgumentNotNull(value, "value"); Dictionary <string, string> cached = aliasLookup.GetOrAdd("variant", _ => { Dictionary <string, string> dict = new Dictionary <string, string>(); XDocument supplementalData = CldrUtility.LoadXml("Codeless.Ecma.Intl.Data.supplementalMetadata.xml.gz"); foreach (XElement elm in supplementalData.XPathSelectElements("/supplementalData/metadata/alias/variantAlias")) { string from = elm.Attribute("type").Value.ToLowerInvariant().Replace('_', '-'); string to = elm.Attribute("replacement").Value.Replace('_', '-'); dict[from] = to; } return(dict); }); return(cached.TryGetValue(value.ToLowerInvariant(), out string canonical) ? canonical : value.ToLowerInvariant()); }
public static CldrRelativeTimeFormat Resolve(string locale, string type) { string key = locale + "/" + type; if (resolvedPatterns.TryGetValue(key, out CldrRelativeTimeFormat cached)) { return(cached); } CldrRelativeTimeFormat formatter = new CldrRelativeTimeFormat(locale, type); XElement field = xDocument.XPathSelectElement(String.Format("/root/fields[@locale = '{0}']/field[@type = '{1}']", locale, type)); if (field == null) { throw new InvalidOperationException("Unknown locale or type"); } if (CldrUtility.IsAlias(field, out string use)) { return(resolvedPatterns.GetOrAdd(key, Resolve(locale, use))); } bool hasInheritedValues = field.Attribute("inherits") != null; foreach (XElement relative in field.Elements("relative")) { int amount = Int32.Parse(relative.Attribute("type").Value); formatter.relative[amount] = FormattedString.Parse(relative.Value); } foreach (XElement relativeTime in field.Elements("relativeTime")) { Dictionary <PluralCategories, FormattedString> dict = relativeTime.Attribute("type").Value == "future" ? formatter.future : formatter.past; foreach (XElement child in relativeTime.Elements()) { PluralCategories category = IntlProviderOptions.ParseEnum <PluralCategories>(child.Attribute("count").Value); dict[category] = FormattedString.Parse(child.Value); } hasInheritedValues |= relativeTime.Attribute("inherits") != null; } if (hasInheritedValues) { CldrRelativeTimeFormat parent = CldrUtility.GetParentPatterns(locale, type, Resolve); CldrUtility.CopyPatternFromParent(formatter.relative, parent.relative); CldrUtility.CopyPatternFromParent(formatter.future, parent.future); CldrUtility.CopyPatternFromParent(formatter.past, parent.past); } return(resolvedPatterns.GetOrAdd(key, formatter)); }
private static DateTime[] GetEraStartDates() { if (eras == null) { XDocument doc = CldrUtility.LoadXml("Codeless.Ecma.Intl.Data.supplementalData.xml.gz"); List <DateTime> values = new List <DateTime>(); foreach (XElement era in doc.XPathSelectElements("/supplementalData/calendarData/calendar[@type = 'japanese']/eras/era")) { try { values.Add(DateTime.Parse(era.Attribute("start").Value)); } catch { values.Add(new DateTime(Int32.Parse(era.Attribute("start").Value.Substring(0, 4)), 3, 1)); } } eras = values.ToArray(); } return(eras); }
private NumberFormatPattern GetCurrencyStyleFormat(CurrencySignFormat sign) { XElement currencyFormats = elements.FirstOrDefault(v => v.Name.LocalName == "currencyFormats"); if (currencyFormats == null) { return(this.Parent.GetCurrencyStyleFormat(sign)); } if (CldrUtility.IsAlias(currencyFormats, out string numberSystem)) { return(GetFormat(locale, numberSystem).GetCurrencyStyleFormat(sign)); } XElement currencyFormat = currencyFormats.XPathSelectElement(String.Format("currencyFormatLength[not(@type)]/currencyFormat[@type = '{0}']", IntlProviderOptions.ToStringValue(sign))); if (currencyFormat == null) { return(this.Parent.GetCurrencyStyleFormat(sign)); } return(ParseNumberFormatPattern(currencyFormat.Value)); }
private IEnumerable <XElement> GetAvailableFormats() { XElement dateTimeFormats = root.XPathSelectElement("dateTimeFormats"); if (CldrUtility.IsAlias(dateTimeFormats, out string calendar)) { return(Resolve(locale, calendar).GetAvailableFormats()); } XElement availableFormats = dateTimeFormats.Element("availableFormats"); if (availableFormats == null) { return(this.Parent.GetAvailableFormats()); } IEnumerable <XElement> dateFormatItems = availableFormats.Elements("dateFormatItem"); if (availableFormats.Attribute("inherits") != null) { return(dateFormatItems.Concat(this.Parent.GetAvailableFormats())); } return(dateFormatItems); }
private static string GetMetaZoneName(string locale, string metaZone, TimeZoneNameStyle style, bool isDaylightSaving) { XElement metazoneNames = timeZones.XPathSelectElement(String.Format("/root/timeZoneNames[@locale = '{0}']/*[(local-name() = 'metazone' or local-name() = 'zone') and @type = '{1}']", locale, metaZone)); if (metazoneNames != null) { if (style == TimeZoneNameStyle.Short) { metazoneNames = metazoneNames.Element("short") ?? metazoneNames.Element("long"); } else { metazoneNames = metazoneNames.Element("long"); } XElement name = metazoneNames.Element(isDaylightSaving ? "daylight" : "standard"); if (name != null) { return(name.Value); } } return(CldrUtility.GetParentPatterns(locale, s => GetMetaZoneName(s, metaZone, style, isDaylightSaving))); }
public static CldrPluralRules Resolve(PluralRuleType type, string locale) { string normalizedLocale = IntlUtility.RemoveUnicodeExtensions(locale); ConcurrentDictionary <string, CldrPluralRules> cache = type == PluralRuleType.Cardinal ? cardinalRules : ordinalRules; return(cache.GetOrAdd(normalizedLocale, _ => { XDocument doc = CldrUtility.LoadXml(type == PluralRuleType.Cardinal ? CardinalFileName : OrdinalFileName); foreach (XElement node in doc.XPathSelectElements(Xpath)) { string[] locales = node.Attribute("locales").Value.Split(' '); if (locales.Contains(normalizedLocale)) { CldrPluralRules rule = new CldrPluralRules(node); foreach (string v in locales) { cache.TryAdd(v, rule); } return rule; } } return Resolve(type, CldrUtility.GetParentLocale(normalizedLocale)); })); }
public static string GetDefaultExtensionValue(string key) { Guard.ArgumentNotNull(key, "key"); switch (key) { case "hc": return(IntlProviderOptions.ToStringValue(CldrUtility.GetDefaultHourCycle(IntlContext.RegionCode))); case "ca": foreach (string type in CldrUtility.GetPreferredCalenderTypes(IntlContext.RegionCode)) { if (SupportedCalendars.ContainsKey(type)) { return(type); } } break; } if (SupportedValues.ContainsKey(key)) { return(SupportedValues[key][0]); } return(null); }
public static string GetCanonicalExtensionValue(string key, string value) { Guard.ArgumentNotNull(key, "key"); Guard.ArgumentNotNull(value, "value"); Dictionary <string, string> cached = aliasLookup.GetOrAdd(key.ToLowerInvariant(), k => { Dictionary <string, string> dict = new Dictionary <string, string>(); if (k == "sd" || k == "rg") { XDocument supplementalData = CldrUtility.LoadXml("Codeless.Ecma.Intl.Data.supplementalData.xml.gz"); foreach (XElement elm in supplementalData.XPathSelectElements("/supplementalData/metadata/alias/subdivisionAlias")) { string from = elm.Attribute("type").Value.ToLowerInvariant().Replace('_', '-'); string to = elm.Attribute("replacement").Value.Replace('_', '-'); dict[from] = to; } } else { XDocument bcp47 = CldrUtility.LoadXml("Codeless.Ecma.Intl.Data.bcp47.xml.gz"); foreach (XElement elm in bcp47.XPathSelectElements(String.Format("/ldmlBCP47/keyword/key[@name = '{0}']/type[@alias or @deprecated]", k))) { if (elm.Attribute("deprecated") != null) { dict[elm.Attribute("name").Value.ToLowerInvariant()] = elm.Attribute("preferred").Value; } else { dict[elm.Attribute("alias").Value.ToLowerInvariant()] = elm.Attribute("name").Value; } } } return(dict); }); return(cached.TryGetValue(value.ToLowerInvariant(), out string canonical) ? canonical : value); }
public ReadOnlyCollection <CldrDateTimeFormat> GetAvailableTimeFormats() { if (this.timeFormats == null) { XElement timeFormats = root.XPathSelectElement("timeFormats"); if (CldrUtility.IsAlias(timeFormats, out string calendar)) { this.timeFormats = Resolve(locale, calendar).GetAvailableTimeFormats(); } else { Dictionary <string, XElement> patterns = new Dictionary <string, XElement>(); foreach (XElement timeFormatLength in timeFormats.Elements("timeFormatLength")) { patterns[timeFormatLength.Attribute("type").Value] = timeFormatLength.XPathSelectElement("timeFormat/pattern"); } foreach (XElement dateFormatItem in GetAvailableFormats()) { string id = dateFormatItem.Attribute("id").Value; if (id.IndexOfAny(requiredTimeComponents) >= 0 && id.IndexOfAny(unsupportedTimeComponents) < 0) { patterns[id] = dateFormatItem; } } Dictionary <DateTimePartStyles, CldrDateTimeFormat> formats = new Dictionary <DateTimePartStyles, CldrDateTimeFormat>(); Dictionary <DateTimePartStyles, List <string> > patternKeys = new Dictionary <DateTimePartStyles, List <string> >(); foreach (KeyValuePair <string, XElement> entry in patterns) { string pattern = ParseDateTimeFormat(entry.Value.Value, out DateTimePartStyles styles); if (!formats.TryGetValue(styles, out CldrDateTimeFormat format)) { List <string> patternIds = new List <string>(); format = new CldrDateTimeFormat(this, styles, pattern, patternIds); formats.Add(styles, format); patternKeys.Add(styles, patternIds); } if (patternKeys.TryGetValue(styles, out List <string> keys)) { keys.Add(entry.Key); } } if (timeFormats.Attribute("inherits") != null) { ReadOnlyCollection <CldrDateTimeFormat> parentFormats = GetGenericOrParent().GetAvailableDateFormats(); foreach (string key in new[] { "full", "long", "medium", "short" }) { if (!patterns.ContainsKey(key)) { CldrDateTimeFormat parent = parentFormats.FirstOrDefault(v => v.PatternId.Contains(key)); if (parent != null) { formats[parent.Styles] = parent; } } } } this.timeFormats = formats.Values.ToList().AsReadOnly(); } } return(this.timeFormats); }
private Dictionary <string, string[]> GetLabels(int type, string sectionName, string path, Dictionary <string, string> keyMapping, string[] types = null) { if (this.labels[type] == null) { XElement section = root.XPathSelectElement(sectionName); if (section == null) { this.labels[type] = this.Parent.GetLabels(type, sectionName, path, keyMapping, types); } else if (CldrUtility.IsAlias(section, out string calendar)) { this.labels[type] = Resolve(locale, calendar).GetLabels(type, sectionName, path, keyMapping, types); } else { bool hasInheritedValues = false; Dictionary <string, string> copy = new Dictionary <string, string>(); Dictionary <string, string[]> dict = new Dictionary <string, string[]>(); foreach (XElement child in section.XPathSelectElements(path)) { string labelType = keyMapping[child.Attribute("type")?.Value ?? child.Name.LocalName]; if (CldrUtility.IsAlias(child, out string use)) { copy[labelType] = keyMapping[use]; } else { IEnumerable <XElement> elements = child.XPathSelectElements("*[not(@alt)]"); string[] labels = (types == null ? elements : types.Select(v => elements.FirstOrDefault(w => w.Attribute("type").Value == v))).Select(v => v?.Value).ToArray(); hasInheritedValues |= labels.Contains(null); dict[labelType] = labels; } } foreach (KeyValuePair <string, string> e in copy) { dict[e.Key] = dict[e.Value]; } if (dict.Count < 3 || hasInheritedValues) { Dictionary <string, string[]> parent = this.Parent.GetLabels(type, sectionName, path, keyMapping, types); if (locale != "root") { if (dict.Count == 0) { dict = parent; } else { if (dict.Count < 3) { CldrUtility.CopyPatternFromParent(dict, parent); } } } if (!dict.ContainsKey("narrow")) { dict["narrow"] = dict.ContainsKey("short") ? dict["short"] : dict["long"]; } if (!dict.ContainsKey("short")) { dict["short"] = dict.ContainsKey("narrow") ? dict["narrow"] : dict["long"]; } if (!dict.ContainsKey("long")) { dict["long"] = dict.ContainsKey("short") ? dict["short"] : dict["narrow"]; } if (hasInheritedValues) { foreach (KeyValuePair <string, string[]> e in dict) { CldrUtility.CopyPatternFromParent(e.Value, parent[e.Key]); } } } this.labels[type] = dict; } } return(this.labels[type]); }