为project babel加上geshi语法高亮显示
注:本文使用的正则表达式为php风格。
从v2ex到M6,我一直喜欢project babel(PB)。自己也尝试在本地或服务器上架设PB系统。遇到的一个问题是:PB只支持有限的ubb代码,当我想在PB上贴源码时,没有语法高亮很不美观。
管理员对此的答复是,简约是最好的,不必非得使用72号红色字体加上一堆感叹号才能让文字有力度。当然了,这样不给脑残以任何自证的机会,当然是不错。可是因为怕脑残搞乱而消减功能,就有些类似于怕一个男人淫乱而将全天下男人葵花宝典掉一样了。
代码语法高亮,最著名的模块莫过于geshi。我使用过php写过几行代码,语法什么的都需要现查手册;对css、form之类也不是很熟悉。因此让我自己改造PB的话,一时摸不到头绪。于是在M6上发了求教贴。有热心人sara回复如下:
有个缺点,就是一个帖子里同一种代码只能用一次,希望有高手能改进一下。
比如php代码:[php]your code[/php]
- 在v2excore.php加geshi的路径。
- 在utilities.php加
1
2
3
4
5
6
7
8
9preg_match('/\[php\]/i', $text, $_m_php_open);
preg_match('/\[\/php\]/i', $text, $_m_php_close);
if ((count($_m_php_open) == 1) && (count($_m_php_open) == count($_m_php_close))) {
list($a, $b) = explode('[php]', $text);
list($c, $d) = explode('[/php]', $b);
$c = str_replace('<', '<', $c);
$c = str_replace('>', '>', $c);
$text = $a . '<div class="codes php">' . geshi_highlight($c, 'php', '', 'true') . '</div>' . $d;
}加在
1$text = preg_replace($p, $r, $text);的后面。
我读了这段代码之后,发现它并没有大段的CSS内容,这我就放心多了。于是细读之,遇到问题就查手册。
这段代码翻译成自然语言,就是:
- 查找文本中[php]的次数$_m_php_open,以及[/php]的次数$_m_php_close;查找时不分大小写。
- 次数$_m_php_open与$_m_php_close是否相等且等于1。如果不满足条件,就不处理了。
只有两者相等且为1时,记录下[php]与[/php]之间的内容$c,把里面所有的”<”、”>”都换成”<"、">“形式。 - 把需要处理的代码部分$c使用geshi_highlight的相关语法(这里是PHP)进行格式化。
既如此,那我就可以自已实现了。
刚才使用
1 2 | preg_match('/\[php\]/i', $text, $_m_php_open); preg_match('/\[\/php\]/i', $text, $_m_php_close); |
寻找配对的标签,不是一种好的方法。因为它的通用性不强,不便于前后配对。较好的解决方法是:
1 | $text=preg_replace_callback("#\[(asp|bash|c|cpp|csharp|css|delphi|div|dos|dot|ini|java|java5|javascript|latex|lisp|luamatlab|mysql|pascal|perl|php|python|qbasic|rails|reg|ruby|scheme|sql|tcl|text|vb|vbnet|xml)\](.*?)\[/\\1\]#ix","geshi_replace",$text); |
使用正则表达式,第一组括号捕获了语言种类标签,第二组捕获了程序内容。选项i表示不分大小写,s表示点号可以匹配任意字符(包括换行符)。
之所以使用callback方式的正则匹配,是因为替换的内容多而复杂。该callback函数是这样定义的:
1 2 3 4 5 6 7 8 9 10 11 12 | function geshi_replace($matches) { //matches[1]=lang //matches[2]=code $code=$matches[2]; $lang=$matches[1]; $code = str_replace('<', '<', $code); $code = str_replace('>', '>', $code); $str = '<div class="code">'. geshi_highlight($code, $lang,'','true') .'</div>'; $str = str_replace("<br />","",$str); return $str; } |
程序与原来给出的大同小异。只是还有一行
1 | $str = str_replace("<br />","",$str); |
是新加上去的。这是因为geshi_highlight输出的文本,总是包含”<br /><br />”,因此显示出来的高亮代码行距太大,这里给它修剪一下,就可以了。
总结一下如何在PB6.0中加入geshi:
1. 上传geshi到babel目录;
2. 在v2excore.php加geshi的路径,让pb能找到geshi.php。
3. 在Utilities.php文件下,function format_ubb之前加上如下function:
1 2 3 4 5 6 7 8 9 10 11 12 | function geshi_replace($matches) { //matches[1]=lang //matches[2]=code $code=$matches[2]; $lang=$matches[1]; $code = str_replace('<', '<', $code); $code = str_replace('>', '>', $code); $str = '<div class="code">'. geshi_highlight($code, $lang,'','true') .'</div>'; $str = str_replace("<br />","",$str); return $str; } |
4. 在function format_ubb中的
1 | $text = preg_replace($p, $r, $text); |
之后插入一行代码:
1 | $text=preg_replace_callback("#\[(asp|bash|c|cpp-qt|cpp|csharp|css|delphi|diff|div|dos|dot|eiffel|fortran|freebasic|genero|gml|groovy|haskell|html4strict|idl|ini|inno|io|java|java5|javascript|latex|lisp|lua|m68k|matlab|mirc|mpasm|mysql|nsis|objc|ocaml-brief|ocaml|oobas|oracle8|pascal|per|perl|php-brief|php|plsql|python|qbasic|rails|reg|robots|ruby|sas|scheme|sdlbasic|smalltalk|smarty|sql|tcl|text|thinbasic|tsql|vb|vbnet|vhdl|visualfoxpro|winbatch|xml)\](.*?)\[/\\1\]#is","geshi_replace",$text); |
大功告成。
使用方法:
- 在PB贴子的编辑框中使用[lang]…[/lang]标签。
- lang标签不可嵌套。
- lang的可选方案以geshi支持为限,大致包括:asm, asp , bash, c, cpp-qt, cpp, csharp, css, delphi, diff, div, dos, dot, eiffel, fortran, freebasic, genero, gml, groovy, haskell, html4strict, idl, ini, inno, io, java, java5, javascript, latex, lisp, lua, m68k, matlab, mirc, mpasm, mysql, nsis, objc, ocaml-brief, ocaml, oobas, oracle8, pascal, per, perl, php-brief, php, plsql, python, qbasic, rails, reg, robots, ruby, sas, scheme, sdlbasic, smalltalk, smarty, sql, tcl, text, thinbasic, tsql, vb, vbnet, vhdl, visualfoxpro, winbatch, xml。呵呵。
结论:
试试这个:无需代码插件在blog中做代码高亮
代码发芽网:http://www.fayaa.com/code/
支持近百种编程语言的
[Reply]