/// <summary> /// Reads a token until the end of a variable segment and advances the enumerator position /// </summary> /// <param name="sb">The StringBuilder to write to</param> /// <param name="markupEnumerator">The string enumerator</param> /// <returns>True if valid variable, otherwise false</returns> private static bool ReadToEndOfVariable(StringBuilder sb, CharEnumerator markupEnumerator) { while (markupEnumerator.HasNext()) { var nextChar = markupEnumerator.Next; if (SearchVariableEnd.Contains(nextChar)) { return(true); } if (!ReadWordChar(sb, markupEnumerator)) { return(false); } } ; return(true); }
/// <summary> /// Enumerates over a variable sequence in dotted or bracket notation /// </summary> /// <param name="source">The Liquid Variable string</param> /// <exception cref="SyntaxException"></exception> internal static IEnumerator <string> GetVariableEnumerator(string source) { if (string.IsNullOrEmpty(source)) { yield break; } using (var markupEnumerator = new CharEnumerator(source)) { while (markupEnumerator.HasNext()) { var isComplete = false; var nextVariable = new StringBuilder(); switch (markupEnumerator.Next) { case '[': // Example Syntax: [var] or ["literal"] markupEnumerator.AppendNext(nextVariable); if (!markupEnumerator.HasNext()) { break; } switch (markupEnumerator.Next) { case '"': case '\'': markupEnumerator.AppendNext(nextVariable); isComplete = ReadToChar(nextVariable, markupEnumerator, markupEnumerator.Next) && ReadToChar(nextVariable, markupEnumerator, BracketEnd); break; default: isComplete = ReadToChar(nextVariable, markupEnumerator, BracketEnd); break; } break; default: isComplete = ReadWordChar(nextVariable, markupEnumerator) && ReadToEndOfVariable(nextVariable, markupEnumerator); break; } if (!isComplete) // Somehow we reached the end without finding the end character(s) { throw new SyntaxException(Liquid.ResourceManager.GetString("VariableNotTerminatedException"), source, Liquid.VariableEnd); } if (markupEnumerator.HasNext() && markupEnumerator.Next == '.' && markupEnumerator.Remaining > 1) // Don't include dot in tokens as it is a separator { markupEnumerator.MoveNext(); } if (nextVariable.Length > 0) { yield return(nextVariable.ToString()); } } ; } }