<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>crazycow</title>
    <description></description>
    <link>http://crazycow.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>学习JavaEye，完善自己的UBB转义</title>
        <author>crazycow</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://crazycow.javaeye.com">crazycow</a>&nbsp;
          链接：<a href="http://crazycow.javaeye.com/blog/206770" style="color:red;">http://crazycow.javaeye.com/blog/206770</a>&nbsp;
          发表时间: 2008年06月21日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <strong>背景</strong><br />当本Blog从PJBlog的ASP改装成JSP的时候，网页HTML编辑器就是一大软肋，PJBlog支持两种HTML编辑器支持FCKeditor和UBB，前者功能强大，内容丰富，但出于对JavaScript和CSS的不熟悉，我最后只采用了简单的UBB，但即便是UBB，我也得用Java重写UBB转义部分的代码，我先是从网上下载了某人的源码，然后对其修改和添加以适合自己的具体需求。于是乎，大量的字符串查找，匹配和替换，其中还混杂着我后来添加的一些正则表达式，代码变得凌乱不堪，当添加新的转义时，常常故此失彼。这是我打算重写UBB转义代码的首要原因。<br /><br />另外，我努力使Blog以技术文章为主，有很多地方会引用到代码，而原来的UBB已被我折腾得肯定不支持code了...<br /><br />最后，看到JavaEye的页面对代码支持得不错，UBB编辑也够简单，对我也刚好够用，于是决定开搞了<br /><br /><strong>准备</strong><br />在JavaEye上draft了一篇测试文章，把所有UBB代码都用了一边，将该文章内容（里面含有原始的UBB代码）其copy出来，以txt文件保存到本地，不妨命名为crazycow.txt。然后发布这篇文章，并使用浏览器的“另存为”把该文章的页面下载到本地，不妨命名为crazycow，于是得到一个crazycow.htm文件和一个crazycow文件夹，文件夹中的内容就是该htm页面要用到的一些资源：JavaScript代码，CSS代码和图片。<br /><br />对htm的内容稍做修改，将对css, JavaScript和图片的引用链接修改正确，然后将这htm文件和文件夹，放到自己本地的应用下面，开启Tomcat，测试一下这个页面，效果和JavaEye上的一模一样，于是我知道拥有这部分内容就可以实现我的需求了。<br /><br /><br /><strong>分析</strong><br />从下载的html代码可以看出，原始的含有UBB代码的文章经过JavaEye的UBB转义所形成的html代码主要集中在标签&lt;div class="blog_content"&rt;之内，转义主要做了如下工作：<br /><ul><li>1，简单的UBB代码转换，比如将<strong>变成了strong，将[list]变成了ul等</li><li>2，code标签的转换，只是简单地把[code="java"]变成了pre，标签里面的内容除了将"&lt;"html转义之外，没有做其他改动</li><li>3，在每一行的行尾添加了一个br，当然除了[code]里面的换行。</li></ul><br /><br />到了这里，我大概知道了JavaEye实现UBB代码转义的基本原理，对于简单的UBB标签，用服务器后台程序转义直接成html代码，对于[code]的转义，则是先将其转义成新的标签，然后再结合JavaScript和CSS实现代码高亮的功能。<br /><br />于是我们在到JavaScript文件中去寻找相关的代码，注意到html代码中有一段JavaScript，其中有一句：dp.SyntaxHighlighter.HighlightAll('code', true, true);　正是这句代码将原来在页面平淡无味的代码变得丰富多彩．我在shCoreCommon.js中找到了相关的定义．读下来，大概思路是：找到name属性值为code的，名为pre的所有tag；对这每一个pre标签，找到其code属性的值，如java,c等，再根据这个值用相应的高亮刷（shCoreCommon.js为每一个所支持的语言提供一个高亮刷），刷pre标签里面的代码，实际上是重新生成了能够被SynataxHighlighter.css作用的html代码，最后将原来pre标签隐藏，并插入新生成的html代码．借助于SynataxHighlighter.css，最终代码就能被高亮地显示在页面上了．<br /><br />[b]实现自己的UBB转义</strong><br />看到这里，前台部分应该结束了，下面就是实现自己的UBB转义了，既然要用到JavaEye的前台功能，那我只能按照她的要求来实现了．我有下面两个途径：<br />1,使用Java的正则表达式．<br />2,自己对文章内容从前到后逐字做解析．<br />用正则表达式的好处是，抽象功能强，也比较适于结构性强的文本解析，还有强大的替换功能，你只要能写出正确的正则表达式，剩下来的工作就很简单了，而且你的代码也会很简单．然而，我在最先尝试这条路径，竟遇到了死胡同：我能匹配大部分UBB标签，除了list和code，我的正则表达式如下：<br /><br /><strong>"\\[(\\w+)(=\"([\\w:,/-\\\\.]+)\")?\\]([^\\]]*)\\[/\\1\\]"</strong><br /><br />其中group(1)对应于UBB标签，如code，group(3)对应标签的属性，如java，group(4)对应于标签内的内容，因为Java的正则表达式好像是最大匹配，如果你用"\\[.*\\]"去匹配"[aa]bb[cc]"只能find到一个匹配，它把"aa]bb[cc"都用来匹配.*，于是我用排除"]"的正则表达式来匹配标签内的内容，可这样以来就匹配不了list和code了，因为它们内部都有"]"，就算你将list和code单独提出来，使用多次匹配，仍只能解决list的问题，因为list有"<li>"特征，但这个方法不能解决code，因为code里面的内容没有特征，而且仍然会有"]"，如果你的文章中存在两段code，就一点办法都没有了．再一个，如果进行多次匹配，遇到了大文章，性能上也是不划算的．(如果java的正则表达式能给出"不出现某字符串"的正则匹配，那我这个问题也能解决，不过我没有试出来，也没有找到)</li><br />于是我只好采用第二种方法，幸运的是，解析没有我想得那么复杂，很简单的逻辑也就完成了，部分代码如下．<br /><br /><strong>收尾</strong><br />差不多可以在我的网站上使用支持code的UBB了，最后再部署之前，我还做了一些裁减工作，将和自己需求无关的内容全部去掉，可以最大程度上减少外来代码和本地代码的冲突。于是在一遍遍Ctrl-C, Ctrl-V，F5和alert之后，我只用到了shCoreCommon.js和SyntaxHighlighter.css，其实shCoreCommon.js中还用到了定义在application.js中的部分代码，我只是觉得这部分代码很小而且很独立，就直接copy过来，放到了shCoreCommon.js里面。<br /><br /><strong>结论</strong><br /><ul><li>1，JavaEye实现UBB代码转义的基本原理：对于简单的UBB标签，用后台程序转义直接成html代码，对于[code]，则是先将其转义成新的标签，然后再结合JavaScript和CSS实现代码高亮的功能。</li><li>2，如果以后别人网站上有自己喜欢的功能，想自己拿来用，以上的介绍的步骤是我认为是可以达到目的的，当初我抓PJ的前台也是通过这样的方法，一点点地分析出来的．</li><li>3，有什么不对的，欢迎大家指出．</li></ul>
          <br/>
          <span style="color:red;">
            <a href="http://crazycow.javaeye.com/blog/206770#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 21 Jun 2008 23:29:53 +0800</pubDate>
        <link>http://crazycow.javaeye.com/blog/206770</link>
        <guid>http://crazycow.javaeye.com/blog/206770</guid>
      </item>
      <item>
        <title>测试测试</title>
        <author>crazycow</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://crazycow.javaeye.com">crazycow</a>&nbsp;
          链接：<a href="http://crazycow.javaeye.com/blog/203463" style="color:red;">http://crazycow.javaeye.com/blog/203463</a>&nbsp;
          发表时间: 2008年06月15日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          正文正文正文正文正文正文正文正文正文正文正文正文<br />正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文<br />  空格<br />	Tab<br /><strong>黑体黑体</strong><br /><div class="quote_title">引用</div><div class="quote_div">斜体斜体</div><br /><u>下划线</u><br /><pre name="code" class="java">
