Browse Source

Ported HtmlSyntaxColorizer to AvalonEdit.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@5527 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
pull/1/head
Daniel Grunwald 16 years ago
parent
commit
d79c461876
  1. 18
      samples/HtmlSyntaxColorizer/HtmlSyntaxColorizer.csproj
  2. 6
      samples/HtmlSyntaxColorizer/HtmlSyntaxColorizer.sln
  3. 219
      samples/HtmlSyntaxColorizer/HtmlWriter.cs
  4. 10
      samples/HtmlSyntaxColorizer/Main.cs
  5. 19
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HighlightedLine.cs
  6. 35
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HtmlClipboard.cs

18
samples/HtmlSyntaxColorizer/HtmlSyntaxColorizer.csproj

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<PropertyGroup>
<ProjectGuid>{6D17428C-A444-4C26-8FE3-976160F41D97}</ProjectGuid>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@ -6,6 +7,7 @@ @@ -6,6 +7,7 @@
<OutputType>Exe</OutputType>
<RootNamespace>HtmlSyntaxColorizer</RootNamespace>
<AssemblyName>HtmlSyntaxColorizer</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<OutputPath>bin\Debug\</OutputPath>
@ -23,14 +25,22 @@ @@ -23,14 +25,22 @@
</PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
<ItemGroup>
<Reference Include="ICSharpCode.TextEditor">
<HintPath>..\..\bin\ICSharpCode.TextEditor.dll</HintPath>
<SpecificVersion>False</SpecificVersion>
<Reference Include="ICSharpCode.AvalonEdit">
<HintPath>..\..\bin\ICSharpCode.AvalonEdit.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Data.DataSetExtensions">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Drawing" />
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="AssemblyInfo.cs" />

6
samples/HtmlSyntaxColorizer/HtmlSyntaxColorizer.sln

@ -1,7 +1,7 @@ @@ -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

219
samples/HtmlSyntaxColorizer/HtmlWriter.cs

@ -1,5 +1,5 @@ @@ -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; @@ -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 @@ -57,10 +58,11 @@ namespace ICSharpCode.HtmlSyntaxColorizer
public string StyleClassPrefix = "code";
Dictionary<string, string> stylesheetCache = new Dictionary<string, string>();
StringBuilder stylesheet = new StringBuilder();
/// <summary>
/// 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.
/// </summary>
public void ResetStylesheetCache()
{
@ -69,182 +71,117 @@ namespace ICSharpCode.HtmlSyntaxColorizer @@ -69,182 +71,117 @@ namespace ICSharpCode.HtmlSyntaxColorizer
string GetClass(string style)
{
return stylesheetCache[style];
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
void CacheClass(string style, StringBuilder b)
public string GenerateHtml(string code, IHighlightingDefinition highlightDefinition)
{
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(" }");
}
return GenerateHtml(new TextDocument(code), highlightDefinition);
}
#endregion
public string GenerateHtml(string code, string highlighterName)
public string GenerateHtml(TextDocument document, IHighlightingDefinition highlightDefinition)
{
IDocument doc = new DocumentFactory().CreateDocument();
doc.HighlightingStrategy = HighlightingManager.Manager.FindHighlighter(highlighterName);
doc.TextContent = code;
return GenerateHtml(doc);
return GenerateHtml(document, new DocumentHighlighter(document, highlightDefinition.MainRuleSet));
}
HighlightColor currentDefaultTextColor;
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("<style type=\"text/css\">");
if (ShowLineNumbers || AlternateLineBackground) {
CacheClass(myMainStyle, b);
CacheClass(LineStyle, b);
} else {
CacheClass(myMainStyle + LineStyle, b);
}
if (AlternateLineBackground) CacheClass(AlternateLineStyle, b);
if (ShowLineNumbers) CacheClass(LineNumberStyle, b);
foreach (LineSegment ls in document.LineSegmentCollection) {
foreach (TextWord word in ls.Words) {
CacheClass(GetStyle(word), b);
}
}
b.AppendLine("</style>");
}
StringWriter output = new StringWriter();
if (ShowLineNumbers || AlternateLineBackground) {
b.Append("<div");
WriteStyle(myMainStyle, b);
b.AppendLine(">");
output.Write("<div");
WriteStyle(output, myMainStyle);
output.WriteLine(">");
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("<pre");
for (int lineNumber = 1; lineNumber <= document.LineCount; lineNumber++) {
HighlightedLine line = highlighter.HighlightLine(lineNumber);
output.Write("<pre");
if (AlternateLineBackground && (lineNumber % 2) == 0) {
WriteStyle(AlternateLineStyle, b);
WriteStyle(output, AlternateLineStyle);
} else {
WriteStyle(LineStyle, b);
WriteStyle(output, LineStyle);
}
b.Append(">");
output.Write(">");
if (ShowLineNumbers) {
b.Append("<span");
WriteStyle(LineNumberStyle, b);
b.Append('>');
b.Append(lineNumber.ToString().PadLeft(longestNumberLength));
b.Append(": ");
b.Append("</span>");
}
if (lineSegment.Words.Count == 0) {
b.Append("&nbsp;");
} else {
PrintWords(lineSegment, b);
output.Write("<span");
WriteStyle(output, LineNumberStyle);
output.Write('>');
output.Write(lineNumber.ToString().PadLeft(longestNumberLength));
output.Write(": ");
output.Write("</span>");
}
b.AppendLine("</pre>");
lineNumber++;
PrintWords(output, line);
output.WriteLine("</pre>");
}
b.AppendLine("</div>");
output.WriteLine("</div>");
} else {
b.Append("<pre");
WriteStyle(myMainStyle + LineStyle, b);
b.AppendLine(">");
foreach (LineSegment lineSegment in document.LineSegmentCollection) {
PrintWords(lineSegment, b);
b.AppendLine();
}
b.AppendLine("</pre>");
output.Write("<pre");
WriteStyle(output, myMainStyle + LineStyle);
output.WriteLine(">");
for (int lineNumber = 1; lineNumber <= document.LineCount; lineNumber++) {
HighlightedLine line = highlighter.HighlightLine(lineNumber);
PrintWords(output, line);
output.WriteLine();
}
output.WriteLine("</pre>");
}
if (CreateStylesheet && stylesheet.Length > 0) {
string result = "<style type=\"text/css\">" + stylesheet.ToString() + "</style>" + output.ToString();
stylesheet = new StringBuilder();
return result;
} else {
return output.ToString();
}
return b.ToString();
}
void PrintWords(LineSegment lineSegment, StringBuilder b)
void PrintWords(TextWriter writer, HighlightedLine line)
{
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("</span>");
if (newSpan != null) {
b.Append("<span");
WriteStyle(newSpan, b);
b.Append('>');
}
currentSpan = newSpan;
}
b.Append(HtmlEncode(word.Word));
}
}
if (currentSpan != null) b.Append("</span>");
writer.Write(line.ToHtml(new MyHtmlOptions(this)));
}
static string HtmlEncode(string word)
class MyHtmlOptions : HtmlOptions
{
return word.Replace("&", "&amp;").Replace("<", "&lt;").Replace(">", "&gt;");
}
readonly HtmlWriter htmlWriter;
void WriteStyle(string style, StringBuilder b)
internal MyHtmlOptions(HtmlWriter htmlWriter)
{
if (CreateStylesheet) {
b.Append(" class=\"");
b.Append(GetClass(style));
b.Append('"');
} else {
b.Append(" style='");
b.Append(style);
b.Append("'");
}
this.htmlWriter = htmlWriter;
}
string GetStyle(TextWord word)
public override void WriteStyleAttributeForColor(TextWriter writer, HighlightingColor color)
{
if (word.SyntaxColor == null || word.SyntaxColor.ToString() == currentDefaultTextColor.ToString())
return null;
string style = "color: " + ColorToString(word.Color) + ";";
if (word.Bold) {
style += " font-weight: bold;";
}
if (word.Italic) {
style += " font-style: italic;";
htmlWriter.WriteStyle(writer, color.ToCss());
}
if (word.SyntaxColor.HasBackground) {
style += " background-color: " + ColorToString(word.SyntaxColor.BackgroundColor) + ";";
}
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("'");
}
}
}
}

