/// <summary>
        /// returns true, if the get the string s2 at index matches the expression expr
        /// </summary>
        static bool MatchExpr(LineSegment lineSegment, char[] expr, int index, IDocument document, bool ignoreCase)
        {
            for (int i = 0, j = 0; i < expr.Length; ++i, ++j)
            {
                switch (expr[i])
                {
                case '@':                         // "special" meaning
                    ++i;
                    if (i == expr.Length)
                    {
                        throw new HighlightingDefinitionInvalidException("Unexpected end of @ sequence, use @@ to look for a single @.");
                    }
                    switch (expr[i])
                    {
                    case 'C':                                     // match whitespace or punctuation
                        if (index + j == lineSegment.Offset || index + j >= lineSegment.Offset + lineSegment.Length)
                        {
                            // nothing (EOL or SOL)
                        }
                        else
                        {
                            char ch = document.GetCharAt(lineSegment.Offset + index + j);
                            if (!Char.IsWhiteSpace(ch) && !Char.IsPunctuation(ch))
                            {
                                return(false);
                            }
                        }
                        break;

                    case '!':                                     // don't match the following expression
                    {
                        StringBuilder whatmatch = new StringBuilder();
                        ++i;
                        while (i < expr.Length && expr[i] != '@')
                        {
                            whatmatch.Append(expr[i++]);
                        }
                        if (lineSegment.Offset + index + j + whatmatch.Length < document.TextLength)
                        {
                            int k = 0;
                            for (; k < whatmatch.Length; ++k)
                            {
                                char docChar  = ignoreCase ? Char.ToUpperInvariant(document.GetCharAt(lineSegment.Offset + index + j + k)) : document.GetCharAt(lineSegment.Offset + index + j + k);
                                char spanChar = ignoreCase ? Char.ToUpperInvariant(whatmatch[k]) : whatmatch[k];
                                if (docChar != spanChar)
                                {
                                    break;
                                }
                            }
                            if (k >= whatmatch.Length)
                            {
                                return(false);
                            }
                        }
//									--j;
                        break;
                    }

                    case '-':                                     // don't match the  expression before
                    {
                        StringBuilder whatmatch = new StringBuilder();
                        ++i;
                        while (i < expr.Length && expr[i] != '@')
                        {
                            whatmatch.Append(expr[i++]);
                        }
                        if (index - whatmatch.Length >= 0)
                        {
                            int k = 0;
                            for (; k < whatmatch.Length; ++k)
                            {
                                char docChar  = ignoreCase ? Char.ToUpperInvariant(document.GetCharAt(lineSegment.Offset + index - whatmatch.Length + k)) : document.GetCharAt(lineSegment.Offset + index - whatmatch.Length + k);
                                char spanChar = ignoreCase ? Char.ToUpperInvariant(whatmatch[k]) : whatmatch[k];
                                if (docChar != spanChar)
                                {
                                    break;
                                }
                            }
                            if (k >= whatmatch.Length)
                            {
                                return(false);
                            }
                        }
//									--j;
                        break;
                    }

                    case '@':                                     // matches @
                        if (index + j >= lineSegment.Length || '@' != document.GetCharAt(lineSegment.Offset + index + j))
                        {
                            return(false);
                        }
                        break;
                    }
                    break;

                default:
                {
                    if (index + j >= lineSegment.Length)
                    {
                        return(false);
                    }
                    char docChar  = ignoreCase ? Char.ToUpperInvariant(document.GetCharAt(lineSegment.Offset + index + j)) : document.GetCharAt(lineSegment.Offset + index + j);
                    char spanChar = ignoreCase ? Char.ToUpperInvariant(expr[i]) : expr[i];
                    if (docChar != spanChar)
                    {
                        return(false);
                    }
                    break;
                }
                }
            }
            return(true);
        }
 protected virtual void OnParsedLine(IDocument document, LineSegment currentLine, List <TextWord> words)
 {
 }
 protected virtual HighlightColor GetColor(HighlightRuleSet ruleSet, IDocument document, LineSegment currentSegment, int currentOffset, int currentLength)
 {
     if (ruleSet != null)
     {
         if (ruleSet.Reference != null)
         {
             return(ruleSet.Highlighter.GetColor(document, currentSegment, currentOffset, currentLength));
         }
         else
         {
             return((HighlightColor)ruleSet.KeyWords[document, currentSegment, currentOffset, currentLength]);
         }
     }
     return(null);
 }
        bool MarkTokensInLine(IDocument document, int lineNumber, ref bool spanChanged)
        {
            currentLineNumber = lineNumber;
            bool        processNextLine = false;
            LineSegment previousLine    = (lineNumber > 0 ? document.GetLineSegment(lineNumber - 1) : null);

            currentSpanStack = ((previousLine != null && previousLine.HighlightSpanStack != null) ? previousLine.HighlightSpanStack.Clone() : null);
            if (currentSpanStack != null)
            {
                while (!currentSpanStack.IsEmpty && currentSpanStack.Peek().StopEOL)
                {
                    currentSpanStack.Pop();
                }
                if (currentSpanStack.IsEmpty)
                {
                    currentSpanStack = null;
                }
            }

            currentLine = (LineSegment)document.LineSegmentCollection[lineNumber];

            if (currentLine.Length == -1)               // happens when buffer is empty !
            {
                return(false);
            }

            List <TextWord> words = ParseLine(document);

            if (currentSpanStack != null && currentSpanStack.IsEmpty)
            {
                currentSpanStack = null;
            }

            // Check if the span state has changed, if so we must re-render the next line
            // This check may seem utterly complicated but I didn't want to introduce any function calls
            // or allocations here for perf reasons.
            if (currentLine.HighlightSpanStack != currentSpanStack)
            {
                if (currentLine.HighlightSpanStack == null)
                {
                    processNextLine = false;
                    foreach (Span sp in currentSpanStack)
                    {
                        if (!sp.StopEOL)
                        {
                            spanChanged     = true;
                            processNextLine = true;
                            break;
                        }
                    }
                }
                else if (currentSpanStack == null)
                {
                    processNextLine = false;
                    foreach (Span sp in currentLine.HighlightSpanStack)
                    {
                        if (!sp.StopEOL)
                        {
                            spanChanged     = true;
                            processNextLine = true;
                            break;
                        }
                    }
                }
                else
                {
                    SpanStack.Enumerator e1 = currentSpanStack.GetEnumerator();
                    SpanStack.Enumerator e2 = currentLine.HighlightSpanStack.GetEnumerator();
                    bool done = false;
                    while (!done)
                    {
                        bool blockSpanIn1 = false;
                        while (e1.MoveNext())
                        {
                            if (!((Span)e1.Current).StopEOL)
                            {
                                blockSpanIn1 = true;
                                break;
                            }
                        }
                        bool blockSpanIn2 = false;
                        while (e2.MoveNext())
                        {
                            if (!((Span)e2.Current).StopEOL)
                            {
                                blockSpanIn2 = true;
                                break;
                            }
                        }
                        if (blockSpanIn1 || blockSpanIn2)
                        {
                            if (blockSpanIn1 && blockSpanIn2)
                            {
                                if (e1.Current != e2.Current)
                                {
                                    done            = true;
                                    processNextLine = true;
                                    spanChanged     = true;
                                }
                            }
                            else
                            {
                                spanChanged     = true;
                                done            = true;
                                processNextLine = true;
                            }
                        }
                        else
                        {
                            done            = true;
                            processNextLine = false;
                        }
                    }
                }
            }
            else
            {
                processNextLine = false;
            }

            //// Alex: remove old words
            if (currentLine.Words != null)
            {
                currentLine.Words.Clear();
            }
            currentLine.Words = words;
            currentLine.HighlightSpanStack = (currentSpanStack != null && !currentSpanStack.IsEmpty) ? currentSpanStack : null;

            return(processNextLine);
        }
 public HighlightColor GetColor(IDocument document, LineSegment currentSegment, int currentOffset, int currentLength)
 {
     return(GetColor(defaultRuleSet, document, currentSegment, currentOffset, currentLength));
 }