2014-10-22 18 views
8

Với Marked Tôi có thể dễ dàng ghi đè/thêm/thay đổi quy tắc lexer trong quá trình triển khai và tuyệt vời! Ví dụ tôi có thể buộc phải sử dụng khoảng trống giữa băm ký một văn bản để thực hiện một tiêu đề như thế này:cách viết quy tắc InlineLexer tùy chỉnh cho 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!

Nhưng có cách nào, để dễ dàng thực hiện tương tự cho inlineLexer? Giống như tôi cần làm cho mọi người có thể thêm hình ảnh với chuỗi tiếp theo: %[My Image](http://example.com/img.jpg)? Vì vậy, tôi đã sửa đổi:

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

Tôi nên làm gì tiếp theo? Cách liên kết một inlineLexer tùy chỉnh với một cá thể được đánh dấu? Vui lòng cho tôi xem ví dụ về cách thực hiện việc này! Làm cách nào để sửa đổi/thêm quy tắc lexer nội tuyến tùy chỉnh?

+1

Vui lòng xem [issue] này (https://github.com/chjj/marked/issues/504) nơi tôi đăng giải pháp của mình. – Rugal

Trả lời

4

Tôi đã xem mã nguồn của marker.js để tìm cách ghi đè các phần của nó để cho phép một số tùy chỉnh của lexer nội tuyến, mà không thay đổi nguồn thư viện hoặc ảnh hưởng đến cá thể hoặc nguyên mẫu được đánh dấu toàn cầu.

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

Tôi đã sử dụng angular.copy() để thực hiện một bản sao sâu của các quy tắc lexer nội tuyến chỉ để súc tích, và bởi vì tôi sử dụng angularjs, nhưng bất kỳ bản sao sâu sẽ được sử dụng tốt. –

+1

Tuyệt vời. Tôi sẽ thử. Nhưng đã nhiều thế kỷ trước. :) –

Các vấn đề liên quan