经常要往 blog 里贴代码,没个代码高亮实在有点落伍。找来找去,wordpress 下也就 WP-Syntax 最好用了,支持的语言也比较多,像 linux 下的 bash, vim 都可以被高亮化。不过 WP-Syntax 也并非完美,有些地方和我的使用习惯相差甚远:

先来看下改造前和改造后的代码吧:

wp-syntax

  1. pre 标签被两层 div 嵌套,代码冗余
  2. pre 标签内被硬植入字族的 inline stylesheet,覆盖了我的 CSS 设置
  3. 插件自带的 CSS 文件重置了我的 CSS 设置
  4. 自动转义 <, >, & 这类代码,问题是稍有经验的 coder 都会事先自己主动转义过的,所以之前已经转义过了的代码反而会以 &lt;, &gt;, &amp; 这类形式输出

首先改造代码嵌套的问题

找到插件目录下的 wp-syntax.php 文件,搜索 wp_syntax_highlight 函数,将以下几行注释掉 ( 注释行前加了 // 符号 ):

function wp_syntax_highlight($match)
{
    global $wp_syntax_matches;
    ......
    if ($escaped != "false") $code = htmlspecialchars_decode($code);

    $geshi = new GeSHi($code, $language);
    $geshi->enable_keyword_links(false);
    do_action_ref_array('wp_syntax_init_geshi', array(&$geshi));

    //$output = "\n<div class=\"wp_syntax\">";

    if ($line)
    {
    ......
    }
    else
    {
	//$output .= "<div class=\"code\">";
        $output .= $geshi->parse_code();
	//$output .= "</div>";
    }
	//return

	//$output .= "</div>\n";

    return $output;
}

```php

### 转义问题

还是`wp_syntax_highlight`函数,将这句:

```php
if ($escaped == "true") $code = htmlspecialchars_decode($code);

替换成

if ($escaped != "false") $code = htmlspecialchars_decode($code);

就是了,也就是说除非手动在 <pre> 里加入 escaped="false" 参数,输出的代码是不会自动转义的。

硬植入 CSS 问题

由于 WP-Syntax 可以方便的调用 wp_syntax_init_geshi 来修改 geshi 的初始设置,解决 CSS 问题可以不需要修改 WP-Syntax 本身的插件代码,全部在主题文件夹下的 functions.php 里就可以搞定了。

首先解决往 pre 里插入字族设置的问题,在 functions.php 里加入一函数:

function my_custom_geshi_styles(&$geshi) {
    $geshi->set_overall_style('');
    $geshi->set_code_style('');
};

它会把 geshi 预设的 inline stylesheet 全部清除为空,然后再利用 Wordpress 的 add_action hook 重新初始化 geshi 的设置,在 functions.php 里加入这句:

add_action('wp_syntax_init_geshi', 'my_custom_geshi_styles');

至于去掉 WP-Syntax 自带的 CSS 文件就更简单了,还是往 functions.php 里添加一句 remove_action 的 hook 就是了:

remove_action('wp_head', 'wp_syntax_head');

其实 WP-PageNavi 带的那两三行代码的 CSS 文件也可以这么干掉:

remove_action('wp_head', 'pagenavi_css');

小结

其实 Wordpress 主题文件夹下的 functions.php 文件是相当有用的,利用 Wordpress 本身提供的 Plugin API, 很多东西都可以直接在 functions.php 下直接用一个函数挂上 action 或者 filter 的钩子就搞定了。