使用google-code-prettify实现代码高亮

首先感谢坏猫的方法。
因为我这两天其实一直就在筹划干掉玻璃泉的wp-code-highlight插件,今天看到坏猫的办法之后,正好两厢参照,作出了自己的方案。

首先,说说为什么要干掉wp-code-highlight。因为一直在谋划心目中的完美主题,其中一个先期工作就是要让所有css和js可控。而很不幸wp-code-highlight的js和css不是按照wp的正统方式追加的,也就是说,我要么使用这个插件,要么不用,但无法做到启用后限定js的作用范围。

因为坏猫那边说得已经很详细了,所以我这里的侧重点是如何分页面控制加载js。
我这里的习惯是把这种可以与主题分开的控制项目,单独做成一个插件,这样即使换了主题,代码也可以生效。如果想要在自己的主题里实现,尽管加到functions.php里好了,具体的不同参照注释。能自己改代码的应该都能看懂……

第一步,追加触发动作

add_action('plugins_loaded', 'apip_init');
//add_action( 'after_setup_theme', 'apip_init' ); /*如果是主题,用这句*/
function apip_init()
{
	add_action('get_header','apip_header_actions') ;
	add_action('get_footer','apip_footer_actions') ;
	
	add_action('admin_print_footer_scripts','apip_quicktags');
}

第二步,在header动作里追加对于文章内容的过滤项。加上这个,就不用修改既存的《pre》标签了。

function apip_header_actions()
{
	if ( in_category('code_share') )
	/*定义一个categroy,只有这个类别的才加载css,可以提高一丢丢速度。或者换成in_tag然后追加一个tag也可*/
	{
		add_filter('the_content', 'apip_code_highlight') ;
	}
}

//下面这个函数要感谢玻璃泉。不加的话双引号会引起内容错乱。
function wch_stripslashes($code){
	$code=str_replace('\"', '"',$code);
	$code=htmlspecialchars($code,ENT_QUOTES);
	return $code;
}

//如果想要行号,在prettyprint 后面加上一个 linenums
function apip_code_highlight($content) {
	return preg_replace("/<pre(.*?)>(.*?)<\/pre>/ise",                                                          
		"'<pre class=" prettyprint ">'.wch_stripslashes('$2').'</ pre>'", $content);
}

第三步,在footer里加css和js。一般来说css和js要在footer里加。但因为已经对类别进行了限制,所以跟第二步的写到一起其实也影响不大。

function apip_footer_actions()
{
	if ( in_category('code_share') )
	{
?>
		<script type="text/javascript">
			window.onload = function(){prettyPrint();};
		</script>
<?php
		//如果是主题,下面两个函数换成template_dir_url( __FILE__ )
		wp_enqueue_script('prettify_js', plugin_dir_url( __FILE__ ) . 'js/prettify.js', array('jquery'), null, true);
		wp_enqueue_style( 'prettify_style', plugin_dir_url( __FILE__ ) . 'css/prettify.css' );
	}
}

第四步,追加编辑画面的标签

function apip_quicktags()
{
?>
	<script type="text/javascript" charset="utf-8">
		QTags.addButton( 'eg_pre', 'pre', '<pre>\n', '\n</ pre>\n', 'p' );
	</script>
<?php
}

js和css的下载地址,自备梯子。

===== Update.2019.8.7 =====
因为php7不支持preg_replace第一个参数的/e选项,所以第二步的第三段代码要作如下修改:

function apip_code_highlight($content) {
    $result = preg_replace_callback('/<pre(.*?)>(.*?)<\/pre>/is', function ($matches) {
        return '<pre class=" prettyprint ">' . wch_stripslashes($matches[2]) . '</ pre >'; } , $content);
   return $result ;
}

已有11条评论

    1. 这个其实只是捎带,我在尝试不同的页面加载不同的js.但主题不是自己写的不明白每个js的用途,闹心.

      1. 如果不是合并加密的js,应该不难看懂啊。

        1. 加了min了
          而且我现在用的是子主题的方法,追求父主题一字不动之道。

  1. W

    我也想着EM里编辑器里能否有个引用,图片边框的效果。

    1. 这个直接写css就能实现吧

      1. W

        谢谢支招,空下来了就试试。

        1. 只对贴代码程序猿的有意义.王老师转行当攻城狮的时候才能用得上吧…

  2. 精益求精的态度啊,用什么加载什么,赞。

    1. 因为被一个测速度的网站鄙视了.

  3. 这个还不错,相对而言代码看起来清晰

    1. 在坏猫的基础上改的。

  4. 我前两天也折腾了,但是影响加载速度哦,就没搞了。

    1. 我的方法不会影响首页,只在有代码的时候加载

        1. 你指的是引js吗?我是在第三步做的.

  5. 个人觉得知更鸟的那个代码高亮转换挺不错的,代码实现挺好的

    1. 宁可慢死也不会每次贴代码都去访问一下他的站.

      1. 这个倒也是,我也是用他的主题,顺便的。如果不用他的主题,也挺麻烦的,折腾这个

        1. 自己动手丰衣足食

  6. 上面列出的代码都需要写到functions.php里吗?

    1. 往主题里加的话,是。
      if ( in_category(‘code_share’) )注掉,这是我自己的分类。
      我更喜欢放到自己写的插件里。

你好,新朋友。留言前请先填写昵称邮箱