/**
 * @author Administrator
 */
import java.util.Date;
class A {
  int x;
  public A() {
  }
}
</pre><br /><pre name="code" class="c">
#include &lt;stdio.h>
int main() {
  //注视
  int x;
  return x;
}
</pre><br /><pre name="code" class="xml">
&lt;x>
  &lt;y att="value">
    cat
  &lt;y>
&lt;x>
</pre><br /><ul><li>列表1</li><li>列表1</li></ul><br /><ol><li>列表2</li><li>列表2</li></ol><br /><img src="http://www.crazycow.cn/logo/logo.gif" /><br /><a href="http://www.sina.com.cn" target="_blank">http://www.sina.com.cn</a><br /><a href="http://www.sina.com.cn" target="_blank">新郎</a><br /><object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,29,0" width="200" height="200"><param name="movie" value="http://d1.sina.com.cn/200806/11/140572_home-64090.swf" /><param name="quality" value="high" /><param name="menu" value="false" /><param name="wmode" value="" /><embed src="http://d1.sina.com.cn/200806/11/140572_home-64090.swf" wmode="" quality="high" menu="false" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" width="200" height="200"></embed></object><br /><img src="/images/smiles/icon_lol.gif"/><img src="/images/smiles/icon_evil.gif"/>
          <br/>
          <span style="color:red;">
            <a href="http://crazycow.javaeye.com/blog/203463#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 15 Jun 2008 13:35:57 +0800</pubDate>
        <link>http://crazycow.javaeye.com/blog/203463</link>
        <guid>http://crazycow.javaeye.com/blog/203463</guid>
      </item>
      <item>
        <title>如果需要“接口定义类方法”，该怎么办？</title>
        <author>crazycow</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://crazycow.javaeye.com">crazycow</a>&nbsp;
          链接：<a href="http://crazycow.javaeye.com/blog/99366" style="color:red;">http://crazycow.javaeye.com/blog/99366</a>&nbsp;
          发表时间: 2007年07月09日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          比如：<br />  接口C有两个实现类C1和C2<br />  C1和C2中都有一个静态成员count，分别用于统计C1和C2实例的个数<br />  请问我能否通过接口C的引用得到C1或者C2的count，如果不能改如何设计代码框架以达到相同的效果？<br />  (C1和C2只是同一个功能的两种不同的实现，不必在程序运行时同时使用，我这样做只是想尽量不改上层代码)
          <br/>
          <span style="color:red;">
            <a href="http://crazycow.javaeye.com/blog/99366#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 09 Jul 2007 12:05:56 +0800</pubDate>
        <link>http://crazycow.javaeye.com/blog/99366</link>
        <guid>http://crazycow.javaeye.com/blog/99366</guid>
      </item>
  </channel>
</rss>