10
samples/HtmlSyntaxColorizer/Main.cs

@ -1,5 +1,5 @@ @@ -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 @@ @@ -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 @@ -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><body>" + html + "</body></html>");
Process.Start("output.html"); // view in browser
}

19
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HighlightedLine.cs

@ -7,6 +7,7 @@ @@ -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 @@ -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 @@ -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("</span>");
w.Write("</span>");
} else {
b.Append("<span style=\"");
b.Append(e.Color.ToCss());
b.Append("\">");
w.Write("<span");
options.WriteStyleAttributeForColor(w, e.Color);
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();
}
/// <inheritdoc/>

35
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HtmlClipboard.cs

@ -8,6 +8,7 @@ @@ -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 @@ -101,13 +102,13 @@ namespace ICSharpCode.AvalonEdit.Highlighting
/// <summary>
/// Escapes text and writes the result to the StringBuilder.
/// </summary>
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("&nbsp;");
w.Write("&nbsp;");
else
spaceCount++;
} else if (c == '\t') {
@ -116,34 +117,34 @@ namespace ICSharpCode.AvalonEdit.Highlighting @@ -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("&nbsp;");
w.Write("&nbsp;");
}
}
spaceCount = 0;
switch (c) {
case '<':
b.Append("&lt;");
w.Write("&lt;");
break;
case '>':
b.Append("&gt;");
w.Write("&gt;");
break;
case '&':
b.Append("&amp;");
w.Write("&amp;");
break;
case '"':
b.Append("&quot;");
w.Write("&quot;");
break;
default:
b.Append(c);
w.Write(c);
break;
}
}
}
for (int i = 0; i < spaceCount; i++) {
b.Append("&nbsp;");
w.Write("&nbsp;");
}
}
}
@ -176,5 +177,19 @@ namespace ICSharpCode.AvalonEdit.Highlighting @@ -176,5 +177,19 @@ namespace ICSharpCode.AvalonEdit.Highlighting
/// 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("\"");
}
}
}

Loading…
Cancel
Save