我在制作个人博客,使用ajax获取markdown文件,使用showdown.js
来解析markdown语法。目前进行得比较顺利,但是有一个问题,我一直没有找到我满意的语法高亮解决方案。
我尝试使用过showdown-highlight来实现语法高亮,效果也比较让人满意,只是在webpack
打包的时候出现了这样的报错:
ERROR in bundle.js from UglifyJs SyntaxError: Unexpected token punc «(», expected punc «:» [./~/showdown-highlight/lib/index.js:20,0]
这个比较尴尬,毕竟代码肯定是要压缩的,否则2MB的js文件加载起来实在太慢了。我尝试查阅了highlight.js
的文档,没有相关的信息。
我翻阅了showdown的相关issue,看到有提供这样的解决方案:
showdown.extension('codehighlight', function() { function htmlunencode(text) { return ( text .replace(/&/g, '&') .replace(/</g, '<') .replace(/>/g, '>') ); } return [ { type: 'output', filter: function (text, converter, options) { // use new shodown's regexp engine to conditionally parse codeblocks var left = '', flags = 'g', replacement = function (wholeMatch, match, left, right) { // unescape match to prevent double escaping match = htmlunencode(match); return left + hljs.highlightAuto(match).value + right; }; return showdown.helper.replaceRecursiveRegExp(text, replacement, left, right, flags); } } ]; });]*>', right = '
我之前在webpack里引用是这样的:
var showdown = require('showdown'), showdownhighlight = require('showdown-highlight'); var converter = new showdown.Converter({extensions: [showdownhighlight]});
这种引用方式和issue里的解决方案有所不同,琢磨半天也没琢磨透,请问有什么更好的解决方案吗?
结果刚提了问就找到了解决办法。。
var converter = new showdown.Converter({extensions: function() { function htmlunencode(text) { return ( text .replace(/&/g, '&') .replace(/</g, '<') .replace(/>/g, '>') ); } return [ { type: 'output', filter: function (text, converter, options) { // use new shodown's regexp engine to conditionally parse codeblocks var left = '<pre><code\\b[^>]*>', right = '</code></pre>', flags = 'g', replacement = function (wholeMatch, match, left, right) { // unescape match to prevent double escaping match = htmlunencode(match); return left + hljs.highlightAuto(match).value + right; }; return showdown.helper.replaceRecursiveRegExp(text, replacement, left, right, flags); } } ]; }()});
比较粗暴地把后面的匿名函数当成参数传入,就可以实现了。