public override bool TryEvalulateAllLiterals(IFormattingInfo formattingInfo) { var format = formattingInfo.Format; if (format == null) { return(false); } var parameters = format.Split('|', 4); if (parameters.Count < 2) { return(false); } var itemFormat = parameters[0]; // Spacer if (parameters.Count >= 1) { formattingInfo.Write(parameters[0], null); } // Last spacer if (parameters.Count >= 3) { formattingInfo.Write(parameters[2], null); } // Two spacer if (parameters.Count >= 4) { formattingInfo.Write(parameters[3], null); } if (!itemFormat.HasNested) { // The format is not nested, // so we will treat it as an itemFormat: var newItemFormat = FormatItemPool.GetFormat(m_SmartSettings, itemFormat.baseString, itemFormat.startIndex, itemFormat.endIndex, true); var newPlaceholder = FormatItemPool.GetPlaceholder(m_SmartSettings, newItemFormat, itemFormat.startIndex, 0, itemFormat, itemFormat.endIndex); newItemFormat.Items.Add(newPlaceholder); itemFormat = newItemFormat; } formattingInfo.Write(itemFormat, null); return(true); }
public override 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 if (!(current is IEnumerable enumerable)) { 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; if (!itemFormat.HasNested) { // The format is not nested, // so we will treat it as an itemFormat: var newItemFormat = FormatItemPool.GetFormat(m_SmartSettings, itemFormat.baseString, itemFormat.startIndex, itemFormat.endIndex, true); var newPlaceholder = FormatItemPool.GetPlaceholder(m_SmartSettings, newItemFormat, itemFormat.startIndex, 0, itemFormat, itemFormat.endIndex); newItemFormat.Items.Add(newPlaceholder); itemFormat = newItemFormat; } // Let's buffer all items from the enumerable (to ensure the Count without double-enumeration): List <object> bufferItems = null; if (!(current is ICollection items)) { bufferItems = ListPool <object> .Get(); foreach (var item in enumerable) { bufferItems.Add(item); } items = bufferItems; } var oldCollectionIndex = CollectionIndex; // In case we have nested arrays, we might need to restore the CollectionIndex CollectionIndex = -1; foreach (var 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 if (bufferItems != null) { ListPool <object> .Release(bufferItems); } return(true); }