public virtual void MarkTokens(IDocument document) { if (Rules.Count == 0) { return; } int lineNumber = 0; while (lineNumber < document.TotalNumberOfLines) { LineSegment previousLine = (lineNumber > 0 ? document.GetLineSegment(lineNumber - 1) : null); if (lineNumber >= document.LineSegmentCollection.Count) // may be, if the last line ends with a delimiter { break; // then the last line is not in the collection :) } 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; } currentLineNumber = lineNumber; List <TextWord> words = ParseLine(document); // Alex: clear old words if (currentLine.Words != null) { currentLine.Words.Clear(); } currentLine.Words = words; currentLine.HighlightSpanStack = (currentSpanStack == null || currentSpanStack.IsEmpty) ? null : currentSpanStack; ++lineNumber; } document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.WholeTextArea)); document.CommitUpdate(); currentLine = null; }
void UpdateSpanStateVariables() { inSpan = (currentSpanStack != null && !currentSpanStack.IsEmpty); activeSpan = inSpan ? currentSpanStack.Peek() : null; activeRuleSet = GetRuleSet(activeSpan); }
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); }