static IEnumerable <TemplateToken> Parse(string text) { var scanner = new TextScanner(text); while (true) { // Find the next start tag var endOfLastToken = scanner.Position; var startTag = scanner.ScanTo(StartTag); if (!startTag.HasValue) { // No more start tags found, emit remaining text token yield return(new TemplateText(text, endOfLastToken, scanner.End)); yield break; } // Otherwise emit text between end of last token and the start tag yield return(new TemplateText(text, endOfLastToken, startTag.Value)); // Find the next end tag var afterStartTag = scanner.Position; var endTag = scanner.ScanTo(EndTag); if (!endTag.HasValue) { throw new TemplateParseError("Couldn't find closing '" + EndTag + "'", startTag.Value.ToPosition(text)); } // emit the text between the start and end tag yield return(new TemplateVariable(text.Substring(afterStartTag, endTag.Value - afterStartTag))); } }