2014-10-22 1 views
8

С Marked Я могу легко переопределить/добавить/изменить правила lexer во время реализации, и это отлично! Например, я могу заставить использовать пространство между хэш подписать текст, чтобы сделать заголовок так:Как написать собственное правило InlineLexer для отмеченных .js?

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 с отмеченным экземпляром? Пожалуйста, покажите мне пример того, как это сделать! Как я могу изменить/добавить пользовательские встроенные правила lexer?

+1

Пожалуйста, ознакомьтесь с этим [вопросом] (https://github.com/chjj/marked/issues/504), где я разместил свое решение. – Rugal

ответ

4

Я рассмотрел исходный код для отмеченного.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; 
} 
+0

Я использовал angular.copy(), чтобы выполнить глубокую копию правил встроенного лексера, чтобы быть кратким, и потому что я использую angularjs, но любая глубокая копия будет в порядке. –

+1

Отлично. Я бы попробовал. Но это было много веков назад. :) –