// SharpDevelop samples // Copyright (c) 2007, AlphaSierraPapa // All rights reserved. // // Redistribution and use in source and binary forms, with or without modification, are // permitted provided that the following conditions are met: // // - Redistributions of source code must retain the above copyright notice, this list // of conditions and the following disclaimer. // // - Redistributions in binary form must reproduce the above copyright notice, this list // of conditions and the following disclaimer in the documentation and/or other materials // provided with the distribution. // // - Neither the name of the SharpDevelop team nor the names of its contributors may be used to // endorse or promote products derived from this software without specific prior written // permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS &AS IS& AND ANY EXPRESS // OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER // IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT // OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using System; using System.Collections.Generic; using System.IO; using System.Text; using System.Xml; using ICSharpCode.TextEditor; using ICSharpCode.TextEditor.Document; namespace ICSharpCode.HtmlSyntaxColorizer { public class HtmlWriter { public bool AlternateLineBackground; public bool ShowLineNumbers; public string MainStyle = "font-size: small; font-family: Consolas, \"Courier New\", Courier, Monospace;"; public string LineStyle = "margin: 0em;"; public string AlternateLineStyle = "margin: 0em; width: 100%; background-color: #f0f0f0;"; #region Stylesheet cache /// /// Specifies whether a CSS stylesheet should be created to reduce the size of the created code. /// The default value is true. /// public bool CreateStylesheet = true; /// /// Specifies the prefix to use in front of generate style class names. /// public string StyleClassPrefix = "code"; Dictionary stylesheetCache = new Dictionary(); /// /// Resets the CSS stylesheet cache. Stylesheet classes will be cached on GenerateHtml calls. /// If you want to reuse the HtmlWriter for multiple /// public void ResetStylesheetCache() { stylesheetCache.Clear(); } 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(" }"); } } #endregion public string GenerateHtml(string code, string highlighterName) { IDocument doc = new DocumentFactory().CreateDocument(); doc.HighlightingStrategy = HighlightingManager.Manager.FindHighlighter(highlighterName); doc.TextContent = code; return GenerateHtml(doc); } HighlightColor currentDefaultTextColor; public string GenerateHtml(IDocument document) { 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;"; } StringBuilder b = new StringBuilder(); if (CreateStylesheet) { b.AppendLine(""); } if (ShowLineNumbers || AlternateLineBackground) { b.Append(""); int longestNumberLength = 1 + (int)Math.Log10(document.TotalNumberOfLines); int lineNumber = 1; foreach (LineSegment lineSegment in document.LineSegmentCollection) { b.Append(""); 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); } b.AppendLine(""); lineNumber++; } b.AppendLine(""); } else { b.Append(""); foreach (LineSegment lineSegment in document.LineSegmentCollection) { PrintWords(lineSegment, b); b.AppendLine(); } b.AppendLine(""); } 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 (currentSpan != null) b.Append(""); } static string HtmlEncode(string word) { return word.Replace("&", "&").Replace("<", "<").Replace(">", ">"); } void WriteStyle(string style, StringBuilder b) { 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; string style = "color: " + ColorToString(word.Color) + ";"; if (word.Bold) { style += " font-weight: bold;"; } if (word.Italic) { style += " font-style: italic;"; } if (word.SyntaxColor.HasBackground) { style += " background-color: " + ColorToString(word.SyntaxColor.BackgroundColor) + ";"; } return style; } static string ColorToString(System.Drawing.Color color) { return "#" + color.R.ToString("x2") + color.G.ToString("x2") + color.B.ToString("x2"); } } }