2014-10-22 14 views
8

Dzięki Marked mogę łatwo zastąpić/dodać/zmienić zasady lexera podczas implementacji i to świetnie! Na przykład mogę zmusić do wykorzystania przestrzeń pomiędzy hash podpisać tekst, aby nagłówek tak:jak napisać niestandardową regułę InlineLexer dla marked.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> 

Cool!

Ale czy istnieje sposób, aby łatwo zrobić to samo dla inlineLexer? Muszę sprawić, że ludzie będą mogli dodawać obrazy z następną sekwencją: %[My Image](http://example.com/img.jpg)? Więc zmodyfikowałem:

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

Co mam zrobić dalej? Jak powiązać niestandardowy inlineLexer z zaznaczonym wystąpieniem? Pokaż mi, jak to zrobić! Jak mogę zmodyfikować/dodać niestandardowe reguły lexera?

+1

Proszę spojrzeć na to [wydanie] (https://github.com/chjj/marked/issues/504) gdzie opublikowałem moje rozwiązanie. – Rugal

Odpowiedz

4

Przyjrzałem się kodowi źródłowemu znacznika.js, aby znaleźć sposób na przesłonięcie jego części w celu umożliwienia dostosowania inline lexer, bez zmiany źródła biblioteki lub wpływu na globalnie oznaczoną instancję lub prototypy.

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

Użyłem metody angular.copy(), aby wykonać głęboką kopię wewnętrznych zasad leksera, aby była zwięzła, a ponieważ używam angularjs, ale każda głęboka kopia będzie w porządku. –

+1

Świetnie. Spróbuję. Ale to było wieki temu. :) –

Powiązane problemy