diff options
| author | Roy Ben Shabat <Roy.mail.net@gmail.com> | 2019-04-09 01:47:48 +0300 |
|---|---|---|
| committer | Roy Ben Shabat <Roy.mail.net@gmail.com> | 2019-04-09 01:47:48 +0300 |
| commit | 080f1697e97e13461ec6df4d31c8924d01257a1b (patch) | |
| tree | b1fe0285de7bc9bc52e9e2195e66fe022bf8f5b3 /Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting | |
| parent | 1608e69a417bc5e40a607c3958c4a60f19f66f1a (diff) | |
| download | Tango-080f1697e97e13461ec6df4d31c8924d01257a1b.tar.gz Tango-080f1697e97e13461ec6df4d31c8924d01257a1b.zip | |
MERGE
Diffstat (limited to 'Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting')
54 files changed, 7141 insertions, 0 deletions
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/DocumentHighlighter.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/DocumentHighlighter.cs new file mode 100644 index 000000000..393c0a930 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/DocumentHighlighter.cs @@ -0,0 +1,468 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text.RegularExpressions; + +using Tango.Scripting.Editors.Document; +using Tango.Scripting.Editors.Utils; +using SpanStack = Tango.Scripting.Editors.Utils.ImmutableStack<Tango.Scripting.Editors.Highlighting.HighlightingSpan>; + +namespace Tango.Scripting.Editors.Highlighting +{ + /// <summary> + /// This class can syntax-highlight a document. + /// It automatically manages invalidating the highlighting when the document changes. + /// </summary> + public class DocumentHighlighter : ILineTracker, IHighlighter + { + /// <summary> + /// Stores the span state at the end of each line. + /// storedSpanStacks[0] = state at beginning of document + /// storedSpanStacks[i] = state after line i + /// </summary> + readonly CompressingTreeList<SpanStack> storedSpanStacks = new CompressingTreeList<SpanStack>(object.ReferenceEquals); + readonly CompressingTreeList<bool> isValid = new CompressingTreeList<bool>((a, b) => a == b); + readonly TextDocument document; + readonly HighlightingRuleSet baseRuleSet; + bool isHighlighting; + + /// <summary> + /// Gets the document that this DocumentHighlighter is highlighting. + /// </summary> + public TextDocument Document { + get { return document; } + } + + /// <summary> + /// Creates a new DocumentHighlighter instance. + /// </summary> + public DocumentHighlighter(TextDocument document, HighlightingRuleSet baseRuleSet) + { + if (document == null) + throw new ArgumentNullException("document"); + if (baseRuleSet == null) + throw new ArgumentNullException("baseRuleSet"); + this.document = document; + this.baseRuleSet = baseRuleSet; + WeakLineTracker.Register(document, this); + InvalidateHighlighting(); + } + + void ILineTracker.BeforeRemoveLine(DocumentLine line) + { + CheckIsHighlighting(); + int number = line.LineNumber; + storedSpanStacks.RemoveAt(number); + isValid.RemoveAt(number); + if (number < isValid.Count) { + isValid[number] = false; + if (number < firstInvalidLine) + firstInvalidLine = number; + } + } + + void ILineTracker.SetLineLength(DocumentLine line, int newTotalLength) + { + CheckIsHighlighting(); + int number = line.LineNumber; + isValid[number] = false; + if (number < firstInvalidLine) + firstInvalidLine = number; + } + + void ILineTracker.LineInserted(DocumentLine insertionPos, DocumentLine newLine) + { + CheckIsHighlighting(); + Debug.Assert(insertionPos.LineNumber + 1 == newLine.LineNumber); + int lineNumber = newLine.LineNumber; + storedSpanStacks.Insert(lineNumber, null); + isValid.Insert(lineNumber, false); + if (lineNumber < firstInvalidLine) + firstInvalidLine = lineNumber; + } + + void ILineTracker.RebuildDocument() + { + InvalidateHighlighting(); + } + + ImmutableStack<HighlightingSpan> initialSpanStack = SpanStack.Empty; + + /// <summary> + /// Gets/sets the the initial span stack of the document. Default value is <see cref="SpanStack.Empty" />. + /// </summary> + public ImmutableStack<HighlightingSpan> InitialSpanStack { + get { return initialSpanStack; } + set { + if (value == null) + initialSpanStack = SpanStack.Empty; + else + initialSpanStack = value; + InvalidateHighlighting(); + } + } + + /// <summary> + /// Invalidates all stored highlighting info. + /// When the document changes, the highlighting is invalidated automatically, this method + /// needs to be called only when there are changes to the highlighting rule set. + /// </summary> + public void InvalidateHighlighting() + { + CheckIsHighlighting(); + storedSpanStacks.Clear(); + storedSpanStacks.Add(initialSpanStack); + storedSpanStacks.InsertRange(1, document.LineCount, null); + isValid.Clear(); + isValid.Add(true); + isValid.InsertRange(1, document.LineCount, false); + firstInvalidLine = 1; + } + + int firstInvalidLine; + + /// <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> + [ObsoleteAttribute("Use the (int lineNumber) overload instead")] + public HighlightedLine HighlightLine(DocumentLine line) + { + if (!document.Lines.Contains(line)) + throw new ArgumentException("The specified line does not belong to the document."); + return HighlightLine(line.LineNumber); + } + + /// <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; + } + } + + /// <inheritdoc/> + public SpanStack GetSpanStack(int lineNumber) + { + ThrowUtil.CheckInRangeInclusive(lineNumber, "lineNumber", 0, document.LineCount); + if (firstInvalidLine <= lineNumber) { + CheckIsHighlighting(); + isHighlighting = true; + try { + HighlightUpTo(lineNumber + 1); + } finally { + isHighlighting = false; + } + } + return storedSpanStacks[lineNumber]; + } + + void CheckIsHighlighting() + { + if (isHighlighting) { + throw new InvalidOperationException("Invalid call - a highlighting operation is currently running."); + } + } + + void HighlightUpTo(int targetLineNumber) + { + Debug.Assert(highlightedLine == null); // ensure this method is only used for + while (firstInvalidLine < targetLineNumber) { + HighlightLineAndUpdateTreeList(document.GetLineByNumber(firstInvalidLine), firstInvalidLine); + } + } + + void HighlightLineAndUpdateTreeList(DocumentLine line, int lineNumber) + { + //Debug.WriteLine("Highlight line " + lineNumber + (highlightedLine != null ? "" : " (span stack only)")); + spanStack = storedSpanStacks[lineNumber - 1]; + HighlightLineInternal(line); + if (!EqualSpanStacks(spanStack, storedSpanStacks[lineNumber])) { + isValid[lineNumber] = true; + //Debug.WriteLine("Span stack in line " + lineNumber + " changed from " + storedSpanStacks[lineNumber] + " to " + spanStack); + storedSpanStacks[lineNumber] = spanStack; + if (lineNumber + 1 < isValid.Count) { + isValid[lineNumber + 1] = false; + firstInvalidLine = lineNumber + 1; + } else { + firstInvalidLine = int.MaxValue; + } + OnHighlightStateChanged(line, lineNumber); + } else if (firstInvalidLine == lineNumber) { + isValid[lineNumber] = true; + firstInvalidLine = isValid.IndexOf(false); + if (firstInvalidLine < 0) + firstInvalidLine = int.MaxValue; + } + } + + static bool EqualSpanStacks(SpanStack a, SpanStack b) + { + // We must use value equality between the stacks because TextViewDocumentHighlighter.OnHighlightStateChanged + // depends on the fact that equal input state + unchanged line contents produce equal output state. + if (a == b) + return true; + if (a == null || b == null) + return false; + while (!a.IsEmpty && !b.IsEmpty) { + if (a.Peek() != b.Peek()) + return false; + a = a.Pop(); + b = b.Pop(); + if (a == b) + return true; + } + return a.IsEmpty && b.IsEmpty; + } + + /// <summary> + /// Is called when the highlighting state at the end of the specified line has changed. + /// </summary> + /// <remarks>This callback must not call HighlightLine or InvalidateHighlighting. + /// It may call GetSpanStack, but only for the changed line and lines above. + /// This method must not modify the document.</remarks> + protected virtual void OnHighlightStateChanged(DocumentLine line, int lineNumber) + { + } + + #region Highlighting Engine + SpanStack spanStack; + + // local variables from HighlightLineInternal (are member because they are accessed by HighlighLine helper methods) + string lineText; + int lineStartOffset; + int position; + + /// <summary> + /// the HighlightedLine where highlighting output is being written to. + /// if this variable is null, nothing is highlighted and only the span state is updated + /// </summary> + HighlightedLine highlightedLine; + + void HighlightLineInternal(DocumentLine line) + { + lineStartOffset = line.Offset; + lineText = document.GetText(line.Offset, line.Length); + position = 0; + ResetColorStack(); + HighlightingRuleSet currentRuleSet = this.CurrentRuleSet; + Stack<Match[]> storedMatchArrays = new Stack<Match[]>(); + Match[] matches = AllocateMatchArray(currentRuleSet.Spans.Count); + Match endSpanMatch = null; + + while (true) { + for (int i = 0; i < matches.Length; i++) { + if (matches[i] == null || (matches[i].Success && matches[i].Index < position)) + matches[i] = currentRuleSet.Spans[i].StartExpression.Match(lineText, position); + } + if (endSpanMatch == null && !spanStack.IsEmpty) + endSpanMatch = spanStack.Peek().EndExpression.Match(lineText, position); + + Match firstMatch = Minimum(matches, endSpanMatch); + if (firstMatch == null) + break; + + HighlightNonSpans(firstMatch.Index); + + Debug.Assert(position == firstMatch.Index); + + if (firstMatch == endSpanMatch) { + HighlightingSpan poppedSpan = spanStack.Peek(); + if (!poppedSpan.SpanColorIncludesEnd) + PopColor(); // pop SpanColor + PushColor(poppedSpan.EndColor); + position = firstMatch.Index + firstMatch.Length; + PopColor(); // pop EndColor + if (poppedSpan.SpanColorIncludesEnd) + PopColor(); // pop SpanColor + spanStack = spanStack.Pop(); + currentRuleSet = this.CurrentRuleSet; + //FreeMatchArray(matches); + if (storedMatchArrays.Count > 0) { + matches = storedMatchArrays.Pop(); + int index = currentRuleSet.Spans.IndexOf(poppedSpan); + Debug.Assert(index >= 0 && index < matches.Length); + if (matches[index].Index == position) { + throw new InvalidOperationException( + "A highlighting span matched 0 characters, which would cause an endless loop.\n" + + "Change the highlighting definition so that either the start or the end regex matches at least one character.\n" + + "Start regex: " + poppedSpan.StartExpression + "\n" + + "End regex: " + poppedSpan.EndExpression); + } + } else { + matches = AllocateMatchArray(currentRuleSet.Spans.Count); + } + } else { + int index = Array.IndexOf(matches, firstMatch); + Debug.Assert(index >= 0); + HighlightingSpan newSpan = currentRuleSet.Spans[index]; + spanStack = spanStack.Push(newSpan); + currentRuleSet = this.CurrentRuleSet; + storedMatchArrays.Push(matches); + matches = AllocateMatchArray(currentRuleSet.Spans.Count); + if (newSpan.SpanColorIncludesStart) + PushColor(newSpan.SpanColor); + PushColor(newSpan.StartColor); + position = firstMatch.Index + firstMatch.Length; + PopColor(); + if (!newSpan.SpanColorIncludesStart) + PushColor(newSpan.SpanColor); + } + endSpanMatch = null; + } + HighlightNonSpans(line.Length); + + PopAllColors(); + } + + void HighlightNonSpans(int until) + { + Debug.Assert(position <= until); + if (position == until) + return; + if (highlightedLine != null) { + IList<HighlightingRule> rules = CurrentRuleSet.Rules; + Match[] matches = AllocateMatchArray(rules.Count); + while (true) { + for (int i = 0; i < matches.Length; i++) { + if (matches[i] == null || (matches[i].Success && matches[i].Index < position)) + matches[i] = rules[i].Regex.Match(lineText, position, until - position); + } + Match firstMatch = Minimum(matches, null); + if (firstMatch == null) + break; + + position = firstMatch.Index; + int ruleIndex = Array.IndexOf(matches, firstMatch); + if (firstMatch.Length == 0) { + throw new InvalidOperationException( + "A highlighting rule matched 0 characters, which would cause an endless loop.\n" + + "Change the highlighting definition so that the rule matches at least one character.\n" + + "Regex: " + rules[ruleIndex].Regex); + } + PushColor(rules[ruleIndex].Color); + position = firstMatch.Index + firstMatch.Length; + PopColor(); + } + //FreeMatchArray(matches); + } + position = until; + } + + static readonly HighlightingRuleSet emptyRuleSet = new HighlightingRuleSet() { Name = "EmptyRuleSet" }; + + HighlightingRuleSet CurrentRuleSet { + get { + if (spanStack.IsEmpty) + return baseRuleSet; + else + return spanStack.Peek().RuleSet ?? emptyRuleSet; + } + } + #endregion + + #region Color Stack Management + Stack<HighlightedSection> highlightedSectionStack; + HighlightedSection lastPoppedSection; + + void ResetColorStack() + { + Debug.Assert(position == 0); + lastPoppedSection = null; + if (highlightedLine == null) { + highlightedSectionStack = null; + } else { + highlightedSectionStack = new Stack<HighlightedSection>(); + foreach (HighlightingSpan span in spanStack.Reverse()) { + PushColor(span.SpanColor); + } + } + } + + void PushColor(HighlightingColor color) + { + if (highlightedLine == null) + return; + if (color == null) { + highlightedSectionStack.Push(null); + } else if (lastPoppedSection != null && lastPoppedSection.Color == color + && lastPoppedSection.Offset + lastPoppedSection.Length == position + lineStartOffset) + { + highlightedSectionStack.Push(lastPoppedSection); + lastPoppedSection = null; + } else { + HighlightedSection hs = new HighlightedSection { + Offset = position + lineStartOffset, + Color = color + }; + highlightedLine.Sections.Add(hs); + highlightedSectionStack.Push(hs); + lastPoppedSection = null; + } + } + + void PopColor() + { + if (highlightedLine == null) + return; + HighlightedSection s = highlightedSectionStack.Pop(); + if (s != null) { + s.Length = (position + lineStartOffset) - s.Offset; + if (s.Length == 0) + highlightedLine.Sections.Remove(s); + else + lastPoppedSection = s; + } + } + + void PopAllColors() + { + if (highlightedSectionStack != null) { + while (highlightedSectionStack.Count > 0) + PopColor(); + } + } + #endregion + + #region Match helpers + /// <summary> + /// Returns the first match from the array or endSpanMatch. + /// </summary> + static Match Minimum(Match[] arr, Match endSpanMatch) + { + Match min = null; + foreach (Match v in arr) { + if (v.Success && (min == null || v.Index < min.Index)) + min = v; + } + if (endSpanMatch != null && endSpanMatch.Success && (min == null || endSpanMatch.Index < min.Index)) + return endSpanMatch; + else + return min; + } + + static Match[] AllocateMatchArray(int count) + { + if (count == 0) + return Empty<Match>.Array; + else + return new Match[count]; + } + #endregion + } +} diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/HighlightedInlineBuilder.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/HighlightedInlineBuilder.cs new file mode 100644 index 000000000..ccfce3d49 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/HighlightedInlineBuilder.cs @@ -0,0 +1,214 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Windows; +using System.Windows.Documents; +using System.Windows.Media; + +namespace Tango.Scripting.Editors.Highlighting +{ + /// <summary> + /// Takes a series of highlighting commands and stores them. + /// Later, it can build inline objects (for use with WPF TextBlock) from the commands. + /// </summary> + /// <remarks> + /// This class is not used in AvalonEdit - but it is useful for someone who wants to put a HighlightedLine + /// into a TextBlock. + /// In SharpDevelop, we use it to provide syntax highlighting inside the search results pad. + /// </remarks> + public sealed class HighlightedInlineBuilder + { + sealed class HighlightingState + { + internal Brush Foreground; + internal Brush Background; + internal FontFamily Family; + internal FontWeight? Weight; + internal FontStyle? Style; + + public HighlightingState Clone() + { + return new HighlightingState { + Foreground = this.Foreground, + Background = this.Background, + Family = this.Family, + Weight = this.Weight, + Style = this.Style + }; + } + } + + readonly string text; + List<int> stateChangeOffsets = new List<int>(); + List<HighlightingState> stateChanges = new List<HighlightingState>(); + + int GetIndexForOffset(int offset) + { + if (offset < 0 || offset > text.Length) + throw new ArgumentOutOfRangeException("offset"); + int index = stateChangeOffsets.BinarySearch(offset); + if (index < 0) { + index = ~index; + if (offset < text.Length) { + stateChanges.Insert(index, stateChanges[index - 1].Clone()); + stateChangeOffsets.Insert(index, offset); + } + } + return index; + } + + /// <summary> + /// Creates a new HighlightedInlineBuilder instance. + /// </summary> + public HighlightedInlineBuilder(string text) + { + if (text == null) + throw new ArgumentNullException("text"); + this.text = text; + stateChangeOffsets.Add(0); + stateChanges.Add(new HighlightingState()); + } + + HighlightedInlineBuilder(string text, int[] offsets, HighlightingState[] states) + { + this.text = text; + stateChangeOffsets.AddRange(offsets); + stateChanges.AddRange(states); + } + + /// <summary> + /// Gets the text. + /// </summary> + public string Text { + get { return text; } + } + + /// <summary> + /// Applies the properties from the HighlightingColor to the specified text segment. + /// </summary> + public void SetHighlighting(int offset, int length, HighlightingColor color) + { + if (color == null) + throw new ArgumentNullException("color"); + if (color.Foreground == null && color.FontStyle == null && color.FontWeight == null) { + // Optimization: don't split the HighlightingState when we're not changing + // any property. For example, the "Punctuation" color in C# is + // empty by default. + return; + } + int startIndex = GetIndexForOffset(offset); + int endIndex = GetIndexForOffset(offset + length); + for (int i = startIndex; i < endIndex; i++) { + HighlightingState state = stateChanges[i]; + if (color.Foreground != null) + state.Foreground = color.Foreground.GetBrush(null); + if (color.Background != null) + state.Background = color.Background.GetBrush(null); + if (color.FontStyle != null) + state.Style = color.FontStyle; + if (color.FontWeight != null) + state.Weight = color.FontWeight; + } + } + + /// <summary> + /// Sets the foreground brush on the specified text segment. + /// </summary> + public void SetForeground(int offset, int length, Brush brush) + { + int startIndex = GetIndexForOffset(offset); + int endIndex = GetIndexForOffset(offset + length); + for (int i = startIndex; i < endIndex; i++) { + stateChanges[i].Foreground = brush; + } + } + + /// <summary> + /// Sets the background brush on the specified text segment. + /// </summary> + public void SetBackground(int offset, int length, Brush brush) + { + int startIndex = GetIndexForOffset(offset); + int endIndex = GetIndexForOffset(offset + length); + for (int i = startIndex; i < endIndex; i++) { + stateChanges[i].Background = brush; + } + } + + /// <summary> + /// Sets the font weight on the specified text segment. + /// </summary> + public void SetFontWeight(int offset, int length, FontWeight weight) + { + int startIndex = GetIndexForOffset(offset); + int endIndex = GetIndexForOffset(offset + length); + for (int i = startIndex; i < endIndex; i++) { + stateChanges[i].Weight = weight; + } + } + + /// <summary> + /// Sets the font style on the specified text segment. + /// </summary> + public void SetFontStyle(int offset, int length, FontStyle style) + { + int startIndex = GetIndexForOffset(offset); + int endIndex = GetIndexForOffset(offset + length); + for (int i = startIndex; i < endIndex; i++) { + stateChanges[i].Style = style; + } + } + + /// <summary> + /// Sets the font family on the specified text segment. + /// </summary> + public void SetFontFamily(int offset, int length, FontFamily family) + { + int startIndex = GetIndexForOffset(offset); + int endIndex = GetIndexForOffset(offset + length); + for (int i = startIndex; i < endIndex; i++) { + stateChanges[i].Family = family; + } + } + + /// <summary> + /// Creates WPF Run instances that can be used for TextBlock.Inlines. + /// </summary> + public Run[] CreateRuns() + { + Run[] runs = new Run[stateChanges.Count]; + for (int i = 0; i < runs.Length; i++) { + int startOffset = stateChangeOffsets[i]; + int endOffset = i + 1 < stateChangeOffsets.Count ? stateChangeOffsets[i + 1] : text.Length; + Run r = new Run(text.Substring(startOffset, endOffset - startOffset)); + HighlightingState state = stateChanges[i]; + if (state.Foreground != null) + r.Foreground = state.Foreground; + if (state.Background != null) + r.Background = state.Background; + if (state.Weight != null) + r.FontWeight = state.Weight.Value; + if (state.Family != null) + r.FontFamily = state.Family; + if (state.Style != null) + r.FontStyle = state.Style.Value; + runs[i] = r; + } + return runs; + } + + /// <summary> + /// Clones this HighlightedInlineBuilder. + /// </summary> + public HighlightedInlineBuilder Clone() + { + return new HighlightedInlineBuilder(this.text, + stateChangeOffsets.ToArray(), + stateChanges.Select(sc => sc.Clone()).ToArray()); + } + } +} diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/HighlightedLine.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/HighlightedLine.cs new file mode 100644 index 000000000..e6932c0aa --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/HighlightedLine.cs @@ -0,0 +1,154 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Text; + +using Tango.Scripting.Editors.Document; +using Tango.Scripting.Editors.Utils; + +namespace Tango.Scripting.Editors.Highlighting +{ + /// <summary> + /// Represents a highlighted document line. + /// </summary> + public class HighlightedLine + { + /// <summary> + /// Creates a new HighlightedLine instance. + /// </summary> + public HighlightedLine(TextDocument document, DocumentLine documentLine) + { + if (document == null) + throw new ArgumentNullException("document"); + if (!document.Lines.Contains(documentLine)) + throw new ArgumentException("Line is null or not part of document"); + this.Document = document; + this.DocumentLine = documentLine; + this.Sections = new NullSafeCollection<HighlightedSection>(); + } + + /// <summary> + /// Gets the document associated with this HighlightedLine. + /// </summary> + public TextDocument Document { get; private set; } + + /// <summary> + /// Gets the document line associated with this HighlightedLine. + /// </summary> + public DocumentLine DocumentLine { get; private set; } + + /// <summary> + /// Gets the highlighted sections. + /// The sections are not overlapping, but they may be nested. + /// In that case, outer sections come in the list before inner sections. + /// The sections are sorted by start offset. + /// </summary> + public IList<HighlightedSection> Sections { get; private set; } + + /// <summary> + /// Gets the default color of all text outside a <see cref="HighlightedSection"/>. + /// </summary> + public HighlightingColor DefaultTextColor { get; set; } + + sealed class HtmlElement : IComparable<HtmlElement> + { + internal readonly int Offset; + internal readonly int Nesting; + internal readonly bool IsEnd; + internal readonly HighlightingColor Color; + + public HtmlElement(int offset, int nesting, bool isEnd, HighlightingColor color) + { + this.Offset = offset; + this.Nesting = nesting; + this.IsEnd = isEnd; + this.Color = color; + } + + public int CompareTo(HtmlElement other) + { + int r = Offset.CompareTo(other.Offset); + if (r != 0) + return r; + if (IsEnd != other.IsEnd) { + if (IsEnd) + return -1; + else + return 1; + } else { + if (IsEnd) + return other.Nesting.CompareTo(Nesting); + else + return Nesting.CompareTo(other.Nesting); + } + } + } + + /// <summary> + /// Produces HTML code for the line, with <span class="colorName"> tags. + /// </summary> + public string ToHtml(HtmlOptions options) + { + int startOffset = this.DocumentLine.Offset; + return ToHtml(startOffset, startOffset + this.DocumentLine.Length, options); + } + + /// <summary> + /// Produces HTML code for a section of the line, with <span class="colorName"> tags. + /// </summary> + public string ToHtml(int startOffset, int endOffset, HtmlOptions options) + { + if (options == null) + throw new ArgumentNullException("options"); + int documentLineStartOffset = this.DocumentLine.Offset; + int documentLineEndOffset = documentLineStartOffset + this.DocumentLine.Length; + if (startOffset < documentLineStartOffset || startOffset > documentLineEndOffset) + throw new ArgumentOutOfRangeException("startOffset", startOffset, "Value must be between " + documentLineStartOffset + " and " + documentLineEndOffset); + if (endOffset < startOffset || endOffset > documentLineEndOffset) + throw new ArgumentOutOfRangeException("endOffset", endOffset, "Value must be between startOffset and " + documentLineEndOffset); + ISegment requestedSegment = new SimpleSegment(startOffset, endOffset - startOffset); + + List<HtmlElement> elements = new List<HtmlElement>(); + for (int i = 0; i < this.Sections.Count; i++) { + HighlightedSection s = this.Sections[i]; + if (s.GetOverlap(requestedSegment).Length > 0) { + elements.Add(new HtmlElement(s.Offset, i, false, s.Color)); + elements.Add(new HtmlElement(s.Offset + s.Length, i, true, s.Color)); + } + } + elements.Sort(); + + TextDocument document = this.Document; + StringWriter w = new StringWriter(CultureInfo.InvariantCulture); + int textOffset = startOffset; + foreach (HtmlElement e in elements) { + int newOffset = Math.Min(e.Offset, endOffset); + if (newOffset > startOffset) { + HtmlClipboard.EscapeHtml(w, document.GetText(textOffset, newOffset - textOffset), options); + } + textOffset = Math.Max(textOffset, newOffset); + if (options.ColorNeedsSpanForStyling(e.Color)) { + if (e.IsEnd) { + w.Write("</span>"); + } else { + w.Write("<span"); + options.WriteStyleAttributeForColor(w, e.Color); + w.Write('>'); + } + } + } + HtmlClipboard.EscapeHtml(w, document.GetText(textOffset, endOffset - textOffset), options); + return w.ToString(); + } + + /// <inheritdoc/> + public override string ToString() + { + return "[" + GetType().Name + " " + ToHtml(new HtmlOptions()) + "]"; + } + } +} diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/HighlightedSection.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/HighlightedSection.cs new file mode 100644 index 000000000..9e6fb56f1 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/HighlightedSection.cs @@ -0,0 +1,33 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using Tango.Scripting.Editors.Document; + +namespace Tango.Scripting.Editors.Highlighting +{ + /// <summary> + /// A text section with syntax highlighting information. + /// </summary> + public class HighlightedSection : ISegment + { + /// <summary> + /// Gets/sets the document offset of the section. + /// </summary> + public int Offset { get; set; } + + /// <summary> + /// Gets/sets the length of the section. + /// </summary> + public int Length { get; set; } + + int ISegment.EndOffset { + get { return this.Offset + this.Length; } + } + + /// <summary> + /// Gets the highlighting color associated with the highlighted section. + /// </summary> + public HighlightingColor Color { get; set; } + } +} diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/HighlightingBrush.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/HighlightingBrush.cs new file mode 100644 index 000000000..2e99013f3 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/HighlightingBrush.cs @@ -0,0 +1,117 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Diagnostics; +using System.Globalization; +using System.Reflection; +using System.Runtime.Serialization; +using System.Windows; +using System.Windows.Media; + +using Tango.Scripting.Editors.Rendering; + +namespace Tango.Scripting.Editors.Highlighting +{ + /// <summary> + /// A brush used for syntax highlighting. Can retrieve a real brush on-demand. + /// </summary> + [Serializable] + public abstract class HighlightingBrush + { + /// <summary> + /// Gets the real brush. + /// </summary> + /// <param name="context">The construction context. context can be null!</param> + public abstract Brush GetBrush(ITextRunConstructionContext context); + + /// <summary> + /// Gets the color of the brush. + /// </summary> + /// <param name="context">The construction context. context can be null!</param> + public virtual Color? GetColor(ITextRunConstructionContext context) + { + SolidColorBrush scb = GetBrush(context) as SolidColorBrush; + if (scb != null) + return scb.Color; + else + return null; + } + } + + /// <summary> + /// Highlighting brush implementation that takes a frozen brush. + /// </summary> + [Serializable] + sealed class SimpleHighlightingBrush : HighlightingBrush, ISerializable + { + readonly SolidColorBrush brush; + + public SimpleHighlightingBrush(SolidColorBrush brush) + { + brush.Freeze(); + this.brush = brush; + } + + public SimpleHighlightingBrush(Color color) : this(new SolidColorBrush(color)) {} + + public override Brush GetBrush(ITextRunConstructionContext context) + { + return brush; + } + + public override string ToString() + { + return brush.ToString(); + } + + SimpleHighlightingBrush(SerializationInfo info, StreamingContext context) + { + this.brush = new SolidColorBrush((Color)ColorConverter.ConvertFromString(info.GetString("color"))); + brush.Freeze(); + } + + void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue("color", brush.Color.ToString(CultureInfo.InvariantCulture)); + } + } + + /// <summary> + /// HighlightingBrush implementation that finds a brush using a resource. + /// </summary> + [Serializable] + sealed class SystemColorHighlightingBrush : HighlightingBrush, ISerializable + { + readonly PropertyInfo property; + + public SystemColorHighlightingBrush(PropertyInfo property) + { + Debug.Assert(property.ReflectedType == typeof(SystemColors)); + Debug.Assert(typeof(Brush).IsAssignableFrom(property.PropertyType)); + this.property = property; + } + + public override Brush GetBrush(ITextRunConstructionContext context) + { + return (Brush)property.GetValue(null, null); + } + + public override string ToString() + { + return property.Name; + } + + SystemColorHighlightingBrush(SerializationInfo info, StreamingContext context) + { + property = typeof(SystemColors).GetProperty(info.GetString("propertyName")); + if (property == null) + throw new ArgumentException("Error deserializing SystemColorHighlightingBrush"); + } + + void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue("propertyName", property.Name); + } + } +} diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/HighlightingColor.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/HighlightingColor.cs new file mode 100644 index 000000000..f1b1a25c8 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/HighlightingColor.cs @@ -0,0 +1,119 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Globalization; +using System.Runtime.Serialization; +using System.Security.Permissions; +using System.Text; +using System.Windows; +using System.Windows.Media; + +namespace Tango.Scripting.Editors.Highlighting +{ + /// <summary> + /// A highlighting color is a set of font properties and foreground and background color. + /// </summary> + [Serializable] + public class HighlightingColor : ISerializable + { + /// <summary> + /// Gets/Sets the name of the color. + /// </summary> + public string Name { get; set; } + + /// <summary> + /// Gets/sets the font weight. Null if the highlighting color does not change the font weight. + /// </summary> + public FontWeight? FontWeight { get; set; } + + /// <summary> + /// Gets/sets the font style. Null if the highlighting color does not change the font style. + /// </summary> + public FontStyle? FontStyle { get; set; } + + /// <summary> + /// Gets/sets the foreground color applied by the highlighting. + /// </summary> + public HighlightingBrush Foreground { get; set; } + + /// <summary> + /// Gets/sets the background color applied by the highlighting. + /// </summary> + public HighlightingBrush Background { get; set; } + + /// <summary> + /// Creates a new HighlightingColor instance. + /// </summary> + public HighlightingColor() + { + } + + /// <summary> + /// Deserializes a HighlightingColor. + /// </summary> + protected HighlightingColor(SerializationInfo info, StreamingContext context) + { + if (info == null) + throw new ArgumentNullException("info"); + this.Name = info.GetString("Name"); + if (info.GetBoolean("HasWeight")) + this.FontWeight = System.Windows.FontWeight.FromOpenTypeWeight(info.GetInt32("Weight")); + if (info.GetBoolean("HasStyle")) + this.FontStyle = (FontStyle?)new FontStyleConverter().ConvertFromInvariantString(info.GetString("Style")); + this.Foreground = (HighlightingBrush)info.GetValue("Foreground", typeof(HighlightingBrush)); + this.Background = (HighlightingBrush)info.GetValue("Background", typeof(HighlightingBrush)); + } + + /// <summary> + /// Serializes this HighlightingColor instance. + /// </summary> + [System.Security.SecurityCritical] + public virtual void GetObjectData(SerializationInfo info, StreamingContext context) + { + if (info == null) + throw new ArgumentNullException("info"); + info.AddValue("Name", this.Name); + info.AddValue("HasWeight", this.FontWeight.HasValue); + if (this.FontWeight.HasValue) + info.AddValue("Weight", this.FontWeight.Value.ToOpenTypeWeight()); + info.AddValue("HasStyle", this.FontStyle.HasValue); + if (this.FontStyle.HasValue) + info.AddValue("Style", this.FontStyle.Value.ToString()); + info.AddValue("Foreground", this.Foreground); + info.AddValue("Background", this.Background); + } + + /// <summary> + /// Gets CSS code for the color. + /// </summary> + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase", Justification = "CSS usually uses lowercase, and all possible values are English-only")] + public virtual string ToCss() + { + StringBuilder b = new StringBuilder(); + if (Foreground != null) { + Color? c = Foreground.GetColor(null); + if (c != null) { + b.AppendFormat(CultureInfo.InvariantCulture, "color: #{0:x2}{1:x2}{2:x2}; ", c.Value.R, c.Value.G, c.Value.B); + } + } + if (FontWeight != null) { + b.Append("font-weight: "); + b.Append(FontWeight.Value.ToString().ToLowerInvariant()); + b.Append("; "); + } + if (FontStyle != null) { + b.Append("font-style: "); + b.Append(FontStyle.Value.ToString().ToLowerInvariant()); + b.Append("; "); + } + return b.ToString(); + } + + /// <inheritdoc/> + public override string ToString() + { + return "[" + GetType() + " " + (string.IsNullOrEmpty(this.Name) ? ToCss() : this.Name) + "]"; + } + } +} diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/HighlightingColorizer.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/HighlightingColorizer.cs new file mode 100644 index 000000000..9dfcc3976 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/HighlightingColorizer.cs @@ -0,0 +1,286 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Diagnostics; +using System.Windows; +using System.Windows.Media; +using System.Windows.Threading; + +using Tango.Scripting.Editors.Document; +using Tango.Scripting.Editors.Rendering; + +namespace Tango.Scripting.Editors.Highlighting +{ + /// <summary> + /// A colorizes that interprets a highlighting rule set and colors the document accordingly. + /// </summary> + public class HighlightingColorizer : DocumentColorizingTransformer + { + readonly HighlightingRuleSet ruleSet; + + /// <summary> + /// Creates a new HighlightingColorizer instance. + /// </summary> + /// <param name="ruleSet">The root highlighting rule set.</param> + public HighlightingColorizer(HighlightingRuleSet ruleSet) + { + if (ruleSet == null) + throw new ArgumentNullException("ruleSet"); + this.ruleSet = ruleSet; + } + + /// <summary> + /// This constructor is obsolete - please use the other overload instead. + /// </summary> + /// <param name="textView">UNUSED</param> + /// <param name="ruleSet">The root highlighting rule set.</param> + [Obsolete("The TextView parameter is no longer used, please use the constructor taking only HighlightingRuleSet instead")] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "textView")] + public HighlightingColorizer(TextView textView, HighlightingRuleSet ruleSet) + : this(ruleSet) + { + } + + void textView_DocumentChanged(object sender, EventArgs e) + { + OnDocumentChanged((TextView)sender); + } + + void OnDocumentChanged(TextView textView) + { + // remove existing highlighter, if any exists + textView.Services.RemoveService(typeof(IHighlighter)); + textView.Services.RemoveService(typeof(DocumentHighlighter)); + + TextDocument document = textView.Document; + if (document != null) { + IHighlighter highlighter = CreateHighlighter(textView, document); + textView.Services.AddService(typeof(IHighlighter), highlighter); + // for backward compatiblity, we're registering using both the interface and concrete types + if (highlighter is DocumentHighlighter) + textView.Services.AddService(typeof(DocumentHighlighter), highlighter); + } + } + + /// <summary> + /// Creates the IHighlighter instance for the specified text document. + /// </summary> + protected virtual IHighlighter CreateHighlighter(TextView textView, TextDocument document) + { + return new TextViewDocumentHighlighter(this, textView, document, ruleSet); + } + + /// <inheritdoc/> + protected override void OnAddToTextView(TextView textView) + { + base.OnAddToTextView(textView); + textView.DocumentChanged += textView_DocumentChanged; + textView.VisualLineConstructionStarting += textView_VisualLineConstructionStarting; + OnDocumentChanged(textView); + } + + /// <inheritdoc/> + protected override void OnRemoveFromTextView(TextView textView) + { + base.OnRemoveFromTextView(textView); + textView.Services.RemoveService(typeof(IHighlighter)); + textView.Services.RemoveService(typeof(DocumentHighlighter)); + textView.DocumentChanged -= textView_DocumentChanged; + textView.VisualLineConstructionStarting -= textView_VisualLineConstructionStarting; + } + + void textView_VisualLineConstructionStarting(object sender, VisualLineConstructionStartEventArgs e) + { + IHighlighter highlighter = ((TextView)sender).Services.GetService(typeof(IHighlighter)) as IHighlighter; + if (highlighter != null) { + // Force update of highlighting state up to the position where we start generating visual lines. + // This is necessary in case the document gets modified above the FirstLineInView so that the highlighting state changes. + // We need to detect this case and issue a redraw (through TextViewDocumentHighligher.OnHighlightStateChanged) + // before the visual line construction reuses existing lines that were built using the invalid highlighting state. + lineNumberBeingColorized = e.FirstLineInView.LineNumber - 1; + highlighter.GetSpanStack(lineNumberBeingColorized); + lineNumberBeingColorized = 0; + } + } + + DocumentLine lastColorizedLine; + + /// <inheritdoc/> + protected override void Colorize(ITextRunConstructionContext context) + { + this.lastColorizedLine = null; + base.Colorize(context); + if (this.lastColorizedLine != context.VisualLine.LastDocumentLine) { + IHighlighter highlighter = context.TextView.Services.GetService(typeof(IHighlighter)) as IHighlighter; + if (highlighter != null) { + // In some cases, it is possible that we didn't highlight the last document line within the visual line + // (e.g. when the line ends with a fold marker). + // But even if we didn't highlight it, we'll have to update the highlighting state for it so that the + // proof inside TextViewDocumentHighlighter.OnHighlightStateChanged holds. + lineNumberBeingColorized = context.VisualLine.LastDocumentLine.LineNumber; + highlighter.GetSpanStack(lineNumberBeingColorized); + lineNumberBeingColorized = 0; + } + } + this.lastColorizedLine = null; + } + + int lineNumberBeingColorized; + + /// <inheritdoc/> + protected override void ColorizeLine(DocumentLine line) + { + IHighlighter highlighter = CurrentContext.TextView.Services.GetService(typeof(IHighlighter)) as IHighlighter; + 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; + } + + /// <summary> + /// Gets whether the color is empty (has no effect on a VisualLineTextElement). + /// For example, the C# "Punctuation" is an empty color. + /// </summary> + bool IsEmptyColor(HighlightingColor color) + { + if (color == null) + return true; + return color.Background == null && color.Foreground == null + && color.FontStyle == null && color.FontWeight == null; + } + + /// <summary> + /// Applies a highlighting color to a visual line element. + /// </summary> + protected virtual void ApplyColorToElement(VisualLineElement element, HighlightingColor color) + { + if (color.Foreground != null) { + Brush b = color.Foreground.GetBrush(CurrentContext); + if (b != null) + element.TextRunProperties.SetForegroundBrush(b); + } + if (color.Background != null) { + Brush b = color.Background.GetBrush(CurrentContext); + if (b != null) + element.BackgroundBrush = b; + } + if (color.FontStyle != null || color.FontWeight != null) { + Typeface tf = element.TextRunProperties.Typeface; + element.TextRunProperties.SetTypeface(new Typeface( + tf.FontFamily, + color.FontStyle ?? tf.Style, + color.FontWeight ?? tf.Weight, + tf.Stretch + )); + } + } + + /// <summary> + /// This class is responsible for telling the TextView to redraw lines when the highlighting state has changed. + /// </summary> + /// <remarks> + /// Creation of a VisualLine triggers the syntax highlighter (which works on-demand), so it says: + /// Hey, the user typed "/*". Don't just recreate that line, but also the next one + /// because my highlighting state (at end of line) changed! + /// </remarks> + sealed class TextViewDocumentHighlighter : DocumentHighlighter + { + readonly HighlightingColorizer colorizer; + readonly TextView textView; + + public TextViewDocumentHighlighter(HighlightingColorizer colorizer, TextView textView, TextDocument document, HighlightingRuleSet baseRuleSet) + : base(document, baseRuleSet) + { + Debug.Assert(colorizer != null); + Debug.Assert(textView != null); + this.colorizer = colorizer; + this.textView = textView; + } + + protected override void OnHighlightStateChanged(DocumentLine line, int lineNumber) + { + base.OnHighlightStateChanged(line, lineNumber); + if (colorizer.lineNumberBeingColorized != lineNumber) { + // Ignore notifications for any line except the one we're interested in. + // This improves the performance as Redraw() can take quite some time when called repeatedly + // while scanning the document (above the visible area) for highlighting changes. + return; + } + if (textView.Document != this.Document) { + // May happen if document on text view was changed but some user code is still using the + // existing IHighlighter instance. + return; + } + + // The user may have inserted "/*" into the current line, and so far only that line got redrawn. + // So when the highlighting state is changed, we issue a redraw for the line immediately below. + // If the highlighting state change applies to the lines below, too, the construction of each line + // will invalidate the next line, and the construction pass will regenerate all lines. + + //Debug.WriteLine("OnHighlightStateChanged forces redraw of line " + (lineNumber + 1)); + + // If the VisualLine construction is in progress, we have to avoid sending redraw commands for + // anything above the line currently being constructed. + // It takes some explanation to see why this cannot happen. + // VisualLines always get constructed from top to bottom. + // Each VisualLine construction calls into the highlighter and thus forces an update of the + // highlighting state for all lines up to the one being constructed. + + // To guarantee that we don't redraw lines we just constructed, we need to show that when + // a VisualLine is being reused, the highlighting state at that location is still up-to-date. + + // This isn't exactly trivial and the initial implementation was incorrect in the presence of external document changes + // (e.g. split view). + + // For the first line in the view, the TextView.VisualLineConstructionStarting event is used to check that the + // highlighting state is up-to-date. If it isn't, this method will be executed, and it'll mark the first line + // in the view as requiring a redraw. This is safely possible because that event occurs before any lines are reused. + + // Once we take care of the first visual line, we won't get in trouble with other lines due to the top-to-bottom + // construction process. + + // We'll prove that: if line N is being reused, then the highlighting state is up-to-date until (end of) line N-1. + + // Start of induction: the first line in view is reused only if the highlighting state was up-to-date + // until line N-1 (no change detected in VisualLineConstructionStarting event). + + // Induction step: + // If another line N+1 is being reused, then either + // a) the previous line (the visual line containing document line N) was newly constructed + // or b) the previous line was reused + // In case a, the construction updated the highlighting state. This means the stack at end of line N is up-to-date. + // In case b, the highlighting state at N-1 was up-to-date, and the text of line N was not changed. + // (if the text was changed, the line could not have been reused). + // From this follows that the highlighting state at N is still up-to-date. + + // The above proof holds even in the presence of folding: folding only ever hides text in the middle of a visual line. + // Our Colorize-override ensures that the highlighting state is always updated for the LastDocumentLine, + // so it will always invalidate the next visual line when a folded line is constructed + // and the highlighting stack has changed. + + textView.Redraw(line.NextLine, DispatcherPriority.Normal); + + /* + * Meta-comment: "why does this have to be so complicated?" + * + * The problem is that I want to re-highlight only on-demand and incrementally; + * and at the same time only repaint changed lines. + * So the highlighter and the VisualLine construction both have to run in a single pass. + * The highlighter must take care that it never touches already constructed visual lines; + * if it detects that something must be redrawn because the highlighting state changed, + * it must do so early enough in the construction process. + * But doing it too early means it doesn't have the information necessary to re-highlight and redraw only the desired parts. + */ + } + } + } +} diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/HighlightingDefinitionInvalidException.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/HighlightingDefinitionInvalidException.cs new file mode 100644 index 000000000..dccd6a481 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/HighlightingDefinitionInvalidException.cs @@ -0,0 +1,43 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Runtime.Serialization; + +namespace Tango.Scripting.Editors.Highlighting +{ + /// <summary> + /// Indicates that the highlighting definition that was tried to load was invalid. + /// </summary> + [Serializable()] + public class HighlightingDefinitionInvalidException : Exception + { + /// <summary> + /// Creates a new HighlightingDefinitionInvalidException instance. + /// </summary> + public HighlightingDefinitionInvalidException() : base() + { + } + + /// <summary> + /// Creates a new HighlightingDefinitionInvalidException instance. + /// </summary> + public HighlightingDefinitionInvalidException(string message) : base(message) + { + } + + /// <summary> + /// Creates a new HighlightingDefinitionInvalidException instance. + /// </summary> + public HighlightingDefinitionInvalidException(string message, Exception innerException) : base(message, innerException) + { + } + + /// <summary> + /// Creates a new HighlightingDefinitionInvalidException instance. + /// </summary> + protected HighlightingDefinitionInvalidException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + } +} diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/HighlightingDefinitionTypeConverter.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/HighlightingDefinitionTypeConverter.cs new file mode 100644 index 000000000..7463d9353 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/HighlightingDefinitionTypeConverter.cs @@ -0,0 +1,54 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.ComponentModel; +using System.Globalization; + +namespace Tango.Scripting.Editors.Highlighting +{ + /// <summary> + /// Converts between strings and <see cref="IHighlightingDefinition"/> by treating the string as the definition name + /// and calling <c>HighlightingManager.Instance.<see cref="HighlightingManager.GetDefinition">GetDefinition</see>(name)</c>. + /// </summary> + public sealed class HighlightingDefinitionTypeConverter : TypeConverter + { + /// <inheritdoc/> + public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) + { + if (sourceType == typeof(string)) + return true; + else + return base.CanConvertFrom(context, sourceType); + } + + /// <inheritdoc/> + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + { + string definitionName = value as string; + if (definitionName != null) + return HighlightingManager.Instance.GetDefinition(definitionName); + else + return base.ConvertFrom(context, culture, value); + } + + /// <inheritdoc/> + public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) + { + if (destinationType == typeof(string)) + return true; + else + return base.CanConvertTo(context, destinationType); + } + + /// <inheritdoc/> + public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + IHighlightingDefinition definition = value as IHighlightingDefinition; + if (definition != null && destinationType == typeof(string)) + return definition.Name; + else + return base.ConvertTo(context, culture, value, destinationType); + } + } +} diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/HighlightingManager.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/HighlightingManager.cs new file mode 100644 index 000000000..8db4787d7 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/HighlightingManager.cs @@ -0,0 +1,290 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Diagnostics; +using System.IO; +using System.Xml; + +using Tango.Scripting.Editors.Utils; + +namespace Tango.Scripting.Editors.Highlighting +{ + /// <summary> + /// Manages a list of syntax highlighting definitions. + /// </summary> + /// <remarks> + /// All memers on this class (including instance members) are thread-safe. + /// </remarks> + public class HighlightingManager : IHighlightingDefinitionReferenceResolver + { + sealed class DelayLoadedHighlightingDefinition : IHighlightingDefinition2 + { + readonly object lockObj = new object(); + readonly string name; + Func<IHighlightingDefinition> lazyLoadingFunction; + IHighlightingDefinition definition; + Exception storedException; + + public DelayLoadedHighlightingDefinition(string name, Func<IHighlightingDefinition> lazyLoadingFunction) + { + this.name = name; + this.lazyLoadingFunction = lazyLoadingFunction; + } + + public string Name { + get { + if (name != null) + return name; + else + return GetDefinition().Name; + } + } + + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", + Justification = "The exception will be rethrown")] + IHighlightingDefinition GetDefinition() + { + Func<IHighlightingDefinition> func; + lock (lockObj) { + if (this.definition != null) + return this.definition; + func = this.lazyLoadingFunction; + } + Exception exception = null; + IHighlightingDefinition def = null; + try { + using (var busyLock = BusyManager.Enter(this)) { + if (!busyLock.Success) + throw new InvalidOperationException("Tried to create delay-loaded highlighting definition recursively. Make sure the are no cyclic references between the highlighting definitions."); + def = func(); + } + if (def == null) + throw new InvalidOperationException("Function for delay-loading highlighting definition returned null"); + } catch (Exception ex) { + exception = ex; + } + lock (lockObj) { + this.lazyLoadingFunction = null; + if (this.definition == null && this.storedException == null) { + this.definition = def; + this.storedException = exception; + } + if (this.storedException != null) + throw new HighlightingDefinitionInvalidException("Error delay-loading highlighting definition", this.storedException); + return this.definition; + } + } + + public HighlightingRuleSet MainRuleSet { + get { + return GetDefinition().MainRuleSet; + } + } + + public HighlightingRuleSet GetNamedRuleSet(string name) + { + return GetDefinition().GetNamedRuleSet(name); + } + + public HighlightingColor GetNamedColor(string name) + { + return GetDefinition().GetNamedColor(name); + } + + public IEnumerable<HighlightingColor> NamedHighlightingColors { + get { + return GetDefinition().NamedHighlightingColors; + } + } + + public override string ToString() + { + return this.Name; + } + + public IDictionary<string, string> Properties { + get { + var def = GetDefinition() as IHighlightingDefinition2; + if (def != null) + return def.Properties; + return null; + } + } + } + + readonly object lockObj = new object(); + Dictionary<string, IHighlightingDefinition> highlightingsByName = new Dictionary<string, IHighlightingDefinition>(); + Dictionary<string, IHighlightingDefinition> highlightingsByExtension = new Dictionary<string, IHighlightingDefinition>(StringComparer.OrdinalIgnoreCase); + List<IHighlightingDefinition> allHighlightings = new List<IHighlightingDefinition>(); + + /// <summary> + /// Gets a highlighting definition by name. + /// Returns null if the definition is not found. + /// </summary> + public IHighlightingDefinition GetDefinition(string name) + { + lock (lockObj) { + IHighlightingDefinition rh; + if (highlightingsByName.TryGetValue(name, out rh)) + return rh; + else + return null; + } + } + + /// <summary> + /// Gets a copy of all highlightings. + /// </summary> + public ReadOnlyCollection<IHighlightingDefinition> HighlightingDefinitions { + get { + lock (lockObj) { + return Array.AsReadOnly(allHighlightings.ToArray()); + } + } + } + + /// <summary> + /// Gets the names of the registered highlightings. + /// </summary> + [ObsoleteAttribute("Use the HighlightingDefinitions property instead.")] + public IEnumerable<string> HighlightingNames { + get { + lock (lockObj) { + return new List<string>(highlightingsByName.Keys); + } + } + } + + /// <summary> + /// Gets a highlighting definition by extension. + /// Returns null if the definition is not found. + /// </summary> + public IHighlightingDefinition GetDefinitionByExtension(string extension) + { + lock (lockObj) { + IHighlightingDefinition rh; + if (highlightingsByExtension.TryGetValue(extension, out rh)) + return rh; + else + return null; + } + } + + /// <summary> + /// Registers a highlighting definition. + /// </summary> + /// <param name="name">The name to register the definition with.</param> + /// <param name="extensions">The file extensions to register the definition for.</param> + /// <param name="highlighting">The highlighting definition.</param> + public void RegisterHighlighting(string name, string[] extensions, IHighlightingDefinition highlighting) + { + if (highlighting == null) + throw new ArgumentNullException("highlighting"); + + lock (lockObj) { + allHighlightings.Add(highlighting); + if (name != null) { + highlightingsByName[name] = highlighting; + } + if (extensions != null) { + foreach (string ext in extensions) { + highlightingsByExtension[ext] = highlighting; + } + } + } + } + + /// <summary> + /// Registers a highlighting definition. + /// </summary> + /// <param name="name">The name to register the definition with.</param> + /// <param name="extensions">The file extensions to register the definition for.</param> + /// <param name="lazyLoadedHighlighting">A function that loads the highlighting definition.</param> + public void RegisterHighlighting(string name, string[] extensions, Func<IHighlightingDefinition> lazyLoadedHighlighting) + { + if (lazyLoadedHighlighting == null) + throw new ArgumentNullException("lazyLoadedHighlighting"); + RegisterHighlighting(name, extensions, new DelayLoadedHighlightingDefinition(name, lazyLoadedHighlighting)); + } + + /// <summary> + /// Gets the default HighlightingManager instance. + /// The default HighlightingManager comes with built-in highlightings. + /// </summary> + public static HighlightingManager Instance { + get { + return DefaultHighlightingManager.Instance; + } + } + + internal sealed class DefaultHighlightingManager : HighlightingManager + { + public new static readonly DefaultHighlightingManager Instance = new DefaultHighlightingManager(); + + public DefaultHighlightingManager() + { + Resources.RegisterBuiltInHighlightings(this); + } + + // Registering a built-in highlighting + internal void RegisterHighlighting(string name, string[] extensions, string resourceName) + { + try { + #if DEBUG + // don't use lazy-loading in debug builds, show errors immediately + Xshd.XshdSyntaxDefinition xshd; + using (Stream s = Resources.OpenStream(resourceName)) { + using (XmlTextReader reader = new XmlTextReader(s)) { + xshd = Xshd.HighlightingLoader.LoadXshd(reader, false); + } + } + Debug.Assert(name == xshd.Name); + if (extensions != null) + Debug.Assert(System.Linq.Enumerable.SequenceEqual(extensions, xshd.Extensions)); + else + Debug.Assert(xshd.Extensions.Count == 0); + + // round-trip xshd: +// string resourceFileName = Path.Combine(Path.GetTempPath(), resourceName); +// using (XmlTextWriter writer = new XmlTextWriter(resourceFileName, System.Text.Encoding.UTF8)) { +// writer.Formatting = Formatting.Indented; +// new Xshd.SaveXshdVisitor(writer).WriteDefinition(xshd); +// } +// using (FileStream fs = File.Create(resourceFileName + ".bin")) { +// new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter().Serialize(fs, xshd); +// } +// using (FileStream fs = File.Create(resourceFileName + ".compiled")) { +// new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter().Serialize(fs, Xshd.HighlightingLoader.Load(xshd, this)); +// } + + RegisterHighlighting(name, extensions, Xshd.HighlightingLoader.Load(xshd, this)); + #else + RegisterHighlighting(name, extensions, LoadHighlighting(resourceName)); + #endif + } catch (HighlightingDefinitionInvalidException ex) { + throw new InvalidOperationException("The built-in highlighting '" + name + "' is invalid.", ex); + } + } + + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", + Justification = "LoadHighlighting is used only in release builds")] + Func<IHighlightingDefinition> LoadHighlighting(string resourceName) + { + Func<IHighlightingDefinition> func = delegate { + Xshd.XshdSyntaxDefinition xshd; + using (Stream s = Resources.OpenStream(resourceName)) { + using (XmlTextReader reader = new XmlTextReader(s)) { + // in release builds, skip validating the built-in highlightings + xshd = Xshd.HighlightingLoader.LoadXshd(reader, true); + } + } + return Xshd.HighlightingLoader.Load(xshd, this); + }; + return func; + } + } + } +} diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/HighlightingRule.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/HighlightingRule.cs new file mode 100644 index 000000000..18edf4974 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/HighlightingRule.cs @@ -0,0 +1,31 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Text.RegularExpressions; + +namespace Tango.Scripting.Editors.Highlighting +{ + /// <summary> + /// A highlighting rule. + /// </summary> + [Serializable] + public class HighlightingRule + { + /// <summary> + /// Gets/Sets the regular expression for the rule. + /// </summary> + public Regex Regex { get; set; } + + /// <summary> + /// Gets/Sets the highlighting color. + /// </summary> + public HighlightingColor Color { get; set; } + + /// <inheritdoc/> + public override string ToString() + { + return "[" + GetType().Name + " " + Regex + "]"; + } + } +} diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/HighlightingRuleSet.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/HighlightingRuleSet.cs new file mode 100644 index 000000000..f887b9d54 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/HighlightingRuleSet.cs @@ -0,0 +1,46 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using Tango.Scripting.Editors.Utils; + +namespace Tango.Scripting.Editors.Highlighting +{ + /// <summary> + /// A highlighting rule set describes a set of spans that are valid at a given code location. + /// </summary> + [Serializable] + public class HighlightingRuleSet + { + /// <summary> + /// Creates a new RuleSet instance. + /// </summary> + public HighlightingRuleSet() + { + this.Spans = new NullSafeCollection<HighlightingSpan>(); + this.Rules = new NullSafeCollection<HighlightingRule>(); + } + + /// <summary> + /// Gets/Sets the name of the rule set. + /// </summary> + public string Name { get; set; } + + /// <summary> + /// Gets the list of spans. + /// </summary> + public IList<HighlightingSpan> Spans { get; private set; } + + /// <summary> + /// Gets the list of rules. + /// </summary> + public IList<HighlightingRule> Rules { get; private set; } + + /// <inheritdoc/> + public override string ToString() + { + return "[" + GetType().Name + " " + Name + "]"; + } + } +} diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/HighlightingSpan.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/HighlightingSpan.cs new file mode 100644 index 000000000..b57e70a93 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/HighlightingSpan.cs @@ -0,0 +1,64 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Text.RegularExpressions; + +namespace Tango.Scripting.Editors.Highlighting +{ + /// <summary> + /// A highlighting span is a region with start+end expression that has a different RuleSet inside + /// and colors the region. + /// </summary> + [Serializable] + public class HighlightingSpan + { + /// <summary> + /// Gets/Sets the start expression. + /// </summary> + public Regex StartExpression { get; set; } + + /// <summary> + /// Gets/Sets the end expression. + /// </summary> + public Regex EndExpression { get; set; } + + /// <summary> + /// Gets/Sets the rule set that applies inside this span. + /// </summary> + public HighlightingRuleSet RuleSet { get; set; } + + /// <summary> + /// Gets the color used for the text matching the start expression. + /// </summary> + public HighlightingColor StartColor { get; set; } + + /// <summary> + /// Gets the color used for the text between start and end. + /// </summary> + public HighlightingColor SpanColor { get; set; } + + /// <summary> + /// Gets the color used for the text matching the end expression. + /// </summary> + public HighlightingColor EndColor { get; set; } + + /// <summary> + /// Gets/Sets whether the span color includes the start. + /// The default is <c>false</c>. + /// </summary> + public bool SpanColorIncludesStart { get; set; } + + /// <summary> + /// Gets/Sets whether the span color includes the end. + /// The default is <c>false</c>. + /// </summary> + public bool SpanColorIncludesEnd { get; set; } + + /// <inheritdoc/> + public override string ToString() + { + return "[" + GetType().Name + " Start=" + StartExpression + ", End=" + EndExpression + "]"; + } + } +} diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/HtmlClipboard.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/HtmlClipboard.cs new file mode 100644 index 000000000..a656308b7 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/HtmlClipboard.cs @@ -0,0 +1,201 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Diagnostics; +using System.Globalization; +using System.IO; +using System.Text; +using System.Windows; + +using Tango.Scripting.Editors.Document; + +namespace Tango.Scripting.Editors.Highlighting +{ + /// <summary> + /// Allows copying HTML text to the clipboard. + /// </summary> + public static class HtmlClipboard + { + /// <summary> + /// Builds a header for the CF_HTML clipboard format. + /// </summary> + static string BuildHeader(int startHTML, int endHTML, int startFragment, int endFragment) + { + StringBuilder b = new StringBuilder(); + b.AppendLine("Version:0.9"); + b.AppendLine("StartHTML:" + startHTML.ToString("d8", CultureInfo.InvariantCulture)); + b.AppendLine("EndHTML:" + endHTML.ToString("d8", CultureInfo.InvariantCulture)); + b.AppendLine("StartFragment:" + startFragment.ToString("d8", CultureInfo.InvariantCulture)); + b.AppendLine("EndFragment:" + endFragment.ToString("d8", CultureInfo.InvariantCulture)); + return b.ToString(); + } + + /// <summary> + /// Sets the TextDataFormat.Html on the data object to the specified html fragment. + /// This helper methods takes care of creating the necessary CF_HTML header. + /// </summary> + public static void SetHtml(DataObject dataObject, string htmlFragment) + { + if (dataObject == null) + throw new ArgumentNullException("dataObject"); + if (htmlFragment == null) + throw new ArgumentNullException("htmlFragment"); + + string htmlStart = @"<!DOCTYPE HTML PUBLIC ""-//W3C//DTD HTML 4.0 Transitional//EN"">" + Environment.NewLine + + "<HTML>" + Environment.NewLine + + "<BODY>" + Environment.NewLine + + "<!--StartFragment-->" + Environment.NewLine; + string htmlEnd = "<!--EndFragment-->" + Environment.NewLine + "</BODY>" + Environment.NewLine + "</HTML>" + Environment.NewLine; + string dummyHeader = BuildHeader(0, 0, 0, 0); + // the offsets are stored as UTF-8 bytes (see CF_HTML documentation) + int startHTML = dummyHeader.Length; + int startFragment = startHTML + htmlStart.Length; + int endFragment = startFragment + Encoding.UTF8.GetByteCount(htmlFragment); + int endHTML = endFragment + htmlEnd.Length; + string cf_html = BuildHeader(startHTML, endHTML, startFragment, endFragment) + htmlStart + htmlFragment + htmlEnd; + Debug.WriteLine(cf_html); + dataObject.SetText(cf_html, TextDataFormat.Html); + } + + /// <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(); + } + + /// <summary> + /// Escapes text and writes the result to the StringBuilder. + /// </summary> + internal static void EscapeHtml(StringWriter w, string text, HtmlOptions options) + { + int spaceCount = -1; + foreach (char c in text) { + if (c == ' ') { + if (spaceCount < 0) + w.Write(" "); + else + spaceCount++; + } else if (c == '\t') { + if (spaceCount < 0) + spaceCount = 0; + spaceCount += options.TabSize; + } else { + if (spaceCount == 1) { + w.Write(' '); + } else if (spaceCount >= 1) { + for (int i = 0; i < spaceCount; i++) { + w.Write(" "); + } + } + spaceCount = 0; + switch (c) { + case '<': + w.Write("<"); + break; + case '>': + w.Write(">"); + break; + case '&': + w.Write("&"); + break; + case '"': + w.Write("""); + break; + default: + w.Write(c); + break; + } + } + } + for (int i = 0; i < spaceCount; i++) { + w.Write(" "); + } + } + } + + /// <summary> + /// Holds options for converting text to HTML. + /// </summary> + public class HtmlOptions + { + /// <summary> + /// Creates a default HtmlOptions instance. + /// </summary> + public HtmlOptions() + { + this.TabSize = 4; + } + + /// <summary> + /// Creates a new HtmlOptions instance that copies applicable options from the <see cref="TextEditorOptions"/>. + /// </summary> + public HtmlOptions(TextEditorOptions options) + : this() + { + if (options == null) + throw new ArgumentNullException("options"); + this.TabSize = options.IndentationSize; + } + + /// <summary> + /// The amount of spaces a tab gets converted to. + /// </summary> + public int TabSize { get; set; } + + /// <summary> + /// Writes the HTML attribute for the style to the text writer. + /// </summary> + public virtual void WriteStyleAttributeForColor(TextWriter writer, HighlightingColor color) + { + if (writer == null) + throw new ArgumentNullException("writer"); + if (color == null) + throw new ArgumentNullException("color"); + writer.Write(" style=\""); + writer.Write(color.ToCss()); + writer.Write("\""); + } + + /// <summary> + /// Gets whether the color needs to be written out to HTML. + /// </summary> + public virtual bool ColorNeedsSpanForStyling(HighlightingColor color) + { + if (color == null) + throw new ArgumentNullException("color"); + return !string.IsNullOrEmpty(color.ToCss()); + } + } +} diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/IHighlighter.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/IHighlighter.cs new file mode 100644 index 000000000..1b5cab138 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/IHighlighter.cs @@ -0,0 +1,35 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using Tango.Scripting.Editors.Document; +using Tango.Scripting.Editors.Utils; + +namespace Tango.Scripting.Editors.Highlighting +{ + /// <summary> + /// Represents a highlighted document. + /// </summary> + /// <remarks>This interface is used by the <see cref="HighlightingColorizer"/> to register the highlighter as a TextView service.</remarks> + public interface IHighlighter + { + /// <summary> + /// Gets the underlying text document. + /// </summary> + TextDocument Document { get; } + + /// <summary> + /// Gets the span stack at the end of the specified line. + /// -> GetSpanStack(1) returns the spans at the start of the second line. + /// </summary> + /// <remarks>GetSpanStack(0) is valid and will always return the empty stack.</remarks> + ImmutableStack<HighlightingSpan> GetSpanStack(int lineNumber); + + /// <summary> + /// Highlights the specified document line. + /// </summary> + /// <param name="lineNumber">The line to highlight.</param> + /// <returns>A <see cref="HighlightedLine"/> line object that represents the highlighted sections.</returns> + HighlightedLine HighlightLine(int lineNumber); + } +} diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/IHighlightingDefinition.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/IHighlightingDefinition.cs new file mode 100644 index 000000000..0b42cd426 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/IHighlightingDefinition.cs @@ -0,0 +1,54 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.ComponentModel; + +namespace Tango.Scripting.Editors.Highlighting +{ + /// <summary> + /// A highlighting definition. + /// </summary> + [TypeConverter(typeof(HighlightingDefinitionTypeConverter))] + public interface IHighlightingDefinition + { + /// <summary> + /// Gets the name of the highlighting definition. + /// </summary> + string Name { get; } + + /// <summary> + /// Gets the main rule set. + /// </summary> + HighlightingRuleSet MainRuleSet { get; } + + /// <summary> + /// Gets a rule set by name. + /// </summary> + /// <returns>The rule set, or null if it is not found.</returns> + HighlightingRuleSet GetNamedRuleSet(string name); + + /// <summary> + /// Gets a named highlighting color. + /// </summary> + /// <returns>The highlighting color, or null if it is not found.</returns> + HighlightingColor GetNamedColor(string name); + + /// <summary> + /// Gets the list of named highlighting colors. + /// </summary> + IEnumerable<HighlightingColor> NamedHighlightingColors { get; } + } + + /// <summary> + /// Extension of IHighlightingDefinition to avoid breaking changes in the API. + /// </summary> + public interface IHighlightingDefinition2 : IHighlightingDefinition + { + /// <summary> + /// Gets the list of properties. + /// </summary> + IDictionary<string, string> Properties { get; } + } +} diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/IHighlightingDefinitionReferenceResolver.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/IHighlightingDefinitionReferenceResolver.cs new file mode 100644 index 000000000..d378ae1b7 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/IHighlightingDefinitionReferenceResolver.cs @@ -0,0 +1,18 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; + +namespace Tango.Scripting.Editors.Highlighting +{ + /// <summary> + /// Interface for resolvers that can solve cross-definition references. + /// </summary> + public interface IHighlightingDefinitionReferenceResolver + { + /// <summary> + /// Gets the highlighting definition by name, or null if it is not found. + /// </summary> + IHighlightingDefinition GetDefinition(string name); + } +} diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/OffsetColorizer.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/OffsetColorizer.cs new file mode 100644 index 000000000..a05d1fc75 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/OffsetColorizer.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Media; +using Tango.Scripting.Editors.Document; +using Tango.Scripting.Editors.Rendering; + +namespace Tango.Scripting.Editors.Highlighting +{ + public class OffsetColorizer : DocumentColorizingTransformer + { + public int StartOffset { get; set; } + public int EndOffset { get; set; } + public Brush Brush { get; set; } + public DocumentLine Line { get; set; } + + public OffsetColorizer(DocumentLine line, int start, int end, Brush brush) + { + Line = line; + StartOffset = start; + EndOffset = end; + Brush = brush; + } + + protected override void ColorizeLine(DocumentLine line) + { + if (Line == line) + { + try + { + ChangeLinePart(StartOffset, EndOffset, element => element.TextRunProperties.SetForegroundBrush(Brush)); + } + catch { } + } + } + } +} diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/ASPX.xshd b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/ASPX.xshd new file mode 100644 index 000000000..bd0c922ac --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/ASPX.xshd @@ -0,0 +1,16 @@ +<?xml version="1.0"?> +<!-- converted to AvalonEdit format by Siegfried Pammer in 2010 --> +<SyntaxDefinition name="ASP/XHTML" extensions=".asp;.aspx;.asax;.asmx;.ascx;.master" xmlns="http://icsharpcode.net/sharpdevelop/syntaxdefinition/2008"> + <Color name="ASPSectionStartEndTags" foreground="Black" background="Yellow" exampleText="<% System.Console.WriteLine("Hello World!"); %>" /> + <Color name="ASPSection" foreground="Black" background="#FFF7F2E3" exampleText="<% System.Console.WriteLine("Hello World!"); %>" /> + <RuleSet ignoreCase="true"> + <Span ruleSet="ASP" multiline="true"> + <Begin color="ASPSectionStartEndTags"><%</Begin> + <End color="ASPSectionStartEndTags">%></End> + </Span> + <Import ruleSet="HTML/" /> + </RuleSet> + <RuleSet name="ASP"> + <Import ruleSet="C#/" /> + </RuleSet> +</SyntaxDefinition> diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/Boo.xshd b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/Boo.xshd new file mode 100644 index 000000000..a4e555198 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/Boo.xshd @@ -0,0 +1,212 @@ +<SyntaxDefinition name="Boo" extensions=".boo" xmlns="http://icsharpcode.net/sharpdevelop/syntaxdefinition/2008"> + <Color name="Comment" foreground="Green" /> + <Color name="String" foreground="Blue" /> + <Color name="Regex" foreground="#FFFF6600" /> + <RuleSet> + <Span color="Comment" multiline="true"> + <Begin>"""</Begin> + <End>"""</End> + </Span> + <Span foreground="Gray"> + <Begin>\#</Begin> + </Span> + <Span foreground="#FF999999"> + <Begin>//</Begin> + </Span> + <Span color="Comment" ruleSet="comments set" multiline="true"> + <Begin>/\*</Begin> + <End>\*/</End> + </Span> + <Span color="String"> + <Begin>"</Begin> + <End>"</End> + <RuleSet> + <Span begin="\\" end="." /> + <Span foreground="#FF993366" ruleSet=""> + <!-- ruleSet="" reference this file's main ruleset, allowing normal boo code inside ${} --> + <Begin>\$\{</Begin> + <End>}</End> + </Span> + </RuleSet> + </Span> + <Span color="String"> + <Begin>'</Begin> + <End>'</End> + <RuleSet> + <Span begin="\\" end="." /> + </RuleSet> + </Span> + <Span color="Regex" multiline="true"> + <Begin>@/</Begin> + <End>/</End> + </Span> + <Span color="Regex"> + <!-- this is a span (not a rule) because " within a regex doesn't start a string literal --> + <Begin>/\S+/</Begin> + <End></End> <!-- end immediately after Begin --> + </Span> + <Keywords foreground="Black" fontWeight="bold"> + <Word>self</Word> + <Word>super</Word> + </Keywords> + <Keywords foreground="DarkCyan" fontWeight="bold"> + <Word>is</Word> + <Word>isa</Word> + <Word>and</Word> + <Word>or</Word> + <Word>not</Word> + </Keywords> + <Keywords foreground="Blue" fontWeight="bold"> + <Word>else</Word> + <Word>elif</Word> + <Word>if</Word> + <Word>match</Word> + <Word>case</Word> + <Word>unless</Word> + <Word>otherwise</Word> + <Word>for</Word> + <Word>in</Word> + <Word>while</Word> + </Keywords> + <Keywords foreground="Navy"> + <Word>break</Word> + <Word>continue</Word> + <Word>return</Word> + <Word>yield</Word> + <Word>goto</Word> + </Keywords> + <Keywords foreground="Teal" fontWeight="bold"> + <Word>try</Word> + <Word>raise</Word> + <Word>ensure</Word> + <Word>except</Word> + <Word>retry</Word> + <Word>success</Word> + </Keywords> + <Keywords foreground="Olive"> + <Word>fixed</Word> + <Word>unsafe</Word> + </Keywords> + <Keywords foreground="Purple" fontWeight="bold"> + <Word>bool</Word> + <Word>double</Word> + <Word>single</Word> + <Word>byte</Word> + <Word>sbyte</Word> + <Word>short</Word> + <Word>ushort</Word> + <Word>int</Word> + <Word>uint</Word> + <Word>long</Word> + <Word>ulong</Word> + <Word>date</Word> + <Word>timespan</Word> + <Word>decimal</Word> + <Word>char</Word> + <Word>object</Word> + <Word>duck</Word> + <Word>string</Word> + <Word>regex</Word> + </Keywords> + <Keywords foreground="Red"> + <Word>void</Word> + </Keywords> + <Keywords foreground="Blue" fontWeight="bold"> + <Word>cast</Word> + <Word>as</Word> + </Keywords> + <Keywords foreground="Brown"> + <Word>override</Word> + <Word>static</Word> + <Word>virtual</Word> + <Word>abstract</Word> + <Word>final</Word> + <Word>transient</Word> + <Word>partial</Word> + </Keywords> + <Keywords foreground="Blue" fontWeight="bold"> + <Word>public</Word> + <Word>protected</Word> + <Word>private</Word> + <Word>internal</Word> + </Keywords> + <Keywords foreground="Green" fontWeight="bold"> + <Word>namespace</Word> + <Word>import</Word> + <Word>from</Word> + </Keywords> + <Keywords foreground="SaddleBrown"> + <Word>get</Word> + <Word>set</Word> + </Keywords> + <Keywords foreground="Black" fontWeight="bold"> + <Word>null</Word> + <Word>value</Word> + <Word>true</Word> + <Word>false</Word> + <Word>ast</Word> + </Keywords> + <Keywords foreground="Maroon"> + <Word>using</Word> + <Word>unchecked</Word> + <Word>checked</Word> + <Word>lock</Word> + <Word>getter</Word> + <Word>required</Word> + <Word>rawArrayIndexing</Word> + <Word>normalArrayIndexing</Word> + <Word>yieldAll</Word> + </Keywords> + <Keywords foreground="Purple"> + <Word>assert</Word> + <Word>array</Word> + <Word>matrix</Word> + <Word>print</Word> + <Word>gets</Word> + <Word>prompt</Word> + <Word>enumerate</Word> + <Word>zip</Word> + <Word>filter</Word> + <Word>map</Word> + <Word>cat</Word> + <Word>__eval__</Word> + <Word>__switch__</Word> + </Keywords> + <Keywords foreground="Blue" fontWeight="bold"> + <Word>constructor</Word> + <Word>destructor</Word> + <Word>def</Word> + <Word>include</Word> + <Word>event</Word> + <Word>ref</Word> + </Keywords> + <Keywords foreground="Gray"> + <Word>pass</Word> + </Keywords> + <Keywords foreground="Blue" fontWeight="bold"> + <Word>enum</Word> + <Word>class</Word> + <Word>struct</Word> + <Word>interface</Word> + <Word>mixin</Word> + <Word>callable</Word> + <Word>do</Word> + <Word>of</Word> + </Keywords> + <Rule foreground="MidnightBlue">[\d\w_]+(?=(\s*\())</Rule> + <Rule foreground="DarkBlue">\b0[xX][0-9a-fA-F]+|(\b\d+(\.[0-9]+)?|\.[0-9]+)([eE][+-]?[0-9]+)?</Rule> + </RuleSet> + <RuleSet name="comments set"> + <!-- allows nested /**/ comments, coloring them Green/Teal alternately --> + <Span foreground="Teal" multiline="true"> + <Begin>/\*</Begin> + <End>\*/</End> + <RuleSet> + <Span color="Comment" ruleSet="comments set" multiline="true"> + <Begin>/\*</Begin> + <End>\*/</End> + </Span> + </RuleSet> + </Span> + </RuleSet> +</SyntaxDefinition>
\ No newline at end of file diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/CPP-Mode.xshd b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/CPP-Mode.xshd new file mode 100644 index 000000000..f552ad413 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/CPP-Mode.xshd @@ -0,0 +1,195 @@ +<?xml version="1.0"?> +<!-- syntaxdefinition for C/C++ 2001 by Andrea Paatz and Mike Krueger --> +<!-- converted to AvalonEdit format by Siegfried Pammer in 2010 --> +<SyntaxDefinition name="C++" extensions=".c;.h;.cc;.cpp;.hpp" xmlns="http://icsharpcode.net/sharpdevelop/syntaxdefinition/2008"> + <Color name="Comment" foreground="Green" /> + <Color name="Character" foreground="Fuchsia" /> + <Color name="String" foreground="Fuchsia" /> + <Color name="Preprocessor" foreground="Green" /> + <Color name="Punctuation" foreground="DarkGreen" /> + <Color name="MethodName" foreground="MidnightBlue" fontWeight="bold" /> + <Color name="Digits" foreground="DarkBlue" /> + <Color name="CompoundKeywords" foreground="Black" fontWeight="bold" /> + <Color name="This" foreground="Black" fontWeight="bold" /> + <Color name="Operators" foreground="#FF008B8B" fontWeight="bold" /> + <Color name="Namespace" foreground="#FF008000" fontWeight="bold" /> + <Color name="Friend" foreground="#FFA52A2A" /> + <Color name="Modifiers" foreground="#FF0000FF" fontWeight="bold" /> + <Color name="TypeKeywords" foreground="#FFFF0000" /> + <Color name="BooleanConstants" foreground="#FF000000" fontWeight="bold" /> + <Color name="Keywords" foreground="#FF0000FF" fontWeight="bold" /> + <Color name="LoopKeywords" foreground="#FF0000FF" fontWeight="bold" /> + <Color name="JumpKeywords" foreground="#FF000080" /> + <Color name="ExceptionHandling" foreground="#FF008080" fontWeight="bold" /> + <Color name="ControlFlow" foreground="#FF0000FF" fontWeight="bold" /> + <RuleSet ignoreCase="false"> + <Rule color="Punctuation"> + [?,.;()\[\]{}+\-/%*<>^=~!&]+ + </Rule> + <Keywords color="CompoundKeywords"> + <Word>__abstract</Word> + <Word>__box</Word> + <Word>__delegate</Word> + <Word>__gc</Word> + <Word>__identifier</Word> + <Word>__nogc</Word> + <Word>__pin</Word> + <Word>__property</Word> + <Word>__sealed</Word> + <Word>__try_cast</Word> + <Word>__typeof</Word> + <Word>__value</Word> + <Word>__event</Word> + <Word>__hook</Word> + <Word>__raise</Word> + <Word>__unhook</Word> + <Word>__interface</Word> + <Word>ref class</Word> + <Word>ref struct</Word> + <Word>value class</Word> + <Word>value struct</Word> + <Word>interface class</Word> + <Word>interface struct</Word> + <Word>enum class</Word> + <Word>enum struct</Word> + <Word>delegate</Word> + <Word>event</Word> + <Word>property</Word> + <Word>abstract</Word> + <Word>override</Word> + <Word>sealed</Word> + <Word>generic</Word> + <Word>where</Word> + <Word>finally</Word> + <Word>for each</Word> + <Word>gcnew</Word> + <Word>in</Word> + <Word>initonly</Word> + <Word>literal</Word> + <Word>nullptr</Word> + </Keywords> + <Keywords color="This"> + <Word>this</Word> + </Keywords> + <Keywords color="Operators"> + <Word>and</Word> + <Word>and_eq</Word> + <Word>bitand</Word> + <Word>bitor</Word> + <Word>new</Word> + <Word>not</Word> + <Word>not_eq</Word> + <Word>or</Word> + <Word>or_eq</Word> + <Word>xor</Word> + <Word>xor_eq</Word> + </Keywords> + <Keywords color="Namespace"> + <Word>using</Word> + <Word>namespace</Word> + </Keywords> + <Keywords color="Friend"> + <Word>friend</Word> + </Keywords> + <Keywords color="Modifiers"> + <Word>private</Word> + <Word>protected</Word> + <Word>public</Word> + <Word>const</Word> + <Word>volatile</Word> + <Word>static</Word> + </Keywords> + <Keywords color="TypeKeywords"> + <Word>bool</Word> + <Word>char</Word> + <Word>unsigned</Word> + <Word>union</Word> + <Word>virtual</Word> + <Word>double</Word> + <Word>float</Word> + <Word>short</Word> + <Word>signed</Word> + <Word>void</Word> + <Word>class</Word> + <Word>enum</Word> + <Word>struct</Word> + </Keywords> + <Keywords color="BooleanConstants"> + <Word>false</Word> + <Word>true</Word> + </Keywords> + <Keywords color="LoopKeywords"> + <Word>do</Word> + <Word>for</Word> + <Word>while</Word> + </Keywords> + <Keywords color="JumpKeywords"> + <Word>break</Word> + <Word>continue</Word> + <Word>goto</Word> + <Word>return</Word> + </Keywords> + <Keywords color="ExceptionHandling"> + <Word>catch</Word> + <Word>throw</Word> + <Word>try</Word> + </Keywords> + <Keywords color="ControlFlow"> + <Word>case</Word> + <Word>else</Word> + <Word>if</Word> + <Word>switch</Word> + <Word>default</Word> + </Keywords> + <Keywords color="Keywords"> + <Word>asm</Word> + <Word>auto</Word> + <Word>compl</Word> + <Word>mutable</Word> + <Word>const_cast</Word> + <Word>delete</Word> + <Word>dynamic_cast</Word> + <Word>explicit</Word> + <Word>export</Word> + <Word>extern</Word> + <Word>inline</Word> + <Word>int</Word> + <Word>long</Word> + <Word>operator</Word> + <Word>register</Word> + <Word>reinterpret_cast</Word> + <Word>sizeof</Word> + <Word>static_cast</Word> + <Word>template</Word> + <Word>typedef</Word> + <Word>typeid</Word> + <Word>typename</Word> + </Keywords> + <Span color="Preprocessor"> + <Begin>\#</Begin> + </Span> + <Span color="Comment"> + <Begin>//</Begin> + </Span> + <Span color="Comment" multiline="true"> + <Begin>/\*</Begin> + <End>\*/</End> + </Span> + <Span color="String"> + <Begin>"</Begin> + <End>"</End> + <RuleSet> + <Span begin="\\" end="." /> + </RuleSet> + </Span> + <Span color="Character"> + <Begin>'</Begin> + <End>'</End> + <RuleSet> + <Span begin="\\" end="." /> + </RuleSet> + </Span> + <Rule color="MethodName">[\d\w_]+(?=(\s*\())</Rule> + <Rule color="Digits">\b0[xX][0-9a-fA-F]+|(\b\d+(\.[0-9]+)?|\.[0-9]+)([eE][+-]?[0-9]+)?</Rule> + </RuleSet> +</SyntaxDefinition>
\ No newline at end of file diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/CSS-Mode.xshd b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/CSS-Mode.xshd new file mode 100644 index 000000000..3ef562f0d --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/CSS-Mode.xshd @@ -0,0 +1,57 @@ +<SyntaxDefinition name="CSS" extensions=".css" xmlns="http://icsharpcode.net/sharpdevelop/syntaxdefinition/2008"> + <Color name="Comment" foreground="Gray" /> + <Color name="String" foreground="Green" /> + <Color name="Selector" foreground="DarkBlue" fontWeight="bold" /> + <Color name="Class" foreground="DarkMagenta" /> + <Color name="Property" foreground="Red"/> + <Color name="Value" foreground="Blue" /> + <Color name="Default" foreground="Pink" /> + <Color name="CurlyBraces" foreground="Black" /> + <Color name="Colon" foreground="Black" /> + <RuleSet ignoreCase="true"> + <Span color="Comment" multiline="true"> + <Begin>/\*</Begin> + <End>\*/</End> + </Span> + <Span + color="Property" + multiline="true" + ruleSet="CSSBlock"> + <Begin color="CurlyBraces">\{</Begin> + <End color="CurlyBraces">\}</End> + </Span> + <Span color="Class"> + <Begin>\#</Begin> + <End>\s</End> + </Span> + <Rule color="Selector">[\d\w]</Rule> + </RuleSet> + + <RuleSet name="CSSBlock"> + <Span color="Comment" multiline="true"> + <Begin>/\*</Begin> + <End>\*/</End> + </Span> + <Span color="Value" multiline="true"> + <Begin color="Colon">\:</Begin> + <End color="CurlyBraces">\;|(?=\})</End> + <RuleSet> + <Span color="String" multiline="true"> + <Begin>"</Begin> + <End>"</End> + <RuleSet> + <Span begin="\\" end="." /> + </RuleSet> + </Span> + <Span color="String" multiline="true"> + <Begin>'</Begin> + <End>'</End> + <RuleSet> + <Span begin="\\" end="." /> + </RuleSet> + </Span> + </RuleSet> + </Span> + </RuleSet> +</SyntaxDefinition> + diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/CSharp-Mode.xshd b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/CSharp-Mode.xshd new file mode 100644 index 000000000..40f362e08 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/CSharp-Mode.xshd @@ -0,0 +1,311 @@ +<?xml version="1.0"?> +<SyntaxDefinition name="C#" extensions=".cs" xmlns="http://icsharpcode.net/sharpdevelop/syntaxdefinition/2008"> + <!-- The named colors 'Comment' and 'String' are used in SharpDevelop to detect if a line is inside a multiline string/comment --> + <Color name="Comment" foreground="#57A33A" exampleText="// comment" /> + <Color name="String" foreground="#D69D85" exampleText="string text = "Hello, World!""/> + <Color name="Char" foreground="#D69D85" exampleText="char linefeed = '\n';"/> + <Color name="Preprocessor" foreground="DimGray" exampleText="#region Title" /> + <Color name="Punctuation" exampleText="a(b.c);" /> + <Color name="ValueTypes" foreground="#3F8FD6" exampleText="bool b = true;" /> + <Color name="ReferenceTypes" foreground="#4EC9B0" exampleText="object o;" /> + <Color name="InterfaceTypes" foreground="#B5CE8A" exampleText="object o;" /> + <Color name="MethodCall" foreground="Gainsboro" exampleText="o.ToString();"/> + <Color name="NumberLiteral" foreground="#B5CE8A" exampleText="3.1415f"/> + <Color name="ThisOrBaseReference" exampleText="this.Do(); base.Do();"/> + <Color name="NullOrValueKeywords" exampleText="if (value == null)"/> + <Color name="Keywords" foreground="#3F8FD6" exampleText="if (a) {} else {}"/> + <Color name="GotoKeywords" foreground="#3F8FD6" exampleText="continue; return null;"/> + <Color name="ContextKeywords" foreground="#3F8FD6" exampleText="var a = from x in y select z;"/> + <Color name="ExceptionKeywords" foreground="#3F8FD6" exampleText="try {} catch {} finally {}"/> + <Color name="CheckedKeyword" foreground="DarkGray" exampleText="checked {}"/> + <Color name="UnsafeKeywords" foreground="#3F8FD6" exampleText="unsafe { fixed (..) {} }"/> + <Color name="OperatorKeywords" foreground="Pink" exampleText="public static implicit operator..."/> + <Color name="ParameterModifiers" foreground="DeepPink" exampleText="(ref int a, params int[] b)"/> + <Color name="Modifiers" foreground="#3F8FD6" exampleText="static readonly int a;"/> + <Color name="CustomKeywords" foreground="#FAFF00" /> + <Color name="Visibility" foreground="#3F8FD6" exampleText="public override void ToString();"/> + <Color name="NamespaceKeywords" foreground="#569CD6" exampleText="namespace A.B { using System; }"/> + <Color name="GetSetAddRemove" foreground="#3F8FD6" exampleText="int Prop { get; set; }"/> + <Color name="TrueFalse" foreground="#3F8FD6" exampleText="b = false; a = true;" /> + <Color name="TypeKeywords" foreground="#3F8FD6" exampleText="if (x is int) { a = x as int; type = typeof(int); size = sizeof(int); c = new object(); }"/> + + <!--RegEx--> + <Color name="ScriptClass" foreground="#4EC9B0" exampleText="object o;" /> + + <!--<Property name="DocCommentMarker" value="///" />--> + + <RuleSet name="CommentMarkerSet"> + <Keywords foreground="Red"> + <Word>TODO</Word> + <Word>FIXME</Word> + </Keywords> + <Keywords foreground="#E0E000"> + <Word>HACK</Word> + <Word>UNDONE</Word> + </Keywords> + </RuleSet> + + <!-- This is the main ruleset. --> + <RuleSet> + <Span color="Preprocessor"> + <Begin>\#</Begin> + <RuleSet name="PreprocessorSet"> + <Span> <!-- preprocessor directives that allows comments --> + <Begin > + (define|undef|if|elif|else|endif|line)\b + </Begin> + <RuleSet> + <Span color="Comment" ruleSet="CommentMarkerSet"> + <Begin>//</Begin> + </Span> + </RuleSet> + </Span> + <Span> <!-- preprocessor directives that don't allow comments --> + <Begin > + (region|endregion|error|warning|pragma)\b + </Begin> + </Span> + </RuleSet> + </Span> + + <!--<Span color="Comment"> + <Begin color="XmlDoc/DocComment">///</Begin> + <RuleSet> + <Import ruleSet="XmlDoc/DocCommentSet"/> + <Import ruleSet="CommentMarkerSet"/> + </RuleSet> + </Span>--> + + <Span color="Comment" ruleSet="CommentMarkerSet"> + <Begin>//</Begin> + </Span> + + <Span color="Comment" ruleSet="CommentMarkerSet" multiline="true"> + <Begin>/\*</Begin> + <End>\*/</End> + </Span> + + <Span color="String"> + <Begin>"</Begin> + <End>"</End> + <RuleSet> + <!-- span for escape sequences --> + <Span begin="\\" end="."/> + </RuleSet> + </Span> + + <Span color="Char"> + <Begin>'</Begin> + <End>'</End> + <RuleSet> + <!-- span for escape sequences --> + <Span begin="\\" end="."/> + </RuleSet> + </Span> + + <Span color="String" multiline="true"> + <Begin>@"</Begin> + <End>"</End> + <RuleSet> + <!-- span for escape sequences --> + <Span begin='""' end=""/> + </RuleSet> + </Span> + + <!-- don't highlight "@int" as keyword --> + <Rule> + @[\w\d_]+ + </Rule> + + <Keywords color="CustomKeywords"> + <Word>include</Word> + <Word>import</Word> + </Keywords> + + <Keywords color="ThisOrBaseReference"> + <Word>this</Word> + <Word>base</Word> + </Keywords> + + <Keywords color="TypeKeywords"> + <Word>as</Word> + <Word>is</Word> + <Word>new</Word> + <Word>sizeof</Word> + <Word>typeof</Word> + <Word>stackalloc</Word> + </Keywords> + + <Keywords color="TrueFalse"> + <Word>true</Word> + <Word>false</Word> + </Keywords> + + <Keywords color="Keywords"> + <Word>else</Word> + <Word>if</Word> + <Word>switch</Word> + <Word>case</Word> + <Word>default</Word> + <Word>do</Word> + <Word>for</Word> + <Word>foreach</Word> + <Word>in</Word> + <Word>while</Word> + <Word>lock</Word> + </Keywords> + + <Keywords color="GotoKeywords"> + <Word>break</Word> + <Word>continue</Word> + <Word>goto</Word> + <Word>return</Word> + </Keywords> + + <Keywords color="ContextKeywords"> + <Word>yield</Word> + <Word>partial</Word> + <Word>class</Word> + <Word>global</Word> + <Word>where</Word> + <Word>select</Word> + <Word>group</Word> + <Word>by</Word> + <Word>into</Word> + <Word>from</Word> + <Word>ascending</Word> + <Word>descending</Word> + <Word>orderby</Word> + <Word>let</Word> + <Word>join</Word> + <Word>on</Word> + <Word>equals</Word> + <Word>var</Word> + <Word>dynamic</Word> + <Word>await</Word> + <Word>void</Word> + <Word>interface</Word> + <Word>this</Word> + </Keywords> + + <Keywords color="ExceptionKeywords"> + <Word>try</Word> + <Word>throw</Word> + <Word>catch</Word> + <Word>finally</Word> + </Keywords> + + <Keywords color="CheckedKeyword"> + <Word>checked</Word> + <Word>unchecked</Word> + </Keywords> + + <Keywords color="UnsafeKeywords"> + <Word>fixed</Word> + <Word>unsafe</Word> + </Keywords> + + <Keywords color="ValueTypes"> + <Word>bool</Word> + <Word>byte</Word> + <Word>char</Word> + <Word>decimal</Word> + <Word>double</Word> + <Word>enum</Word> + <Word>float</Word> + <Word>int</Word> + <Word>string</Word> + <Word>long</Word> + <Word>sbyte</Word> + <Word>short</Word> + <Word>struct</Word> + <Word>uint</Word> + <Word>ushort</Word> + <Word>ulong</Word> + <Word>null</Word> + </Keywords> + + <Keywords color="ReferenceTypes"> + <Word>@ReferenceTypes@</Word> + </Keywords> + + <Keywords color="InterfaceTypes"> + <Word>@InterfaceTypes@</Word> + </Keywords> + + <Keywords color="OperatorKeywords"> + <Word>explicit</Word> + <Word>implicit</Word> + <Word>operator</Word> + </Keywords> + + <Keywords color="ParameterModifiers"> + <Word>params</Word> + <Word>ref</Word> + <Word>out</Word> + </Keywords> + + <Keywords color="Modifiers"> + <Word>abstract</Word> + <Word>const</Word> + <Word>event</Word> + <Word>extern</Word> + <Word>override</Word> + <Word>readonly</Word> + <Word>sealed</Word> + <Word>static</Word> + <Word>virtual</Word> + <Word>volatile</Word> + <Word>async</Word> + </Keywords> + + <Keywords color="Visibility"> + <Word>public</Word> + <Word>protected</Word> + <Word>private</Word> + <Word>internal</Word> + </Keywords> + + <Keywords color="NamespaceKeywords"> + <Word>namespace</Word> + <Word>using</Word> + </Keywords> + + <Keywords color="GetSetAddRemove"> + <Word>get</Word> + <Word>set</Word> + <Word>add</Word> + <Word>remove</Word> + </Keywords> + + <Keywords color="NullOrValueKeywords"> + <Word>null</Word> + <Word>value</Word> + </Keywords> + + <!-- Mark previous rule--> + <Rule color="MethodCall"> + \b + [\d\w_]+ # an identifier + (?=\s*\() # followed by ( + </Rule> + + <!-- Digits --> + <Rule color="NumberLiteral"> + \b0[xX][0-9a-fA-F]+ # hex number + | + ( \b\d+(\.[0-9]+)? #number with optional floating point + | \.[0-9]+ #or just starting with floating point + ) + ([eE][+-]?[0-9]+)? # optional exponent + </Rule> + + <Rule color="Punctuation"> + [?,.;()\[\]{}+\-/%*<>^+~!|&]+ + </Rule> + + <!--<Rule color="ScriptClass"> + (?<=public class ).+ + </Rule>--> + </RuleSet> +</SyntaxDefinition> diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/Coco-Mode.xshd b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/Coco-Mode.xshd new file mode 100644 index 000000000..9395198b5 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/Coco-Mode.xshd @@ -0,0 +1,74 @@ +<?xml version="1.0" ?> +<!-- syntaxdefinition for Coco/R 2003 by Mike Krueger --> +<!-- converted to AvalonEdit format by Siegfried Pammer in 2010 --> +<SyntaxDefinition name="Coco" extensions=".atg" xmlns="http://icsharpcode.net/sharpdevelop/syntaxdefinition/2008"> + <Color name="Comment" foreground="#FF808080" fontStyle="italic" /> + <Color name="Punctuation" foreground="#FF000000" fontWeight="bold" /> + <Color name="Keywords" foreground="#FF0000FF" fontWeight="bold" /> + <Color name="String" foreground="#FF006400" /> + <RuleSet ignoreCase="false"> + <Rule color="Punctuation"> + [{}\(\)\[\]|+\-=\.]+ + </Rule> + <Keywords color="Keywords"> + <Word>ANY</Word> + <Word>CHARACTERS</Word> + <Word>COMMENTS</Word> + <Word>COMPILER</Word> + <Word>CONTEXT</Word> + <Word>END</Word> + <Word>FROM</Word> + <Word>IF</Word> + <Word>IGNORE</Word> + <Word>NAMESPACE</Word> + <Word>NESTED</Word> + <Word>PRAGMAS</Word> + <Word>PRODUCTIONS</Word> + <Word>SYNC</Word> + <Word>TO</Word> + <Word>TOKENS</Word> + <Word>TOKENNAMES</Word> + <Word>WEAK</Word> + <Word>using</Word> + </Keywords> + <Span color="Comment"> + <Begin>//</Begin> + </Span> + <Span color="Comment" multiline="true"> + <Begin>/\*</Begin> + <End>\*/</End> + </Span> + <Span foreground="Black" ruleSet="CSharp" multiline="true"> + <Begin color="Keywords">COMPILER</Begin> + <End color="Keywords">TOKENNAMES</End> + </Span> + <Span color="String"> + <Begin>"</Begin> + <End>"</End> + </Span> + <Span color="String"> + <Begin>'</Begin> + <End>'</End> + </Span> + <Span foreground="#FF000000" ruleSet="ParamList"> + <Begin foreground="#FF000000" fontWeight="bold"><</Begin> + <End foreground="#FF000000" fontWeight="bold">></End> + </Span> + <Span foreground="#FF2F4F4F" fontWeight="normal" fontStyle="normal" ruleSet="CSharp" multiline="true"> + <Begin foreground="#FF008000" fontWeight="bold" fontStyle="italic">\(\.</Begin> + <End foreground="#FF008000" fontWeight="bold" fontStyle="italic">\.\)</End> + </Span> + <Rule foreground="#FF00008B" fontWeight="normal" fontStyle="normal">\b0[xX][0-9a-fA-F]+|(\b\d+(\.[0-9]+)?|\.[0-9]+)([eE][+-]?[0-9]+)?</Rule> + </RuleSet> + <RuleSet name="CSharp" ignoreCase="false"> + <Import ruleSet="C#/" /> + <Rule foreground="#FF00008B" fontWeight="normal" fontStyle="normal">\b0[xX][0-9a-fA-F]+|(\b\d+(\.[0-9]+)?|\.[0-9]+)([eE][+-]?[0-9]+)?</Rule> + </RuleSet> + <RuleSet name="ParamList" ignoreCase="false"> + <Import ruleSet="C#/" /> + <Rule foreground="#FF00008B" fontWeight="normal" fontStyle="normal">\b0[xX][0-9a-fA-F]+|(\b\d+(\.[0-9]+)?|\.[0-9]+)([eE][+-]?[0-9]+)?</Rule> + </RuleSet> + <RuleSet name="RuleDefinition" ignoreCase="false"> + <Rule foreground="#FF00008B" fontWeight="normal" fontStyle="normal">\b0[xX][0-9a-fA-F]+|(\b\d+(\.[0-9]+)?|\.[0-9]+)([eE][+-]?[0-9]+)?</Rule> + </RuleSet> +</SyntaxDefinition>
\ No newline at end of file diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/HTML-Mode.xshd b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/HTML-Mode.xshd new file mode 100644 index 000000000..fd8211fe4 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/HTML-Mode.xshd @@ -0,0 +1,388 @@ +<?xml version="1.0"?> +<!-- syntaxdefinition for HTML 2000 by Mike Krueger --> +<!-- converted to AvalonEdit format by Siegfried Pammer in 2010 --> +<SyntaxDefinition name="HTML" extensions=".htm;.html" xmlns="http://icsharpcode.net/sharpdevelop/syntaxdefinition/2008"> + <Color name="Comment" foreground="green" exampleText="<!-- comment -->" /> + <Color name="Digits" foreground="#BBAD34" exampleText="<digits>0123456789</digits>" /> + <Color name="ScriptTag" foreground="#3F8FD6" exampleText="<script>alert('Hello World!');</script>" /> + <Color name="JavaScriptTag" foreground="#3F8FD6" exampleText="<script lang="JavaScript">alert('Hello World!');</script>" /> + <Color name="JScriptTag" foreground="#3F8FD6" exampleText="<script lang="JScript">Response.Write("Hello World!");</script>" /> + <Color name="VBScriptTag" foreground="#3F8FD6" exampleText="<script lang="VBScript">Response.Write("Hello World!")</script>" /> + <Color name="UnknownScriptTag" foreground="#3F8FD6" exampleText="<script la>alert('Hello World!');</script>" /> + <Color name="HtmlTag" foreground="#3F8FD6" exampleText="<html>Hello World!/html>" /> + <Color name="Tags" foreground="#3F8FD6" exampleText="<html>Hello World! <test /></html>" /> + <Color name="Attributes" foreground="#3F8FD6" exampleText="<html background='green'>Hello World! <test /></html>" /> + <Color name="Slash" foreground="Gainsboro" exampleText="<html background='green'>Hello World! <test /></html>" /> + <Color name="Assignment" foreground="Gainsboro" exampleText="<html background='green'>Hello World! <test /></html>" /> + <Color name="String" foreground="#E48383" exampleText="<html background='green'>Hello World! <test /></html>" /> + <Color name="EntityReference" foreground="#3F8FD6" exampleText="<html background='green'>Hello&nbsp;World! <test /></html>" /> + <Color name="Entities" foreground="#3F8FD6" exampleText="<html background='green'>Hello&nbsp;World! <test /></html>" /> + <Color name="UnknownAttribute" foreground="#DCDCDC" exampleText="<html foo='bar' background='green'>Hello&nbsp;World! <test /></html>" /> + <RuleSet ignoreCase="true"> + <Span color="Comment" multiline="true"> + <Begin><!--</Begin> + <End>--></End> + </Span> + <Span ruleSet="JavaScriptSet" multiline="true"> + <Begin color="JavaScriptTag"><script\ lang="JavaScript"></Begin> + <End color="JavaScriptTag"></script></End> + </Span> + <Span ruleSet="JavaScriptSet" multiline="true"> + <Begin color="JavaScriptTag"><script\s.*?text/javascript.*?></Begin> + <End color="JavaScriptTag"></script></End> + </Span> + <Span multiline="true"> + <Begin color="JScriptTag"><script\ lang="JScript"></Begin> + <End color="JScriptTag"></script></End> + </Span> + <Span multiline="true"> + <Begin color="VBScriptTag"><script\ lang="VBScript"></Begin> + <End color="VBScriptTag"></script></End> + </Span> + <Span ruleSet="JavaScriptSet" multiline="true"> + <Begin color="ScriptTag"><script></Begin> + <End color="ScriptTag"></script></End> + </Span> + <Span multiline="true"> + <Begin color="UnknownScriptTag"><script[^\w\d_]</Begin> + <End color="UnknownScriptTag"></script></End> + </Span> + <Span color="HtmlTag" ruleSet="HtmlTagSet" multiline="true"> + <Begin><</Begin> + <End>></End> + </Span> + <Span color="EntityReference" ruleSet="EntityReferenceSet"> + <Begin>&</Begin> + <End>;</End> + </Span> + <Rule color="Digits">\b0[xX][0-9a-fA-F]+|(\b\d+(\.[0-9]+)?|\.[0-9]+)([eE][+-]?[0-9]+)?</Rule> + </RuleSet> + <RuleSet name="JavaScriptSet"> + <Import ruleSet="JavaScript/" /> + <Rule color="Digits">\b0[xX][0-9a-fA-F]+|(\b\d+(\.[0-9]+)?|\.[0-9]+)([eE][+-]?[0-9]+)?</Rule> + </RuleSet> + <RuleSet name="EntityReferenceSet" ignoreCase="false"> + <Keywords color="Entities"> + <Word>aacute</Word> + <Word>agrave</Word> + <Word>acirc</Word> + <Word>amp</Word> + <Word>atilde</Word> + <Word>aring</Word> + <Word>auml</Word> + <Word>aelig</Word> + <Word>ccedil</Word> + <Word>copy</Word> + <Word>eacute</Word> + <Word>egrave</Word> + <Word>ecirc</Word> + <Word>euml</Word> + <Word>iacute</Word> + <Word>igrave</Word> + <Word>icirc</Word> + <Word>iuml</Word> + <Word>eth</Word> + <Word>gt</Word> + <Word>lt</Word> + <Word>nbsp</Word> + <Word>ntilde</Word> + <Word>oacute</Word> + <Word>ograve</Word> + <Word>ocirc</Word> + <Word>otilde</Word> + <Word>ouml</Word> + <Word>oslash</Word> + <Word>quot</Word> + <Word>reg</Word> + <Word>szlig</Word> + <Word>uacute</Word> + <Word>ugrave</Word> + <Word>ucirc</Word> + <Word>uuml</Word> + <Word>yacute</Word> + <Word>thorn</Word> + <Word>trade</Word> + <Word>yuml</Word> + </Keywords> + <Rule color="Digits">\b0[xX][0-9a-fA-F]+|(\b\d+(\.[0-9]+)?|\.[0-9]+)([eE][+-]?[0-9]+)?</Rule> + </RuleSet> + <RuleSet name="HtmlTagSet" ignoreCase="false"> + <Keywords color="Slash"> + <Word>/</Word> + </Keywords> + <Keywords color="Assignment"> + <Word>=</Word> + </Keywords> + <Keywords color="Tags"> + <Word>!DOCTYPE</Word> + <Word>A</Word> + <Word>ABBR</Word> + <Word>ACRONYM</Word> + <Word>ADDRESS</Word> + <Word>APPLET</Word> + <Word>AREA</Word> + <Word>B</Word> + <Word>BASE</Word> + <Word>BASEFONT</Word> + <Word>BGSOUND</Word> + <Word>BDO</Word> + <Word>BIG</Word> + <Word>BLINK</Word> + <Word>BLOCKQUOTE</Word> + <Word>BODY</Word> + <Word>BR</Word> + <Word>BUTTON</Word> + <Word>CAPTION</Word> + <Word>CENTER</Word> + <Word>CITE</Word> + <Word>CODE</Word> + <Word>COL</Word> + <Word>COLGROUP</Word> + <Word>COMMENT</Word> + <Word>DD</Word> + <Word>DEL</Word> + <Word>DFN</Word> + <Word>DIR</Word> + <Word>DIV</Word> + <Word>DL</Word> + <Word>DT</Word> + <Word>EM</Word> + <Word>EMBED</Word> + <Word>FIELDSET</Word> + <Word>FONT</Word> + <Word>FORM</Word> + <Word>FRAME</Word> + <Word>FRAMESET</Word> + <Word>H</Word> + <Word>H1</Word> + <Word>H2</Word> + <Word>H3</Word> + <Word>H4</Word> + <Word>H5</Word> + <Word>H6</Word> + <Word>HEAD</Word> + <Word>HR</Word> + <Word>HTA:APPLICATION</Word> + <Word>HTML</Word> + <Word>I</Word> + <Word>IFRAME</Word> + <Word>IMG</Word> + <Word>INPUT</Word> + <Word>INS</Word> + <Word>ISINDEX</Word> + <Word>KBD</Word> + <Word>LABEL</Word> + <Word>LEGEnd</Word> + <Word>LI</Word> + <Word>LINK</Word> + <Word>LISTING</Word> + <Word>MAP</Word> + <Word>MARQUEE</Word> + <Word>MENU</Word> + <Word>META</Word> + <Word>MULTICOL</Word> + <Word>NEXTID</Word> + <Word>NOBR</Word> + <Word>NOFRAMES</Word> + <Word>NOSCRIPT</Word> + <Word>OBJECT</Word> + <Word>OL</Word> + <Word>OPTGROUP</Word> + <Word>OPTION</Word> + <Word>P</Word> + <Word>PARAM</Word> + <Word>PLAINTEXT</Word> + <Word>PRE</Word> + <Word>Q</Word> + <Word>S</Word> + <Word>SAMP</Word> + <Word>SCRIPT</Word> + <Word>SELECT</Word> + <Word>SERVER</Word> + <Word>SMALL</Word> + <Word>SOUND</Word> + <Word>SPACER</Word> + <Word>Span</Word> + <Word>STRONG</Word> + <Word>STYLE</Word> + <Word>SUB</Word> + <Word>SUP</Word> + <Word>TABLE</Word> + <Word>TBODY</Word> + <Word>TD</Word> + <Word>TEXTAREA</Word> + <Word>TEXTFLOW</Word> + <Word>TFOOT</Word> + <Word>TH</Word> + <Word>THEAD</Word> + <Word>TITLE</Word> + <Word>TR</Word> + <Word>TT</Word> + <Word>U</Word> + <Word>VAR</Word> + <Word>WBR</Word> + <Word>XMP</Word> + </Keywords> + <Keywords color="Attributes"> + <Word>abbr</Word> + <Word>accept-charset</Word> + <Word>accept</Word> + <Word>accesskey</Word> + <Word>action</Word> + <Word>align</Word> + <Word>alink</Word> + <Word>alt</Word> + <Word>applicationname</Word> + <Word>archive</Word> + <Word>axis</Word> + <Word>background</Word> + <Word>behavior</Word> + <Word>bgcolor</Word> + <Word>bgproperties</Word> + <Word>border</Word> + <Word>bordercolor</Word> + <Word>bordercolordark</Word> + <Word>bordercolorligh</Word> + <Word>borderstyle</Word> + <Word>caption</Word> + <Word>cellpadding</Word> + <Word>cellspacing</Word> + <Word>char</Word> + <Word>charoff</Word> + <Word>charset</Word> + <Word>checked</Word> + <Word>cite</Word> + <Word>class</Word> + <Word>classid</Word> + <Word>clear</Word> + <Word>code</Word> + <Word>codetype</Word> + <Word>color</Word> + <Word>cols</Word> + <Word>colspan</Word> + <Word>compact</Word> + <Word>content</Word> + <Word>coords</Word> + <Word>data</Word> + <Word>datetime</Word> + <Word>declare</Word> + <Word>defer</Word> + <Word>dir</Word> + <Word>direction</Word> + <Word>disabled</Word> + <Word>dynsrc</Word> + <Word>enctype</Word> + <Word>face</Word> + <Word>for</Word> + <Word>frame</Word> + <Word>frameborder</Word> + <Word>framespacing</Word> + <Word>gutter</Word> + <Word>headers</Word> + <Word>height</Word> + <Word>href</Word> + <Word>hreflang</Word> + <Word>hspace</Word> + <Word>http-equiv</Word> + <Word>icon</Word> + <Word>id</Word> + <Word>ismap</Word> + <Word>label</Word> + <Word>language</Word> + <Word>leftmargin</Word> + <Word>link</Word> + <Word>longdesc</Word> + <Word>loop</Word> + <Word>lowsrc</Word> + <Word>marginheight</Word> + <Word>marginwidth</Word> + <Word>maximizebutton</Word> + <Word>maxlength</Word> + <Word>media</Word> + <Word>method</Word> + <Word>methods</Word> + <Word>minimizebutton</Word> + <Word>multiple</Word> + <Word>name</Word> + <Word>nohref</Word> + <Word>noresize</Word> + <Word>noshade</Word> + <Word>nowrap</Word> + <Word>object</Word> + <Word>onabort</Word> + <Word>onblur</Word> + <Word>onchange</Word> + <Word>onclick</Word> + <Word>ondblclick</Word> + <Word>onerror</Word> + <Word>onfocus</Word> + <Word>onkeydown</Word> + <Word>onkeypress</Word> + <Word>onkeyup</Word> + <Word>onload</Word> + <Word>onmousedown</Word> + <Word>onmousemove</Word> + <Word>onmouseout</Word> + <Word>onmouseover</Word> + <Word>onmouseup</Word> + <Word>onreset</Word> + <Word>onselect</Word> + <Word>onsubmit</Word> + <Word>onunload</Word> + <Word>profile</Word> + <Word>prompt</Word> + <Word>readonly</Word> + <Word>rel</Word> + <Word>rev</Word> + <Word>rows</Word> + <Word>rowspan</Word> + <Word>rules</Word> + <Word>runat</Word> + <Word>scheme</Word> + <Word>scope</Word> + <Word>scrollamount</Word> + <Word>scrolldelay</Word> + <Word>scrolling</Word> + <Word>selected</Word> + <Word>shape</Word> + <Word>showintaskbar</Word> + <Word>singleinstance</Word> + <Word>size</Word> + <Word>span</Word> + <Word>src</Word> + <Word>standby</Word> + <Word>start</Word> + <Word>style</Word> + <Word>summary</Word> + <Word>sysmenu</Word> + <Word>tabindex</Word> + <Word>target</Word> + <Word>text</Word> + <Word>title</Word> + <Word>topmargin</Word> + <Word>type</Word> + <Word>urn</Word> + <Word>usemap</Word> + <Word>valign</Word> + <Word>value</Word> + <Word>valuetype</Word> + <Word>version</Word> + <Word>vlink</Word> + <Word>vrml</Word> + <Word>vspace</Word> + <Word>width</Word> + <Word>windowstate</Word> + <Word>wrap</Word> + </Keywords> + <Span color="String"> + <Begin>"</Begin> + <End>"</End> + </Span> + <Span color="String"> + <Begin>'</Begin> + <End>'</End> + </Span> + <Rule color="UnknownAttribute">[\d\w_]+(?=(\s*=))</Rule> + <Rule color="Digits">\b0[xX][0-9a-fA-F]+|(\b\d+(\.[0-9]+)?|\.[0-9]+)([eE][+-]?[0-9]+)?</Rule> + </RuleSet> +</SyntaxDefinition>
\ No newline at end of file diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/Java-Mode.xshd b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/Java-Mode.xshd new file mode 100644 index 000000000..dd5053e91 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/Java-Mode.xshd @@ -0,0 +1,152 @@ +<?xml version="1.0"?> +<!-- syntaxdefinition for Java 2001 by Jonathan Pierce & Mike Krueger --> +<!-- converted to AvalonEdit format by Siegfried Pammer in 2010 --> +<SyntaxDefinition name="Java" extensions=".java" xmlns="http://icsharpcode.net/sharpdevelop/syntaxdefinition/2008"> + <Color name="MethodName" foreground="DarkBlue" /> + <Color name="Digits" foreground="DarkBlue" fontStyle="italic" /> + <Color name="String" foreground="Magenta" /> + <Color name="Character" foreground="Magenta" /> + <Color name="Comment" foreground="SlateGray" /> + <Color name="Punctuation" foreground="DarkGreen" /> + <Color name="AccessKeywords" foreground="Black" fontWeight="bold" /> + <Color name="OperatorKeywords" foreground="DarkCyan" fontWeight="bold" /> + <Color name="SelectionStatements" foreground="Blue" fontWeight="bold" /> + <Color name="IterationStatements" foreground="Blue" fontWeight="bold" /> + <Color name="ExceptionHandlingStatements" foreground="Teal" fontWeight="bold" /> + <Color name="ValueTypes" foreground="Red" fontWeight="bold" /> + <Color name="ReferenceTypes" foreground="Red" /> + <Color name="Void" foreground="Red" /> + <Color name="JumpStatements" foreground="Navy" /> + <Color name="Modifiers" foreground="Brown" /> + <Color name="AccessModifiers" foreground="Blue" fontWeight="bold" /> + <Color name="Package" foreground="Green" fontWeight="bold" /> + <Color name="Literals" foreground="Black" fontWeight="bold" /> + <Color name="CommentTags" foreground="Red" fontWeight="bold" fontStyle="italic" /> + <Color name="JavaDocTags" foreground="DarkGray" fontWeight="bold" fontStyle="italic" /> + <RuleSet ignoreCase="false"> + <Rule color="Punctuation"> + [?,.()\[\]{}+\-/%*<>^!|]+ + </Rule> + <Keywords color="AccessKeywords"> + <Word>this</Word> + <Word>super</Word> + </Keywords> + <Keywords color="OperatorKeywords"> + <Word>new</Word> + <Word>instanceof</Word> + <Word>true</Word> + <Word>false</Word> + </Keywords> + <Keywords color="SelectionStatements"> + <Word>else</Word> + <Word>if</Word> + <Word>switch</Word> + <Word>case</Word> + </Keywords> + <Keywords color="IterationStatements"> + <Word>do</Word> + <Word>for</Word> + <Word>while</Word> + </Keywords> + <Keywords color="JumpStatements"> + <Word>break</Word> + <Word>continue</Word> + <Word>default</Word> + <Word>goto</Word> + <Word>return</Word> + </Keywords> + <Keywords color="ExceptionHandlingStatements"> + <Word>try</Word> + <Word>throw</Word> + <Word>catch</Word> + <Word>finally</Word> + </Keywords> + <Keywords color="ValueTypes"> + <Word>boolean</Word> + <Word>double</Word> + <Word>int</Word> + <Word>short</Word> + <Word>long</Word> + <Word>float</Word> + <Word>byte</Word> + <Word>char</Word> + </Keywords> + <Keywords color="ReferenceTypes"> + <Word>class</Word> + <Word>interface</Word> + <Word>object</Word> + </Keywords> + <Keywords color="Void"> + <Word>void</Word> + </Keywords> + <Keywords color="Modifiers"> + <Word>abstract</Word> + <Word>const</Word> + <Word>static</Word> + <Word>final</Word> + <Word>native</Word> + <Word>extends</Word> + <Word>implements</Word> + <Word>volatile</Word> + <Word>transient</Word> + <Word>throws</Word> + <Word>strictfp</Word> + <Word>synchronized</Word> + </Keywords> + <Keywords color="AccessModifiers"> + <Word>public</Word> + <Word>protected</Word> + <Word>private</Word> + </Keywords> + <Keywords color="Package"> + <Word>package</Word> + <Word>import</Word> + </Keywords> + <Keywords color="Literals"> + <Word>null</Word> + </Keywords> + <Span color="Comment" ruleSet="TestSet"> + <Begin>//</Begin> + </Span> + <Span color="Comment" ruleSet="TestSet" multiline="true"> + <Begin>/\*</Begin> + <End>\*/</End> + </Span> + <Span color="String"> + <Begin>"</Begin> + <End>"</End> + <RuleSet> + <Span begin="\\" end="." /> + </RuleSet> + </Span> + <Span color="Character"> + <Begin>'</Begin> + <End>'</End> + <RuleSet> + <Span begin="\\" end="." /> + </RuleSet> + </Span> + <Rule color="MethodName">[\d\w_]+(?=(\s*\())</Rule> + <Rule color="Digits">\b0[xX][0-9a-fA-F]+|(\b\d+(\.[0-9]+)?|\.[0-9]+)([eE][+-]?[0-9]+)?</Rule> + </RuleSet> + <RuleSet name="TestSet" ignoreCase="true"> + <Keywords color="CommentTags"> + <Word>TODO</Word> + </Keywords> + <Keywords color="JavaDocTags"> + <Word>@author</Word> + <Word>@version</Word> + <Word>@param</Word> + <Word>@return</Word> + <Word>@exception</Word> + <Word>@throws</Word> + <Word>@see</Word> + <Word>@since</Word> + <Word>@serial</Word> + <Word>@serialField</Word> + <Word>@serialData</Word> + <Word>@deprecated</Word> + </Keywords> + <Rule color="Digits">\b0[xX][0-9a-fA-F]+|(\b\d+(\.[0-9]+)?|\.[0-9]+)([eE][+-]?[0-9]+)?</Rule> + </RuleSet> +</SyntaxDefinition>
\ No newline at end of file diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/JavaScript-Mode.xshd b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/JavaScript-Mode.xshd new file mode 100644 index 000000000..97775dce5 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/JavaScript-Mode.xshd @@ -0,0 +1,132 @@ +<?xml version="1.0"?> +<!-- syntaxdefinition for JavaScript 2.0 by Svante Lidman --> +<!-- converted to AvalonEdit format by Siegfried Pammer in 2010 --> +<SyntaxDefinition name="JavaScript" extensions=".js" xmlns="http://icsharpcode.net/sharpdevelop/syntaxdefinition/2008"> + <Color name="Digits" foreground="DarkBlue" /> + <Color name="Comment" foreground="Green" /> + <Color name="String" foreground="Sienna" /> + <Color name="Character" foreground="Sienna" /> + <Color name="Regex" foreground="Sienna" /> + <Color name="JavaScriptKeyWords" foreground="Blue" /> + <Color name="JavaScriptIntrinsics" foreground="Blue" /> + <Color name="JavaScriptLiterals" foreground="Blue" /> + <Color name="JavaScriptGlobalFunctions" foreground="Blue" /> + <RuleSet ignoreCase="false"> + <Keywords color="JavaScriptKeyWords"> + <Word>break</Word> + <Word>continue</Word> + <Word>delete</Word> + <Word>else</Word> + <Word>for</Word> + <Word>function</Word> + <Word>if</Word> + <Word>in</Word> + <Word>new</Word> + <Word>return</Word> + <Word>this</Word> + <Word>typeof</Word> + <Word>var</Word> + <Word>void</Word> + <Word>while</Word> + <Word>with</Word> + <Word>abstract</Word> + <Word>boolean</Word> + <Word>byte</Word> + <Word>case</Word> + <Word>catch</Word> + <Word>char</Word> + <Word>class</Word> + <Word>const</Word> + <Word>debugger</Word> + <Word>default</Word> + <Word>do</Word> + <Word>double</Word> + <Word>enum</Word> + <Word>export</Word> + <Word>extends</Word> + <Word>final</Word> + <Word>finally</Word> + <Word>float</Word> + <Word>goto</Word> + <Word>implements</Word> + <Word>import</Word> + <Word>instanceof</Word> + <Word>int</Word> + <Word>interface</Word> + <Word>long</Word> + <Word>native</Word> + <Word>package</Word> + <Word>private</Word> + <Word>protected</Word> + <Word>public</Word> + <Word>short</Word> + <Word>static</Word> + <Word>super</Word> + <Word>switch</Word> + <Word>synchronized</Word> + <Word>throw</Word> + <Word>throws</Word> + <Word>transient</Word> + <Word>try</Word> + <Word>volatile</Word> + </Keywords> + <Keywords color="JavaScriptIntrinsics"> + <Word>Array</Word> + <Word>Boolean</Word> + <Word>Date</Word> + <Word>Function</Word> + <Word>Global</Word> + <Word>Math</Word> + <Word>Number</Word> + <Word>Object</Word> + <Word>RegExp</Word> + <Word>String</Word> + </Keywords> + <Keywords color="JavaScriptLiterals"> + <Word>false</Word> + <Word>null</Word> + <Word>true</Word> + <Word>NaN</Word> + <Word>Infinity</Word> + </Keywords> + <Keywords color="JavaScriptGlobalFunctions"> + <Word>eval</Word> + <Word>parseInt</Word> + <Word>parseFloat</Word> + <Word>escape</Word> + <Word>unescape</Word> + <Word>isNaN</Word> + <Word>isFinite</Word> + </Keywords> + <Span color="Comment"> + <Begin>//</Begin> + </Span> + <Span color="Comment" multiline="true"> + <Begin>/\*</Begin> + <End>\*/</End> + </Span> + <!--<Rule color="Regex">/.*/</Rule>--> + <Span color="Regex"> + <Begin>/</Begin> + <End>/</End> + <RuleSet> + <Span begin="\\/" end="." /> + </RuleSet> + </Span> + <Span color="String" multiline="true"> + <Begin>"</Begin> + <End>"</End> + <RuleSet> + <Span begin="\\" end="." /> + </RuleSet> + </Span> + <Span color="Character"> + <Begin>'</Begin> + <End>'</End> + <RuleSet> + <Span begin="\\" end="." /> + </RuleSet> + </Span> + <Rule color="Digits">\b0[xX][0-9a-fA-F]+|(\b\d+(\.[0-9]+)?|\.[0-9]+)([eE][+-]?[0-9]+)?</Rule> + </RuleSet> +</SyntaxDefinition>
\ No newline at end of file diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/MarkDown-Mode.xshd b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/MarkDown-Mode.xshd new file mode 100644 index 000000000..ead5045ab --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/MarkDown-Mode.xshd @@ -0,0 +1,56 @@ +<?xml version="1.0"?> +<SyntaxDefinition name="MarkDown" extensions=".md" xmlns="http://icsharpcode.net/sharpdevelop/syntaxdefinition/2008"> + <Color name="Heading" foreground="Maroon" exampleText="# Title #" /> + <Color name="Emphasis" fontStyle="italic" exampleText="*this* is important!" /> + <Color name="StrongEmphasis" fontWeight="bold" exampleText="**this** is more important!" /> + <Color name="Code" exampleText="this is `int.GetHashCode()`" /> + <Color name="BlockQuote" foreground="DarkBlue" exampleText="> This is a\r\n> quote." /> + <Color name="Link" foreground="Blue" exampleText="[text](http://example.com)" /> + <Color name="Image" foreground="Green" exampleText="[text][http://example.com/test.png]" /> + <Color name="LineBreak" background="LightGray" exampleText="end of line \r\n2nd line " /> + + <RuleSet ignoreCase="true"> + <Rule color="Heading"> + ^\#.* + </Rule> + <Rule color="StrongEmphasis"> + \*\*.*\*\* + </Rule> + <Rule color="StrongEmphasis"> + __.*__ + </Rule> + <Rule color="Emphasis"> + \*(?![ ]).*\* + </Rule> + <Rule color="Emphasis"> + _.*_ + </Rule> + <Rule color="Code"> + `.*` + </Rule> + <Span color="Code" ruleSet="C#/" multiline="true"> + <Begin>^\t</Begin> + <End>^(?!\t)</End> + </Span> + <Span color="Code" ruleSet="C#/" multiline="true"> + <Begin>^[ ]{4}</Begin> + <End>^(?![ ]{4})</End> + </Span> + <Span color="BlockQuote" multiline="true"> + <Begin>^></Begin> + <End>^(?!>)</End> + </Span> + <Rule color="Image"> + \!\[.*\]\[.*\] + </Rule> + <Rule color="Link"> + \[.*\]\(.*\) + </Rule> + <Rule color="Link"> + \[.*\]\[.*\] + </Rule> + <Rule color="LineBreak"> + [ ]{2}$ + </Rule> + </RuleSet> +</SyntaxDefinition>
\ No newline at end of file diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/ModeV1.xsd b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/ModeV1.xsd new file mode 100644 index 000000000..82bce451d --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/ModeV1.xsd @@ -0,0 +1,296 @@ +<?xml version="1.0" encoding="utf-8" ?> +<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" > + <xsd:annotation> + <xsd:documentation> + This schema defines the syntax for mode definitions in SharpDevelop. + The schema can be simplified quite a bit but it does the job as is. + + + If you are using this file as a reference it is probably easiest to scroll to + the botton to find the definition of the root element called SyntaxDefinition and + then unwind the different type definitions and refernces. + + Note on coloring: + Many tags define how some symbol should be colored. If a specific symbol + can not be matched onto either a Span definition, Keyword, or a Digit/Number it + will be rendered in the current default color. Which is the default color of the + current span or the default color of the mode as a whole if no span has been entered. + </xsd:documentation> + </xsd:annotation> + + <!-- Defines the default rendering of the mode --> + <xsd:complexType name="EnvironmentEntry"> + <xsd:attribute name="bold" type="xsd:boolean" /> + <xsd:attribute name="italic" type="xsd:boolean" /> + <xsd:attribute name="color" type="xsd:string" /> + <xsd:attribute name="bgcolor" type="xsd:string" /> + </xsd:complexType> + + <xsd:complexType name="CustomEnvironmentEntry"> + <xsd:attribute name="name" type="xsd:string" use="required" /> + <xsd:attribute name="bold" type="xsd:boolean" /> + <xsd:attribute name="italic" type="xsd:boolean" /> + <xsd:attribute name="color" type="xsd:string" /> + <xsd:attribute name="bgcolor" type="xsd:string" /> + </xsd:complexType> + + <!-- The environment tag defines the coloring of various attributes in SharpDevelop --> + <xsd:complexType name="Environment"> + + <xsd:choice minOccurs="0" maxOccurs="unbounded"> + <xsd:element name="Default" type="EnvironmentEntry" minOccurs="0" maxOccurs="1" /> + <xsd:element name="Selection" type="EnvironmentEntry" minOccurs="0" maxOccurs="1"/> + <xsd:element name="VRuler" type="EnvironmentEntry" minOccurs="0" maxOccurs="1"/> + <xsd:element name="InvalidLines" type="EnvironmentEntry" minOccurs="0" maxOccurs="1"/> + <xsd:element name="CaretMarker" type="EnvironmentEntry" minOccurs="0" maxOccurs="1"/> + <xsd:element name="CaretLine" type="EnvironmentEntry" minOccurs="0" maxOccurs="1"/> + + <xsd:element name="LineNumbers" type="EnvironmentEntry" minOccurs="0" maxOccurs="1"/> + + <xsd:element name="FoldLine" type="EnvironmentEntry" minOccurs="0" maxOccurs="1"/> + <xsd:element name="FoldMarker" type="EnvironmentEntry" minOccurs="0" maxOccurs="1"/> + <xsd:element name="SelectedFoldLine" type="EnvironmentEntry" minOccurs="0" maxOccurs="1"/> + + <xsd:element name="EOLMarkers" type="EnvironmentEntry" minOccurs="0" maxOccurs="1"/> + <xsd:element name="SpaceMarkers" type="EnvironmentEntry" minOccurs="0" maxOccurs="1"/> + <xsd:element name="TabMarkers" type="EnvironmentEntry" minOccurs="0" maxOccurs="1"/> + + <xsd:element name="Custom" type="CustomEnvironmentEntry" minOccurs="0" maxOccurs="unbounded"/> + </xsd:choice> + </xsd:complexType> + + <xsd:complexType name="Properties"> + <xsd:sequence> + <xsd:element name="Property" type="Property" minOccurs="0" maxOccurs="unbounded"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="Property"> + <!-- The actual KeyWord, typically reserved words or symbols in a programming language --> + <xsd:attribute name="name" type="xsd:string" /> + <xsd:attribute name="value" type="xsd:string" /> + </xsd:complexType> + + <!-- The Digits tag defines the color for rendering Digits--> + <xsd:complexType name="Digits"> + <xsd:attribute name="name" type="xsd:string" /> + <xsd:attribute name="bold" type="xsd:boolean" /> + <xsd:attribute name="italic" type="xsd:boolean" /> + <xsd:attribute name="color" type="xsd:string" /> + <xsd:attribute name="bgcolor" type="xsd:string" /> + </xsd:complexType> + + <!-- Defines the delimiting characters of the syntax, e.g., the characters that, "break up" a line + into separate symbols, typically key words. It is not necessary, or desirable to include the + characters that denot the start or end of a span. Space and Tab are implicitly defined as delimeters + and they don't need to be includeded explicitly (this will probably be changed at some future time).--> + <xsd:complexType name="Delimiters"> + <xsd:simpleContent> + <xsd:extension base="xsd:string"> + </xsd:extension> + </xsd:simpleContent> + </xsd:complexType> + + <!-- The beginning symbol of a Span --> + <xsd:complexType name="Begin"> + <xsd:simpleContent> + <xsd:extension base="xsd:string"> + <xsd:attribute name="singleword" type="xsd:boolean" /> + <xsd:attribute name="startofline" type="xsd:boolean" /> + <!-- The default rendering style for the Begin symbol. If not specified + the defaul rendering style for the span will be used. --> + <xsd:attribute name="bold" type="xsd:boolean" /> + <xsd:attribute name="italic" type="xsd:boolean" /> + <xsd:attribute name="color" type="xsd:string" /> + <xsd:attribute name="bgcolor" type="xsd:string" /> + </xsd:extension> + </xsd:simpleContent> + </xsd:complexType> + + <!-- The end symbol of a Span --> + <xsd:complexType name="End"> + <xsd:simpleContent> + <xsd:extension base="xsd:string"> + <xsd:attribute name="singleword" type="xsd:boolean" /> + <!-- The default rendering style for the End symbol. If not specified + the defaul rendering style for the span will be used. --> + <xsd:attribute name="bold" type="xsd:boolean" /> + <xsd:attribute name="italic" type="xsd:boolean" /> + <xsd:attribute name="color" type="xsd:string" /> + <xsd:attribute name="bgcolor" type="xsd:string" /> + </xsd:extension> + </xsd:simpleContent> + </xsd:complexType> + + <xsd:complexType name="Span"> + <xsd:sequence> + <!-- Defines the symbol that indicates the beginning of the span. --> + <xsd:element name="Begin" type="Begin" /> + <!-- Defines the symbol that indicates the end of the span. May be omitted for + one-line spans. --> + <xsd:element name="End" minOccurs="0" type="End" /> + </xsd:sequence> + <!-- The name of the span definition --> + <xsd:attribute name="name" type="xsd:string" use="required" /> + <!-- Defines the rule set that is applicable in the Span. May be omitted. --> + <xsd:attribute name="rule" type="xsd:string" /> + <!-- Defines wether the Span should terminate automatically at the end of line. Typical examples + include one-line comments such as // in C++ or REM in Windows .Bat files. --> + <xsd:attribute name="stopateol" type="xsd:boolean" /> + + <!-- OBSOLUTE: Defines whether C-style escape sequences using \ are applicable or not in the span. --> + <xsd:attribute name="noescapesequences" type="xsd:boolean" /> + + <!-- defines the escape character --> + <xsd:attribute name="escapecharacter" type="xsd:string" /> + + <!-- The default rendering style for the span --> + <xsd:attribute name="bold" type="xsd:boolean" /> + <xsd:attribute name="italic" type="xsd:boolean" /> + <xsd:attribute name="color" type="xsd:string" /> + <xsd:attribute name="bgcolor" type="xsd:string" /> + </xsd:complexType> + + <xsd:complexType name="MarkPrevious"> + <xsd:simpleContent> + <xsd:extension base="xsd:string"> + <!-- Svante Lidman, looking in the code it is a bit unclear what the intent is here... --> + <xsd:attribute name="markmarker" type="xsd:boolean" /> + <!-- The rendering style to be used --> + <xsd:attribute name="bold" type="xsd:boolean" /> + <xsd:attribute name="italic" type="xsd:boolean" /> + <xsd:attribute name="color" type="xsd:string" /> + <xsd:attribute name="bgcolor" type="xsd:string" /> + </xsd:extension> + </xsd:simpleContent> + </xsd:complexType> + + <!-- Allows you to define the coloring of the symbol that follows a specified symbol --> + <xsd:complexType name="MarkFollowing"> + <xsd:simpleContent> + <xsd:extension base="xsd:string"> + <!-- Svante Lidman, looking in the code it is a bit unclear what the intent is here... --> + <xsd:attribute name="markmarker" type="xsd:boolean" /> + <!-- The rendering style to be used --> + <xsd:attribute name="bold" type="xsd:boolean" /> + <xsd:attribute name="italic" type="xsd:boolean" /> + <xsd:attribute name="color" type="xsd:string" /> + <xsd:attribute name="bgcolor" type="xsd:string" /> + </xsd:extension> + </xsd:simpleContent> + </xsd:complexType> + + <xsd:complexType name="Key"> + <!-- The actual KeyWord, typically reserved words or symbols in a programming language --> + <xsd:attribute name="word" type="xsd:string" /> + </xsd:complexType> + + + <!-- A grouping of keywords that sholuld be colored the same way --> + <xsd:complexType name="KeyWords"> + <xsd:sequence> + <!-- allow groups with 0 keywords: this simplifies the syntax highlighting editor --> + <!-- A KeyWord --> + <xsd:element name="Key" type="Key" minOccurs="0" maxOccurs="unbounded"> + </xsd:element> + </xsd:sequence> + <!-- The name of the KeyWord group --> + <xsd:attribute name="name" type="xsd:string" /> + <!-- The rendering style of the KeyWord group --> + <xsd:attribute name="bold" type="xsd:boolean" /> + <xsd:attribute name="italic" type="xsd:boolean" /> + <xsd:attribute name="color" type="xsd:string" /> + <xsd:attribute name="bgcolor" type="xsd:string" /> + </xsd:complexType> + + <xsd:complexType name="RuleSet"> + <xsd:sequence> + <!-- Defines the delimiting characters of the syntax, e.g., the characters that, "break up" a line + into separate symbols, typically key words. It is not necessary, or desirable to include the + characters that denot the start or end of a span. Space and Tab are implicitly defined as delimeters + and they don't need to be includeded explicitly (this will probably be changed at some future time).--> + <xsd:element name="Delimiters" type="Delimiters" minOccurs="0" maxOccurs="1"> + </xsd:element> + <!-- A Span tag defines a scope, or what can be seen as a separate parsing context where a different set of + highlighting rules are applicable compared to the text where the span is found. + Examples of spans include: + - A string in a language as C + - A <script> tag in Html + - The internals of a tag in XML (between < and >). + A span can have a rule set associated with it that defines the highlighting rules that are applicable + in the span. --> + <xsd:element name="Span" type="Span" minOccurs="0" maxOccurs="unbounded"> + </xsd:element> + <!-- The MarkPrevious tag allows you to define the coloring of the item that preceeds a specific + symbol. An example of where this comes in handy is when coloring the contents of an XML-tag, + in particular the attributes and attribute names. The following definition: + <MarkPrevious bold="false" italic="false" color="Red">=</MarkPrevious> + will make teh highlighter color words that are followed by an = to be colored in Red. + You can see this in this file if you view it with the default XML-mode in SharpDevelop. --> + <xsd:element name="MarkPrevious" type="MarkPrevious" minOccurs="0" maxOccurs="unbounded"> + </xsd:element> + <!-- The MarkFollowing tag works similarly as the MarkPrevious tag but relates to the coloring + of the symbol that follows the specified symbol. --> + <xsd:element name="MarkFollowing" type="MarkFollowing" minOccurs="0" maxOccurs="unbounded"> + </xsd:element> + <!-- Defines a group of keywords that should be colored the same way --> + <xsd:element name="KeyWords" type="KeyWords" minOccurs="0" maxOccurs="unbounded"> + </xsd:element> + </xsd:sequence> + <!-- The name of the RuleSet. Used when you refer to the RuleSet in the rule attribute of a Span tag. + Each mode file should have a rule definition without a defined name. This denotes the default rule + set for the mode. --> + <xsd:attribute name="name" type="xsd:string" /> + <!-- Allows you to use another mode, defined in another file as a RuleSet. For an example see the + use of the JavaScript mode from the HTML-mode. --> + <xsd:attribute name="reference" type="xsd:string" /> + <!-- Defines whether case is significant for matching keywords in the mode. --> + <xsd:attribute name="ignorecase" type="xsd:boolean" /> + <!-- OBSOLETE: noescapesequences --> + <xsd:attribute name="noescapesequences" type="xsd:boolean" /> + <!-- defines the escape character --> + <xsd:attribute name="escapecharacter" type="xsd:string" /> + </xsd:complexType> + + <!-- The RuleSets tag is just a grouping of the set of RuleSets for a mode. --> + <xsd:complexType name="RuleSets"> + <xsd:sequence minOccurs="0" maxOccurs="unbounded"> + <!-- Any number of RuleSet tag can be defined in a mode --> + <xsd:element name="RuleSet" type="RuleSet" minOccurs="1" maxOccurs="unbounded"> + </xsd:element> + </xsd:sequence> + </xsd:complexType> + + <!-- SyntaxDefinition is the root-element in a mode definition file --> + <xsd:element name="SyntaxDefinition"> + <xsd:complexType> + <xsd:sequence> + <!-- The Environment tag defines colors, for various standard elements in the SharpDevelop GUI, if + not given the default values are used. --> + <xsd:element name="Environment" type="Environment" minOccurs="0" maxOccurs="1"/> + + <!-- The Properties section defines properties which are bound to the highlighting --> + <xsd:element name="Properties" type="Properties" minOccurs="0" maxOccurs="1" /> + + <!-- The Digits tag defines the color for rendering Digits--> + <xsd:element name="Digits" type="Digits" minOccurs="0" maxOccurs="1"/> + + <!-- The RuleSets tag defines the rule sets that are used in the mode. Note that all modes are defined in + a flat structture even if they are used recursively. For an example of a mode that uses + multiple rule sets see the XML-mode. There is a top level rule-set and and another rule-set + that handles highligting within a tag, i.e., between < and >. --> + <xsd:element name="RuleSets" type="RuleSets" /> + </xsd:sequence> + <!-- The name of the mode. This is used when you, in the defintion of a RuleSet refers to another + mode. I.e., one that is defined in an external file. For an example of this see the HTML-Mode that + uses the JavaScript-mode this way. --> + <xsd:attribute name="name" type="xsd:string" /> + <!-- The file extensions that the mode is applicable for. Extensions must be written with lower case and + should include the ., as in .txt. If several extensions are applicable they should be separeated with | --> + <xsd:attribute name="extensions" type="xsd:string" /> + <!-- Name of a syntax mode where rulesets, spans, keywords and other settings are imported from --> + <xsd:attribute name="extends" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + +</xsd:schema> diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/ModeV2.xsd b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/ModeV2.xsd new file mode 100644 index 000000000..047ef38a1 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/ModeV2.xsd @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8"?> +<xsd:schema version="2" elementFormDefault="qualified" targetNamespace="http://icsharpcode.net/sharpdevelop/syntaxdefinition/2008" xmlns="http://icsharpcode.net/sharpdevelop/syntaxdefinition/2008" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> + <!-- Font Weight --> + <xsd:simpleType name="FontWeight"> + <xsd:union> + <xsd:simpleType> + <xsd:restriction base="xsd:integer"> + <xsd:minInclusive value="1"/> + <xsd:maxInclusive value="999"/> + </xsd:restriction> + </xsd:simpleType> + <xsd:simpleType> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="bold"/> + <xsd:enumeration value="normal"/> + <xsd:enumeration value="regular"/> + <!-- should we support other font weight names? --> + </xsd:restriction> + </xsd:simpleType> + </xsd:union> + </xsd:simpleType> + + <!-- Font Style --> + <xsd:simpleType name="FontStyle"> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="italic"/> + <xsd:enumeration value="normal"/> + <xsd:enumeration value="oblique"/> + </xsd:restriction> + </xsd:simpleType> + + <!-- Color --> + <xsd:attributeGroup name="ColorAttributes"> + <xsd:attribute name="foreground" type="xsd:string" use="optional" /> + <xsd:attribute name="background" type="xsd:string" use="optional" /> + <xsd:attribute name="fontWeight" type="FontWeight" use="optional" /> + <xsd:attribute name="fontStyle" type="FontStyle" use="optional" /> + <xsd:anyAttribute namespace="##other" processContents="lax" /> + </xsd:attributeGroup> + + <xsd:attributeGroup name="ColorReferenceAttributes"> + <xsd:attributeGroup ref="ColorAttributes" /> + <xsd:attribute name="color" type="xsd:string" use="optional" /> + </xsd:attributeGroup> + + <xsd:element name="Color"> + <xsd:complexType> + <xsd:attribute name="name" type="xsd:string" use="required" /> + <xsd:attribute name="exampleText" type="xsd:string" use="optional" /> + <xsd:attributeGroup ref="ColorAttributes"/> + </xsd:complexType> + </xsd:element> + + <xsd:element name="Property"> + <xsd:complexType> + <xsd:attribute name="name" type="xsd:string" use="required" /> + <xsd:attribute name="value" type="xsd:string" use="required" /> + <xsd:anyAttribute namespace="##other" processContents="lax" /> + </xsd:complexType> + </xsd:element> + + <!-- Regular expression --> + <xsd:simpleType name="regex"> + <xsd:restriction base="xsd:string"/> + </xsd:simpleType> + + <xsd:simpleType name="regexIgnorePatternWhitespace"> + <xsd:restriction base="xsd:string"/> + </xsd:simpleType> + + <!-- Keywords --> + <xsd:element name="Keywords"> + <xsd:complexType> + <xsd:sequence> + <xsd:element ref="Word" minOccurs="1" maxOccurs="unbounded"/> + </xsd:sequence> + <xsd:attributeGroup ref="ColorReferenceAttributes"/> + </xsd:complexType> + </xsd:element> + + <xsd:element name="Word"> + <xsd:complexType> + <xsd:simpleContent> + <xsd:extension base="xsd:string"> + <xsd:anyAttribute namespace="##other" processContents="lax" /> + </xsd:extension> + </xsd:simpleContent> + </xsd:complexType> + </xsd:element> + + <!-- Spans --> + <xsd:element name="Span"> + <xsd:complexType> + <xsd:sequence> + <xsd:element ref="Begin" minOccurs="0" maxOccurs="1"/> + <xsd:element ref="End" minOccurs="0" maxOccurs="1"/> + <xsd:element ref="RuleSet" minOccurs="0" maxOccurs="1"/> + </xsd:sequence> + + <xsd:attributeGroup ref="ColorReferenceAttributes"/> + <xsd:attribute name="multiline" type="xsd:boolean" use="optional"/> + <xsd:attribute name="ruleSet" type="xsd:string" use="optional"/> + <xsd:attribute name="begin" type="regex" use="optional"/> + <xsd:attribute name="end" type="regex" use="optional"/> + </xsd:complexType> + </xsd:element> + + <xsd:complexType name="SpanBeginEnd"> + <xsd:simpleContent> + <xsd:extension base="regexIgnorePatternWhitespace"> + <xsd:attributeGroup ref="ColorReferenceAttributes"/> + </xsd:extension> + </xsd:simpleContent> + </xsd:complexType> + + <xsd:element name="Begin" type="SpanBeginEnd"/> + <xsd:element name="End" type="SpanBeginEnd"/> + + <!-- Imports --> + <xsd:element name="Import"> + <xsd:complexType> + <xsd:attribute name="ruleSet" type="xsd:string" use="required"/> + </xsd:complexType> + </xsd:element> + + <!-- Rules --> + <xsd:element name="Rule"> + <xsd:complexType> + <xsd:simpleContent> + <xsd:extension base="regexIgnorePatternWhitespace"> + <xsd:attributeGroup ref="ColorReferenceAttributes"/> + </xsd:extension> + </xsd:simpleContent> + </xsd:complexType> + </xsd:element> + + <!-- Rule set --> + <xsd:element name="RuleSet"> + <xsd:complexType> + <xsd:choice minOccurs="0" maxOccurs="unbounded"> + <xsd:element ref="Keywords"/> + <xsd:element ref="Span"/> + <xsd:element ref="Import"/> + <xsd:element ref="Rule"/> + <xsd:any namespace="##other" processContents="lax" /> + </xsd:choice> + <xsd:attribute name="name" type="xsd:string" use="optional" /> + <xsd:attribute name="ignoreCase" type="xsd:boolean" use="optional" /> + <xsd:anyAttribute namespace="##other" processContents="lax" /> + </xsd:complexType> + </xsd:element> + + <!-- Main syntax definition --> + <xsd:element name="SyntaxDefinition"> + <xsd:complexType> + <xsd:choice minOccurs="1" maxOccurs="unbounded"> + <xsd:element ref="Property"/> + <xsd:element ref="Color"/> + <xsd:element ref="RuleSet"/> + <xsd:any namespace="##other" processContents="lax" /> + </xsd:choice> + <xsd:attribute name="name" type="xsd:string" use="optional" /> + <xsd:attribute name="extensions" type="xsd:string" use="optional" /> + <xsd:anyAttribute namespace="##other" processContents="lax" /> + </xsd:complexType> + </xsd:element> +</xsd:schema>
\ No newline at end of file diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/PHP-Mode.xshd b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/PHP-Mode.xshd new file mode 100644 index 000000000..f09ff27d9 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/PHP-Mode.xshd @@ -0,0 +1,158 @@ +<?xml version="1.0"?> +<!-- syntaxdefinition for PHP 2001 by Chad Smith & Mike Krueger --> +<!-- converted to AvalonEdit format by Siegfried Pammer in 2010 --> +<SyntaxDefinition name ="PHP" extensions = ".php" xmlns="http://icsharpcode.net/sharpdevelop/syntaxdefinition/2008"> + <Color name="Comment" foreground="Green" exampleText="// comment" /> + <Color name="String" foreground="Blue" exampleText="$text = "Hello, World!"" /> + <Color name="NumberLiteral" foreground="DarkBlue" exampleText="3.1415" /> + <Color name="Punctuation" foreground="DarkGreen" exampleText="a(b + c)" /> + <Color name="FunctionCall" foreground="MidnightBlue" fontWeight="bold" exampleText="abs(num);"/> + <Color name="AccessKeywords" foreground="Black" fontWeight="bold" exampleText="global $database;" /> + <Color name="OperatorKeywords" foreground="DarkCyan" fontWeight="bold" exampleText="if (x === false and y === false) { }" /> + <Color name="SelectionStatements" foreground="Blue" fontWeight="bold" exampleText="if (true) { } else { }" /> + <Color name="IterationStatements" foreground="Blue" fontWeight="bold" exampleText="while (true) { }" /> + <Color name="JumpStatements" foreground="Navy" fontWeight="bold" exampleText="if (x == 5) continue;" /> + <Color name="ControlStatements" foreground="Teal" fontWeight="bold" exampleText="include("test.php");" /> + <Color name="ValueTypes" foreground="Red" fontWeight="bold" exampleText="int test = 5;" /> + <Color name="OtherTypes" foreground="Red" exampleText="object test = null;" /> + <Color name="AccessModifiers" foreground="Blue" fontWeight="bold" exampleText="public function test() {}" /> + <RuleSet> + <Span color="Comment"> + <Begin>\#</Begin> + </Span> + + <Span color="Comment"> + <Begin>//</Begin> + </Span> + + <Span color="Comment" multiline="true"> + <Begin>/\*</Begin> + <End>\*/</End> + </Span> + + <!-- Digits --> + <Rule color="NumberLiteral"> + \b0[xX][0-9a-fA-F]+ # hex number + | + \b0[0-9]+ # octal number + | + ( \b\d+(\.[0-9]+)? #number with optional floating point + | \.[0-9]+ #or just starting with floating point + ) + ([eE][+-]?[0-9]+)? # optional exponent + </Rule> + + <Rule color="Punctuation"> + [?,.:;()\[\]{}+\-/%*<>&^!|~@]+ + </Rule> + + <!-- Mark previous rule--> + <Rule color="FunctionCall"> + \b + [\d\w_]+ # an identifier + (?=\s*\() # followed by ( + </Rule> + + <Span color="String" multiline="true"> + <Begin>'</Begin> + <End>'</End> + <RuleSet> + <!-- span for escape sequences --> + <Span begin="\\" end="."/> + </RuleSet> + </Span> + + <Span color="String" multiline="true"> + <Begin>"</Begin> + <End>"</End> + <RuleSet> + <!-- span for escape sequences --> + <Span begin="\\" end="."/> + </RuleSet> + </Span> + + <!-- heredoc syntax --> + <Span color="String" multiline="true"> + <Begin><<<\"?[\d\w_]+\"?$</Begin> + <End>^[\d\w_]+;</End> + </Span> + + <!-- nowdoc syntax --> + <Span color="String" multiline="true"> + <Begin><<<\'[\d\w_]+\'$</Begin> + <End>^[\d\w_]+;</End> + </Span> + + <Keywords color="AccessKeywords"> + <Word>global</Word> + <Word>my</Word> + <Word>var</Word> + </Keywords> + + <Keywords color="OperatorKeywords"> + <Word>and</Word> + <Word>or</Word> + <Word>new</Word> + <Word>clone</Word> + <Word>instanceof</Word> + <Word>xor</Word> + <Word>true</Word> + <Word>false</Word> + </Keywords> + + <Keywords color="SelectionStatements"> + <Word>else</Word> + <Word>else</Word> + <Word>switch</Word> + <Word>case</Word> + <Word>endif</Word> + <Word>elseif</Word> + </Keywords> + + <Keywords color="IterationStatements"> + <Word>do</Word> + <Word>for</Word> + <Word>foreach</Word> + <Word>while</Word> + <Word>endwhile</Word> + <Word>exit</Word> + </Keywords> + + <Keywords color="JumpStatements"> + <Word>break</Word> + <Word>continue</Word> + <Word>default</Word> + <Word>goto</Word> + <Word>return</Word> + </Keywords> + + <Keywords color="ControlStatements"> + <Word>require</Word> + <Word>include</Word> + <Word>require</Word> + <Word>include</Word> + <Word>function</Word> + </Keywords> + + <Keywords color="ValueTypes"> + <Word>int</Word> + <Word>integer</Word> + <Word>real</Word> + <Word>double</Word> + <Word>float</Word> + <Word>string</Word> + <Word>array</Word> + <Word>object</Word> + </Keywords> + + <Keywords color="OtherTypes"> + <Word>class</Word> + <Word>void</Word> + </Keywords> + + <Keywords color="AccessModifiers"> + <Word>public</Word> + <Word>private</Word> + </Keywords> + </RuleSet> +</SyntaxDefinition> diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/Patch-Mode.xshd b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/Patch-Mode.xshd new file mode 100644 index 000000000..c8e1c3cfd --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/Patch-Mode.xshd @@ -0,0 +1,35 @@ +<?xml version="1.0"?> +<SyntaxDefinition name="Patch" extensions=".patch;.diff" xmlns="http://icsharpcode.net/sharpdevelop/syntaxdefinition/2008"> + <Color name="AddedText" foreground="Navy" exampleText="+added" /> + <Color name="RemovedText" foreground="#FF339966" exampleText="-removed" /> + <Color name="UnchangedText" exampleText=" unchanged" /> + <Color name="Position" foreground="Navy" exampleText="@@ -186,6 +186,12 @@" /> + <Color name="Header" foreground="DarkRed" exampleText="--- (oldversion) +++ (newversion)" /> + <Color name="FileName" foreground="Green" fontWeight="bold" exampleText="Index: path/to/file" /> + <RuleSet> + <Span color="FileName"> + <Begin>Index:\s</Begin> + </Span> + <Span color="Header"> + <Begin>==</Begin> + </Span> + <Span color="Header"> + <Begin>---</Begin> + </Span> + <Span color="Header"> + <Begin>\+\+\+</Begin> + </Span> + <Span foreground="Purple"> + <Begin>@@</Begin> + </Span> + <Span color="RemovedText"> + <Begin>-</Begin> + </Span> + <Span color="AddedText"> + <Begin>\+</Begin> + </Span> + <Span color="UnchangedText"> + <Begin>\s</Begin> + </Span> + </RuleSet> +</SyntaxDefinition>
\ No newline at end of file diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/PowerShell.xshd b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/PowerShell.xshd new file mode 100644 index 000000000..ee6fec4c8 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/PowerShell.xshd @@ -0,0 +1,146 @@ +<?xml version="1.0"?> +<SyntaxDefinition name="PowerShell" extensions=".ps1;.psm1;.psd1" xmlns="http://icsharpcode.net/sharpdevelop/syntaxdefinition/2008"> + <Color name="Comment" foreground="Green" exampleText="// comment" /> + <Color name="String" foreground="Blue" exampleText="string text = "Hello, World!""/> + <Color name="Char" foreground="Magenta" exampleText="char linefeed = '\n';"/> + <Color name="Punctuation" exampleText="a(b.c);" /> + <Color name="NumberLiteral" foreground="DarkBlue" exampleText="3.1415f"/> + <Color name="Keywords" fontWeight="bold" foreground="Blue" exampleText="if (a)"/> + <Color name="Variable" foreground="Maroon" exampleText="$param = 1" /> + <Color name="ExceptionKeywords" fontWeight="bold" foreground="Teal" /> + <Color name="GotoKeywords" foreground="Navy" /> + <Color name="ReferenceTypes" foreground="Red" /> + <Color name="Command" fontWeight="bold" foreground="MidnightBlue" /> + <Color name="Operators" foreground="#FF8515EA" exampleText="-eq"/> + + <RuleSet ignoreCase="true"> + <Span color="Comment"> + <Begin>\#</Begin> + </Span> + + <Span color="Comment" multiline="true"> + <Begin><\#</Begin> + <End>\#></End> + </Span> + + <Span color="String"> + <Begin>"</Begin> + <End>"</End> + <RuleSet> + <!-- span for escape sequences --> + <Span begin="\\" end="."/> + </RuleSet> + </Span> + + <Span color="Char"> + <Begin>'</Begin> + <End>'</End> + <RuleSet> + <!-- span for escape sequences --> + <Span begin="\\" end="."/> + </RuleSet> + </Span> + + <Span color="String" multiline="true"> + <Begin color="String">@"</Begin> + <End>"@</End> + <RuleSet> + <!-- span for escape sequences --> + <Span begin='""' end=""/> + </RuleSet> + </Span> + + <Keywords color="Keywords"> + <Word>while</Word> + <Word>param</Word> + <Word>end</Word> + <Word>define</Word> + <Word>else</Word> + <Word>from</Word> + <Word>foreach</Word> + <Word>var</Word> + <Word>dynamicparam</Word> + <Word>filter</Word> + <Word>dp</Word> + <Word>until</Word> + <Word>for</Word> + <Word>exit</Word> + <Word>switch</Word> + <Word>process</Word> + <Word>begin</Word> + <Word>elseif</Word> + <Word>if</Word> + <Word>in</Word> + <Word>data</Word> + <Word>class</Word> + <Word>using</Word> + <Word>function</Word> + </Keywords> + + <Keywords color="ExceptionKeywords"> + <Word>catch</Word> + <Word>finally</Word> + <Word>throw</Word> + <Word>trap</Word> + <Word>try</Word> + </Keywords> + + <Keywords color="GotoKeywords"> + <Word>break</Word> + <Word>continue</Word> + <Word>return</Word> + </Keywords> + + <Keywords color="ReferenceTypes"> + <Word>class</Word> + </Keywords> + + <Keywords color="Operators"> + <Word>-not</Word> + <Word>-band</Word> + <Word>-bor</Word> + <Word>-replace</Word> + <Word>-ireplace</Word> + <Word>-creplace</Word> + <Word>-and</Word> + <Word>-or</Word> + <Word>-is</Word> + <Word>-isnot</Word> + <Word>-as</Word> + <Word>-lt</Word> + <Word>-le</Word> + <Word>-gt</Word> + <Word>-ge</Word> + <Word>-eq</Word> + <Word>-ne</Word> + <Word>-contains</Word> + <Word>-notcontains</Word> + <Word>-like</Word> + <Word>-notlike</Word> + <Word>-match</Word> + <Word>-notmatch</Word> + </Keywords> + + <Rule color="Variable"> + \$[\d\w_]+ + </Rule> + + <Rule color="Command"> + [\w]+-[\w]+ + </Rule> + + <!-- Digits --> + <Rule color="NumberLiteral"> + \b0[xX][0-9a-fA-F]+ # hex number + | + ( \b\d+(\.[0-9]+)? #number with optional floating point + | \.[0-9]+ #or just starting with floating point + ) + ([eE][+-]?[0-9]+)? # optional exponent + </Rule> + + <Rule color="Punctuation"> + [?,.;()\[\]{}+\-/%*<>^+~!|&]+ + </Rule> + </RuleSet> +</SyntaxDefinition> diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/Resources.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/Resources.cs new file mode 100644 index 000000000..3ac838ce3 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/Resources.cs @@ -0,0 +1,48 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.IO; + +namespace Tango.Scripting.Editors.Highlighting +{ + static class Resources + { + static readonly string Prefix = typeof(Resources).FullName + "."; + + public static Stream OpenStream(string name) + { + Stream s = typeof(Resources).Assembly.GetManifestResourceStream(Prefix + name); + if (s == null) + throw new FileNotFoundException("The resource file '" + name + "' was not found."); + return s; + } + + internal static void RegisterBuiltInHighlightings(HighlightingManager.DefaultHighlightingManager hlm) + { + hlm.RegisterHighlighting("XmlDoc", null, "XmlDoc.xshd"); + hlm.RegisterHighlighting("C#", new[] { ".cs" }, "CSharp-Mode.xshd"); + + hlm.RegisterHighlighting("JavaScript", new[] { ".js" }, "JavaScript-Mode.xshd"); + hlm.RegisterHighlighting("HTML", new[] { ".htm", ".html" }, "HTML-Mode.xshd"); + hlm.RegisterHighlighting("ASP/XHTML", new[] { ".asp", ".aspx", ".asax", ".asmx", ".ascx", ".master" }, "ASPX.xshd"); + + hlm.RegisterHighlighting("Boo", new[] { ".boo" }, "Boo.xshd"); + hlm.RegisterHighlighting("Coco", new[] { ".atg" }, "Coco-Mode.xshd"); + hlm.RegisterHighlighting("CSS", new[] { ".css" }, "CSS-Mode.xshd"); + hlm.RegisterHighlighting("C++", new[] { ".c", ".h", ".cc", ".cpp" , ".hpp" }, "CPP-Mode.xshd"); + hlm.RegisterHighlighting("Java", new[] { ".java" }, "Java-Mode.xshd"); + hlm.RegisterHighlighting("Patch", new[] { ".patch", ".diff" }, "Patch-Mode.xshd"); + hlm.RegisterHighlighting("PowerShell", new[] { ".ps1", ".psm1", ".psd1" }, "PowerShell.xshd"); + hlm.RegisterHighlighting("PHP", new[] { ".php" }, "PHP-Mode.xshd"); + hlm.RegisterHighlighting("TeX", new[] { ".tex" }, "Tex-Mode.xshd"); + hlm.RegisterHighlighting("VBNET", new[] { ".vb" }, "VBNET-Mode.xshd"); + hlm.RegisterHighlighting("XML", (".xml;.xsl;.xslt;.xsd;.manifest;.config;.addin;" + + ".xshd;.wxs;.wxi;.wxl;.proj;.csproj;.vbproj;.ilproj;" + + ".booproj;.build;.xfrm;.targets;.xaml;.xpt;" + + ".xft;.map;.wsdl;.disco;.ps1xml;.nuspec").Split(';'), + "XML-Mode.xshd"); + hlm.RegisterHighlighting("MarkDown", new[] { ".md" }, "MarkDown-Mode.xshd"); + } + } +} diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/Tex-Mode.xshd b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/Tex-Mode.xshd new file mode 100644 index 000000000..91083b0ab --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/Tex-Mode.xshd @@ -0,0 +1,108 @@ +<?xml version="1.0"?> +<!-- syntaxdefinition for TeX document 2001 by Mike Krueger (gleaned from Jedit) --> + +<SyntaxDefinition name = "TeX" extensions = ".tex"> + + <Digits name = "Digits" bold = "false" italic = "false" color = "Black"/> + + <RuleSets> + <RuleSet ignorecase = "false"> + <Delimiters>&~!@%^*()-+=|\#/{}[]:;"'<> , .?</Delimiters> + + <Span name = "LineComment" bold = "false" italic = "true" color = "SlateGray" stopateol = "true"> + <Begin>%</Begin> + </Span> + + <Span name = "MathMode" rule = "MathMode" bold = "false" italic = "false" color = "Black" stopateol = "false"> + <Begin>$$</Begin> + <End>$$</End> + </Span> + <Span name = "LatexMathMode" rule = "MathMode" bold = "false" italic = "false" color = "Black" stopateol = "false"> + <Begin>\[</Begin> + <End>\]</End> + </Span> + + <!-- \... commands --> + <MarkFollowing markmarker ="true" bold = "true" italic = "false" color = "MidnightBlue">\</MarkFollowing> + + <!-- some commands must be handled specially --> + <KeyWords name = "Keyword1" bold = "false" italic = "false" color = "Blue"> + <Key word = "\$" /> + <Key word = "\\" /> + <Key word = "\%" /> + </KeyWords> + + <KeyWords name = "KeyWords2" bold="true" italic="false" color="Green"> + <Key word = ")" /> + <Key word = ")" /> + <Key word = "{" /> + <Key word = "}" /> + <Key word = "[" /> + <Key word = "]" /> + <Key word = "=" /> + <Key word = "!" /> + <Key word = "+" /> + <Key word = "-" /> + <Key word = "/" /> + <Key word = "*" /> + <Key word = ">" /> + <Key word = "<" /> + <Key word = "&" /> + <Key word = "|" /> + <Key word = "^" /> + <Key word = "~" /> + <Key word = "." /> + <Key word = "," /> + <Key word = ";" /> + <Key word = "?" /> + <Key word = ":" /> + <Key word = "'" /> + <!-- <Key word = """ />--> + <Key word = "`" /> + </KeyWords> + </RuleSet> + + <RuleSet name = "MathMode" ignorecase = "false"> + <Delimiters>&~!@%^*()-+=|\#/{}[]:;"'<> , .?</Delimiters> + + + <Span name = "LineComment" bold = "false" italic = "true" color = "SlateGray" stopateol = "true"> + <Begin>%</Begin> + </Span> + + <!-- \... commands --> + <MarkFollowing markmarker ="true" bold = "true" italic = "false" color = "MidnightBlue">\</MarkFollowing> + + <KeyWords name = "KeyWords2" bold="true" italic="false" color="Green"> + <Key word = ")" /> + <Key word = ")" /> + <Key word = "{" /> + <Key word = "}" /> + <Key word = "[" /> + <Key word = "]" /> + <Key word = "=" /> + <Key word = "!" /> + <Key word = "+" /> + <Key word = "-" /> + <Key word = "/" /> + <Key word = "*" /> + <Key word = ">" /> + <Key word = "<" /> + <Key word = "&" /> + <Key word = "|" /> + <Key word = "^" /> + <Key word = "~" /> + <Key word = "." /> + <Key word = "," /> + <Key word = ";" /> + <Key word = "?" /> + <Key word = ":" /> + <Key word = "'" /> + <!-- <Key word = """ />--> + <Key word = "`" /> + </KeyWords> + </RuleSet> + </RuleSets> + +</SyntaxDefinition> + diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/VBNET-Mode.xshd b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/VBNET-Mode.xshd new file mode 100644 index 000000000..b22555a29 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/VBNET-Mode.xshd @@ -0,0 +1,256 @@ +<?xml version="1.0"?> + +<!-- Syntaxdefinition for VB.NET, v0.1 Rev 1 by Christian Holm --> +<!-- Updated 2005 by Daniel Grunwald for VB.NET 2.0 --> +<!-- Converted to AvalonEdit format by Daniel Grunwald in 2010 --> +<!-- Updated 2010 by Siegfried Oleg Pammer for VB.NET 9 and 10 --> +<!-- Updated 2011 by Siegfried Oleg Pammer for VB 11 CTP --> +<SyntaxDefinition name="VBNET" extensions=".vb" xmlns="http://icsharpcode.net/sharpdevelop/syntaxdefinition/2008"> + <Color name="Comment" foreground="Green" exampleText="' comment" /> + <Color name="String" exampleText="text = "Hello, World!"" /> + + <Color name="DateLiteral" foreground="Blue" exampleText="endOfWorld = #2012-12-21#" /> + <Color name="Preprocessor" foreground="Maroon" exampleText="#Region "Title"" /> + <Color name="DataTypes" foreground="#FF6F002F" exampleText="Dim b As Boolean = True" /> + <Color name="Operators" foreground="#FF8515EA" exampleText="If a OrElse b Then"/> + <Color name="Constants" foreground="Blue" exampleText="b = False" /> + <Color name="Keywords" foreground="Blue" exampleText="If a OrElse b Then" /> + <Color name="FunctionKeywords" foreground="Blue" exampleText="CInt(a)" /> + <Color name="ContextKeywords" foreground="Blue" exampleText="Declare Unicode Sub SomeMethod" /> + + <Property name="DocCommentMarker" value="'''" /> + + <RuleSet ignoreCase="true"> + <Span color="String"> + <Begin>"</Begin> + <End>"</End> + <RuleSet> + <Span begin="""" end="" /> + </RuleSet> + </Span> + <Span color="Preprocessor" ruleSet="PreprocessorSet"> + <Begin>(?<=(^\s*))\#</Begin> + </Span> + <Span color="DateLiteral"> + <Begin>(?<!(^\s*))\#</Begin> + <End>\#</End> + </Span> + <Span color="Comment" ruleSet="XmlDoc/DocCommentSet"> + <Begin color="XmlDoc/DocComment">'''</Begin> + </Span> + <Span color="Comment"> + <Begin>'</Begin> + </Span> + <Span color="Comment"> + <Begin>\bREM\b</Begin> + </Span> + <Keywords color="DataTypes"> + <Word>Boolean</Word> + <Word>Byte</Word> + <Word>Char</Word> + <Word>Date</Word> + <Word>Decimal</Word> + <Word>Double</Word> + <Word>Integer</Word> + <Word>Long</Word> + <Word>Object</Word> + <Word>SByte</Word> + <Word>Short</Word> + <Word>Single</Word> + <Word>String</Word> + <Word>UInteger</Word> + <Word>ULong</Word> + <Word>UShort</Word> + <Word>Variant</Word> + </Keywords> + <Keywords color="Operators"> + <Word>AddressOf</Word> + <Word>And</Word> + <Word>AndAlso</Word> + <Word>Await</Word> + <Word>Is</Word> + <Word>IsNot</Word> + <Word>Like</Word> + <Word>Mod</Word> + <Word>New</Word> + <Word>Not</Word> + <Word>Or</Word> + <Word>OrElse</Word> + <Word>Xor</Word> + </Keywords> + <Keywords color="Constants"> + <Word>False</Word> + <Word>Me</Word> + <Word>MyBase</Word> + <Word>MyClass</Word> + <Word>Nothing</Word> + <Word>True</Word> + </Keywords> + <Keywords color="FunctionKeywords"> + <Word>CBool</Word> + <Word>CByte</Word> + <Word>CChar</Word> + <Word>CDate</Word> + <Word>CDbl</Word> + <Word>CDec</Word> + <Word>CInt</Word> + <Word>CLng</Word> + <Word>CObj</Word> + <Word>CSByte</Word> + <Word>CShort</Word> + <Word>CSng</Word> + <Word>CStr</Word> + <Word>CType</Word> + <Word>CUInt</Word> + <Word>CULng</Word> + <Word>CUShort</Word> + <Word>DirectCast</Word> + <Word>GetType</Word> + <Word>GetXmlNamespace</Word> + <Word>IIf</Word> + <Word>TryCast</Word> + <Word>TypeOf</Word> + </Keywords> + <Keywords color="Keywords"> + <Word>AddHandler</Word> + <Word>Alias</Word> + <Word>As</Word> + <Word>ByRef</Word> + <Word>ByVal</Word> + <Word>Call</Word> + <Word>Case</Word> + <Word>Catch</Word> + <Word>Class</Word> + <Word>Const</Word> + <Word>Continue</Word> + <Word>Declare</Word> + <Word>Default</Word> + <Word>Delegate</Word> + <Word>Dim</Word> + <Word>Do</Word> + <Word>Each</Word> + <Word>Else</Word> + <Word>ElseIf</Word> + <Word>End</Word> + <Word>EndIf</Word> + <Word>Enum</Word> + <Word>Erase</Word> + <Word>Error</Word> + <Word>Event</Word> + <Word>Exit</Word> + <Word>Finally</Word> + <Word>For</Word> + <Word>Friend</Word> + <Word>Function</Word> + <Word>Get</Word> + <Word>Global</Word> + <Word>GoSub</Word> + <Word>GoTo</Word> + <Word>Handles</Word> + <Word>If</Word> + <Word>Implements</Word> + <Word>Imports</Word> + <Word>In</Word> + <Word>Inherits</Word> + <Word>Interface</Word> + <Word>Let</Word> + <Word>Lib</Word> + <Word>Loop</Word> + <Word>Module</Word> + <Word>MustInherit</Word> + <Word>MustOverride</Word> + <Word>Namespace</Word> + <Word>Narrowing</Word> + <Word>New</Word> + <Word>Next</Word> + <Word>NotInheritable</Word> + <Word>NotOverridable</Word> + <Word>Of</Word> + <Word>On</Word> + <Word>Operator</Word> + <Word>Option</Word> + <Word>Optional</Word> + <Word>Overloads</Word> + <Word>Overridable</Word> + <Word>Overrides</Word> + <Word>ParamArray</Word> + <Word>Partial</Word> + <Word>Private</Word> + <Word>Property</Word> + <Word>Protected</Word> + <Word>Public</Word> + <Word>RaiseEvent</Word> + <Word>ReadOnly</Word> + <Word>ReDim</Word> + <Word>RemoveHandler</Word> + <Word>Resume</Word> + <Word>Return</Word> + <Word>Select</Word> + <Word>Set</Word> + <Word>Shadows</Word> + <Word>Shared</Word> + <Word>Static</Word> + <Word>Step</Word> + <Word>Stop</Word> + <Word>Structure</Word> + <Word>Sub</Word> + <Word>SyncLock</Word> + <Word>Then</Word> + <Word>Throw</Word> + <Word>To</Word> + <Word>Try</Word> + <Word>Using</Word> + <Word>Wend</Word> + <Word>When</Word> + <Word>While</Word> + <Word>Widening</Word> + <Word>With</Word> + <Word>WithEvents</Word> + <Word>WriteOnly</Word> + </Keywords> + <Keywords color="ContextKeywords"> + <Word>Aggregate</Word> + <Word>Ansi</Word> + <Word>Ascending</Word> + <Word>Async</Word> + <Word>Auto</Word> + <Word>Binary</Word> + <Word>By</Word> + <Word>Compare</Word> + <Word>Custom</Word> + <Word>Descending</Word> + <Word>Distinct</Word> + <Word>Equals</Word> + <Word>Explicit</Word> + <Word>From</Word> + <Word>Group</Word> + <Word>Infer</Word> + <Word>Into</Word> + <Word>Iterator</Word> + <Word>Join</Word> + <Word>Key</Word> + <Word>Off</Word> + <Word>Preserve</Word> + <Word>Skip</Word> + <Word>Strict</Word> + <Word>Take</Word> + <Word>Text</Word> + <Word>Unicode</Word> + <Word>Until</Word> + <Word>Where</Word> + <Word>Yield</Word> + </Keywords> + </RuleSet> + <RuleSet name="PreprocessorSet" ignoreCase="true"> + <Keywords fontWeight="bold"> + <Word>Const</Word> + <Word>Else</Word> + <Word>ElseIf</Word> + <Word>End</Word> + <Word>ExternalChecksum</Word> + <Word>ExternalSource</Word> + <Word>If</Word> + <Word>Region</Word> + </Keywords> + </RuleSet> +</SyntaxDefinition>
\ No newline at end of file diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/XML-Mode.xshd b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/XML-Mode.xshd new file mode 100644 index 000000000..8f0bdef76 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/XML-Mode.xshd @@ -0,0 +1,63 @@ +<SyntaxDefinition name="XML" extensions=".xml;.xsl;.xslt;.xsd;.manifest;.config;.addin;.xshd;.wxs;.wxi;.wxl;.proj;.csproj;.vbproj;.ilproj;.booproj;.build;.xfrm;.targets;.xaml;.xpt;.xft;.map;.wsdl;.disco;.ps1xml;.nuspec" xmlns="http://icsharpcode.net/sharpdevelop/syntaxdefinition/2008"> + <Color foreground="Green" name="Comment" exampleText="<!-- comment -->" /> + <Color foreground="Blue" name="CData" exampleText="<![CDATA[data]]>" /> + <Color foreground="Blue" name="DocType" exampleText="<!DOCTYPE rootElement>" /> + <Color foreground="Blue" name="XmlDeclaration" exampleText='<?xml version="1.0"?>' /> + <Color foreground="DarkMagenta" name="XmlTag" exampleText='<tag attribute="value" />' /> + <Color foreground="Red" name="AttributeName" exampleText='<tag attribute="value" />' /> + <Color foreground="Blue" name="AttributeValue" exampleText='<tag attribute="value" />' /> + <Color foreground="Teal" name="Entity" exampleText="index.aspx?a=1&amp;b=2" /> + <Color foreground="Olive" name="BrokenEntity" exampleText="index.aspx?a=1&b=2" /> + + <RuleSet> + <Span color="Comment" multiline="true"> + <Begin><!--</Begin> + <End>--></End> + </Span> + <Span color="CData" multiline="true"> + <Begin><!\[CDATA\[</Begin> + <End>]]></End> + </Span> + <Span color="DocType" multiline="true"> + <Begin><!DOCTYPE</Begin> + <End>></End> + </Span> + <Span color="XmlDeclaration" multiline="true"> + <Begin><\?</Begin> + <End>\?></End> + </Span> + <Span color="XmlTag" multiline="true"> + <Begin><</Begin> + <End>></End> + <RuleSet> + <!-- Treat the position before '<' as end, as that's not a valid character + in attribute names and indicates the user forgot a closing quote. --> + <Span color="AttributeValue" multiline="true" ruleSet="EntitySet"> + <Begin>"</Begin> + <End>"|(?=<)</End> + </Span> + <Span color="AttributeValue" multiline="true" ruleSet="EntitySet"> + <Begin>'</Begin> + <End>'|(?=<)</End> + </Span> + <Rule color="AttributeName">[\d\w_\-\.]+(?=(\s*=))</Rule> + <Rule color="AttributeValue">=</Rule> + </RuleSet> + </Span> + <Import ruleSet="EntitySet"/> + </RuleSet> + + <RuleSet name="EntitySet"> + <Rule color="Entity"> + & + [\w\d\#]+ + ; + </Rule> + + <Rule color="BrokenEntity"> + & + [\w\d\#]* + #missing ; + </Rule> + </RuleSet> +</SyntaxDefinition>
\ No newline at end of file diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/XmlDoc.xshd b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/XmlDoc.xshd new file mode 100644 index 000000000..e4303de6a --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/XmlDoc.xshd @@ -0,0 +1,57 @@ +<?xml version="1.0"?> +<SyntaxDefinition name="XmlDoc" xmlns="http://icsharpcode.net/sharpdevelop/syntaxdefinition/2008"> + <Color name="XmlString" foreground="Silver" fontWeight="bold" exampleText="${DocCommentMarker} <exception cref="System.Exception" />" /> + <Color name="DocComment" foreground="Gray" exampleText="${DocCommentMarker} <exception cref="System.Exception" />" /> + <Color name="XmlPunctuation" fontWeight="bold" exampleText="${DocCommentMarker} <exception cref="System.Exception" />" /> + <Color name="KnownDocTags" fontWeight="bold" exampleText="${DocCommentMarker} <exception cref="System.Exception" />" /> + + <RuleSet name="DocCommentSet"> + <Span color="DocComment"> + <Begin><</Begin> + <End>></End> + <RuleSet> + <Span color="XmlString"> + <Begin>"</Begin> + <End>"</End> + </Span> + <Keywords color="XmlPunctuation"> + <Word>/</Word> + <Word>|</Word> + <Word>=</Word> + </Keywords> + <Keywords color="KnownDocTags"> + <Word>c</Word> + <Word>code</Word> + <Word>example</Word> + <Word>exception</Word> + <Word>list</Word> + <Word>para</Word> + <Word>param</Word> + <Word>paramref</Word> + <Word>permission</Word> + <Word>remarks</Word> + <Word>returns</Word> + <Word>see</Word> + <Word>seealso</Word> + <Word>summary</Word> + <Word>value</Word> + + <Word>type</Word> + <Word>name</Word> + <Word>cref</Word> + <Word>item</Word> + <Word>term</Word> + <Word>description</Word> + <Word>listheader</Word> + <Word>typeparam</Word> + <Word>typeparamref</Word> + </Keywords> + </RuleSet> + </Span> + </RuleSet> + + <!-- root ruleset = DocCommentSet --> + <RuleSet> + <Import ruleSet="DocCommentSet" /> + </RuleSet> +</SyntaxDefinition>
\ No newline at end of file diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/HighlightingLoader.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/HighlightingLoader.cs new file mode 100644 index 000000000..f1d0d8554 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/HighlightingLoader.cs @@ -0,0 +1,99 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Xml; +using System.Xml.Schema; + +namespace Tango.Scripting.Editors.Highlighting.Xshd +{ + /// <summary> + /// Static class with helper methods to load XSHD highlighting files. + /// </summary> + public static class HighlightingLoader + { + #region XSHD loading + /// <summary> + /// Lodas a syntax definition from the xml reader. + /// </summary> + public static XshdSyntaxDefinition LoadXshd(XmlReader reader) + { + return LoadXshd(reader, false); + } + + internal static XshdSyntaxDefinition LoadXshd(XmlReader reader, bool skipValidation) + { + if (reader == null) + throw new ArgumentNullException("reader"); + try { + reader.MoveToContent(); + if (reader.NamespaceURI == V2Loader.Namespace) { + return V2Loader.LoadDefinition(reader, skipValidation); + } else { + return V1Loader.LoadDefinition(reader, skipValidation); + } + } catch (XmlSchemaException ex) { + throw WrapException(ex, ex.LineNumber, ex.LinePosition); + } catch (XmlException ex) { + throw WrapException(ex, ex.LineNumber, ex.LinePosition); + } + } + + static Exception WrapException(Exception ex, int lineNumber, int linePosition) + { + return new HighlightingDefinitionInvalidException(FormatExceptionMessage(ex.Message, lineNumber, linePosition), ex); + } + + internal static string FormatExceptionMessage(string message, int lineNumber, int linePosition) + { + if (lineNumber <= 0) + return message; + else + return "Error at position (line " + lineNumber + ", column " + linePosition + "):\n" + message; + } + + internal static XmlReader GetValidatingReader(XmlReader input, bool ignoreWhitespace, XmlSchemaSet schemaSet) + { + XmlReaderSettings settings = new XmlReaderSettings(); + settings.CloseInput = true; + settings.IgnoreComments = true; + settings.IgnoreWhitespace = ignoreWhitespace; + if (schemaSet != null) { + settings.Schemas = schemaSet; + settings.ValidationType = ValidationType.Schema; + } + return XmlReader.Create(input, settings); + } + + internal static XmlSchemaSet LoadSchemaSet(XmlReader schemaInput) + { + XmlSchemaSet schemaSet = new XmlSchemaSet(); + schemaSet.Add(null, schemaInput); + schemaSet.ValidationEventHandler += delegate(object sender, ValidationEventArgs args) { + throw new HighlightingDefinitionInvalidException(args.Message); + }; + return schemaSet; + } + #endregion + + #region Load Highlighting from XSHD + /// <summary> + /// Creates a highlighting definition from the XSHD file. + /// </summary> + public static IHighlightingDefinition Load(XshdSyntaxDefinition syntaxDefinition, IHighlightingDefinitionReferenceResolver resolver) + { + if (syntaxDefinition == null) + throw new ArgumentNullException("syntaxDefinition"); + return new XmlHighlightingDefinition(syntaxDefinition, resolver); + } + + /// <summary> + /// Creates a highlighting definition from the XSHD file. + /// </summary> + public static IHighlightingDefinition Load(XmlReader reader, IHighlightingDefinitionReferenceResolver resolver) + { + return Load(LoadXshd(reader), resolver); + } + #endregion + } +} diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/IXshdVisitor.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/IXshdVisitor.cs new file mode 100644 index 000000000..f328a32d3 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/IXshdVisitor.cs @@ -0,0 +1,32 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; + +namespace Tango.Scripting.Editors.Highlighting.Xshd +{ + /// <summary> + /// A visitor over the XSHD element tree. + /// </summary> + public interface IXshdVisitor + { + /// <summary/> + object VisitRuleSet(XshdRuleSet ruleSet); + + /// <summary/> + object VisitColor(XshdColor color); + + /// <summary/> + object VisitKeywords(XshdKeywords keywords); + + /// <summary/> + object VisitSpan(XshdSpan span); + + /// <summary/> + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", Justification = "A VB programmer implementing a visitor?")] + object VisitImport(XshdImport import); + + /// <summary/> + object VisitRule(XshdRule rule); + } +} diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/SaveXshdVisitor.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/SaveXshdVisitor.cs new file mode 100644 index 000000000..e158954f1 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/SaveXshdVisitor.cs @@ -0,0 +1,182 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Linq; +using System.Xml; + +namespace Tango.Scripting.Editors.Highlighting.Xshd +{ + /// <summary> + /// Xshd visitor implementation that saves an .xshd file as XML. + /// </summary> + public sealed class SaveXshdVisitor : IXshdVisitor + { + /// <summary> + /// XML namespace for XSHD. + /// </summary> + public const string Namespace = V2Loader.Namespace; + + XmlWriter writer; + + /// <summary> + /// Creates a new SaveXshdVisitor instance. + /// </summary> + public SaveXshdVisitor(XmlWriter writer) + { + if (writer == null) + throw new ArgumentNullException("writer"); + this.writer = writer; + } + + /// <summary> + /// Writes the specified syntax definition. + /// </summary> + public void WriteDefinition(XshdSyntaxDefinition definition) + { + if (definition == null) + throw new ArgumentNullException("definition"); + writer.WriteStartElement("SyntaxDefinition", Namespace); + if (definition.Name != null) + writer.WriteAttributeString("name", definition.Name); + if (definition.Extensions != null) + writer.WriteAttributeString("extensions", string.Join(";", definition.Extensions.ToArray())); + + definition.AcceptElements(this); + + writer.WriteEndElement(); + } + + object IXshdVisitor.VisitRuleSet(XshdRuleSet ruleSet) + { + writer.WriteStartElement("RuleSet", Namespace); + + if (ruleSet.Name != null) + writer.WriteAttributeString("name", ruleSet.Name); + WriteBoolAttribute("ignoreCase", ruleSet.IgnoreCase); + + ruleSet.AcceptElements(this); + + writer.WriteEndElement(); + return null; + } + + void WriteBoolAttribute(string attributeName, bool? value) + { + if (value != null) { + writer.WriteAttributeString(attributeName, value.Value ? "true" : "false"); + } + } + + void WriteRuleSetReference(XshdReference<XshdRuleSet> ruleSetReference) + { + if (ruleSetReference.ReferencedElement != null) { + if (ruleSetReference.ReferencedDefinition != null) + writer.WriteAttributeString("ruleSet", ruleSetReference.ReferencedDefinition + "/" + ruleSetReference.ReferencedElement); + else + writer.WriteAttributeString("ruleSet", ruleSetReference.ReferencedElement); + } + } + + void WriteColorReference(XshdReference<XshdColor> color) + { + if (color.InlineElement != null) { + WriteColorAttributes(color.InlineElement); + } else if (color.ReferencedElement != null) { + if (color.ReferencedDefinition != null) + writer.WriteAttributeString("color", color.ReferencedDefinition + "/" + color.ReferencedElement); + else + writer.WriteAttributeString("color", color.ReferencedElement); + } + } + + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase", Justification = "The file format requires lowercase, and all possible values are English-only")] + void WriteColorAttributes(XshdColor color) + { + if (color.Foreground != null) + writer.WriteAttributeString("foreground", color.Foreground.ToString()); + if (color.Background != null) + writer.WriteAttributeString("background", color.Background.ToString()); + if (color.FontWeight != null) + writer.WriteAttributeString("fontWeight", V2Loader.FontWeightConverter.ConvertToInvariantString(color.FontWeight.Value).ToLowerInvariant()); + if (color.FontStyle != null) + writer.WriteAttributeString("fontStyle", V2Loader.FontStyleConverter.ConvertToInvariantString(color.FontStyle.Value).ToLowerInvariant()); + } + + object IXshdVisitor.VisitColor(XshdColor color) + { + writer.WriteStartElement("Color", Namespace); + if (color.Name != null) + writer.WriteAttributeString("name", color.Name); + WriteColorAttributes(color); + if (color.ExampleText != null) + writer.WriteAttributeString("exampleText", color.ExampleText); + writer.WriteEndElement(); + return null; + } + + object IXshdVisitor.VisitKeywords(XshdKeywords keywords) + { + writer.WriteStartElement("Keywords", Namespace); + WriteColorReference(keywords.ColorReference); + foreach (string word in keywords.Words) { + writer.WriteElementString("Word", Namespace, word); + } + writer.WriteEndElement(); + return null; + } + + object IXshdVisitor.VisitSpan(XshdSpan span) + { + writer.WriteStartElement("Span", Namespace); + WriteColorReference(span.SpanColorReference); + if (span.BeginRegexType == XshdRegexType.Default && span.BeginRegex != null) + writer.WriteAttributeString("begin", span.BeginRegex); + if (span.EndRegexType == XshdRegexType.Default && span.EndRegex != null) + writer.WriteAttributeString("end", span.EndRegex); + WriteRuleSetReference(span.RuleSetReference); + if (span.Multiline) + writer.WriteAttributeString("multiline", "true"); + + if (span.BeginRegexType == XshdRegexType.IgnorePatternWhitespace) + WriteBeginEndElement("Begin", span.BeginRegex, span.BeginColorReference); + if (span.EndRegexType == XshdRegexType.IgnorePatternWhitespace) + WriteBeginEndElement("End", span.EndRegex, span.EndColorReference); + + if (span.RuleSetReference.InlineElement != null) + span.RuleSetReference.InlineElement.AcceptVisitor(this); + + writer.WriteEndElement(); + return null; + } + + void WriteBeginEndElement(string elementName, string regex, XshdReference<XshdColor> colorReference) + { + if (regex != null) { + writer.WriteStartElement(elementName, Namespace); + WriteColorReference(colorReference); + writer.WriteString(regex); + writer.WriteEndElement(); + } + } + + object IXshdVisitor.VisitImport(XshdImport import) + { + writer.WriteStartElement("Import", Namespace); + WriteRuleSetReference(import.RuleSetReference); + writer.WriteEndElement(); + return null; + } + + object IXshdVisitor.VisitRule(XshdRule rule) + { + writer.WriteStartElement("Rule", Namespace); + WriteColorReference(rule.ColorReference); + + writer.WriteString(rule.Regex); + + writer.WriteEndElement(); + return null; + } + } +} diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/V1Loader.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/V1Loader.cs new file mode 100644 index 000000000..f3caa7eda --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/V1Loader.cs @@ -0,0 +1,325 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Globalization; +using System.Text; +using System.Text.RegularExpressions; +using System.Windows; +using System.Windows.Media; +using System.Xml; +using System.Xml.Schema; + +using Tango.Scripting.Editors.Utils; + +namespace Tango.Scripting.Editors.Highlighting.Xshd +{ + /// <summary> + /// Loads .xshd files, version 1.0. + /// </summary> + sealed class V1Loader + { + static XmlSchemaSet schemaSet; + + static XmlSchemaSet SchemaSet { + get { + if (schemaSet == null) { + schemaSet = HighlightingLoader.LoadSchemaSet(new XmlTextReader( + Resources.OpenStream("ModeV1.xsd"))); + } + return schemaSet; + } + } + + public static XshdSyntaxDefinition LoadDefinition(XmlReader reader, bool skipValidation) + { + reader = HighlightingLoader.GetValidatingReader(reader, false, skipValidation ? null : SchemaSet); + XmlDocument document = new XmlDocument(); + document.Load(reader); + V1Loader loader = new V1Loader(); + return loader.ParseDefinition(document.DocumentElement); + } + + XshdSyntaxDefinition ParseDefinition(XmlElement syntaxDefinition) + { + XshdSyntaxDefinition def = new XshdSyntaxDefinition(); + def.Name = syntaxDefinition.GetAttributeOrNull("name"); + if (syntaxDefinition.HasAttribute("extensions")) { + def.Extensions.AddRange(syntaxDefinition.GetAttribute("extensions").Split(';', '|')); + } + + XshdRuleSet mainRuleSetElement = null; + foreach (XmlElement element in syntaxDefinition.GetElementsByTagName("RuleSet")) { + XshdRuleSet ruleSet = ImportRuleSet(element); + def.Elements.Add(ruleSet); + if (ruleSet.Name == null) + mainRuleSetElement = ruleSet; + + if (syntaxDefinition["Digits"] != null) { + // create digit highlighting rule + + const string optionalExponent = @"([eE][+-]?[0-9]+)?"; + const string floatingPoint = @"\.[0-9]+"; + ruleSet.Elements.Add( + new XshdRule { + ColorReference = GetColorReference(syntaxDefinition["Digits"]), + RegexType = XshdRegexType.IgnorePatternWhitespace, + Regex = @"\b0[xX][0-9a-fA-F]+" + + @"|" + + @"(\b\d+(" + floatingPoint + ")?" + + @"|" + floatingPoint + ")" + + optionalExponent + }); + } + } + + if (syntaxDefinition.HasAttribute("extends") && mainRuleSetElement != null) { + // convert 'extends="HTML"' to '<Import ruleSet="HTML/" />' in main rule set. + mainRuleSetElement.Elements.Add( + new XshdImport { RuleSetReference = new XshdReference<XshdRuleSet>( + syntaxDefinition.GetAttribute("extends"), string.Empty + ) }); + } + return def; + } + + static XshdColor GetColorFromElement(XmlElement element) + { + if (!element.HasAttribute("bold") && !element.HasAttribute("italic") && !element.HasAttribute("color") && !element.HasAttribute("bgcolor")) + return null; + XshdColor color = new XshdColor(); + if (element.HasAttribute("bold")) + color.FontWeight = XmlConvert.ToBoolean(element.GetAttribute("bold")) ? FontWeights.Bold : FontWeights.Normal; + if (element.HasAttribute("italic")) + color.FontStyle = XmlConvert.ToBoolean(element.GetAttribute("italic")) ? FontStyles.Italic : FontStyles.Normal; + if (element.HasAttribute("color")) + color.Foreground = ParseColor(element.GetAttribute("color")); + if (element.HasAttribute("bgcolor")) + color.Background = ParseColor(element.GetAttribute("bgcolor")); + return color; + } + + static XshdReference<XshdColor> GetColorReference(XmlElement element) + { + XshdColor color = GetColorFromElement(element); + if (color != null) + return new XshdReference<XshdColor>(color); + else + return new XshdReference<XshdColor>(); + } + + static HighlightingBrush ParseColor(string c) + { + if (c.StartsWith("#", StringComparison.Ordinal)) { + int a = 255; + int offset = 0; + if (c.Length > 7) { + offset = 2; + a = Int32.Parse(c.Substring(1,2), NumberStyles.HexNumber, CultureInfo.InvariantCulture); + } + + int r = Int32.Parse(c.Substring(1 + offset,2), NumberStyles.HexNumber, CultureInfo.InvariantCulture); + int g = Int32.Parse(c.Substring(3 + offset,2), NumberStyles.HexNumber, CultureInfo.InvariantCulture); + int b = Int32.Parse(c.Substring(5 + offset,2), NumberStyles.HexNumber, CultureInfo.InvariantCulture); + return new SimpleHighlightingBrush(Color.FromArgb((byte)a, (byte)r, (byte)g, (byte)b)); + } else if (c.StartsWith("SystemColors.", StringComparison.Ordinal)) { + return V2Loader.GetSystemColorBrush(null, c); + } else { + return new SimpleHighlightingBrush((Color)V2Loader.ColorConverter.ConvertFromInvariantString(c)); + } + } + + char ruleSetEscapeCharacter; + + XshdRuleSet ImportRuleSet(XmlElement element) + { + XshdRuleSet ruleSet = new XshdRuleSet(); + ruleSet.Name = element.GetAttributeOrNull("name"); + + if (element.HasAttribute("escapecharacter")) { + ruleSetEscapeCharacter = element.GetAttribute("escapecharacter")[0]; + } else { + ruleSetEscapeCharacter = '\0'; + } + + if (element.HasAttribute("reference")) { + ruleSet.Elements.Add( + new XshdImport { RuleSetReference = new XshdReference<XshdRuleSet>( + element.GetAttribute("reference"), string.Empty + ) }); + } + ruleSet.IgnoreCase = element.GetBoolAttribute("ignorecase"); + + foreach (XmlElement el in element.GetElementsByTagName("KeyWords")) { + XshdKeywords keywords = new XshdKeywords(); + keywords.ColorReference = GetColorReference(el); + // we have to handle old syntax highlighting definitions that contain + // empty keywords or empty keyword groups + foreach (XmlElement node in el.GetElementsByTagName("Key")) { + string word = node.GetAttribute("word"); + if (!string.IsNullOrEmpty(word)) + keywords.Words.Add(word); + } + if (keywords.Words.Count > 0) { + ruleSet.Elements.Add(keywords); + } + } + + foreach (XmlElement el in element.GetElementsByTagName("Span")) { + ruleSet.Elements.Add(ImportSpan(el)); + } + + foreach (XmlElement el in element.GetElementsByTagName("MarkPrevious")) { + ruleSet.Elements.Add(ImportMarkPrevNext(el, false)); + } + foreach (XmlElement el in element.GetElementsByTagName("MarkFollowing")) { + ruleSet.Elements.Add(ImportMarkPrevNext(el, true)); + } + + return ruleSet; + } + + static XshdRule ImportMarkPrevNext(XmlElement el, bool markFollowing) + { + bool markMarker = el.GetBoolAttribute("markmarker") ?? false; + string what = Regex.Escape(el.InnerText); + const string identifier = @"[\d\w_]+"; + const string whitespace = @"\s*"; + + string regex; + if (markFollowing) { + if (markMarker) { + regex = what + whitespace + identifier; + } else { + regex = "(?<=(" + what + whitespace + "))" + identifier; + } + } else { + if (markMarker) { + regex = identifier + whitespace + what; + } else { + regex = identifier + "(?=(" + whitespace + what + "))"; + } + } + return new XshdRule { + ColorReference = GetColorReference(el), + Regex = regex, + RegexType = XshdRegexType.IgnorePatternWhitespace + }; + } + + XshdSpan ImportSpan(XmlElement element) + { + XshdSpan span = new XshdSpan(); + if (element.HasAttribute("rule")) { + span.RuleSetReference = new XshdReference<XshdRuleSet>(null, element.GetAttribute("rule")); + } + char escapeCharacter = ruleSetEscapeCharacter; + if (element.HasAttribute("escapecharacter")) { + escapeCharacter = element.GetAttribute("escapecharacter")[0]; + } + span.Multiline = !(element.GetBoolAttribute("stopateol") ?? false); + + span.SpanColorReference = GetColorReference(element); + + span.BeginRegexType = XshdRegexType.IgnorePatternWhitespace; + span.BeginRegex = ImportRegex(element["Begin"].InnerText, + element["Begin"].GetBoolAttribute("singleword") ?? false, + element["Begin"].GetBoolAttribute("startofline")); + span.BeginColorReference = GetColorReference(element["Begin"]); + + string endElementText = string.Empty; + if (element["End"] != null) { + span.EndRegexType = XshdRegexType.IgnorePatternWhitespace; + endElementText = element["End"].InnerText; + span.EndRegex = ImportRegex(endElementText, + element["End"].GetBoolAttribute("singleword") ?? false, + null); + span.EndColorReference = GetColorReference(element["End"]); + } + + if (escapeCharacter != '\0') { + XshdRuleSet ruleSet = new XshdRuleSet(); + if (endElementText.Length == 1 && endElementText[0] == escapeCharacter) { + // ""-style escape + ruleSet.Elements.Add(new XshdSpan { + BeginRegex = Regex.Escape(endElementText + endElementText), + EndRegex = "" + }); + } else { + // \"-style escape + ruleSet.Elements.Add(new XshdSpan { + BeginRegex = Regex.Escape(escapeCharacter.ToString()), + EndRegex = "." + }); + } + if (span.RuleSetReference.ReferencedElement != null) { + ruleSet.Elements.Add(new XshdImport { RuleSetReference = span.RuleSetReference }); + } + span.RuleSetReference = new XshdReference<XshdRuleSet>(ruleSet); + } + return span; + } + + static string ImportRegex(string expr, bool singleWord, bool? startOfLine) + { + StringBuilder b = new StringBuilder(); + if (startOfLine != null) { + if (startOfLine.Value) { + b.Append(@"(?<=(^\s*))"); + } else { + b.Append(@"(?<!(^\s*))"); + } + } else { + if (singleWord) + b.Append(@"\b"); + } + for (int i = 0; i < expr.Length; i++) { + char c = expr[i]; + if (c == '@') { + ++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 + b.Append(@"[^\w\d_]"); + break; + case '!': // negative lookahead + { + StringBuilder whatmatch = new StringBuilder(); + ++i; + while (i < expr.Length && expr[i] != '@') { + whatmatch.Append(expr[i++]); + } + b.Append("(?!("); + b.Append(Regex.Escape(whatmatch.ToString())); + b.Append("))"); + } + break; + case '-': // negative lookbehind + { + StringBuilder whatmatch = new StringBuilder(); + ++i; + while (i < expr.Length && expr[i] != '@') { + whatmatch.Append(expr[i++]); + } + b.Append("(?<!("); + b.Append(Regex.Escape(whatmatch.ToString())); + b.Append("))"); + } + break; + case '@': + b.Append("@"); + break; + default: + throw new HighlightingDefinitionInvalidException("Unknown character in @ sequence."); + } + } else { + b.Append(Regex.Escape(c.ToString())); + } + } + if (singleWord) + b.Append(@"\b"); + return b.ToString(); + } + } +} diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/V2Loader.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/V2Loader.cs new file mode 100644 index 000000000..ab2dbfc93 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/V2Loader.cs @@ -0,0 +1,334 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Windows; +using System.Windows.Media; +using System.Xml; +using System.Xml.Schema; + +using Tango.Scripting.Editors.Utils; + +namespace Tango.Scripting.Editors.Highlighting.Xshd +{ + /// <summary> + /// Loads .xshd files, version 2.0. + /// Version 2.0 files are recognized by the namespace. + /// </summary> + static class V2Loader + { + public const string Namespace = "http://icsharpcode.net/sharpdevelop/syntaxdefinition/2008"; + + static XmlSchemaSet schemaSet; + + static XmlSchemaSet SchemaSet { + get { + if (schemaSet == null) { + schemaSet = HighlightingLoader.LoadSchemaSet(new XmlTextReader( + Resources.OpenStream("ModeV2.xsd"))); + } + return schemaSet; + } + } + + public static XshdSyntaxDefinition LoadDefinition(XmlReader reader, bool skipValidation) + { + reader = HighlightingLoader.GetValidatingReader(reader, true, skipValidation ? null : SchemaSet); + reader.Read(); + return ParseDefinition(reader); + } + + static XshdSyntaxDefinition ParseDefinition(XmlReader reader) + { + Debug.Assert(reader.LocalName == "SyntaxDefinition"); + XshdSyntaxDefinition def = new XshdSyntaxDefinition(); + def.Name = reader.GetAttribute("name"); + string extensions = reader.GetAttribute("extensions"); + if (extensions != null) + def.Extensions.AddRange(extensions.Split(';')); + ParseElements(def.Elements, reader); + Debug.Assert(reader.NodeType == XmlNodeType.EndElement); + Debug.Assert(reader.LocalName == "SyntaxDefinition"); + return def; + } + + static void ParseElements(ICollection<XshdElement> c, XmlReader reader) + { + if (reader.IsEmptyElement) + return; + while (reader.Read() && reader.NodeType != XmlNodeType.EndElement) { + Debug.Assert(reader.NodeType == XmlNodeType.Element); + if (reader.NamespaceURI != Namespace) { + if (!reader.IsEmptyElement) + reader.Skip(); + continue; + } + switch (reader.Name) { + case "RuleSet": + c.Add(ParseRuleSet(reader)); + break; + case "Property": + c.Add(ParseProperty(reader)); + break; + case "Color": + c.Add(ParseNamedColor(reader)); + break; + case "Keywords": + c.Add(ParseKeywords(reader)); + break; + case "Span": + c.Add(ParseSpan(reader)); + break; + case "Import": + c.Add(ParseImport(reader)); + break; + case "Rule": + c.Add(ParseRule(reader)); + break; + default: + throw new NotSupportedException("Unknown element " + reader.Name); + } + } + } + + static XshdElement ParseProperty(XmlReader reader) + { + XshdProperty property = new XshdProperty(); + SetPosition(property, reader); + property.Name = reader.GetAttribute("name"); + property.Value = reader.GetAttribute("value"); + return property; + } + + static XshdRuleSet ParseRuleSet(XmlReader reader) + { + XshdRuleSet ruleSet = new XshdRuleSet(); + SetPosition(ruleSet, reader); + ruleSet.Name = reader.GetAttribute("name"); + ruleSet.IgnoreCase = reader.GetBoolAttribute("ignoreCase"); + + CheckElementName(reader, ruleSet.Name); + ParseElements(ruleSet.Elements, reader); + return ruleSet; + } + + static XshdRule ParseRule(XmlReader reader) + { + XshdRule rule = new XshdRule(); + SetPosition(rule, reader); + rule.ColorReference = ParseColorReference(reader); + if (!reader.IsEmptyElement) { + reader.Read(); + if (reader.NodeType == XmlNodeType.Text) { + rule.Regex = reader.ReadContentAsString(); + rule.RegexType = XshdRegexType.IgnorePatternWhitespace; + } + } + return rule; + } + + static XshdKeywords ParseKeywords(XmlReader reader) + { + XshdKeywords keywords = new XshdKeywords(); + SetPosition(keywords, reader); + keywords.ColorReference = ParseColorReference(reader); + reader.Read(); + while (reader.NodeType != XmlNodeType.EndElement) { + Debug.Assert(reader.NodeType == XmlNodeType.Element); + keywords.Words.Add(reader.ReadElementString()); + } + return keywords; + } + + static XshdImport ParseImport(XmlReader reader) + { + XshdImport import = new XshdImport(); + SetPosition(import, reader); + import.RuleSetReference = ParseRuleSetReference(reader); + if (!reader.IsEmptyElement) + reader.Skip(); + return import; + } + + static XshdSpan ParseSpan(XmlReader reader) + { + XshdSpan span = new XshdSpan(); + SetPosition(span, reader); + span.BeginRegex = reader.GetAttribute("begin"); + span.EndRegex = reader.GetAttribute("end"); + span.Multiline = reader.GetBoolAttribute("multiline") ?? false; + span.SpanColorReference = ParseColorReference(reader); + span.RuleSetReference = ParseRuleSetReference(reader); + if (!reader.IsEmptyElement) { + reader.Read(); + while (reader.NodeType != XmlNodeType.EndElement) { + Debug.Assert(reader.NodeType == XmlNodeType.Element); + switch (reader.Name) { + case "Begin": + if (span.BeginRegex != null) + throw Error(reader, "Duplicate Begin regex"); + span.BeginColorReference = ParseColorReference(reader); + span.BeginRegex = reader.ReadElementString(); + span.BeginRegexType = XshdRegexType.IgnorePatternWhitespace; + break; + case "End": + if (span.EndRegex != null) + throw Error(reader, "Duplicate End regex"); + span.EndColorReference = ParseColorReference(reader); + span.EndRegex = reader.ReadElementString(); + span.EndRegexType = XshdRegexType.IgnorePatternWhitespace; + break; + case "RuleSet": + if (span.RuleSetReference.ReferencedElement != null) + throw Error(reader, "Cannot specify both inline RuleSet and RuleSet reference"); + span.RuleSetReference = new XshdReference<XshdRuleSet>(ParseRuleSet(reader)); + reader.Read(); + break; + default: + throw new NotSupportedException("Unknown element " + reader.Name); + } + } + } + return span; + } + + static Exception Error(XmlReader reader, string message) + { + return Error(reader as IXmlLineInfo, message); + } + + static Exception Error(IXmlLineInfo lineInfo, string message) + { + if (lineInfo != null) + return new HighlightingDefinitionInvalidException(HighlightingLoader.FormatExceptionMessage(message, lineInfo.LineNumber, lineInfo.LinePosition)); + else + return new HighlightingDefinitionInvalidException(message); + } + + /// <summary> + /// Sets the element's position to the XmlReader's position. + /// </summary> + static void SetPosition(XshdElement element, XmlReader reader) + { + IXmlLineInfo lineInfo = reader as IXmlLineInfo; + if (lineInfo != null) { + element.LineNumber = lineInfo.LineNumber; + element.ColumnNumber = lineInfo.LinePosition; + } + } + + static XshdReference<XshdRuleSet> ParseRuleSetReference(XmlReader reader) + { + string ruleSet = reader.GetAttribute("ruleSet"); + if (ruleSet != null) { + // '/' is valid in highlighting definition names, so we need the last occurence + int pos = ruleSet.LastIndexOf('/'); + if (pos >= 0) { + return new XshdReference<XshdRuleSet>(ruleSet.Substring(0, pos), ruleSet.Substring(pos + 1)); + } else { + return new XshdReference<XshdRuleSet>(null, ruleSet); + } + } else { + return new XshdReference<XshdRuleSet>(); + } + } + + static void CheckElementName(XmlReader reader, string name) + { + if (name != null) { + if (name.Length == 0) + throw Error(reader, "The empty string is not a valid name."); + if (name.IndexOf('/') >= 0) + throw Error(reader, "Element names must not contain a slash."); + } + } + + #region ParseColor + static XshdColor ParseNamedColor(XmlReader reader) + { + XshdColor color = ParseColorAttributes(reader); + // check removed: invisible named colors may be useful now that apps can read highlighting data + //if (color.Foreground == null && color.FontWeight == null && color.FontStyle == null) + // throw Error(reader, "A named color must have at least one element."); + color.Name = reader.GetAttribute("name"); + CheckElementName(reader, color.Name); + color.ExampleText = reader.GetAttribute("exampleText"); + return color; + } + + static XshdReference<XshdColor> ParseColorReference(XmlReader reader) + { + string color = reader.GetAttribute("color"); + if (color != null) { + int pos = color.LastIndexOf('/'); + if (pos >= 0) { + return new XshdReference<XshdColor>(color.Substring(0, pos), color.Substring(pos + 1)); + } else { + return new XshdReference<XshdColor>(null, color); + } + } else { + return new XshdReference<XshdColor>(ParseColorAttributes(reader)); + } + } + + static XshdColor ParseColorAttributes(XmlReader reader) + { + XshdColor color = new XshdColor(); + SetPosition(color, reader); + IXmlLineInfo position = reader as IXmlLineInfo; + color.Foreground = ParseColor(position, reader.GetAttribute("foreground")); + color.Background = ParseColor(position, reader.GetAttribute("background")); + color.FontWeight = ParseFontWeight(reader.GetAttribute("fontWeight")); + color.FontStyle = ParseFontStyle(reader.GetAttribute("fontStyle")); + return color; + } + + internal readonly static ColorConverter ColorConverter = new ColorConverter(); + internal readonly static FontWeightConverter FontWeightConverter = new FontWeightConverter(); + internal readonly static FontStyleConverter FontStyleConverter = new FontStyleConverter(); + + static HighlightingBrush ParseColor(IXmlLineInfo lineInfo, string color) + { + if (string.IsNullOrEmpty(color)) + return null; + if (color.StartsWith("SystemColors.", StringComparison.Ordinal)) + return GetSystemColorBrush(lineInfo, color); + else + return FixedColorHighlightingBrush((Color?)ColorConverter.ConvertFromInvariantString(color)); + } + + internal static SystemColorHighlightingBrush GetSystemColorBrush(IXmlLineInfo lineInfo, string name) + { + Debug.Assert(name.StartsWith("SystemColors.", StringComparison.Ordinal)); + string shortName = name.Substring(13); + var property = typeof(SystemColors).GetProperty(shortName + "Brush"); + if (property == null) + throw Error(lineInfo, "Cannot find '" + name + "'."); + return new SystemColorHighlightingBrush(property); + } + + static HighlightingBrush FixedColorHighlightingBrush(Color? color) + { + if (color == null) + return null; + return new SimpleHighlightingBrush(color.Value); + } + + static FontWeight? ParseFontWeight(string fontWeight) + { + if (string.IsNullOrEmpty(fontWeight)) + return null; + return (FontWeight?)FontWeightConverter.ConvertFromInvariantString(fontWeight); + } + + static FontStyle? ParseFontStyle(string fontStyle) + { + if (string.IsNullOrEmpty(fontStyle)) + return null; + return (FontStyle?)FontStyleConverter.ConvertFromInvariantString(fontStyle); + } + #endregion + } +} diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/XmlHighlightingDefinition.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/XmlHighlightingDefinition.cs new file mode 100644 index 000000000..3f52e5d87 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/XmlHighlightingDefinition.cs @@ -0,0 +1,406 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Runtime.Serialization; +using System.Text; +using System.Text.RegularExpressions; +using Tango.Scripting.Editors.Utils; + +namespace Tango.Scripting.Editors.Highlighting.Xshd +{ + [Serializable] + sealed class XmlHighlightingDefinition : IHighlightingDefinition2 + { + public string Name { get; private set; } + + public XmlHighlightingDefinition(XshdSyntaxDefinition xshd, IHighlightingDefinitionReferenceResolver resolver) + { + this.Name = xshd.Name; + // Create HighlightingRuleSet instances + var rnev = new RegisterNamedElementsVisitor(this); + xshd.AcceptElements(rnev); + // Assign MainRuleSet so that references can be resolved + foreach (XshdElement element in xshd.Elements) { + XshdRuleSet xrs = element as XshdRuleSet; + if (xrs != null && xrs.Name == null) { + if (MainRuleSet != null) + throw Error(element, "Duplicate main RuleSet. There must be only one nameless RuleSet!"); + else + MainRuleSet = rnev.ruleSets[xrs]; + } + } + if (MainRuleSet == null) + throw new HighlightingDefinitionInvalidException("Could not find main RuleSet."); + // Translate elements within the rulesets (resolving references and processing imports) + xshd.AcceptElements(new TranslateElementVisitor(this, rnev.ruleSets, resolver)); + + foreach (var p in xshd.Elements.OfType<XshdProperty>()) + propDict.Add(p.Name, p.Value); + } + + #region RegisterNamedElements + sealed class RegisterNamedElementsVisitor : IXshdVisitor + { + XmlHighlightingDefinition def; + internal readonly Dictionary<XshdRuleSet, HighlightingRuleSet> ruleSets + = new Dictionary<XshdRuleSet, HighlightingRuleSet>(); + + public RegisterNamedElementsVisitor(XmlHighlightingDefinition def) + { + this.def = def; + } + + public object VisitRuleSet(XshdRuleSet ruleSet) + { + HighlightingRuleSet hrs = new HighlightingRuleSet(); + ruleSets.Add(ruleSet, hrs); + if (ruleSet.Name != null) { + if (ruleSet.Name.Length == 0) + throw Error(ruleSet, "Name must not be the empty string"); + if (def.ruleSetDict.ContainsKey(ruleSet.Name)) + throw Error(ruleSet, "Duplicate rule set name '" + ruleSet.Name + "'."); + + def.ruleSetDict.Add(ruleSet.Name, hrs); + } + ruleSet.AcceptElements(this); + return null; + } + + public object VisitColor(XshdColor color) + { + if (color.Name != null) { + if (color.Name.Length == 0) + throw Error(color, "Name must not be the empty string"); + if (def.colorDict.ContainsKey(color.Name)) + throw Error(color, "Duplicate color name '" + color.Name + "'."); + + def.colorDict.Add(color.Name, new HighlightingColor()); + } + return null; + } + + public object VisitKeywords(XshdKeywords keywords) + { + return keywords.ColorReference.AcceptVisitor(this); + } + + public object VisitSpan(XshdSpan span) + { + span.BeginColorReference.AcceptVisitor(this); + span.SpanColorReference.AcceptVisitor(this); + span.EndColorReference.AcceptVisitor(this); + return span.RuleSetReference.AcceptVisitor(this); + } + + public object VisitImport(XshdImport import) + { + return import.RuleSetReference.AcceptVisitor(this); + } + + public object VisitRule(XshdRule rule) + { + return rule.ColorReference.AcceptVisitor(this); + } + } + #endregion + + #region TranslateElements + sealed class TranslateElementVisitor : IXshdVisitor + { + readonly XmlHighlightingDefinition def; + readonly Dictionary<XshdRuleSet, HighlightingRuleSet> ruleSetDict; + readonly Dictionary<HighlightingRuleSet, XshdRuleSet> reverseRuleSetDict; + readonly IHighlightingDefinitionReferenceResolver resolver; + HashSet<XshdRuleSet> processingStartedRuleSets = new HashSet<XshdRuleSet>(); + HashSet<XshdRuleSet> processedRuleSets = new HashSet<XshdRuleSet>(); + bool ignoreCase; + + public TranslateElementVisitor(XmlHighlightingDefinition def, Dictionary<XshdRuleSet, HighlightingRuleSet> ruleSetDict, IHighlightingDefinitionReferenceResolver resolver) + { + Debug.Assert(def != null); + Debug.Assert(ruleSetDict != null); + this.def = def; + this.ruleSetDict = ruleSetDict; + this.resolver = resolver; + reverseRuleSetDict = new Dictionary<HighlightingRuleSet, XshdRuleSet>(); + foreach (var pair in ruleSetDict) { + reverseRuleSetDict.Add(pair.Value, pair.Key); + } + } + + public object VisitRuleSet(XshdRuleSet ruleSet) + { + HighlightingRuleSet rs = ruleSetDict[ruleSet]; + if (processedRuleSets.Contains(ruleSet)) + return rs; + if (!processingStartedRuleSets.Add(ruleSet)) + throw Error(ruleSet, "RuleSet cannot be processed because it contains cyclic <Import>"); + + bool oldIgnoreCase = ignoreCase; + if (ruleSet.IgnoreCase != null) + ignoreCase = ruleSet.IgnoreCase.Value; + + rs.Name = ruleSet.Name; + + foreach (XshdElement element in ruleSet.Elements) { + object o = element.AcceptVisitor(this); + HighlightingRuleSet elementRuleSet = o as HighlightingRuleSet; + if (elementRuleSet != null) { + Merge(rs, elementRuleSet); + } else { + HighlightingSpan span = o as HighlightingSpan; + if (span != null) { + rs.Spans.Add(span); + } else { + HighlightingRule elementRule = o as HighlightingRule; + if (elementRule != null) { + rs.Rules.Add(elementRule); + } + } + } + } + + ignoreCase = oldIgnoreCase; + processedRuleSets.Add(ruleSet); + + return rs; + } + + static void Merge(HighlightingRuleSet target, HighlightingRuleSet source) + { + target.Rules.AddRange(source.Rules); + target.Spans.AddRange(source.Spans); + } + + public object VisitColor(XshdColor color) + { + HighlightingColor c; + if (color.Name != null) + c = def.colorDict[color.Name]; + else if (color.Foreground == null && color.FontStyle == null && color.FontWeight == null) + return null; + else + c = new HighlightingColor(); + + c.Name = color.Name; + c.Foreground = color.Foreground; + c.Background = color.Background; + c.FontStyle = color.FontStyle; + c.FontWeight = color.FontWeight; + return c; + } + + public object VisitKeywords(XshdKeywords keywords) + { + if (keywords.Words.Count == 0) + return Error(keywords, "Keyword group must not be empty."); + foreach (string keyword in keywords.Words) { + if (string.IsNullOrEmpty(keyword)) + throw Error(keywords, "Cannot use empty string as keyword"); + } + StringBuilder keyWordRegex = new StringBuilder(); + // We can use "\b" only where the keyword starts/ends with a letter or digit, otherwise we don't + // highlight correctly. (example: ILAsm-Mode.xshd with ".maxstack" keyword) + if (keywords.Words.All(IsSimpleWord)) { + keyWordRegex.Append(@"\b(?>"); + // (?> = atomic group + // atomic groups increase matching performance, but we + // must ensure that the keywords are sorted correctly. + // "\b(?>in|int)\b" does not match "int" because the atomic group captures "in". + // To solve this, we are sorting the keywords by descending length. + int i = 0; + foreach (string keyword in keywords.Words.OrderByDescending(w=>w.Length)) { + if (i++ > 0) + keyWordRegex.Append('|'); + keyWordRegex.Append(Regex.Escape(keyword)); + } + keyWordRegex.Append(@")\b"); + } else { + keyWordRegex.Append('('); + int i = 0; + foreach (string keyword in keywords.Words) { + if (i++ > 0) + keyWordRegex.Append('|'); + if (char.IsLetterOrDigit(keyword[0])) + keyWordRegex.Append(@"\b"); + keyWordRegex.Append(Regex.Escape(keyword)); + if (char.IsLetterOrDigit(keyword[keyword.Length - 1])) + keyWordRegex.Append(@"\b"); + } + keyWordRegex.Append(')'); + } + return new HighlightingRule { + Color = GetColor(keywords, keywords.ColorReference), + Regex = CreateRegex(keywords, keyWordRegex.ToString(), XshdRegexType.Default) + }; + } + + static bool IsSimpleWord(string word) + { + return char.IsLetterOrDigit(word[0]) && char.IsLetterOrDigit(word, word.Length - 1); + } + + Regex CreateRegex(XshdElement position, string regex, XshdRegexType regexType) + { + if (regex == null) + throw Error(position, "Regex missing"); + RegexOptions options = RegexOptions.CultureInvariant | RegexOptions.ExplicitCapture; + if (regexType == XshdRegexType.IgnorePatternWhitespace) + options |= RegexOptions.IgnorePatternWhitespace; + if (ignoreCase) + options |= RegexOptions.IgnoreCase; + try { + return new Regex(regex, options); + } catch (ArgumentException ex) { + throw Error(position, ex.Message); + } + } + + HighlightingColor GetColor(XshdElement position, XshdReference<XshdColor> colorReference) + { + if (colorReference.InlineElement != null) { + return (HighlightingColor)colorReference.InlineElement.AcceptVisitor(this); + } else if (colorReference.ReferencedElement != null) { + IHighlightingDefinition definition = GetDefinition(position, colorReference.ReferencedDefinition); + HighlightingColor color = definition.GetNamedColor(colorReference.ReferencedElement); + if (color == null) + throw Error(position, "Could not find color named '" + colorReference.ReferencedElement + "'."); + return color; + } else { + return null; + } + } + + IHighlightingDefinition GetDefinition(XshdElement position, string definitionName) + { + if (definitionName == null) + return def; + if (resolver == null) + throw Error(position, "Resolving references to other syntax definitions is not possible because the IHighlightingDefinitionReferenceResolver is null."); + IHighlightingDefinition d = resolver.GetDefinition(definitionName); + if (d == null) + throw Error(position, "Could not find definition with name '" + definitionName + "'."); + return d; + } + + HighlightingRuleSet GetRuleSet(XshdElement position, XshdReference<XshdRuleSet> ruleSetReference) + { + if (ruleSetReference.InlineElement != null) { + return (HighlightingRuleSet)ruleSetReference.InlineElement.AcceptVisitor(this); + } else if (ruleSetReference.ReferencedElement != null) { + IHighlightingDefinition definition = GetDefinition(position, ruleSetReference.ReferencedDefinition); + HighlightingRuleSet ruleSet = definition.GetNamedRuleSet(ruleSetReference.ReferencedElement); + if (ruleSet == null) + throw Error(position, "Could not find rule set named '" + ruleSetReference.ReferencedElement + "'."); + return ruleSet; + } else { + return null; + } + } + + public object VisitSpan(XshdSpan span) + { + string endRegex = span.EndRegex; + if (string.IsNullOrEmpty(span.BeginRegex) && string.IsNullOrEmpty(span.EndRegex)) + throw Error(span, "Span has no start/end regex."); + if (!span.Multiline) { + if (endRegex == null) + endRegex = "$"; + else if (span.EndRegexType == XshdRegexType.IgnorePatternWhitespace) + endRegex = "($|" + endRegex + "\n)"; + else + endRegex = "($|" + endRegex + ")"; + } + HighlightingColor wholeSpanColor = GetColor(span, span.SpanColorReference); + return new HighlightingSpan { + StartExpression = CreateRegex(span, span.BeginRegex, span.BeginRegexType), + EndExpression = CreateRegex(span, endRegex, span.EndRegexType), + RuleSet = GetRuleSet(span, span.RuleSetReference), + StartColor = GetColor(span, span.BeginColorReference), + SpanColor = wholeSpanColor, + EndColor = GetColor(span, span.EndColorReference), + SpanColorIncludesStart = true, + SpanColorIncludesEnd = true + }; + } + + public object VisitImport(XshdImport import) + { + HighlightingRuleSet hrs = GetRuleSet(import, import.RuleSetReference); + XshdRuleSet inputRuleSet; + if (reverseRuleSetDict.TryGetValue(hrs, out inputRuleSet)) { + // ensure the ruleset is processed before importing its members + if (VisitRuleSet(inputRuleSet) != hrs) + Debug.Fail("this shouldn't happen"); + } + return hrs; + } + + public object VisitRule(XshdRule rule) + { + return new HighlightingRule { + Color = GetColor(rule, rule.ColorReference), + Regex = CreateRegex(rule, rule.Regex, rule.RegexType) + }; + } + } + #endregion + + static Exception Error(XshdElement element, string message) + { + if (element.LineNumber > 0) + return new HighlightingDefinitionInvalidException( + "Error at line " + element.LineNumber + ":\n" + message); + else + return new HighlightingDefinitionInvalidException(message); + } + + Dictionary<string, HighlightingRuleSet> ruleSetDict = new Dictionary<string, HighlightingRuleSet>(); + Dictionary<string, HighlightingColor> colorDict = new Dictionary<string, HighlightingColor>(); + [OptionalField] + Dictionary<string, string> propDict = new Dictionary<string, string>(); + + public HighlightingRuleSet MainRuleSet { get; private set; } + + public HighlightingRuleSet GetNamedRuleSet(string name) + { + if (string.IsNullOrEmpty(name)) + return MainRuleSet; + HighlightingRuleSet r; + if (ruleSetDict.TryGetValue(name, out r)) + return r; + else + return null; + } + + public HighlightingColor GetNamedColor(string name) + { + HighlightingColor c; + if (colorDict.TryGetValue(name, out c)) + return c; + else + return null; + } + + public IEnumerable<HighlightingColor> NamedHighlightingColors { + get { + return colorDict.Values; + } + } + + public override string ToString() + { + return this.Name; + } + + public IDictionary<string, string> Properties { + get { + return propDict; + } + } + } +} diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/XshdColor.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/XshdColor.cs new file mode 100644 index 000000000..bbc5abb98 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/XshdColor.cs @@ -0,0 +1,97 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Runtime.Serialization; +using System.Security.Permissions; +using System.Windows; + +namespace Tango.Scripting.Editors.Highlighting.Xshd +{ + /// <summary> + /// A color in an Xshd file. + /// </summary> + [Serializable] + public class XshdColor : XshdElement, ISerializable + { + /// <summary> + /// Gets/sets the name. + /// </summary> + public string Name { get; set; } + + /// <summary> + /// Gets/sets the foreground brush. + /// </summary> + public HighlightingBrush Foreground { get; set; } + + /// <summary> + /// Gets/sets the background brush. + /// </summary> + public HighlightingBrush Background { get; set; } + + /// <summary> + /// Gets/sets the font weight. + /// </summary> + public FontWeight? FontWeight { get; set; } + + /// <summary> + /// Gets/sets the font style. + /// </summary> + public FontStyle? FontStyle { get; set; } + + /// <summary> + /// Gets/Sets the example text that demonstrates where the color is used. + /// </summary> + public string ExampleText { get; set; } + + /// <summary> + /// Creates a new XshdColor instance. + /// </summary> + public XshdColor() + { + } + + /// <summary> + /// Deserializes an XshdColor. + /// </summary> + protected XshdColor(SerializationInfo info, StreamingContext context) + { + if (info == null) + throw new ArgumentNullException("info"); + this.Name = info.GetString("Name"); + this.Foreground = (HighlightingBrush)info.GetValue("Foreground", typeof(HighlightingBrush)); + this.Background = (HighlightingBrush)info.GetValue("Background", typeof(HighlightingBrush)); + if (info.GetBoolean("HasWeight")) + this.FontWeight = System.Windows.FontWeight.FromOpenTypeWeight(info.GetInt32("Weight")); + if (info.GetBoolean("HasStyle")) + this.FontStyle = (FontStyle?)new FontStyleConverter().ConvertFromInvariantString(info.GetString("Style")); + this.ExampleText = info.GetString("ExampleText"); + } + + /// <summary> + /// Serializes this XshdColor instance. + /// </summary> + [System.Security.SecurityCritical] + public virtual void GetObjectData(SerializationInfo info, StreamingContext context) + { + if (info == null) + throw new ArgumentNullException("info"); + info.AddValue("Name", this.Name); + info.AddValue("Foreground", this.Foreground); + info.AddValue("Background", this.Background); + info.AddValue("HasWeight", this.FontWeight.HasValue); + if (this.FontWeight.HasValue) + info.AddValue("Weight", this.FontWeight.Value.ToOpenTypeWeight()); + info.AddValue("HasStyle", this.FontStyle.HasValue); + if (this.FontStyle.HasValue) + info.AddValue("Style", this.FontStyle.Value.ToString()); + info.AddValue("ExampleText", this.ExampleText); + } + + /// <inheritdoc/> + public override object AcceptVisitor(IXshdVisitor visitor) + { + return visitor.VisitColor(this); + } + } +} diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/XshdElement.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/XshdElement.cs new file mode 100644 index 000000000..d7634e63e --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/XshdElement.cs @@ -0,0 +1,29 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; + +namespace Tango.Scripting.Editors.Highlighting.Xshd +{ + /// <summary> + /// An element in a XSHD rule set. + /// </summary> + [Serializable] + public abstract class XshdElement + { + /// <summary> + /// Gets the line number in the .xshd file. + /// </summary> + public int LineNumber { get; set; } + + /// <summary> + /// Gets the column number in the .xshd file. + /// </summary> + public int ColumnNumber { get; set; } + + /// <summary> + /// Applies the visitor to this element. + /// </summary> + public abstract object AcceptVisitor(IXshdVisitor visitor); + } +} diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/XshdImport.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/XshdImport.cs new file mode 100644 index 000000000..68ecdd2d0 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/XshdImport.cs @@ -0,0 +1,25 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; + +namespace Tango.Scripting.Editors.Highlighting.Xshd +{ + /// <summary> + /// <Import> element. + /// </summary> + [Serializable] + public class XshdImport : XshdElement + { + /// <summary> + /// Gets/sets the referenced rule set. + /// </summary> + public XshdReference<XshdRuleSet> RuleSetReference { get; set; } + + /// <inheritdoc/> + public override object AcceptVisitor(IXshdVisitor visitor) + { + return visitor.VisitImport(this); + } + } +} diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/XshdKeywords.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/XshdKeywords.cs new file mode 100644 index 000000000..245f34ae5 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/XshdKeywords.cs @@ -0,0 +1,36 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using Tango.Scripting.Editors.Utils; + +namespace Tango.Scripting.Editors.Highlighting.Xshd +{ + /// <summary> + /// A list of keywords. + /// </summary> + [Serializable] + public class XshdKeywords : XshdElement + { + /// <summary> + /// The color. + /// </summary> + public XshdReference<XshdColor> ColorReference { get; set; } + + readonly NullSafeCollection<string> words = new NullSafeCollection<string>(); + + /// <summary> + /// Gets the list of key words. + /// </summary> + public IList<string> Words { + get { return words; } + } + + /// <inheritdoc/> + public override object AcceptVisitor(IXshdVisitor visitor) + { + return visitor.VisitKeywords(this); + } + } +} diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/XshdProperty.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/XshdProperty.cs new file mode 100644 index 000000000..3ca65f4b4 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/XshdProperty.cs @@ -0,0 +1,38 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; + +namespace Tango.Scripting.Editors.Highlighting.Xshd +{ + /// <summary> + /// A property in an Xshd file. + /// </summary> + [Serializable] + public class XshdProperty : XshdElement + { + /// <summary> + /// Gets/sets the name. + /// </summary> + public string Name { get; set; } + + /// <summary> + /// Gets/sets the value. + /// </summary> + public string Value { get; set; } + + /// <summary> + /// Creates a new XshdColor instance. + /// </summary> + public XshdProperty() + { + } + + /// <inheritdoc/> + public override object AcceptVisitor(IXshdVisitor visitor) + { + return null; +// return visitor.VisitProperty(this); + } + } +} diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/XshdReference.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/XshdReference.cs new file mode 100644 index 000000000..363cd881c --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/XshdReference.cs @@ -0,0 +1,127 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; + +namespace Tango.Scripting.Editors.Highlighting.Xshd +{ + /// <summary> + /// A reference to an xshd color, or an inline xshd color. + /// </summary> + [Serializable] + public struct XshdReference<T> : IEquatable<XshdReference<T>> where T : XshdElement + { + string referencedDefinition; + string referencedElement; + T inlineElement; + + /// <summary> + /// Gets the reference. + /// </summary> + public string ReferencedDefinition { + get { return referencedDefinition; } + } + + /// <summary> + /// Gets the reference. + /// </summary> + public string ReferencedElement { + get { return referencedElement; } + } + + /// <summary> + /// Gets the inline element. + /// </summary> + public T InlineElement { + get { return inlineElement; } + } + + /// <summary> + /// Creates a new XshdReference instance. + /// </summary> + public XshdReference(string referencedDefinition, string referencedElement) + { + if (referencedElement == null) + throw new ArgumentNullException("referencedElement"); + this.referencedDefinition = referencedDefinition; + this.referencedElement = referencedElement; + this.inlineElement = null; + } + + /// <summary> + /// Creates a new XshdReference instance. + /// </summary> + public XshdReference(T inlineElement) + { + if (inlineElement == null) + throw new ArgumentNullException("inlineElement"); + this.referencedDefinition = null; + this.referencedElement = null; + this.inlineElement = inlineElement; + } + + /// <summary> + /// Applies the visitor to the inline element, if there is any. + /// </summary> + public object AcceptVisitor(IXshdVisitor visitor) + { + if (inlineElement != null) + return inlineElement.AcceptVisitor(visitor); + else + return null; + } + + #region Equals and GetHashCode implementation + // The code in this region is useful if you want to use this structure in collections. + // If you don't need it, you can just remove the region and the ": IEquatable<XshdColorReference>" declaration. + + /// <inheritdoc/> + public override bool Equals(object obj) + { + if (obj is XshdReference<T>) + return Equals((XshdReference<T>)obj); // use Equals method below + else + return false; + } + + /// <summary> + /// Equality operator. + /// </summary> + public bool Equals(XshdReference<T> other) + { + // add comparisions for all members here + return this.referencedDefinition == other.referencedDefinition + && this.referencedElement == other.referencedElement + && this.inlineElement == other.inlineElement; + } + + /// <inheritdoc/> + public override int GetHashCode() + { + // combine the hash codes of all members here (e.g. with XOR operator ^) + return GetHashCode(referencedDefinition) ^ GetHashCode(referencedElement) ^ GetHashCode(inlineElement); + } + + static int GetHashCode(object o) + { + return o != null ? o.GetHashCode() : 0; + } + + /// <summary> + /// Equality operator. + /// </summary> + public static bool operator ==(XshdReference<T> left, XshdReference<T> right) + { + return left.Equals(right); + } + + /// <summary> + /// Inequality operator. + /// </summary> + public static bool operator !=(XshdReference<T> left, XshdReference<T> right) + { + return !left.Equals(right); + } + #endregion + } +} diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/XshdRule.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/XshdRule.cs new file mode 100644 index 000000000..abca25f69 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/XshdRule.cs @@ -0,0 +1,35 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; + +namespace Tango.Scripting.Editors.Highlighting.Xshd +{ + /// <summary> + /// <Rule> element. + /// </summary> + [Serializable] + public class XshdRule : XshdElement + { + /// <summary> + /// Gets/sets the rule regex. + /// </summary> + public string Regex { get; set; } + + /// <summary> + /// Gets/sets the rule regex type. + /// </summary> + public XshdRegexType RegexType { get; set; } + + /// <summary> + /// Gets/sets the color reference. + /// </summary> + public XshdReference<XshdColor> ColorReference { get; set; } + + /// <inheritdoc/> + public override object AcceptVisitor(IXshdVisitor visitor) + { + return visitor.VisitRule(this); + } + } +} diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/XshdRuleSet.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/XshdRuleSet.cs new file mode 100644 index 000000000..2ffa16143 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/XshdRuleSet.cs @@ -0,0 +1,51 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using Tango.Scripting.Editors.Utils; + +namespace Tango.Scripting.Editors.Highlighting.Xshd +{ + /// <summary> + /// A rule set in a XSHD file. + /// </summary> + [Serializable] + public class XshdRuleSet : XshdElement + { + /// <summary> + /// Gets/Sets the name of the rule set. + /// </summary> + public string Name { get; set; } + + /// <summary> + /// Gets/sets whether the case is ignored in expressions inside this rule set. + /// </summary> + public bool? IgnoreCase { get; set; } + + readonly NullSafeCollection<XshdElement> elements = new NullSafeCollection<XshdElement>(); + + /// <summary> + /// Gets the collection of elements. + /// </summary> + public IList<XshdElement> Elements { + get { return elements; } + } + + /// <summary> + /// Applies the visitor to all elements. + /// </summary> + public void AcceptElements(IXshdVisitor visitor) + { + foreach (XshdElement element in Elements) { + element.AcceptVisitor(visitor); + } + } + + /// <inheritdoc/> + public override object AcceptVisitor(IXshdVisitor visitor) + { + return visitor.VisitRuleSet(this); + } + } +} diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/XshdSpan.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/XshdSpan.cs new file mode 100644 index 000000000..6d32abad4 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/XshdSpan.cs @@ -0,0 +1,82 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; + +namespace Tango.Scripting.Editors.Highlighting.Xshd +{ + /// <summary> + /// Specifies the type of the regex. + /// </summary> + public enum XshdRegexType + { + /// <summary> + /// Normal regex. Used when the regex was specified as attribute. + /// </summary> + Default, + /// <summary> + /// Ignore pattern whitespace / allow regex comments. Used when the regex was specified as text element. + /// </summary> + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", + Justification = "Using the same case as the RegexOption")] + IgnorePatternWhitespace + } + + /// <summary> + /// <Span> element. + /// </summary> + [Serializable] + public class XshdSpan : XshdElement + { + /// <summary> + /// Gets/sets the begin regex. + /// </summary> + public string BeginRegex { get; set; } + + /// <summary> + /// Gets/sets the begin regex type. + /// </summary> + public XshdRegexType BeginRegexType { get; set; } + + /// <summary> + /// Gets/sets the end regex. + /// </summary> + public string EndRegex { get; set; } + + /// <summary> + /// Gets/sets the end regex type. + /// </summary> + public XshdRegexType EndRegexType { get; set; } + + /// <summary> + /// Gets/sets whether the span is multiline. + /// </summary> + public bool Multiline { get; set; } + + /// <summary> + /// Gets/sets the rule set reference. + /// </summary> + public XshdReference<XshdRuleSet> RuleSetReference { get; set; } + + /// <summary> + /// Gets/sets the span color. + /// </summary> + public XshdReference<XshdColor> SpanColorReference { get; set; } + + /// <summary> + /// Gets/sets the span begin color. + /// </summary> + public XshdReference<XshdColor> BeginColorReference { get; set; } + + /// <summary> + /// Gets/sets the span end color. + /// </summary> + public XshdReference<XshdColor> EndColorReference { get; set; } + + /// <inheritdoc/> + public override object AcceptVisitor(IXshdVisitor visitor) + { + return visitor.VisitSpan(this); + } + } +} diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/XshdSyntaxDefinition.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/XshdSyntaxDefinition.cs new file mode 100644 index 000000000..347f14d25 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Xshd/XshdSyntaxDefinition.cs @@ -0,0 +1,50 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using Tango.Scripting.Editors.Utils; + +namespace Tango.Scripting.Editors.Highlighting.Xshd +{ + /// <summary> + /// A <SyntaxDefinition> element. + /// </summary> + [Serializable] + public class XshdSyntaxDefinition + { + /// <summary> + /// Creates a new XshdSyntaxDefinition object. + /// </summary> + public XshdSyntaxDefinition() + { + this.Elements = new NullSafeCollection<XshdElement>(); + this.Extensions = new NullSafeCollection<string>(); + } + + /// <summary> + /// Gets/sets the definition name + /// </summary> + public string Name { get; set; } + + /// <summary> + /// Gets the associated extensions. + /// </summary> + public IList<string> Extensions { get; private set; } + + /// <summary> + /// Gets the collection of elements. + /// </summary> + public IList<XshdElement> Elements { get; private set; } + + /// <summary> + /// Applies the visitor to all elements. + /// </summary> + public void AcceptElements(IXshdVisitor visitor) + { + foreach (XshdElement element in Elements) { + element.AcceptVisitor(visitor); + } + } + } +} |
