/// <summary> /// Highlights the specified line in the specified document. /// /// Before calling this method, <see cref="CurrentSpanStack"/> must be set to the proper /// state for the beginning of this line. After highlighting has completed, /// <see cref="CurrentSpanStack"/> will be updated to represent the state after the line. /// </summary> public HighlightedLine HighlightLine(IDocument document, IDocumentLine line) { this.lineStartOffset = line.Offset; this.lineText = document.GetText(line); try { this.highlightedLine = new HighlightedLine(document, line); HighlightLineInternal(); return(this.highlightedLine); } finally { this.highlightedLine = null; this.lineText = null; this.lineStartOffset = 0; } }
/// <inheritdoc/> public HighlightedLine HighlightLine(int lineNumber) { ThrowUtil.CheckInRangeInclusive(lineNumber, "lineNumber", 1, document.LineCount); CheckIsHighlighting(); isHighlighting = true; try { HighlightUpTo(lineNumber - 1); IDocumentLine line = document.GetLineByNumber(lineNumber); HighlightedLine result = engine.HighlightLine(document, line); UpdateTreeList(lineNumber); return(result); } finally { isHighlighting = false; } }
/// <inheritdoc/> protected override void ColorizeLine(DocumentLine line) { IHighlighter highlighter = CurrentContext.TextView.Services.GetService(typeof(IHighlighter)) as IHighlighter; if (highlighter != null) { HighlightedLine hl = highlighter.HighlightLine(line.LineNumber); foreach (HighlightedSection section in hl.Sections) { ChangeLinePart(section.Offset, section.Offset + section.Length, visualLineElement => ApplyColorToElement(visualLineElement, section.Color)); } } this.lastColorizedLine = line; }
/// <inheritdoc/> public HighlightedLine HighlightLine(int lineNumber) { ThrowUtil.CheckInRangeInclusive(lineNumber, "lineNumber", 1, document.LineCount); CheckIsHighlighting(); isHighlighting = true; try { HighlightUpTo(lineNumber); DocumentLine line = document.GetLineByNumber(lineNumber); highlightedLine = new HighlightedLine(document, line); HighlightLineAndUpdateTreeList(line, lineNumber); return(highlightedLine); } finally { highlightedLine = null; isHighlighting = false; } }
/// <summary> /// Highlights the specified document line. /// </summary> /// <param name="line">The line to highlight.</param> /// <returns>A <see cref="HighlightedLine"/> line object that represents the highlighted sections.</returns> public HighlightedLine HighlightLine(DocumentLine line) { if (!document.Lines.Contains(line)) { throw new ArgumentException("The specified line does not belong to the document."); } highlightedLine = null; int targetLineNumber = line.LineNumber; while (firstInvalidLine < targetLineNumber) { HighlightLineAndUpdateTreeList(document.GetLineByNumber(firstInvalidLine), firstInvalidLine); } highlightedLine = new HighlightedLine(line); HighlightLineAndUpdateTreeList(line, targetLineNumber); return(highlightedLine); }
/// <inheritdoc/> protected override void ColorizeLine(DocumentLine line) { if (CurrentContext.TextView != textView) { throw new InvalidOperationException("Wrong TextView"); } if (highlighter != null) { currentLineEndOffset = line.Offset + line.TotalLength; HighlightedLine hl = highlighter.HighlightLine(line); foreach (HighlightedSection section in hl.Sections) { ChangeLinePart(section.Offset, section.Offset + section.Length, visualLineElement => ApplyColorToElement(visualLineElement, section.Color)); } } }
/// <summary> /// Creates a HTML fragment from a part of a document. /// </summary> /// <param name="document">The document to create HTML from.</param> /// <param name="highlighter">The highlighter used to highlight the document. <c>null</c> is valid and will create HTML without any highlighting.</param> /// <param name="segment">The part of the document to create HTML for. You can pass <c>null</c> to create HTML for the whole document.</param> /// <param name="options">The options for the HTML creation.</param> /// <returns>HTML code for the document part.</returns> public static string CreateHtmlFragment(TextDocument document, IHighlighter highlighter, ISegment segment, HtmlOptions options) { if (document == null) { throw new ArgumentNullException("document"); } if (options == null) { throw new ArgumentNullException("options"); } if (highlighter != null && highlighter.Document != document) { throw new ArgumentException("Highlighter does not belong to the specified document."); } if (segment == null) { segment = new SimpleSegment(0, document.TextLength); } StringBuilder html = new StringBuilder(); int segmentEndOffset = segment.EndOffset; DocumentLine line = document.GetLineByOffset(segment.Offset); while (line != null && line.Offset < segmentEndOffset) { HighlightedLine highlightedLine; if (highlighter != null) { highlightedLine = highlighter.HighlightLine(line.LineNumber); } else { highlightedLine = new HighlightedLine(document, line); } SimpleSegment s = segment.GetOverlap(line); if (html.Length > 0) { html.AppendLine("<br>"); } html.Append(highlightedLine.ToHtml(s.Offset, s.EndOffset, options)); line = line.NextLine; } return(html.ToString()); }
/// <inheritdoc/> protected override void ColorizeLine(DocumentLine line) { if (highlighter != null) { lineNumberBeingColorized = line.LineNumber; HighlightedLine hl = highlighter.HighlightLine(lineNumberBeingColorized); lineNumberBeingColorized = 0; foreach (HighlightedSection section in hl.Sections) { if (IsEmptyColor(section.Color)) { continue; } ChangeLinePart(section.Offset, section.Offset + section.Length, visualLineElement => ApplyColorToElement(visualLineElement, section.Color)); } } this.lastColorizedLine = line; }
public void SimpleMerge1() { HighlightedLine baseLine = new HighlightedLine(document, document.GetLineByNumber(1)); baseLine.Sections.Add(MakeSection(0, 1, "B")); HighlightedLine additionalLine = new HighlightedLine(document, document.GetLineByNumber(1)); additionalLine.Sections.Add(MakeSection(0, 2, "A")); baseLine.MergeWith(additionalLine); // The additional section gets split up so that it fits into the tree structure Assert.That(baseLine.Sections, Is.EqualTo( new[] { MakeSection(0, 1, "B"), MakeSection(0, 1, "A"), MakeSection(1, 2, "A") }).Using(new SectionComparer())); }
/// <summary> /// Highlights the specified document line. /// </summary> /// <param name="line">The line to highlight.</param> /// <returns>A <see cref="HighlightedLine"/> line object that represents the highlighted sections.</returns> public HighlightedLine HighlightLine(DocumentLine line) { if (!document.Lines.Contains(line)) { throw new ArgumentException("The specified line does not belong to the document."); } CheckIsHighlighting(); isHighlighting = true; try { int targetLineNumber = line.LineNumber; HighlightUpTo(targetLineNumber); highlightedLine = new HighlightedLine(document, line); HighlightLineAndUpdateTreeList(line, targetLineNumber); return(highlightedLine); } finally { highlightedLine = null; isHighlighting = false; } }
/// <summary> /// Merges the additional line into this line. /// </summary> public void MergeWith(HighlightedLine additionalLine) { if (additionalLine == null) { return; } #if DEBUG ValidateInvariants(); additionalLine.ValidateInvariants(); #endif int pos = 0; Stack <int> activeSectionEndOffsets = new Stack <int>(); int lineEndOffset = this.DocumentLine.EndOffset; activeSectionEndOffsets.Push(lineEndOffset); foreach (HighlightedSection newSection in additionalLine.Sections) { int newSectionStart = newSection.Offset; // Track the existing sections using the stack, up to the point where // we need to insert the first part of the newSection while (pos < this.Sections.Count) { HighlightedSection s = this.Sections[pos]; if (newSection.Offset < s.Offset) { break; } while (s.Offset > activeSectionEndOffsets.Peek()) { activeSectionEndOffsets.Pop(); } activeSectionEndOffsets.Push(s.Offset + s.Length); pos++; } // Now insert the new section // Create a copy of the stack so that we can track the sections we traverse // during the insertion process: Stack <int> insertionStack = new Stack <int>(activeSectionEndOffsets.Reverse()); // The stack enumerator reverses the order of the elements, so we call Reverse() to restore // the original order. int i; for (i = pos; i < this.Sections.Count; i++) { HighlightedSection s = this.Sections[i]; if (newSection.Offset + newSection.Length <= s.Offset) { break; } // Insert a segment in front of s: Insert(ref i, ref newSectionStart, s.Offset, newSection.Color, insertionStack); while (s.Offset > insertionStack.Peek()) { insertionStack.Pop(); } insertionStack.Push(s.Offset + s.Length); } Insert(ref i, ref newSectionStart, newSection.Offset + newSection.Length, newSection.Color, insertionStack); } #if DEBUG ValidateInvariants(); #endif }