网页源代码着色
从网上搜集了一些源代码着色资料,经过整理和优化后现将代码分享给你们。
修改 public static string[] KEYWORD_LIST属性可以自定义高亮显示关键字。
.codearea
{
margin-bottom: 5px;
margin-top: 5px;
padding: 2px 2px 2px 2px; /*font-family: verdana, sans-serif;*/
font-family: Courier New;
width: auto;
background-color: #E6F0FD;
border-right: #94AAC5 1px solid;
border-top: #94AAC5 1px solid;
border-left: #94AAC5 1px solid;
border-bottom: #94AAC5 1px solid;
}
.codecomment
{
color: Green;
}
.codecomment1
{
color: gray;
}
.codekeyword
{
color: Blue;
}
.codefont
{
font-size: 9pt;
font-family: Courier New;
}
使用方法:
修改 public static string[] KEYWORD_LIST属性可以自定义高亮显示关键字。
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
namespace vjsdn.forum
{
/// <summary>
/// 源代码着色类
/// </summary>
public class CSourceRenderer
{
/// <summary>
/// 源代码着色构造器
/// </summary>
public string RenderSource(string src)
{
string html = "";
html = ColorComment(src); //转换注释
html = ColorKeyword(html); //转换关键字
html = IndentCode(html); //空格缩进
html = ReplaceCSSTag(html); //替换CSS
html = "<div class=\"codearea\">" + html + "</div>";
return html;
}
private string ReplaceCSSTag(string src)
{
src = src.Replace(" class='codecomment' ", " class='codecomment' ");
src = src.Replace(" class='codecomment1' ", " class='codecomment1' ");
src = src.Replace(" class='codekeyword' ", " class='codekeyword' ");
src = src.Replace(" class='codefont' ", " class='codefont' ");
src = src.Replace("\r</span>", "</span>\r");
src = src.Replace("\n", "</br>");
return src;
}
/// <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 class='codecomment' >$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 class='codecomment1' >$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 = "";
string frameTailer = "<br/>";
retCode.Append(frameHeader);
string[] lines = src.Split('\n');
foreach (string line in lines)
{
string formatedLine = line.Trim();
string lineHeader = "";
string lineTailer = "<br/>";
formatedLine = lineHeader + formatedLine + lineTailer;
retCode.Append(formatedLine);
}
retCode.Append(frameTailer);
return retCode.ToString();
}
/// <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 class='codekeyword' >$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();
}
/// <summary>
/// 关键字列表
/// </summary>
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"
};
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
namespace vjsdn.forum
{
/// <summary>
/// 源代码着色类
/// </summary>
public class CSourceRenderer
{
/// <summary>
/// 源代码着色构造器
/// </summary>
public string RenderSource(string src)
{
string html = "";
html = ColorComment(src); //转换注释
html = ColorKeyword(html); //转换关键字
html = IndentCode(html); //空格缩进
html = ReplaceCSSTag(html); //替换CSS
html = "<div class=\"codearea\">" + html + "</div>";
return html;
}
private string ReplaceCSSTag(string src)
{
src = src.Replace(" class='codecomment' ", " class='codecomment' ");
src = src.Replace(" class='codecomment1' ", " class='codecomment1' ");
src = src.Replace(" class='codekeyword' ", " class='codekeyword' ");
src = src.Replace(" class='codefont' ", " class='codefont' ");
src = src.Replace("\r</span>", "</span>\r");
src = src.Replace("\n", "</br>");
return src;
}
/// <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 class='codecomment' >$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 class='codecomment1' >$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 = "";
string frameTailer = "<br/>";
retCode.Append(frameHeader);
string[] lines = src.Split('\n');
foreach (string line in lines)
{
string formatedLine = line.Trim();
string lineHeader = "";
string lineTailer = "<br/>";
formatedLine = lineHeader + formatedLine + lineTailer;
retCode.Append(formatedLine);
}
retCode.Append(frameTailer);
return retCode.ToString();
}
/// <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 class='codekeyword' >$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();
}
/// <summary>
/// 关键字列表
/// </summary>
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 class='codecomment1' >$1</span>$2<span class='codecomment1' >$3</span>");
}
else
{
return "<span class='codecomment1' >" + 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 class='codecomment' >" + line + "</span>" + "\n");
}
return retCode.ToString();
}
/// <summary>
/// 为注释着色,例如:对C#,包括///型、//型和/**/的注释
/// </summary>
/// <param name="src">输入源码</param>
/// <returns>格式化后的源码</returns>
private string ColorComment(string src)
{
string retCode = src;
retCode = ColorBasicComment(retCode);
retCode = ColorXmlComment(retCode);
return retCode;
}
/// <summary>
/// 为关键字着色
/// </summary>
/// <param name="src">输入源码</param>
/// <returns>格式化后的源码</returns>
private 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>
private 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();
if (line.Trim() == "}")
{
indent--;
}
for (int i = 0; i < indent; i++)
{
formatedLine = " " + formatedLine;
}
retCode.Append(formatedLine + "\n");
if (line.Trim() == "{" || line.EndsWith("{"))
{
indent++;
}
}
return retCode.ToString();
}
}
}
相关css定义{
Regex r = new Regex("(^.*>)(.*)(</.*$)");
if (r.Match(m.Value).Success)
{
return r.Replace(m.Value, "<span class='codecomment1' >$1</span>$2<span class='codecomment1' >$3</span>");
}
else
{
return "<span class='codecomment1' >" + 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 class='codecomment' >" + line + "</span>" + "\n");
}
return retCode.ToString();
}
/// <summary>
/// 为注释着色,例如:对C#,包括///型、//型和/**/的注释
/// </summary>
/// <param name="src">输入源码</param>
/// <returns>格式化后的源码</returns>
private string ColorComment(string src)
{
string retCode = src;
retCode = ColorBasicComment(retCode);
retCode = ColorXmlComment(retCode);
return retCode;
}
/// <summary>
/// 为关键字着色
/// </summary>
/// <param name="src">输入源码</param>
/// <returns>格式化后的源码</returns>
private 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>
private 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();
if (line.Trim() == "}")
{
indent--;
}
for (int i = 0; i < indent; i++)
{
formatedLine = " " + formatedLine;
}
retCode.Append(formatedLine + "\n");
if (line.Trim() == "{" || line.EndsWith("{"))
{
indent++;
}
}
return retCode.ToString();
}
}
}
.codearea
{
margin-bottom: 5px;
margin-top: 5px;
padding: 2px 2px 2px 2px; /*font-family: verdana, sans-serif;*/
font-family: Courier New;
width: auto;
background-color: #E6F0FD;
border-right: #94AAC5 1px solid;
border-top: #94AAC5 1px solid;
border-left: #94AAC5 1px solid;
border-bottom: #94AAC5 1px solid;
}
.codecomment
{
color: Green;
}
.codecomment1
{
color: gray;
}
.codekeyword
{
color: Blue;
}
.codefont
{
font-size: 9pt;
font-family: Courier New;
}
string htmlcode = new CSourceRenderer().RenderSource(Server.HtmlEncode(txtCode.Text));
txtCode.Text = htmlcode;
txtCode.Text = htmlcode;