网页源代码着色

 从网上搜集了一些源代码着色资料,经过整理和优化后现将代码分享给你们。
  修改 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(@"(/// *)&lt;(.*)&gt;", 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("&quot;");
         int lengthOfQuot = "&quot;".Length;
         if (indexOfQuot >= 0)
         {
            while (indexOfQuot >= 0)
            {
               retCode.Append(str.Substring(0, indexOfQuot + lengthOfQuot));
               str = str.Substring(indexOfQuot + lengthOfQuot);
               indexOfQuot = str.IndexOf("&quot;");
               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("&quot;");
            }
         }
         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("(^.*&gt;)(.*)(&lt;/.*$)");
   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 = "&nbsp;&nbsp;&nbsp;" + formatedLine;
      }
      retCode.Append(formatedLine + "\n");
      
      if (line.Trim() == "{" || line.EndsWith("{"))
      {
         indent++;
      }
   }
   return retCode.ToString();
}
}
}


相关css定义


.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;

posted @ 2009-12-09 18:13  J&amp;W  阅读(354)  评论(0)    收藏  举报