背景
当本Blog从PJBlog的ASP改装成JSP的时候,网页HTML编辑器就是一大软肋,PJBlog支持两种HTML编辑器支持FCKeditor和UBB,前者功能强大,内容丰富,但出于对JavaScript和CSS的不熟悉,我最后只采用了简单的UBB,但即便是UBB,我也得用Java重写UBB转义部分的代码,我先是从网上下载了某人的源码,然后对其修改和添加以适合自己的具体需求。于是乎,大量的字符串查找,匹配和替换,其中还混杂着我后来添加的一些正则表达式,代码变得凌乱不堪,当添加新的转义时,常常故此失彼。这是我打算重写UBB转义代码的首要原因。
另外,我努力使Blog以技术文章为主,有很多地方会引用到代码,而原来的UBB已被我折腾得肯定不支持code了...
最后,看到JavaEye的页面对代码支持得不错,UBB编辑也够简单,对我也刚好够用,于是决定开搞了
准备
在JavaEye上draft了一篇测试文章,把所有UBB代码都用了一边,将该文章内容(里面含有原始的UBB代码)其copy出来,以txt文件保存到本地,不妨命名为crazycow.txt。然后发布这篇文章,并使用浏览器的“另存为”把该文章的页面下载到本地,不妨命名为crazycow,于是得到一个crazycow.htm文件和一个crazycow文件夹,文件夹中的内容就是该htm页面要用到的一些资源:JavaScript代码,CSS代码和图片。
对htm的内容稍做修改,将对css, JavaScript和图片的引用链接修改正确,然后将这htm文件和文件夹,放到自己本地的应用下面,开启Tomcat,测试一下这个页面,效果和JavaEye上的一模一样,于是我知道拥有这部分内容就可以实现我的需求了。
分析
从下载的html代码可以看出,原始的含有UBB代码的文章经过JavaEye的UBB转义所形成的html代码主要集中在标签<div class="blog_content"&rt;之内,转义主要做了如下工作:
- 1,简单的UBB代码转换,比如将变成了strong,将[list]变成了ul等
- 2,code标签的转换,只是简单地把变成了pre,标签里面的内容除了将"<"html转义之外,没有做其他改动
- 3,在每一行的行尾添加了一个br,当然除了里面的换行。
到了这里,我大概知道了JavaEye实现UBB代码转义的基本原理,对于简单的UBB标签,用服务器后台程序转义直接成html代码,对于的转义,则是先将其转义成新的标签,然后再结合JavaScript和CSS实现代码高亮的功能。
于是我们在到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,最终代码就能被高亮地显示在页面上了.
[b]实现自己的UBB转义
看到这里,前台部分应该结束了,下面就是实现自己的UBB转义了,既然要用到JavaEye的前台功能,那我只能按照她的要求来实现了.我有下面两个途径:
1,使用Java的正则表达式.
2,自己对文章内容从前到后逐字做解析.
用正则表达式的好处是,抽象功能强,也比较适于结构性强的文本解析,还有强大的替换功能,你只要能写出正确的正则表达式,剩下来的工作就很简单了,而且你的代码也会很简单.然而,我在最先尝试这条路径,竟遇到了死胡同:我能匹配大部分UBB标签,除了list和code,我的正则表达式如下:
"\\[(\\w+)(=\"([\\w:,/-\\\\.]+)\")?\\]([^\\]]*)\\[/\\1\\]"
其中group(1)对应于UBB标签,如code,group(3)对应标签的属性,如java,group(4)对应于标签内的内容,因为Java的正则表达式好像是最大匹配,如果你用"\\[.*\\]"去匹配"[aa]bb[cc]"只能find到一个匹配,它把"aa]bb[cc"都用来匹配.*,于是我用排除"]"的正则表达式来匹配标签内的内容,可这样以来就匹配不了list和code了,因为它们内部都有"]",就算你将list和code单独提出来,使用多次匹配,仍只能解决list的问题,因为list有"
"特征,但这个方法不能解决code,因为code里面的内容没有特征,而且仍然会有"]",如果你的文章中存在两段code,就一点办法都没有了.再一个,如果进行多次匹配,遇到了大文章,性能上也是不划算的.(如果java的正则表达式能给出"不出现某字符串"的正则匹配,那我这个问题也能解决,不过我没有试出来,也没有找到)
于是我只好采用第二种方法,幸运的是,解析没有我想得那么复杂,很简单的逻辑也就完成了,部分代码如下.
收尾
差不多可以在我的网站上使用支持code的UBB了,最后再部署之前,我还做了一些裁减工作,将和自己需求无关的内容全部去掉,可以最大程度上减少外来代码和本地代码的冲突。于是在一遍遍Ctrl-C, Ctrl-V,F5和alert之后,我只用到了shCoreCommon.js和SyntaxHighlighter.css,其实shCoreCommon.js中还用到了定义在application.js中的部分代码,我只是觉得这部分代码很小而且很独立,就直接copy过来,放到了shCoreCommon.js里面。
结论
- 1,JavaEye实现UBB代码转义的基本原理:对于简单的UBB标签,用后台程序转义直接成html代码,对于,则是先将其转义成新的标签,然后再结合JavaScript和CSS实现代码高亮的功能。
- 2,如果以后别人网站上有自己喜欢的功能,想自己拿来用,以上的介绍的步骤是我认为是可以达到目的的,当初我抓PJ的前台也是通过这样的方法,一点点地分析出来的.
- 3,有什么不对的,欢迎大家指出.
分享到:
相关推荐
JavaEye博文JavaEye博文JavaEye博文JavaEye博文JavaEye博文
javaeye被黑 大家看看
JavaEye3.0开发手记
JavaEye+技术架构,讲述java框架的应用
javaeye的信息提示框代码之css,application.js
javaeye月刊2008年4月 总第2期.pdf
javaeye sourcecode 开源安卓客户端, JavaEYE
JavaEye新闻月刊_-_2009年3月_-_总第13期.
自己仿照javaeye写的jspf分页(原创),请各位多多指教
自己打算找一个和javaeye一样的workpress代码高亮插件, 没找到, 于是把javaeye的拔了出来.
javaeye 论坛小测试 javaeye论坛小测试答案 javaeye论坛测试答案 这下你们就省事了。
讲述javaeye硬件架构以及软件架构的发展历史
javaeye 新闻月刊 2010 4月
android javaeye客户端 javaeye发布的
javaeye 新闻月刊 2010 12月
李兴华 MLDN 整理笔记 JavaEye .doc
介绍了javaeye,如何用ruby on rails 开发出javaeye2.0网站的
javaeye Robbin 论缓存技术方面的东西