private static Regex CreateRegex(IFormattingInfo info) { StringBuilder pattern = new StringBuilder(); bool first = true; foreach (CodeElement p in info.Patterns) { if (first) { first = false; } else { pattern.Append("|"); } pattern.Append(p.Regex); } RegexOptions options = RegexOptions.Multiline; if (!info.CaseSensitive) { options |= RegexOptions.IgnoreCase; } return(new Regex(pattern.ToString(), options)); }
public bool TryEvaluateFormat(IFormattingInfo formattingInfo) { var expression = formattingInfo.FormatterOptions ?? string.Empty; var formats = formattingInfo.Format?.Split('|'); if (formats is null) { return(false); } if (formats.Count == 0) { return(true); } if (formats.Count != 2) { throw new FormatException("Exactly 2 format options are required."); } var regEx = new Regex(expression, RegexOptions); if (formattingInfo.CurrentValue != null && regEx.IsMatch(formattingInfo.CurrentValue.ToString() !)) { formattingInfo.Write(formats[0], formattingInfo.CurrentValue); }
private static Format DetermineChosenFormat(IFormattingInfo formattingInfo, IList<Format> choiceFormats, string[] chooseOptions) { var currentValue = formattingInfo.CurrentValue; var currentValueString = (currentValue == null) ? "null" : currentValue.ToString(); var chosenIndex = Array.IndexOf(chooseOptions, currentValueString); // Validate the number of formats: if (choiceFormats.Count < chooseOptions.Length) { throw formattingInfo.FormattingException("You must specify at least " + chooseOptions.Length + " choices"); } else if (choiceFormats.Count > chooseOptions.Length + 1) { throw formattingInfo.FormattingException("You cannot specify more than " + (chooseOptions.Length + 1) + " choices"); } else if (chosenIndex == -1 && choiceFormats.Count == chooseOptions.Length) { throw formattingInfo.FormattingException("\"" + currentValueString + "\" is not a valid choice, and a \"default\" choice was not supplied"); } if (chosenIndex == -1) { chosenIndex = choiceFormats.Count - 1; } var chosenFormat = choiceFormats[chosenIndex]; return chosenFormat; }
///<inheritdoc /> public bool TryEvaluateFormat(IFormattingInfo formattingInfo) { var format = formattingInfo.Format; var current = formattingInfo.CurrentValue; // Check whether arguments can be handled by this formatter if (format is { HasNested : true })
private static bool FormatCodeMultilanguage(IFormattingInfo info, string code, StringBuilder result, int start, int length, IMultilanguageFormattingInfo multilanguageInfo) { bool usedFallbackFormatting = false; string fullContextCode = null; LanguageRegion[] regions = multilanguageInfo.SplitRegions(code, start, length).ToArray(); foreach (LanguageRegion region in regions) { if (region.CssClass != null) { result.Append("<span class=\""); result.Append(region.CssClass); result.Append("\">"); } IFormattingInfo regionInfo = region.FormattingInfo ?? info; string regionCode = code; if (region.NeedsFullContext) { if (fullContextCode == null) { fullContextCode = StripAndAdjustRegionsForContext(code, regions, start, length); } regionCode = fullContextCode; } usedFallbackFormatting |= FormatCodeCore(regionInfo, regionCode, result, region.FormattingInfo != null, region.Start, region.Length, region.NeedsFullContext); if (region.CssClass != null) { result.Append("</span>"); } } return(usedFallbackFormatting); }
private PluralRules.PluralRuleDelegate?GetPluralRule(IFormattingInfo formattingInfo) { // See if the language was explicitly passed: var pluralOptions = formattingInfo.FormatterOptions; if (pluralOptions?.Length != 0) { return(PluralRules.GetPluralRule(pluralOptions)); } // See if a CustomPluralRuleProvider is available from the FormatProvider: var provider = formattingInfo.FormatDetails.Provider; var pluralRuleProvider = (CustomPluralRuleProvider?)provider?.GetFormat(typeof(CustomPluralRuleProvider)); if (pluralRuleProvider != null) { return(pluralRuleProvider.GetPluralRule()); } // Use the CultureInfo, if provided: if (provider is CultureInfo cultureInfo) { var culturePluralRule = PluralRules.GetPluralRule(cultureInfo.TwoLetterISOLanguageName); return(culturePluralRule); } // Use the default, if provided: return(PluralRules.GetPluralRule(DefaultTwoLetterISOLanguageName));; }
public bool TryEvaluateFormat(IFormattingInfo formattingInfo) { if (formattingInfo.FormatterOptions == "") return false; var chooseOptions = formattingInfo.FormatterOptions.Split(splitChar); var formats = formattingInfo.Format.Split(splitChar); if (formats.Count < 2) return false; var chosenFormat = DetermineChosenFormat(formattingInfo, formats, chooseOptions); formattingInfo.Write(chosenFormat, formattingInfo.CurrentValue); return true; }
public bool TryEvaluateFormat(IFormattingInfo formattingInfo) { var obj = formattingInfo.CurrentValue; var type = obj.GetType(); var foreignKey = (IForeignKey)type.GetProperty("ForeignKeyObject").GetValue(obj, null); var namespaceString = (string)type.GetProperty("Namespace").GetValue(obj, null); var nakedEntityName = EntityListFormatter.GetNakedNameOfIEntityType(foreignKey.DeclaringEntityType); formattingInfo.Write(string.Format("using {0}.{1}Classes", namespaceString, nakedEntityName)); return(true); }
public bool TryEvaluateFormat(IFormattingInfo formattingInfo) { var format = formattingInfo.Format; var current = formattingInfo.CurrentValue; // Ignore formats that start with "?" (this can be used to bypass this extension) if (format == null || format.baseString[format.startIndex] == ':') { return false; } // Extract the plural words from the format string: var pluralWords = format.Split('|'); // This extension requires at least two plural words: if (pluralWords.Count == 1) return false; // See if the value is a number: var currentIsNumber = current is byte || current is short || current is int || current is long || current is float || current is double || current is decimal; // This extension only formats numbers: if (!currentIsNumber) return false; // Normalize the number to decimal: var value = Convert.ToDecimal(current); // Get the plural rule: var pluralRule = GetPluralRule(formattingInfo); if (pluralRule == null) { // Not a supported language. return false; } var pluralCount = pluralWords.Count; var pluralIndex = pluralRule(value, pluralCount); if (pluralIndex < 0 || pluralWords.Count <= pluralIndex) { // The plural rule should always return a value in-range! throw new FormattingException(format, "Invalid number of plural parameters", pluralWords.Last().endIndex); } // Output the selected word (allowing for nested formats): var pluralForm = pluralWords[pluralIndex]; formattingInfo.Write(pluralForm, current); return true; }
public bool TryEvaluateFormat(IFormattingInfo formattingInfo) { var iCanHandleThisInput = formattingInfo.CurrentValue is IEnumerable <IAnnotation>; if (!iCanHandleThisInput) { return(false); } var appending = formattingInfo.Format.GetLiteralText(); var annotations = (IEnumerable <IAnnotation>)formattingInfo.CurrentValue; formattingInfo.Write(GetAnnotationString(annotations, appending)); return(true); }
public void Write(string text, int startIndex, int length, IFormattingInfo formattingInfo) { // Depending on the nested level, we will color this item differently: if (formattingInfo.FormatDetails.FormattingException != null) { output.BackColor(errorColor).Append(text, startIndex, length); } else if (formattingInfo.Placeholder == null) { // There is no "nesting" so just output plain text: output.Append(text, startIndex, length); } else { var nestedDepth = formattingInfo.Placeholder.NestedDepth; var backcolor = this.nestedColors[nestedDepth % nestedColors.Length]; output.BackColor(backcolor).Append(text, startIndex, length); } }
public bool TryEvaluateFormat(IFormattingInfo formattingInfo) { var format = formattingInfo.Format; var current = formattingInfo.CurrentValue; if (format != null && format.HasNested) return false; string options; if (formattingInfo.FormatterOptions != "") options = formattingInfo.FormatterOptions; else if (format != null) options = format.GetLiteralText(); else options = ""; TimeSpan fromTime; if (current is TimeSpan) { fromTime = (TimeSpan)current; } else if (current is DateTime && formattingInfo.FormatterOptions != "") { fromTime = DateTime.Now.Subtract((DateTime)current); } else if (current is DateTime && options.StartsWith("timestring")) { options = options.Substring(10); fromTime = DateTime.Now.Subtract((DateTime)current); } else { return false; } var timeTextInfo = GetTimeTextInfo(formattingInfo.FormatDetails.Provider); if (timeTextInfo == null) { return false; } var formattingOptions = TimeSpanFormatOptionsConverter.Parse(options); var timeString = TimeSpanUtility.ToTimeString(fromTime, formattingOptions, timeTextInfo); formattingInfo.Write(timeString); return true; }
public bool TryEvaluateFormat(IFormattingInfo formattingInfo) { var templateName = formattingInfo.FormatterOptions; if (templateName == "") { if (formattingInfo.Format.HasNested) { return false; } templateName = formattingInfo.Format.RawText; } Format template; if (!_templates.TryGetValue(templateName, out template)) { return false; } formattingInfo.Write(template, formattingInfo.CurrentValue); return true; }
public bool TryEvaluateFormat(IFormattingInfo formattingInfo) { var format = formattingInfo.Format; var current = formattingInfo.CurrentValue; XElement currentXElement = null; if (format != null && format.HasNested) return false; // if we need to format list of XElements then we just take and format first var xElmentsAsList = current as IList<XElement>; if (xElmentsAsList != null && xElmentsAsList.Count > 0) { currentXElement = xElmentsAsList[0]; } var currentAsXElement = (currentXElement) ?? current as XElement; if (currentAsXElement != null) { formattingInfo.Write(currentAsXElement.Value); return true; } return false; }
private PluralRules.PluralRuleDelegate GetPluralRule(IFormattingInfo formattingInfo) { // See if the language was explicitly passed: var pluralOptions = formattingInfo.FormatterOptions; if (pluralOptions.Length != 0) { return PluralRules.GetPluralRule(pluralOptions); } // See if a CustomPluralRuleProvider is available from the FormatProvider: var provider = formattingInfo.FormatDetails.Provider; if (provider != null) { var pluralRuleProvider = (CustomPluralRuleProvider) provider.GetFormat(typeof (CustomPluralRuleProvider)); if (pluralRuleProvider != null) { return pluralRuleProvider.GetPluralRule(); } } // Use the CultureInfo, if provided: var cultureInfo = provider as CultureInfo; if (cultureInfo != null) { var culturePluralRule = PluralRules.GetPluralRule(cultureInfo.TwoLetterISOLanguageName); return culturePluralRule; } // Use the default, if provided: if (this.defaultPluralRule != null) { return this.defaultPluralRule; } return null; }
public bool TryEvaluateFormat(IFormattingInfo formattingInfo) { var format = formattingInfo.Format; var current = formattingInfo.CurrentValue; if (format == null) return false; // Ignore a leading ":", which is used to bypass the PluralLocalizationExtension if (format.baseString[format.startIndex] == ':') { format = format.Substring(1); } // See if the format string contains un-nested "|": var parameters = format.Split('|'); if (parameters.Count == 1) return false; // There are no parameters found. // See if the value is a number: var currentIsNumber = current is byte || current is short || current is int || current is long || current is float || current is double || current is decimal; // An Enum is a number too: if (currentIsNumber == false && current != null && current.GetType().IsEnum) { currentIsNumber = true; } var currentNumber = currentIsNumber ? Convert.ToDecimal(current) : 0; int paramIndex; // Determines which parameter to use for output // First, we'll see if we are using "complex conditions": if (currentIsNumber) { paramIndex = -1; while (true) { paramIndex++; if (paramIndex == parameters.Count) { // We reached the end of our parameters, // so we output nothing return true; } bool conditionWasTrue; Format outputItem; if (!TryEvaluateCondition(parameters[paramIndex], currentNumber, out conditionWasTrue, out outputItem)) { // This parameter doesn't have a // complex condition (making it a "else" condition) // Only do "complex conditions" if the first item IS a "complex condition". if (paramIndex == 0) { break; } // Otherwise, output the "else" section: conditionWasTrue = true; } // If the conditional statement was true, then we can break. if (conditionWasTrue) { formattingInfo.Write(outputItem, current); return true; } } // We don't have any "complex conditions", // so let's do the normal conditional formatting: } var paramCount = parameters.Count; // Determine the Current item's Type: if (currentIsNumber) { if (currentNumber < 0) { paramIndex = paramCount - 1; } else { paramIndex = Math.Min((int)Math.Floor(currentNumber), paramCount - 1); } } else if (current is bool) { // Bool: True|False bool arg = (bool)current; if (arg) { paramIndex = 0; } else { paramIndex = 1; } } else if (current is DateTime) { // Date: Past|Present|Future or Past/Present|Future DateTime arg = (DateTime)current; if (paramCount == 3 && arg.Date == DateTime.Today) { paramIndex = 1; } else if (arg <= DateTime.Now) { paramIndex = 0; } else { paramIndex = paramCount - 1; } } else if (current is TimeSpan) { // TimeSpan: Negative|Zero|Positive or Negative/Zero|Positive TimeSpan arg = (TimeSpan)current; if (paramCount == 3 && arg == TimeSpan.Zero) { paramIndex = 1; } else if (arg.CompareTo(TimeSpan.Zero) <= 0) { paramIndex = 0; } else { paramIndex = paramCount - 1; } } else if (current is string) { // String: Value|NullOrEmpty var arg = (string)current; if (!string.IsNullOrEmpty(arg)) { paramIndex = 0; } else { paramIndex = 1; } } else { // Object: Something|Nothing object arg = current; if (arg != null) { paramIndex = 0; } else { paramIndex = 1; } } // Now, output the selected parameter: var selectedParameter = parameters[paramIndex]; // Output the selectedParameter: formattingInfo.Write(selectedParameter, current); return true; }
public void Write(string text, IFormattingInfo formattingInfo) { Output.Write(text); }
public void Write(string text, int startIndex, int length, IFormattingInfo formattingInfo) { Output.Write(text.Substring(startIndex, length)); }
public void Write(string text, int startIndex, int length, IFormattingInfo formattingInfo) { output.Append(text, startIndex, length); }
public void Write(string text, IFormattingInfo formattingInfo) { output.Append(text); }
public bool TryEvaluateFormat(IFormattingInfo formattingInfo) { var format = formattingInfo.Format; var current = formattingInfo.CurrentValue; // If the format has nested placeholders, we process those first // instead of formatting the item: if (format != null && format.HasNested) { formattingInfo.Write(format, current); return true; } // If the object is null, we shouldn't write anything if (current == null) { current = ""; } // (The following code was adapted from the built-in String.Format code) // We will try using IFormatProvider, IFormattable, and if all else fails, ToString. string result = null; ICustomFormatter cFormatter; IFormattable formattable; // Use the provider to see if a CustomFormatter is available: var provider = formattingInfo.FormatDetails.Provider; if (provider != null && (cFormatter = provider.GetFormat(typeof(ICustomFormatter)) as ICustomFormatter) != null) { var formatText = format == null ? null : format.GetLiteralText(); result = cFormatter.Format(formatText, current, provider); } // IFormattable: else if ((formattable = current as IFormattable) != null) { var formatText = format == null ? null : format.ToString(); result = formattable.ToString(formatText, provider); } // ToString: else { result = current.ToString(); } // Now that we have the result, let's output it (and consider alignment): // See if there's a pre-alignment to consider: if (formattingInfo.Alignment > 0) { var spaces = formattingInfo.Alignment - result.Length; if (spaces > 0) { formattingInfo.Write(new String(' ', spaces)); } } // Output the result: formattingInfo.Write(result); // See if there's a post-alignment to consider: if (formattingInfo.Alignment < 0) { var spaces = -formattingInfo.Alignment - result.Length; if (spaces > 0) { formattingInfo.Write(new String(' ', spaces)); } } return true; }
public bool TryEvaluateFormat(IFormattingInfo formattingInfo) { var format = formattingInfo.Format; var current = formattingInfo.CurrentValue; // Ignore formats that start with "?" (this can be used to bypass this extension) if (format == null || format.baseString[format.startIndex] == ':') { return false; } // Extract the plural words from the format string: var pluralWords = format.Split('|'); // This extension requires at least two plural words: if (pluralWords.Count == 1) return false; decimal value; // We can format numbers, and IEnumerables. For IEnumerables we look at the number of items // in the collection: this means the user can e.g. use the same parameter for both plural and list, for example // 'Smart.Format("The following {0:plural:person is|people are} impressed: {0:list:{}|, |, and}", new[] { "bob", "alice" });' if (current is byte || current is short || current is int || current is long || current is float || current is double || current is decimal) { // Normalize the number to decimal: value = Convert.ToDecimal(current); } else if (current is IEnumerable<object>) { // Relay on IEnumerable covariance, but don't care about non-generic IEnumerable value = ((IEnumerable<object>)current).Count(); } else { // This extension only permits numbers and IEnumerables return false; } // Get the plural rule: var pluralRule = GetPluralRule(formattingInfo); if (pluralRule == null) { // Not a supported language. return false; } var pluralCount = pluralWords.Count; var pluralIndex = pluralRule(value, pluralCount); if (pluralIndex < 0 || pluralWords.Count <= pluralIndex) { // The plural rule should always return a value in-range! throw new FormattingException(format, "Invalid number of plural parameters", pluralWords.Last().endIndex); } // Output the selected word (allowing for nested formats): var pluralForm = pluralWords[pluralIndex]; formattingInfo.Write(pluralForm, current); return true; }
public bool TryEvaluateFormat(IFormattingInfo formattingInfo) { var options = formattingInfo.FormatterOptions; var format = formattingInfo.Format; var formatString = format != null ? format.ToString() : ""; formattingInfo.Write("TestExtension2 Options: " + options + ", Format: " + formatString); return true; }
public bool TryEvaluateFormat(IFormattingInfo formattingInfo) { var format = formattingInfo.Format; var current = formattingInfo.CurrentValue; // This method needs the Highest priority so that it comes before the PluralLocalizationExtension and ConditionalExtension // This extension requires at least IEnumerable var enumerable = current as IEnumerable; if (enumerable == null) return false; // Ignore Strings, because they're IEnumerable. // This issue might actually need a solution // for other objects that are IEnumerable. if (current is string) return false; // If the object is IFormattable, ignore it if (current is IFormattable) return false; // This extension requires a | to specify the spacer: if (format == null) return false; var parameters = format.Split('|', 4); if (parameters.Count < 2) return false; // Grab all formatting options: // They must be in one of these formats: // itemFormat|spacer // itemFormat|spacer|lastSpacer // itemFormat|spacer|lastSpacer|twoSpacer var itemFormat = parameters[0]; var spacer = (parameters.Count >= 2) ? parameters[1].GetLiteralText() : ""; var lastSpacer = (parameters.Count >= 3) ? parameters[2].GetLiteralText() : spacer; var twoSpacer = (parameters.Count >= 4) ? parameters[3].GetLiteralText() : lastSpacer; // TODO: [Obsolete] Not necessary, should remove: if (!itemFormat.HasNested) { // The format is not nested, // so we will treat it as an itemFormat: var newItemFormat = new Format(itemFormat.baseString); newItemFormat.startIndex = itemFormat.startIndex; newItemFormat.endIndex = itemFormat.endIndex; newItemFormat.HasNested = true; var newPlaceholder = new Placeholder(newItemFormat, itemFormat.startIndex, 0); newPlaceholder.Format = itemFormat; newPlaceholder.endIndex = itemFormat.endIndex; newItemFormat.Items.Add(newPlaceholder); itemFormat = newItemFormat; } // Let's buffer all items from the enumerable (to ensure the Count without double-enumeration): ICollection items = current as ICollection; if (items == null) { var allItems = new List<object>(); foreach (var item in enumerable) { allItems.Add(item); } items = allItems; } int oldCollectionIndex = CollectionIndex; // In case we have nested arrays, we might need to restore the CollectionIndex CollectionIndex = -1; foreach (object item in items) { CollectionIndex += 1; // Keep track of the index // Determine which spacer to write: if (spacer == null || CollectionIndex == 0) { // Don't write the spacer. } else if (CollectionIndex < items.Count - 1) { formattingInfo.Write(spacer); } else if (CollectionIndex == 1) { formattingInfo.Write(twoSpacer); } else { formattingInfo.Write(lastSpacer); } // Output the nested format for this item: formattingInfo.Write(itemFormat, item); } CollectionIndex = oldCollectionIndex; // Restore the CollectionIndex return true; }
public void Write(string text, IFormattingInfo formattingInfo) { Write(text, 0, text.Length, formattingInfo); }