From d79c461876dc453fb0e7c0a15350ff1e311837fe Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Mon, 22 Feb 2010 10:48:15 +0000 Subject: [PATCH] Ported HtmlSyntaxColorizer to AvalonEdit. git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@5527 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61 --- .../HtmlSyntaxColorizer.csproj | 18 +- .../HtmlSyntaxColorizer.sln | 6 +- samples/HtmlSyntaxColorizer/HtmlWriter.cs | 221 +++++++----------- samples/HtmlSyntaxColorizer/Main.cs | 10 +- .../Highlighting/HighlightedLine.cs | 19 +- .../Highlighting/HtmlClipboard.cs | 35 ++- 6 files changed, 138 insertions(+), 171 deletions(-) diff --git a/samples/HtmlSyntaxColorizer/HtmlSyntaxColorizer.csproj b/samples/HtmlSyntaxColorizer/HtmlSyntaxColorizer.csproj index b092068218..e3a64b00df 100644 --- a/samples/HtmlSyntaxColorizer/HtmlSyntaxColorizer.csproj +++ b/samples/HtmlSyntaxColorizer/HtmlSyntaxColorizer.csproj @@ -1,4 +1,5 @@ - + + {6D17428C-A444-4C26-8FE3-976160F41D97} Debug @@ -6,6 +7,7 @@ Exe HtmlSyntaxColorizer HtmlSyntaxColorizer + v3.5 bin\Debug\ @@ -23,14 +25,22 @@ - - ..\..\bin\ICSharpCode.TextEditor.dll - False + + ..\..\bin\ICSharpCode.AvalonEdit.dll + + 3.5 + + + 3.5 + + + 3.5 + diff --git a/samples/HtmlSyntaxColorizer/HtmlSyntaxColorizer.sln b/samples/HtmlSyntaxColorizer/HtmlSyntaxColorizer.sln index db77ce7721..3449be3a7f 100644 --- a/samples/HtmlSyntaxColorizer/HtmlSyntaxColorizer.sln +++ b/samples/HtmlSyntaxColorizer/HtmlSyntaxColorizer.sln @@ -1,7 +1,7 @@  -Microsoft Visual Studio Solution File, Format Version 9.00 -# Visual Studio 2005 -# SharpDevelop 2.1.0.2513 +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +# SharpDevelop 4.0.0.5490 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HtmlSyntaxColorizer", "HtmlSyntaxColorizer.csproj", "{6D17428C-A444-4C26-8FE3-976160F41D97}" EndProject Global diff --git a/samples/HtmlSyntaxColorizer/HtmlWriter.cs b/samples/HtmlSyntaxColorizer/HtmlWriter.cs index 8218939b9b..66f595624f 100644 --- a/samples/HtmlSyntaxColorizer/HtmlWriter.cs +++ b/samples/HtmlSyntaxColorizer/HtmlWriter.cs @@ -1,5 +1,5 @@ // SharpDevelop samples -// Copyright (c) 2007, AlphaSierraPapa +// Copyright (c) 2010, AlphaSierraPapa // All rights reserved. // // Redistribution and use in source and binary forms, with or without modification, are @@ -30,8 +30,9 @@ using System.Collections.Generic; using System.IO; using System.Text; using System.Xml; -using ICSharpCode.TextEditor; -using ICSharpCode.TextEditor.Document; + +using ICSharpCode.AvalonEdit.Document; +using ICSharpCode.AvalonEdit.Highlighting; namespace ICSharpCode.HtmlSyntaxColorizer { @@ -57,10 +58,11 @@ namespace ICSharpCode.HtmlSyntaxColorizer public string StyleClassPrefix = "code"; Dictionary stylesheetCache = new Dictionary(); + StringBuilder stylesheet = new StringBuilder(); /// /// Resets the CSS stylesheet cache. Stylesheet classes will be cached on GenerateHtml calls. - /// If you want to reuse the HtmlWriter for multiple + /// If you want to reuse the HtmlWriter for multiple .html files. /// public void ResetStylesheetCache() { @@ -69,182 +71,117 @@ namespace ICSharpCode.HtmlSyntaxColorizer string GetClass(string style) { - return stylesheetCache[style]; - } - - void CacheClass(string style, StringBuilder b) - { - if (style == null) return; - if (!stylesheetCache.ContainsKey(style)) { - string styleName = StyleClassPrefix + stylesheetCache.Count; - stylesheetCache[style] = styleName; - b.Append('.'); - b.Append(styleName); - b.Append(" { "); - b.Append(style); - b.AppendLine(" }"); + string className; + if (!stylesheetCache.TryGetValue(style, out className)) { + className = StyleClassPrefix + stylesheetCache.Count; + stylesheet.Append('.'); + stylesheet.Append(className); + stylesheet.Append(" { "); + stylesheet.Append(style); + stylesheet.AppendLine(" }"); + stylesheetCache[style] = className; } + return className; } #endregion - public string GenerateHtml(string code, string highlighterName) + public string GenerateHtml(string code, IHighlightingDefinition highlightDefinition) { - IDocument doc = new DocumentFactory().CreateDocument(); - doc.HighlightingStrategy = HighlightingManager.Manager.FindHighlighter(highlighterName); - doc.TextContent = code; - return GenerateHtml(doc); + return GenerateHtml(new TextDocument(code), highlightDefinition); } - HighlightColor currentDefaultTextColor; + public string GenerateHtml(TextDocument document, IHighlightingDefinition highlightDefinition) + { + return GenerateHtml(document, new DocumentHighlighter(document, highlightDefinition.MainRuleSet)); + } - public string GenerateHtml(IDocument document) + public string GenerateHtml(TextDocument document, IHighlighter highlighter) { string myMainStyle = MainStyle; - currentDefaultTextColor = document.HighlightingStrategy.GetColorFor("Default"); - myMainStyle += " color: " + ColorToString(currentDefaultTextColor.Color) + ";" - + " background-color: " + ColorToString(currentDefaultTextColor.BackgroundColor) + ";"; - - string LineNumberStyle; - HighlightColor lineNumbersColor = document.HighlightingStrategy.GetColorFor("LineNumbers"); - if (lineNumbersColor != null) { - LineNumberStyle = "color: " + ColorToString(lineNumbersColor.Color) + ";" - + " background-color: " + ColorToString(lineNumbersColor.BackgroundColor) + ";"; - } else { - LineNumberStyle = "color: #606060;"; - } + string LineNumberStyle = "color: #606060;"; - StringBuilder b = new StringBuilder(); - if (CreateStylesheet) { - b.AppendLine(""); - } + StringWriter output = new StringWriter(); if (ShowLineNumbers || AlternateLineBackground) { - b.Append(""); + output.Write(""); - int longestNumberLength = 1 + (int)Math.Log10(document.TotalNumberOfLines); + int longestNumberLength = 1 + (int)Math.Log10(document.LineCount); - int lineNumber = 1; - foreach (LineSegment lineSegment in document.LineSegmentCollection) { - b.Append(""); + output.Write(">"); if (ShowLineNumbers) { - b.Append("'); - b.Append(lineNumber.ToString().PadLeft(longestNumberLength)); - b.Append(": "); - b.Append(""); - } - - - if (lineSegment.Words.Count == 0) { - b.Append(" "); - } else { - PrintWords(lineSegment, b); + output.Write("'); + output.Write(lineNumber.ToString().PadLeft(longestNumberLength)); + output.Write(": "); + output.Write(""); } - b.AppendLine(""); - lineNumber++; + PrintWords(output, line); + output.WriteLine(""); } - b.AppendLine(""); + output.WriteLine(""); } else { - b.Append(""); - foreach (LineSegment lineSegment in document.LineSegmentCollection) { - PrintWords(lineSegment, b); - b.AppendLine(); + output.Write(""); + for (int lineNumber = 1; lineNumber <= document.LineCount; lineNumber++) { + HighlightedLine line = highlighter.HighlightLine(lineNumber); + PrintWords(output, line); + output.WriteLine(); } - b.AppendLine(""); + output.WriteLine(""); } - return b.ToString(); - } - - void PrintWords(LineSegment lineSegment, StringBuilder b) - { - string currentSpan = null; - foreach (TextWord word in lineSegment.Words) { - if (word.Type == TextWordType.Space) { - b.Append(' '); - } else if (word.Type == TextWordType.Tab) { - b.Append('\t'); - } else { - string newSpan = GetStyle(word); - if (currentSpan != newSpan) { - if (currentSpan != null) b.Append(""); - if (newSpan != null) { - b.Append("'); - } - currentSpan = newSpan; - } - b.Append(HtmlEncode(word.Word)); - } + if (CreateStylesheet && stylesheet.Length > 0) { + string result = "" + output.ToString(); + stylesheet = new StringBuilder(); + return result; + } else { + return output.ToString(); } - if (currentSpan != null) b.Append(""); } - static string HtmlEncode(string word) + void PrintWords(TextWriter writer, HighlightedLine line) { - return word.Replace("&", "&").Replace("<", "<").Replace(">", ">"); + writer.Write(line.ToHtml(new MyHtmlOptions(this))); } - void WriteStyle(string style, StringBuilder b) + class MyHtmlOptions : HtmlOptions { - if (CreateStylesheet) { - b.Append(" class=\""); - b.Append(GetClass(style)); - b.Append('"'); - } else { - b.Append(" style='"); - b.Append(style); - b.Append("'"); - } - } - - string GetStyle(TextWord word) - { - if (word.SyntaxColor == null || word.SyntaxColor.ToString() == currentDefaultTextColor.ToString()) - return null; + readonly HtmlWriter htmlWriter; - string style = "color: " + ColorToString(word.Color) + ";"; - if (word.Bold) { - style += " font-weight: bold;"; - } - if (word.Italic) { - style += " font-style: italic;"; + internal MyHtmlOptions(HtmlWriter htmlWriter) + { + this.htmlWriter = htmlWriter; } - if (word.SyntaxColor.HasBackground) { - style += " background-color: " + ColorToString(word.SyntaxColor.BackgroundColor) + ";"; + + public override void WriteStyleAttributeForColor(TextWriter writer, HighlightingColor color) + { + htmlWriter.WriteStyle(writer, color.ToCss()); } - return style; } - static string ColorToString(System.Drawing.Color color) + void WriteStyle(TextWriter writer, string style) { - return "#" + color.R.ToString("x2") + color.G.ToString("x2") + color.B.ToString("x2"); + if (CreateStylesheet) { + writer.Write(" class=\""); + writer.Write(GetClass(style)); + writer.Write('"'); + } else { + writer.Write(" style='"); + writer.Write(style); + writer.Write("'"); + } } } } diff --git a/samples/HtmlSyntaxColorizer/Main.cs b/samples/HtmlSyntaxColorizer/Main.cs index 8cae6c5b1c..91e69a7bff 100644 --- a/samples/HtmlSyntaxColorizer/Main.cs +++ b/samples/HtmlSyntaxColorizer/Main.cs @@ -1,5 +1,5 @@ // SharpDevelop samples -// Copyright (c) 2007, AlphaSierraPapa +// Copyright (c) 2010, AlphaSierraPapa // All rights reserved. // // Redistribution and use in source and binary forms, with or without modification, are @@ -26,9 +26,11 @@ // OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using System; +using System.Collections.Generic; using System.Diagnostics; using System.IO; -using System.Collections.Generic; + +using ICSharpCode.AvalonEdit.Highlighting; namespace ICSharpCode.HtmlSyntaxColorizer { @@ -36,11 +38,13 @@ namespace ICSharpCode.HtmlSyntaxColorizer { public static void Main(string[] args) { + IHighlightingDefinition highlightDefinition = HighlightingManager.Instance.GetDefinition("C#"); + HtmlWriter w = new HtmlWriter(); w.ShowLineNumbers = true; w.AlternateLineBackground = true; string code = File.ReadAllText("../../Main.cs"); - string html = w.GenerateHtml(code, "C#"); + string html = w.GenerateHtml(code, highlightDefinition); File.WriteAllText("output.html", "" + html + ""); Process.Start("output.html"); // view in browser } diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HighlightedLine.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HighlightedLine.cs index 962e5298eb..5de428006b 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HighlightedLine.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HighlightedLine.cs @@ -7,6 +7,7 @@ using System; using System.Collections.Generic; +using System.IO; using System.Text; using ICSharpCode.AvalonEdit.Document; @@ -79,7 +80,7 @@ namespace ICSharpCode.AvalonEdit.Highlighting return 1; } else { if (IsEnd) - return -Nesting.CompareTo(other.Nesting); + return other.Nesting.CompareTo(Nesting); else return Nesting.CompareTo(other.Nesting); } @@ -121,24 +122,24 @@ namespace ICSharpCode.AvalonEdit.Highlighting elements.Sort(); TextDocument document = this.Document; - StringBuilder b = new StringBuilder(); + StringWriter w = new StringWriter(); int textOffset = startOffset; foreach (HtmlElement e in elements) { int newOffset = Math.Min(e.Offset, endOffset); if (newOffset > startOffset) { - HtmlClipboard.EscapeHtml(b, document.GetText(textOffset, newOffset - textOffset), options); + HtmlClipboard.EscapeHtml(w, document.GetText(textOffset, newOffset - textOffset), options); } textOffset = Math.Max(textOffset, newOffset); if (e.IsEnd) { - b.Append(""); + w.Write(""); } else { - b.Append(""); + w.Write("'); } } - HtmlClipboard.EscapeHtml(b, document.GetText(textOffset, endOffset - textOffset), options); - return b.ToString(); + HtmlClipboard.EscapeHtml(w, document.GetText(textOffset, endOffset - textOffset), options); + return w.ToString(); } /// diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HtmlClipboard.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HtmlClipboard.cs index acf8aff925..b51851d1c6 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HtmlClipboard.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HtmlClipboard.cs @@ -8,6 +8,7 @@ using System; using System.Diagnostics; using System.Globalization; +using System.IO; using System.Text; using System.Windows; @@ -101,13 +102,13 @@ namespace ICSharpCode.AvalonEdit.Highlighting /// /// Escapes text and writes the result to the StringBuilder. /// - internal static void EscapeHtml(StringBuilder b, string text, HtmlOptions options) + internal static void EscapeHtml(StringWriter w, string text, HtmlOptions options) { int spaceCount = -1; foreach (char c in text) { if (c == ' ') { if (spaceCount < 0) - b.Append(" "); + w.Write(" "); else spaceCount++; } else if (c == '\t') { @@ -116,34 +117,34 @@ namespace ICSharpCode.AvalonEdit.Highlighting spaceCount += options.TabSize; } else { if (spaceCount == 1) { - b.Append(' '); + w.Write(' '); } else if (spaceCount >= 1) { for (int i = 0; i < spaceCount; i++) { - b.Append(" "); + w.Write(" "); } } spaceCount = 0; switch (c) { case '<': - b.Append("<"); + w.Write("<"); break; case '>': - b.Append(">"); + w.Write(">"); break; case '&': - b.Append("&"); + w.Write("&"); break; case '"': - b.Append("""); + w.Write("""); break; default: - b.Append(c); + w.Write(c); break; } } } for (int i = 0; i < spaceCount; i++) { - b.Append(" "); + w.Write(" "); } } } @@ -176,5 +177,19 @@ namespace ICSharpCode.AvalonEdit.Highlighting /// The amount of spaces a tab gets converted to. /// public int TabSize { get; set; } + + /// + /// Writes the HTML attribute for the style to the text writer. + /// + 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("\""); + } } }