2006-12-30
语法高亮的简单JavaScript实现
关键字: 语法高亮 JavaScript作者:cleverpig

最近参考Fernando M.A.d.S编写的CodePress,做了一个简单的JavaScript语法高亮实现(需要prototype1.4版支持)。在这里,和大家分享一下。
演示页面:

页面延用CodePress的风格,使用多个分别对应语言的CSS文件,文件名以相应的语言为后缀:比如codepress-java.css就是java语言的样式表:
css 代码
- b,i,s {display:inline;font-size:12px;font-weight:bold;text-decoration:none;letter-spacing:1px}
- b {color:#7F0055;} /* reserved words */
- i, i b, i s {color:#3F7F5F;} /* comments */
- s, s b {color:#2A00FF;font-weight:normal;} /* strings */
页面主要方法synchronize和render调用后面介绍的HighlightRender类方法:
js 代码
- //同步语法显示:动态修改css,进行渲染
- function synchronize(syntax){
- $('syntaxHighlightCSSLink').href='./css/languages/codepress-'
- +syntax+'.css?forceReload='+(new Date().valueOf());
- $('syntaxSelector').value=$('currentSyntax').innerHTML=syntax;
- if ($F('editor')!=''){
- render();
- }
- }
- //根据语言选择栏的值进行渲染,并将渲染结构显示在highlightView中
- function render(){
- var syntaxRender=new HighlightRender($F('syntaxSelector'));
- $('highlightView').innerHTML=syntaxRender.syntaxHighlight($F('editor'));
- }
核心代码为前面的languageReplacePatterns属性(按照语言区分的正则表达式数组)和syntaxHighlight方法。
js 代码
- /**
- * 语法高亮渲染器:支持java、javascript、php、html、css
- */
- var HighlightRender=Class.create();
- HighlightRender.prototype={
- //用于语法高亮的语言替换模板
- languageReplacePatterns:{
- java : [
- …
- ],
- javascript : [
- …
- ],
- php : [
- …
- ],
- html : [
- …
- ],
- css : [
- …
- ],
- text : [
- // do nothing, as expected
- ]
- },
- //当前使用的语言
- language:'',
- initialize:function(language){
- this.language=language;
- },
- /**
- * 计算数字的位数
- * @param num
- * @return
- */
- calculateNumBit:function(num){
- var s=''+num;
- return s.length;
- },
- /**
- * 添加行编号
- * @param str 字符串
- * @return 返回添加行编号后的html
- */
- addIdentity:function(str){
- var rows=str.split('<br>');
- var code='';
- var codeLineMaxBit=this.calculateNumBit(rows.length);///10+1;
- for(var i=0;i<rows.length;i++){
- var codeLineNum=i+1;
- var currentLineBit=this.calculateNumBit(i+1);///10+1;
- for(var j=0;j<=codeLineMaxBit-currentLineBit;j++){
- codeLineNum+=' ';
- }
- var codeLine='<id>'+codeLineNum+'</id>'+rows[i]+'<br>';
- code+=codeLine;
- }
- return code;
- },
- /**
- * 语法高亮
- * @param str 原始字符串
- * @return 返回高亮处理后的html
- */
- syntaxHighlight:function(str){
- var ret=str;
- if (this.language=='html'){
- ret=ret.escapeHTML();
- }
- ret = ret.replace(/<.*?>/g,'').replace(/\n/g,'<br>').replace(/\s/g,' ');
- if (ret.lastIndexOf('<br>')<0){
- ret+='<br>';
- }
- for(i=0;i<this.languageReplacePatterns[this.language].length;i++){
- ret = ret.replace(
- this.languageReplacePatterns[this.language][i],
- this.languageReplacePatterns[this.language][i+1]);
- }
- ret=this.addIdentity(ret);
- return ret;
- }
- }
辅助工具类OSUtil:
js 代码
- /**
- * 工具类
- */
- var OSUtil=Class.create();
- OSUtil.prototype={
- initialize:function(){},
- /**
- * 测试浏览器类型
- * @return IE 或者 Mozilla
- */
- detectOS:function(){
- if (window.navigator.appName.indexOf('Microsoft')>=0){
- return "IE";
- }
- else if (window.navigator.appName.indexOf('Netscape')>=0){
- return "Mozilla";
- }
- },
- /**
- * 通过事件找到事件触发对象
- * @param evt 事件对象
- * @return 事件触发对象
- */
- getElementByEvent:function(evt){
- //根据事件的发起者id查找影响者cellUnit,进而触发数据变化的影响
- var elementId='';
- if (this.detectOS()=='IE'){
- elementId=evt.srcElement.id;
- }
- else{
- elementId=evt.currentTarget.id;
- }
- return $(elementId);
- }
- }
更完善的实现:

dp.SyntaxHighlighter堪称
实现highlight的JS“忍者”
dp.SyntaxHighlighter
相关资源:
演示代码下载
在线演示
Prototype开发者手册
Fernando M.A.d.S编写的CodePress
评论
cleverpig
2007-01-04
恩,大家说得有道理。应该参考一下javaeye的code标签,使用
的形式把代码行功能提炼出来,然后再加上代码收缩功能。
但是使用ol+lo模式渲染代码的做法,需要重新修改css和正则表达式。
本文是出于演示和研究的目的,如果实际使用还是直接使用dp.SyntaxHighlighter比较好。
<ol start="1"> <li class="alt">..</li> ... </ol>
的形式把代码行功能提炼出来,然后再加上代码收缩功能。
但是使用ol+lo模式渲染代码的做法,需要重新修改css和正则表达式。
本文是出于演示和研究的目的,如果实际使用还是直接使用dp.SyntaxHighlighter比较好。
daoger
2006-12-31
lighter
2006-12-31
非常不错,看一下上面的代码高亮的演示,楼主可以改进一下,做得更好一些.
强烈支持一下
强烈支持一下
JavaFlasher
2006-12-31
确实不错,就是缺少 代码折叠 功能, 非常遗憾 不知道 这个功能 怎么实现 !
- 浏览: 60059 次
- 性别:


- 详细资料
搜索本博客
最近加入圈子
最新评论
-
掌控上传进度的AJAX Uploa ...
我在系统中也用的是这个机制. 但是有个问题想请教一下:当检查到content-l ...
-- by qzhong1028 -
掌控上传进度的AJAX Uploa ...
不错!谢谢...跑起来了...但是 我的鼠标一直在闪...有人遇到过这个吗?
-- by classicbride -
掌控上传进度的AJAX Uploa ...
把fileUpload_single.html放到里层目录,且修改了js的相对地 ...
-- by xiao7cn -
掌控上传进度的AJAX Uploa ...
我用的是U3版 我去掉了com\bjinfotech\practice\ajax ...
-- by qcs0726 -
掌控上传进度的AJAX Uploa ...
slepher 写道如果同时开着两个窗口进行上传会出现卡进度条的现象 有什么好 ...
-- by hax






评论排行榜