/// <summary> /// Handles a custom delimeter from it's start until it's end. /// Also handles tokens within those custom delimeters /// </summary> /// <param name="currentToken">current token (which is a delimeter)</param> /// <param name="tokenStream"></param> private List<Token> HandleCustomDelimeter(Token currentToken, IWaneTokenStream tokenStream) { if (!IsCustomDelimeter(currentToken)) throw new ArgumentException("Expected custome delimeter", "currentToken"); var tokens = new List<Token>(); currentToken.IsStartingDelimeter = true; tokens.Add(currentToken); //find ending delimeter List<Token> tokensToInspect = GetRawTokensUntilAndIncludingEndingDelimeter(currentToken, tokenStream); if (tokensToInspect.Count > 0) { //remove ending token else this will not be processed properly Token closingToken = tokensToInspect.Last(); tokensToInspect.RemoveAt(tokensToInspect.Count - 1); var internalStream = new WaneEnumerableTokenStream(tokensToInspect); //get and remove properties ExtractPropertiesFromTokenListAndApplyToCurrentToken(currentToken, internalStream); if (!internalStream.IsEndOfStream) { List<Token> procesedInternalStreamTokens = ProcessTokenStream(internalStream); tokens.AddRange(procesedInternalStreamTokens); } //add closing delimeter token closingToken.IsEndingDelimeter = true; tokens.Add(closingToken); WarnIfClosingTokenHasProperties(closingToken, tokenStream); } else { //no closing delimeter currentToken.ChangeTokenTypeToText(); currentToken.AddWarning("Delimeter start does not have a matching end delimeter, or the actual start delimeter has been escaped"); } return tokens; }
/// <summary> /// Appends text to list of tokens that already exists. /// /// If previous token was text, then appends to that, otherwise appends as it's own token /// </summary> /// <param name="tokens">tokens to append to</param> /// <param name="currentToken">current token</param> /// <param name="allowCurrentTokenToBeAppended">if true if the previous token is not a TEXT then allows current token to be appended to stream, if false only allows token to be combined with previous token if that previous token is TEXT</param> private void AppendTextToTokens(List<Token> tokens, Token currentToken) { Token previousToken = tokens.LastOrDefault(); if (previousToken != null && previousToken.IsText && !previousToken.HasWarnings) previousToken.Text += currentToken.Text; else if(!IsEscapeDelimieter(currentToken)) { if(currentToken.TokenType != TokenType.Text) currentToken.ChangeTokenTypeToText(); tokens.Add(currentToken); } }
/// <summary> /// Determines if a token causes the next token to be escaped /// </summary> /// <param name="currentToken">the current token to check if it's an escape char, and if the escape char is escaping</param> /// <param name="tokenStream">remaining token stream</param> /// <returns>true if causes escape, otherwise false</returns> private bool DelimeterCausesEscape(Token currentToken, IWaneTokenStream tokenStream) { if (IsEscapeDelimieter(currentToken)) { Token nextToken = tokenStream.Peek(); if (nextToken.IsDelimeter) return true; else currentToken.ChangeTokenTypeToText(); } return false; }