全文本代码着色(带源码和示例)
来源:互联网 发布:淘宝引擎推广怎么操作 编辑:程序博客网 时间:2024/06/11 18:59
写了一个全文本的C#代码着色器,不采用任何图片,因为事先没有参考任何已有着色器源码,可能有些地方实现的不是很优雅,如果谁手里有其他着色器的源码,望多交流!
完整源码下载地址:
http://teddy.51.net/products/HtmlCodeColor.rar
代码示例:
完整源码下载地址:
http://teddy.51.net/products/HtmlCodeColor.rar
代码示例:
using System;
using System.Text.RegularExpressions;
namespace CN.Teddy.Util.HtmlCodeColor
{
/// <summary>
/// C#代码着色适配器
/// </summary>
public class CSharpAdapter : ICodeColorAdapter
{
+ Constructors
public CSharpAdapter()
{
//null
}
- #endregion
+ Private Members
/// <summary>
/// 为//和/**/类型的注释着色
/// </summary>
/// <param name="src">输入源码</param>
/// <returns>格式化后的源码</returns>
private string ColorBasicComment(string src)
{
string retCode = src;
Regex r1 = new Regex(@"(^|;)([ /t]*)(//.*$)", RegexOptions.Multiline);
retCode = r1.Replace(retCode, "$1$2<span style=/"color: green/">$3</span>");
Regex r2 = new Regex(@"(^|[ /t]+)(//*[^/*/]*/*/[ /t/r]*$)", RegexOptions.Multiline);
retCode = r2.Replace(retCode, new MatchEvaluator(this.ColorBasicComment2Evaluator));
return retCode;
}
/// <summary>
/// 为///类型的注释着色
/// </summary>
/// <param name="src">输入源码</param>
/// <returns>格式化后的源码</returns>
private string ColorXmlComment(string src)
{
string retCode = src;
Regex r1 = new Regex(@"(/// *)<(.*)>", RegexOptions.Multiline);
retCode = r1.Replace(retCode, new MatchEvaluator(this.ColorXmlCommentEvaluator));
Regex r2 = new Regex(@"(/// *)(.*$)", RegexOptions.Multiline);
retCode = r2.Replace(retCode, "<span style=/"color: gray/">$1</span>$2");
return retCode;
}
/// <summary>
/// 为折叠显示代码构建HtmlTable框架
/// </summary>
/// <param name="src">输入源码</param>
/// <returns>格式化后的源码</returns>
private string DrawCollapseFrameTable(string src)
{
System.Text.StringBuilder retCode = new System.Text.StringBuilder();
string frameHeader = "<table border=0 cellpadding=0 cellspacing=0 width=95% style='border: windowtext 0.5pt solid; background-color:#fefefe'><tr><td valign=top align=center style='border-right-color: #808080; border-right-style: solid; border-right-width: 1px'><table border=0 cellpadding=0 cellspacing=0><tr><td> </td><td> </td></tr></table></td><td><table border=0 cellpadding=1 cellspacing=0 width=100%>";
string frameTailer = "</table></td></tr></table>";
retCode.Append(frameHeader);
string[] lines = src.Split('/n');
foreach (string line in lines)
{
string formatedLine = line.Trim();
string lineHeader = "<tr><td style='width: 0px'><table style='width: 9px; height: 9px'><tr><td></td></tr></table></td><td style='width: 0px'></td><td style='width: 100%'><code style='font: 9pt Tahoma'>";
string lineTailer = "</code></td></tr>";
formatedLine = lineHeader + formatedLine + lineTailer;
retCode.Append(formatedLine);
}
retCode.Append(frameTailer);
return retCode.ToString();
}
/// <summary>
/// 折叠Region
/// </summary>
/// <param name="src">输入源码</param>
/// <returns>格式化后的源码</returns>
private string CollapseRegion(string src)
{
string retCode = src;
string lineHeader = "<tr><td style='width: 0px'><table style='width: 9px; height: 9px'><tr><td></td></tr></table></td><td style='width: 0px'></td><td style='width: 100%'><code style='font: 9pt Tahoma'>";
Regex r = new Regex(lineHeader + @"( )*<span style=/""color: blue/"">#region<.*$", RegexOptions.Multiline);
while (r.Match(retCode).Success)
{
//add "+" tag
retCode = r.Replace(retCode, new MatchEvaluator(this.CollapseRegionEvaluator));
}
return retCode;
}
/// <summary>
/// 为一行源码中的关键字着色
/// </summary>
/// <param name="codeLine">某一行源码</param>
/// <param name="keywordList">关键字列表</param>
/// <returns>格式化后的源码</returns>
/// <summary>
private string ColorKeyword(string codeLine, string[] keywordList)
{
string retCode = codeLine;
if (!retCode.StartsWith("//"))
{
foreach (string keyword in KEYWORD_LIST)
{
Regex r = new Regex(@"(^|/s+|,|/)|/(|/{|/}|/[|/]|/.|=|;)(" + keyword + @")(/s+|,|/)|/(|/{|/}|/[|/]|/.|=|;|$)");
retCode = r.Replace(retCode, "$1<span style=/"color: blue/">$2</span>$3");
}
}
retCode = ClearColoredKeyworsInString(retCode);
return retCode.Trim();
}
/// <summary>
/// 清除字符串中的被着色的关键字
/// </summary>
/// <param name="codeLine">某一行源码</param>
/// <returns>格式化后的源码</returns>
private string ClearColoredKeyworsInString(string codeLine)
{
System.Text.StringBuilder retCode = new System.Text.StringBuilder();
string str = codeLine.Trim();
int indexOfQuot = str.IndexOf(""");
int lengthOfQuot = """.Length;
if (indexOfQuot >= 0)
{
while (indexOfQuot >= 0)
{
retCode.Append(str.Substring(0, indexOfQuot + lengthOfQuot));
str = str.Substring(indexOfQuot + lengthOfQuot);
indexOfQuot = str.IndexOf(""");
if (indexOfQuot >= 0)
{
string inStr = str.Substring(0, indexOfQuot + lengthOfQuot);
inStr = inStr.Replace("/"color: blue/"", "/"/"");
retCode.Append(inStr);
str = str.Substring(indexOfQuot + lengthOfQuot);
}
indexOfQuot = str.IndexOf(""");
}
}
retCode.Append(str);
return retCode.ToString();
}
public static string[] KEYWORD_LIST = {
"abstract", "event", "new", "struct", "as", "explicit", "null", "switch",
"base", "extern", "object", "this", "bool", "false", "operator", "throw",
"break", "finally", "out", "true", "byte", "fixed", "override", "try",
"case", "float", "params", "typeof", "catch", "for", "private", "uint",
"char", "foreach", "protected", "ulong", "checked", "goto", "public",
"unchecked", "class", "if", "readonly", "unsafe", "const", "implicit",
"ref", "ushort", "continue", "in", "return", "using", "decimal", "int",
"sbyte", "virtual", "default", "interface", "sealed", "volatile",
"delegate", "internal", "short", "void", "do", "is", "sizeof", "while",
"double", "lock", "stackalloc", "else", "long", "static", "enum",
"namespace", "string", "get", "set", "#region", "#endregion", "true",
"false"
};
private string ColorXmlCommentEvaluator(Match m)
{
Regex r = new Regex("(^.*>)(.*)(</.*$)");
if (r.Match(m.Value).Success)
{
return r.Replace(m.Value, "<span style=/"color: gray/">$1</span>$2<span style=/"color: gray/">$3</span>");
}
else
{
return "<span style=/"color: gray/">" + m.Value + "</span>";
}
}
private string ColorBasicComment2Evaluator(Match m)
{
System.Text.StringBuilder retCode = new System.Text.StringBuilder();
string[] lines = m.Value.Split('/n');
foreach (string line in lines)
{
retCode.Append("<span style=/"color: green/">" + line + "</span>" + "/n");
}
return retCode.ToString();
}
private string CollapseRegionEvaluator(Match m)
{
//get region code block
string retCode = m.Value;
string lineHeader = "<tr><td style='width: 0px'><table style='width: 9px; height: 9px'><tr><td></td></tr></table></td><td style='width: 0px'></td><td style='width: 100%'><code style='font: 9pt Tahoma'>";
string lineTailer = "</code></td></tr>";
Regex r = new Regex("^" + lineHeader + @"( )*<span style=/""color: blue/"">#region</span>[^<]*" + lineTailer, RegexOptions.Multiline);
retCode = r.Replace(retCode, new MatchEvaluator(this.CollapseRegionEvaluator2));
//find out #region - #endregion block & add collapse code
string endRegionLinePattern = "<tr><td style='width: 0px'><table style='width: 9px; height: 9px'><tr><td></td></tr></table></td><td style='width: 0px'></td><td style='width: 100%'><code style='font: 9pt Tahoma'>( )*<span style=/"color: blue/">#endregion</span></code></td></tr>";
Regex r2 = new Regex(endRegionLinePattern);
string endRegionLine = r2.Match(retCode).Value;
string formatedEndRegionLine = endRegionLine.Replace("<td style='width: 0px'></td><td style='width: 100%'>", "<td style='width: 0px'><span style='position: relative; left: -12px; font: 12px'><font color=#808080 face='Tahoma'>-</font></span></td><td style='width: 100%'>");
string regionBlock = retCode.Substring(0, retCode.IndexOf(endRegionLine)) + formatedEndRegionLine;
string spaces = new Regex("( )+").Match(regionBlock).Value;
string regionDescWidthTag = new Regex("#region</span> ([^<]*)</code>").Match(regionBlock).Value;
string regionDesc = regionDescWidthTag.Substring(15, regionDescWidthTag.Length - ("#region</span> ").Length - ("</code>").Length);
regionBlock = regionBlock.Replace("</tr><tr><td style='width: 0px'>", "</tr><tr style='display: none'><td style='width: 0px'>");
regionBlock = regionBlock.Substring(0, regionBlock.IndexOf("<code style='font: 9pt Tahoma'>") + "<code style='font: 9pt Tahoma'>".Length) +
"<span>" + spaces + "</span>" + "<span style='border: 1px solid gray'><font color=gray>" + regionDesc + "</font></span>" +
regionBlock.Substring(regionBlock.IndexOf("</code>"));
retCode = regionBlock + retCode.Substring(retCode.IndexOf(endRegionLine) + endRegionLine.Length);
return retCode;
}
private string CollapseRegionEvaluator2(Match m)
{
string retCode = m.Value;
//add rectangle
retCode = retCode.Replace("style='width: 9px; height: 9px'", "style='position: relative; left: -6px; top: 0px; border-color: #808080; border-style: solid; border-width: 1px; background: white; width: 9px; height: 9px'");
string spaces = new Regex("( )+").Match(m.Value).Value;
string regionDescWidthTag = new Regex("#region</span> ([^<]*)</code>").Match(m.Value).Value;
string regionDesc = regionDescWidthTag.Substring(15, regionDescWidthTag.Length - ("#region</span> ").Length - ("</code>").Length);
//add "+" tag
retCode = retCode.Replace("<td style='width: 0px'></td>", "<td style='width: 0px'><span style='position: relative; left: -16px; top: -1px; font: 12px; cursor: hand' onclick='if (this.childNodes[0].innerHTML == /"_/") { this.childNodes[0].innerHTML = /"+/"; this.style.top = /"-1px/"; this.parentNode.nextSibling.childNodes[0].innerHTML = /"<span>" + spaces + "</span><span><font color=gray>" + regionDesc + "</font></span>/"; this.parentNode.nextSibling.childNodes[0].childNodes[1].style.border = /"1px solid gray/"; for (var i = 1 + this.parentNode.parentNode.rowIndex; i < this.parentNode.parentNode.parentNode.childNodes.length; i++) { this.parentNode.parentNode.parentNode.childNodes[i].style.display=/"none/"; if ( this.parentNode.parentNode.parentNode.childNodes[i].childNodes[1].innerText.length > 0 ) { break; } } } else { this.childNodes[0].innerHTML = /"_/"; this.style.top = /"-6px/"; var oldDesc = this.parentNode.nextSibling.childNodes[0].childNodes[1].childNodes[0].innerHTML; this.parentNode.nextSibling.childNodes[0].innerHTML = /"<span>" + spaces + "</span><span><font color=blue>#region </font></span><span></span>/"; this.parentNode.nextSibling.childNodes[0].childNodes[2].innerHTML = oldDesc; for (var i = 1 + this.parentNode.parentNode.rowIndex; i < this.parentNode.parentNode.parentNode.childNodes.length; i++) { this.parentNode.parentNode.parentNode.childNodes[i].style.display=/"block/"; if ( this.parentNode.parentNode.parentNode.childNodes[i].childNodes[1].innerText.length > 0 ) { break; } } }'><font color=#808080 face='Tahoma'>+</font></span></td>");
return retCode;
}
- #endregion
+ ICodeColorAdapter 成员
/// <summary>
/// 为注释着色,例如:对C#,包括///型、//型和/**/的注释
/// </summary>
/// <param name="src">输入源码</param>
/// <returns>格式化后的源码</returns>
public string ColorComment(string src)
{
string retCode = src;
retCode = ColorBasicComment(retCode);
retCode = ColorXmlComment(retCode);
return retCode;
}
/// <summary>
/// 为关键字着色
/// </summary>
/// <param name="src">输入源码</param>
/// <returns>格式化后的源码</returns>
public string ColorKeyword(string src)
{
System.Text.StringBuilder retCode = new System.Text.StringBuilder();
string[] lines = src.Split('/n');
if (lines != null && lines.Length > 0)
{
bool isInComment = false;
foreach (string line in lines)
{
string formatedLine = line.Trim();
if (new Regex(@"(^|[ /t]+)(//*)").Match(line).Success)
{
isInComment = true;
}
if (!isInComment)
{
formatedLine = ColorKeyword(line, KEYWORD_LIST);
}
if (new Regex(@"/*/[ /t/r]*$").Match(line).Success)
{
isInComment = false;
}
retCode.Append(formatedLine + "/n");
}
}
return retCode.ToString();
}
/// <summary>
/// 使代码支持折叠显示
/// </summary>
/// <param name="src">输入源码</param>
/// <returns>格式化后的源码</returns>
public string CollapseCode(string src)
{
string retCode = src;
retCode = DrawCollapseFrameTable(retCode);
retCode = CollapseRegion(retCode);
return retCode;
}
/// <summary>
/// 代码缩进
/// </summary>
/// <param name="src">输入源码</param>
/// <returns>格式化后的源码</returns>
public string IndentCode(string src)
{
System.Text.StringBuilder retCode = new System.Text.StringBuilder();
int indent = 0;
string [] lines = src.Split('/n');
foreach (string line in lines)
{
string formatedLine = line.Trim();
Regex r = new Regex(@"/}(/}|/s)*;?/s*$");
if (r.Match(line).Success)
{
indent--;
}
for (int i = 0; i < indent; i++)
{
formatedLine = " " + formatedLine;
}
retCode.Append(formatedLine + "/n");
if (line.EndsWith("{"))
{
indent++;
}
else if (line.StartsWith("{"))
{
indent++;
}
}
return retCode.ToString();
}
- #endregion
}
}
- 全文本代码着色(带源码和示例)
- lucene实现全文检索的示例代码
- 微软一站式示例代码库新功能:提供带个示例代码下载和最新示例代码索引
- Linq动态查询与模糊查询(带源码示例)
- Linq动态查询与模糊查询(带源码示例)
- Spring Security 4 退出 示例(带源码)
- OpenGL蓝宝书源码学习(十三)第六章——OpenGL着色器和着色语言
- OpenGL(二十四) VAO、VBO和着色器使用示例
- WPF实现漂亮的自定义时钟(带示例代码)
- 带缓存的I/O操作代码示例(复习)
- JavaScript代码格式化和语法着色
- JS代码格式化和语法着色
- 代码着色
- 代码着色
- MyBatis-Spring MVC 整合示例(带源码)
- lucene全文检索应用示例及代码简析
- Lucene全文检索应用示例及代码简析
- lucene全文检索应用示例及代码简析
- 完成 BlogBenchV2 Beta,大家能帮忙做下测试吗?
- 急!有谁知道如何截获WebBrowser控件的 ie脚本错误提示 吗?
- .Net 环境下实现可变大小的无标题窗口拖动
- 读《Uml Toolkit》有感 -- 用例驱动的中小型系统设计过程
- 需求跟踪矩阵
- 全文本代码着色(带源码和示例)
- BlogBench V1.0.1 发布
- BlogBench V2.0改进目标和几个难点!
- 关于BlogBench的任何建议和Bug请在这里留言,谢谢支持!
- BlogBench Ver 1.0 发布
- 终于成功发布我的博客园处女贴,不过,真的颇费周章,两个htmleditor都非常不好用~~
- DbHelperV2 - Teddy的通用数据库访问组件设计和思考
- 正则表达式--递归匹配、非贪婪匹配与分组替换
- 解决问题:心态 原则 方法