/// <summary> /// Clones this instance and all of it's items. This lets us reuse pattern parsing result, without having to remember /// the item's initial state before being modified to match the results of the formatters. /// </summary> /// <returns> /// The <see cref="IFormatterRequestCollection" />. /// </returns> public IFormatterRequestCollection Clone() { var result = new FormatterRequestCollection(); foreach (var request in this) { result.Add(request.Clone()); } return(result); }
/// <summary> /// Parses the specified source. /// </summary> /// <param name="source"> /// The source. /// </param> /// <returns> /// The <see cref="IFormatterRequestCollection" />. /// </returns> public IFormatterRequestCollection Parse(StringBuilder source) { var literals = this.literalParser.ParseLiterals(source).ToArray(); if (literals.Length == 0) { return(new FormatterRequestCollection()); } var result = new FormatterRequestCollection(); foreach (var literal in literals) { // The first token to follow an opening brace will be the variable name. int lastIndex; string variableName = ReadLiteralSection(literal, 0, false, out lastIndex) !; // The next (if any), is the formatter to use. Null is allowed. string?formatterKey = null; // The rest of the string is what we pass into the formatter. Can be null. string?formatterArgs = null; if (variableName.Length != literal.InnerText.Length) { formatterKey = ReadLiteralSection(literal, variableName.Length + 1, true, out lastIndex); if (formatterKey != null) { formatterArgs = literal.InnerText.ToString(lastIndex + 1, literal.InnerText.Length - lastIndex - 1).Trim(); } } result.Add(new FormatterRequest(literal, variableName, formatterKey, formatterArgs)); } return(result); }