/// <summary> /// Randomizes special groups of characters in <paramref name="Predicate"/> and fills them in with corresponding terms in <paramref name="TermBanks"/>. /// </summary> /// <remarks><para>The way to mark an expression for randomization is to wrap it in braces ("{}"). The format of each expression must be as follows: {IDENTIFIERX}, where IDENTIFIER is a key in <paramref name="TermBanks"/> and X is a positive integer value, every expression with the same identifier and value will be swapped for the same term.</para> /// <para>Special Identifiers exist, which do not run through terms: 'a' will try to guess the most probable expression of the indefinite article.</para></remarks> /// <param name="Predicate">The message whose terms are to be randomized.</param> /// <param name="TermBanks">A string-string[] dictionary where the keys are the explicit identifier of each TermClass and the values are list of terms those expressions can be substituted with.</param> /// <param name="RNG">A Random Number Generator used to extract random terms from <paramref name="TermBanks"/>.</param> /// <param name="Config">The LanguageConfiguration instance to run this process with.</param> /// <returns>A <c>string</c> holding the new, randomized predicate.</returns> public static string RandomizePredicate(string Predicate, Dictionary <string, string[]> TermBanks, Random RNG, LanguageConfiguration Config) { HashSet <TermClass> Terms = new HashSet <TermClass>(); foreach (KeyValuePair <string, string[]> k in TermBanks) { Terms.Add(new TermClass(k.Key, k.Value)); } StringBuilder NewPredicate = new StringBuilder(Predicate.Length * 2); ArticleType ResolveArticle = ArticleType.None; PluralType ResolvePlural = PluralType.None; PossessiveType ResolvePossessive = PossessiveType.None; while (Predicate.Length > 0) { int InsertIndex = Predicate.IndexOf(Config.TermInsertionStartIndicator); if (InsertIndex == -1) { NewPredicate.Append(Predicate); break; } int EndIndex = Predicate.IndexOf(Config.TermInsertionEndIndicator); if (EndIndex == -1) { throw new FormatException($"There was an error parsing predicate {Predicate}, unbalanced braces. Please contact the developer team."); } NewPredicate.Append(Predicate[..InsertIndex]);
/* * Initializes the <code>PluralRules</code> object. * Postcondition:<br/> * <code>ulocale</code> : is <code>locale</code><br/> * <code>pluralRules</code>: if <code>rules</code> != <code>null</code> * it's set to rules, otherwise it is the * predefined plural rule set for the locale * <code>ulocale</code>.<br/> * <code>parsedValues</code>: is <code>null</code><br/> * <code>pattern</code>: is <code>null</code><br/> * <code>numberFormat</code>: a <code>NumberFormat</code> for the locale * <code>ulocale</code>. */ private void Init(PluralRules rules, PluralType type, ULocale locale, NumberFormat numberFormat) { ulocale = locale; pluralRules = (rules == null) ? PluralRules.ForLocale(ulocale, type) : rules; pluralRulesWrapper = new PluralSelectorAdapter(pluralRules); // ICU4N: Have to pass a reference to pluralRules in the constructor ResetPattern(); this.numberFormat = (numberFormat == null) ? NumberFormat.GetInstance(ulocale) : numberFormat; }
/* * Initializes the <code>PluralRules</code> object. * Postcondition:<br/> * <code>ulocale</code> : is <code>locale</code><br/> * <code>pluralRules</code>: if <code>rules</code> != <code>null</code> * it's set to rules, otherwise it is the * predefined plural rule set for the locale * <code>ulocale</code>.<br/> * <code>parsedValues</code>: is <code>null</code><br/> * <code>pattern</code>: is <code>null</code><br/> * <code>numberFormat</code>: a <code>NumberFormat</code> for the locale * <code>ulocale</code>. */ private void Init(PluralRules rules, PluralType type, UCultureInfo locale, NumberFormat numberFormat) { ulocale = locale; pluralRules = (rules == null) ? PluralRules.ForLocale(ulocale, type) // ICU4N TODO: Make extension method for UCultureInfo.GetPluralRules(PluralType)..? : rules; pluralRulesWrapper = new PluralSelectorAdapter(pluralRules); // ICU4N: Have to pass a reference to pluralRules in the constructor ResetPattern(); this.numberFormat = (numberFormat == null) ? NumberFormat.GetInstance(ulocale) : numberFormat; }
/// <summary> /// Returns the plural rules for the the locale. If we don't have data, /// <see cref="PluralRules.Default"/> is returned. /// </summary> #pragma warning disable 672 public override PluralRules ForLocale(ULocale locale, PluralType type) #pragma warning restore 672 { string rulesId = GetRulesIdForLocale(locale, type); if (rulesId == null || rulesId.Trim().Length == 0) { return(PluralRules.Default); } PluralRules rules = GetRulesForRulesId(rulesId); if (rules == null) { rules = PluralRules.Default; } return(rules); }
/// <summary> /// Gets the rulesId from the locale,with locale fallback. If there is no /// rulesId, return null. The rulesId might be the empty string if the rule /// is the default rule. /// </summary> public virtual string GetRulesIdForLocale(ULocale locale, PluralType type) { IDictionary <string, string> idMap = GetLocaleIdToRulesIdMap(type); string localeId = ULocale.Canonicalize(locale.GetBaseName()); string rulesId = null; while (!idMap.TryGetValue(localeId, out rulesId) || null == rulesId) { int ix = localeId.LastIndexOf('_'); if (ix == -1) { break; } localeId = localeId.Substring(0, ix); // ICU4N: Checked 2nd substring arg } return(rulesId); }
/// <summary> /// Returns the lazily-constructed map. /// </summary> private IDictionary <string, string> GetLocaleIdToRulesIdMap(PluralType type) { CheckBuildRulesIdMaps(); return((type == PluralType.Cardinal) ? localeIdToCardinalRulesId : localeIdToOrdinalRulesId); }
/// <summary> /// Creates a new <see cref="PluralFormat"/> for a plural type, a /// pattern and a locale. /// </summary> /// <param name="ulocale">the <see cref="PluralFormat"/> will be configured with /// rules for this locale. This locale will also be used for standard /// number formatting.</param> /// <param name="type">The plural type (e.g., cardinal or ordinal).</param> /// <param name="pattern">the pattern for this <see cref="PluralFormat"/>.</param> /// <param name="numberFormat">The number formatter to use.</param> /// <exception cref="ArgumentException">If the pattern is invalid.</exception> internal PluralFormat(ULocale ulocale, PluralType type, string pattern, NumberFormat numberFormat) { Init(null, type, ulocale, numberFormat); ApplyPattern(pattern); }
/// <summary> /// Creates a new <see cref="PluralFormat"/> for a plural type, a /// pattern and a locale. /// </summary> /// <param name="ulocale">the <see cref="PluralFormat"/> will be configured with /// rules for this locale. This locale will also be used for standard /// number formatting.</param> /// <param name="type">The plural type (e.g., cardinal or ordinal).</param> /// <param name="pattern">the pattern for this <see cref="PluralFormat"/>.</param> /// <exception cref="ArgumentException">if the pattern is invalid.</exception> /// <stable>ICU 50</stable> public PluralFormat(ULocale ulocale, PluralType type, string pattern) { Init(null, type, ulocale, null); ApplyPattern(pattern); }
/// <summary> /// Creates a new <see cref="PluralFormat"/> for the plural type. /// The standard number formatting will be done using the given <see cref="CultureInfo"/>. /// </summary> /// <param name="locale">the default number formatting will be done using this /// locale.</param> /// <param name="type">The plural type (e.g., cardinal or ordinal).</param> /// <stable>ICU 54</stable> public PluralFormat(CultureInfo locale, PluralType type) : this(ULocale.ForLocale(locale), type) { }
/// <summary> /// Creates a new <see cref="PluralFormat"/> for the plural type. /// The standard number formatting will be done using the given locale. /// </summary> /// <param name="ulocale">the default number formatting will be done using this /// locale.</param> /// <param name="type">The plural type (e.g., cardinal or ordinal).</param> /// <stable>ICU 50</stable> public PluralFormat(ULocale ulocale, PluralType type) { Init(null, type, ulocale, null); }
/// <summary> /// Creates a new <see cref="PluralFormat"/> for the plural type. /// The standard number formatting will be done using the given <see cref="CultureInfo"/>. /// </summary> /// <param name="locale">the default number formatting will be done using this /// locale.</param> /// <param name="type">The plural type (e.g., cardinal or ordinal).</param> /// <stable>ICU 54</stable> public PluralFormat(CultureInfo locale, PluralType type) : this(locale.ToUCultureInfo(), type) { }
/// <summary> /// Creates a new <see cref="PluralFormat"/> for the plural type. /// The standard number formatting will be done using the given locale. /// </summary> /// <param name="ulocale">the default number formatting will be done using this /// locale.</param> /// <param name="type">The plural type (e.g., cardinal or ordinal).</param> /// <stable>ICU 50</stable> public PluralFormat(UCultureInfo ulocale, PluralType type) { Init(null, type, ulocale, null); }