经过长达几个小时的折腾,在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 <
?