/// <summary> /// Tokenizes an identifier. /// </summary> /// <returns>The state result</returns> private StateResult Identifier() { // We assume the first character has been considered. TakeCurrent(); // Take all characters that are considered identifiers. TakeUntil(c => !HandlebarsHelpers.IsIdentifierPart(c)); HandlebarsSymbol symbol = null; if (HaveContent) { var keyword = HandlebarsKeywordDetector.SymbolTypeForIdentifier(Buffer.ToString()); var type = HandlebarsSymbolType.Identifier; if (keyword != null) { type = HandlebarsSymbolType.Keyword; } symbol = new HandlebarsSymbol(CurrentStart, Buffer.ToString(), type) { Keyword = keyword }; } // Start a new symbol. StartSymbol(); return(Stay(symbol)); }
/// <summary> /// Continues the content of the tag. /// </summary> /// <param name="raw">True if we are expected a raw tag.</param> /// <returns>The state result.</returns> private StateResult ContinueTagContent(bool raw) { if (CurrentCharacter == '@') { TakeCurrent(); return(Stay(EndSymbol(HandlebarsSymbolType.At))); } if (HandlebarsHelpers.IsIdentifierStart(CurrentCharacter)) { return(Identifier()); } if (Char.IsDigit(CurrentCharacter)) { return(NumericLiteral()); } switch (CurrentCharacter) { case '.': { TakeCurrent(); if (CurrentCharacter == '/') { // We've matched a link to the current context. TakeCurrent(); return(Stay(EndSymbol(HandlebarsSymbolType.CurrentContext))); } if (CurrentCharacter == '.' && Peek() == '/') { // We've matched a link to the parent context. TakeCurrent(); TakeCurrent(); return(Stay(EndSymbol(HandlebarsSymbolType.ParentContext))); } // We've matched a dot, which could be part of an expression. return(Stay(EndSymbol(HandlebarsSymbolType.Dot))); } case '/': { TakeCurrent(); // We've matched a forward-slash, which could be part of an expression. return(Stay(EndSymbol(HandlebarsSymbolType.Slash))); } case ' ': { // Take all the available whitespace. TakeUntil(c => !ParserHelpers.IsWhiteSpace(c)); return(Stay(EndSymbol(HandlebarsSymbolType.WhiteSpace))); } case '~': { TakeCurrent(); // We've reached a '~' character, so jump to the end of the tag. return(Transition(EndSymbol(HandlebarsSymbolType.Tilde), () => EndTag(raw))); } case '"': case '\'': { var quote = CurrentCharacter; TakeCurrent(); // We've reached a quoted literal. return(QuotedLiteral(quote)); } case '=': { // We're reached a map assignment. TakeCurrent(); return(Stay(EndSymbol(HandlebarsSymbolType.Assign))); } case '}': { // We've reached a closing tag, so transition away. return(Transition(() => EndTag(raw))); } default: { CurrentErrors.Add(new Error("Unexpected character: " + CurrentCharacter, CurrentLocation)); return(Transition(Stop)); } } }