博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

为论坛和Blog添加代码高亮显示的功能。

Posted on 2009-10-26 09:14  eevann  阅读(379)  评论(1)    收藏  举报

在cnblogs和许多其他论坛、Blog上都有插入程序代码高亮显示的功能。现参考cnblogs的为例,以discuz!NT 2.0 rc2为例,说明如何增加插入代码高亮功能。

cnblogs的代码高亮功能是通过一个共享软件实现的,可以到以下网址下载使用
http://www.actiprosoftware.com/Download/Freeware.aspx

此软件的Api很简单,就是一个Asp.net的控件。可以在网页上输出高亮显示的代码。但我们不想让高亮代码在网页上输出,而是插入到文章中。可以对discuz自带的Editor进行改造,以达到响应的功能。

首先将 ActiproSoftware.CodeHighlighter.Net20.dll、ActiproSoftware.Shared.Net20.dllCodeHighlighterTest.dll Copy到discuz的bin目录。然后在discuz的页面文件价(aspx/1)下添加InsertCode.aspx文件,内容如下

 

  1  <%@ Page Language="C#" %>
  2  <%@ Import Namespace="ActiproSoftware.CodeHighlighter" %>
  3 <%@ Import Namespace="System.Reflection" %>
  4 
  5  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  6  
  7  <script runat="server">
  8      protected string ReturnCode;
  9      
 10     protected override void OnLoad(EventArgs e)
 11     {
 12         if (!IsPostBack)
 13         {
 14     //绑定列表,显示所有支持的语言        CodeHighlighterConfiguration config = (CodeHighlighterConfiguration)ConfigurationManager.GetSection("codeHighlighter");
 15             string[] keys = new string[config.LanguageConfigs.Keys.Count];
 16             config.LanguageConfigs.Keys.CopyTo(keys, 0);
 17             Array.Sort(keys);
 18             foreach (string key in keys)
 19             {
 20                 LanguageDropDownList.Items.Add(key);
 21             }

 22             LanguageDropDownList.SelectedIndex = LanguageDropDownList.Items.IndexOf(LanguageDropDownList.Items.FindByText("C#"));
 23         }

 24         
 25         base.OnLoad(e);
 26     }

 27
 28     protected void Insert_Click(object sender, EventArgs e)
 29     {
 30         ActiproSoftware.CodeHighlighter.CodeHighlighter ch = new ActiproSoftware.CodeHighlighter.CodeHighlighter();
 31         ch.LanguageKey = LanguageDropDownList.SelectedValue;
 32         ch.Text = Code.Text;
 33         ch.Page = this;
 34        Type t = ch.GetType();
 35 
 36         //通过反射运行控件的处理代码的私有方法
 37         MethodInfo method = t.GetMethod("a", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);
 38         method.Invoke(ch, null);
 39 
 40         //通过反射处理后的代码
 41         FieldInfo field = t.GetField("i", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);
 42         ReturnCode = (string)field.GetValue(ch);
 43 
 44         //将代码放入pre标签中以保持代码格式,并将代码以JavaScript字符串的格式编码,以输出到浏览器
 45         ReturnCode = JStringEncode("<pre style='background-color:#eeeeee;font-size:13px;BORDER:1px solid #CCCCCC;PADDING-RIGHT: 5px;PADDING-BOTTOM: 4px;PADDING-left: 4px;PADDING-TOP: 4px;WIDTH: 98%;word-break:break-all'>" + ReturnCode + "</pre>");
 46         ReturnPanel.Visible = true;
 47     }

 48         /**//// <summary>
 49         /// 替换掉字符串中的特殊字符,如把 " 替换成 \"
 50         /// </summary>
 51         /// <param name="str"></param>
 52         /// <returns></returns>

 53         public static string JStringEncode( string str )
 54         {
 55             if( str == null )
 56             {
 57                 return string.Empty;
 58             }

 59             //替换反斜杠
 60             str = str.Replace( @"\"@"\\" );
 61             //替换回车
 62             str = str.Replace( "\r"@"\r" );
 63             str = str.Replace( "\n"@"\n" );
 64             //替换 " 号
 65             str = str.Replace( "\"""\\\"" );
 66             return str;
 67         }

 68 </script>
 69 
 70 <html xmlns="http://www.w3.org/1999/xhtml">
 71 
 72 <head id="Head1" runat="server">
 73     <title>插入源代码</title>
 74 </head>
 75 <body>
 76     <form id="form1" runat="server">
 77         <div>
 78             <table id="Table1" class="tb" cellspacing="0" cellpadding="3" border="0">
 79                 <tr>
 80                     <th align="right" style="width: 80px;">
 81                         编程语言:</th>
 82                     <td>
 83                         <asp:DropDownList ID="LanguageDropDownList" runat="server" Width="100px">
 84                         </asp:DropDownList></td>
 85                </tr>
 86                <!--tr>
 87                    <th align="right">
 88                        选项:</th>
 89                    <td>
 90                         <input id="chkLineNumberMarginVisible" type="checkbox" name="chkLineNumberMarginVisible" /><label
 91                             for="chkLineNumberMarginVisible">显示行号</label>&nbsp;<input id="chkOutliningEnabled"
 92                                 type="checkbox" name="chkOutliningEnabled" checked="checked" /><label for="chkOutliningEnabled">允许代码折叠</label>&nbsp;<input
 93                                     id="ckbIsCollapse" type="checkbox" name="ckbIsCollapse" /><label for="ckbIsCollapse">全部折叠</label>&nbsp;折叠标题:
 94                         <input name="txbCollapseText" type="text" id="txbCollapseText" style="width: 70" /></td>
 95                 </tr-->
 96                 <tr>
 97                     <th valign="top" align="right">
 98                        代码:</th>
 99                    <td>
100                       <asp:TextBox ID="Code" runat="server" Height="200px" TextMode="MultiLine" Width="500px"></asp:TextBox></td>
101               </tr>
102               <tr>
103                   <td>
104                       &nbsp;</td>
105                   <td>
106                       &nbsp;<asp:Button ID="Insert" runat="server" OnClick="Insert_Click" Text="确定" />&nbsp;&nbsp;&nbsp;<input
107                            onclick="return window.close()" type="button" value="关闭"></td>
108                </tr>
109            </table>
110        </div>
111        <asp:Panel ID="ReturnPanel" runat="server" Visible="false">
112        <script language="javascript">
113        //在Opener页面中插入处理后的Html文本
114        window.opener.insertText("<% = ReturnCode %>");
115        window.close();
116        </script>
117        </asp:Panel>
118    </form>
119</body>
120</html>
121

 然后修改discuz的webconfig,如下所示

 

  1<?xml version="1.0" encoding="utf-8" ?>
  
2<configuration>
  
3    <configSections>
  
4        <section name="codeHighlighter" requirePermission="false" type="ActiproSoftware.CodeHighlighter.CodeHighlighterConfigurationSectionHandler, ActiproSoftware.CodeHighlighter.Net20"/>
  
5    </configSections>
  
6
  
7  <system.web>
  
8
  
9    <compilation 
 
10         defaultLanguage="c#"
 
11         debug="false"
 
12    />
 
13     
 
14    <authorization>
 
15        <allow users="*" /> <!-- 允许所有用户 -->
 
16    </authorization>
 
17
 
18    <trace
 
19        enabled="false"
 
20        requestLimit="10"
 
21        pageOutput="false"
 
22        traceMode="SortByTime"
 
23        localOnly="true"
 
24    />
 
25
 
26    <!-- 以下为Discuz!NT相关的一些系统设置, 如果有疑问, 请访问 http://nt.discuz.net/config 获得更详细的说明
 27    -->
 
28
 
29
 
30
 
31    <!--  注意:此节设置错误信息的显示
 
32
 
33          "On" 始终显示自定义(友好的)信息。
 
34          "Off" 始终显示详细的 ASP.NET 错误信息。
 
35          "RemoteOnly" 只对不在本地 Web 服务器上运行的
 
36    -->
 
37    <customErrors 
 
38    mode="RemoteOnly" 
 
39    /> 
 
40
 
41    <!--  注意:此节设置全球化,Discuz!NT由此支持多语言。
 
42    -->
 
43    <globalization 
 
44            requestEncoding="utf-8" 
 
45            responseEncoding="utf-8" 
 
46            fileEncoding="utf-8"
 
47    />
 
48
 
49    <!--  注意:此节设置是否使用ASP.net表单安全验证,Discuz!NT使用自己的验证。
 
50    -->
 
51    <pages
 
52            validateRequest="false"
 
53            enableEventValidation="false"
 
54            enableViewStateMac="false"
 
55            viewStateEncryptionMode ="Never"
 
56    /> 
 
57
 
58    <!--  注意:此节设置由Discuz!NT接管http请求。不会干涉对非Discuz!NT论坛路径下的请求。
 
59    -->
 
60    <httpModules>
 
61        <add type="Discuz.Forum.HttpModule, Discuz.Forum" name="HttpModule" />
 
62    </httpModules>
 
63
 
64    <xhtmlConformance mode="Legacy"/>
 
65
 
66    <httpRuntime maxRequestLength="2097151" executionTimeout="3600"/>
 
67
 
68    <webServices>
 
69      <protocols>
 
70        <add name="HttpGet" />
 
71        <add name="HttpPost"/>
 
72      </protocols>
 
73    </webServices>
 
74
 
75
 
76 </system.web>
77
 
78    <codeHighlighter>
 
79        <cache languageTimeout="3"/>
 
80        <keywordLinking enabled="true" target="_blank" defaultKeywordCollectionKey="ActiproKeywords">
 
81            <keywordCollection key="ActiproKeywords">
 
82                <explicitKeyword tokenKey="IdentifierToken" patternValue="Actipro" url="http://www.actiprosoftware.com" caseSensitive="false"/>
 
83                <explicitKeyword tokenKey="IdentifierToken" patternValue="CodeHighlighter" url="http://www.codehighlighter.com" caseSensitive="false"/>
 
84            </keywordCollection>
 
85        </keywordLinking>
 
86        <languages>
 
87            <language key="Assembly" definitionPath="~/Languages/Lexers/ActiproSoftware.Assembly.xml"/>
 
88            <language key="BatchFile" definitionPath="~/Languages/Lexers/ActiproSoftware.BatchFile.xml"/>
 
89            <language key="C#" definitionPath="~/Languages/Lexers/ActiproSoftware.CSharp.xml"/>
 
90            <language key="CSS" definitionPath="~/Languages/Lexers/ActiproSoftware.CSS.xml"/>
 
91            <language key="HTML" definitionPath="~/Languages/Lexers/ActiproSoftware.HTML.xml"/>
 
92            <language key="INIFile" definitionPath="~/Languages/Lexers/ActiproSoftware.INIFile.xml"/>
 
93            <language key="Java" definitionPath="~/Languages/Lexers/ActiproSoftware.Java.xml"/>
 
94            <language key="JScript" definitionPath="~/Languages/Lexers/ActiproSoftware.JScript.xml"/>
 
95            <language key="Lua" definitionPath="~/Languages/Lexers/ActiproSoftware.Lua.xml"/>
 
96            <language key="MSIL" definitionPath="~/Languages/Lexers/ActiproSoftware.MSIL.xml"/>
 
97            <language key="Pascal" definitionPath="~/Languages/Lexers/ActiproSoftware.Pascal.xml"/>
 
98            <language key="Perl" definitionPath="~/Languages/Lexers/ActiproSoftware.Perl.xml"/>
 
99            <language key="PHP" definitionPath="~/Languages/Lexers/ActiproSoftware.PHP.xml"/>
100            <language key="PowerShell" definitionPath="~/Languages/Lexers/ActiproSoftware.PowerShell.xml"/>
101            <language key="Python" definitionPath="~/Languages/Lexers/ActiproSoftware.Python.xml"/>
102            <language key="SQL" definitionPath="~/Languages/Lexers/ActiproSoftware.SQL.xml"/>
103            <language key="VB.NET" definitionPath="~/Languages/Lexers/ActiproSoftware.VBDotNet.xml"/>
104            <language key="VBScript" definitionPath="~/Languages/Lexers/ActiproSoftware.VBScript.xml"/>
105            <language key="XAML" definitionPath="~/Languages/Lexers/ActiproSoftware.XAML.xml"/>
106            <language key="XML" definitionPath="~/Languages/Lexers/ActiproSoftware.XML.xml"/>
107        </languages>
108        <lineNumberMargin foreColor="Teal" paddingCharacter=" " visible="true"/>
109        <outlining enabled="true" imagesPath="~/Images/OutliningIndicators/"/>
110        <spacesInTabs count="4"/>
111    </codeHighlighter>
112
113</configuration>

 Copy高亮组件的 Languages\Lexers、Images\OutliningIndicators 目录到discuz的指定目录

在discuz的编辑器文件 editor\editor.js,在function discuzcode(cmd, arg)函数中if else组里添加处理insertcode的代码

if (cmd == "insertcode")
    {
        window.open(
'../InsertCode.aspx'null'height=500, width=600, toolbar=no, menubar=no, scrollbars=no, resizable=no,location=no, status=no');
    }
修改discuz编辑器文件 editor\cp_editor.htm 在插入图片后变添加插入代码的命令

 

<id="posteditor_cmd_insertcode">插入代码</a>

 

现在,discuz的blog里就有插入高亮代码的功能了。