经过长达几个小时的折腾,在Markdown使用代码高亮SyntaxHighlighter,几乎不可行。最后使用Google Code Prettify,绕过该问题,详情见博文《在Markdown使用代码高亮Google Code Prettify》。
0. 写在前面
最近打算转到用Markdown写博文(因为Window Live Writer不跨平台,输入数学公式也不方便),Markdown插入代码块是用triple backticks,被解析成<pre><code class="python">...</code></pre>,这与之前在WLW使用PreCode(基于SyntaxHighlighter,其格式形如<pre class="brush: py">...</pre>)不尽相同。最开始的想法是找到一种方法使两者能兼容,但遇到了不少困难,最后得知Markdown不会处理HTML块级元素(当然也包括<pre></pre>),以为可以直接在Markdown,以<pre class="brush: ...">...</pre>的方式插入代码快。然而,SyntaxHighlighter要求所有在<pre>...</pre>间的<必须事先替换成HTML实体<,使得在Markdown直接以<pre>...</pre>的方式插入代码快几乎不可能。
PROBLEMS: Major issue with this method is that all left angle brackets must be HTML escaped, eg all
<must be replaced with<This will ensure correct rendering.
这是之前做的笔记。记录吧不用插件安装SyntaxHighlighter,在markdown使用SyntaxHighlighter遇到的问题及可能的解决方法,并整理SyntaxHighlighter使用方法,方便日后查阅。
另,SyntaxHighlighter目前最新版本是3.0.9(我也是后来才知道,相对于3.0.83改动很大),整个项目搬到了GitHub,在这里。不过,本文用的是3.0.83(2010年,在这里)。
1. 无插件安装SyntaxHighlighter
可以直接安装wordpress插件SyntaxHighlighter Evolved(事实上,我之前也是这么做的),考虑到自己需要加一些不被该插件支持的语言(比如latex),于是决定手动安装SyntaxHighlighter。
步骤1:下载和定制
在SyntaxHighlighter官网下载,按自已需要将所需文件整理到一个文件夹(如sh),并上传到跟主题或者子主题同目录下(以我为例:themes/radiate-child-01/)。以下文件是必须的:
styles/目录下的shCore.css、shThemeFadeToGrey.css(选个自己喜欢的主题,可以在这里预览主题样式)scripts/文件下的shCore.js、shAutoloader.js,还有所需语言的javascript(如Python:shBrushPython.js),更多语言的js,可以查看All available brushes(目前已无法访问)
另,默认的代码块,第一行和最后一行贴边框太紧,可以修改shCore.css中的样式,如下:
/** modified in `sh/shCore.css` directly **/
.syntaxhighlighter table {
margin-top: 0.5em !important;
margin-bottom: 0.5em !important;
}
步骤2:加载js和css
在functions.php添加必备css样式和js脚本,源代码如下(选个自己喜欢的主题):
function add_sh_styles_scripts() {
wp_enqueue_style( 'shCore.css', get_stylesheet_directory_uri() . '/sh/shCore.css' );
wp_enqueue_style( 'shThemeFadeToGrey.css', get_stylesheet_directory_uri() . '/sh/shThemeFadeToGrey.css' );
wp_enqueue_script( 'shCore.js', get_stylesheet_directory_uri() . '/sh/shCore.js', array(), false, false);
wp_enqueue_script( 'shAutoloader.js', get_stylesheet_directory_uri() . '/sh/shAutoloader.js', array(), false, false);
}
add_action( 'wp_enqueue_scripts', 'add_sh_styles_scripts' );
在footer.php的</body>之前添加如下代码(需要根据所选的语言做一些调整):
<script type="text/javascript">
SyntaxHighlighter.autoloader(
['python', 'py', '<?php echo get_stylesheet_directory_uri(); ?>/sh/shBrushPython.js'],
['java', '<?php echo get_stylesheet_directory_uri(); ?>/sh/shBrushJava.js'],
['bash','shell','<?php echo get_stylesheet_directory_uri(); ?>/sh/shBrushBash.js'],
['css','<?php echo get_stylesheet_directory_uri(); ?>/sh/shBrushCss.js'],
['sql','<?php echo get_stylesheet_directory_uri(); ?>/sh/shBrushSql.js'],
['latex', 'tex','<?php echo get_stylesheet_directory_uri(); ?>/sh/shBrushLatex.js'],
['plain', 'text','<?php echo get_stylesheet_directory_uri(); ?>/sh/shBrushPlain.js'],
['php','<?php echo get_stylesheet_directory_uri(); ?>/sh/shBrushPhp.js'],
['js','jscript','javascript','<?php echo get_stylesheet_directory_uri(); ?>/sh/shBrushJScript.js'],
['xml', 'xhtml', 'xslt', 'html', 'xhtml','<?php echo get_stylesheet_directory_uri(); ?>/sh/shBrushXml.js']
);
SyntaxHighlighter.defaults['toolbar'] = false;
SyntaxHighlighter.all();
</script>
值得注意的是,javascript的相对路径是基于当前页面,所以不能直接使用/sh/shBrushPython.js,因为会被解析成http://sparkandshine.net/sample-posts/sh/shBrushPython.js,报“not found”错误。另,如果不是用子主题,获取目录的函数get_stylesheet_directory_uri()可能需要改成get_template_directory_uri()。
2. SyntaxHighlighter配置及使用
(1)配置
可以在上述代码SyntaxHighlighter.all();前加入SyntaxHighlighter配置,详情见这里,举例如下:
SyntaxHighlighter.config.stripBrs = true;
SyntaxHighlighter.defaults['gutter'] = false;
SyntaxHighlighter.defaults['html-script'] = true;
SyntaxHighlighter.defaults['toolbar'] = false;
SyntaxHighlighter.all();
(2)使用
实际插入代码,选项hightlight可能会用到比较多,用逗号(遵循csv格式)将要突出的行号分隔开,并用中括号括起来,举例如下:
<pre class="brush: js; highlight: [2, 4, 6]">
...
</pre>
3. 遇到的问题
3.1 在Markdown使用SyntaxHighlighter
在Markdown使用triple backticks插入代码会解析成<pre><code class="...">...</code></pre>,SyntaxHighlighter无法正常解析,因为不符合SyntaxHighlighter的格式<pre class="brush: python">...</pre>。
要是直接在Markdown编辑器直接插入<pre class="brush: ...">...</pre>,如果代码块包含<,SyntaxHighlighter也无法正常解析,因为SyntaxHighlighter要求<pre>...</pre>间的所有左尖括号<必须先转化成HTML实体,否则会出现匪夷所思的结果(源于SyntaxHighlighter自动匹配左尖括号<),举例如下:
// 好端端的代码
<pre class="brush: java">
private class MaxPropComparator implements Comparator<message> {
...
}
</pre>
// 会解析成这样(多添加了</message>)
<pre class="brush: java">
private class MaxPropComparator implements Comparator<message> {
...
}
</message></pre>
一个可能的方法是事先将所有<转换成<($str = str_replace('<', '<', $str);),这样尽管解决了代码高亮问题,但下次编辑博文,看到代码块散落的<,是不是想死的心都有了?
3.2 html-script不可用
将html-script设为true时(SyntaxHighlighter.defaults['html-script'] = true;),会提示如下错误:
TypeError: e.brushes.Xml is not a constructor
SyntaxHighlighter</e.HtmlScript() shCore.js:1
SyntaxHighlighter</e.highlight() shCore.js:1
o/a.onreadystatechange() shAutoloader.js:1
参考资料:
[1] StackOverflow: How to fix the pre tag's issues with left angle brackets <?