2014-10-22 15 views
8

Con Marked Posso facilmente sovrascrivere/aggiungere/modificare le regole di lexer durante l'implementazione, ed è fantastico! Per esempio posso forzare di utilizzare lo spazio tra le hash firmare un testo per fare un colpo di testa in questo modo:come scrivere regola InlineLexer personalizzata per 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!

Ma c'è un modo, per fare facilmente lo stesso per inlineLexer? Come ho bisogno di rendere le persone in grado di aggiungere immagini con la sequenza successiva: %[My Image](http://example.com/img.jpg)? Così ho modificato:

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

Che cosa devo fare dopo? Come associare un inlineLexer personalizzato a un'istanza contrassegnata? Per favore, mostrami un esempio di come farlo! Come posso modificare/aggiungere regole inline lexer personalizzate?

+1

Si prega di guardare questo [problema] (https://github.com/chjj/marked/issues/504) dove ho postato la mia soluzione. – Rugal

risposta

4

Ho esaminato il codice sorgente per marked.js per trovare un modo per sovrascrivere le parti di esso al fine di consentire alcune personalizzazioni del lexer in linea, senza modificare l'origine della libreria o influenzare l'istanza o i prototipi contrassegnati globali.

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

Ho usato angular.copy() per eseguire una copia profonda delle regole del lexer inline solo per essere conciso, e perché io uso angularjs, ma qualsiasi copia profonda andrà bene. –

+1

Grande. Ci proverei. Ma era secoli fa. :) –

Problemi correlati