2

我正在尝试在 AngularJS 中编写降价编辑器。我正在使用 angular-markdown(AngularJS Showdown 包装器)来解析 markdown,我想使用 highlightjs 突出显示代码块。我写了以下摊牌扩展:

/* global
    hljs,
    Showdown
*/

(function() {
    'use strict';

    Showdown.extensions.hljs = function(converter) {
        return [
            {
                type: 'lang',
                filter: function(text) {
                    return text;
                    var m = /([`]{3}[\S\s]*[`]{3})/gm.exec(text);
                    if(!m) {
                        return text;
                    }
                    for(var i in m) {
                        if(isNaN(i)) {
                            continue
                        }
                        var match = m[i];
                        var lang = match.replace(
                            /([`]{3})([\s\S]*)(\n){1}([\s\S]*)([`]{3})/gm,
                            '$2');
                        var code = match.replace(
                            /([`]{3})([\S\n]*)(\n){1}([\s\S]*)([`]{3})/gm,
                            '$4');
                        var hl;
                        try {
                            var hl = hljs.highlight(lang, code);
                        } catch(e) {
                            var hl = hljs.highlightAuto(code);
                        }
                        text = text.replace(match, '<pre>' + hl.value + '</pre>');
                    }
                    return text;
                }
            }
        ];
    };
}());

不过,这还不完美。第一个代码片段之后的文本也被嵌套并突出显示。

我在这里创建了一个 plunkr 。相关代码在js/angular-markdown-hljs.js.

我的问题是:我怎样才能让它工作?

4

1 回答 1

4

使用https://highlightjs.org/对代码高亮进行扩展,使用新摊牌的扩展 RegExp 引擎会很容易。

这是最新摊牌的代码示例。

showdown.extension('codehighlight', function() {
  function htmlunencode(text) {
    return (
      text
        .replace(/&amp;/g, '&')
        .replace(/&lt;/g, '<')
        .replace(/&gt;/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);
      }
    }
  ];
});
于 2016-01-04T17:34:48.477 回答