zoukankan      html  css  js  c++  java
  • 全文本代码着色(带源码和示例)

    写了一个全文本的C#代码着色器,不采用任何图片,因为事先没有参考任何已有着色器源码,可能有些地方实现的不是很优雅,如果谁手里有其他着色器的源码,望多交流!

    完整源码下载地址:
    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(@"(/// *)&lt;(.*)&gt;", 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- 1px'><table border=0 cellpadding=0 cellspacing=0><tr><td>&nbsp;</td><td>&nbsp;</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=' 0px'><table style=' 9px; height: 9px'><tr><td></td></tr></table></td><td style=' 0px'></td><td style=' 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=' 0px'><table style=' 9px; height: 9px'><tr><td></td></tr></table></td><td style=' 0px'></td><td style=' 100%'><code style='font: 9pt Tahoma'>";
                      
                      Regex r = new Regex(lineHeader + @"(&nbsp;)*<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("&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();
                }
                
                
                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 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=' 0px'><table style=' 9px; height: 9px'><tr><td></td></tr></table></td><td style=' 0px'></td><td style=' 100%'><code style='font: 9pt Tahoma'>";
                      string lineTailer = "</code></td></tr>";
                      
                      Regex r = new Regex("^" + lineHeader + @"(&nbsp;)*<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=' 0px'><table style=' 9px; height: 9px'><tr><td></td></tr></table></td><td style=' 0px'></td><td style=' 100%'><code style='font: 9pt Tahoma'>(&nbsp;)*<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=' 0px'></td><td style=' 100%'>", "<td style=' 0px'><span style='position: relative; left: -12px; font: 12px'><font color=#808080 face='Tahoma'>-</font></span></td><td style=' 100%'>");
                      string regionBlock = retCode.Substring(0, retCode.IndexOf(endRegionLine)) + formatedEndRegionLine;
                      
                      string spaces = new Regex("(&nbsp;)+").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=' 0px'>", "</tr><tr style='display: none'><td style=' 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=' 9px; height: 9px'", "style='position: relative; left: -6px; top: 0px; border-color: #808080; border-style: solid; border- 1px; background: white; 9px; height: 9px'");
                      
                      string spaces = new Regex("(&nbsp;)+").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=' 0px'></td>", "<td style=' 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 = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" + formatedLine;
                            }
                            
                            retCode.Append(formatedLine + "\n");
                            
                            if (line.EndsWith("{"))
                            {
                                  indent++;
                            }
                            else if (line.StartsWith("{"))
                            {
                                  indent++;
                            }
                      }
                      
                      return retCode.ToString();
                }
    -             #endregion
          }
    }
  • 相关阅读:
    Datediff的使用(统计本日,昨日,本周,本月)
    数据库之查询语句
    数据库之表关系
    数据库中的数据类型
    数据库概念和基本操作
    IO模型
    并发编程之协程
    GIL与多线程(线程池与进程池,同步异步阻塞非阻塞)
    并发编程之多线程
    并发编程之多进程
  • 原文地址:https://www.cnblogs.com/teddyma/p/89466.html
Copyright © 2011-2022 走看看