SyntaxHighlighter 的正确使用姿势 - InstantClick 哭晕在厕所

2015-03-05 • 博客记录11 Comments

今天闲得无聊,让 InstantClick 支持了 SynatxHighlighter,并且对 Typecho 动了些手脚,使得在 Markdown 渲染的时候无需手动指定就可自动识别代码语言并渲染高亮。

看起来逼格很高的两个事情,其实只需要简单的几个操作。

InstantClick 不支持 SynatxHighlighter ,是因为后者是监听 document.ready 事件的。这种动态渲染的插件,大多和 InstantClick 不兼容。解决方法和在 使用 InstantClick 时 piwik 、 MathJax 的配置 文中描述的一样,只需要加入一段渲染的代码就完工了:

InstantClick.on('change', function() {
    SyntaxHighlighter.highlight();
});

值得一提的是,我之前一直在试着加 SyntaxHighlighter.all() 发现没有用,后来读源码才发现, SyntaxHighlighter.all() 这个函数依然是监听 document.ready 事件,并在监听后调用 SyntaxHighlighter.highlight() 的,所以应该直接调用后者。

另外,SyntaxHighlighter 在换页后似乎无法 Autoload 对应的 Brush,所以需要在页面中预先用 script 标签加载所有的 brush。

至于 Markdown 渲染的时候加入自动识别,其实也就是加了个简单的正则。是在 /var/MarkdownExtraExtended.php 文件中,修改 _doCodeBlocks_callback 函数如下:

<?php
    protected function _doCodeBlocks_callback($matches) {
            $codeblock = $this->unhashHTMLBlocks($matches[1]);

            $codeblock = $this->outdent($codeblock);
            $codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES);

            # trim leading newlines and trailing newlines
            $codeblock = preg_replace('/\A\n+|\n+\z/', '', $codeblock);
            $codeRegexs = array(
                    'php' => '#\\?php#',
                    'html' => '#\(html|body|head|title|h1|div|p|?xml)#',
                    'js' => '#var|function \(|window\.|document\.|innerHTML#',
                    'bash' => '#curl|wget|sh|^\#!|service .* start|yum install|clone |cd #',
                    'sql' => '#SELECT|UPDATE|DELETE|WHERE#',
                    'python' => '#if.*:|def .*\(#',
                    'css' => '#background-color|font-family|margin|padding#',
            );
            $brush = 'text';
            foreach ($codeRegexs as $lang => $reg) {
                    if(preg_match($reg, $codeblock)){
                            $brush = $lang;
                            break;
                    }
            }
            $codeblock = "<pre class='brush: $brush'>$codeblock\n</pre>";
            return "\n\n".$this->hashBlock($codeblock)."\n\n";
    }

好了,从此告别手动指定语言,走向新时代啦~

已有 11 条评论

  1. 发现博客留言出了问题,到你这测试下是不是也这样…

  2. mcc mcc

    不得不说syntaxhightlight真的样式好看。。。我要不要弄个django版本。。

    1. 一个前端库而已~随便套一下就好了

      1. mcc mcc

        主要我已经用了hightlight.js,本身会认语言,其他样式还好都可以自己定制,就是木有行号。。。

        1. 写个小 js 认下语言也挺好的……只是 SHL 的 js 太坑我懒得改……

  3. 技术控

  4. www赶紧改自己的博客去

    1. 小问题挺多的……#装逼的代价#

  5. /var/MarkdownExtraExtended.php 没有这个文件啊 2333

    1. 我的 typecho 是 0.9.x 的,最新的 1.x 可能不支持~