如何为marked.js编写自定义InlineLexer规则?

时间:2014-10-22 12:22:06

标签: javascript markdown lexer

使用Marked我可以在实现过程中轻松覆盖/添加/更改词法分析器规则,它非常棒! 例如,我可以强制在散列符号和文本之间使用空格来制作这样的标题:

var lexer = new marked.Lexer(options);
console.log(lexer);
lexer.rules.heading = /^\s*(#{1,6})\s+([^\n]+?) *#* *(?:\n+|$)/

console.log(marked.parser(lexer.lex('#hashtag?'), options));
//<p>#hashtag?</p>
console.log(marked.parser(lexer.lex('# heading?'), options));
//<h1 id="undefinedheading-">heading?</h1>

酷!

但是有没有办法,为inlineLexer轻松做同样的事情? 就像我需要让人们能够添加下一个序列的图像:%[My Image](http://example.com/img.jpg)? 所以我修改了:

var inlineLexer = marked.InlineLexer;
inlineLexer.rules.link = /^[!%]{0,1}?\[((?:\[[^\]]*\]|[^\[\]]|\](?=[^\[]*\]))*)\]\(\s*<?([\s\S]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*\)/;
...

接下来我该怎么办? 如何将自定义inlineLexer绑定到标记的实例? 请给我看一个如何做到这一点的例子!如何修改/添加自定义内联词法分析器规则?

1 个答案:

答案 0 :(得分:5)

我查看了marked.js的源代码,找到了覆盖部分内容的方法,以便允许对内联词法分析器进行一些自定义,而无需更改库源或影响全局标记的实例或原型

var renderer = new marked.Renderer();
var lexer = new marked.Lexer();
var parser = new marked.Parser();

var options = {
    renderer: renderer,
    gfm: true,
    tables: false,
    breaks: true,
    pedantic: false,
    sanitize: true,
    smartLists: true,
    smartypants: false
}

parser.inline = new marked.InlineLexer([], options);
parser.inline.rules = angular.copy(parser.inline.rules); // deep copy, otherwise global marked will be affected

parser.inline.rules.link = /^[!%]{0,1}?\[((?:\[[^\]]*\]|[^\[\]]|\](?=[^\[]*\]))*)\]\(\s*<?([\s\S]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*\)/;
renderer.link =  function(href, title, text) {
    // this is the standard link renderer that can be altered if desired ...
    if (this.options.sanitize) {
        try {
            var prot = decodeURIComponent(unescape(href))
                .replace(/[^\w:]/g, '')
                .toLowerCase();
        } catch (e) {
            return '';
        }
        if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0) {
            return '';
        }
    }
    var out = '<a href="' + href + '"';
    if (title) {
        out += ' title="' + title + '"';
    }
    out += '>' + text + '</a>';
    return out;
}

function parse(src) {
    parser.inline.links = src.links;
    parser.tokens = src.reverse();
    var out = '';
    while (parser.next()) {
        out += parser.tok();
    }
    return out;
};

function parseText(text) {
    var lex = lexer.lex(text);
    var r = parse(lex);
    return r;
}